| 110 | }; |
| 111 | |
| 112 | export class LobeGoogleAI implements LobeRuntimeAI { |
| 113 | private client: GoogleGenAI; |
| 114 | private isVertexAi: boolean; |
| 115 | baseURL?: string; |
| 116 | apiKey?: string; |
| 117 | provider: string; |
| 118 | private readonly modelIdMappingOptions: ModelIdMappingOptions; |
| 119 | |
| 120 | constructor({ |
| 121 | apiKey, |
| 122 | baseURL, |
| 123 | client, |
| 124 | isVertexAi, |
| 125 | id, |
| 126 | defaultHeaders, |
| 127 | modelIdMapping, |
| 128 | }: LobeGoogleAIParams = {}) { |
| 129 | if (!apiKey) throw AgentRuntimeError.createError(AgentRuntimeErrorType.InvalidProviderAPIKey); |
| 130 | |
| 131 | const httpOptions = baseURL |
| 132 | ? ({ baseUrl: baseURL, headers: defaultHeaders } as HttpOptions) |
| 133 | : undefined; |
| 134 | |
| 135 | this.apiKey = apiKey; |
| 136 | this.client = client ?? new GoogleGenAI({ apiKey, httpOptions }); |
| 137 | this.baseURL = client ? undefined : baseURL || DEFAULT_BASE_URL; |
| 138 | this.isVertexAi = isVertexAi || false; |
| 139 | this.modelIdMappingOptions = { modelIdMapping }; |
| 140 | |
| 141 | this.provider = id || (isVertexAi ? 'vertexai' : 'google'); |
| 142 | } |
| 143 | |
| 144 | async chat(rawPayload: ChatStreamPayload, options?: ChatMethodOptions) { |
| 145 | try { |
| 146 | const payload = this.buildPayload(rawPayload); |
| 147 | const { model, thinkingBudget, thinkingLevel, imageAspectRatio, imageResolution } = payload; |
| 148 | |
| 149 | // https://ai.google.dev/gemini-api/docs/thinking#set-budget |
| 150 | const thinkingConfig = resolveGoogleThinkingConfig(model, { |
| 151 | thinkingBudget, |
| 152 | thinkingLevel, |
| 153 | }) as ThinkingConfig; |
| 154 | |
| 155 | const contents = await buildGoogleMessages(payload.messages, { model }); |
| 156 | const isImageResponseModel = isGoogleImageResponseModel(model); |
| 157 | |
| 158 | const controller = new AbortController(); |
| 159 | const originalSignal = options?.signal; |
| 160 | |
| 161 | if (originalSignal) { |
| 162 | if (originalSignal.aborted) { |
| 163 | controller.abort(); |
| 164 | } else { |
| 165 | originalSignal.addEventListener('abort', () => { |
| 166 | controller.abort(); |
| 167 | }); |
| 168 | } |
| 169 | } |
nothing calls this directly
no outgoing calls
no test coverage detected