Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GEMINI SETUP, BETTER ERROR HANDLING AND COMPLETE CHANGE OF CHAT INTERFACE UI #38

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
DATABASE_URL=
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=
CLERK_SECRET_KEY=
GEMINI_API_KEY=
NEXT_PUBLIC_UMAMI_WEBSITE_ID
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
21 changes: 21 additions & 0 deletions components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "src/app/globals.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}
21,053 changes: 13,785 additions & 7,268 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@
},
"dependencies": {
"@clerk/nextjs": "^5.2.4",
"@google/generative-ai": "^0.21.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Security vulnerabilities detected in DOMPurify dependency

Critical and high severity vulnerabilities have been found in DOMPurify. The current version 3.2.2 is affected by:

  • CRITICAL: Prototype pollution vulnerability (affects < 2.4.2)
  • HIGH: Nesting-based mXSS vulnerability (affects >= 3.0.0, < 3.1.3)
  • HIGH: Prototype pollution vulnerability (affects >= 3.0.0, < 3.1.3)

Action required:

  • Upgrade DOMPurify to version >= 3.1.3 to address these security issues
  • Update @types/dompurify to match the new DOMPurify version

Other dependencies (@google/generative-ai and html-react-parser) are at their latest versions and have no known vulnerabilities.

🔗 Analysis chain

Verify compatibility of new dependencies

Please ensure the versions of new dependencies are compatible:

  • @google/generative-ai@0.21.0
  • @types/dompurify@3.0.5
  • dompurify@3.2.2
  • html-react-parser@5.1.18

Also applies to: 28-28, 35-35, 40-40

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for compatibility issues and security advisories

# Check for known vulnerabilities in new dependencies
gh api graphql -f query='
{
  securityVulnerabilities(first: 5, ecosystem: NPM, package: "dompurify") {
    nodes {
      advisory {
        summary
        severity
        publishedAt
      }
      vulnerableVersionRange
    }
  }
}'

# Check latest versions
for pkg in "@google/generative-ai" "@types/dompurify" "dompurify" "html-react-parser"; do
  echo "Checking $pkg..."
  npm view $pkg version
done

Length of output: 1907

"@heroicons/react": "^2.1.5",
"@mdx-js/loader": "^3.0.1",
"@mdx-js/react": "^3.0.1",
@@ -23,16 +24,20 @@
"@radix-ui/react-dropdown-menu": "^2.1.1",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-tabs": "^1.1.0",
"@radix-ui/react-toast": "^1.2.2",
Copy link
Contributor

@coderabbitai coderabbitai bot Nov 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider consolidating toast libraries

The PR adds both @radix-ui/react-toast and sonner for toast notifications. While both are excellent libraries, using two different toast libraries might lead to inconsistent user experiences and unnecessary bundle size increase. Consider standardizing on one solution.

Also applies to: 50-50

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Rahulsoni9321 check this pls let's just keep @radix-ui/react-toast

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

"@types/dompurify": "^3.0.5",
"@types/mdx": "^2.0.13",
"@vercel/analytics": "^1.3.1",
"@vercel/speed-insights": "^1.0.12",
"axios": "^1.7.4",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"dompurify": "^3.2.2",
"framer-motion": "^10.18.0",
"geist": "^1.3.1",
"gray-matter": "^4.0.3",
"highlight.js": "^11.10.0",
"html-react-parser": "^5.1.18",
"lucide-react": "^0.416.0",
"mermaid": "^11.0.2",
"next": "^14.2.13",
@@ -45,8 +50,10 @@
"react-intersection-observer": "^9.13.1",
"react-type-animation": "^3.2.0",
"rehype-highlight": "^7.0.0",
"sonner": "^1.7.0",
"tailwind-merge": "^2.4.0",
"tailwindcss-animate": "^1.0.7",
"ui": "github:shadcn/ui",
Copy link
Contributor

@coderabbitai coderabbitai bot Nov 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Version pin the shadcn/ui dependency

Using a direct GitHub repository reference without version pinning ("ui": "github:shadcn/ui") can lead to reproducibility issues. Consider:

  1. Pinning to a specific commit hash
  2. Using a released version if available

Apply this change:

-    "ui": "github:shadcn/ui",
+    "ui": "github:shadcn/ui#<specific-commit-hash>",

Committable suggestion skipped: line range outside the PR's diff.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Rahulsoni9321 check this one as well

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

"vaul": "^0.9.1"
},
"devDependencies": {
77 changes: 46 additions & 31 deletions src/app/api/summarize/route.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,54 @@
import { NextResponse } from 'next/server';
import axios from 'axios';

const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
const ANTHROPIC_API_URL = 'https://api.anthropic.com/v1/messages';

import { GoogleGenerativeAI, GoogleGenerativeAIError } from "@google/generative-ai";
import { NextResponse } from "next/server";


const GEMINI_API_KEY = process.env.GEMINI_API_KEY;

Copy link
Contributor

@coderabbitai coderabbitai bot Nov 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add validation for GEMINI_API_KEY

The API key is used without validation. If the environment variable is missing, this could lead to runtime errors.

-const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
+if (!GEMINI_API_KEY) {
+  throw new Error('GEMINI_API_KEY environment variable is not set');
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
if (!GEMINI_API_KEY) {
throw new Error('GEMINI_API_KEY environment variable is not set');
}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Rahulsoni9321 pls check all the suggestions raised by @coderabbitai

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tyaga001, I've reviewed the code and noticed that the GEMINI_API_KEY environment variable is already being validated, which addresses the issue.


If you found this review helpful, would you consider giving us a shout-out on X?
Thank you for using CodeRabbit!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Rahulsoni9321 pls check all the suggestions raised by @coderabbitai

@tyaga001 made all the suggested changes by @coderabbitai and open a new pr (#49), Please have a look and let me know if changes needed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Rahulsoni9321, thank you for addressing the suggestions and opening PR #49. Let me know if you need any further assistance.

if (!GEMINI_API_KEY) {
throw new Error("Something went wrong while fetching API Keys.")
}
const genAI = new GoogleGenerativeAI(GEMINI_API_KEY!);
const model = genAI.getGenerativeModel({
model: "gemini-1.5-flash",
systemInstruction: "You're an AI assistant, Who only answers questions related to the blog post that have provided to you in the prompt.\n\nTry to Answer using numeric points for readability and Bold the title of the point. \n\n If the user wants help related to the topic mentioned in the blog you can answer that.\n\n If the question is not related to the blog post or the topic that is mentioned on the blog, Throw error response."
},

);

export async function POST(request: Request) {

const { content, query } = await request.json();

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add input validation for request body

The content and query are destructured without validation. Missing or invalid input could cause unexpected behavior.

-const { content, query } = await request.json();
+const body = await request.json();
+
+if (!body.content || typeof body.content !== 'string' || !body.query || typeof body.query !== 'string') {
+  return NextResponse.json(
+    { error: 'Invalid request: content and query are required and must be strings', success: false },
+    { status: 400 }
+  );
+}
+
+const { content, query } = body;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const { content, query } = await request.json();
const body = await request.json();
if (!body.content || typeof body.content !== 'string' || !body.query || typeof body.query !== 'string') {
return NextResponse.json(
{ error: 'Invalid request: content and query are required and must be strings', success: false },
{ status: 400 }
);
}
const { content, query } = body;

try {
const { content, query } = await request.json();

if (!ANTHROPIC_API_KEY) {
throw new Error('ANTHROPIC_API_KEY is not set');
}

const response = await axios.post(ANTHROPIC_API_URL, {
model: "claude-3-sonnet-20240229",
messages: [
{ role: "system", content: "You are an AI assistant that answers questions about blog posts." },
{ role: "human", content: `Here's a blog post:\n\n${content}\n\nQuestion: ${query}` }
],
max_tokens: 1000,
}, {
headers: {
'Content-Type': 'application/json',
'x-api-key': ANTHROPIC_API_KEY,
'anthropic-version': '2023-06-01'
},
const prompt = `Here's a blog post:\n\n${content}\n\nQuestion: ${query}`;

const result = await model.generateContent(prompt);
return NextResponse.json({
answer: result.response.text(),
success: true
})
}
Comment on lines +28 to +31
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Success field is inconsistently used across API endpoints

The success field is only used in the summarize API endpoint but not in other API endpoints (comments, views). This inconsistency could lead to confusion in frontend error handling. Other endpoints simply return the data or an error object with appropriate HTTP status codes, which is a more standard REST API pattern.

  • src/app/api/summarize/route.ts: Uses success: true/false
  • src/app/api/comments/route.ts: Returns data directly or error with status code
  • src/app/api/views/[slug]/route.ts: Returns data directly or error with status code
🔗 Analysis chain

Verify success response structure

The response structure includes a success field as mentioned in the PR objectives. However, let's verify this is consistently used across the frontend.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for usage of the success field in frontend components
rg -l "success.*true|success.*false" --type ts --type tsx

Length of output: 87


Script:

#!/bin/bash
# Search for usage of the success field in frontend components and API responses
# Using ripgrep without file type restrictions since .tsx extension wasn't recognized
rg -l "success.*true|success.*false" 

Length of output: 69


Script:

#!/bin/bash
# Search for API response handling in components
rg -A 5 "NextResponse.json" 

Length of output: 3037


Script:

#!/bin/bash
# Look for other API route handlers to check response consistency
fd "route.ts" --exec cat {}

Length of output: 3656

catch (error: any) {
const isGoogleAIError = error instanceof GoogleGenerativeAIError;

console.error('API Error:', {
type: isGoogleAIError ? 'GoogleGenerativeAI' : 'Unknown',
message: error.message,
timestamp: new Date().toISOString()
});

const answer = response.data.content[0].text;
return NextResponse.json({ answer });
} catch (error: any) {
console.error('Error in API:', error.response?.data || error.message);
return NextResponse.json(
{ error: 'Error processing request. Please try again.' },
{ status: error.response?.status || 500 }
);
const clientMessage = isGoogleAIError
? 'The AI service is temporarily unavailable. Please try again later.'
: 'Internal Server Error. Please try again after some time.';

return NextResponse.json(
{
error: clientMessage,
success: false
},
{ status: isGoogleAIError ? 503 : 500 }
);
}
}
13 changes: 13 additions & 0 deletions src/app/globals.css
Original file line number Diff line number Diff line change
@@ -87,3 +87,16 @@ html {
background-color: #333;
margin: 40px 0;
}


.ChatArea::-webkit-scrollbar {
width: 6px ;
border-radius: 4px;
background-color: #6e6b6b;
}

.ChatArea::-webkit-scrollbar-thumb {

background-color: white;
border-radius: 4px;
}
55 changes: 30 additions & 25 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -9,6 +9,8 @@ import './globals.css';
import 'highlight.js/styles/github-dark.css';
import { Metadata } from 'next';
import Script from 'next/script'
import { Toaster } from '@/components/ui/toaster';


export const metadata: Metadata = {
title: {
@@ -58,31 +60,34 @@ export default function RootLayout({ children }: RootLayoutProps) {

return (
<html lang="en" suppressHydrationWarning>
<head>
<SocialMetadata
title={title}
description={metadata.description ?? 'Learn about awesome developer tools'}
url={metadata.metadataBase?.toString() ?? 'https://devtoolsacademy.com'}
image={`${metadata.metadataBase?.toString() ?? 'https://devtoolsacademy.com'}/favicon.png`}
type="website"
/>
<Script
src="https://cloud.umami.is/script.js"
data-website-id={process.env.NEXT_PUBLIC_UMAMI_WEBSITE_ID}
strategy="afterInteractive"
/>
</head>
<body className={`${GeistSans.variable} ${GeistMono.variable} font-sans antialiased`}>
<ClerkProvider>
<div className="flex flex-col min-h-screen">
<Navbar />
<main className="flex-grow container mx-auto px-4 sm:px-6 lg:px-8 py-8">
{children}
</main>
</div>
</ClerkProvider>
<Analytics />
</body>
<head>
<SocialMetadata
title={title}
description={metadata.description ?? 'Learn about awesome developer tools'}
url={metadata.metadataBase?.toString() ?? 'https://devtoolsacademy.com'}
image={`${metadata.metadataBase?.toString() ?? 'https://devtoolsacademy.com'}/favicon.png`}
type="website"
/>

<Script
src="https://cloud.umami.is/script.js"
data-website-id={process.env.NEXT_PUBLIC_UMAMI_WEBSITE_ID}
strategy="afterInteractive"
/>
</head>
<body className={`${GeistSans.variable} ${GeistMono.variable} font-sans antialiased`}>
<ClerkProvider>
<div className="flex flex-col min-h-screen">
<Navbar />
<main className="flex-grow container mx-auto px-4 sm:px-6 lg:px-8 ">
{children}
</main>

<Toaster></Toaster>
</div>
</ClerkProvider>
<Analytics />
</body>
</html>
);
}
Loading