@aigne/gemini 1.74.0-beta.10 → 1.74.0-beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,6 @@ let _aigne_uuid = require("@aigne/uuid");
7
7
  let _google_genai = require("@google/genai");
8
8
  let yaml = require("yaml");
9
9
  let zod = require("zod");
10
- let zod_to_json_schema = require("zod-to-json-schema");
11
10
 
12
11
  //#region src/gemini-chat-model.ts
13
12
  const GEMINI_DEFAULT_CHAT_MODEL = "gemini-2.0-flash";
@@ -246,7 +245,7 @@ var GeminiChatModel = class extends _aigne_model_base.ChatModel {
246
245
  type: "json_schema",
247
246
  jsonSchema: {
248
247
  name: "output",
249
- schema: (0, zod_to_json_schema.zodToJsonSchema)(outputSchema)
248
+ schema: zod.z.toJSONSchema(outputSchema)
250
249
  }
251
250
  }
252
251
  }, options));
@@ -1 +1 @@
1
- {"version":3,"file":"gemini-chat-model.d.cts","names":[],"sources":["../src/gemini-chat-model.ts"],"mappings":";;;;;UAoDiB,sBAAA,SAA+B,gBAAA;;AAAhD;;;;EAME,MAAA;EAN8C;;;EAW9C,aAAA,GAAgB,OAAA,CAAQ,kBAAA;AAAA;;;;;;AAc1B;;;;;;cAAa,eAAA,SAAwB,SAAA;EACP,OAAA,GAAU,sBAAA;cAAV,OAAA,GAAU,sBAAA;EAAA,UAO5B,aAAA;EAAA,UAEA,aAAA,GAAgB,WAAA;EAAA,IAEtB,YAAA,CAAA,GAAY,WAAA;EAAA,IAkBH,UAAA,CAAA;;;;MAaT,YAAA,CAAA,GAAY,qBAAA;EAID,WAAA,CAAY,KAAA,EAAO,cAAA,GAAiB,OAAA;EAAA,QAwB3C,qBAAA;EAeC,OAAA,CACP,KAAA,EAAO,cAAA,EACP,OAAA,EAAS,kBAAA,GACR,cAAA,CAAe,kBAAA,CAAmB,eAAA;EAAA,UAK3B,sBAAA;;;;;;;;;;;;;;;;;;;YAmCA,sBAAA;;;;;;YAOA,gBAAA;;;;;;YAOA,iBAAA,CACR,KAAA,UACA,MAAA,EAAQ,qBAAA;IACL,OAAA;IAAkB,MAAA;IAAiB,KAAA,GAAQ,aAAA;EAAA;EAAA,QA4BlC,aAAA;EAAA,QAgCC,YAAA;EAAA,QAgLD,WAAA;EAAA,QAiCA,UAAA;EAAA,QAiCA,sBAAA;EAAA,QAwCA,aAAA;EAAA,QA2GA,cAAA;EAAA,QAyBN,4BAAA;AAAA"}
1
+ {"version":3,"file":"gemini-chat-model.d.cts","names":[],"sources":["../src/gemini-chat-model.ts"],"mappings":";;;;;UAmDiB,sBAAA,SAA+B,gBAAA;;AAAhD;;;;EAME,MAAA;EAN8C;;;EAW9C,aAAA,GAAgB,OAAA,CAAQ,kBAAA;AAAA;;;;;;AAc1B;;;;;;cAAa,eAAA,SAAwB,SAAA;EACP,OAAA,GAAU,sBAAA;cAAV,OAAA,GAAU,sBAAA;EAAA,UAO5B,aAAA;EAAA,UAEA,aAAA,GAAgB,WAAA;EAAA,IAEtB,YAAA,CAAA,GAAY,WAAA;EAAA,IAkBH,UAAA,CAAA;;;;MAaT,YAAA,CAAA,GAAY,qBAAA;EAID,WAAA,CAAY,KAAA,EAAO,cAAA,GAAiB,OAAA;EAAA,QAwB3C,qBAAA;EAeC,OAAA,CACP,KAAA,EAAO,cAAA,EACP,OAAA,EAAS,kBAAA,GACR,cAAA,CAAe,kBAAA,CAAmB,eAAA;EAAA,UAK3B,sBAAA;;;;;;;;;;;;;;;;;;;YAmCA,sBAAA;;;;;;YAOA,gBAAA;;;;;;YAOA,iBAAA,CACR,KAAA,UACA,MAAA,EAAQ,qBAAA;IACL,OAAA;IAAkB,MAAA;IAAiB,KAAA,GAAQ,aAAA;EAAA;EAAA,QA4BlC,aAAA;EAAA,QAgCC,YAAA;EAAA,QAgLD,WAAA;EAAA,QAiCA,UAAA;EAAA,QAiCA,sBAAA;EAAA,QAwCA,aAAA;EAAA,QA2GA,cAAA;EAAA,QAyBN,4BAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"gemini-chat-model.d.mts","names":[],"sources":["../src/gemini-chat-model.ts"],"mappings":";;;;;UAoDiB,sBAAA,SAA+B,gBAAA;;AAAhD;;;;EAME,MAAA;EAN8C;;;EAW9C,aAAA,GAAgB,OAAA,CAAQ,kBAAA;AAAA;;;;;;AAc1B;;;;;;cAAa,eAAA,SAAwB,SAAA;EACP,OAAA,GAAU,sBAAA;cAAV,OAAA,GAAU,sBAAA;EAAA,UAO5B,aAAA;EAAA,UAEA,aAAA,GAAgB,WAAA;EAAA,IAEtB,YAAA,CAAA,GAAY,WAAA;EAAA,IAkBH,UAAA,CAAA;;;;MAaT,YAAA,CAAA,GAAY,qBAAA;EAID,WAAA,CAAY,KAAA,EAAO,cAAA,GAAiB,OAAA;EAAA,QAwB3C,qBAAA;EAeC,OAAA,CACP,KAAA,EAAO,cAAA,EACP,OAAA,EAAS,kBAAA,GACR,cAAA,CAAe,kBAAA,CAAmB,eAAA;EAAA,UAK3B,sBAAA;;;;;;;;;;;;;;;;;;;YAmCA,sBAAA;;;;;;YAOA,gBAAA;;;;;;YAOA,iBAAA,CACR,KAAA,UACA,MAAA,EAAQ,qBAAA;IACL,OAAA;IAAkB,MAAA;IAAiB,KAAA,GAAQ,aAAA;EAAA;EAAA,QA4BlC,aAAA;EAAA,QAgCC,YAAA;EAAA,QAgLD,WAAA;EAAA,QAiCA,UAAA;EAAA,QAiCA,sBAAA;EAAA,QAwCA,aAAA;EAAA,QA2GA,cAAA;EAAA,QAyBN,4BAAA;AAAA"}
1
+ {"version":3,"file":"gemini-chat-model.d.mts","names":[],"sources":["../src/gemini-chat-model.ts"],"mappings":";;;;;UAmDiB,sBAAA,SAA+B,gBAAA;;AAAhD;;;;EAME,MAAA;EAN8C;;;EAW9C,aAAA,GAAgB,OAAA,CAAQ,kBAAA;AAAA;;;;;;AAc1B;;;;;;cAAa,eAAA,SAAwB,SAAA;EACP,OAAA,GAAU,sBAAA;cAAV,OAAA,GAAU,sBAAA;EAAA,UAO5B,aAAA;EAAA,UAEA,aAAA,GAAgB,WAAA;EAAA,IAEtB,YAAA,CAAA,GAAY,WAAA;EAAA,IAkBH,UAAA,CAAA;;;;MAaT,YAAA,CAAA,GAAY,qBAAA;EAID,WAAA,CAAY,KAAA,EAAO,cAAA,GAAiB,OAAA;EAAA,QAwB3C,qBAAA;EAeC,OAAA,CACP,KAAA,EAAO,cAAA,EACP,OAAA,EAAS,kBAAA,GACR,cAAA,CAAe,kBAAA,CAAmB,eAAA;EAAA,UAK3B,sBAAA;;;;;;;;;;;;;;;;;;;YAmCA,sBAAA;;;;;;YAOA,gBAAA;;;;;;YAOA,iBAAA,CACR,KAAA,UACA,MAAA,EAAQ,qBAAA;IACL,OAAA;IAAkB,MAAA;IAAiB,KAAA,GAAQ,aAAA;EAAA;EAAA,QA4BlC,aAAA;EAAA,QAgCC,YAAA;EAAA,QAgLD,WAAA;EAAA,QAiCA,UAAA;EAAA,QAiCA,sBAAA;EAAA,QAwCA,aAAA;EAAA,QA2GA,cAAA;EAAA,QAyBN,4BAAA;AAAA"}
@@ -7,7 +7,6 @@ import { v7 } from "@aigne/uuid";
7
7
  import { FunctionCallingConfigMode, GoogleGenAI, ThinkingLevel, createPartFromUri, createUserContent } from "@google/genai";
8
8
  import { parse } from "yaml";
9
9
  import { z } from "zod";
10
- import { zodToJsonSchema } from "zod-to-json-schema";
11
10
 
12
11
  //#region src/gemini-chat-model.ts
13
12
  const GEMINI_DEFAULT_CHAT_MODEL = "gemini-2.0-flash";
@@ -246,7 +245,7 @@ var GeminiChatModel = class extends ChatModel {
246
245
  type: "json_schema",
247
246
  jsonSchema: {
248
247
  name: "output",
249
- schema: zodToJsonSchema(outputSchema)
248
+ schema: z.toJSONSchema(outputSchema)
250
249
  }
251
250
  }
252
251
  }, options));
@@ -1 +1 @@
1
- {"version":3,"file":"gemini-chat-model.mjs","names":[],"sources":["../src/gemini-chat-model.ts"],"sourcesContent":["import {\n ChatModel,\n type ChatModelInput,\n type ChatModelInputMessageContent,\n type ChatModelInputOptions,\n type ChatModelOptions,\n type ChatModelOutput,\n type ChatModelOutputToolCall,\n type ChatModelOutputUsage,\n type FileUnionContent,\n type ModelInvokeOptions,\n type ModelProcessAsyncGenerator,\n type ModelProcessResult,\n modelProcessResultToObject,\n StructuredOutputError,\n safeParseJSON,\n} from \"@aigne/model-base\";\nimport { logger } from \"@aigne/model-base/utils/logger\";\nimport { mergeUsage } from \"@aigne/model-base/utils/model-utils\";\nimport { nodejs } from \"@aigne/model-base/utils/nodejs\";\nimport {\n isNil,\n isNonNullable,\n isRecord,\n type PromiseOrValue,\n} from \"@aigne/model-base/utils/type-utils\";\nimport { v7 } from \"@aigne/uuid\";\nimport {\n type Content,\n type ContentUnion,\n createPartFromUri,\n createUserContent,\n type FunctionCallingConfig,\n FunctionCallingConfigMode,\n type FunctionResponse,\n type GenerateContentConfig,\n type GenerateContentParameters,\n GoogleGenAI,\n type GoogleGenAIOptions,\n type Part,\n ThinkingLevel,\n type ToolListUnion,\n} from \"@google/genai\";\nimport { parse } from \"yaml\";\nimport { z } from \"zod\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\n\nconst GEMINI_DEFAULT_CHAT_MODEL = \"gemini-2.0-flash\";\n\nconst OUTPUT_FUNCTION_NAME = \"output\";\nconst NEED_UPLOAD_MAX_FILE_SIZE_MB = 20;\n\nexport interface GeminiChatModelOptions extends ChatModelOptions {\n /**\n * API key for Gemini API\n *\n * If not provided, will look for GEMINI_API_KEY or GOOGLE_API_KEY in environment variables\n */\n apiKey?: string;\n\n /**\n * Optional client options for the Gemini SDK\n */\n clientOptions?: Partial<GoogleGenAIOptions>;\n}\n\n/**\n * Implementation of the ChatModel interface for Google's Gemini API\n *\n * @example\n * Here's how to create and use a Gemini chat model:\n * {@includeCode ../test/gemini-chat-model.test.ts#example-gemini-chat-model}\n *\n * @example\n * Here's an example with streaming response:\n * {@includeCode ../test/gemini-chat-model.test.ts#example-gemini-chat-model-streaming}\n */\nexport class GeminiChatModel extends ChatModel {\n constructor(public override options?: GeminiChatModelOptions) {\n super({\n ...options,\n model: options?.model || GEMINI_DEFAULT_CHAT_MODEL,\n });\n }\n\n protected apiKeyEnvName = \"GEMINI_API_KEY\";\n\n protected _googleClient?: GoogleGenAI;\n\n get googleClient() {\n if (this._googleClient) return this._googleClient;\n\n const { apiKey } = this.credential;\n\n if (!apiKey)\n throw new Error(\n `${this.name} requires an API key. Please provide it via \\`options.apiKey\\`, or set the \\`${this.apiKeyEnvName}\\` environment variable`,\n );\n\n this._googleClient ??= new GoogleGenAI({\n apiKey,\n ...this.options?.clientOptions,\n });\n\n return this._googleClient;\n }\n\n override get credential() {\n const apiKey =\n this.options?.apiKey ||\n process.env[this.apiKeyEnvName] ||\n process.env.GEMINI_API_KEY ||\n process.env.GOOGLE_API_KEY;\n\n return {\n apiKey,\n model: this.options?.model || GEMINI_DEFAULT_CHAT_MODEL,\n };\n }\n\n get modelOptions() {\n return this.options?.modelOptions;\n }\n\n override async countTokens(input: ChatModelInput): Promise<number> {\n const { model, ...request } = await this.getParameters(input);\n\n const contents: Content[] = [];\n\n const { systemInstruction, tools } = request.config ?? {};\n\n if (systemInstruction) contents.push(this.contentUnionToContent(systemInstruction));\n if (tools?.length) contents.push({ role: \"system\", parts: [{ text: JSON.stringify(tools) }] });\n\n contents.push(...[request.contents].flat().map(this.contentUnionToContent));\n\n const tokens = (\n await this.googleClient.models.countTokens({\n model,\n contents,\n })\n ).totalTokens;\n\n if (!isNil(tokens)) return tokens;\n\n return super.countTokens(input);\n }\n\n private contentUnionToContent(content: ContentUnion): Content {\n if (typeof content === \"object\" && \"parts\" in content) {\n return { role: \"system\", parts: content.parts };\n } else if (typeof content === \"string\") {\n return { role: \"system\", parts: [{ text: content }] };\n } else if (Array.isArray(content)) {\n return {\n role: \"system\",\n parts: content.map((i) => (typeof i === \"string\" ? { text: i } : i)),\n };\n } else {\n return { role: \"system\", parts: [content as Part] };\n }\n }\n\n override process(\n input: ChatModelInput,\n options: ModelInvokeOptions,\n ): PromiseOrValue<ModelProcessResult<ChatModelOutput>> {\n return this.processInput(input, options);\n }\n\n // References: https://ai.google.dev/gemini-api/docs/thinking#set-budget\n protected thinkingBudgetModelMap = [\n // 注意:gemini-2.5-flash-image-preview 模型并不支持 thinking。see: https://github.com/CherryHQ/cherry-studio/issues/9614\n {\n pattern: /gemini-2.5-flash-image-preview/,\n support: false,\n },\n {\n pattern: /gemini-3(?!.*-image-)/,\n support: true,\n type: \"level\",\n },\n {\n pattern: /gemini-2.5-pro/,\n support: true,\n min: 128,\n max: 32768,\n },\n {\n pattern: /gemini-2.5-flash/,\n support: true,\n min: 0,\n max: 24576,\n },\n {\n pattern: /2.5-flash-lite/,\n support: true,\n min: 512,\n max: 24576,\n },\n {\n pattern: /.*/,\n support: false,\n },\n ];\n\n protected thinkingBudgetLevelMap = {\n high: 100000, // use 100k for high, finally capped by model max\n medium: 10000,\n low: 5000,\n minimal: 200,\n };\n\n protected thinkingLevelMap = {\n high: ThinkingLevel.HIGH,\n medium: ThinkingLevel.HIGH,\n low: ThinkingLevel.LOW,\n minimal: ThinkingLevel.LOW,\n };\n\n protected getThinkingBudget(\n model: string,\n effort: ChatModelInputOptions[\"reasoningEffort\"],\n ): { support: boolean; budget?: number; level?: ThinkingLevel } {\n const m = this.thinkingBudgetModelMap.find((i) => i.pattern.test(model));\n\n if (!m?.support) return { support: false };\n\n if (m.type === \"level\") {\n let level = ThinkingLevel.THINKING_LEVEL_UNSPECIFIED;\n\n if (typeof effort === \"string\") {\n level = this.thinkingLevelMap[effort];\n } else if (typeof effort === \"number\") {\n level =\n effort >= this.thinkingBudgetLevelMap[\"medium\"] ? ThinkingLevel.HIGH : ThinkingLevel.LOW;\n }\n\n return { support: true, level };\n }\n\n let budget =\n typeof effort === \"string\" ? this.thinkingBudgetLevelMap[effort] || undefined : effort;\n if (typeof budget === \"undefined\") return { support: true };\n\n if (typeof m.min === \"number\") budget = Math.max(m.min, budget);\n if (typeof m.max === \"number\") budget = Math.min(m.max, budget);\n\n return { support: true, budget };\n }\n\n private async getParameters(input: ChatModelInput): Promise<GenerateContentParameters> {\n const { modelOptions = {} } = input;\n\n const model = modelOptions.model || this.credential.model;\n const { contents, config } = await this.buildContents(input);\n\n const thinkingBudget = this.getThinkingBudget(model, modelOptions.reasoningEffort);\n\n const parameters: GenerateContentParameters = {\n model,\n contents,\n config: {\n thinkingConfig: thinkingBudget.support\n ? {\n includeThoughts: true,\n thinkingBudget: thinkingBudget.budget,\n thinkingLevel: thinkingBudget.level,\n }\n : undefined,\n responseModalities: modelOptions.modalities,\n temperature: modelOptions.temperature,\n topP: modelOptions.topP,\n frequencyPenalty: modelOptions.frequencyPenalty,\n presencePenalty: modelOptions.presencePenalty,\n ...config,\n ...(await this.buildConfig(input)),\n },\n };\n\n return parameters;\n }\n\n private async *processInput(\n input: ChatModelInput,\n options: ModelInvokeOptions,\n ): ModelProcessAsyncGenerator<ChatModelOutput> {\n const parameters = await this.getParameters(input);\n\n const response = await this.googleClient.models.generateContentStream(parameters);\n\n let usage: ChatModelOutputUsage = {\n inputTokens: 0,\n outputTokens: 0,\n };\n let responseModel: string | undefined;\n\n const files: FileUnionContent[] = [];\n const toolCalls: ChatModelOutputToolCall[] = [];\n let text = \"\";\n let json: any;\n\n for await (const chunk of response) {\n if (!responseModel && chunk.modelVersion) {\n responseModel = chunk.modelVersion;\n yield { delta: { json: { model: responseModel } } };\n }\n\n for (const { content } of chunk.candidates ?? []) {\n if (content?.parts) {\n for (const part of content.parts) {\n if (part.text) {\n if (part.thought) {\n yield { delta: { text: { thoughts: part.text } } };\n } else {\n text += part.text;\n if (input.responseFormat?.type !== \"json_schema\") {\n yield { delta: { text: { text: part.text } } };\n }\n }\n }\n if (part.inlineData?.data) {\n files.push({\n type: \"file\",\n data: part.inlineData.data,\n filename: part.inlineData.displayName,\n mimeType: part.inlineData.mimeType,\n });\n }\n\n if (part.functionCall?.name) {\n if (part.functionCall.name === OUTPUT_FUNCTION_NAME) {\n json = part.functionCall.args;\n } else {\n const toolCall: ChatModelOutputToolCall = {\n id: part.functionCall.id || v7(),\n type: \"function\",\n function: {\n name: part.functionCall.name,\n arguments: part.functionCall.args || {},\n },\n };\n\n // Preserve thought_signature for 3.x models\n if (part.thoughtSignature && parameters.model.includes(\"gemini-3\")) {\n toolCall.metadata = {\n thoughtSignature: part.thoughtSignature,\n };\n }\n\n toolCalls.push(toolCall);\n }\n }\n }\n }\n }\n\n if (chunk.usageMetadata) {\n if (chunk.usageMetadata.promptTokenCount)\n usage.inputTokens = chunk.usageMetadata.promptTokenCount;\n if (chunk.usageMetadata.candidatesTokenCount || chunk.usageMetadata.thoughtsTokenCount)\n usage.outputTokens =\n (chunk.usageMetadata.candidatesTokenCount || 0) +\n (chunk.usageMetadata.thoughtsTokenCount || 0);\n // Parse cache statistics if available\n if (chunk.usageMetadata.cachedContentTokenCount) {\n usage.cacheReadInputTokens = chunk.usageMetadata.cachedContentTokenCount;\n }\n }\n }\n\n if (toolCalls.length) {\n yield { delta: { json: { toolCalls } } };\n }\n if (input.responseFormat?.type === \"json_schema\") {\n if (json) {\n yield { delta: { json: { json } } };\n } else if (text) {\n yield { delta: { json: { json: safeParseJSON(text) } } };\n } else if (!toolCalls.length) {\n throw new StructuredOutputError(\"No JSON response from the model\");\n }\n } else if (!toolCalls.length) {\n // NOTE: gemini-2.5-pro sometimes returns an empty response,\n // so we check here and retry with structured output mode (empty responses occur less frequently with tool calls)\n if (!text && !files.length) {\n logger.warn(\"Empty response from Gemini, retrying with structured output mode\");\n\n try {\n const outputSchema = z.object({\n output: z.string().describe(\"The final answer from the model\"),\n });\n\n const response = await this.process(\n {\n ...input,\n responseFormat: {\n type: \"json_schema\",\n jsonSchema: {\n name: \"output\",\n schema: zodToJsonSchema(outputSchema),\n },\n },\n },\n options,\n );\n\n const result = await modelProcessResultToObject(response);\n\n // Merge retry usage with the original usage\n usage = mergeUsage(usage, result.usage);\n\n // Return the tool calls if retry has tool calls\n if (result.toolCalls?.length) {\n toolCalls.push(...result.toolCalls);\n yield { delta: { json: { toolCalls } } };\n }\n // Return the text from structured output of retry\n else {\n if (!result.json)\n throw new Error(\"Retrying with structured output mode got no json response\");\n\n const parsed = outputSchema.safeParse(result.json);\n\n if (!parsed.success)\n throw new Error(\"Retrying with structured output mode got invalid json response\");\n\n text = parsed.data.output;\n yield { delta: { text: { text } } };\n\n logger.warn(\n \"Empty response from Gemini, retried with structured output mode successfully\",\n );\n }\n } catch (error) {\n logger.error(\n \"Empty response from Gemini, retrying with structured output mode failed\",\n error,\n );\n throw new StructuredOutputError(\"No response from the model\");\n }\n }\n }\n\n yield {\n delta: {\n json: {\n usage,\n files: files.length ? files : undefined,\n modelOptions: {\n reasoningEffort:\n parameters.config?.thinkingConfig?.thinkingLevel ||\n parameters.config?.thinkingConfig?.thinkingBudget,\n },\n },\n },\n };\n }\n\n private async buildConfig(input: ChatModelInput): Promise<GenerateContentParameters[\"config\"]> {\n const config: GenerateContentParameters[\"config\"] = {};\n\n const { tools, toolConfig } = await this.buildTools(input);\n\n config.tools = tools;\n config.toolConfig = toolConfig;\n\n if (input.responseFormat?.type === \"json_schema\") {\n if (config.tools?.length) {\n config.tools.push({\n functionDeclarations: [\n {\n name: OUTPUT_FUNCTION_NAME,\n description: \"Output the final response\",\n parametersJsonSchema: input.responseFormat.jsonSchema.schema,\n },\n ],\n });\n\n config.toolConfig = {\n ...config.toolConfig,\n functionCallingConfig: { mode: FunctionCallingConfigMode.ANY },\n };\n } else {\n config.responseJsonSchema = input.responseFormat.jsonSchema.schema;\n config.responseMimeType = \"application/json\";\n }\n }\n\n return config;\n }\n\n private async buildTools(\n input: ChatModelInput,\n ): Promise<Pick<GenerateContentConfig, \"tools\" | \"toolConfig\">> {\n const tools: ToolListUnion = [];\n\n for (const tool of input.tools ?? []) {\n tools.push({\n functionDeclarations: [\n {\n name: tool.function.name,\n description: tool.function.description,\n parametersJsonSchema: tool.function.parameters,\n },\n ],\n });\n }\n\n const functionCallingConfig: FunctionCallingConfig | undefined = !input.toolChoice\n ? undefined\n : input.toolChoice === \"auto\"\n ? { mode: FunctionCallingConfigMode.AUTO }\n : input.toolChoice === \"none\"\n ? { mode: FunctionCallingConfigMode.NONE }\n : input.toolChoice === \"required\"\n ? { mode: FunctionCallingConfigMode.ANY }\n : {\n mode: FunctionCallingConfigMode.ANY,\n allowedFunctionNames: [input.toolChoice.function.name],\n };\n\n return { tools, toolConfig: { functionCallingConfig } };\n }\n\n private async buildVideoContentParts(media: FileUnionContent): Promise<Part | undefined> {\n const { path: filePath, mimeType: fileMimeType } = await this.transformFileType(\"local\", media);\n\n if (filePath) {\n const stats = await nodejs.fs.stat(filePath);\n const fileSizeInBytes = stats.size;\n const fileSizeMB = fileSizeInBytes / (1024 * 1024);\n\n if (fileSizeMB > NEED_UPLOAD_MAX_FILE_SIZE_MB) {\n const uploadedFile = await this.googleClient.files.upload({\n file: filePath,\n config: { mimeType: fileMimeType },\n });\n\n let file = uploadedFile;\n while (file.state === \"PROCESSING\") {\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n if (file.name) {\n file = await this.googleClient.files.get({ name: file.name });\n }\n }\n\n if (file.state !== \"ACTIVE\") {\n throw new Error(`File ${file.name} failed to process: ${file.state}`);\n }\n\n if (file.uri && file.mimeType) {\n const result = createUserContent([createPartFromUri(file.uri, file.mimeType), \"\"]);\n const part = result.parts?.find((x) => x.fileData);\n\n if (part) {\n await nodejs.fs.rm(filePath);\n return part;\n }\n }\n }\n }\n }\n\n private async buildContents(\n input: ChatModelInput,\n ): Promise<Omit<GenerateContentParameters, \"model\">> {\n const result: Omit<GenerateContentParameters, \"model\"> = {\n contents: [],\n };\n\n const systemParts: Part[] = [];\n\n result.contents = (\n await Promise.all(\n input.messages.map(async (msg) => {\n if (msg.role === \"system\") {\n if (typeof msg.content === \"string\") {\n systemParts.push({ text: msg.content });\n } else if (Array.isArray(msg.content)) {\n systemParts.push(\n ...msg.content.map<Part>((item) => {\n if (item.type === \"text\") return { text: item.text };\n throw new Error(`Unsupported content type: ${item.type}`);\n }),\n );\n }\n\n return;\n }\n\n const content: Content = {\n role: msg.role === \"agent\" ? \"model\" : msg.role === \"user\" ? \"user\" : undefined,\n };\n\n if (msg.toolCalls) {\n content.parts = msg.toolCalls.map((call) => {\n const part: Part = {\n functionCall: {\n id: call.id,\n name: call.function.name,\n args: call.function.arguments,\n },\n };\n\n // Restore thought_signature for 3.x models\n if (call.metadata?.thoughtSignature) {\n part.thoughtSignature = call.metadata.thoughtSignature;\n }\n\n return part;\n });\n } else if (msg.toolCallId) {\n const call = input.messages\n .flatMap((i) => i.toolCalls)\n .find((c) => c?.id === msg.toolCallId);\n if (!call) throw new Error(`Tool call not found: ${msg.toolCallId}`);\n if (!msg.content) throw new Error(\"Tool call must have content\");\n\n // parse tool result as a record\n let toolResult: Record<string, unknown> | undefined;\n {\n let text: string | undefined;\n if (typeof msg.content === \"string\") text = msg.content;\n else if (msg.content?.length === 1) {\n const first = msg.content[0];\n if (first?.type === \"text\") text = first.text;\n }\n\n if (text) {\n try {\n const obj = parse(text);\n if (isRecord(obj)) toolResult = obj;\n } catch {\n // ignore\n }\n if (!toolResult) toolResult = { result: text };\n }\n }\n\n const functionResponse: FunctionResponse = {\n id: msg.toolCallId,\n name: call.function.name,\n };\n\n if (toolResult) {\n functionResponse.response = toolResult;\n } else {\n functionResponse.parts = await this.contentToParts(msg.content);\n }\n\n content.parts = [{ functionResponse }];\n } else if (msg.content) {\n content.parts = await this.contentToParts(msg.content);\n }\n\n return content;\n }),\n )\n ).filter(isNonNullable);\n\n this.ensureMessagesHasUserMessage(systemParts, result.contents);\n\n if (systemParts.length) {\n result.config ??= {};\n result.config.systemInstruction = systemParts;\n }\n\n return result;\n }\n\n private async contentToParts(content: ChatModelInputMessageContent): Promise<Part[]> {\n if (typeof content === \"string\") return [{ text: content }];\n\n return Promise.all(\n content.map<Promise<Part>>(async (item) => {\n switch (item.type) {\n case \"text\":\n return { text: item.text };\n case \"url\":\n return { fileData: { fileUri: item.url, mimeType: item.mimeType } };\n case \"file\": {\n const part = await this.buildVideoContentParts(item);\n if (part) return part;\n\n return { inlineData: { data: item.data, mimeType: item.mimeType } };\n }\n case \"local\":\n throw new Error(\n `Unsupported local file: ${item.path}, it should be converted to base64 at ChatModel`,\n );\n }\n }),\n );\n }\n\n private ensureMessagesHasUserMessage(systems: Part[], contents: Content[]) {\n // no messages but system messages\n if (!contents.length && systems.length) {\n const system = systems.pop();\n if (system) contents.push({ role: \"user\", parts: [system] });\n }\n\n // first message is from model\n if (contents[0]?.role === \"model\") {\n const system = systems.pop();\n if (system) contents.unshift({ role: \"user\", parts: [system] });\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"gemini-chat-model.mjs","names":[],"sources":["../src/gemini-chat-model.ts"],"sourcesContent":["import {\n ChatModel,\n type ChatModelInput,\n type ChatModelInputMessageContent,\n type ChatModelInputOptions,\n type ChatModelOptions,\n type ChatModelOutput,\n type ChatModelOutputToolCall,\n type ChatModelOutputUsage,\n type FileUnionContent,\n type ModelInvokeOptions,\n type ModelProcessAsyncGenerator,\n type ModelProcessResult,\n modelProcessResultToObject,\n StructuredOutputError,\n safeParseJSON,\n} from \"@aigne/model-base\";\nimport { logger } from \"@aigne/model-base/utils/logger\";\nimport { mergeUsage } from \"@aigne/model-base/utils/model-utils\";\nimport { nodejs } from \"@aigne/model-base/utils/nodejs\";\nimport {\n isNil,\n isNonNullable,\n isRecord,\n type PromiseOrValue,\n} from \"@aigne/model-base/utils/type-utils\";\nimport { v7 } from \"@aigne/uuid\";\nimport {\n type Content,\n type ContentUnion,\n createPartFromUri,\n createUserContent,\n type FunctionCallingConfig,\n FunctionCallingConfigMode,\n type FunctionResponse,\n type GenerateContentConfig,\n type GenerateContentParameters,\n GoogleGenAI,\n type GoogleGenAIOptions,\n type Part,\n ThinkingLevel,\n type ToolListUnion,\n} from \"@google/genai\";\nimport { parse } from \"yaml\";\nimport { z } from \"zod\";\n\nconst GEMINI_DEFAULT_CHAT_MODEL = \"gemini-2.0-flash\";\n\nconst OUTPUT_FUNCTION_NAME = \"output\";\nconst NEED_UPLOAD_MAX_FILE_SIZE_MB = 20;\n\nexport interface GeminiChatModelOptions extends ChatModelOptions {\n /**\n * API key for Gemini API\n *\n * If not provided, will look for GEMINI_API_KEY or GOOGLE_API_KEY in environment variables\n */\n apiKey?: string;\n\n /**\n * Optional client options for the Gemini SDK\n */\n clientOptions?: Partial<GoogleGenAIOptions>;\n}\n\n/**\n * Implementation of the ChatModel interface for Google's Gemini API\n *\n * @example\n * Here's how to create and use a Gemini chat model:\n * {@includeCode ../test/gemini-chat-model.test.ts#example-gemini-chat-model}\n *\n * @example\n * Here's an example with streaming response:\n * {@includeCode ../test/gemini-chat-model.test.ts#example-gemini-chat-model-streaming}\n */\nexport class GeminiChatModel extends ChatModel {\n constructor(public override options?: GeminiChatModelOptions) {\n super({\n ...options,\n model: options?.model || GEMINI_DEFAULT_CHAT_MODEL,\n });\n }\n\n protected apiKeyEnvName = \"GEMINI_API_KEY\";\n\n protected _googleClient?: GoogleGenAI;\n\n get googleClient() {\n if (this._googleClient) return this._googleClient;\n\n const { apiKey } = this.credential;\n\n if (!apiKey)\n throw new Error(\n `${this.name} requires an API key. Please provide it via \\`options.apiKey\\`, or set the \\`${this.apiKeyEnvName}\\` environment variable`,\n );\n\n this._googleClient ??= new GoogleGenAI({\n apiKey,\n ...this.options?.clientOptions,\n });\n\n return this._googleClient;\n }\n\n override get credential() {\n const apiKey =\n this.options?.apiKey ||\n process.env[this.apiKeyEnvName] ||\n process.env.GEMINI_API_KEY ||\n process.env.GOOGLE_API_KEY;\n\n return {\n apiKey,\n model: this.options?.model || GEMINI_DEFAULT_CHAT_MODEL,\n };\n }\n\n get modelOptions() {\n return this.options?.modelOptions;\n }\n\n override async countTokens(input: ChatModelInput): Promise<number> {\n const { model, ...request } = await this.getParameters(input);\n\n const contents: Content[] = [];\n\n const { systemInstruction, tools } = request.config ?? {};\n\n if (systemInstruction) contents.push(this.contentUnionToContent(systemInstruction));\n if (tools?.length) contents.push({ role: \"system\", parts: [{ text: JSON.stringify(tools) }] });\n\n contents.push(...[request.contents].flat().map(this.contentUnionToContent));\n\n const tokens = (\n await this.googleClient.models.countTokens({\n model,\n contents,\n })\n ).totalTokens;\n\n if (!isNil(tokens)) return tokens;\n\n return super.countTokens(input);\n }\n\n private contentUnionToContent(content: ContentUnion): Content {\n if (typeof content === \"object\" && \"parts\" in content) {\n return { role: \"system\", parts: content.parts };\n } else if (typeof content === \"string\") {\n return { role: \"system\", parts: [{ text: content }] };\n } else if (Array.isArray(content)) {\n return {\n role: \"system\",\n parts: content.map((i) => (typeof i === \"string\" ? { text: i } : i)),\n };\n } else {\n return { role: \"system\", parts: [content as Part] };\n }\n }\n\n override process(\n input: ChatModelInput,\n options: ModelInvokeOptions,\n ): PromiseOrValue<ModelProcessResult<ChatModelOutput>> {\n return this.processInput(input, options);\n }\n\n // References: https://ai.google.dev/gemini-api/docs/thinking#set-budget\n protected thinkingBudgetModelMap = [\n // 注意:gemini-2.5-flash-image-preview 模型并不支持 thinking。see: https://github.com/CherryHQ/cherry-studio/issues/9614\n {\n pattern: /gemini-2.5-flash-image-preview/,\n support: false,\n },\n {\n pattern: /gemini-3(?!.*-image-)/,\n support: true,\n type: \"level\",\n },\n {\n pattern: /gemini-2.5-pro/,\n support: true,\n min: 128,\n max: 32768,\n },\n {\n pattern: /gemini-2.5-flash/,\n support: true,\n min: 0,\n max: 24576,\n },\n {\n pattern: /2.5-flash-lite/,\n support: true,\n min: 512,\n max: 24576,\n },\n {\n pattern: /.*/,\n support: false,\n },\n ];\n\n protected thinkingBudgetLevelMap = {\n high: 100000, // use 100k for high, finally capped by model max\n medium: 10000,\n low: 5000,\n minimal: 200,\n };\n\n protected thinkingLevelMap = {\n high: ThinkingLevel.HIGH,\n medium: ThinkingLevel.HIGH,\n low: ThinkingLevel.LOW,\n minimal: ThinkingLevel.LOW,\n };\n\n protected getThinkingBudget(\n model: string,\n effort: ChatModelInputOptions[\"reasoningEffort\"],\n ): { support: boolean; budget?: number; level?: ThinkingLevel } {\n const m = this.thinkingBudgetModelMap.find((i) => i.pattern.test(model));\n\n if (!m?.support) return { support: false };\n\n if (m.type === \"level\") {\n let level = ThinkingLevel.THINKING_LEVEL_UNSPECIFIED;\n\n if (typeof effort === \"string\") {\n level = this.thinkingLevelMap[effort];\n } else if (typeof effort === \"number\") {\n level =\n effort >= this.thinkingBudgetLevelMap[\"medium\"] ? ThinkingLevel.HIGH : ThinkingLevel.LOW;\n }\n\n return { support: true, level };\n }\n\n let budget =\n typeof effort === \"string\" ? this.thinkingBudgetLevelMap[effort] || undefined : effort;\n if (typeof budget === \"undefined\") return { support: true };\n\n if (typeof m.min === \"number\") budget = Math.max(m.min, budget);\n if (typeof m.max === \"number\") budget = Math.min(m.max, budget);\n\n return { support: true, budget };\n }\n\n private async getParameters(input: ChatModelInput): Promise<GenerateContentParameters> {\n const { modelOptions = {} } = input;\n\n const model = modelOptions.model || this.credential.model;\n const { contents, config } = await this.buildContents(input);\n\n const thinkingBudget = this.getThinkingBudget(model, modelOptions.reasoningEffort);\n\n const parameters: GenerateContentParameters = {\n model,\n contents,\n config: {\n thinkingConfig: thinkingBudget.support\n ? {\n includeThoughts: true,\n thinkingBudget: thinkingBudget.budget,\n thinkingLevel: thinkingBudget.level,\n }\n : undefined,\n responseModalities: modelOptions.modalities,\n temperature: modelOptions.temperature,\n topP: modelOptions.topP,\n frequencyPenalty: modelOptions.frequencyPenalty,\n presencePenalty: modelOptions.presencePenalty,\n ...config,\n ...(await this.buildConfig(input)),\n },\n };\n\n return parameters;\n }\n\n private async *processInput(\n input: ChatModelInput,\n options: ModelInvokeOptions,\n ): ModelProcessAsyncGenerator<ChatModelOutput> {\n const parameters = await this.getParameters(input);\n\n const response = await this.googleClient.models.generateContentStream(parameters);\n\n let usage: ChatModelOutputUsage = {\n inputTokens: 0,\n outputTokens: 0,\n };\n let responseModel: string | undefined;\n\n const files: FileUnionContent[] = [];\n const toolCalls: ChatModelOutputToolCall[] = [];\n let text = \"\";\n let json: any;\n\n for await (const chunk of response) {\n if (!responseModel && chunk.modelVersion) {\n responseModel = chunk.modelVersion;\n yield { delta: { json: { model: responseModel } } };\n }\n\n for (const { content } of chunk.candidates ?? []) {\n if (content?.parts) {\n for (const part of content.parts) {\n if (part.text) {\n if (part.thought) {\n yield { delta: { text: { thoughts: part.text } } };\n } else {\n text += part.text;\n if (input.responseFormat?.type !== \"json_schema\") {\n yield { delta: { text: { text: part.text } } };\n }\n }\n }\n if (part.inlineData?.data) {\n files.push({\n type: \"file\",\n data: part.inlineData.data,\n filename: part.inlineData.displayName,\n mimeType: part.inlineData.mimeType,\n });\n }\n\n if (part.functionCall?.name) {\n if (part.functionCall.name === OUTPUT_FUNCTION_NAME) {\n json = part.functionCall.args;\n } else {\n const toolCall: ChatModelOutputToolCall = {\n id: part.functionCall.id || v7(),\n type: \"function\",\n function: {\n name: part.functionCall.name,\n arguments: part.functionCall.args || {},\n },\n };\n\n // Preserve thought_signature for 3.x models\n if (part.thoughtSignature && parameters.model.includes(\"gemini-3\")) {\n toolCall.metadata = {\n thoughtSignature: part.thoughtSignature,\n };\n }\n\n toolCalls.push(toolCall);\n }\n }\n }\n }\n }\n\n if (chunk.usageMetadata) {\n if (chunk.usageMetadata.promptTokenCount)\n usage.inputTokens = chunk.usageMetadata.promptTokenCount;\n if (chunk.usageMetadata.candidatesTokenCount || chunk.usageMetadata.thoughtsTokenCount)\n usage.outputTokens =\n (chunk.usageMetadata.candidatesTokenCount || 0) +\n (chunk.usageMetadata.thoughtsTokenCount || 0);\n // Parse cache statistics if available\n if (chunk.usageMetadata.cachedContentTokenCount) {\n usage.cacheReadInputTokens = chunk.usageMetadata.cachedContentTokenCount;\n }\n }\n }\n\n if (toolCalls.length) {\n yield { delta: { json: { toolCalls } } };\n }\n if (input.responseFormat?.type === \"json_schema\") {\n if (json) {\n yield { delta: { json: { json } } };\n } else if (text) {\n yield { delta: { json: { json: safeParseJSON(text) } } };\n } else if (!toolCalls.length) {\n throw new StructuredOutputError(\"No JSON response from the model\");\n }\n } else if (!toolCalls.length) {\n // NOTE: gemini-2.5-pro sometimes returns an empty response,\n // so we check here and retry with structured output mode (empty responses occur less frequently with tool calls)\n if (!text && !files.length) {\n logger.warn(\"Empty response from Gemini, retrying with structured output mode\");\n\n try {\n const outputSchema = z.object({\n output: z.string().describe(\"The final answer from the model\"),\n });\n\n const response = await this.process(\n {\n ...input,\n responseFormat: {\n type: \"json_schema\",\n jsonSchema: {\n name: \"output\",\n schema: z.toJSONSchema(outputSchema) as Record<string, unknown>,\n },\n },\n },\n options,\n );\n\n const result = await modelProcessResultToObject(response);\n\n // Merge retry usage with the original usage\n usage = mergeUsage(usage, result.usage);\n\n // Return the tool calls if retry has tool calls\n if (result.toolCalls?.length) {\n toolCalls.push(...result.toolCalls);\n yield { delta: { json: { toolCalls } } };\n }\n // Return the text from structured output of retry\n else {\n if (!result.json)\n throw new Error(\"Retrying with structured output mode got no json response\");\n\n const parsed = outputSchema.safeParse(result.json);\n\n if (!parsed.success)\n throw new Error(\"Retrying with structured output mode got invalid json response\");\n\n text = parsed.data.output;\n yield { delta: { text: { text } } };\n\n logger.warn(\n \"Empty response from Gemini, retried with structured output mode successfully\",\n );\n }\n } catch (error) {\n logger.error(\n \"Empty response from Gemini, retrying with structured output mode failed\",\n error,\n );\n throw new StructuredOutputError(\"No response from the model\");\n }\n }\n }\n\n yield {\n delta: {\n json: {\n usage,\n files: files.length ? files : undefined,\n modelOptions: {\n reasoningEffort:\n parameters.config?.thinkingConfig?.thinkingLevel ||\n parameters.config?.thinkingConfig?.thinkingBudget,\n },\n },\n },\n };\n }\n\n private async buildConfig(input: ChatModelInput): Promise<GenerateContentParameters[\"config\"]> {\n const config: GenerateContentParameters[\"config\"] = {};\n\n const { tools, toolConfig } = await this.buildTools(input);\n\n config.tools = tools;\n config.toolConfig = toolConfig;\n\n if (input.responseFormat?.type === \"json_schema\") {\n if (config.tools?.length) {\n config.tools.push({\n functionDeclarations: [\n {\n name: OUTPUT_FUNCTION_NAME,\n description: \"Output the final response\",\n parametersJsonSchema: input.responseFormat.jsonSchema.schema,\n },\n ],\n });\n\n config.toolConfig = {\n ...config.toolConfig,\n functionCallingConfig: { mode: FunctionCallingConfigMode.ANY },\n };\n } else {\n config.responseJsonSchema = input.responseFormat.jsonSchema.schema;\n config.responseMimeType = \"application/json\";\n }\n }\n\n return config;\n }\n\n private async buildTools(\n input: ChatModelInput,\n ): Promise<Pick<GenerateContentConfig, \"tools\" | \"toolConfig\">> {\n const tools: ToolListUnion = [];\n\n for (const tool of input.tools ?? []) {\n tools.push({\n functionDeclarations: [\n {\n name: tool.function.name,\n description: tool.function.description,\n parametersJsonSchema: tool.function.parameters,\n },\n ],\n });\n }\n\n const functionCallingConfig: FunctionCallingConfig | undefined = !input.toolChoice\n ? undefined\n : input.toolChoice === \"auto\"\n ? { mode: FunctionCallingConfigMode.AUTO }\n : input.toolChoice === \"none\"\n ? { mode: FunctionCallingConfigMode.NONE }\n : input.toolChoice === \"required\"\n ? { mode: FunctionCallingConfigMode.ANY }\n : {\n mode: FunctionCallingConfigMode.ANY,\n allowedFunctionNames: [input.toolChoice.function.name],\n };\n\n return { tools, toolConfig: { functionCallingConfig } };\n }\n\n private async buildVideoContentParts(media: FileUnionContent): Promise<Part | undefined> {\n const { path: filePath, mimeType: fileMimeType } = await this.transformFileType(\"local\", media);\n\n if (filePath) {\n const stats = await nodejs.fs.stat(filePath);\n const fileSizeInBytes = stats.size;\n const fileSizeMB = fileSizeInBytes / (1024 * 1024);\n\n if (fileSizeMB > NEED_UPLOAD_MAX_FILE_SIZE_MB) {\n const uploadedFile = await this.googleClient.files.upload({\n file: filePath,\n config: { mimeType: fileMimeType },\n });\n\n let file = uploadedFile;\n while (file.state === \"PROCESSING\") {\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n if (file.name) {\n file = await this.googleClient.files.get({ name: file.name });\n }\n }\n\n if (file.state !== \"ACTIVE\") {\n throw new Error(`File ${file.name} failed to process: ${file.state}`);\n }\n\n if (file.uri && file.mimeType) {\n const result = createUserContent([createPartFromUri(file.uri, file.mimeType), \"\"]);\n const part = result.parts?.find((x) => x.fileData);\n\n if (part) {\n await nodejs.fs.rm(filePath);\n return part;\n }\n }\n }\n }\n }\n\n private async buildContents(\n input: ChatModelInput,\n ): Promise<Omit<GenerateContentParameters, \"model\">> {\n const result: Omit<GenerateContentParameters, \"model\"> = {\n contents: [],\n };\n\n const systemParts: Part[] = [];\n\n result.contents = (\n await Promise.all(\n input.messages.map(async (msg) => {\n if (msg.role === \"system\") {\n if (typeof msg.content === \"string\") {\n systemParts.push({ text: msg.content });\n } else if (Array.isArray(msg.content)) {\n systemParts.push(\n ...msg.content.map<Part>((item) => {\n if (item.type === \"text\") return { text: item.text };\n throw new Error(`Unsupported content type: ${item.type}`);\n }),\n );\n }\n\n return;\n }\n\n const content: Content = {\n role: msg.role === \"agent\" ? \"model\" : msg.role === \"user\" ? \"user\" : undefined,\n };\n\n if (msg.toolCalls) {\n content.parts = msg.toolCalls.map((call) => {\n const part: Part = {\n functionCall: {\n id: call.id,\n name: call.function.name,\n args: call.function.arguments,\n },\n };\n\n // Restore thought_signature for 3.x models\n if (call.metadata?.thoughtSignature) {\n part.thoughtSignature = call.metadata.thoughtSignature;\n }\n\n return part;\n });\n } else if (msg.toolCallId) {\n const call = input.messages\n .flatMap((i) => i.toolCalls)\n .find((c) => c?.id === msg.toolCallId);\n if (!call) throw new Error(`Tool call not found: ${msg.toolCallId}`);\n if (!msg.content) throw new Error(\"Tool call must have content\");\n\n // parse tool result as a record\n let toolResult: Record<string, unknown> | undefined;\n {\n let text: string | undefined;\n if (typeof msg.content === \"string\") text = msg.content;\n else if (msg.content?.length === 1) {\n const first = msg.content[0];\n if (first?.type === \"text\") text = first.text;\n }\n\n if (text) {\n try {\n const obj = parse(text);\n if (isRecord(obj)) toolResult = obj;\n } catch {\n // ignore\n }\n if (!toolResult) toolResult = { result: text };\n }\n }\n\n const functionResponse: FunctionResponse = {\n id: msg.toolCallId,\n name: call.function.name,\n };\n\n if (toolResult) {\n functionResponse.response = toolResult;\n } else {\n functionResponse.parts = await this.contentToParts(msg.content);\n }\n\n content.parts = [{ functionResponse }];\n } else if (msg.content) {\n content.parts = await this.contentToParts(msg.content);\n }\n\n return content;\n }),\n )\n ).filter(isNonNullable);\n\n this.ensureMessagesHasUserMessage(systemParts, result.contents);\n\n if (systemParts.length) {\n result.config ??= {};\n result.config.systemInstruction = systemParts;\n }\n\n return result;\n }\n\n private async contentToParts(content: ChatModelInputMessageContent): Promise<Part[]> {\n if (typeof content === \"string\") return [{ text: content }];\n\n return Promise.all(\n content.map<Promise<Part>>(async (item) => {\n switch (item.type) {\n case \"text\":\n return { text: item.text };\n case \"url\":\n return { fileData: { fileUri: item.url, mimeType: item.mimeType } };\n case \"file\": {\n const part = await this.buildVideoContentParts(item);\n if (part) return part;\n\n return { inlineData: { data: item.data, mimeType: item.mimeType } };\n }\n case \"local\":\n throw new Error(\n `Unsupported local file: ${item.path}, it should be converted to base64 at ChatModel`,\n );\n }\n }),\n );\n }\n\n private ensureMessagesHasUserMessage(systems: Part[], contents: Content[]) {\n // no messages but system messages\n if (!contents.length && systems.length) {\n const system = systems.pop();\n if (system) contents.push({ role: \"user\", parts: [system] });\n }\n\n // first message is from model\n if (contents[0]?.role === \"model\") {\n const system = systems.pop();\n if (system) contents.unshift({ role: \"user\", parts: [system] });\n }\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/gemini",
3
- "version": "1.74.0-beta.10",
3
+ "version": "1.74.0-beta.11",
4
4
  "description": "AIGNE Gemini SDK for integrating with Google's Gemini AI models",
5
5
  "license": "Elastic-2.0",
6
6
  "publishConfig": {
@@ -36,9 +36,8 @@
36
36
  "@aigne/uuid": "^13.0.1",
37
37
  "@google/genai": "^1.30.0",
38
38
  "yaml": "^2.8.1",
39
- "zod": "^3.25.67",
40
- "zod-to-json-schema": "^3.24.6",
41
- "@aigne/model-base": "^1.74.0-beta.10"
39
+ "zod": "^4.3.6",
40
+ "@aigne/model-base": "^1.74.0-beta.11"
42
41
  },
43
42
  "devDependencies": {
44
43
  "@types/bun": "^1.3.6",