-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13 from chhakuli123/11-feature-request-intigratio…
…n-with-llm 11 feature request intigration with llm
- Loading branch information
Showing
21 changed files
with
789 additions
and
6,442 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { NextRequest, NextResponse } from "next/server"; | ||
import { callChain } from "@/lib/langchain"; | ||
import { Message } from "ai"; | ||
|
||
const formatMessage = (message: Message) => { | ||
return `${message.role === "user" ? "Human" : "Assistant"}: ${ | ||
message.content | ||
}`; | ||
}; | ||
|
||
export async function POST(req: NextRequest) { | ||
const body = await req.json(); | ||
const messages: Message[] = body.messages ?? []; | ||
console.log("Messages ", messages); | ||
const formattedPreviousMessages = messages.slice(0, -1).map(formatMessage); | ||
const question = messages[messages.length - 1].content; | ||
|
||
console.log("Chat history ", formattedPreviousMessages.join("\n")); | ||
|
||
if (!question) { | ||
return NextResponse.json("Error: No question in the request", { | ||
status: 400, | ||
}); | ||
} | ||
|
||
try { | ||
const streamingTextResponse = callChain({ | ||
question, | ||
chatHistory: formattedPreviousMessages.join("\n"), | ||
}); | ||
|
||
return streamingTextResponse; | ||
} catch (error) { | ||
console.error("Internal server error ", error); | ||
return NextResponse.json("Error: Something went wrong. Try again!", { | ||
status: 500, | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
|
||
import { Chat } from "@/components/chat/chat"; | ||
|
||
export default function chat() { | ||
return ( | ||
<main className="relative container flex min-h-screen flex-col"> | ||
<div className="flex flex-1 py-4"> | ||
<div className="w-full"> | ||
<Chat /> | ||
</div> | ||
</div> | ||
</main> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import Balancer from "react-wrap-balancer"; | ||
import { | ||
Card, | ||
CardContent, | ||
CardDescription, | ||
CardFooter, | ||
CardHeader, | ||
CardTitle, | ||
} from "@/components/ui/card"; | ||
import { | ||
Accordion, | ||
AccordionContent, | ||
AccordionItem, | ||
AccordionTrigger, | ||
} from "@/components/ui/accordion"; | ||
import { Message } from "ai/react"; | ||
import ReactMarkdown from "react-markdown"; | ||
import { formattedText } from "@/lib/utils"; | ||
|
||
const convertNewLines = (text: string) => | ||
text.split("\n").map((line, i) => ( | ||
<span key={i}> | ||
{line} | ||
<br /> | ||
</span> | ||
)); | ||
|
||
interface ChatLineProps extends Partial<Message> { | ||
sources: string[]; | ||
} | ||
|
||
export function ChatLine({ | ||
role = "assistant", | ||
content, | ||
sources, | ||
}: ChatLineProps) { | ||
if (!content) { | ||
return null; | ||
} | ||
const formattedMessage = convertNewLines(content); | ||
|
||
return ( | ||
<div> | ||
<Card className="mb-2"> | ||
<CardHeader> | ||
<CardTitle | ||
className={ | ||
role != "assistant" | ||
? "text-amber-500 dark:text-amber-200" | ||
: "text-blue-500 dark:text-blue-200" | ||
} | ||
> | ||
{role == "assistant" ? "AI" : "You"} | ||
</CardTitle> | ||
</CardHeader> | ||
<CardContent className="text-sm"> | ||
<Balancer>{formattedMessage}</Balancer> | ||
</CardContent> | ||
<CardFooter> | ||
<CardDescription className="w-full"> | ||
{sources && sources.length ? ( | ||
<Accordion type="single" collapsible className="w-full"> | ||
{sources.map((source, index) => ( | ||
<AccordionItem value={`source-${index}`} key={index}> | ||
<AccordionTrigger>{`Source ${index + 1}`}</AccordionTrigger> | ||
<AccordionContent> | ||
<ReactMarkdown > | ||
{formattedText(source)} | ||
</ReactMarkdown> | ||
</AccordionContent> | ||
</AccordionItem> | ||
))} | ||
</Accordion> | ||
) : ( | ||
<></> | ||
)} | ||
</CardDescription> | ||
</CardFooter> | ||
</Card> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
"use client"; | ||
|
||
import { scrollToBottom, initialMessages, getSources } from "@/lib/utils"; | ||
import { ChatLine } from "./chat-line"; | ||
import { useChat, Message } from "ai-stream-experimental/react"; | ||
import { Input } from "@/components/ui/input"; | ||
import { Button } from "@/components/ui/button"; | ||
import { Spinner } from "@/components/ui/spinner"; | ||
import { useEffect, useRef } from "react"; | ||
|
||
export function Chat() { | ||
const containerRef = useRef<HTMLDivElement | null>(null); | ||
const { messages, input, handleInputChange, handleSubmit, isLoading, data } = | ||
useChat({ | ||
initialMessages: initialMessages.map((message) => ({ | ||
...message, | ||
role: message.role as "function" | "system" | "user" | "assistant", | ||
})), | ||
}); | ||
|
||
useEffect(() => { | ||
setTimeout(() => scrollToBottom(containerRef), 100); | ||
}, [messages]); | ||
|
||
return ( | ||
<div className="rounded-2xl border h-[75vh] flex flex-col justify-between"> | ||
<div className="p-6 overflow-auto" ref={containerRef}> | ||
{messages.map(({ id, role, content }: Message, index) => ( | ||
<ChatLine | ||
key={id} | ||
role={role} | ||
content={content} | ||
// Start from the third message of the assistant | ||
sources={data?.length ? getSources(data, role, index) : []} | ||
/> | ||
))} | ||
</div> | ||
|
||
<form onSubmit={handleSubmit} className="p-4 flex clear-both"> | ||
<Input | ||
value={input} | ||
placeholder={"Type to chat with AI..."} | ||
onChange={handleInputChange} | ||
className="mr-2" | ||
/> | ||
|
||
<Button type="submit" className="w-24"> | ||
{isLoading ? <Spinner /> : "Ask"} | ||
</Button> | ||
</form> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
"use client"; | ||
|
||
import * as React from "react"; | ||
import * as AccordionPrimitive from "@radix-ui/react-accordion"; | ||
import { ChevronDown } from "lucide-react"; | ||
|
||
import { cn } from "@/lib/utils"; | ||
|
||
const Accordion = AccordionPrimitive.Root; | ||
|
||
const AccordionItem = React.forwardRef< | ||
React.ElementRef<typeof AccordionPrimitive.Item>, | ||
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item> | ||
>(({ className, ...props }, ref) => ( | ||
<AccordionPrimitive.Item | ||
ref={ref} | ||
className={cn("border-b", className)} | ||
{...props} | ||
/> | ||
)); | ||
AccordionItem.displayName = "AccordionItem"; | ||
|
||
const AccordionTrigger = React.forwardRef< | ||
React.ElementRef<typeof AccordionPrimitive.Trigger>, | ||
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Trigger> | ||
>(({ className, children, ...props }, ref) => ( | ||
<AccordionPrimitive.Header className="flex"> | ||
<AccordionPrimitive.Trigger | ||
ref={ref} | ||
className={cn( | ||
"flex flex-1 items-center justify-between py-4 font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180", | ||
className | ||
)} | ||
{...props} | ||
> | ||
{children} | ||
<ChevronDown className="h-4 w-4 shrink-0 transition-transform duration-200" /> | ||
</AccordionPrimitive.Trigger> | ||
</AccordionPrimitive.Header> | ||
)); | ||
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName; | ||
|
||
const AccordionContent = React.forwardRef< | ||
React.ElementRef<typeof AccordionPrimitive.Content>, | ||
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Content> | ||
>(({ className, children, ...props }, ref) => ( | ||
<AccordionPrimitive.Content | ||
ref={ref} | ||
className="overflow-hidden text-sm transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down" | ||
{...props} | ||
> | ||
<div className={cn("pb-4 pt-0", className)}>{children}</div> | ||
</AccordionPrimitive.Content> | ||
)); | ||
|
||
AccordionContent.displayName = AccordionPrimitive.Content.displayName; | ||
|
||
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.