@langchain/google 0.1.1 → 0.1.3
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.
- package/CHANGELOG.md +24 -0
- package/dist/chat_models/base.cjs +9 -2
- package/dist/chat_models/base.cjs.map +1 -1
- package/dist/chat_models/base.js +9 -2
- package/dist/chat_models/base.js.map +1 -1
- package/dist/converters/messages.cjs +4 -1
- package/dist/converters/messages.cjs.map +1 -1
- package/dist/converters/messages.js +4 -1
- package/dist/converters/messages.js.map +1 -1
- package/dist/converters/params.cjs +2 -0
- package/dist/converters/params.cjs.map +1 -1
- package/dist/converters/params.js +2 -0
- package/dist/converters/params.js.map +1 -1
- package/dist/utils/metadata.cjs +57 -0
- package/dist/utils/metadata.cjs.map +1 -0
- package/dist/utils/metadata.js +56 -0
- package/dist/utils/metadata.js.map +1 -0
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @langchain/google
|
|
2
2
|
|
|
3
|
+
## 0.1.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#10106](https://github.com/langchain-ai/langchainjs/pull/10106) [`9f30267`](https://github.com/langchain-ai/langchainjs/commit/9f30267e95a2a42fac71f1d3674b84c5a190dbbc) Thanks [@hntrl](https://github.com/hntrl)! - Add package version metadata to runnable traces. Each package now stamps its version in `this.metadata.versions` at construction time, making version info available in LangSmith trace metadata.
|
|
8
|
+
|
|
9
|
+
- [#10164](https://github.com/langchain-ai/langchainjs/pull/10164) [`4eae353`](https://github.com/langchain-ai/langchainjs/commit/4eae353512c8361c530b90ab4e74fd18af774287) Thanks [@hntrl](https://github.com/hntrl)! - fix(google): fix inflated usage_metadata during streaming by converting cumulative token counts to deltas
|
|
10
|
+
|
|
11
|
+
The Gemini API sends cumulative `usageMetadata` on every streaming chunk. Previously, these cumulative values were attached directly to each `AIMessageChunk`, causing `mergeUsageMetadata()` to sum them and produce inflated token counts when chunks were concatenated.
|
|
12
|
+
|
|
13
|
+
Now the provider tracks previous cumulative values and emits per-chunk deltas, so additive merging produces the correct final totals while still providing meaningful per-chunk usage data when `streamUsage` is enabled.
|
|
14
|
+
|
|
15
|
+
- [#10170](https://github.com/langchain-ai/langchainjs/pull/10170) [`d42f735`](https://github.com/langchain-ai/langchainjs/commit/d42f735b04d9d42639591fba5639ad65dbb915bf) Thanks [@hntrl](https://github.com/hntrl)! - fix(google): generate unique tool_call IDs to prevent ToolNode from silently skipping execution
|
|
16
|
+
- Use native `functionCall.id` from Gemini API when present, fall back to `uuid.v4()` (matching `@langchain/google-common` behavior)
|
|
17
|
+
- Pass `tool_call_id` through as `functionResponse.id` on both v1 standard and legacy code paths
|
|
18
|
+
|
|
19
|
+
- [#10072](https://github.com/langchain-ai/langchainjs/pull/10072) [`5f6940d`](https://github.com/langchain-ai/langchainjs/commit/5f6940d49033ec322bcfb426652c68e37c82cbaa) Thanks [@kyrisu](https://github.com/kyrisu)! - fix(google): emit on_chat_model_stream events for non-text content blocks
|
|
20
|
+
|
|
21
|
+
## 0.1.2
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- [#10101](https://github.com/langchain-ai/langchainjs/pull/10101) [`a54de44`](https://github.com/langchain-ai/langchainjs/commit/a54de4410be4b5c159b9ee1590a8187017dc9dfc) Thanks [@afirstenberg](https://github.com/afirstenberg)! - add Gemini 3.1 Pro support
|
|
26
|
+
|
|
3
27
|
## 0.1.1
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
|
@@ -4,6 +4,7 @@ const require_stream = require('../utils/stream.cjs');
|
|
|
4
4
|
const require_messages = require('../converters/messages.cjs');
|
|
5
5
|
const require_tools = require('../converters/tools.cjs');
|
|
6
6
|
const require_params = require('../converters/params.cjs');
|
|
7
|
+
const require_metadata = require('../utils/metadata.cjs');
|
|
7
8
|
let _langchain_core_language_models_chat_models = require("@langchain/core/language_models/chat_models");
|
|
8
9
|
let _langchain_core_messages = require("@langchain/core/messages");
|
|
9
10
|
let _langchain_core_utils_stream = require("@langchain/core/utils/stream");
|
|
@@ -34,6 +35,7 @@ var BaseChatGoogle = class extends _langchain_core_language_models_chat_models.B
|
|
|
34
35
|
constructor(params) {
|
|
35
36
|
super(params);
|
|
36
37
|
this.params = params;
|
|
38
|
+
this._addVersion("@langchain/google", "0.1.3");
|
|
37
39
|
if (!params.apiClient) throw new require_errors.ConfigurationError("BaseChatGoogle requires an apiClient. This should be provided automatically by ChatGoogle constructors. If you're extending BaseChatGoogle directly, please provide an apiClient instance.");
|
|
38
40
|
this.apiClient = params.apiClient;
|
|
39
41
|
this.model = params.model;
|
|
@@ -250,6 +252,7 @@ var BaseChatGoogle = class extends _langchain_core_language_models_chat_models.B
|
|
|
250
252
|
throw error;
|
|
251
253
|
}
|
|
252
254
|
if (response.body) {
|
|
255
|
+
let previousUsage;
|
|
253
256
|
const reader = response.body.pipeThrough(new TextDecoderStream()).pipeThrough(new eventsource_parser_stream.EventSourceParserStream()).pipeThrough(new require_stream.SafeJsonEventParserStream()).pipeThrough(new TransformStream({ transform(chunk, controller) {
|
|
254
257
|
runManager?.handleCustomEvent(`google-chunk-${moduleName}`, { chunk });
|
|
255
258
|
if (chunk === null) {
|
|
@@ -279,7 +282,11 @@ var BaseChatGoogle = class extends _langchain_core_language_models_chat_models.B
|
|
|
279
282
|
} : {}
|
|
280
283
|
}
|
|
281
284
|
};
|
|
282
|
-
if (chunk?.usageMetadata && streamUsage)
|
|
285
|
+
if (chunk?.usageMetadata && streamUsage) {
|
|
286
|
+
const cumulative = require_messages.convertGeminiGenerateContentResponseToUsageMetadata(chunk);
|
|
287
|
+
messageChunkParams.usage_metadata = require_metadata.subtractUsageMetadata(cumulative, previousUsage);
|
|
288
|
+
previousUsage = cumulative;
|
|
289
|
+
}
|
|
283
290
|
const messageChunk = new _langchain_core_messages.AIMessageChunk(messageChunkParams);
|
|
284
291
|
controller.enqueue(new _langchain_core_outputs.ChatGenerationChunk({
|
|
285
292
|
text,
|
|
@@ -299,7 +306,7 @@ var BaseChatGoogle = class extends _langchain_core_language_models_chat_models.B
|
|
|
299
306
|
const { done, value } = await reader.read();
|
|
300
307
|
if (done) break;
|
|
301
308
|
yield value;
|
|
302
|
-
|
|
309
|
+
await runManager?.handleLLMNewToken(value.text ?? "", void 0, void 0, void 0, void 0, { chunk: value });
|
|
303
310
|
}
|
|
304
311
|
} finally {
|
|
305
312
|
reader.releaseLock();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.cjs","names":["BaseChatModel","ConfigurationError","convertParamsToPlatformType","PROFILES","convertToolsToGeminiTools","convertToolChoiceToGeminiConfig","convertFieldsToThinkingConfig","convertFieldsToSpeechConfig","convertMessagesToGeminiSystemInstruction","convertMessagesToGeminiContents","RequestError","PromptBlockedError","NoCandidatesError","convertGeminiCandidateToAIMessage","convertAIMessageToText","convertGeminiGenerateContentResponseToUsageMetadata","EventSourceParserStream","SafeJsonEventParserStream","ChatGenerationChunk","AIMessageChunk","convertGeminiPartsToToolCalls","RunnableLambda","AIMessage","MalformedOutputError","StructuredOutputParser","JsonOutputParser","schemaToGeminiParameters","JsonOutputKeyToolsParser","RunnablePassthrough","RunnableSequence"],"sources":["../../src/chat_models/base.ts"],"sourcesContent":["import {\n BaseChatModel,\n type BaseChatModelCallOptions,\n type BaseChatModelParams,\n} from \"@langchain/core/language_models/chat_models\";\nimport {\n AIMessage,\n AIMessageChunk,\n AIMessageChunkFields,\n BaseMessage,\n} from \"@langchain/core/messages\";\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { concat } from \"@langchain/core/utils/stream\";\nimport { ChatGenerationChunk, ChatResult } from \"@langchain/core/outputs\";\nimport { EventSourceParserStream } from \"eventsource-parser/stream\";\nimport type { BindToolsInput } from \"@langchain/core/language_models/chat_models\";\nimport type { ModelProfile } from \"@langchain/core/language_models/profile\";\nimport PROFILES from \"./profiles.js\";\nimport type {\n BaseLanguageModelInput,\n StructuredOutputMethodOptions,\n} from \"@langchain/core/language_models/base\";\nimport {\n Runnable,\n RunnableLambda,\n RunnablePassthrough,\n RunnableSequence,\n} from \"@langchain/core/runnables\";\nimport {\n toJsonSchema,\n type JsonSchema7Type,\n} from \"@langchain/core/utils/json_schema\";\nimport {\n InteropZodType,\n isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\nimport {\n JsonOutputParser,\n StructuredOutputParser,\n} from \"@langchain/core/output_parsers\";\nimport { JsonOutputKeyToolsParser } from \"@langchain/core/output_parsers/openai_tools\";\n\nimport { ApiClient } from \"../clients/index.js\";\nimport type { ChatGoogleFields } from \"./types.js\";\nimport { SafeJsonEventParserStream } from \"../utils/stream.js\";\nimport {\n convertAIMessageToText,\n convertGeminiCandidateToAIMessage,\n convertGeminiGenerateContentResponseToUsageMetadata,\n convertGeminiPartsToToolCalls,\n convertMessagesToGeminiContents,\n convertMessagesToGeminiSystemInstruction,\n} from \"../converters/messages.js\";\nimport {\n ConfigurationError,\n MalformedOutputError,\n NoCandidatesError,\n PromptBlockedError,\n RequestError,\n} from \"../utils/errors.js\";\nimport {\n convertToolsToGeminiTools,\n convertToolChoiceToGeminiConfig,\n schemaToGeminiParameters,\n} from \"../converters/tools.js\";\nimport {\n convertParamsToPlatformType,\n convertFieldsToSpeechConfig,\n convertFieldsToThinkingConfig,\n} from \"../converters/params.js\";\nimport { Gemini } from \"./api-types.js\";\n\nexport type GooglePlatformType = \"gai\" | \"gcp\";\n\nexport function getPlatformType(\n platform: GooglePlatformType | undefined,\n hasApiKey: boolean\n): GooglePlatformType {\n if (typeof platform !== \"undefined\") {\n return platform;\n } else if (hasApiKey) {\n return \"gai\";\n } else {\n return \"gcp\";\n }\n}\n\nexport interface BaseChatGoogleParams\n extends BaseChatModelParams,\n ChatGoogleFields {\n /**\n * The name of the Gemini model to use.\n *\n * Example: \"gemini-3-pro-preview\"\n */\n model: string;\n\n /**\n * Optional. The API client implementation for making HTTP requests to the Gemini API.\n * If not set, a default client will be used based on the runtime environment.\n */\n apiClient?: ApiClient;\n\n /**\n * Hostname for the API call (if this is running on GCP)\n * Usually this is computed based on location and platformType.\n **/\n endpoint?: string;\n\n /**\n * Region where the LLM is stored (if this is running on GCP)\n * Defaults to \"global\"\n **/\n location?: string;\n\n /**\n * The version of the API functions. Part of the path.\n * Usually this is computed based on platformType.\n **/\n apiVersion?: string;\n\n /**\n * What platform to run the service on.\n * If not specified, the class should determine this from other\n * means. Either way, the platform actually used will be in\n * the \"platform\" getter.\n */\n platformType?: GooglePlatformType;\n\n /**\n * For compatibility with Google's libraries, should this use Vertex?\n * The \"platformType\" parmeter takes precedence.\n */\n vertexai?: boolean;\n\n /**\n * Backwards compatibility.\n * @deprecated in favor of using `disableStreaming` or `.stream()`\n */\n streaming?: boolean;\n\n streamUsage?: boolean;\n}\n\nexport interface BaseChatGoogleCallOptions\n extends BaseChatModelCallOptions,\n ChatGoogleFields {}\n\nexport abstract class BaseChatGoogle<\n CallOptions extends BaseChatGoogleCallOptions = BaseChatGoogleCallOptions\n> extends BaseChatModel<CallOptions, AIMessageChunk> {\n model: string;\n\n streaming: boolean;\n\n disableStreaming: boolean;\n\n streamUsage: boolean = true;\n\n protected _platform?: GooglePlatformType;\n\n protected _endpoint?: string;\n\n protected _location?: string;\n\n protected _apiVersion?: string;\n\n protected apiClient: ApiClient;\n\n constructor(protected params: BaseChatGoogleParams) {\n super(params);\n\n if (!params.apiClient) {\n throw new ConfigurationError(\n \"BaseChatGoogle requires an apiClient. This should be provided automatically by ChatGoogle constructors. If you're extending BaseChatGoogle directly, please provide an apiClient instance.\"\n );\n }\n this.apiClient = params.apiClient;\n\n this.model = params.model;\n this._platform = convertParamsToPlatformType(params);\n this._endpoint = params.endpoint;\n this._location = params.location;\n this._apiVersion = params.apiVersion;\n\n this.disableStreaming = params?.disableStreaming === true;\n this.streaming = params?.streaming === true;\n if (this.disableStreaming) this.streaming = false;\n // disable streaming in BaseChatModel if explicitly disabled\n if (params?.streaming === false) this.disableStreaming = true;\n\n this.streamUsage = params?.streamUsage ?? this.streamUsage;\n if (this.disableStreaming) this.streamUsage = false;\n }\n\n _llmType(): string {\n return \"google\";\n }\n\n protected get platformType(): GooglePlatformType | undefined {\n return this._platform;\n }\n\n protected get platform(): GooglePlatformType {\n return getPlatformType(this._platform, this.apiClient.hasApiKey());\n }\n\n protected get isVertexExpress(): boolean {\n return this.platform === \"gcp\" && this.apiClient.hasApiKey();\n }\n\n protected get apiVersion(): string {\n if (typeof this._apiVersion !== \"undefined\") {\n return this._apiVersion;\n } else if (this.platform === \"gai\") {\n return \"v1beta\";\n } else {\n return \"v1\";\n }\n }\n\n protected get location(): string {\n return this._location || \"global\";\n }\n\n protected get endpoint(): string {\n if (typeof this._endpoint !== \"undefined\") {\n return this._endpoint;\n } else if (this.platform === \"gai\") {\n return \"generativelanguage.googleapis.com\";\n } else if (this.isVertexExpress) {\n return \"aiplatform.googleapis.com\";\n } else if (this.location === \"global\") {\n // See https://docs.cloud.google.com/vertex-ai/generative-ai/docs/learn/locations#use_the_global_endpoint\n return \"aiplatform.googleapis.com\";\n } else {\n return `${this.location}-aiplatform.googleapis.com`;\n }\n }\n\n protected get publisher(): string {\n return \"google\";\n }\n\n protected get urlMethod(): string {\n return this.streaming ? \"streamGenerateContent?alt=sse\" : \"generateContent\";\n }\n\n /**\n * Returns the model profile for this instance's model, describing its\n * capabilities and constraints (e.g. max tokens, input/output modalities,\n * tool calling support).\n *\n * @example\n * ```typescript\n * const model = new ChatGoogle({ model: \"gemini-2.5-pro\" });\n * const profile = model.profile;\n * console.log(profile.maxInputTokens); // 1048576\n * console.log(profile.imageInputs); // true\n * ```\n */\n get profile(): ModelProfile {\n return PROFILES[this.model] ?? {};\n }\n\n protected async buildUrlGemini(urlMethod?: string): Promise<string> {\n return `https://${this.endpoint}/${this.apiVersion}/models/${this.model}:${\n urlMethod ?? this.urlMethod\n }`;\n }\n\n protected async buildUrlVertexExpress(urlMethod?: string): Promise<string> {\n return `https://${this.endpoint}/${this.apiVersion}/publishers/${\n this.publisher\n }/models/${this.model}:${urlMethod ?? this.urlMethod}`;\n }\n\n protected async buildUrlVertexLocation(urlMethod?: string): Promise<string> {\n const projectId = await this.apiClient.getProjectId();\n return `https://${this.endpoint}/${\n this.apiVersion\n }/projects/${projectId}/locations/${this.location}/publishers/${\n this.publisher\n }/models/${this.model}:${urlMethod ?? this.urlMethod}`;\n }\n\n protected async buildUrlVertex(urlMethod?: string): Promise<string> {\n if (this.isVertexExpress) {\n return this.buildUrlVertexExpress(urlMethod);\n } else {\n return this.buildUrlVertexLocation(urlMethod);\n }\n }\n\n protected async buildUrl(urlMethod?: string): Promise<string> {\n switch (this.platform) {\n case \"gai\":\n return this.buildUrlGemini(urlMethod);\n default:\n return this.buildUrlVertex(urlMethod);\n }\n }\n\n override invocationParams(options: this[\"ParsedCallOptions\"]) {\n const fields = combineGoogleChatModelFields(this.params, options);\n\n // Convert tools to Gemini format\n const tools = fields.tools\n ? convertToolsToGeminiTools(fields.tools)\n : undefined;\n\n // Convert tool choice to Gemini function calling config\n const toolConfig = convertToolChoiceToGeminiConfig(\n options.tool_choice,\n !!(tools && tools.length > 0)\n );\n\n let responseJsonSchema:\n | JsonSchema7Type\n | Record<string, unknown>\n | undefined;\n let responseMimeType: string | undefined;\n\n if (fields.responseSchema) {\n // Convert Zod schema to JSON Schema if needed\n if (isInteropZodSchema(fields.responseSchema)) {\n responseJsonSchema = toJsonSchema(fields.responseSchema);\n } else {\n responseJsonSchema = fields.responseSchema as Record<string, unknown>;\n }\n // Automatically set responseMimeType to \"application/json\" when schema is provided\n responseMimeType = \"application/json\";\n }\n\n return {\n ...(tools && tools.length > 0 ? { tools } : {}),\n ...(toolConfig ? { toolConfig } : {}),\n safetySettings: fields.safetySettings,\n generationConfig: {\n temperature: fields.temperature,\n topP: fields.topP,\n topK: fields.topK,\n maxOutputTokens: fields.maxOutputTokens,\n presencePenalty: fields.presencePenalty,\n frequencyPenalty: fields.frequencyPenalty,\n stopSequences: fields.stopSequences,\n ...(responseMimeType ? { responseMimeType } : {}),\n ...(responseJsonSchema ? { responseJsonSchema } : {}),\n ...(fields.responseModalities && fields.responseModalities.length > 0\n ? { responseModalities: fields.responseModalities }\n : {}),\n candidateCount: 1,\n seed: fields.seed,\n responseLogprobs: fields.responseLogprobs,\n logprobs: fields.logprobs,\n ...(fields.enableEnhancedCivicAnswers !== undefined\n ? { enableEnhancedCivicAnswers: fields.enableEnhancedCivicAnswers }\n : {}),\n thinkingConfig: convertFieldsToThinkingConfig(this.model, fields),\n speechConfig: convertFieldsToSpeechConfig(fields),\n ...(fields.imageConfig ? { imageConfig: fields.imageConfig } : {}),\n ...(fields.mediaResolution\n ? { mediaResolution: fields.mediaResolution }\n : {}),\n },\n };\n }\n\n async _generate(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n if (this.streaming) {\n const stream = await this._streamResponseChunks(\n messages,\n options,\n runManager\n );\n let finalChunk: ChatGenerationChunk | null = null;\n for await (const chunk of stream) {\n finalChunk = !finalChunk ? chunk : concat(finalChunk, chunk);\n }\n if (\n typeof finalChunk?.message?.content === \"string\" &&\n typeof (\n finalChunk?.message?.additional_kwargs\n ?.originalTextContentBlock as Record<string, unknown>\n )?.text === \"string\"\n ) {\n (\n finalChunk.message.additional_kwargs\n .originalTextContentBlock as Record<string, unknown>\n ).text = finalChunk.message.content;\n }\n return {\n generations: finalChunk ? [finalChunk] : [],\n };\n }\n\n const url = await this.buildUrl();\n const body = {\n ...this.invocationParams(options),\n systemInstruction: convertMessagesToGeminiSystemInstruction(messages),\n contents: convertMessagesToGeminiContents(messages),\n };\n\n const moduleName = this.constructor.name;\n await runManager?.handleCustomEvent(`google-request-${moduleName}`, {\n url,\n body,\n });\n\n const response = await this.apiClient.fetch(\n new Request(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n })\n );\n\n if (!response.ok) {\n const error = await RequestError.fromResponse(response);\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n error,\n });\n throw error;\n }\n\n const data: Gemini.GenerateContentResponse = await response.json();\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n data,\n url: response.url,\n headers: response.headers,\n status: response.status,\n statusText: response.statusText,\n });\n\n // Check for prompt feedback errors\n if (data.promptFeedback?.blockReason) {\n throw PromptBlockedError.fromPromptFeedback(data.promptFeedback);\n }\n\n // Check if we have candidates\n if (!data.candidates || data.candidates.length === 0) {\n throw new NoCandidatesError();\n }\n\n // Use the first candidate\n const candidate = data.candidates[0];\n const message = convertGeminiCandidateToAIMessage(candidate);\n\n // Extract text content from the message\n const text = convertAIMessageToText(message);\n\n const usageMetadata =\n convertGeminiGenerateContentResponseToUsageMetadata(data);\n message.usage_metadata = usageMetadata;\n\n return {\n generations: [\n {\n text,\n message,\n generationInfo: {\n finishReason: candidate.finishReason,\n finishMessage: candidate.finishMessage,\n safetyRatings: candidate.safetyRatings,\n citationMetadata: candidate.citationMetadata,\n tokenCount: candidate.tokenCount,\n },\n },\n ],\n llmOutput: {\n tokenUsage: usageMetadata,\n model: data.modelVersion,\n responseId: data.responseId,\n usageMetadata,\n },\n };\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const streamUsage: boolean = this.streamUsage ?? true;\n\n const body = {\n ...this.invocationParams(options),\n systemInstruction: convertMessagesToGeminiSystemInstruction(messages),\n contents: convertMessagesToGeminiContents(messages),\n };\n\n const url = await this.buildUrl(\"streamGenerateContent?alt=sse\");\n const moduleName = this.constructor.name;\n await runManager?.handleCustomEvent(`google-request-${moduleName}`, {\n url,\n body,\n });\n\n const response = await this.apiClient.fetch(\n new Request(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n signal: options.signal,\n })\n );\n\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n url: response.url,\n headers: response.headers,\n status: response.status,\n statusText: response.statusText,\n });\n\n if (!response.ok) {\n const error = await RequestError.fromResponse(response);\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n error,\n });\n throw error;\n }\n\n if (response.body) {\n const stream = response.body\n .pipeThrough(new TextDecoderStream())\n .pipeThrough(new EventSourceParserStream())\n .pipeThrough(\n new SafeJsonEventParserStream<Gemini.GenerateContentResponse>()\n )\n .pipeThrough(\n new TransformStream<\n Gemini.GenerateContentResponse,\n ChatGenerationChunk\n >({\n transform(chunk, controller) {\n // eslint-disable-next-line no-void\n void runManager?.handleCustomEvent(`google-chunk-${moduleName}`, {\n chunk,\n });\n if (chunk === null) {\n controller.enqueue(\n new ChatGenerationChunk({\n text: \"\",\n message: new AIMessageChunk({ content: \"\" }),\n generationInfo: { finishReason: \"stop\" },\n })\n );\n return;\n }\n\n // Extract text delta from the chunk\n const candidate = chunk.candidates?.[0];\n if (!candidate) {\n return;\n }\n\n const message = convertGeminiCandidateToAIMessage(candidate);\n const text = convertAIMessageToText(message);\n\n const parts = candidate.content?.parts ?? [];\n const toolCalls = convertGeminiPartsToToolCalls(parts);\n\n // Only emit if we have content\n if (parts.length > 0 || candidate.finishReason) {\n const messageChunkParams: AIMessageChunkFields = {\n content: message.content,\n tool_calls: toolCalls,\n response_metadata: {\n model_provider: \"google\",\n },\n additional_kwargs: {\n ...(message.additional_kwargs.originalTextContentBlock\n ? {\n originalTextContentBlock:\n message.additional_kwargs.originalTextContentBlock,\n }\n : {}),\n ...(candidate.finishReason\n ? {\n finishReason: candidate.finishReason,\n finishMessage: candidate.finishMessage,\n }\n : {}),\n },\n };\n\n // Include usageMetadata if there is any and we have\n // enabled it with streamUsage on\n if (chunk?.usageMetadata && streamUsage) {\n messageChunkParams.usage_metadata =\n convertGeminiGenerateContentResponseToUsageMetadata(chunk);\n }\n const messageChunk = new AIMessageChunk(messageChunkParams);\n\n controller.enqueue(\n new ChatGenerationChunk({\n text: text,\n message: messageChunk,\n generationInfo: {\n ...(candidate.finishReason && {\n finishReason: candidate.finishReason,\n finishMessage: candidate.finishMessage,\n }),\n ...(candidate.safetyRatings && {\n safetyRatings: candidate.safetyRatings,\n }),\n },\n })\n );\n }\n },\n })\n );\n\n const reader = stream.getReader();\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n yield value;\n if (value.text) {\n await runManager?.handleLLMNewToken(\n value.text,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: value }\n );\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n }\n\n /**\n * Bind tool-like objects to this chat model.\n *\n * @param tools A list of tool definitions to bind to this chat model.\n * Can be a structured tool, an OpenAI formatted tool, or a Gemini function declaration.\n * @param kwargs Any additional parameters to bind.\n */\n bindTools(\n tools: BindToolsInput[],\n kwargs?: Partial<CallOptions>\n ): Runnable<BaseMessage[], AIMessageChunk, CallOptions> {\n return this.withConfig({\n ...kwargs,\n tools,\n } as Partial<CallOptions>);\n }\n\n /**\n * Get structured output from the model based on a schema.\n *\n * This method supports two modes:\n * - `jsonMode`: Uses `responseSchema` to get JSON responses directly (preferred for structured outputs)\n * - `functionCalling`: Uses function calling with tools (default, for compatibility)\n *\n * @param outputSchema - The schema to use for structured output (Zod schema or JSON Schema)\n * @param config - Configuration options including method and whether to include raw response\n * @returns A Runnable that returns the parsed structured output\n */\n withStructuredOutput<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | Record<string, any>,\n config?: StructuredOutputMethodOptions<boolean>\n ):\n | Runnable<BaseLanguageModelInput, RunOutput>\n | Runnable<\n BaseLanguageModelInput,\n { raw: BaseMessage; parsed: RunOutput }\n > {\n let llm: Runnable<BaseMessage[], AIMessageChunk, CallOptions>;\n let outputParser: Runnable<BaseMessage, RunOutput>;\n\n const { schema, name, includeRaw } = {\n ...config,\n schema: outputSchema,\n };\n let method = config?.method ?? \"functionCalling\";\n\n if (method === \"jsonMode\") {\n console.warn(\n `\"jsonMode\" is not supported for Google models. Falling back to \"jsonSchema\".`\n );\n method = \"jsonSchema\";\n }\n\n if (method === \"jsonSchema\") {\n // Use JSON mode with responseSchema\n llm = this.withConfig({\n responseSchema: schema,\n } as Partial<CallOptions>);\n\n outputParser = RunnableLambda.from<BaseMessage, RunOutput>(\n async (input: BaseMessage): Promise<RunOutput> => {\n if (\n !AIMessage.isInstance(input) &&\n !AIMessageChunk.isInstance(input)\n ) {\n throw new MalformedOutputError({\n message: \"Input is not an AIMessage or AIMessageChunk.\",\n });\n }\n\n if (!input.text) {\n throw new MalformedOutputError({\n message:\n \"No content found in response. Cannot parse structured output.\",\n });\n }\n\n // Parse JSON and validate with schema\n if (isInteropZodSchema(schema)) {\n const zodParser = StructuredOutputParser.fromZodSchema(\n schema as InteropZodType<RunOutput>\n );\n return (await zodParser.parse(input.text)) as RunOutput;\n } else {\n const jsonParser = new JsonOutputParser<RunOutput>();\n return await jsonParser.parse(input.text);\n }\n }\n );\n } else if (method === \"functionCalling\") {\n // Use function calling mode\n let functionName = name ?? \"extract\";\n let tools: Gemini.Tool[];\n\n if (isInteropZodSchema(schema)) {\n const jsonSchema = schemaToGeminiParameters(schema);\n const description =\n typeof jsonSchema.description === \"string\"\n ? jsonSchema.description\n : \"A function available to call.\";\n tools = [\n {\n functionDeclarations: [\n {\n name: functionName,\n description,\n parameters: jsonSchema as Gemini.Tools.Schema,\n },\n ],\n },\n ];\n outputParser = new JsonOutputKeyToolsParser({\n returnSingle: true,\n keyName: functionName,\n zodSchema: schema,\n });\n } else {\n let geminiFunctionDefinition: Gemini.Tools.FunctionDeclaration;\n if (\n typeof schema.name === \"string\" &&\n typeof schema.parameters === \"object\" &&\n schema.parameters != null\n ) {\n geminiFunctionDefinition = schema as Gemini.Tools.FunctionDeclaration;\n functionName = schema.name;\n } else {\n // We are providing the schema for *just* the parameters\n const parameters = schemaToGeminiParameters(schema);\n geminiFunctionDefinition = {\n name: functionName,\n description: (schema as { description?: string }).description ?? \"\",\n parameters,\n };\n }\n tools = [\n {\n functionDeclarations: [geminiFunctionDefinition],\n },\n ];\n outputParser = new JsonOutputKeyToolsParser<RunOutput>({\n returnSingle: true,\n keyName: functionName,\n });\n }\n\n llm = this.bindTools(tools).withConfig({\n tool_choice: functionName,\n } as Partial<CallOptions>);\n } else {\n throw new ConfigurationError(\n `Unrecognized structured output method '${method}'. Expected 'functionCalling' or 'jsonSchema'`\n );\n }\n\n // Shared logic for handling includeRaw\n if (!includeRaw) {\n return llm.pipe(outputParser).withConfig({\n runName: \"ChatGoogleStructuredOutput\",\n }) as Runnable<BaseLanguageModelInput, RunOutput>;\n }\n\n const parserAssign = RunnablePassthrough.assign({\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n parsed: (input: any, config) => outputParser.invoke(input.raw, config),\n });\n const parserNone = RunnablePassthrough.assign({\n parsed: () => null,\n });\n const parsedWithFallback = parserAssign.withFallbacks({\n fallbacks: [parserNone],\n });\n return RunnableSequence.from<\n BaseLanguageModelInput,\n { raw: BaseMessage; parsed: RunOutput }\n >([\n {\n raw: llm,\n },\n parsedWithFallback,\n ]).withConfig({\n runName: \"ChatGoogleStructuredOutputRunnable\",\n });\n }\n}\n\ntype CombinableFields = Omit<BaseChatGoogleParams, \"model\">;\n\nexport function combineGoogleChatModelFields(\n a: CombinableFields,\n b: CombinableFields,\n ...rest: CombinableFields[]\n): CombinableFields {\n const combined: CombinableFields = {\n temperature: b.temperature ?? a.temperature,\n topP: b.topP ?? a.topP,\n topK: b.topK ?? a.topK,\n maxOutputTokens: b.maxOutputTokens ?? a.maxOutputTokens,\n presencePenalty: b.presencePenalty ?? a.presencePenalty,\n frequencyPenalty: b.frequencyPenalty ?? a.frequencyPenalty,\n stopSequences: b.stopSequences ?? a.stopSequences,\n seed: b.seed ?? a.seed,\n responseLogprobs: b.responseLogprobs ?? a.responseLogprobs,\n logprobs: b.logprobs ?? a.logprobs,\n safetySettings: b.safetySettings ?? a.safetySettings,\n responseSchema: b.responseSchema ?? a.responseSchema,\n tools: b.tools ?? a.tools,\n responseModalities: b.responseModalities ?? a.responseModalities,\n enableEnhancedCivicAnswers:\n b.enableEnhancedCivicAnswers ?? a.enableEnhancedCivicAnswers,\n speechConfig: b.speechConfig ?? a.speechConfig,\n imageConfig: b.imageConfig ?? a.imageConfig,\n mediaResolution: b.mediaResolution ?? a.mediaResolution,\n maxReasoningTokens: b.maxReasoningTokens ?? a.maxReasoningTokens,\n thinkingBudget: b.thinkingBudget ?? a.thinkingBudget,\n reasoningEffort: b.reasoningEffort ?? a.reasoningEffort,\n thinkingLevel: b.thinkingLevel ?? a.thinkingLevel,\n };\n if (rest.length > 0) {\n return combineGoogleChatModelFields(combined, rest[0], ...rest.slice(1));\n }\n return combined;\n}\n\nexport function getGoogleChatModelParams<TParams extends BaseChatGoogleParams>(\n modelOrParams: string | TParams,\n paramsArg?: Omit<TParams, \"model\">\n): TParams {\n const model =\n typeof modelOrParams === \"string\" ? modelOrParams : modelOrParams.model;\n const params = typeof modelOrParams === \"string\" ? paramsArg : modelOrParams;\n return { model, ...params } as TParams;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"base.cjs","names":["BaseChatModel","ConfigurationError","convertParamsToPlatformType","PROFILES","convertToolsToGeminiTools","convertToolChoiceToGeminiConfig","convertFieldsToThinkingConfig","convertFieldsToSpeechConfig","convertMessagesToGeminiSystemInstruction","convertMessagesToGeminiContents","RequestError","PromptBlockedError","NoCandidatesError","convertGeminiCandidateToAIMessage","convertAIMessageToText","convertGeminiGenerateContentResponseToUsageMetadata","EventSourceParserStream","SafeJsonEventParserStream","ChatGenerationChunk","AIMessageChunk","convertGeminiPartsToToolCalls","subtractUsageMetadata","RunnableLambda","AIMessage","MalformedOutputError","StructuredOutputParser","JsonOutputParser","schemaToGeminiParameters","JsonOutputKeyToolsParser","RunnablePassthrough","RunnableSequence"],"sources":["../../src/chat_models/base.ts"],"sourcesContent":["import {\n BaseChatModel,\n type BaseChatModelCallOptions,\n type BaseChatModelParams,\n} from \"@langchain/core/language_models/chat_models\";\nimport {\n AIMessage,\n AIMessageChunk,\n AIMessageChunkFields,\n BaseMessage,\n type UsageMetadata,\n} from \"@langchain/core/messages\";\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { concat } from \"@langchain/core/utils/stream\";\nimport { ChatGenerationChunk, ChatResult } from \"@langchain/core/outputs\";\nimport { EventSourceParserStream } from \"eventsource-parser/stream\";\nimport type { BindToolsInput } from \"@langchain/core/language_models/chat_models\";\nimport type { ModelProfile } from \"@langchain/core/language_models/profile\";\nimport PROFILES from \"./profiles.js\";\nimport type {\n BaseLanguageModelInput,\n StructuredOutputMethodOptions,\n} from \"@langchain/core/language_models/base\";\nimport {\n Runnable,\n RunnableLambda,\n RunnablePassthrough,\n RunnableSequence,\n} from \"@langchain/core/runnables\";\nimport {\n toJsonSchema,\n type JsonSchema7Type,\n} from \"@langchain/core/utils/json_schema\";\nimport {\n InteropZodType,\n isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\nimport {\n JsonOutputParser,\n StructuredOutputParser,\n} from \"@langchain/core/output_parsers\";\nimport { JsonOutputKeyToolsParser } from \"@langchain/core/output_parsers/openai_tools\";\n\nimport { ApiClient } from \"../clients/index.js\";\nimport type { ChatGoogleFields } from \"./types.js\";\nimport { SafeJsonEventParserStream } from \"../utils/stream.js\";\nimport {\n convertAIMessageToText,\n convertGeminiCandidateToAIMessage,\n convertGeminiGenerateContentResponseToUsageMetadata,\n convertGeminiPartsToToolCalls,\n convertMessagesToGeminiContents,\n convertMessagesToGeminiSystemInstruction,\n} from \"../converters/messages.js\";\nimport {\n ConfigurationError,\n MalformedOutputError,\n NoCandidatesError,\n PromptBlockedError,\n RequestError,\n} from \"../utils/errors.js\";\nimport {\n convertToolsToGeminiTools,\n convertToolChoiceToGeminiConfig,\n schemaToGeminiParameters,\n} from \"../converters/tools.js\";\nimport {\n convertParamsToPlatformType,\n convertFieldsToSpeechConfig,\n convertFieldsToThinkingConfig,\n} from \"../converters/params.js\";\nimport { Gemini } from \"./api-types.js\";\nimport { subtractUsageMetadata } from \"../utils/metadata.js\";\n\nexport type GooglePlatformType = \"gai\" | \"gcp\";\n\nexport function getPlatformType(\n platform: GooglePlatformType | undefined,\n hasApiKey: boolean\n): GooglePlatformType {\n if (typeof platform !== \"undefined\") {\n return platform;\n } else if (hasApiKey) {\n return \"gai\";\n } else {\n return \"gcp\";\n }\n}\n\nexport interface BaseChatGoogleParams\n extends BaseChatModelParams,\n ChatGoogleFields {\n /**\n * The name of the Gemini model to use.\n *\n * Example: \"gemini-3-pro-preview\"\n */\n model: string;\n\n /**\n * Optional. The API client implementation for making HTTP requests to the Gemini API.\n * If not set, a default client will be used based on the runtime environment.\n */\n apiClient?: ApiClient;\n\n /**\n * Hostname for the API call (if this is running on GCP)\n * Usually this is computed based on location and platformType.\n **/\n endpoint?: string;\n\n /**\n * Region where the LLM is stored (if this is running on GCP)\n * Defaults to \"global\"\n **/\n location?: string;\n\n /**\n * The version of the API functions. Part of the path.\n * Usually this is computed based on platformType.\n **/\n apiVersion?: string;\n\n /**\n * What platform to run the service on.\n * If not specified, the class should determine this from other\n * means. Either way, the platform actually used will be in\n * the \"platform\" getter.\n */\n platformType?: GooglePlatformType;\n\n /**\n * For compatibility with Google's libraries, should this use Vertex?\n * The \"platformType\" parmeter takes precedence.\n */\n vertexai?: boolean;\n\n /**\n * Backwards compatibility.\n * @deprecated in favor of using `disableStreaming` or `.stream()`\n */\n streaming?: boolean;\n\n streamUsage?: boolean;\n}\n\nexport interface BaseChatGoogleCallOptions\n extends BaseChatModelCallOptions,\n ChatGoogleFields {}\n\nexport abstract class BaseChatGoogle<\n CallOptions extends BaseChatGoogleCallOptions = BaseChatGoogleCallOptions\n> extends BaseChatModel<CallOptions, AIMessageChunk> {\n model: string;\n\n streaming: boolean;\n\n disableStreaming: boolean;\n\n streamUsage: boolean = true;\n\n protected _platform?: GooglePlatformType;\n\n protected _endpoint?: string;\n\n protected _location?: string;\n\n protected _apiVersion?: string;\n\n protected apiClient: ApiClient;\n\n constructor(protected params: BaseChatGoogleParams) {\n super(params);\n this._addVersion(\"@langchain/google\", __PKG_VERSION__);\n\n if (!params.apiClient) {\n throw new ConfigurationError(\n \"BaseChatGoogle requires an apiClient. This should be provided automatically by ChatGoogle constructors. If you're extending BaseChatGoogle directly, please provide an apiClient instance.\"\n );\n }\n this.apiClient = params.apiClient;\n\n this.model = params.model;\n this._platform = convertParamsToPlatformType(params);\n this._endpoint = params.endpoint;\n this._location = params.location;\n this._apiVersion = params.apiVersion;\n\n this.disableStreaming = params?.disableStreaming === true;\n this.streaming = params?.streaming === true;\n if (this.disableStreaming) this.streaming = false;\n // disable streaming in BaseChatModel if explicitly disabled\n if (params?.streaming === false) this.disableStreaming = true;\n\n this.streamUsage = params?.streamUsage ?? this.streamUsage;\n if (this.disableStreaming) this.streamUsage = false;\n }\n\n _llmType(): string {\n return \"google\";\n }\n\n protected get platformType(): GooglePlatformType | undefined {\n return this._platform;\n }\n\n protected get platform(): GooglePlatformType {\n return getPlatformType(this._platform, this.apiClient.hasApiKey());\n }\n\n protected get isVertexExpress(): boolean {\n return this.platform === \"gcp\" && this.apiClient.hasApiKey();\n }\n\n protected get apiVersion(): string {\n if (typeof this._apiVersion !== \"undefined\") {\n return this._apiVersion;\n } else if (this.platform === \"gai\") {\n return \"v1beta\";\n } else {\n return \"v1\";\n }\n }\n\n protected get location(): string {\n return this._location || \"global\";\n }\n\n protected get endpoint(): string {\n if (typeof this._endpoint !== \"undefined\") {\n return this._endpoint;\n } else if (this.platform === \"gai\") {\n return \"generativelanguage.googleapis.com\";\n } else if (this.isVertexExpress) {\n return \"aiplatform.googleapis.com\";\n } else if (this.location === \"global\") {\n // See https://docs.cloud.google.com/vertex-ai/generative-ai/docs/learn/locations#use_the_global_endpoint\n return \"aiplatform.googleapis.com\";\n } else {\n return `${this.location}-aiplatform.googleapis.com`;\n }\n }\n\n protected get publisher(): string {\n return \"google\";\n }\n\n protected get urlMethod(): string {\n return this.streaming ? \"streamGenerateContent?alt=sse\" : \"generateContent\";\n }\n\n /**\n * Returns the model profile for this instance's model, describing its\n * capabilities and constraints (e.g. max tokens, input/output modalities,\n * tool calling support).\n *\n * @example\n * ```typescript\n * const model = new ChatGoogle({ model: \"gemini-2.5-pro\" });\n * const profile = model.profile;\n * console.log(profile.maxInputTokens); // 1048576\n * console.log(profile.imageInputs); // true\n * ```\n */\n get profile(): ModelProfile {\n return PROFILES[this.model] ?? {};\n }\n\n protected async buildUrlGemini(urlMethod?: string): Promise<string> {\n return `https://${this.endpoint}/${this.apiVersion}/models/${this.model}:${\n urlMethod ?? this.urlMethod\n }`;\n }\n\n protected async buildUrlVertexExpress(urlMethod?: string): Promise<string> {\n return `https://${this.endpoint}/${this.apiVersion}/publishers/${\n this.publisher\n }/models/${this.model}:${urlMethod ?? this.urlMethod}`;\n }\n\n protected async buildUrlVertexLocation(urlMethod?: string): Promise<string> {\n const projectId = await this.apiClient.getProjectId();\n return `https://${this.endpoint}/${\n this.apiVersion\n }/projects/${projectId}/locations/${this.location}/publishers/${\n this.publisher\n }/models/${this.model}:${urlMethod ?? this.urlMethod}`;\n }\n\n protected async buildUrlVertex(urlMethod?: string): Promise<string> {\n if (this.isVertexExpress) {\n return this.buildUrlVertexExpress(urlMethod);\n } else {\n return this.buildUrlVertexLocation(urlMethod);\n }\n }\n\n protected async buildUrl(urlMethod?: string): Promise<string> {\n switch (this.platform) {\n case \"gai\":\n return this.buildUrlGemini(urlMethod);\n default:\n return this.buildUrlVertex(urlMethod);\n }\n }\n\n override invocationParams(options: this[\"ParsedCallOptions\"]) {\n const fields = combineGoogleChatModelFields(this.params, options);\n\n // Convert tools to Gemini format\n const tools = fields.tools\n ? convertToolsToGeminiTools(fields.tools)\n : undefined;\n\n // Convert tool choice to Gemini function calling config\n const toolConfig = convertToolChoiceToGeminiConfig(\n options.tool_choice,\n !!(tools && tools.length > 0)\n );\n\n let responseJsonSchema:\n | JsonSchema7Type\n | Record<string, unknown>\n | undefined;\n let responseMimeType: string | undefined;\n\n if (fields.responseSchema) {\n // Convert Zod schema to JSON Schema if needed\n if (isInteropZodSchema(fields.responseSchema)) {\n responseJsonSchema = toJsonSchema(fields.responseSchema);\n } else {\n responseJsonSchema = fields.responseSchema as Record<string, unknown>;\n }\n // Automatically set responseMimeType to \"application/json\" when schema is provided\n responseMimeType = \"application/json\";\n }\n\n return {\n ...(tools && tools.length > 0 ? { tools } : {}),\n ...(toolConfig ? { toolConfig } : {}),\n safetySettings: fields.safetySettings,\n generationConfig: {\n temperature: fields.temperature,\n topP: fields.topP,\n topK: fields.topK,\n maxOutputTokens: fields.maxOutputTokens,\n presencePenalty: fields.presencePenalty,\n frequencyPenalty: fields.frequencyPenalty,\n stopSequences: fields.stopSequences,\n ...(responseMimeType ? { responseMimeType } : {}),\n ...(responseJsonSchema ? { responseJsonSchema } : {}),\n ...(fields.responseModalities && fields.responseModalities.length > 0\n ? { responseModalities: fields.responseModalities }\n : {}),\n candidateCount: 1,\n seed: fields.seed,\n responseLogprobs: fields.responseLogprobs,\n logprobs: fields.logprobs,\n ...(fields.enableEnhancedCivicAnswers !== undefined\n ? { enableEnhancedCivicAnswers: fields.enableEnhancedCivicAnswers }\n : {}),\n thinkingConfig: convertFieldsToThinkingConfig(this.model, fields),\n speechConfig: convertFieldsToSpeechConfig(fields),\n ...(fields.imageConfig ? { imageConfig: fields.imageConfig } : {}),\n ...(fields.mediaResolution\n ? { mediaResolution: fields.mediaResolution }\n : {}),\n },\n };\n }\n\n async _generate(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n if (this.streaming) {\n const stream = await this._streamResponseChunks(\n messages,\n options,\n runManager\n );\n let finalChunk: ChatGenerationChunk | null = null;\n for await (const chunk of stream) {\n finalChunk = !finalChunk ? chunk : concat(finalChunk, chunk);\n }\n if (\n typeof finalChunk?.message?.content === \"string\" &&\n typeof (\n finalChunk?.message?.additional_kwargs\n ?.originalTextContentBlock as Record<string, unknown>\n )?.text === \"string\"\n ) {\n (\n finalChunk.message.additional_kwargs\n .originalTextContentBlock as Record<string, unknown>\n ).text = finalChunk.message.content;\n }\n return {\n generations: finalChunk ? [finalChunk] : [],\n };\n }\n\n const url = await this.buildUrl();\n const body = {\n ...this.invocationParams(options),\n systemInstruction: convertMessagesToGeminiSystemInstruction(messages),\n contents: convertMessagesToGeminiContents(messages),\n };\n\n const moduleName = this.constructor.name;\n await runManager?.handleCustomEvent(`google-request-${moduleName}`, {\n url,\n body,\n });\n\n const response = await this.apiClient.fetch(\n new Request(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n })\n );\n\n if (!response.ok) {\n const error = await RequestError.fromResponse(response);\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n error,\n });\n throw error;\n }\n\n const data: Gemini.GenerateContentResponse = await response.json();\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n data,\n url: response.url,\n headers: response.headers,\n status: response.status,\n statusText: response.statusText,\n });\n\n // Check for prompt feedback errors\n if (data.promptFeedback?.blockReason) {\n throw PromptBlockedError.fromPromptFeedback(data.promptFeedback);\n }\n\n // Check if we have candidates\n if (!data.candidates || data.candidates.length === 0) {\n throw new NoCandidatesError();\n }\n\n // Use the first candidate\n const candidate = data.candidates[0];\n const message = convertGeminiCandidateToAIMessage(candidate);\n\n // Extract text content from the message\n const text = convertAIMessageToText(message);\n\n const usageMetadata =\n convertGeminiGenerateContentResponseToUsageMetadata(data);\n message.usage_metadata = usageMetadata;\n\n return {\n generations: [\n {\n text,\n message,\n generationInfo: {\n finishReason: candidate.finishReason,\n finishMessage: candidate.finishMessage,\n safetyRatings: candidate.safetyRatings,\n citationMetadata: candidate.citationMetadata,\n tokenCount: candidate.tokenCount,\n },\n },\n ],\n llmOutput: {\n tokenUsage: usageMetadata,\n model: data.modelVersion,\n responseId: data.responseId,\n usageMetadata,\n },\n };\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const streamUsage: boolean = this.streamUsage ?? true;\n\n const body = {\n ...this.invocationParams(options),\n systemInstruction: convertMessagesToGeminiSystemInstruction(messages),\n contents: convertMessagesToGeminiContents(messages),\n };\n\n const url = await this.buildUrl(\"streamGenerateContent?alt=sse\");\n const moduleName = this.constructor.name;\n await runManager?.handleCustomEvent(`google-request-${moduleName}`, {\n url,\n body,\n });\n\n const response = await this.apiClient.fetch(\n new Request(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n signal: options.signal,\n })\n );\n\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n url: response.url,\n headers: response.headers,\n status: response.status,\n statusText: response.statusText,\n });\n\n if (!response.ok) {\n const error = await RequestError.fromResponse(response);\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n error,\n });\n throw error;\n }\n\n if (response.body) {\n let previousUsage: UsageMetadata | undefined;\n const stream = response.body\n .pipeThrough(new TextDecoderStream())\n .pipeThrough(new EventSourceParserStream())\n .pipeThrough(\n new SafeJsonEventParserStream<Gemini.GenerateContentResponse>()\n )\n .pipeThrough(\n new TransformStream<\n Gemini.GenerateContentResponse,\n ChatGenerationChunk\n >({\n transform(chunk, controller) {\n // eslint-disable-next-line no-void\n void runManager?.handleCustomEvent(`google-chunk-${moduleName}`, {\n chunk,\n });\n if (chunk === null) {\n controller.enqueue(\n new ChatGenerationChunk({\n text: \"\",\n message: new AIMessageChunk({ content: \"\" }),\n generationInfo: { finishReason: \"stop\" },\n })\n );\n return;\n }\n\n // Extract text delta from the chunk\n const candidate = chunk.candidates?.[0];\n if (!candidate) {\n return;\n }\n\n const message = convertGeminiCandidateToAIMessage(candidate);\n const text = convertAIMessageToText(message);\n\n const parts = candidate.content?.parts ?? [];\n const toolCalls = convertGeminiPartsToToolCalls(parts);\n\n // Only emit if we have content\n if (parts.length > 0 || candidate.finishReason) {\n const messageChunkParams: AIMessageChunkFields = {\n content: message.content,\n tool_calls: toolCalls,\n response_metadata: {\n model_provider: \"google\",\n },\n additional_kwargs: {\n ...(message.additional_kwargs.originalTextContentBlock\n ? {\n originalTextContentBlock:\n message.additional_kwargs.originalTextContentBlock,\n }\n : {}),\n ...(candidate.finishReason\n ? {\n finishReason: candidate.finishReason,\n finishMessage: candidate.finishMessage,\n }\n : {}),\n },\n };\n\n if (chunk?.usageMetadata && streamUsage) {\n const cumulative =\n convertGeminiGenerateContentResponseToUsageMetadata(chunk);\n messageChunkParams.usage_metadata = subtractUsageMetadata(\n cumulative,\n previousUsage\n );\n previousUsage = cumulative;\n }\n const messageChunk = new AIMessageChunk(messageChunkParams);\n\n controller.enqueue(\n new ChatGenerationChunk({\n text: text,\n message: messageChunk,\n generationInfo: {\n ...(candidate.finishReason && {\n finishReason: candidate.finishReason,\n finishMessage: candidate.finishMessage,\n }),\n ...(candidate.safetyRatings && {\n safetyRatings: candidate.safetyRatings,\n }),\n },\n })\n );\n }\n },\n })\n );\n\n const reader = stream.getReader();\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n yield value;\n await runManager?.handleLLMNewToken(\n value.text ?? \"\",\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: value }\n );\n }\n } finally {\n reader.releaseLock();\n }\n }\n }\n\n /**\n * Bind tool-like objects to this chat model.\n *\n * @param tools A list of tool definitions to bind to this chat model.\n * Can be a structured tool, an OpenAI formatted tool, or a Gemini function declaration.\n * @param kwargs Any additional parameters to bind.\n */\n bindTools(\n tools: BindToolsInput[],\n kwargs?: Partial<CallOptions>\n ): Runnable<BaseMessage[], AIMessageChunk, CallOptions> {\n return this.withConfig({\n ...kwargs,\n tools,\n } as Partial<CallOptions>);\n }\n\n /**\n * Get structured output from the model based on a schema.\n *\n * This method supports two modes:\n * - `jsonMode`: Uses `responseSchema` to get JSON responses directly (preferred for structured outputs)\n * - `functionCalling`: Uses function calling with tools (default, for compatibility)\n *\n * @param outputSchema - The schema to use for structured output (Zod schema or JSON Schema)\n * @param config - Configuration options including method and whether to include raw response\n * @returns A Runnable that returns the parsed structured output\n */\n withStructuredOutput<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | Record<string, any>,\n config?: StructuredOutputMethodOptions<boolean>\n ):\n | Runnable<BaseLanguageModelInput, RunOutput>\n | Runnable<\n BaseLanguageModelInput,\n { raw: BaseMessage; parsed: RunOutput }\n > {\n let llm: Runnable<BaseMessage[], AIMessageChunk, CallOptions>;\n let outputParser: Runnable<BaseMessage, RunOutput>;\n\n const { schema, name, includeRaw } = {\n ...config,\n schema: outputSchema,\n };\n let method = config?.method ?? \"functionCalling\";\n\n if (method === \"jsonMode\") {\n console.warn(\n `\"jsonMode\" is not supported for Google models. Falling back to \"jsonSchema\".`\n );\n method = \"jsonSchema\";\n }\n\n if (method === \"jsonSchema\") {\n // Use JSON mode with responseSchema\n llm = this.withConfig({\n responseSchema: schema,\n } as Partial<CallOptions>);\n\n outputParser = RunnableLambda.from<BaseMessage, RunOutput>(\n async (input: BaseMessage): Promise<RunOutput> => {\n if (\n !AIMessage.isInstance(input) &&\n !AIMessageChunk.isInstance(input)\n ) {\n throw new MalformedOutputError({\n message: \"Input is not an AIMessage or AIMessageChunk.\",\n });\n }\n\n if (!input.text) {\n throw new MalformedOutputError({\n message:\n \"No content found in response. Cannot parse structured output.\",\n });\n }\n\n // Parse JSON and validate with schema\n if (isInteropZodSchema(schema)) {\n const zodParser = StructuredOutputParser.fromZodSchema(\n schema as InteropZodType<RunOutput>\n );\n return (await zodParser.parse(input.text)) as RunOutput;\n } else {\n const jsonParser = new JsonOutputParser<RunOutput>();\n return await jsonParser.parse(input.text);\n }\n }\n );\n } else if (method === \"functionCalling\") {\n // Use function calling mode\n let functionName = name ?? \"extract\";\n let tools: Gemini.Tool[];\n\n if (isInteropZodSchema(schema)) {\n const jsonSchema = schemaToGeminiParameters(schema);\n const description =\n typeof jsonSchema.description === \"string\"\n ? jsonSchema.description\n : \"A function available to call.\";\n tools = [\n {\n functionDeclarations: [\n {\n name: functionName,\n description,\n parameters: jsonSchema as Gemini.Tools.Schema,\n },\n ],\n },\n ];\n outputParser = new JsonOutputKeyToolsParser({\n returnSingle: true,\n keyName: functionName,\n zodSchema: schema,\n });\n } else {\n let geminiFunctionDefinition: Gemini.Tools.FunctionDeclaration;\n if (\n typeof schema.name === \"string\" &&\n typeof schema.parameters === \"object\" &&\n schema.parameters != null\n ) {\n geminiFunctionDefinition = schema as Gemini.Tools.FunctionDeclaration;\n functionName = schema.name;\n } else {\n // We are providing the schema for *just* the parameters\n const parameters = schemaToGeminiParameters(schema);\n geminiFunctionDefinition = {\n name: functionName,\n description: (schema as { description?: string }).description ?? \"\",\n parameters,\n };\n }\n tools = [\n {\n functionDeclarations: [geminiFunctionDefinition],\n },\n ];\n outputParser = new JsonOutputKeyToolsParser<RunOutput>({\n returnSingle: true,\n keyName: functionName,\n });\n }\n\n llm = this.bindTools(tools).withConfig({\n tool_choice: functionName,\n } as Partial<CallOptions>);\n } else {\n throw new ConfigurationError(\n `Unrecognized structured output method '${method}'. Expected 'functionCalling' or 'jsonSchema'`\n );\n }\n\n // Shared logic for handling includeRaw\n if (!includeRaw) {\n return llm.pipe(outputParser).withConfig({\n runName: \"ChatGoogleStructuredOutput\",\n }) as Runnable<BaseLanguageModelInput, RunOutput>;\n }\n\n const parserAssign = RunnablePassthrough.assign({\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n parsed: (input: any, config) => outputParser.invoke(input.raw, config),\n });\n const parserNone = RunnablePassthrough.assign({\n parsed: () => null,\n });\n const parsedWithFallback = parserAssign.withFallbacks({\n fallbacks: [parserNone],\n });\n return RunnableSequence.from<\n BaseLanguageModelInput,\n { raw: BaseMessage; parsed: RunOutput }\n >([\n {\n raw: llm,\n },\n parsedWithFallback,\n ]).withConfig({\n runName: \"ChatGoogleStructuredOutputRunnable\",\n });\n }\n}\n\ntype CombinableFields = Omit<BaseChatGoogleParams, \"model\">;\n\nexport function combineGoogleChatModelFields(\n a: CombinableFields,\n b: CombinableFields,\n ...rest: CombinableFields[]\n): CombinableFields {\n const combined: CombinableFields = {\n temperature: b.temperature ?? a.temperature,\n topP: b.topP ?? a.topP,\n topK: b.topK ?? a.topK,\n maxOutputTokens: b.maxOutputTokens ?? a.maxOutputTokens,\n presencePenalty: b.presencePenalty ?? a.presencePenalty,\n frequencyPenalty: b.frequencyPenalty ?? a.frequencyPenalty,\n stopSequences: b.stopSequences ?? a.stopSequences,\n seed: b.seed ?? a.seed,\n responseLogprobs: b.responseLogprobs ?? a.responseLogprobs,\n logprobs: b.logprobs ?? a.logprobs,\n safetySettings: b.safetySettings ?? a.safetySettings,\n responseSchema: b.responseSchema ?? a.responseSchema,\n tools: b.tools ?? a.tools,\n responseModalities: b.responseModalities ?? a.responseModalities,\n enableEnhancedCivicAnswers:\n b.enableEnhancedCivicAnswers ?? a.enableEnhancedCivicAnswers,\n speechConfig: b.speechConfig ?? a.speechConfig,\n imageConfig: b.imageConfig ?? a.imageConfig,\n mediaResolution: b.mediaResolution ?? a.mediaResolution,\n maxReasoningTokens: b.maxReasoningTokens ?? a.maxReasoningTokens,\n thinkingBudget: b.thinkingBudget ?? a.thinkingBudget,\n reasoningEffort: b.reasoningEffort ?? a.reasoningEffort,\n thinkingLevel: b.thinkingLevel ?? a.thinkingLevel,\n };\n if (rest.length > 0) {\n return combineGoogleChatModelFields(combined, rest[0], ...rest.slice(1));\n }\n return combined;\n}\n\nexport function getGoogleChatModelParams<TParams extends BaseChatGoogleParams>(\n modelOrParams: string | TParams,\n paramsArg?: Omit<TParams, \"model\">\n): TParams {\n const model =\n typeof modelOrParams === \"string\" ? modelOrParams : modelOrParams.model;\n const params = typeof modelOrParams === \"string\" ? paramsArg : modelOrParams;\n return { model, ...params } as TParams;\n}\n"],"mappings":"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"}
|
package/dist/chat_models/base.js
CHANGED
|
@@ -4,6 +4,7 @@ import { SafeJsonEventParserStream } from "../utils/stream.js";
|
|
|
4
4
|
import { convertAIMessageToText, convertGeminiCandidateToAIMessage, convertGeminiGenerateContentResponseToUsageMetadata, convertGeminiPartsToToolCalls, convertMessagesToGeminiContents, convertMessagesToGeminiSystemInstruction } from "../converters/messages.js";
|
|
5
5
|
import { convertToolChoiceToGeminiConfig, convertToolsToGeminiTools, schemaToGeminiParameters } from "../converters/tools.js";
|
|
6
6
|
import { convertFieldsToSpeechConfig, convertFieldsToThinkingConfig, convertParamsToPlatformType } from "../converters/params.js";
|
|
7
|
+
import { subtractUsageMetadata } from "../utils/metadata.js";
|
|
7
8
|
import { BaseChatModel } from "@langchain/core/language_models/chat_models";
|
|
8
9
|
import { AIMessage, AIMessageChunk } from "@langchain/core/messages";
|
|
9
10
|
import { concat } from "@langchain/core/utils/stream";
|
|
@@ -34,6 +35,7 @@ var BaseChatGoogle = class extends BaseChatModel {
|
|
|
34
35
|
constructor(params) {
|
|
35
36
|
super(params);
|
|
36
37
|
this.params = params;
|
|
38
|
+
this._addVersion("@langchain/google", "0.1.3");
|
|
37
39
|
if (!params.apiClient) throw new ConfigurationError("BaseChatGoogle requires an apiClient. This should be provided automatically by ChatGoogle constructors. If you're extending BaseChatGoogle directly, please provide an apiClient instance.");
|
|
38
40
|
this.apiClient = params.apiClient;
|
|
39
41
|
this.model = params.model;
|
|
@@ -250,6 +252,7 @@ var BaseChatGoogle = class extends BaseChatModel {
|
|
|
250
252
|
throw error;
|
|
251
253
|
}
|
|
252
254
|
if (response.body) {
|
|
255
|
+
let previousUsage;
|
|
253
256
|
const reader = response.body.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream()).pipeThrough(new SafeJsonEventParserStream()).pipeThrough(new TransformStream({ transform(chunk, controller) {
|
|
254
257
|
runManager?.handleCustomEvent(`google-chunk-${moduleName}`, { chunk });
|
|
255
258
|
if (chunk === null) {
|
|
@@ -279,7 +282,11 @@ var BaseChatGoogle = class extends BaseChatModel {
|
|
|
279
282
|
} : {}
|
|
280
283
|
}
|
|
281
284
|
};
|
|
282
|
-
if (chunk?.usageMetadata && streamUsage)
|
|
285
|
+
if (chunk?.usageMetadata && streamUsage) {
|
|
286
|
+
const cumulative = convertGeminiGenerateContentResponseToUsageMetadata(chunk);
|
|
287
|
+
messageChunkParams.usage_metadata = subtractUsageMetadata(cumulative, previousUsage);
|
|
288
|
+
previousUsage = cumulative;
|
|
289
|
+
}
|
|
283
290
|
const messageChunk = new AIMessageChunk(messageChunkParams);
|
|
284
291
|
controller.enqueue(new ChatGenerationChunk({
|
|
285
292
|
text,
|
|
@@ -299,7 +306,7 @@ var BaseChatGoogle = class extends BaseChatModel {
|
|
|
299
306
|
const { done, value } = await reader.read();
|
|
300
307
|
if (done) break;
|
|
301
308
|
yield value;
|
|
302
|
-
|
|
309
|
+
await runManager?.handleLLMNewToken(value.text ?? "", void 0, void 0, void 0, void 0, { chunk: value });
|
|
303
310
|
}
|
|
304
311
|
} finally {
|
|
305
312
|
reader.releaseLock();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","names":[],"sources":["../../src/chat_models/base.ts"],"sourcesContent":["import {\n BaseChatModel,\n type BaseChatModelCallOptions,\n type BaseChatModelParams,\n} from \"@langchain/core/language_models/chat_models\";\nimport {\n AIMessage,\n AIMessageChunk,\n AIMessageChunkFields,\n BaseMessage,\n} from \"@langchain/core/messages\";\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { concat } from \"@langchain/core/utils/stream\";\nimport { ChatGenerationChunk, ChatResult } from \"@langchain/core/outputs\";\nimport { EventSourceParserStream } from \"eventsource-parser/stream\";\nimport type { BindToolsInput } from \"@langchain/core/language_models/chat_models\";\nimport type { ModelProfile } from \"@langchain/core/language_models/profile\";\nimport PROFILES from \"./profiles.js\";\nimport type {\n BaseLanguageModelInput,\n StructuredOutputMethodOptions,\n} from \"@langchain/core/language_models/base\";\nimport {\n Runnable,\n RunnableLambda,\n RunnablePassthrough,\n RunnableSequence,\n} from \"@langchain/core/runnables\";\nimport {\n toJsonSchema,\n type JsonSchema7Type,\n} from \"@langchain/core/utils/json_schema\";\nimport {\n InteropZodType,\n isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\nimport {\n JsonOutputParser,\n StructuredOutputParser,\n} from \"@langchain/core/output_parsers\";\nimport { JsonOutputKeyToolsParser } from \"@langchain/core/output_parsers/openai_tools\";\n\nimport { ApiClient } from \"../clients/index.js\";\nimport type { ChatGoogleFields } from \"./types.js\";\nimport { SafeJsonEventParserStream } from \"../utils/stream.js\";\nimport {\n convertAIMessageToText,\n convertGeminiCandidateToAIMessage,\n convertGeminiGenerateContentResponseToUsageMetadata,\n convertGeminiPartsToToolCalls,\n convertMessagesToGeminiContents,\n convertMessagesToGeminiSystemInstruction,\n} from \"../converters/messages.js\";\nimport {\n ConfigurationError,\n MalformedOutputError,\n NoCandidatesError,\n PromptBlockedError,\n RequestError,\n} from \"../utils/errors.js\";\nimport {\n convertToolsToGeminiTools,\n convertToolChoiceToGeminiConfig,\n schemaToGeminiParameters,\n} from \"../converters/tools.js\";\nimport {\n convertParamsToPlatformType,\n convertFieldsToSpeechConfig,\n convertFieldsToThinkingConfig,\n} from \"../converters/params.js\";\nimport { Gemini } from \"./api-types.js\";\n\nexport type GooglePlatformType = \"gai\" | \"gcp\";\n\nexport function getPlatformType(\n platform: GooglePlatformType | undefined,\n hasApiKey: boolean\n): GooglePlatformType {\n if (typeof platform !== \"undefined\") {\n return platform;\n } else if (hasApiKey) {\n return \"gai\";\n } else {\n return \"gcp\";\n }\n}\n\nexport interface BaseChatGoogleParams\n extends BaseChatModelParams,\n ChatGoogleFields {\n /**\n * The name of the Gemini model to use.\n *\n * Example: \"gemini-3-pro-preview\"\n */\n model: string;\n\n /**\n * Optional. The API client implementation for making HTTP requests to the Gemini API.\n * If not set, a default client will be used based on the runtime environment.\n */\n apiClient?: ApiClient;\n\n /**\n * Hostname for the API call (if this is running on GCP)\n * Usually this is computed based on location and platformType.\n **/\n endpoint?: string;\n\n /**\n * Region where the LLM is stored (if this is running on GCP)\n * Defaults to \"global\"\n **/\n location?: string;\n\n /**\n * The version of the API functions. Part of the path.\n * Usually this is computed based on platformType.\n **/\n apiVersion?: string;\n\n /**\n * What platform to run the service on.\n * If not specified, the class should determine this from other\n * means. Either way, the platform actually used will be in\n * the \"platform\" getter.\n */\n platformType?: GooglePlatformType;\n\n /**\n * For compatibility with Google's libraries, should this use Vertex?\n * The \"platformType\" parmeter takes precedence.\n */\n vertexai?: boolean;\n\n /**\n * Backwards compatibility.\n * @deprecated in favor of using `disableStreaming` or `.stream()`\n */\n streaming?: boolean;\n\n streamUsage?: boolean;\n}\n\nexport interface BaseChatGoogleCallOptions\n extends BaseChatModelCallOptions,\n ChatGoogleFields {}\n\nexport abstract class BaseChatGoogle<\n CallOptions extends BaseChatGoogleCallOptions = BaseChatGoogleCallOptions\n> extends BaseChatModel<CallOptions, AIMessageChunk> {\n model: string;\n\n streaming: boolean;\n\n disableStreaming: boolean;\n\n streamUsage: boolean = true;\n\n protected _platform?: GooglePlatformType;\n\n protected _endpoint?: string;\n\n protected _location?: string;\n\n protected _apiVersion?: string;\n\n protected apiClient: ApiClient;\n\n constructor(protected params: BaseChatGoogleParams) {\n super(params);\n\n if (!params.apiClient) {\n throw new ConfigurationError(\n \"BaseChatGoogle requires an apiClient. This should be provided automatically by ChatGoogle constructors. If you're extending BaseChatGoogle directly, please provide an apiClient instance.\"\n );\n }\n this.apiClient = params.apiClient;\n\n this.model = params.model;\n this._platform = convertParamsToPlatformType(params);\n this._endpoint = params.endpoint;\n this._location = params.location;\n this._apiVersion = params.apiVersion;\n\n this.disableStreaming = params?.disableStreaming === true;\n this.streaming = params?.streaming === true;\n if (this.disableStreaming) this.streaming = false;\n // disable streaming in BaseChatModel if explicitly disabled\n if (params?.streaming === false) this.disableStreaming = true;\n\n this.streamUsage = params?.streamUsage ?? this.streamUsage;\n if (this.disableStreaming) this.streamUsage = false;\n }\n\n _llmType(): string {\n return \"google\";\n }\n\n protected get platformType(): GooglePlatformType | undefined {\n return this._platform;\n }\n\n protected get platform(): GooglePlatformType {\n return getPlatformType(this._platform, this.apiClient.hasApiKey());\n }\n\n protected get isVertexExpress(): boolean {\n return this.platform === \"gcp\" && this.apiClient.hasApiKey();\n }\n\n protected get apiVersion(): string {\n if (typeof this._apiVersion !== \"undefined\") {\n return this._apiVersion;\n } else if (this.platform === \"gai\") {\n return \"v1beta\";\n } else {\n return \"v1\";\n }\n }\n\n protected get location(): string {\n return this._location || \"global\";\n }\n\n protected get endpoint(): string {\n if (typeof this._endpoint !== \"undefined\") {\n return this._endpoint;\n } else if (this.platform === \"gai\") {\n return \"generativelanguage.googleapis.com\";\n } else if (this.isVertexExpress) {\n return \"aiplatform.googleapis.com\";\n } else if (this.location === \"global\") {\n // See https://docs.cloud.google.com/vertex-ai/generative-ai/docs/learn/locations#use_the_global_endpoint\n return \"aiplatform.googleapis.com\";\n } else {\n return `${this.location}-aiplatform.googleapis.com`;\n }\n }\n\n protected get publisher(): string {\n return \"google\";\n }\n\n protected get urlMethod(): string {\n return this.streaming ? \"streamGenerateContent?alt=sse\" : \"generateContent\";\n }\n\n /**\n * Returns the model profile for this instance's model, describing its\n * capabilities and constraints (e.g. max tokens, input/output modalities,\n * tool calling support).\n *\n * @example\n * ```typescript\n * const model = new ChatGoogle({ model: \"gemini-2.5-pro\" });\n * const profile = model.profile;\n * console.log(profile.maxInputTokens); // 1048576\n * console.log(profile.imageInputs); // true\n * ```\n */\n get profile(): ModelProfile {\n return PROFILES[this.model] ?? {};\n }\n\n protected async buildUrlGemini(urlMethod?: string): Promise<string> {\n return `https://${this.endpoint}/${this.apiVersion}/models/${this.model}:${\n urlMethod ?? this.urlMethod\n }`;\n }\n\n protected async buildUrlVertexExpress(urlMethod?: string): Promise<string> {\n return `https://${this.endpoint}/${this.apiVersion}/publishers/${\n this.publisher\n }/models/${this.model}:${urlMethod ?? this.urlMethod}`;\n }\n\n protected async buildUrlVertexLocation(urlMethod?: string): Promise<string> {\n const projectId = await this.apiClient.getProjectId();\n return `https://${this.endpoint}/${\n this.apiVersion\n }/projects/${projectId}/locations/${this.location}/publishers/${\n this.publisher\n }/models/${this.model}:${urlMethod ?? this.urlMethod}`;\n }\n\n protected async buildUrlVertex(urlMethod?: string): Promise<string> {\n if (this.isVertexExpress) {\n return this.buildUrlVertexExpress(urlMethod);\n } else {\n return this.buildUrlVertexLocation(urlMethod);\n }\n }\n\n protected async buildUrl(urlMethod?: string): Promise<string> {\n switch (this.platform) {\n case \"gai\":\n return this.buildUrlGemini(urlMethod);\n default:\n return this.buildUrlVertex(urlMethod);\n }\n }\n\n override invocationParams(options: this[\"ParsedCallOptions\"]) {\n const fields = combineGoogleChatModelFields(this.params, options);\n\n // Convert tools to Gemini format\n const tools = fields.tools\n ? convertToolsToGeminiTools(fields.tools)\n : undefined;\n\n // Convert tool choice to Gemini function calling config\n const toolConfig = convertToolChoiceToGeminiConfig(\n options.tool_choice,\n !!(tools && tools.length > 0)\n );\n\n let responseJsonSchema:\n | JsonSchema7Type\n | Record<string, unknown>\n | undefined;\n let responseMimeType: string | undefined;\n\n if (fields.responseSchema) {\n // Convert Zod schema to JSON Schema if needed\n if (isInteropZodSchema(fields.responseSchema)) {\n responseJsonSchema = toJsonSchema(fields.responseSchema);\n } else {\n responseJsonSchema = fields.responseSchema as Record<string, unknown>;\n }\n // Automatically set responseMimeType to \"application/json\" when schema is provided\n responseMimeType = \"application/json\";\n }\n\n return {\n ...(tools && tools.length > 0 ? { tools } : {}),\n ...(toolConfig ? { toolConfig } : {}),\n safetySettings: fields.safetySettings,\n generationConfig: {\n temperature: fields.temperature,\n topP: fields.topP,\n topK: fields.topK,\n maxOutputTokens: fields.maxOutputTokens,\n presencePenalty: fields.presencePenalty,\n frequencyPenalty: fields.frequencyPenalty,\n stopSequences: fields.stopSequences,\n ...(responseMimeType ? { responseMimeType } : {}),\n ...(responseJsonSchema ? { responseJsonSchema } : {}),\n ...(fields.responseModalities && fields.responseModalities.length > 0\n ? { responseModalities: fields.responseModalities }\n : {}),\n candidateCount: 1,\n seed: fields.seed,\n responseLogprobs: fields.responseLogprobs,\n logprobs: fields.logprobs,\n ...(fields.enableEnhancedCivicAnswers !== undefined\n ? { enableEnhancedCivicAnswers: fields.enableEnhancedCivicAnswers }\n : {}),\n thinkingConfig: convertFieldsToThinkingConfig(this.model, fields),\n speechConfig: convertFieldsToSpeechConfig(fields),\n ...(fields.imageConfig ? { imageConfig: fields.imageConfig } : {}),\n ...(fields.mediaResolution\n ? { mediaResolution: fields.mediaResolution }\n : {}),\n },\n };\n }\n\n async _generate(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n if (this.streaming) {\n const stream = await this._streamResponseChunks(\n messages,\n options,\n runManager\n );\n let finalChunk: ChatGenerationChunk | null = null;\n for await (const chunk of stream) {\n finalChunk = !finalChunk ? chunk : concat(finalChunk, chunk);\n }\n if (\n typeof finalChunk?.message?.content === \"string\" &&\n typeof (\n finalChunk?.message?.additional_kwargs\n ?.originalTextContentBlock as Record<string, unknown>\n )?.text === \"string\"\n ) {\n (\n finalChunk.message.additional_kwargs\n .originalTextContentBlock as Record<string, unknown>\n ).text = finalChunk.message.content;\n }\n return {\n generations: finalChunk ? [finalChunk] : [],\n };\n }\n\n const url = await this.buildUrl();\n const body = {\n ...this.invocationParams(options),\n systemInstruction: convertMessagesToGeminiSystemInstruction(messages),\n contents: convertMessagesToGeminiContents(messages),\n };\n\n const moduleName = this.constructor.name;\n await runManager?.handleCustomEvent(`google-request-${moduleName}`, {\n url,\n body,\n });\n\n const response = await this.apiClient.fetch(\n new Request(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n })\n );\n\n if (!response.ok) {\n const error = await RequestError.fromResponse(response);\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n error,\n });\n throw error;\n }\n\n const data: Gemini.GenerateContentResponse = await response.json();\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n data,\n url: response.url,\n headers: response.headers,\n status: response.status,\n statusText: response.statusText,\n });\n\n // Check for prompt feedback errors\n if (data.promptFeedback?.blockReason) {\n throw PromptBlockedError.fromPromptFeedback(data.promptFeedback);\n }\n\n // Check if we have candidates\n if (!data.candidates || data.candidates.length === 0) {\n throw new NoCandidatesError();\n }\n\n // Use the first candidate\n const candidate = data.candidates[0];\n const message = convertGeminiCandidateToAIMessage(candidate);\n\n // Extract text content from the message\n const text = convertAIMessageToText(message);\n\n const usageMetadata =\n convertGeminiGenerateContentResponseToUsageMetadata(data);\n message.usage_metadata = usageMetadata;\n\n return {\n generations: [\n {\n text,\n message,\n generationInfo: {\n finishReason: candidate.finishReason,\n finishMessage: candidate.finishMessage,\n safetyRatings: candidate.safetyRatings,\n citationMetadata: candidate.citationMetadata,\n tokenCount: candidate.tokenCount,\n },\n },\n ],\n llmOutput: {\n tokenUsage: usageMetadata,\n model: data.modelVersion,\n responseId: data.responseId,\n usageMetadata,\n },\n };\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const streamUsage: boolean = this.streamUsage ?? true;\n\n const body = {\n ...this.invocationParams(options),\n systemInstruction: convertMessagesToGeminiSystemInstruction(messages),\n contents: convertMessagesToGeminiContents(messages),\n };\n\n const url = await this.buildUrl(\"streamGenerateContent?alt=sse\");\n const moduleName = this.constructor.name;\n await runManager?.handleCustomEvent(`google-request-${moduleName}`, {\n url,\n body,\n });\n\n const response = await this.apiClient.fetch(\n new Request(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n signal: options.signal,\n })\n );\n\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n url: response.url,\n headers: response.headers,\n status: response.status,\n statusText: response.statusText,\n });\n\n if (!response.ok) {\n const error = await RequestError.fromResponse(response);\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n error,\n });\n throw error;\n }\n\n if (response.body) {\n const stream = response.body\n .pipeThrough(new TextDecoderStream())\n .pipeThrough(new EventSourceParserStream())\n .pipeThrough(\n new SafeJsonEventParserStream<Gemini.GenerateContentResponse>()\n )\n .pipeThrough(\n new TransformStream<\n Gemini.GenerateContentResponse,\n ChatGenerationChunk\n >({\n transform(chunk, controller) {\n // eslint-disable-next-line no-void\n void runManager?.handleCustomEvent(`google-chunk-${moduleName}`, {\n chunk,\n });\n if (chunk === null) {\n controller.enqueue(\n new ChatGenerationChunk({\n text: \"\",\n message: new AIMessageChunk({ content: \"\" }),\n generationInfo: { finishReason: \"stop\" },\n })\n );\n return;\n }\n\n // Extract text delta from the chunk\n const candidate = chunk.candidates?.[0];\n if (!candidate) {\n return;\n }\n\n const message = convertGeminiCandidateToAIMessage(candidate);\n const text = convertAIMessageToText(message);\n\n const parts = candidate.content?.parts ?? [];\n const toolCalls = convertGeminiPartsToToolCalls(parts);\n\n // Only emit if we have content\n if (parts.length > 0 || candidate.finishReason) {\n const messageChunkParams: AIMessageChunkFields = {\n content: message.content,\n tool_calls: toolCalls,\n response_metadata: {\n model_provider: \"google\",\n },\n additional_kwargs: {\n ...(message.additional_kwargs.originalTextContentBlock\n ? {\n originalTextContentBlock:\n message.additional_kwargs.originalTextContentBlock,\n }\n : {}),\n ...(candidate.finishReason\n ? {\n finishReason: candidate.finishReason,\n finishMessage: candidate.finishMessage,\n }\n : {}),\n },\n };\n\n // Include usageMetadata if there is any and we have\n // enabled it with streamUsage on\n if (chunk?.usageMetadata && streamUsage) {\n messageChunkParams.usage_metadata =\n convertGeminiGenerateContentResponseToUsageMetadata(chunk);\n }\n const messageChunk = new AIMessageChunk(messageChunkParams);\n\n controller.enqueue(\n new ChatGenerationChunk({\n text: text,\n message: messageChunk,\n generationInfo: {\n ...(candidate.finishReason && {\n finishReason: candidate.finishReason,\n finishMessage: candidate.finishMessage,\n }),\n ...(candidate.safetyRatings && {\n safetyRatings: candidate.safetyRatings,\n }),\n },\n })\n );\n }\n },\n })\n );\n\n const reader = stream.getReader();\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n yield value;\n if (value.text) {\n await runManager?.handleLLMNewToken(\n value.text,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: value }\n );\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n }\n\n /**\n * Bind tool-like objects to this chat model.\n *\n * @param tools A list of tool definitions to bind to this chat model.\n * Can be a structured tool, an OpenAI formatted tool, or a Gemini function declaration.\n * @param kwargs Any additional parameters to bind.\n */\n bindTools(\n tools: BindToolsInput[],\n kwargs?: Partial<CallOptions>\n ): Runnable<BaseMessage[], AIMessageChunk, CallOptions> {\n return this.withConfig({\n ...kwargs,\n tools,\n } as Partial<CallOptions>);\n }\n\n /**\n * Get structured output from the model based on a schema.\n *\n * This method supports two modes:\n * - `jsonMode`: Uses `responseSchema` to get JSON responses directly (preferred for structured outputs)\n * - `functionCalling`: Uses function calling with tools (default, for compatibility)\n *\n * @param outputSchema - The schema to use for structured output (Zod schema or JSON Schema)\n * @param config - Configuration options including method and whether to include raw response\n * @returns A Runnable that returns the parsed structured output\n */\n withStructuredOutput<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | Record<string, any>,\n config?: StructuredOutputMethodOptions<boolean>\n ):\n | Runnable<BaseLanguageModelInput, RunOutput>\n | Runnable<\n BaseLanguageModelInput,\n { raw: BaseMessage; parsed: RunOutput }\n > {\n let llm: Runnable<BaseMessage[], AIMessageChunk, CallOptions>;\n let outputParser: Runnable<BaseMessage, RunOutput>;\n\n const { schema, name, includeRaw } = {\n ...config,\n schema: outputSchema,\n };\n let method = config?.method ?? \"functionCalling\";\n\n if (method === \"jsonMode\") {\n console.warn(\n `\"jsonMode\" is not supported for Google models. Falling back to \"jsonSchema\".`\n );\n method = \"jsonSchema\";\n }\n\n if (method === \"jsonSchema\") {\n // Use JSON mode with responseSchema\n llm = this.withConfig({\n responseSchema: schema,\n } as Partial<CallOptions>);\n\n outputParser = RunnableLambda.from<BaseMessage, RunOutput>(\n async (input: BaseMessage): Promise<RunOutput> => {\n if (\n !AIMessage.isInstance(input) &&\n !AIMessageChunk.isInstance(input)\n ) {\n throw new MalformedOutputError({\n message: \"Input is not an AIMessage or AIMessageChunk.\",\n });\n }\n\n if (!input.text) {\n throw new MalformedOutputError({\n message:\n \"No content found in response. Cannot parse structured output.\",\n });\n }\n\n // Parse JSON and validate with schema\n if (isInteropZodSchema(schema)) {\n const zodParser = StructuredOutputParser.fromZodSchema(\n schema as InteropZodType<RunOutput>\n );\n return (await zodParser.parse(input.text)) as RunOutput;\n } else {\n const jsonParser = new JsonOutputParser<RunOutput>();\n return await jsonParser.parse(input.text);\n }\n }\n );\n } else if (method === \"functionCalling\") {\n // Use function calling mode\n let functionName = name ?? \"extract\";\n let tools: Gemini.Tool[];\n\n if (isInteropZodSchema(schema)) {\n const jsonSchema = schemaToGeminiParameters(schema);\n const description =\n typeof jsonSchema.description === \"string\"\n ? jsonSchema.description\n : \"A function available to call.\";\n tools = [\n {\n functionDeclarations: [\n {\n name: functionName,\n description,\n parameters: jsonSchema as Gemini.Tools.Schema,\n },\n ],\n },\n ];\n outputParser = new JsonOutputKeyToolsParser({\n returnSingle: true,\n keyName: functionName,\n zodSchema: schema,\n });\n } else {\n let geminiFunctionDefinition: Gemini.Tools.FunctionDeclaration;\n if (\n typeof schema.name === \"string\" &&\n typeof schema.parameters === \"object\" &&\n schema.parameters != null\n ) {\n geminiFunctionDefinition = schema as Gemini.Tools.FunctionDeclaration;\n functionName = schema.name;\n } else {\n // We are providing the schema for *just* the parameters\n const parameters = schemaToGeminiParameters(schema);\n geminiFunctionDefinition = {\n name: functionName,\n description: (schema as { description?: string }).description ?? \"\",\n parameters,\n };\n }\n tools = [\n {\n functionDeclarations: [geminiFunctionDefinition],\n },\n ];\n outputParser = new JsonOutputKeyToolsParser<RunOutput>({\n returnSingle: true,\n keyName: functionName,\n });\n }\n\n llm = this.bindTools(tools).withConfig({\n tool_choice: functionName,\n } as Partial<CallOptions>);\n } else {\n throw new ConfigurationError(\n `Unrecognized structured output method '${method}'. Expected 'functionCalling' or 'jsonSchema'`\n );\n }\n\n // Shared logic for handling includeRaw\n if (!includeRaw) {\n return llm.pipe(outputParser).withConfig({\n runName: \"ChatGoogleStructuredOutput\",\n }) as Runnable<BaseLanguageModelInput, RunOutput>;\n }\n\n const parserAssign = RunnablePassthrough.assign({\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n parsed: (input: any, config) => outputParser.invoke(input.raw, config),\n });\n const parserNone = RunnablePassthrough.assign({\n parsed: () => null,\n });\n const parsedWithFallback = parserAssign.withFallbacks({\n fallbacks: [parserNone],\n });\n return RunnableSequence.from<\n BaseLanguageModelInput,\n { raw: BaseMessage; parsed: RunOutput }\n >([\n {\n raw: llm,\n },\n parsedWithFallback,\n ]).withConfig({\n runName: \"ChatGoogleStructuredOutputRunnable\",\n });\n }\n}\n\ntype CombinableFields = Omit<BaseChatGoogleParams, \"model\">;\n\nexport function combineGoogleChatModelFields(\n a: CombinableFields,\n b: CombinableFields,\n ...rest: CombinableFields[]\n): CombinableFields {\n const combined: CombinableFields = {\n temperature: b.temperature ?? a.temperature,\n topP: b.topP ?? a.topP,\n topK: b.topK ?? a.topK,\n maxOutputTokens: b.maxOutputTokens ?? a.maxOutputTokens,\n presencePenalty: b.presencePenalty ?? a.presencePenalty,\n frequencyPenalty: b.frequencyPenalty ?? a.frequencyPenalty,\n stopSequences: b.stopSequences ?? a.stopSequences,\n seed: b.seed ?? a.seed,\n responseLogprobs: b.responseLogprobs ?? a.responseLogprobs,\n logprobs: b.logprobs ?? a.logprobs,\n safetySettings: b.safetySettings ?? a.safetySettings,\n responseSchema: b.responseSchema ?? a.responseSchema,\n tools: b.tools ?? a.tools,\n responseModalities: b.responseModalities ?? a.responseModalities,\n enableEnhancedCivicAnswers:\n b.enableEnhancedCivicAnswers ?? a.enableEnhancedCivicAnswers,\n speechConfig: b.speechConfig ?? a.speechConfig,\n imageConfig: b.imageConfig ?? a.imageConfig,\n mediaResolution: b.mediaResolution ?? a.mediaResolution,\n maxReasoningTokens: b.maxReasoningTokens ?? a.maxReasoningTokens,\n thinkingBudget: b.thinkingBudget ?? a.thinkingBudget,\n reasoningEffort: b.reasoningEffort ?? a.reasoningEffort,\n thinkingLevel: b.thinkingLevel ?? a.thinkingLevel,\n };\n if (rest.length > 0) {\n return combineGoogleChatModelFields(combined, rest[0], ...rest.slice(1));\n }\n return combined;\n}\n\nexport function getGoogleChatModelParams<TParams extends BaseChatGoogleParams>(\n modelOrParams: string | TParams,\n paramsArg?: Omit<TParams, \"model\">\n): TParams {\n const model =\n typeof modelOrParams === \"string\" ? modelOrParams : modelOrParams.model;\n const params = typeof modelOrParams === \"string\" ? paramsArg : modelOrParams;\n return { model, ...params } as TParams;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AA0EA,SAAgB,gBACd,UACA,WACoB;AACpB,KAAI,OAAO,aAAa,YACtB,QAAO;UACE,UACT,QAAO;KAEP,QAAO;;AAiEX,IAAsB,iBAAtB,cAEU,cAA2C;CACnD;CAEA;CAEA;CAEA,cAAuB;CAEvB,AAAU;CAEV,AAAU;CAEV,AAAU;CAEV,AAAU;CAEV,AAAU;CAEV,YAAY,AAAU,QAA8B;AAClD,QAAM,OAAO;EADO;AAGpB,MAAI,CAAC,OAAO,UACV,OAAM,IAAI,mBACR,6LACD;AAEH,OAAK,YAAY,OAAO;AAExB,OAAK,QAAQ,OAAO;AACpB,OAAK,YAAY,4BAA4B,OAAO;AACpD,OAAK,YAAY,OAAO;AACxB,OAAK,YAAY,OAAO;AACxB,OAAK,cAAc,OAAO;AAE1B,OAAK,mBAAmB,QAAQ,qBAAqB;AACrD,OAAK,YAAY,QAAQ,cAAc;AACvC,MAAI,KAAK,iBAAkB,MAAK,YAAY;AAE5C,MAAI,QAAQ,cAAc,MAAO,MAAK,mBAAmB;AAEzD,OAAK,cAAc,QAAQ,eAAe,KAAK;AAC/C,MAAI,KAAK,iBAAkB,MAAK,cAAc;;CAGhD,WAAmB;AACjB,SAAO;;CAGT,IAAc,eAA+C;AAC3D,SAAO,KAAK;;CAGd,IAAc,WAA+B;AAC3C,SAAO,gBAAgB,KAAK,WAAW,KAAK,UAAU,WAAW,CAAC;;CAGpE,IAAc,kBAA2B;AACvC,SAAO,KAAK,aAAa,SAAS,KAAK,UAAU,WAAW;;CAG9D,IAAc,aAAqB;AACjC,MAAI,OAAO,KAAK,gBAAgB,YAC9B,QAAO,KAAK;WACH,KAAK,aAAa,MAC3B,QAAO;MAEP,QAAO;;CAIX,IAAc,WAAmB;AAC/B,SAAO,KAAK,aAAa;;CAG3B,IAAc,WAAmB;AAC/B,MAAI,OAAO,KAAK,cAAc,YAC5B,QAAO,KAAK;WACH,KAAK,aAAa,MAC3B,QAAO;WACE,KAAK,gBACd,QAAO;WACE,KAAK,aAAa,SAE3B,QAAO;MAEP,QAAO,GAAG,KAAK,SAAS;;CAI5B,IAAc,YAAoB;AAChC,SAAO;;CAGT,IAAc,YAAoB;AAChC,SAAO,KAAK,YAAY,kCAAkC;;;;;;;;;;;;;;;CAgB5D,IAAI,UAAwB;AAC1B,SAAO,SAAS,KAAK,UAAU,EAAE;;CAGnC,MAAgB,eAAe,WAAqC;AAClE,SAAO,WAAW,KAAK,SAAS,GAAG,KAAK,WAAW,UAAU,KAAK,MAAM,GACtE,aAAa,KAAK;;CAItB,MAAgB,sBAAsB,WAAqC;AACzE,SAAO,WAAW,KAAK,SAAS,GAAG,KAAK,WAAW,cACjD,KAAK,UACN,UAAU,KAAK,MAAM,GAAG,aAAa,KAAK;;CAG7C,MAAgB,uBAAuB,WAAqC;EAC1E,MAAM,YAAY,MAAM,KAAK,UAAU,cAAc;AACrD,SAAO,WAAW,KAAK,SAAS,GAC9B,KAAK,WACN,YAAY,UAAU,aAAa,KAAK,SAAS,cAChD,KAAK,UACN,UAAU,KAAK,MAAM,GAAG,aAAa,KAAK;;CAG7C,MAAgB,eAAe,WAAqC;AAClE,MAAI,KAAK,gBACP,QAAO,KAAK,sBAAsB,UAAU;MAE5C,QAAO,KAAK,uBAAuB,UAAU;;CAIjD,MAAgB,SAAS,WAAqC;AAC5D,UAAQ,KAAK,UAAb;GACE,KAAK,MACH,QAAO,KAAK,eAAe,UAAU;GACvC,QACE,QAAO,KAAK,eAAe,UAAU;;;CAI3C,AAAS,iBAAiB,SAAoC;EAC5D,MAAM,SAAS,6BAA6B,KAAK,QAAQ,QAAQ;EAGjE,MAAM,QAAQ,OAAO,QACjB,0BAA0B,OAAO,MAAM,GACvC;EAGJ,MAAM,aAAa,gCACjB,QAAQ,aACR,CAAC,EAAE,SAAS,MAAM,SAAS,GAC5B;EAED,IAAI;EAIJ,IAAI;AAEJ,MAAI,OAAO,gBAAgB;AAEzB,OAAI,mBAAmB,OAAO,eAAe,CAC3C,sBAAqB,aAAa,OAAO,eAAe;OAExD,sBAAqB,OAAO;AAG9B,sBAAmB;;AAGrB,SAAO;GACL,GAAI,SAAS,MAAM,SAAS,IAAI,EAAE,OAAO,GAAG,EAAE;GAC9C,GAAI,aAAa,EAAE,YAAY,GAAG,EAAE;GACpC,gBAAgB,OAAO;GACvB,kBAAkB;IAChB,aAAa,OAAO;IACpB,MAAM,OAAO;IACb,MAAM,OAAO;IACb,iBAAiB,OAAO;IACxB,iBAAiB,OAAO;IACxB,kBAAkB,OAAO;IACzB,eAAe,OAAO;IACtB,GAAI,mBAAmB,EAAE,kBAAkB,GAAG,EAAE;IAChD,GAAI,qBAAqB,EAAE,oBAAoB,GAAG,EAAE;IACpD,GAAI,OAAO,sBAAsB,OAAO,mBAAmB,SAAS,IAChE,EAAE,oBAAoB,OAAO,oBAAoB,GACjD,EAAE;IACN,gBAAgB;IAChB,MAAM,OAAO;IACb,kBAAkB,OAAO;IACzB,UAAU,OAAO;IACjB,GAAI,OAAO,+BAA+B,SACtC,EAAE,4BAA4B,OAAO,4BAA4B,GACjE,EAAE;IACN,gBAAgB,8BAA8B,KAAK,OAAO,OAAO;IACjE,cAAc,4BAA4B,OAAO;IACjD,GAAI,OAAO,cAAc,EAAE,aAAa,OAAO,aAAa,GAAG,EAAE;IACjE,GAAI,OAAO,kBACP,EAAE,iBAAiB,OAAO,iBAAiB,GAC3C,EAAE;IACP;GACF;;CAGH,MAAM,UACJ,UACA,SACA,YACqB;AACrB,MAAI,KAAK,WAAW;GAClB,MAAM,SAAS,MAAM,KAAK,sBACxB,UACA,SACA,WACD;GACD,IAAI,aAAyC;AAC7C,cAAW,MAAM,SAAS,OACxB,cAAa,CAAC,aAAa,QAAQ,OAAO,YAAY,MAAM;AAE9D,OACE,OAAO,YAAY,SAAS,YAAY,YACxC,QACE,YAAY,SAAS,mBACjB,2BACH,SAAS,SAEZ,CACE,WAAW,QAAQ,kBAChB,yBACH,OAAO,WAAW,QAAQ;AAE9B,UAAO,EACL,aAAa,aAAa,CAAC,WAAW,GAAG,EAAE,EAC5C;;EAGH,MAAM,MAAM,MAAM,KAAK,UAAU;EACjC,MAAM,OAAO;GACX,GAAG,KAAK,iBAAiB,QAAQ;GACjC,mBAAmB,yCAAyC,SAAS;GACrE,UAAU,gCAAgC,SAAS;GACpD;EAED,MAAM,aAAa,KAAK,YAAY;AACpC,QAAM,YAAY,kBAAkB,kBAAkB,cAAc;GAClE;GACA;GACD,CAAC;EAEF,MAAM,WAAW,MAAM,KAAK,UAAU,MACpC,IAAI,QAAQ,KAAK;GACf,QAAQ;GACR,SAAS,EACP,gBAAgB,oBACjB;GACD,MAAM,KAAK,UAAU,KAAK;GAC3B,CAAC,CACH;AAED,MAAI,CAAC,SAAS,IAAI;GAChB,MAAM,QAAQ,MAAM,aAAa,aAAa,SAAS;AACvD,SAAM,YAAY,kBAAkB,mBAAmB,cAAc,EACnE,OACD,CAAC;AACF,SAAM;;EAGR,MAAM,OAAuC,MAAM,SAAS,MAAM;AAClE,QAAM,YAAY,kBAAkB,mBAAmB,cAAc;GACnE;GACA,KAAK,SAAS;GACd,SAAS,SAAS;GAClB,QAAQ,SAAS;GACjB,YAAY,SAAS;GACtB,CAAC;AAGF,MAAI,KAAK,gBAAgB,YACvB,OAAM,mBAAmB,mBAAmB,KAAK,eAAe;AAIlE,MAAI,CAAC,KAAK,cAAc,KAAK,WAAW,WAAW,EACjD,OAAM,IAAI,mBAAmB;EAI/B,MAAM,YAAY,KAAK,WAAW;EAClC,MAAM,UAAU,kCAAkC,UAAU;EAG5D,MAAM,OAAO,uBAAuB,QAAQ;EAE5C,MAAM,gBACJ,oDAAoD,KAAK;AAC3D,UAAQ,iBAAiB;AAEzB,SAAO;GACL,aAAa,CACX;IACE;IACA;IACA,gBAAgB;KACd,cAAc,UAAU;KACxB,eAAe,UAAU;KACzB,eAAe,UAAU;KACzB,kBAAkB,UAAU;KAC5B,YAAY,UAAU;KACvB;IACF,CACF;GACD,WAAW;IACT,YAAY;IACZ,OAAO,KAAK;IACZ,YAAY,KAAK;IACjB;IACD;GACF;;CAGH,OAAO,sBACL,UACA,SACA,YACqC;EACrC,MAAM,cAAuB,KAAK,eAAe;EAEjD,MAAM,OAAO;GACX,GAAG,KAAK,iBAAiB,QAAQ;GACjC,mBAAmB,yCAAyC,SAAS;GACrE,UAAU,gCAAgC,SAAS;GACpD;EAED,MAAM,MAAM,MAAM,KAAK,SAAS,gCAAgC;EAChE,MAAM,aAAa,KAAK,YAAY;AACpC,QAAM,YAAY,kBAAkB,kBAAkB,cAAc;GAClE;GACA;GACD,CAAC;EAEF,MAAM,WAAW,MAAM,KAAK,UAAU,MACpC,IAAI,QAAQ,KAAK;GACf,QAAQ;GACR,SAAS,EACP,gBAAgB,oBACjB;GACD,MAAM,KAAK,UAAU,KAAK;GAC1B,QAAQ,QAAQ;GACjB,CAAC,CACH;AAED,QAAM,YAAY,kBAAkB,mBAAmB,cAAc;GACnE,KAAK,SAAS;GACd,SAAS,SAAS;GAClB,QAAQ,SAAS;GACjB,YAAY,SAAS;GACtB,CAAC;AAEF,MAAI,CAAC,SAAS,IAAI;GAChB,MAAM,QAAQ,MAAM,aAAa,aAAa,SAAS;AACvD,SAAM,YAAY,kBAAkB,mBAAmB,cAAc,EACnE,OACD,CAAC;AACF,SAAM;;AAGR,MAAI,SAAS,MAAM;GA4FjB,MAAM,SA3FS,SAAS,KACrB,YAAY,IAAI,mBAAmB,CAAC,CACpC,YAAY,IAAI,yBAAyB,CAAC,CAC1C,YACC,IAAI,2BAA2D,CAChE,CACA,YACC,IAAI,gBAGF,EACA,UAAU,OAAO,YAAY;AAE3B,IAAK,YAAY,kBAAkB,gBAAgB,cAAc,EAC/D,OACD,CAAC;AACF,QAAI,UAAU,MAAM;AAClB,gBAAW,QACT,IAAI,oBAAoB;MACtB,MAAM;MACN,SAAS,IAAI,eAAe,EAAE,SAAS,IAAI,CAAC;MAC5C,gBAAgB,EAAE,cAAc,QAAQ;MACzC,CAAC,CACH;AACD;;IAIF,MAAM,YAAY,MAAM,aAAa;AACrC,QAAI,CAAC,UACH;IAGF,MAAM,UAAU,kCAAkC,UAAU;IAC5D,MAAM,OAAO,uBAAuB,QAAQ;IAE5C,MAAM,QAAQ,UAAU,SAAS,SAAS,EAAE;IAC5C,MAAM,YAAY,8BAA8B,MAAM;AAGtD,QAAI,MAAM,SAAS,KAAK,UAAU,cAAc;KAC9C,MAAM,qBAA2C;MAC/C,SAAS,QAAQ;MACjB,YAAY;MACZ,mBAAmB,EACjB,gBAAgB,UACjB;MACD,mBAAmB;OACjB,GAAI,QAAQ,kBAAkB,2BAC1B,EACE,0BACE,QAAQ,kBAAkB,0BAC7B,GACD,EAAE;OACN,GAAI,UAAU,eACV;QACE,cAAc,UAAU;QACxB,eAAe,UAAU;QAC1B,GACD,EAAE;OACP;MACF;AAID,SAAI,OAAO,iBAAiB,YAC1B,oBAAmB,iBACjB,oDAAoD,MAAM;KAE9D,MAAM,eAAe,IAAI,eAAe,mBAAmB;AAE3D,gBAAW,QACT,IAAI,oBAAoB;MAChB;MACN,SAAS;MACT,gBAAgB;OACd,GAAI,UAAU,gBAAgB;QAC5B,cAAc,UAAU;QACxB,eAAe,UAAU;QAC1B;OACD,GAAI,UAAU,iBAAiB,EAC7B,eAAe,UAAU,eAC1B;OACF;MACF,CAAC,CACH;;MAGN,CAAC,CACH,CAEmB,WAAW;AACjC,OAAI;AACF,WAAO,MAAM;KACX,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,MAAM;AAC3C,SAAI,KAAM;AACV,WAAM;AACN,SAAI,MAAM,KACR,OAAM,YAAY,kBAChB,MAAM,MACN,QACA,QACA,QACA,QACA,EAAE,OAAO,OAAO,CACjB;;aAGG;AACR,WAAO,aAAa;;;;;;;;;;;CAY1B,UACE,OACA,QACsD;AACtD,SAAO,KAAK,WAAW;GACrB,GAAG;GACH;GACD,CAAyB;;;;;;;;;;;;;CAc5B,qBAIE,cAIA,QAMI;EACJ,IAAI;EACJ,IAAI;EAEJ,MAAM,EAAE,QAAQ,MAAM,eAAe;GACnC,GAAG;GACH,QAAQ;GACT;EACD,IAAI,SAAS,QAAQ,UAAU;AAE/B,MAAI,WAAW,YAAY;AACzB,WAAQ,KACN,+EACD;AACD,YAAS;;AAGX,MAAI,WAAW,cAAc;AAE3B,SAAM,KAAK,WAAW,EACpB,gBAAgB,QACjB,CAAyB;AAE1B,kBAAe,eAAe,KAC5B,OAAO,UAA2C;AAChD,QACE,CAAC,UAAU,WAAW,MAAM,IAC5B,CAAC,eAAe,WAAW,MAAM,CAEjC,OAAM,IAAI,qBAAqB,EAC7B,SAAS,gDACV,CAAC;AAGJ,QAAI,CAAC,MAAM,KACT,OAAM,IAAI,qBAAqB,EAC7B,SACE,iEACH,CAAC;AAIJ,QAAI,mBAAmB,OAAO,CAI5B,QAAQ,MAHU,uBAAuB,cACvC,OACD,CACuB,MAAM,MAAM,KAAK;QAGzC,QAAO,MADY,IAAI,kBAA6B,CAC5B,MAAM,MAAM,KAAK;KAG9C;aACQ,WAAW,mBAAmB;GAEvC,IAAI,eAAe,QAAQ;GAC3B,IAAI;AAEJ,OAAI,mBAAmB,OAAO,EAAE;IAC9B,MAAM,aAAa,yBAAyB,OAAO;IACnD,MAAM,cACJ,OAAO,WAAW,gBAAgB,WAC9B,WAAW,cACX;AACN,YAAQ,CACN,EACE,sBAAsB,CACpB;KACE,MAAM;KACN;KACA,YAAY;KACb,CACF,EACF,CACF;AACD,mBAAe,IAAI,yBAAyB;KAC1C,cAAc;KACd,SAAS;KACT,WAAW;KACZ,CAAC;UACG;IACL,IAAI;AACJ,QACE,OAAO,OAAO,SAAS,YACvB,OAAO,OAAO,eAAe,YAC7B,OAAO,cAAc,MACrB;AACA,gCAA2B;AAC3B,oBAAe,OAAO;WACjB;KAEL,MAAM,aAAa,yBAAyB,OAAO;AACnD,gCAA2B;MACzB,MAAM;MACN,aAAc,OAAoC,eAAe;MACjE;MACD;;AAEH,YAAQ,CACN,EACE,sBAAsB,CAAC,yBAAyB,EACjD,CACF;AACD,mBAAe,IAAI,yBAAoC;KACrD,cAAc;KACd,SAAS;KACV,CAAC;;AAGJ,SAAM,KAAK,UAAU,MAAM,CAAC,WAAW,EACrC,aAAa,cACd,CAAyB;QAE1B,OAAM,IAAI,mBACR,0CAA0C,OAAO,+CAClD;AAIH,MAAI,CAAC,WACH,QAAO,IAAI,KAAK,aAAa,CAAC,WAAW,EACvC,SAAS,8BACV,CAAC;EAGJ,MAAM,eAAe,oBAAoB,OAAO,EAE9C,SAAS,OAAY,WAAW,aAAa,OAAO,MAAM,KAAK,OAAO,EACvE,CAAC;EACF,MAAM,aAAa,oBAAoB,OAAO,EAC5C,cAAc,MACf,CAAC;EACF,MAAM,qBAAqB,aAAa,cAAc,EACpD,WAAW,CAAC,WAAW,EACxB,CAAC;AACF,SAAO,iBAAiB,KAGtB,CACA,EACE,KAAK,KACN,EACD,mBACD,CAAC,CAAC,WAAW,EACZ,SAAS,sCACV,CAAC;;;AAMN,SAAgB,6BACd,GACA,GACA,GAAG,MACe;CAClB,MAAM,WAA6B;EACjC,aAAa,EAAE,eAAe,EAAE;EAChC,MAAM,EAAE,QAAQ,EAAE;EAClB,MAAM,EAAE,QAAQ,EAAE;EAClB,iBAAiB,EAAE,mBAAmB,EAAE;EACxC,iBAAiB,EAAE,mBAAmB,EAAE;EACxC,kBAAkB,EAAE,oBAAoB,EAAE;EAC1C,eAAe,EAAE,iBAAiB,EAAE;EACpC,MAAM,EAAE,QAAQ,EAAE;EAClB,kBAAkB,EAAE,oBAAoB,EAAE;EAC1C,UAAU,EAAE,YAAY,EAAE;EAC1B,gBAAgB,EAAE,kBAAkB,EAAE;EACtC,gBAAgB,EAAE,kBAAkB,EAAE;EACtC,OAAO,EAAE,SAAS,EAAE;EACpB,oBAAoB,EAAE,sBAAsB,EAAE;EAC9C,4BACE,EAAE,8BAA8B,EAAE;EACpC,cAAc,EAAE,gBAAgB,EAAE;EAClC,aAAa,EAAE,eAAe,EAAE;EAChC,iBAAiB,EAAE,mBAAmB,EAAE;EACxC,oBAAoB,EAAE,sBAAsB,EAAE;EAC9C,gBAAgB,EAAE,kBAAkB,EAAE;EACtC,iBAAiB,EAAE,mBAAmB,EAAE;EACxC,eAAe,EAAE,iBAAiB,EAAE;EACrC;AACD,KAAI,KAAK,SAAS,EAChB,QAAO,6BAA6B,UAAU,KAAK,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;AAE1E,QAAO;;AAGT,SAAgB,yBACd,eACA,WACS;AAIT,QAAO;EAAE,OAFP,OAAO,kBAAkB,WAAW,gBAAgB,cAAc;EAEpD,GADD,OAAO,kBAAkB,WAAW,YAAY;EACpC"}
|
|
1
|
+
{"version":3,"file":"base.js","names":[],"sources":["../../src/chat_models/base.ts"],"sourcesContent":["import {\n BaseChatModel,\n type BaseChatModelCallOptions,\n type BaseChatModelParams,\n} from \"@langchain/core/language_models/chat_models\";\nimport {\n AIMessage,\n AIMessageChunk,\n AIMessageChunkFields,\n BaseMessage,\n type UsageMetadata,\n} from \"@langchain/core/messages\";\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { concat } from \"@langchain/core/utils/stream\";\nimport { ChatGenerationChunk, ChatResult } from \"@langchain/core/outputs\";\nimport { EventSourceParserStream } from \"eventsource-parser/stream\";\nimport type { BindToolsInput } from \"@langchain/core/language_models/chat_models\";\nimport type { ModelProfile } from \"@langchain/core/language_models/profile\";\nimport PROFILES from \"./profiles.js\";\nimport type {\n BaseLanguageModelInput,\n StructuredOutputMethodOptions,\n} from \"@langchain/core/language_models/base\";\nimport {\n Runnable,\n RunnableLambda,\n RunnablePassthrough,\n RunnableSequence,\n} from \"@langchain/core/runnables\";\nimport {\n toJsonSchema,\n type JsonSchema7Type,\n} from \"@langchain/core/utils/json_schema\";\nimport {\n InteropZodType,\n isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\nimport {\n JsonOutputParser,\n StructuredOutputParser,\n} from \"@langchain/core/output_parsers\";\nimport { JsonOutputKeyToolsParser } from \"@langchain/core/output_parsers/openai_tools\";\n\nimport { ApiClient } from \"../clients/index.js\";\nimport type { ChatGoogleFields } from \"./types.js\";\nimport { SafeJsonEventParserStream } from \"../utils/stream.js\";\nimport {\n convertAIMessageToText,\n convertGeminiCandidateToAIMessage,\n convertGeminiGenerateContentResponseToUsageMetadata,\n convertGeminiPartsToToolCalls,\n convertMessagesToGeminiContents,\n convertMessagesToGeminiSystemInstruction,\n} from \"../converters/messages.js\";\nimport {\n ConfigurationError,\n MalformedOutputError,\n NoCandidatesError,\n PromptBlockedError,\n RequestError,\n} from \"../utils/errors.js\";\nimport {\n convertToolsToGeminiTools,\n convertToolChoiceToGeminiConfig,\n schemaToGeminiParameters,\n} from \"../converters/tools.js\";\nimport {\n convertParamsToPlatformType,\n convertFieldsToSpeechConfig,\n convertFieldsToThinkingConfig,\n} from \"../converters/params.js\";\nimport { Gemini } from \"./api-types.js\";\nimport { subtractUsageMetadata } from \"../utils/metadata.js\";\n\nexport type GooglePlatformType = \"gai\" | \"gcp\";\n\nexport function getPlatformType(\n platform: GooglePlatformType | undefined,\n hasApiKey: boolean\n): GooglePlatformType {\n if (typeof platform !== \"undefined\") {\n return platform;\n } else if (hasApiKey) {\n return \"gai\";\n } else {\n return \"gcp\";\n }\n}\n\nexport interface BaseChatGoogleParams\n extends BaseChatModelParams,\n ChatGoogleFields {\n /**\n * The name of the Gemini model to use.\n *\n * Example: \"gemini-3-pro-preview\"\n */\n model: string;\n\n /**\n * Optional. The API client implementation for making HTTP requests to the Gemini API.\n * If not set, a default client will be used based on the runtime environment.\n */\n apiClient?: ApiClient;\n\n /**\n * Hostname for the API call (if this is running on GCP)\n * Usually this is computed based on location and platformType.\n **/\n endpoint?: string;\n\n /**\n * Region where the LLM is stored (if this is running on GCP)\n * Defaults to \"global\"\n **/\n location?: string;\n\n /**\n * The version of the API functions. Part of the path.\n * Usually this is computed based on platformType.\n **/\n apiVersion?: string;\n\n /**\n * What platform to run the service on.\n * If not specified, the class should determine this from other\n * means. Either way, the platform actually used will be in\n * the \"platform\" getter.\n */\n platformType?: GooglePlatformType;\n\n /**\n * For compatibility with Google's libraries, should this use Vertex?\n * The \"platformType\" parmeter takes precedence.\n */\n vertexai?: boolean;\n\n /**\n * Backwards compatibility.\n * @deprecated in favor of using `disableStreaming` or `.stream()`\n */\n streaming?: boolean;\n\n streamUsage?: boolean;\n}\n\nexport interface BaseChatGoogleCallOptions\n extends BaseChatModelCallOptions,\n ChatGoogleFields {}\n\nexport abstract class BaseChatGoogle<\n CallOptions extends BaseChatGoogleCallOptions = BaseChatGoogleCallOptions\n> extends BaseChatModel<CallOptions, AIMessageChunk> {\n model: string;\n\n streaming: boolean;\n\n disableStreaming: boolean;\n\n streamUsage: boolean = true;\n\n protected _platform?: GooglePlatformType;\n\n protected _endpoint?: string;\n\n protected _location?: string;\n\n protected _apiVersion?: string;\n\n protected apiClient: ApiClient;\n\n constructor(protected params: BaseChatGoogleParams) {\n super(params);\n this._addVersion(\"@langchain/google\", __PKG_VERSION__);\n\n if (!params.apiClient) {\n throw new ConfigurationError(\n \"BaseChatGoogle requires an apiClient. This should be provided automatically by ChatGoogle constructors. If you're extending BaseChatGoogle directly, please provide an apiClient instance.\"\n );\n }\n this.apiClient = params.apiClient;\n\n this.model = params.model;\n this._platform = convertParamsToPlatformType(params);\n this._endpoint = params.endpoint;\n this._location = params.location;\n this._apiVersion = params.apiVersion;\n\n this.disableStreaming = params?.disableStreaming === true;\n this.streaming = params?.streaming === true;\n if (this.disableStreaming) this.streaming = false;\n // disable streaming in BaseChatModel if explicitly disabled\n if (params?.streaming === false) this.disableStreaming = true;\n\n this.streamUsage = params?.streamUsage ?? this.streamUsage;\n if (this.disableStreaming) this.streamUsage = false;\n }\n\n _llmType(): string {\n return \"google\";\n }\n\n protected get platformType(): GooglePlatformType | undefined {\n return this._platform;\n }\n\n protected get platform(): GooglePlatformType {\n return getPlatformType(this._platform, this.apiClient.hasApiKey());\n }\n\n protected get isVertexExpress(): boolean {\n return this.platform === \"gcp\" && this.apiClient.hasApiKey();\n }\n\n protected get apiVersion(): string {\n if (typeof this._apiVersion !== \"undefined\") {\n return this._apiVersion;\n } else if (this.platform === \"gai\") {\n return \"v1beta\";\n } else {\n return \"v1\";\n }\n }\n\n protected get location(): string {\n return this._location || \"global\";\n }\n\n protected get endpoint(): string {\n if (typeof this._endpoint !== \"undefined\") {\n return this._endpoint;\n } else if (this.platform === \"gai\") {\n return \"generativelanguage.googleapis.com\";\n } else if (this.isVertexExpress) {\n return \"aiplatform.googleapis.com\";\n } else if (this.location === \"global\") {\n // See https://docs.cloud.google.com/vertex-ai/generative-ai/docs/learn/locations#use_the_global_endpoint\n return \"aiplatform.googleapis.com\";\n } else {\n return `${this.location}-aiplatform.googleapis.com`;\n }\n }\n\n protected get publisher(): string {\n return \"google\";\n }\n\n protected get urlMethod(): string {\n return this.streaming ? \"streamGenerateContent?alt=sse\" : \"generateContent\";\n }\n\n /**\n * Returns the model profile for this instance's model, describing its\n * capabilities and constraints (e.g. max tokens, input/output modalities,\n * tool calling support).\n *\n * @example\n * ```typescript\n * const model = new ChatGoogle({ model: \"gemini-2.5-pro\" });\n * const profile = model.profile;\n * console.log(profile.maxInputTokens); // 1048576\n * console.log(profile.imageInputs); // true\n * ```\n */\n get profile(): ModelProfile {\n return PROFILES[this.model] ?? {};\n }\n\n protected async buildUrlGemini(urlMethod?: string): Promise<string> {\n return `https://${this.endpoint}/${this.apiVersion}/models/${this.model}:${\n urlMethod ?? this.urlMethod\n }`;\n }\n\n protected async buildUrlVertexExpress(urlMethod?: string): Promise<string> {\n return `https://${this.endpoint}/${this.apiVersion}/publishers/${\n this.publisher\n }/models/${this.model}:${urlMethod ?? this.urlMethod}`;\n }\n\n protected async buildUrlVertexLocation(urlMethod?: string): Promise<string> {\n const projectId = await this.apiClient.getProjectId();\n return `https://${this.endpoint}/${\n this.apiVersion\n }/projects/${projectId}/locations/${this.location}/publishers/${\n this.publisher\n }/models/${this.model}:${urlMethod ?? this.urlMethod}`;\n }\n\n protected async buildUrlVertex(urlMethod?: string): Promise<string> {\n if (this.isVertexExpress) {\n return this.buildUrlVertexExpress(urlMethod);\n } else {\n return this.buildUrlVertexLocation(urlMethod);\n }\n }\n\n protected async buildUrl(urlMethod?: string): Promise<string> {\n switch (this.platform) {\n case \"gai\":\n return this.buildUrlGemini(urlMethod);\n default:\n return this.buildUrlVertex(urlMethod);\n }\n }\n\n override invocationParams(options: this[\"ParsedCallOptions\"]) {\n const fields = combineGoogleChatModelFields(this.params, options);\n\n // Convert tools to Gemini format\n const tools = fields.tools\n ? convertToolsToGeminiTools(fields.tools)\n : undefined;\n\n // Convert tool choice to Gemini function calling config\n const toolConfig = convertToolChoiceToGeminiConfig(\n options.tool_choice,\n !!(tools && tools.length > 0)\n );\n\n let responseJsonSchema:\n | JsonSchema7Type\n | Record<string, unknown>\n | undefined;\n let responseMimeType: string | undefined;\n\n if (fields.responseSchema) {\n // Convert Zod schema to JSON Schema if needed\n if (isInteropZodSchema(fields.responseSchema)) {\n responseJsonSchema = toJsonSchema(fields.responseSchema);\n } else {\n responseJsonSchema = fields.responseSchema as Record<string, unknown>;\n }\n // Automatically set responseMimeType to \"application/json\" when schema is provided\n responseMimeType = \"application/json\";\n }\n\n return {\n ...(tools && tools.length > 0 ? { tools } : {}),\n ...(toolConfig ? { toolConfig } : {}),\n safetySettings: fields.safetySettings,\n generationConfig: {\n temperature: fields.temperature,\n topP: fields.topP,\n topK: fields.topK,\n maxOutputTokens: fields.maxOutputTokens,\n presencePenalty: fields.presencePenalty,\n frequencyPenalty: fields.frequencyPenalty,\n stopSequences: fields.stopSequences,\n ...(responseMimeType ? { responseMimeType } : {}),\n ...(responseJsonSchema ? { responseJsonSchema } : {}),\n ...(fields.responseModalities && fields.responseModalities.length > 0\n ? { responseModalities: fields.responseModalities }\n : {}),\n candidateCount: 1,\n seed: fields.seed,\n responseLogprobs: fields.responseLogprobs,\n logprobs: fields.logprobs,\n ...(fields.enableEnhancedCivicAnswers !== undefined\n ? { enableEnhancedCivicAnswers: fields.enableEnhancedCivicAnswers }\n : {}),\n thinkingConfig: convertFieldsToThinkingConfig(this.model, fields),\n speechConfig: convertFieldsToSpeechConfig(fields),\n ...(fields.imageConfig ? { imageConfig: fields.imageConfig } : {}),\n ...(fields.mediaResolution\n ? { mediaResolution: fields.mediaResolution }\n : {}),\n },\n };\n }\n\n async _generate(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n if (this.streaming) {\n const stream = await this._streamResponseChunks(\n messages,\n options,\n runManager\n );\n let finalChunk: ChatGenerationChunk | null = null;\n for await (const chunk of stream) {\n finalChunk = !finalChunk ? chunk : concat(finalChunk, chunk);\n }\n if (\n typeof finalChunk?.message?.content === \"string\" &&\n typeof (\n finalChunk?.message?.additional_kwargs\n ?.originalTextContentBlock as Record<string, unknown>\n )?.text === \"string\"\n ) {\n (\n finalChunk.message.additional_kwargs\n .originalTextContentBlock as Record<string, unknown>\n ).text = finalChunk.message.content;\n }\n return {\n generations: finalChunk ? [finalChunk] : [],\n };\n }\n\n const url = await this.buildUrl();\n const body = {\n ...this.invocationParams(options),\n systemInstruction: convertMessagesToGeminiSystemInstruction(messages),\n contents: convertMessagesToGeminiContents(messages),\n };\n\n const moduleName = this.constructor.name;\n await runManager?.handleCustomEvent(`google-request-${moduleName}`, {\n url,\n body,\n });\n\n const response = await this.apiClient.fetch(\n new Request(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n })\n );\n\n if (!response.ok) {\n const error = await RequestError.fromResponse(response);\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n error,\n });\n throw error;\n }\n\n const data: Gemini.GenerateContentResponse = await response.json();\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n data,\n url: response.url,\n headers: response.headers,\n status: response.status,\n statusText: response.statusText,\n });\n\n // Check for prompt feedback errors\n if (data.promptFeedback?.blockReason) {\n throw PromptBlockedError.fromPromptFeedback(data.promptFeedback);\n }\n\n // Check if we have candidates\n if (!data.candidates || data.candidates.length === 0) {\n throw new NoCandidatesError();\n }\n\n // Use the first candidate\n const candidate = data.candidates[0];\n const message = convertGeminiCandidateToAIMessage(candidate);\n\n // Extract text content from the message\n const text = convertAIMessageToText(message);\n\n const usageMetadata =\n convertGeminiGenerateContentResponseToUsageMetadata(data);\n message.usage_metadata = usageMetadata;\n\n return {\n generations: [\n {\n text,\n message,\n generationInfo: {\n finishReason: candidate.finishReason,\n finishMessage: candidate.finishMessage,\n safetyRatings: candidate.safetyRatings,\n citationMetadata: candidate.citationMetadata,\n tokenCount: candidate.tokenCount,\n },\n },\n ],\n llmOutput: {\n tokenUsage: usageMetadata,\n model: data.modelVersion,\n responseId: data.responseId,\n usageMetadata,\n },\n };\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this[\"ParsedCallOptions\"],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const streamUsage: boolean = this.streamUsage ?? true;\n\n const body = {\n ...this.invocationParams(options),\n systemInstruction: convertMessagesToGeminiSystemInstruction(messages),\n contents: convertMessagesToGeminiContents(messages),\n };\n\n const url = await this.buildUrl(\"streamGenerateContent?alt=sse\");\n const moduleName = this.constructor.name;\n await runManager?.handleCustomEvent(`google-request-${moduleName}`, {\n url,\n body,\n });\n\n const response = await this.apiClient.fetch(\n new Request(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n signal: options.signal,\n })\n );\n\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n url: response.url,\n headers: response.headers,\n status: response.status,\n statusText: response.statusText,\n });\n\n if (!response.ok) {\n const error = await RequestError.fromResponse(response);\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n error,\n });\n throw error;\n }\n\n if (response.body) {\n let previousUsage: UsageMetadata | undefined;\n const stream = response.body\n .pipeThrough(new TextDecoderStream())\n .pipeThrough(new EventSourceParserStream())\n .pipeThrough(\n new SafeJsonEventParserStream<Gemini.GenerateContentResponse>()\n )\n .pipeThrough(\n new TransformStream<\n Gemini.GenerateContentResponse,\n ChatGenerationChunk\n >({\n transform(chunk, controller) {\n // eslint-disable-next-line no-void\n void runManager?.handleCustomEvent(`google-chunk-${moduleName}`, {\n chunk,\n });\n if (chunk === null) {\n controller.enqueue(\n new ChatGenerationChunk({\n text: \"\",\n message: new AIMessageChunk({ content: \"\" }),\n generationInfo: { finishReason: \"stop\" },\n })\n );\n return;\n }\n\n // Extract text delta from the chunk\n const candidate = chunk.candidates?.[0];\n if (!candidate) {\n return;\n }\n\n const message = convertGeminiCandidateToAIMessage(candidate);\n const text = convertAIMessageToText(message);\n\n const parts = candidate.content?.parts ?? [];\n const toolCalls = convertGeminiPartsToToolCalls(parts);\n\n // Only emit if we have content\n if (parts.length > 0 || candidate.finishReason) {\n const messageChunkParams: AIMessageChunkFields = {\n content: message.content,\n tool_calls: toolCalls,\n response_metadata: {\n model_provider: \"google\",\n },\n additional_kwargs: {\n ...(message.additional_kwargs.originalTextContentBlock\n ? {\n originalTextContentBlock:\n message.additional_kwargs.originalTextContentBlock,\n }\n : {}),\n ...(candidate.finishReason\n ? {\n finishReason: candidate.finishReason,\n finishMessage: candidate.finishMessage,\n }\n : {}),\n },\n };\n\n if (chunk?.usageMetadata && streamUsage) {\n const cumulative =\n convertGeminiGenerateContentResponseToUsageMetadata(chunk);\n messageChunkParams.usage_metadata = subtractUsageMetadata(\n cumulative,\n previousUsage\n );\n previousUsage = cumulative;\n }\n const messageChunk = new AIMessageChunk(messageChunkParams);\n\n controller.enqueue(\n new ChatGenerationChunk({\n text: text,\n message: messageChunk,\n generationInfo: {\n ...(candidate.finishReason && {\n finishReason: candidate.finishReason,\n finishMessage: candidate.finishMessage,\n }),\n ...(candidate.safetyRatings && {\n safetyRatings: candidate.safetyRatings,\n }),\n },\n })\n );\n }\n },\n })\n );\n\n const reader = stream.getReader();\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n yield value;\n await runManager?.handleLLMNewToken(\n value.text ?? \"\",\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: value }\n );\n }\n } finally {\n reader.releaseLock();\n }\n }\n }\n\n /**\n * Bind tool-like objects to this chat model.\n *\n * @param tools A list of tool definitions to bind to this chat model.\n * Can be a structured tool, an OpenAI formatted tool, or a Gemini function declaration.\n * @param kwargs Any additional parameters to bind.\n */\n bindTools(\n tools: BindToolsInput[],\n kwargs?: Partial<CallOptions>\n ): Runnable<BaseMessage[], AIMessageChunk, CallOptions> {\n return this.withConfig({\n ...kwargs,\n tools,\n } as Partial<CallOptions>);\n }\n\n /**\n * Get structured output from the model based on a schema.\n *\n * This method supports two modes:\n * - `jsonMode`: Uses `responseSchema` to get JSON responses directly (preferred for structured outputs)\n * - `functionCalling`: Uses function calling with tools (default, for compatibility)\n *\n * @param outputSchema - The schema to use for structured output (Zod schema or JSON Schema)\n * @param config - Configuration options including method and whether to include raw response\n * @returns A Runnable that returns the parsed structured output\n */\n withStructuredOutput<\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>\n >(\n outputSchema:\n | InteropZodType<RunOutput>\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n | Record<string, any>,\n config?: StructuredOutputMethodOptions<boolean>\n ):\n | Runnable<BaseLanguageModelInput, RunOutput>\n | Runnable<\n BaseLanguageModelInput,\n { raw: BaseMessage; parsed: RunOutput }\n > {\n let llm: Runnable<BaseMessage[], AIMessageChunk, CallOptions>;\n let outputParser: Runnable<BaseMessage, RunOutput>;\n\n const { schema, name, includeRaw } = {\n ...config,\n schema: outputSchema,\n };\n let method = config?.method ?? \"functionCalling\";\n\n if (method === \"jsonMode\") {\n console.warn(\n `\"jsonMode\" is not supported for Google models. Falling back to \"jsonSchema\".`\n );\n method = \"jsonSchema\";\n }\n\n if (method === \"jsonSchema\") {\n // Use JSON mode with responseSchema\n llm = this.withConfig({\n responseSchema: schema,\n } as Partial<CallOptions>);\n\n outputParser = RunnableLambda.from<BaseMessage, RunOutput>(\n async (input: BaseMessage): Promise<RunOutput> => {\n if (\n !AIMessage.isInstance(input) &&\n !AIMessageChunk.isInstance(input)\n ) {\n throw new MalformedOutputError({\n message: \"Input is not an AIMessage or AIMessageChunk.\",\n });\n }\n\n if (!input.text) {\n throw new MalformedOutputError({\n message:\n \"No content found in response. Cannot parse structured output.\",\n });\n }\n\n // Parse JSON and validate with schema\n if (isInteropZodSchema(schema)) {\n const zodParser = StructuredOutputParser.fromZodSchema(\n schema as InteropZodType<RunOutput>\n );\n return (await zodParser.parse(input.text)) as RunOutput;\n } else {\n const jsonParser = new JsonOutputParser<RunOutput>();\n return await jsonParser.parse(input.text);\n }\n }\n );\n } else if (method === \"functionCalling\") {\n // Use function calling mode\n let functionName = name ?? \"extract\";\n let tools: Gemini.Tool[];\n\n if (isInteropZodSchema(schema)) {\n const jsonSchema = schemaToGeminiParameters(schema);\n const description =\n typeof jsonSchema.description === \"string\"\n ? jsonSchema.description\n : \"A function available to call.\";\n tools = [\n {\n functionDeclarations: [\n {\n name: functionName,\n description,\n parameters: jsonSchema as Gemini.Tools.Schema,\n },\n ],\n },\n ];\n outputParser = new JsonOutputKeyToolsParser({\n returnSingle: true,\n keyName: functionName,\n zodSchema: schema,\n });\n } else {\n let geminiFunctionDefinition: Gemini.Tools.FunctionDeclaration;\n if (\n typeof schema.name === \"string\" &&\n typeof schema.parameters === \"object\" &&\n schema.parameters != null\n ) {\n geminiFunctionDefinition = schema as Gemini.Tools.FunctionDeclaration;\n functionName = schema.name;\n } else {\n // We are providing the schema for *just* the parameters\n const parameters = schemaToGeminiParameters(schema);\n geminiFunctionDefinition = {\n name: functionName,\n description: (schema as { description?: string }).description ?? \"\",\n parameters,\n };\n }\n tools = [\n {\n functionDeclarations: [geminiFunctionDefinition],\n },\n ];\n outputParser = new JsonOutputKeyToolsParser<RunOutput>({\n returnSingle: true,\n keyName: functionName,\n });\n }\n\n llm = this.bindTools(tools).withConfig({\n tool_choice: functionName,\n } as Partial<CallOptions>);\n } else {\n throw new ConfigurationError(\n `Unrecognized structured output method '${method}'. Expected 'functionCalling' or 'jsonSchema'`\n );\n }\n\n // Shared logic for handling includeRaw\n if (!includeRaw) {\n return llm.pipe(outputParser).withConfig({\n runName: \"ChatGoogleStructuredOutput\",\n }) as Runnable<BaseLanguageModelInput, RunOutput>;\n }\n\n const parserAssign = RunnablePassthrough.assign({\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n parsed: (input: any, config) => outputParser.invoke(input.raw, config),\n });\n const parserNone = RunnablePassthrough.assign({\n parsed: () => null,\n });\n const parsedWithFallback = parserAssign.withFallbacks({\n fallbacks: [parserNone],\n });\n return RunnableSequence.from<\n BaseLanguageModelInput,\n { raw: BaseMessage; parsed: RunOutput }\n >([\n {\n raw: llm,\n },\n parsedWithFallback,\n ]).withConfig({\n runName: \"ChatGoogleStructuredOutputRunnable\",\n });\n }\n}\n\ntype CombinableFields = Omit<BaseChatGoogleParams, \"model\">;\n\nexport function combineGoogleChatModelFields(\n a: CombinableFields,\n b: CombinableFields,\n ...rest: CombinableFields[]\n): CombinableFields {\n const combined: CombinableFields = {\n temperature: b.temperature ?? a.temperature,\n topP: b.topP ?? a.topP,\n topK: b.topK ?? a.topK,\n maxOutputTokens: b.maxOutputTokens ?? a.maxOutputTokens,\n presencePenalty: b.presencePenalty ?? a.presencePenalty,\n frequencyPenalty: b.frequencyPenalty ?? a.frequencyPenalty,\n stopSequences: b.stopSequences ?? a.stopSequences,\n seed: b.seed ?? a.seed,\n responseLogprobs: b.responseLogprobs ?? a.responseLogprobs,\n logprobs: b.logprobs ?? a.logprobs,\n safetySettings: b.safetySettings ?? a.safetySettings,\n responseSchema: b.responseSchema ?? a.responseSchema,\n tools: b.tools ?? a.tools,\n responseModalities: b.responseModalities ?? a.responseModalities,\n enableEnhancedCivicAnswers:\n b.enableEnhancedCivicAnswers ?? a.enableEnhancedCivicAnswers,\n speechConfig: b.speechConfig ?? a.speechConfig,\n imageConfig: b.imageConfig ?? a.imageConfig,\n mediaResolution: b.mediaResolution ?? a.mediaResolution,\n maxReasoningTokens: b.maxReasoningTokens ?? a.maxReasoningTokens,\n thinkingBudget: b.thinkingBudget ?? a.thinkingBudget,\n reasoningEffort: b.reasoningEffort ?? a.reasoningEffort,\n thinkingLevel: b.thinkingLevel ?? a.thinkingLevel,\n };\n if (rest.length > 0) {\n return combineGoogleChatModelFields(combined, rest[0], ...rest.slice(1));\n }\n return combined;\n}\n\nexport function getGoogleChatModelParams<TParams extends BaseChatGoogleParams>(\n modelOrParams: string | TParams,\n paramsArg?: Omit<TParams, \"model\">\n): TParams {\n const model =\n typeof modelOrParams === \"string\" ? modelOrParams : modelOrParams.model;\n const params = typeof modelOrParams === \"string\" ? paramsArg : modelOrParams;\n return { model, ...params } as TParams;\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const require_misc = require('../utils/misc.cjs');
|
|
2
2
|
const require_errors = require('../utils/errors.cjs');
|
|
3
3
|
let _langchain_core_messages = require("@langchain/core/messages");
|
|
4
|
+
let uuid = require("uuid");
|
|
4
5
|
|
|
5
6
|
//#region src/converters/messages.ts
|
|
6
7
|
/**
|
|
@@ -188,6 +189,7 @@ function convertStandardContentMessageToGeminiContent(message) {
|
|
|
188
189
|
if (_langchain_core_messages.ToolMessage.isInstance(message) && message.tool_call_id) {
|
|
189
190
|
const responseContent = typeof message.content === "string" ? message.content : JSON.stringify(message.content);
|
|
190
191
|
parts.push({ functionResponse: {
|
|
192
|
+
id: message.tool_call_id,
|
|
191
193
|
name: message.name || "unknown",
|
|
192
194
|
response: { result: responseContent }
|
|
193
195
|
} });
|
|
@@ -325,6 +327,7 @@ function convertLegacyContentMessageToGeminiContent(message, messages) {
|
|
|
325
327
|
const toolCall = messages.filter(_langchain_core_messages.AIMessage.isInstance).find((msg) => msg.tool_calls?.find((tc) => tc.id === message.tool_call_id));
|
|
326
328
|
if (!toolCall) throw new require_errors.ToolCallNotFoundError(message.tool_call_id);
|
|
327
329
|
parts.push({ functionResponse: {
|
|
330
|
+
id: message.tool_call_id,
|
|
328
331
|
name: toolCall?.name || "unknown",
|
|
329
332
|
response: { result: responseContent }
|
|
330
333
|
} });
|
|
@@ -481,7 +484,7 @@ const convertGeminiPartsToToolCalls = (parts) => {
|
|
|
481
484
|
const functionCallPart = part;
|
|
482
485
|
toolCalls.push({
|
|
483
486
|
type: "tool_call",
|
|
484
|
-
id:
|
|
487
|
+
id: functionCallPart.functionCall.id ?? (0, uuid.v4)().replace(/-/g, ""),
|
|
485
488
|
name: functionCallPart.functionCall.name,
|
|
486
489
|
args: functionCallPart.functionCall.args ?? {},
|
|
487
490
|
thoughtSignature: functionCallPart.thoughtSignature
|