-
-
Notifications
You must be signed in to change notification settings - Fork 95
feat: support Claude models #22
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
base: main
Are you sure you want to change the base?
Conversation
|
@smakosh is attempting to deploy a commit to the Harsh's projects Team on Vercel. A member of the Team first needs to authorize it. |
WalkthroughA new AI provider, "llmgateway," was integrated into the application, including support for its API keys and two new Claude models. This involved backend and frontend updates for provider selection, API key management, and model configuration. Additionally, dependencies were updated and minor code style and error-handling adjustments were made. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Frontend
participant Backend
participant LLMGateway
User->>Frontend: Selects "Claude 3.7 Sonnet" or "Claude 3.5 Sonnet"
Frontend->>Frontend: Collects llmgateway API key
Frontend->>Backend: Sends chat request with model and API key
Backend->>LLMGateway: Uses API key to call selected Claude model
LLMGateway-->>Backend: Returns AI response
Backend-->>Frontend: Streams response
Frontend-->>User: Displays AI-generated message
Poem
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
frontend/hooks/useMessageSummary.tsOops! Something went wrong! :( ESLint: 9.28.0 ESLint couldn't find the plugin "eslint-plugin-react-hooks". (The package "eslint-plugin-react-hooks" was not found when loaded as a Node module from the directory "".) It's likely that the plugin isn't installed correctly. Try reinstalling by running the following: The plugin "eslint-plugin-react-hooks" was referenced from the config file in " » eslint-config-next/core-web-vitals » /node_modules/.pnpm/eslint-config-next@15.3.2_eslint@9.28.0_jiti@2.4.2__typescript@5.8.3/node_modules/eslint-config-next/index.js". If you still can't figure out the problem, please see https://eslint.org/docs/latest/use/troubleshooting. frontend/components/APIKeyForm.tsxOops! Something went wrong! :( ESLint: 9.28.0 ESLint couldn't find the plugin "eslint-plugin-react-hooks". (The package "eslint-plugin-react-hooks" was not found when loaded as a Node module from the directory "".) It's likely that the plugin isn't installed correctly. Try reinstalling by running the following: The plugin "eslint-plugin-react-hooks" was referenced from the config file in " » eslint-config-next/core-web-vitals » /node_modules/.pnpm/eslint-config-next@15.3.2_eslint@9.28.0_jiti@2.4.2__typescript@5.8.3/node_modules/eslint-config-next/index.js". If you still can't figure out the problem, please see https://eslint.org/docs/latest/use/troubleshooting. app/api/chat/route.tsOops! Something went wrong! :( ESLint: 9.28.0 ESLint couldn't find the plugin "eslint-plugin-react-hooks". (The package "eslint-plugin-react-hooks" was not found when loaded as a Node module from the directory "".) It's likely that the plugin isn't installed correctly. Try reinstalling by running the following: The plugin "eslint-plugin-react-hooks" was referenced from the config file in " » eslint-config-next/core-web-vitals » /node_modules/.pnpm/eslint-config-next@15.3.2_eslint@9.28.0_jiti@2.4.2__typescript@5.8.3/node_modules/eslint-config-next/index.js". If you still can't figure out the problem, please see https://eslint.org/docs/latest/use/troubleshooting.
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
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.
Actionable comments posted: 3
🧹 Nitpick comments (2)
frontend/stores/APIKeyStore.ts (1)
51-53: Consider updating the required keys logic.The
hasRequiredKeysfunction only checks for Google API key. Consider whether LLMGateway should also be considered as a valid alternative for required functionality.hasRequiredKeys: () => { - return !!get().keys.google; + return !!get().keys.google || !!get().keys.llmgateway; },lib/models.ts (1)
23-32: Consider alphabetical ordering for better maintainability.The new Claude models are added at the beginning of the MODEL_CONFIGS object, which breaks the alphabetical ordering that appears to be followed elsewhere.
Consider reordering to maintain alphabetical consistency:
export const MODEL_CONFIGS = { - 'Claude 3.7 Sonnet': { - modelId: 'claude-3-7-sonnet-20250219', - provider: 'llmgateway', - headerKey: 'Authorization', - }, - 'Claude 3.5 Sonnet': { - modelId: 'claude-3-5-sonnet-20241022', - provider: 'llmgateway', - headerKey: 'Authorization', - }, + 'Claude 3.5 Sonnet': { + modelId: 'claude-3-5-sonnet-20241022', + provider: 'llmgateway', + headerKey: 'Authorization', + }, + 'Claude 3.7 Sonnet': { + modelId: 'claude-3-7-sonnet-20250219', + provider: 'llmgateway', + headerKey: 'Authorization', + }, 'Deepseek R1 0528': {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (6)
app/api/chat/route.ts(4 hunks)frontend/components/APIKeyForm.tsx(2 hunks)frontend/hooks/useMessageSummary.ts(1 hunks)frontend/stores/APIKeyStore.ts(2 hunks)lib/models.ts(2 hunks)package.json(1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
app/api/chat/route.ts
[error] 24-24: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 29-29: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 34-34: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 39-39: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
🔇 Additional comments (8)
package.json (1)
12-12:Details
✅ Verification successful
Verify the dependency versions and security advisories.
The new dependencies support the Claude models integration. Ensure these are the latest stable versions and check for any known security vulnerabilities.
Also applies to: 17-17
🏁 Script executed:
#!/bin/bash # Description: Check for latest versions and security advisories for the new dependencies echo "Checking @ai-sdk/anthropic..." npm view @ai-sdk/anthropic version dist-tags npm audit --audit-level high --omit dev @ai-sdk/anthropic echo "Checking @llmgateway/ai-sdk-provider..." npm view @llmgateway/ai-sdk-provider version dist-tags npm audit --audit-level high --omit dev @llmgateway/ai-sdk-providerLength of output: 1294
🏁 Script executed:
#!/bin/bash set -e # Create a temporary project to generate a lockfile and run an audit TEMP_DIR=$(mktemp -d) cat > "$TEMP_DIR/package.json" <<EOF { "name": "temp-audit", "version": "1.0.0", "dependencies": { "@ai-sdk/anthropic": "1.2.12", "@llmgateway/ai-sdk-provider": "1.0.1" } } EOF cd "$TEMP_DIR" # Generate only a lockfile (no actual installs) npm install --package-lock-only # Run audit for high-severity issues (allow non-zero exit to continue) npm audit --audit-level high --omit dev || true # Fetch license information for both packages echo echo "License for @ai-sdk/anthropic:" npm view @ai-sdk/anthropic license echo echo "License for @llmgateway/ai-sdk-provider:" npm view @llmgateway/ai-sdk-provider licenseLength of output: 596
Dependencies verified: latest stable and secure
- @ai-sdk/anthropic@1.2.12 is the current latest release, licensed under Apache-2.0, and yields no high-severity vulnerabilities in an npm audit.
- @llmgateway/ai-sdk-provider@1.0.1 is the current latest release, licensed under Apache-2.0, and yields no high-severity vulnerabilities in an npm audit.
No further action required.
frontend/stores/APIKeyStore.ts (2)
4-4: LGTM: Provider addition follows existing pattern.The addition of 'llmgateway' to the PROVIDERS array is correctly implemented and maintains consistency with the existing codebase.
41-41: LGTM: Consistent state initialization.The llmgateway key is properly initialized in the store state, following the same pattern as other providers.
frontend/components/APIKeyForm.tsx (2)
25-25: LGTM: Form schema properly extended.The llmgateway field is correctly added to the form schema as optional, maintaining consistency with other optional providers.
88-96: LGTM: Well-integrated API key field.The LLMGateway API key field is properly implemented with:
- Correct models listed (Claude 3.7 Sonnet, Claude 3.5 Sonnet)
- Appropriate placeholder following the expected format
- Valid signup link for user registration
- Consistent integration with the existing form pattern
app/api/chat/route.ts (2)
4-4: LGTM: Clean integration of the new provider.The import follows the established pattern and integrates cleanly with the existing provider architecture.
38-42:Details
✅ Verification successful
Verify the llmgateway provider implementation.
The new switch case follows the established pattern correctly. Ensure that the
@llmgateway/ai-sdk-providerpackage is properly installed and that the API key format matches what the provider expects.Run this script to verify the provider integration:
🏁 Script executed:
#!/bin/bash # Description: Verify llmgateway provider is properly configured # Check if the package is installed if [ -f "package.json" ]; then echo "Checking package.json for @llmgateway/ai-sdk-provider..." grep -n "@llmgateway/ai-sdk-provider" package.json || echo "Package not found in package.json" fi # Check for any existing usage patterns or tests echo "Searching for llmgateway usage patterns..." rg -A 3 -B 3 "llmgateway"Length of output: 5521
LLMGateway provider integration verified
@llmgateway/ai-sdk-provideris declared in package.json (v^1.0.1) and locked in pnpm-lock.yaml.- Proper import and instantiation appear in app/api/chat/route.ts.
- Model entries in lib/models.ts use
provider: 'llmgateway'with the correctheaderKey.- API key entry for LLMGateway is defined in APIKeyForm.tsx.
No further action required.
🧰 Tools
🪛 Biome (1.9.4)
[error] 39-39: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
lib/models.ts (1)
10-11: LGTM: Consistent model naming and integration.The new Claude models follow the established naming convention and are properly integrated into the models array.
| const payload: MessageSummaryPayload = await response.json(); | ||
|
|
||
| if (response.ok) { | ||
| const { title, isTitle, messageId, threadId } = payload; | ||
| const { title, isTitle, messageId, threadId } = payload; |
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.
Critical: Restore proper error handling for HTTP responses.
Removing the response.ok check is dangerous as it will attempt to process failed HTTP responses, potentially causing runtime errors when parsing JSON from error responses. This removes important error feedback for users.
onResponse: async (response) => {
try {
+ if (!response.ok) {
+ console.error('Request failed:', response.status, response.statusText);
+ return;
+ }
const payload: MessageSummaryPayload = await response.json();📝 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.
| const payload: MessageSummaryPayload = await response.json(); | |
| if (response.ok) { | |
| const { title, isTitle, messageId, threadId } = payload; | |
| const { title, isTitle, messageId, threadId } = payload; | |
| onResponse: async (response) => { | |
| try { | |
| if (!response.ok) { | |
| console.error('Request failed:', response.status, response.statusText); | |
| return; | |
| } | |
| const payload: MessageSummaryPayload = await response.json(); | |
| const { title, isTitle, messageId, threadId } = payload; | |
| // …rest of your logic… | |
| } catch (error) { | |
| console.error('Unexpected error in onResponse:', error); | |
| throw error; | |
| } | |
| } |
🤖 Prompt for AI Agents
In frontend/hooks/useMessageSummary.ts around lines 22 to 24, the code is
missing a check for response.ok before parsing JSON, which can cause runtime
errors on failed HTTP responses. Add a conditional to verify response.ok is true
before calling response.json(), and handle the error case appropriately by
throwing an error or returning a fallback value to ensure proper error feedback
for users.
| switch (modelConfig.provider) { | ||
| case 'google': | ||
| case "google": | ||
| const google = createGoogleGenerativeAI({ apiKey }); | ||
| aiModel = google(modelConfig.modelId); | ||
| break; | ||
|
|
||
| case 'openai': | ||
| case "openai": | ||
| const openai = createOpenAI({ apiKey }); | ||
| aiModel = openai(modelConfig.modelId); | ||
| break; | ||
|
|
||
| case 'openrouter': | ||
| case "openrouter": | ||
| const openrouter = createOpenRouter({ apiKey }); | ||
| aiModel = openrouter(modelConfig.modelId); | ||
| break; | ||
|
|
||
| case "llmgateway": | ||
| const llmgateway = createLLMGateway({ apiKey }); | ||
| aiModel = llmgateway(modelConfig.modelId); | ||
| break; | ||
|
|
||
| default: | ||
| return new Response( | ||
| JSON.stringify({ error: 'Unsupported model provider' }), | ||
| JSON.stringify({ error: "Unsupported model provider" }), | ||
| { | ||
| status: 400, | ||
| headers: { 'Content-Type': 'application/json' }, | ||
| headers: { "Content-Type": "application/json" }, | ||
| } | ||
| ); | ||
| } |
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.
Fix variable scoping in switch statement.
The static analysis correctly identifies a scoping issue with variable declarations in switch cases. Variables declared in one case can be accessed by other cases, which can lead to unexpected behavior.
Apply this diff to fix the scoping issue by wrapping declarations in blocks:
let aiModel;
switch (modelConfig.provider) {
- case "google":
+ case "google": {
const google = createGoogleGenerativeAI({ apiKey });
aiModel = google(modelConfig.modelId);
break;
+ }
- case "openai":
+ case "openai": {
const openai = createOpenAI({ apiKey });
aiModel = openai(modelConfig.modelId);
break;
+ }
- case "openrouter":
+ case "openrouter": {
const openrouter = createOpenRouter({ apiKey });
aiModel = openrouter(modelConfig.modelId);
break;
+ }
- case "llmgateway":
+ case "llmgateway": {
const llmgateway = createLLMGateway({ apiKey });
aiModel = llmgateway(modelConfig.modelId);
break;
+ }
default:
return new Response(🧰 Tools
🪛 Biome (1.9.4)
[error] 24-24: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 29-29: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 34-34: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
[error] 39-39: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.
The declaration is defined in this switch clause:
Unsafe fix: Wrap the declaration in a block.
(lint/correctness/noSwitchDeclarations)
🤖 Prompt for AI Agents
In app/api/chat/route.ts between lines 22 and 51, the variables declared inside
each switch case are not properly scoped, which can cause them to be accessible
across cases and lead to bugs. To fix this, wrap the code inside each case in
curly braces to create a block scope, ensuring variables like google, openai,
openrouter, and llmgateway are limited to their respective cases.
| 'Claude 3.7 Sonnet': { | ||
| modelId: 'claude-3-7-sonnet-20250219', | ||
| provider: 'llmgateway', | ||
| headerKey: 'Authorization', | ||
| }, | ||
| 'Claude 3.5 Sonnet': { | ||
| modelId: 'claude-3-5-sonnet-20241022', | ||
| provider: 'llmgateway', | ||
| headerKey: 'Authorization', | ||
| }, |
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.
💡 Verification agent
🧩 Analysis chain
Verify Claude model IDs and Authorization header usage.
The model configurations follow the established pattern. However, please verify:
- Model IDs: Ensure
claude-3-7-sonnet-20250219andclaude-3-5-sonnet-20241022are correct and available via the llmgateway provider. - Authorization header: Unlike other providers that use custom headers (e.g.,
X-OpenAI-API-Key), these use the standardAuthorizationheader. Confirm this is the correct format for llmgateway.
🌐 Web query:
What are the correct model IDs for Claude 3.5 Sonnet and Claude 3.7 Sonnet models, and what is the expected API key header format for llmgateway provider?
💡 Result:
The model IDs for Claude 3.5 Sonnet and Claude 3.7 Sonnet are as follows:
- Claude 3.5 Sonnet:
claude-3-5-sonnet-20240620 - Claude 3.7 Sonnet:
claude-3-7-sonnet-20250219
These identifiers are used across various platforms, including Anthropic's API, AWS Bedrock, and Google Cloud's Vertex AI. (docs.anthropic.com)
Regarding the API key header format for the llmgateway provider, specific details are not readily available in the provided sources. Typically, API key headers are included in the request header as Authorization: Bearer YOUR_API_KEY. For precise implementation, please refer to the official documentation of the llmgateway provider or contact their support team for accurate information.
Citations:
Update Claude 3.5 Sonnet model ID and confirm llmgateway Authorization header
- lib/models.ts (lines 23–32):
- The
modelIdfor Claude 3.5 Sonnet should be updated fromclaude-3-5-sonnet-20241022toclaude-3-5-sonnet-20240620. - The
modelIdfor Claude 3.7 Sonnet (claude-3-7-sonnet-20250219) is already correct.
- The
- Please verify that the
llmgatewayprovider indeed uses the standard
Authorization: Bearer YOUR_API_KEY
header (and not a custom header likeX-LLMGateway-API-Key).
Suggested diff:
'Claude 3.7 Sonnet': {
modelId: 'claude-3-7-sonnet-20250219',
provider: 'llmgateway',
headerKey: 'Authorization',
},
- 'Claude 3.5 Sonnet': {
- modelId: 'claude-3-5-sonnet-20241022',
+ 'Claude 3.5 Sonnet': {
+ modelId: 'claude-3-5-sonnet-20240620',
provider: 'llmgateway',
headerKey: 'Authorization',
},📝 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.
| 'Claude 3.7 Sonnet': { | |
| modelId: 'claude-3-7-sonnet-20250219', | |
| provider: 'llmgateway', | |
| headerKey: 'Authorization', | |
| }, | |
| 'Claude 3.5 Sonnet': { | |
| modelId: 'claude-3-5-sonnet-20241022', | |
| provider: 'llmgateway', | |
| headerKey: 'Authorization', | |
| }, | |
| 'Claude 3.7 Sonnet': { | |
| modelId: 'claude-3-7-sonnet-20250219', | |
| provider: 'llmgateway', | |
| headerKey: 'Authorization', | |
| }, | |
| 'Claude 3.5 Sonnet': { | |
| modelId: 'claude-3-5-sonnet-20240620', | |
| provider: 'llmgateway', | |
| headerKey: 'Authorization', | |
| }, |
🤖 Prompt for AI Agents
In lib/models.ts around lines 23 to 32, update the modelId for "Claude 3.5
Sonnet" from "claude-3-5-sonnet-20241022" to "claude-3-5-sonnet-20240620" to
reflect the correct and current model identifier. Confirm with the llmgateway
provider documentation or support that the API key should be sent using the
standard "Authorization" header with the format "Authorization: Bearer
YOUR_API_KEY" rather than a custom header, and adjust the headerKey value
accordingly if needed.
Screen.Recording.2025-06-09.at.7.02.56.PM.mov
Summary by CodeRabbit
New Features
Improvements
Bug Fixes