Add gemini support

This commit is contained in:
Saoud Rizwan
2024-09-12 08:11:33 -04:00
parent caab575b14
commit fbb7620fa1
11 changed files with 384 additions and 61 deletions

57
src/api/gemini.ts Normal file
View File

@@ -0,0 +1,57 @@
import { Anthropic } from "@anthropic-ai/sdk"
import { FunctionCallingMode, GoogleGenerativeAI } from "@google/generative-ai"
import { ApiHandler, ApiHandlerMessageResponse } from "."
import { ApiHandlerOptions, geminiDefaultModelId, GeminiModelId, geminiModels, ModelInfo } from "../shared/api"
import {
convertAnthropicMessageToGemini,
convertAnthropicToolToGemini,
convertGeminiResponseToAnthropic,
} from "../utils/gemini-format"
export class GeminiHandler implements ApiHandler {
private options: ApiHandlerOptions
private client: GoogleGenerativeAI
constructor(options: ApiHandlerOptions) {
if (!options.geminiApiKey) {
throw new Error("API key is required for Google Gemini")
}
this.options = options
this.client = new GoogleGenerativeAI(options.geminiApiKey)
}
async createMessage(
systemPrompt: string,
messages: Anthropic.Messages.MessageParam[],
tools: Anthropic.Messages.Tool[]
): Promise<ApiHandlerMessageResponse> {
const model = this.client.getGenerativeModel({
model: this.getModel().id,
systemInstruction: systemPrompt,
tools: [{ functionDeclarations: tools.map(convertAnthropicToolToGemini) }],
toolConfig: {
functionCallingConfig: {
mode: FunctionCallingMode.AUTO,
},
},
})
const result = await model.generateContent({
contents: messages.map(convertAnthropicMessageToGemini),
generationConfig: {
maxOutputTokens: this.getModel().info.maxTokens,
},
})
const message = convertGeminiResponseToAnthropic(result.response)
return { message }
}
getModel(): { id: GeminiModelId; info: ModelInfo } {
const modelId = this.options.apiModelId
if (modelId && modelId in geminiModels) {
const id = modelId as GeminiModelId
return { id, info: geminiModels[id] }
}
return { id: geminiDefaultModelId, info: geminiModels[geminiDefaultModelId] }
}
}

View File

@@ -6,6 +6,7 @@ import { OpenRouterHandler } from "./openrouter"
import { VertexHandler } from "./vertex"
import { OpenAiHandler } from "./openai"
import { OllamaHandler } from "./ollama"
import { GeminiHandler } from "./gemini"
export interface ApiHandlerMessageResponse {
message: Anthropic.Messages.Message
@@ -37,6 +38,8 @@ export function buildApiHandler(configuration: ApiConfiguration): ApiHandler {
return new OpenAiHandler(options)
case "ollama":
return new OllamaHandler(options)
case "gemini":
return new GeminiHandler(options)
default:
return new AnthropicHandler(options)
}