chore: Improve Input and Examples UI

This commit is contained in:
zaidmukaddam 2024-08-07 21:16:29 +05:30
parent f8747586ab
commit f4db1c968f
2 changed files with 38 additions and 32 deletions

View File

@ -1,6 +1,6 @@
import { openai } from "@ai-sdk/openai"; import { openai } from "@ai-sdk/openai";
import { anthropic } from '@ai-sdk/anthropic' import { anthropic } from '@ai-sdk/anthropic'
import { convertToCoreMessages, streamText } from "ai"; import { convertToCoreMessages, streamText, tool } from "ai";
import { z } from "zod"; import { z } from "zod";
// Allow streaming responses up to 30 seconds // Allow streaming responses up to 30 seconds
@ -27,6 +27,7 @@ export async function POST(req: Request) {
"Once you have found the information, you provide the user with the information you found in brief like a news paper detail." + "Once you have found the information, you provide the user with the information you found in brief like a news paper detail." +
"The detail should be 3-5 paragraphs in 10-12 sentences, some time pointers, each with citations in the [Text](link) format always!" + "The detail should be 3-5 paragraphs in 10-12 sentences, some time pointers, each with citations in the [Text](link) format always!" +
"Citations can be inline of the text like this: Hey there! [Google](https://google.com) is a search engine." + "Citations can be inline of the text like this: Hey there! [Google](https://google.com) is a search engine." +
"Do not start the responses with newline characters, always start with the first sentence." +
"The current date is: " + "The current date is: " +
new Date() new Date()
.toLocaleDateString("en-US", { .toLocaleDateString("en-US", {
@ -39,7 +40,7 @@ export async function POST(req: Request) {
"Never use the heading format in your response!." + "Never use the heading format in your response!." +
"Refrain from saying things like 'Certainly! I'll search for information about OpenAI GPT-4o mini using the web search tool.'", "Refrain from saying things like 'Certainly! I'll search for information about OpenAI GPT-4o mini using the web search tool.'",
tools: { tools: {
web_search: { web_search: tool({
description: 'Search the web for information with the given query, max results and search depth.', description: 'Search the web for information with the given query, max results and search depth.',
parameters: z.object({ parameters: z.object({
query: z.string() query: z.string()
@ -82,7 +83,7 @@ export async function POST(req: Request) {
results: context results: context
} }
} }
}, }),
}, },
onFinish: async (event) => { onFinish: async (event) => {
console.log(event.text); console.log(event.text);

View File

@ -37,6 +37,7 @@ export default function Home() {
const [showToolResults, setShowToolResults] = useState<{ [key: number]: boolean }>({}); const [showToolResults, setShowToolResults] = useState<{ [key: number]: boolean }>({});
const [isModelSelectorOpen, setIsModelSelectorOpen] = useState(false); const [isModelSelectorOpen, setIsModelSelectorOpen] = useState(false);
const [selectedModel, setSelectedModel] = useState('Speed'); const [selectedModel, setSelectedModel] = useState('Speed');
const [showExamples, setShowExamples] = useState(false)
const { isLoading, input, messages, setInput, append, handleSubmit, setMessages } = useChat({ const { isLoading, input, messages, setInput, append, handleSubmit, setMessages } = useChat({
api: '/api/chat', api: '/api/chat',
@ -315,33 +316,39 @@ export default function Home() {
value={input} value={input}
onChange={(e) => setInput(e.target.value)} onChange={(e) => setInput(e.target.value)}
disabled={isLoading} disabled={isLoading}
className="w-full h-10 py-3 px-4 bg-gray-100 rounded-full pr-12 focus:outline-none focus:ring-2 focus:ring-green-500 text-sm sm:text-base" className="w-full min-h-12 py-3 px-4 bg-muted border border-input rounded-full pr-12 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 text-sm sm:text-base"
onFocus={() => setShowExamples(true)}
onBlur={() => setShowExamples(false)}
/> />
<Button <Button
size="icon"
type="submit" type="submit"
variant="ghost" size={'icon'}
disabled={isLoading} variant={'ghost'}
className="absolute right-2 top-1/2 transform -translate-y-1/2 bg-transparent hover:bg-transparent" className="absolute right-2 top-1/2 transform -translate-y-1/2"
disabled={input.length === 0}
> >
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <ArrowRight size={20} />
<path d="M5 12H19M19 12L12 5M19 12L12 19" stroke="#9CA3AF" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
</svg>
</Button> </Button>
</div> </div>
</form> </form>
<div className="flex flex-col gap-2 text-left items-start justify-start"> <div className={`mx-auto w-full transition-all ${showExamples ? 'visible' : 'invisible'}`}>
{exampleQueries.map((query, index) => ( <div className="bg-background p-2">
<button <div className="flex flex-col items-start space-y-2">
key={index} {exampleQueries.map((message, index) => (
onClick={() => handleExampleClick(query)} <Button
className="mb-1 hover:underline flex flex-row" key={index}
> variant="link"
<ArrowRight className="w-5 h-5 mr-1" /> className="h-auto p-0 text-base"
{query} name={message}
</button> onClick={() => handleExampleClick(message)}
))} >
<ArrowRight size={16} className="mr-2 text-muted-foreground" />
{message}
</Button>
))}
</div>
</div>
</div> </div>
</motion.div> </motion.div>
)} )}
@ -362,7 +369,7 @@ export default function Home() {
initial={{ opacity: 0, y: 20 }} initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }} animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: 0.2 }} transition={{ duration: 0.5, delay: 0.2 }}
className="text-lg sm:text-2xl font-medium font-serif" className="text-2xl font-medium font-serif"
> >
{lastSubmittedQuery} {lastSubmittedQuery}
</motion.p> </motion.p>
@ -390,7 +397,7 @@ export default function Home() {
{messages.map((message, index) => ( {messages.map((message, index) => (
<div key={index}> <div key={index}>
{message.role === 'assistant' && message.content && ( {message.role === 'assistant' && message.content && (
<Card className="bg-card text-card-foreground border border-muted !mb-8 sm:!mb-16"> <Card className="bg-card text-card-foreground border border-muted !mb-20 sm:!mb-16">
<CardContent className="p-3 sm:p-4"> <CardContent className="p-3 sm:p-4">
<h2 className="text-lg sm:text-xl font-semibold mb-2">Answer</h2> <h2 className="text-lg sm:text-xl font-semibold mb-2">Answer</h2>
<div className="text-sm sm:text-base"> <div className="text-sm sm:text-base">
@ -428,18 +435,16 @@ export default function Home() {
value={input} value={input}
onChange={(e) => setInput(e.target.value)} onChange={(e) => setInput(e.target.value)}
disabled={isLoading} disabled={isLoading}
className="w-full h-10 py-3 px-4 bg-gray-100 rounded-full pr-12 focus:outline-none focus:ring-2 focus:ring-green-500 text-sm" className="w-full min-h-12 py-3 px-4 bg-muted border border-input rounded-full pr-12 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 text-sm sm:text-base"
/> />
<Button <Button
size="icon"
type="submit" type="submit"
variant="ghost" size={'icon'}
disabled={isLoading} variant={'ghost'}
className="absolute right-2 top-1/2 transform -translate-y-1/2 bg-transparent hover:bg-transparent" className="absolute right-2 top-1/2 transform -translate-y-1/2"
disabled={input.length === 0}
> >
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <ArrowRight size={20} />
<path d="M5 12H19M19 12L12 5M19 12L12 19" stroke="#9CA3AF" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
</svg>
</Button> </Button>
</div> </div>
</form> </form>