Skip to content

Commit

Permalink
Merge pull request #194 from Sid-80/gemini-model
Browse files Browse the repository at this point in the history
feat: gemini model
  • Loading branch information
subhadeeproy3902 authored Jun 3, 2024
2 parents 2e412ce + 72feff0 commit c5cb8a1
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 37 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ KINDE_POST_LOGOUT_REDIRECT_URL=http://localhost:3000
KINDE_POST_LOGIN_REDIRECT_URL=http://localhost:3000/dashboard
CONVEX_DEPLOYMENT=dev:perfect-panther-605
NEXT_PUBLIC_CONVEX_URL=https://perfect-panther-605.convex.cloud
NEXT_PUBLIC_GEMINI_API_KEY=your-gemini-api-key
#use these variables only ;)
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"@formspree/react": "^2.5.1",
"@hookform/resolvers": "^3.4.0",
"@kinde-oss/kinde-auth-nextjs": "^2.2.6",
"@langchain/google-genai": "^0.0.16",
"@radix-ui/react-alert-dialog": "^1.0.5",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-dialog": "^1.0.5",
Expand All @@ -42,6 +43,7 @@
"embla-carousel-react": "^8.0.4",
"express": "^4.19.2",
"framer-motion": "^11.1.9",
"langchain": "^0.2.4",
"lucide-react": "^0.378.0",
"moment": "^2.30.1",
"next": "^14.2.3",
Expand Down
102 changes: 65 additions & 37 deletions src/components/shared/AiModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,24 @@ import {
FormLabel,
FormMessage,
} from "@/components/ui/form";
import runChat from "@/config/gemini";
import PromptLoader from "./PromptLoader";

const formSchema = z.object({
prompt: z
.string()
.min(100, {
message: "Description should be atleast 100 characters long",
})
// .min(100, {
// message: "Description should be atleast 100 characters long",
// })
.max(550),
});

export function GenAIModal() {
const [docsCheck, setDocsChecked] = useState<boolean>(false);
const [flowchartCheck, setFlowchartChecked] = useState<boolean>(false);
const [validation, setValidation] = useState("");
const [loading, setLoading] = useState(false);
const [isDialogOpen, setIsDialogOpen] = useState(false);

const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
Expand All @@ -46,16 +51,30 @@ export function GenAIModal() {
},
});

function onSubmit(values: z.infer<typeof formSchema>) {
async function onSubmit(values: z.infer<typeof formSchema>) {
// Do something with the form values.
// ✅ This will be type-safe and validated.
console.log(values);
try {
setLoading(true);
if (!docsCheck && !flowchartCheck) setValidation("Select atleast one!");
else {
const res = await runChat(values.prompt, docsCheck, flowchartCheck);
console.log(res);
if(res){
setLoading(false);
setIsDialogOpen(false);
}
}
} catch (err) {
console.log(err);
}
}

return (
<Dialog>
<Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>
<DialogTrigger asChild>
<Button className="flex gap-2">
<Button className="flex gap-2" onClick={() => setIsDialogOpen(true)}>
<WandSparkles className="w-4 h-4" />
<p className="hidden sm:inline">Generate AI</p>
</Button>
Expand All @@ -82,49 +101,58 @@ export function GenAIModal() {
/>
</FormControl>
<FormDescription className=" text-xs font-semibold text-red-500">
<span className="font-bold">Note : </span>
Give detailed description of your problem statement
<span className="font-bold">Note : </span>
Give detailed description of your problem statement
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<div className="flex items-center space-x-2">
<Checkbox
checked={docsCheck}
onCheckedChange={() => setDocsChecked(!docsCheck)}
id="docs"
/>
<label
htmlFor="docs"
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
Generate Documentation
</label>
</div>
<div className="flex flex-col gap-4">
<div className="flex items-center space-x-2">
<Checkbox
checked={docsCheck}
onCheckedChange={() => setDocsChecked(!docsCheck)}
id="docs"
/>
<label
htmlFor="docs"
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
Generate Documentation
</label>
</div>

<div className="flex items-center space-x-2">
<Checkbox
checked={flowchartCheck}
onCheckedChange={() => setFlowchartChecked(!flowchartCheck)}
id="flowchart"
/>
<label
htmlFor="flowchart"
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
Generate Flowchart
</label>
</div>

<div className="flex items-center space-x-2">
<Checkbox
checked={flowchartCheck}
onCheckedChange={() => setFlowchartChecked(!flowchartCheck)}
id="flowchart"
/>
<label
htmlFor="flowchart"
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
Generate Flowchart
</label>
<p className="text-xs font-semibold text-red-500">{validation}</p>
</div>

<DialogFooter>
<Button className="flex gap-2" type="submit">
<p>
Generate
</p>
<Send className="w-[14px] h-[14px]" /> </Button>
<p>Generate</p>
<Send className="w-[14px] h-[14px]" />{" "}
</Button>
</DialogFooter>
</form>
</Form>
{loading && (
<div className="backdrop-blur-sm absolute flex item-center justify-center w-full h-full top-0 left-0">
<PromptLoader />
</div>
)}
</DialogContent>
</Dialog>
);
Expand Down
48 changes: 48 additions & 0 deletions src/components/shared/PromptLoader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { motion } from 'framer-motion'

export default function PromptLoader() {
return (
<div className="flex items-center justify-center">
<div className="flex space-x-2">
<motion.div
className="h-3 w-3 rounded-full bg-red-500"
animate={{
scale: [1, 1.5, 1],
opacity: [0.5, 1, 0.5],
}}
transition={{
duration: 1,
ease: 'easeInOut',
repeat: Infinity,
}}
/>
<motion.div
className="h-3 w-3 rounded-full bg-red-500"
animate={{
scale: [1, 1.5, 1],
opacity: [0.5, 1, 0.5],
}}
transition={{
duration: 1,
ease: 'easeInOut',
repeat: Infinity,
delay: 0.3,
}}
/>
<motion.div
className="h-3 w-3 rounded-full bg-red-500"
animate={{
scale: [1, 1.5, 1],
opacity: [0.5, 1, 0.5],
}}
transition={{
duration: 1,
ease: 'easeInOut',
repeat: Infinity,
delay: 0.6,
}}
/>
</div>
</div>
)
}
58 changes: 58 additions & 0 deletions src/config/gemini.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { GoogleGenerativeAI } from "@google/generative-ai";

const MODEL_NAME = "gemini-1.0-pro";
const API_KEY = process.env.NEXT_PUBLIC_GEMINI_API_KEY;

async function runChat(
prompt: string,
generateDocs: boolean,
generateFlowchart: boolean
) {
if (!API_KEY || API_KEY === "your-gemini-api-key")
throw new Error("Invalid Api Key!");

const genAI = new GoogleGenerativeAI(API_KEY);
const model = genAI.getGenerativeModel({ model: MODEL_NAME });

model.generationConfig = {
temperature: 0.9,
topK: 1,
topP: 1,
};

const chat = model.startChat({
history: [
{
role: "user",
parts: [
{
text: `You are expert in generating documentation and flowcharts. While generating documentation add detailed working of given prompt and generate the flowcharts in mermaid code format. Generate the flowchart in the mermaid code format.`,
},
],
},
{
role: "model",
parts: [{ text: "How can I help you ?" }],
},
],
});

let newPrompt;

if (generateDocs && generateFlowchart) {
newPrompt = `Generate documentation as well as flowchart for following problem statement. Problem Statement : ${prompt}`;
} else if (generateDocs) {
newPrompt = `Generate documentation for following problem statement. Problem Statement : ${prompt}`;
} else if (generateFlowchart) {
newPrompt = `Generate flowchart for following problem statement. Problem Statement : ${prompt}`;
}

if(!generateDocs && !generateFlowchart) throw new Error("No options selected!");

const result = await chat.sendMessage(newPrompt!);
const response = result.response;
console.log(response.text());
return response.text();
}

export default runChat;

0 comments on commit c5cb8a1

Please sign in to comment.