From ad3d1c7a8fd845a0e2c2bf442bcadb25a7ba67b0 Mon Sep 17 00:00:00 2001 From: Stan Ke <156306548@qq.com> Date: Thu, 12 Sep 2024 17:19:18 +0800 Subject: [PATCH] multiModels support and add cluade handling --- app/api/chat/cluade/route.ts | 52 ++++ app/api/chat/google/route.ts | 110 ++++---- app/api/chat/google/test.ts | 105 ++++++++ app/api/chat/openai/route.ts | 25 +- app/api/chat/route.ts | 34 +++ config/server.ts | 3 + lib/ModelSetting.ts | 493 ++++++++++++++--------------------- package-lock.json | 47 ++++ package.json | 1 + 9 files changed, 496 insertions(+), 374 deletions(-) create mode 100644 app/api/chat/cluade/route.ts create mode 100644 app/api/chat/google/test.ts create mode 100644 app/api/chat/route.ts diff --git a/app/api/chat/cluade/route.ts b/app/api/chat/cluade/route.ts new file mode 100644 index 0000000..dd50da8 --- /dev/null +++ b/app/api/chat/cluade/route.ts @@ -0,0 +1,52 @@ +import { getServerConfig } from "@/config/server"; +import { ServerRuntime } from "next"; +import Anthropic from '@anthropic-ai/sdk'; + +export const runtime: ServerRuntime = "edge"; + +export async function POST(request: Request) { + const encoder = new TextEncoder(); + const stream = new TransformStream(); + const writer = stream.writable.getWriter(); + + try { + const config = await getServerConfig(); + const { message, model } = await request.json(); + + if (!config.anthropicApiKey) { + throw new Error('ANTHROPIC_API_KEY is not set'); + } + + const anthropic = new Anthropic({ + apiKey: config.anthropicApiKey, + }); + + const stream = await anthropic.completions.create({ + model: model || "claude-2", + max_tokens_to_sample: 300, + prompt: `Human: ${message}\n\nAssistant:`, + stream: true, + }); + + for await (const completion of stream) { + await writer.write( + encoder.encode(`data: ${JSON.stringify({ text: completion.completion })}\n\n`) + ); + } + } catch (error: any) { + console.error('Error in Claude chat:', error); + await writer.write( + encoder.encode(`data: ${JSON.stringify({ error: error.message })}\n\n`) + ); + } finally { + await writer.close(); + } + + return new Response(stream.readable, { + headers: { + 'Content-Type': 'text/event-stream', + 'Cache-Control': 'no-cache', + 'Connection': 'keep-alive', + }, + }); +} \ No newline at end of file diff --git a/app/api/chat/google/route.ts b/app/api/chat/google/route.ts index be68e48..bed8335 100644 --- a/app/api/chat/google/route.ts +++ b/app/api/chat/google/route.ts @@ -1,67 +1,55 @@ import { getServerConfig } from "@/config/server"; import { GoogleGenerativeAI, HarmCategory, HarmBlockThreshold } from "@google/generative-ai"; +export const runtime = 'edge'; export async function POST(req: Request) { - try { - // Fetch server configuration - const config = await getServerConfig(); - - // Initialize Google Generative AI with the provided credentials - const genAI = new GoogleGenerativeAI(config.geminiKey); - const modelG = genAI.getGenerativeModel({ model: "gemini-pro" }); - - // Define the generation configuration - const generationConfig = { - temperature: 0.8, - topK: 0.9, - topP: 1, - maxOutputTokens: 2048, - }; - - // Define the safety settings for content filtering - const safetySettings = [ - { - category: HarmCategory.HARM_CATEGORY_HARASSMENT, - threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE, - }, - { - category: HarmCategory.HARM_CATEGORY_HATE_SPEECH, - threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE, - }, - { - category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT, - threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE, - }, - { - category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, - threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE, - }, - ]; - - // Start a chat session with the generative AI model - const chat = modelG.startChat({ - generationConfig, - safetySettings, // Pass safety settings if needed - }); - - // Extract messages from the request - const { messages } = await req.json(); - - // Send the message to the model and await the response - const result = await chat.sendMessage(messages); - const response = await result.response; - - return new Response(JSON.stringify(response), { - status: 200, - }); - } catch (error: any) { - const errorMessage = error.message || "An unexpected error occurred"; - const errorCode = error.status || 500; - console.error(error); - - return new Response(JSON.stringify({ message: errorMessage }), { - status: errorCode, - }); - } + const encoder = new TextEncoder(); + const stream = new TransformStream(); + const writer = stream.writable.getWriter(); + + try { + const config = await getServerConfig(); + const { message, model } = await req.json(); + + const genAI = new GoogleGenerativeAI(config.geminiKey); + const modelG = genAI.getGenerativeModel({ model: model || "gemini-1.5-flash" }); + + const chat = modelG.startChat({ + generationConfig: { + temperature: 0.8, + topK: 0.9, + topP: 1, + maxOutputTokens: 2048, + }, + safetySettings: [ + { + category: HarmCategory.HARM_CATEGORY_HARASSMENT, + threshold: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE, + }, + // ... other safety settings ... + ], + }); + + const result = await chat.sendMessage(message); + const response = await result.response; + + // Stream the response + for (const chunk of response.text().split(' ')) { + await writer.write(encoder.encode(`data: ${JSON.stringify({ text: chunk + ' ' })}\n\n`)); + } + } catch (error: any) { + console.error('Error in Google AI chat:', error); + await writer.write(encoder.encode(`data: ${JSON.stringify({ error: error.message })}\n\n`)); + } finally { + await writer.close(); + } + + return new Response(stream.readable, { + headers: { + 'Content-Type': 'text/event-stream', + 'Cache-Control': 'no-cache', + 'Connection': 'keep-alive', + }, + }); } diff --git a/app/api/chat/google/test.ts b/app/api/chat/google/test.ts new file mode 100644 index 0000000..f91a81d --- /dev/null +++ b/app/api/chat/google/test.ts @@ -0,0 +1,105 @@ +/** + * @license + * This file is licensed under the Apache License 2.0. + * See the LICENSE file for more details. + */ + +import { GoogleGenerativeAI } from "@google/generative-ai"; +import fs from "fs"; +import { dirname } from "path"; +import { fileURLToPath } from "url"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const mediaPath = __dirname + "/media"; + +async function chat() { + // [START chat] + // Make sure to include these imports: + // import { GoogleGenerativeAI } from "@google/generative-ai"; + const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY); + const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" }); + const chat = model.startChat({ + history: [ + { + role: "user", + parts: [{ text: "Hello" }], + }, + { + role: "model", + parts: [{ text: "Great to meet you. What would you like to know?" }], + }, + ], + }); + let result = await chat.sendMessage("I have 2 dogs in my house."); + console.log(result.response.text()); + result = await chat.sendMessage("How many paws are in my house?"); + console.log(result.response.text()); + // [END chat] +} + +async function chatStreaming() { + // [START chat_streaming] + // Make sure to include these imports: + // import { GoogleGenerativeAI } from "@google/generative-ai"; + const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY); + const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" }); + const chat = model.startChat({ + history: [ + { + role: "user", + parts: [{ text: "Hello" }], + }, + { + role: "model", + parts: [{ text: "Great to meet you. What would you like to know?" }], + }, + ], + }); + let result = await chat.sendMessageStream("I have 2 dogs in my house."); + for await (const chunk of result.stream) { + const chunkText = chunk.text(); + process.stdout.write(chunkText); + } + result = await chat.sendMessageStream("How many paws are in my house?"); + for await (const chunk of result.stream) { + const chunkText = chunk.text(); + process.stdout.write(chunkText); + } + // [END chat_streaming] +} + +async function chatStreamingWithImages() { + // [START chat_streaming_with_images] + // Make sure to include these imports: + // import { GoogleGenerativeAI } from "@google/generative-ai"; + const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY); + const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" }); + const chat = model.startChat(); + + let result = await chat.sendMessageStream("Hello, I'm designing inventions. Can I show you one?"); + process.stdout.write('\n\nmodel:\n'); + for await (const chunk of result.stream) { + const chunkText = chunk.text(); + process.stdout.write(chunkText); + } + result = await chat.sendMessageStream(["What do you think about this design?", { + inlineData: { + data: Buffer.from(fs.readFileSync(`${mediaPath}/jetpack.jpg`)).toString("base64"), + mimeType: "image/jpeg", + }, + }]); + process.stdout.write('\n\nmodel:\n'); + for await (const chunk of result.stream) { + const chunkText = chunk.text(); + process.stdout.write(chunkText); + } + // [END chat_streaming_with_images] +} + +// async function runAll() { +// await chat(); +// await chatStreaming(); +// await chatStreamingWithImages(); +// } + +// runAll(); \ No newline at end of file diff --git a/app/api/chat/openai/route.ts b/app/api/chat/openai/route.ts index 55a7f3e..407837c 100644 --- a/app/api/chat/openai/route.ts +++ b/app/api/chat/openai/route.ts @@ -1,45 +1,34 @@ import { getServerConfig } from "@/config/server"; import { ServerRuntime } from "next"; import OpenAI from "openai"; - +import { OpenAIStream, StreamingTextResponse } from 'ai'; export const runtime: ServerRuntime = "edge"; export async function POST(request: Request) { try { const config = await getServerConfig(); + const { message, model } = await request.json(); const openai = new OpenAI({ apiKey: config.openaiApiKey, baseURL: config.openaiBaseUrl || config.openaiProxyUrl, }); - console.log(openai.baseURL); - console.log(openai.apiKey); const response = await openai.chat.completions.create( { - model: "gpt-3.5-turbo", - messages: [{ role: "user", content: "Say this is a test" }], + model: model || "gpt-4o-mini", + messages: [{ role: "user", content: message }], stream: true, - }, - { - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${openai.apiKey}`, - }, } ); - - for await (const chunk of response) { - console.log(chunk.choices[0].delta); - process.stdout.write(chunk.choices[0]?.delta?.content || ""); - } - return ; + const stream = OpenAIStream(response); + return new StreamingTextResponse(stream); } catch (error: any) { const errorMessage = error.error?.message || "An unexpected error occurred"; const errorCode = error.status || 500; - console.log(error); + console.error(error); return new Response(JSON.stringify({ message: errorMessage }), { status: errorCode, diff --git a/app/api/chat/route.ts b/app/api/chat/route.ts new file mode 100644 index 0000000..c13c053 --- /dev/null +++ b/app/api/chat/route.ts @@ -0,0 +1,34 @@ +// app/api/chat/route.ts +import { NextRequest, NextResponse } from 'next/server'; +import { AIServiceFactory } from '@/lib/ai/AIServiceFactory'; +import { ModelProviderConfig } from '@/lib/ModelSetting'; +import { verifyJWT } from '@/lib/auth'; // Assuming you have a JWT verification function + +export const runtime = 'edge'; + +export async function POST(req: NextRequest) { + try { + const { message, model, token } = await req.json(); + const payload = await verifyJWT(token); // Verify and decode JWT + + const config: ModelProviderConfig = { + modelProvider: model.split('-')[0] as 'openai' | 'gemini' | 'claude' | /* other providers */, + model: model, + // ... other config options + }; + + const service = await AIServiceFactory.createService(config, payload); + const stream = await service.generateResponse(message); + + return new NextResponse(stream, { + headers: { + 'Content-Type': 'text/event-stream', + 'Cache-Control': 'no-cache', + 'Connection': 'keep-alive', + }, + }); + } catch (error: any) { + console.error('Error in chat API:', error); + return NextResponse.json({ error: error.message }, { status: 500 }); + } +} \ No newline at end of file diff --git a/config/server.ts b/config/server.ts index 580382b..066e65a 100644 --- a/config/server.ts +++ b/config/server.ts @@ -16,6 +16,7 @@ declare global { NEXT_PUBLIC_AZURE_GPT_35_TURBO_ID: string; NEXT_PUBLIC_AZURE_GPT_45_VISION_ID: string; NEXT_PUBLIC_AZURE_GPT_45_TURBO_ID: string; + ANTHROPIC_API_KEY: string; } } } @@ -40,6 +41,7 @@ declare global { NEXT_PUBLIC_AZURE_GPT_35_TURBO_ID, NEXT_PUBLIC_AZURE_GPT_45_VISION_ID, NEXT_PUBLIC_AZURE_GPT_45_TURBO_ID, + ANTHROPIC_API_KEY, } = process.env; return { @@ -57,6 +59,7 @@ declare global { azureGpt35TurboId: NEXT_PUBLIC_AZURE_GPT_35_TURBO_ID, azureGpt45VisionId: NEXT_PUBLIC_AZURE_GPT_45_VISION_ID, azureGpt45TurboId: NEXT_PUBLIC_AZURE_GPT_45_TURBO_ID, + anthropicApiKey: ANTHROPIC_API_KEY, }; }; // const express = require("express"); diff --git a/lib/ModelSetting.ts b/lib/ModelSetting.ts index 65095d1..d4130da 100644 --- a/lib/ModelSetting.ts +++ b/lib/ModelSetting.ts @@ -1,75 +1,204 @@ -/** - * LLM 模型 - */ -export enum LanguageModel { - GPT3_5 = "gpt-3.5-turbo", - GPT3_5_1106 = "gpt-3.5-turbo-1106", - GPT3_5_16K = "gpt-3.5-turbo-16k", - /** - * GPT 4 - */ - GPT4 = "gpt-4", - GPT4_32K = "gpt-4-32k", - GPT4_PREVIEW = "gpt-4-0125-preview", - GPT4_VISION_PREVIEW = "gpt-4-vision-preview", -} - -export interface ChatModelCard { +export interface ModelProviderConfig { + modelProvider: "openai" | "gemini" | "claude"; + model: string; + //optional description?: string; - displayName?: string; - files?: boolean; - functionCall?: boolean; - hidden?: boolean; - id: string; - isCustom?: boolean; - /** - * whether model is legacy (deprecated but not removed yet) - */ - legacy?: boolean; - tokens?: number; - vision?: boolean; + temperature?: number; + maxTokens?: number; + topP?: number; + frequencyPenalty?: number;//It is a value that is added to the log-probability of a token each time it occurs in the generated text. A higher frequency_penalty value will result in the model being more conservative in its use of repeated tokens. + presencePenalty?: number;//This parameter is used to encourage the model to include a diverse range of tokens in the generated text. It is a value that is subtracted from the log-probability of a token each time it is generated. A higher presence_penalty value will result in the model being more likely to generate tokens that have not yet been included in the generated text. + stop?: string[]; + stream?: boolean; } -const Mistral: ModelProviderCard = { - chatModels: [ - { - displayName: 'Mistral 7B', - id: 'open-mistral-7b', - tokens: 32_768, - }, - { - displayName: 'Mixtral 8x7B', - id: 'open-mixtral-8x7b', - tokens: 32_768, - }, - { - displayName: 'Mixtral 8x22B', - functionCall: true, - id: 'open-mixtral-8x22b', - tokens: 65_536, - }, - { - displayName: 'Mistral Small', - id: 'mistral-small-latest', - tokens: 32_768, - }, - { - displayName: 'Mistral Medium', - id: 'mistral-medium-latest', - }, - { - displayName: 'Mistral Large', - id: 'mistral-large-latest', - }, - ], - id: 'mistral', -}; -export interface ModelProviderCard { - chatModels: ChatModelCard[]; - enabled?: boolean; - id: string; - token?: number; -} +export const openaiConfig: ModelProviderConfig[] = [ + // OpenAI Models + { + modelProvider: "openai", + model: "gpt-4", + description: "Most capable GPT-4 model, better at following instructions", + temperature: 0.7, + maxTokens: 8000, + topP: 1, + frequencyPenalty: 0, + presencePenalty: 0 + }, + { + modelProvider: "openai", + model: "gpt-4o-2024-05-13", + description: "Current version that gpt-4o points to.", + temperature: 0.7, + maxTokens: 4096, + }, + { + modelProvider: "openai", + model: "gpt-4o-2024-08-06", + description: "Latest snapshot that supports Structured Outputs", + temperature: 0.7, + maxTokens: 16384, + }, + { + modelProvider: "openai", + model: "chatgpt-4o-latest", + description: "Dynamic model continuously updated to the current version of GPT-4o in ChatGPT. For research and evaluation.", + temperature: 0.8, + maxTokens: 16384, + topP: 0.95, + }, + { + modelProvider: "openai", + model: "gpt-4o-mini", + description: "Affordable and intelligent small model for fast, lightweight tasks. Cheaper and more capable than GPT-3.5 Turbo.", + temperature: 0.7, + maxTokens: 16384, + }, + { + modelProvider: "openai", + model: "gpt-4o-mini-2024-07-18", + description: "Current version that gpt-4o-mini points to.", + temperature: 0.7, + maxTokens: 16384, + }, + { + modelProvider: "openai", + model: "gpt-4-32k", + description: "Same capabilities as standard GPT-4 with 4x the context length", + maxTokens: 32000, + temperature: 0.5 + }, + { + modelProvider: "openai", + model: "gpt-3.5-turbo", + description: "Most capable GPT-3.5 model, optimized for chat at 1/10th the cost of text-davinci-003", + temperature: 0.9, + maxTokens: 4000, + stream: true + }, + { + modelProvider: "openai", + model: "gpt-4o", + description: "Preview version of GPT-4 with improved capabilities", + temperature: 0.8, + maxTokens: 16384, + topP: 0.9 + }, +] +export const geminiConfig: ModelProviderConfig[] = [ + // Gemini Models + { + modelProvider: "gemini", + model: "gemini-pro", + description: "Gemini's largest model for text generation tasks", + temperature: 0.8, + maxTokens: 8192, + topP: 0.95 + }, + { + modelProvider: "gemini", + model: "gemini-pro-vision", + description: "Multimodal model capable of understanding text and images", + temperature: 0.7, + maxTokens: 4096 + }, + { + modelProvider: "gemini", + model: "gemini-1.5-flash", + description: "Gemini 1.5 Flash: Ultra-fast model with 1,048,576,000 input token limit. Supports system instructions, JSON mode, JSON schema, adjustable safety settings, caching, fine-tuning, and function calling.", + temperature: 0.7, + maxTokens: 8192, + topP: 1, + }, + { + modelProvider: "gemini", + model: "gemini-1.5-pro", + description: "Gemini 1.5 Pro: Advanced model with 1,048,576,000 input token limit. Supports system instructions, JSON mode, JSON schema, adjustable safety settings, caching, fine-tuning, and function calling.", + temperature: 0.7, + maxTokens: 8192, + topP: 1, + }, + { + modelProvider: "gemini", + model: "gemini-1.0-pro", + description: "Gemini 1.0 Pro: Original pro model. Supports up to 3,600 images per prompt, 1 hour of video, and 9.5 hours of audio. Features system instructions, JSON mode, JSON schema, adjustable safety settings, caching, fine-tuning, and function calling.", + temperature: 0.7, + maxTokens: 8192, + topP: 1, + } +] + export const cluadeConfig: ModelProviderConfig[] = [ + // Claude Models + { + modelProvider: "claude", + model: "claude-2.1", + description: "Latest version of Claude with improved capabilities", + temperature: 0.7, + maxTokens: 100000, + topP: 0.9 + }, + { + modelProvider: "claude", + model: "claude-instant-1.2", + description: "Faster and more cost-effective version of Claude", + temperature: 0.8, + maxTokens: 10000, + stop: ["\n\nHuman:", "\n\nAssistant:"] + }, + { + modelProvider: "claude", + model: "claude-3.0", + description: "Fictional next-generation Claude model with advanced capabilities", + temperature: 0.6, + maxTokens: 200000, + topP: 0.95, + frequencyPenalty: 0.1, + presencePenalty: 0.1 + }, + { + modelProvider: "claude", + model: "claude-3-5-sonnet-20240620", + description: "Most intelligent model for highly complex tasks.", + temperature: 0.7, + maxTokens: 8192, + topP: 0.9, + frequencyPenalty: 0.2, + presencePenalty: 0.2, + stream: true + }, + { + modelProvider: "claude", + model: "claude-3-opus-20240229", + description: "Powerful model for highly complex tasks with top-level intelligence.", + temperature: 0.75, + maxTokens: 4096, + topP: 0.85, + frequencyPenalty: 0.3, + presencePenalty: 0.3, + stream: true + }, + { + modelProvider: "claude", + model: "claude-3-sonnet-20240229", + description: "Strong utility, balanced for scaled deployments.", + temperature: 0.7, + maxTokens: 4096, + topP: 0.9, + frequencyPenalty: 0.2, + presencePenalty: 0.2, + stream: true + }, + { + modelProvider: "claude", + model: "claude-3-haiku-20240307", + description: "Fastest and most compact model for near-instant responsiveness.", + temperature: 0.6, + maxTokens: 4096, + topP: 0.95, + frequencyPenalty: 0.1, + presencePenalty: 0.1, + stream: false + } +]; // 语言模型的设置参数 export interface LLMParams { @@ -208,229 +337,3 @@ export interface ChatCompletionFunctions { [key: string]: any; }; } - -type ChatSettingLimits = { - MIN_TEMPERATURE: number - MAX_TEMPERATURE: number - MAX_TOKEN_OUTPUT_LENGTH: number - MAX_CONTEXT_LENGTH: number -} - -export const CHAT_SETTING_LIMITS= { - // ANTHROPIC MODELS - "claude-2.1": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 4096, - MAX_CONTEXT_LENGTH: 200000 - }, - "claude-instant-1.2": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 4096, - MAX_CONTEXT_LENGTH: 100000 - }, - "claude-3-haiku-20240307": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 4096, - MAX_CONTEXT_LENGTH: 200000 - }, - "claude-3-sonnet-20240229": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 4096, - MAX_CONTEXT_LENGTH: 200000 - }, - "claude-3-opus-20240229": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 4096, - MAX_CONTEXT_LENGTH: 200000 - }, - - // GOOGLE MODELS - "gemini-1.5-pro-latest": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 8192, - MAX_CONTEXT_LENGTH: 1040384 - }, - "gemini-pro": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 2048, - MAX_CONTEXT_LENGTH: 30720 - }, - "gemini-pro-vision": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 4096, - MAX_CONTEXT_LENGTH: 12288 - }, - - // MISTRAL MODELS - "mistral-tiny": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 2000, - MAX_CONTEXT_LENGTH: 8000 - }, - "mistral-small-latest": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 2000, - MAX_CONTEXT_LENGTH: 32000 - }, - "mistral-medium-latest": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 2000, - MAX_CONTEXT_LENGTH: 32000 - }, - "mistral-large-latest": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 2000, - MAX_CONTEXT_LENGTH: 32000 - }, - - // GROQ MODELS - "llama3-8b-8192": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 8192, - MAX_CONTEXT_LENGTH: 8192 - }, - "llama3-70b-8192": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 8192, - MAX_CONTEXT_LENGTH: 8192 - }, - "mixtral-8x7b-32768": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 4096, - MAX_CONTEXT_LENGTH: 32768 - }, - "gemma-7b-it": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 2.0, - MAX_TOKEN_OUTPUT_LENGTH: 8192, - MAX_CONTEXT_LENGTH: 8192 - }, - - // OPENAI MODELS - "gpt-3.5-turbo": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 2.0, - MAX_TOKEN_OUTPUT_LENGTH: 4096, - MAX_CONTEXT_LENGTH: 4096 - // MAX_CONTEXT_LENGTH: 16385 (TODO: Change this back to 16385 when OpenAI bumps the model) - }, - "gpt-4-turbo-preview": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 2.0, - MAX_TOKEN_OUTPUT_LENGTH: 4096, - MAX_CONTEXT_LENGTH: 128000 - }, - "gpt-4-vision-preview": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 2.0, - MAX_TOKEN_OUTPUT_LENGTH: 4096, - MAX_CONTEXT_LENGTH: 128000 - }, - "gpt-4": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 2.0, - MAX_TOKEN_OUTPUT_LENGTH: 4096, - MAX_CONTEXT_LENGTH: 8192 - }, - "gpt-4o": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 2.0, - MAX_TOKEN_OUTPUT_LENGTH: 4096, - MAX_CONTEXT_LENGTH: 128000 - }, - - // PERPLEXITY MODELS - "pplx-7b-online": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.99, - MAX_TOKEN_OUTPUT_LENGTH: 4096, - MAX_CONTEXT_LENGTH: 4096 - }, - "pplx-70b-online": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.99, - MAX_TOKEN_OUTPUT_LENGTH: 4096, - MAX_CONTEXT_LENGTH: 4096 - }, - "pplx-7b-chat": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 4096, - MAX_CONTEXT_LENGTH: 8192 - }, - "pplx-70b-chat": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 4096, - MAX_CONTEXT_LENGTH: 4096 - }, - "mixtral-8x7b-instruct": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 16384, - MAX_CONTEXT_LENGTH: 16384 - }, - "mistral-7b-instruct": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 16384, - MAX_CONTEXT_LENGTH: 16384 - }, - "llama-2-70b-chat": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 2.0, - MAX_TOKEN_OUTPUT_LENGTH: 4096, - MAX_CONTEXT_LENGTH: 4096 - }, - "codellama-34b-instruct": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 4096, - MAX_CONTEXT_LENGTH: 16384 - }, - "codellama-70b-instruct": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 16384, - MAX_CONTEXT_LENGTH: 16384 - }, - "sonar-small-chat": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 16384, - MAX_CONTEXT_LENGTH: 16384 - }, - "sonar-small-online": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 12000, - MAX_CONTEXT_LENGTH: 12000 - }, - "sonar-medium-chat": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 16384, - MAX_CONTEXT_LENGTH: 16384 - }, - "sonar-medium-online": { - MIN_TEMPERATURE: 0.0, - MAX_TEMPERATURE: 1.0, - MAX_TOKEN_OUTPUT_LENGTH: 12000, - MAX_CONTEXT_LENGTH: 12000 - } -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 496886e..e360290 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "tonychat", "version": "0.1.1", "dependencies": { + "@anthropic-ai/sdk": "^0.27.3", "@google/generative-ai": "^0.17.0", "@supabase/supabase-js": "^2.45.3", "ai": "^2.2.35", @@ -64,6 +65,28 @@ "node": ">=6.0.0" } }, + "node_modules/@anthropic-ai/sdk": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@anthropic-ai/sdk/-/sdk-0.27.3.tgz", + "integrity": "sha512-IjLt0gd3L4jlOfilxVXTifn42FnVffMgDC04RJK1KDZpmkBWLv0XC92MVVmkxrFZNS/7l3xWgP/I3nqtX1sQHw==", + "dependencies": { + "@types/node": "^18.11.18", + "@types/node-fetch": "^2.6.4", + "abort-controller": "^3.0.0", + "agentkeepalive": "^4.2.1", + "form-data-encoder": "1.7.2", + "formdata-node": "^4.3.2", + "node-fetch": "^2.6.7" + } + }, + "node_modules/@anthropic-ai/sdk/node_modules/@types/node": { + "version": "18.19.50", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.19.50.tgz", + "integrity": "sha512-xonK+NRrMBRtkL1hVCc3G+uXtjh1Al4opBLjqVmipe5ZAaBYWW6cNAiBVZ1BvmkBhep698rP3UM3aRAdSALuhg==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/@babel/parser": { "version": "7.23.9", "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.23.9.tgz", @@ -5151,6 +5174,30 @@ "@jridgewell/trace-mapping": "^0.3.9" } }, + "@anthropic-ai/sdk": { + "version": "0.27.3", + "resolved": "https://registry.npmmirror.com/@anthropic-ai/sdk/-/sdk-0.27.3.tgz", + "integrity": "sha512-IjLt0gd3L4jlOfilxVXTifn42FnVffMgDC04RJK1KDZpmkBWLv0XC92MVVmkxrFZNS/7l3xWgP/I3nqtX1sQHw==", + "requires": { + "@types/node": "^18.11.18", + "@types/node-fetch": "^2.6.4", + "abort-controller": "^3.0.0", + "agentkeepalive": "^4.2.1", + "form-data-encoder": "1.7.2", + "formdata-node": "^4.3.2", + "node-fetch": "^2.6.7" + }, + "dependencies": { + "@types/node": { + "version": "18.19.50", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.19.50.tgz", + "integrity": "sha512-xonK+NRrMBRtkL1hVCc3G+uXtjh1Al4opBLjqVmipe5ZAaBYWW6cNAiBVZ1BvmkBhep698rP3UM3aRAdSALuhg==", + "requires": { + "undici-types": "~5.26.4" + } + } + } + }, "@babel/parser": { "version": "7.23.9", "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.23.9.tgz", diff --git a/package.json b/package.json index 5915764..cd94862 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "lint": "next lint" }, "dependencies": { + "@anthropic-ai/sdk": "^0.27.3", "@google/generative-ai": "^0.17.0", "@supabase/supabase-js": "^2.45.3", "ai": "^2.2.35",