-
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 #12 from vhpx/main
feat: add basic gemini chat and test cases page
- Loading branch information
Showing
12 changed files
with
6,285 additions
and
0 deletions.
There are no files selected for viewing
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,35 @@ | ||
import { GoogleGenerativeAI } from '@google/generative-ai'; | ||
import { GoogleGenerativeAIStream, Message, StreamingTextResponse } from 'ai'; | ||
|
||
const genAI = new GoogleGenerativeAI(process.env.GOOGLE_API_KEY || ''); | ||
|
||
// IMPORTANT! Set the runtime to edge | ||
export const runtime = 'edge'; | ||
|
||
// convert messages from the Vercel AI SDK Format to the format | ||
// that is expected by the Google GenAI SDK | ||
const buildGoogleGenAIPrompt = (messages: Message[]) => ({ | ||
contents: messages | ||
.filter( | ||
(message) => message.role === 'user' || message.role === 'assistant' | ||
) | ||
.map((message) => ({ | ||
role: message.role === 'user' ? 'user' : 'model', | ||
parts: [{ text: message.content }], | ||
})), | ||
}); | ||
|
||
export async function POST(req: Request) { | ||
// Extract the `prompt` from the body of the request | ||
const { messages } = await req.json(); | ||
|
||
const geminiStream = await genAI | ||
.getGenerativeModel({ model: 'gemini-pro' }) | ||
.generateContentStream(buildGoogleGenAIPrompt(messages)); | ||
|
||
// Convert the response into a friendly text-stream | ||
const stream = GoogleGenerativeAIStream(geminiStream); | ||
|
||
// Respond with the stream | ||
return new StreamingTextResponse(stream); | ||
} |
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,26 @@ | ||
'use client'; | ||
|
||
import { useChat } from 'ai/react'; | ||
|
||
export default function Chat() { | ||
const { messages, input, handleInputChange, handleSubmit } = useChat(); | ||
|
||
return ( | ||
<div> | ||
{messages.map((m) => ( | ||
<div key={m.id}> | ||
{m.role === 'user' ? 'User: ' : 'AI: '} | ||
{m.content} | ||
</div> | ||
))} | ||
|
||
<form onSubmit={handleSubmit}> | ||
<input | ||
value={input} | ||
placeholder="Say something..." | ||
onChange={handleInputChange} | ||
/> | ||
</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,53 @@ | ||
function CollapsedLine({ | ||
line, | ||
open, | ||
index, | ||
handleOpen, | ||
startLine, | ||
}: { | ||
line: string; | ||
open: boolean; | ||
index: number; | ||
handleOpen: () => void; | ||
startLine: number; | ||
}) { | ||
const isHead = index === 0; | ||
return ( | ||
<div | ||
className={`${ | ||
isHead || open ? "" : " hidden " | ||
} w-full flex items-center gap-1 hover:bg-gray-800`} | ||
onClick={() => isHead && handleOpen()} | ||
> | ||
<a className="text-slate-300 underline hover:text-blue-500 cursor-pointer flex justify-end w-6 md:w-8 lg:w-10 shrink-0 self-start"> | ||
{startLine + index} | ||
</a> | ||
{isHead && ( | ||
<svg | ||
className={`flex-shrink-0 ${ | ||
open ? "rotate-90" : "" | ||
} transition-transform`} | ||
viewBox="0 0 16 16" | ||
width="16" | ||
height="16" | ||
aria-hidden="false" | ||
> | ||
<path | ||
className="fill-slate-200" | ||
fill-rule="evenodd" | ||
d="M6.22 3.22a.75.75 0 011.06 0l4.25 4.25a.75.75 0 010 1.06l-4.25 4.25a.75.75 0 01-1.06-1.06L9.94 8 6.22 4.28a.75.75 0 010-1.06z" | ||
></path> | ||
</svg> | ||
)} | ||
<span | ||
className={`${ | ||
isHead ? "cursor-pointer " : "pl-5" | ||
} flex items-center w-full `} | ||
> | ||
{line} | ||
</span> | ||
</div> | ||
); | ||
} | ||
|
||
export default CollapsedLine; |
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,47 @@ | ||
import { useState } from "react"; | ||
import CollapsedLine from "./CollapsedLine"; | ||
|
||
function TestBlock({ | ||
block, | ||
}: { | ||
block: { | ||
collapsed: boolean; | ||
lineContent: string[]; | ||
startLine: number; | ||
}; | ||
}) { | ||
const [open, setOpen] = useState(false); | ||
const handleOpen = () => { | ||
setOpen(!open); | ||
}; | ||
return ( | ||
<> | ||
{block.collapsed ? ( | ||
block.lineContent.map((line, index) => ( | ||
<CollapsedLine | ||
line={line} | ||
open={open} | ||
index={index} | ||
handleOpen={handleOpen} | ||
startLine={block.startLine} | ||
/> | ||
)) | ||
) : ( | ||
<div className="w-full flex gap-1 lg:gap-1.5 hover:bg-gray-800"> | ||
<a className="text-slate-300 underline hover:text-blue-500 cursor-pointer flex justify-end w-6 md:w-8 lg:w-10 shrink-0"> | ||
{block.startLine} | ||
</a> | ||
<span | ||
className={`${ | ||
block.collapsed ? "cursor-pointer" : "" | ||
} flex items-center w-full `} | ||
> | ||
{block.lineContent} | ||
</span> | ||
</div> | ||
)} | ||
</> | ||
); | ||
} | ||
|
||
export default TestBlock; |
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,27 @@ | ||
import TestBlock from "./TestBlock"; | ||
|
||
function TestBody({ | ||
open, | ||
content, | ||
}: { | ||
open: boolean; | ||
content: { | ||
collapsed: boolean; | ||
lineContent: string[]; | ||
startLine: number; | ||
}[]; | ||
}) { | ||
return ( | ||
<div | ||
className={`${ | ||
open ? "" : "hidden" | ||
} w-full h-fit p-1 m-1 mb-3 text-xs lg:text-sm flex flex-col items-center rounded-md text-slate-200`} | ||
> | ||
{content.map((block, index) => ( | ||
<TestBlock block={block} key={index} /> | ||
))} | ||
</div> | ||
); | ||
} | ||
|
||
export default TestBody; |
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,30 @@ | ||
import { useState } from "react"; | ||
import TestHeader from "./TestHeader"; | ||
import TestBody from "./TestBody"; | ||
|
||
function TestComponents({ | ||
testInfo, | ||
}: { | ||
testInfo: { | ||
name: string; | ||
content: { | ||
collapsed: boolean; | ||
lineContent: string[]; | ||
startLine: number; | ||
}[]; | ||
}; | ||
}) { | ||
const [open, setOpen] = useState(false); | ||
const handleOpen = () => { | ||
// alert(open); | ||
setOpen(!open); | ||
}; | ||
return ( | ||
<div className="w-full md:w-4/5 lg:w-3/5 flex flex-col"> | ||
<TestHeader open={open} handleOpen={handleOpen} name={testInfo.name} /> | ||
<TestBody open={open} content={testInfo.content} /> | ||
</div> | ||
); | ||
} | ||
|
||
export default TestComponents; |
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,49 @@ | ||
function TestHeader({ | ||
open, | ||
handleOpen, | ||
name, | ||
}: { | ||
open: boolean; | ||
handleOpen: () => void; | ||
name: string; | ||
}) { | ||
return ( | ||
<div | ||
onClick={() => handleOpen()} | ||
className={`${ | ||
open ? "bg-slate-800" : "" | ||
} w-full h-8 lg:h-9 lg:px-4 text-sm lg:text-base flex gap-1 md:gap-2 lg:gap-3 items-center hover:bg-slate-800 rounded-md transition-all text-slate-200 cursor-pointer`} | ||
> | ||
<svg | ||
className={`flex-shrink-0 ${ | ||
open ? "rotate-90" : "" | ||
} transition-transform`} | ||
viewBox="0 0 16 16" | ||
width="16" | ||
height="16" | ||
aria-hidden="false" | ||
> | ||
<path | ||
className="fill-slate-200" | ||
fill-rule="evenodd" | ||
d="M6.22 3.22a.75.75 0 011.06 0l4.25 4.25a.75.75 0 010 1.06l-4.25 4.25a.75.75 0 01-1.06-1.06L9.94 8 6.22 4.28a.75.75 0 010-1.06z" | ||
></path> | ||
</svg> | ||
<svg | ||
className=" flex-shrink-0 mr-1" | ||
viewBox="0 0 16 16" | ||
width="16" | ||
height="16" | ||
aria-hidden="true" | ||
> | ||
<path | ||
className="fill-slate-200" | ||
d="M8 16A8 8 0 1 1 8 0a8 8 0 0 1 0 16Zm3.78-9.72a.751.751 0 0 0-.018-1.042.751.751 0 0 0-1.042-.018L6.75 9.19 5.28 7.72a.751.751 0 0 0-1.042.018.751.751 0 0 0-.018 1.042l2 2a.75.75 0 0 0 1.06 0Z" | ||
></path> | ||
</svg> | ||
<span className="flex items-center">{name}</span> | ||
</div> | ||
); | ||
} | ||
|
||
export default TestHeader; |
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 @@ | ||
// simulate data from backend | ||
export const data = new Array(10).fill(0).map((_, i) => ({ | ||
name: `Test ${i + 1}`, | ||
content: | ||
[ | ||
{ | ||
collapsed: false, | ||
startLine: 1, | ||
lineContent: "Lorem ipsum", | ||
}, | ||
{ | ||
collapsed: true, | ||
startLine: 2, | ||
lineContent: [ | ||
"dolor sit amet", | ||
"consectetur adipisicing elit.", | ||
"Lorem ipsum dolor sit amet consectetur adipisicing elit.Dolor voluptatibus ea quasi illum pariatur aspernatur.Alias quia mollitia voluptatum modi consequuntur, eveniet Lorem ipsum dolor sit ai consequuntur, eveniet " | ||
] | ||
}, | ||
{ | ||
collapsed: false, | ||
startLine: 5, | ||
lineContent: "Dolor voluptatibus ea quasi illum pariatur aspernatur." | ||
} | ||
] | ||
})); | ||
/* | ||
content: | ||
[ | ||
{ | ||
collapsed: false, | ||
startLine: 1, | ||
lineContent: "Lorem ipsum", | ||
}, | ||
{ | ||
collapsed: true, | ||
startLine: 2, | ||
lineContent: [ | ||
"dolor sit amet", | ||
"consectetur adipisicing elit.", | ||
"Lorem ipsum dolor sit amet consectetur adipisicing elit.Dolor voluptatibus ea quasi illum pariatur aspernatur.Alias quia mollitia voluptatum modi consequuntur, eveniet Lorem ipsum dolor sit amet consectetur adipisicing elit.Dolor voluptatibus ea quasi illum pariatur aspernatur.Alias quia mollitia voluptatum modi consequuntur, eveniet " | ||
] | ||
}, | ||
{ | ||
collapsed: false, | ||
startLine: 5, | ||
lineContent: "Dolor voluptatibus ea quasi illum pariatur aspernatur." | ||
} | ||
] | ||
content: "Lorem ipsum dolor sit amet consectetur adipisicing elit.Dolor voluptatibus ea quasi illum pariatur aspernatur.Alias quia mollitia voluptatum modi consequuntur, eveniet ullam blanditiis maxime cumque iure.Magni sapiente a omnis voluptatibus eos.Placeat dolor necessitatibus ut officiis consequuntur vitae repudiandae, tempore ducimus fuga in, quis accusamus facilis libero.Dolores." | ||
*/ | ||
|
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,19 @@ | ||
"use client"; | ||
|
||
import TestComponent from "./components/TestComponent"; | ||
import { data } from "./data/data"; | ||
|
||
function page() { | ||
return ( | ||
<div className="p-2 md:p-6 flex flex-col gap-2 bg-black w-full h-screen overflow-auto items-center"> | ||
<h1 className="text-xl md:text-2xl flex items-center text-white md:m-2 lg:m-3"> | ||
Test for branch X | ||
</h1> | ||
{data.map((_: any, i) => ( | ||
<TestComponent testInfo={_} /> | ||
))} | ||
</div> | ||
); | ||
} | ||
|
||
export default page; |
Oops, something went wrong.
831fb88
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
genie – ./
genie-vhpx.vercel.app
intelligenie.vercel.app
supagenie.vercel.app
genie.vohoangphuc.com
genie-git-production-vhpx.vercel.app