@langchain/google 0.2.13 → 0.2.14
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 +8 -0
- package/dist/chat_models/base.cjs +1 -1
- package/dist/chat_models/base.js +1 -1
- package/dist/chat_models/handlers/generate_content.cjs +2 -1
- package/dist/chat_models/handlers/generate_content.cjs.map +1 -1
- package/dist/chat_models/handlers/generate_content.js +3 -2
- package/dist/chat_models/handlers/generate_content.js.map +1 -1
- package/dist/converters/generate_content/messages.cjs +1 -0
- package/dist/converters/generate_content/messages.cjs.map +1 -1
- package/dist/converters/generate_content/messages.js +1 -0
- package/dist/converters/generate_content/messages.js.map +1 -1
- package/dist/converters/generate_content/stream_events.cjs +8 -1
- package/dist/converters/generate_content/stream_events.cjs.map +1 -1
- package/dist/converters/generate_content/stream_events.js +8 -1
- package/dist/converters/generate_content/stream_events.js.map +1 -1
- package/dist/utils/errors.cjs +21 -2
- package/dist/utils/errors.cjs.map +1 -1
- package/dist/utils/errors.js +21 -4
- package/dist/utils/errors.js.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @langchain/google
|
|
2
2
|
|
|
3
|
+
## 0.2.14
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#12122](https://github.com/langchain-ai/langchainjs/pull/12122) [`e92e44d`](https://github.com/langchain-ai/langchainjs/commit/e92e44d738a394a6b7325978858b3c35d7a7c88a) Thanks [@thushanth-bengre-langchain](https://github.com/thushanth-bengre-langchain)! - fix(google): surface model refusals as `ModelRefusalError`
|
|
8
|
+
|
|
9
|
+
Blocked prompts throw `PromptRefusedError`, which matches `ModelRefusalError.isInstance`, including when streaming. A streamed safety stop keeps the text already streamed and ends with a refusal block, and refusal blocks are dropped when history is sent back.
|
|
10
|
+
|
|
3
11
|
## 0.2.13
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
|
@@ -71,7 +71,7 @@ var BaseChatGoogle = class extends _langchain_core_language_models_chat_models.B
|
|
|
71
71
|
constructor(params) {
|
|
72
72
|
super(params);
|
|
73
73
|
this.params = params;
|
|
74
|
-
this._addVersion("@langchain/google", "0.2.
|
|
74
|
+
this._addVersion("@langchain/google", "0.2.14");
|
|
75
75
|
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.");
|
|
76
76
|
this.apiClient = params.apiClient;
|
|
77
77
|
this.model = params.model;
|
package/dist/chat_models/base.js
CHANGED
|
@@ -71,7 +71,7 @@ var BaseChatGoogle = class extends BaseChatModel {
|
|
|
71
71
|
constructor(params) {
|
|
72
72
|
super(params);
|
|
73
73
|
this.params = params;
|
|
74
|
-
this._addVersion("@langchain/google", "0.2.
|
|
74
|
+
this._addVersion("@langchain/google", "0.2.14");
|
|
75
75
|
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.");
|
|
76
76
|
this.apiClient = params.apiClient;
|
|
77
77
|
this.model = params.model;
|
|
@@ -78,7 +78,7 @@ var GenerateContentApiHandler = class extends require_base.GoogleChatApiHandler
|
|
|
78
78
|
status: response.status,
|
|
79
79
|
statusText: response.statusText
|
|
80
80
|
});
|
|
81
|
-
if (data.promptFeedback?.blockReason) throw require_errors.
|
|
81
|
+
if (data.promptFeedback?.blockReason) throw require_errors.promptBlockedError(data.promptFeedback);
|
|
82
82
|
if (!data.candidates || data.candidates.length === 0) throw new require_errors.NoCandidatesError();
|
|
83
83
|
const candidate = data.candidates[0];
|
|
84
84
|
const message = require_messages.convertGeminiCandidateToAIMessage(candidate);
|
|
@@ -164,6 +164,7 @@ var GenerateContentApiHandler = class extends require_base.GoogleChatApiHandler
|
|
|
164
164
|
}));
|
|
165
165
|
return;
|
|
166
166
|
}
|
|
167
|
+
if (chunk.promptFeedback?.blockReason) throw require_errors.promptBlockedError(chunk.promptFeedback);
|
|
167
168
|
const candidate = chunk.candidates?.[0];
|
|
168
169
|
if (!candidate) {
|
|
169
170
|
if (chunk.usageMetadata && streamUsage) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate_content.cjs","names":["GoogleChatApiHandler","combineGoogleChatModelFields","settableServiceTier","convertMessagesToGeminiSystemInstruction","convertMessagesToGeminiContents","RequestError","PromptBlockedError","NoCandidatesError","convertGeminiCandidateToAIMessage","convertAIMessageToText","convertGeminiGenerateContentResponseToUsageMetadata","iife","usageMetadataToTokenUsage","EventSourceParserStream","SafeJsonEventParserStream","ChatGenerationChunk","AIMessageChunk","subtractUsageMetadata","convertGeminiPartsToToolCalls","convertGoogleGeminiStream","mapDetailToMediaResolution","convertToolsToGeminiTools","convertToolChoiceToGeminiConfig","mixesBuiltinAndFunctionTools","isInteropZodSchema","isSerializableSchema","toJsonSchema","convertFieldsToThinkingConfig","convertFieldsToSpeechConfig","convertFieldsToServiceTier","schemaToGeminiParameters"],"sources":["../../../src/chat_models/handlers/generate_content.ts"],"sourcesContent":["import {\n AIMessageChunk,\n type AIMessageChunkFields,\n type BaseMessage,\n type UsageMetadata,\n} from \"@langchain/core/messages\";\nimport { ChatGenerationChunk, type ChatResult } from \"@langchain/core/outputs\";\nimport type { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport type { BindToolsInput } from \"@langchain/core/language_models/chat_models\";\nimport type { ChatModelStreamEvent } from \"@langchain/core/language_models/event\";\nimport {\n type InteropZodType,\n isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\nimport {\n type SerializableSchema,\n isSerializableSchema,\n} from \"@langchain/core/utils/standard_schema\";\nimport {\n toJsonSchema,\n type JsonSchema7Type,\n} from \"@langchain/core/utils/json_schema\";\nimport { EventSourceParserStream } from \"eventsource-parser/stream\";\nimport { GoogleChatApiHandler } from \"./base.js\";\nimport { SafeJsonEventParserStream } from \"../../utils/stream.js\";\nimport {\n subtractUsageMetadata,\n usageMetadataToTokenUsage,\n} from \"../../utils/metadata.js\";\nimport { iife } from \"../../utils/misc.js\";\nimport {\n PromptBlockedError,\n NoCandidatesError,\n RequestError,\n} from \"../../utils/errors.js\";\nimport {\n convertAIMessageToText,\n convertGeminiCandidateToAIMessage,\n convertGeminiGenerateContentResponseToUsageMetadata,\n convertGeminiPartsToToolCalls,\n convertMessagesToGeminiContents,\n convertMessagesToGeminiSystemInstruction,\n} from \"../../converters/generate_content/messages.js\";\nimport {\n convertToolsToGeminiTools,\n convertToolChoiceToGeminiConfig,\n mixesBuiltinAndFunctionTools,\n schemaToGeminiParameters,\n} from \"../../converters/generate_content/tools.js\";\nimport {\n combineGoogleChatModelFields,\n convertFieldsToSpeechConfig,\n convertFieldsToThinkingConfig,\n convertFieldsToServiceTier,\n mapDetailToMediaResolution,\n} from \"../../converters/generate_content/params.js\";\nimport { convertGoogleGeminiStream } from \"../../converters/generate_content/stream_events.js\";\nimport type {\n BaseChatGoogleCallOptions,\n GenerateContentApiHandlerParams,\n GenerateContentInvocationParams,\n Gemini,\n} from \"../types.js\";\nimport { settableServiceTier } from \"../types.js\";\n\ntype ServiceTier = Gemini.ServiceTier;\n\n/**\n * Concrete wire protocol handler for Google's Generate Content API\n * (`/v1beta/models/{model}:generateContent` and `:streamGenerateContent`).\n */\nexport class GenerateContentApiHandler extends GoogleChatApiHandler<\n GenerateContentInvocationParams,\n GenerateContentApiHandlerParams\n> {\n constructor(params: GenerateContentApiHandlerParams) {\n super(params);\n }\n\n protected get urlMethod(): string {\n return this.params.streaming\n ? \"streamGenerateContent?alt=sse\"\n : \"generateContent\";\n }\n\n protected getUrlSuffix(urlMethod?: string): string {\n const method = urlMethod ?? this.urlMethod;\n return `/models/${this.params.model}:${method}`;\n }\n\n override getHeaders(\n options?: BaseChatGoogleCallOptions\n ): Record<string, string> {\n const fields = combineGoogleChatModelFields(this.params, options ?? {});\n\n // The priority type is set via header only for Vertex\n const priorityHeaders: Record<string, string> =\n this.params.platform === \"gcp\" &&\n typeof fields.serviceTier !== \"undefined\" &&\n settableServiceTier.includes(fields.serviceTier)\n ? { \"X-Vertex-AI-LLM-Shared-Request-Type\": fields.serviceTier }\n : {};\n\n return {\n ...priorityHeaders,\n ...super.getHeaders(options),\n };\n }\n\n async generate(\n messages: BaseMessage[],\n options?: BaseChatGoogleCallOptions,\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n const url = await this.buildUrl(\"generateContent\");\n const headers = this.getHeaders(options);\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 headers,\n body,\n });\n\n let response: Response;\n try {\n response = await this.params.caller.callWithOptions(\n { signal: options?.signal, maxRetries: options?.maxRetries },\n async () => {\n const nextResponse = await this.params.apiClient.fetch(\n new Request(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: options?.signal,\n })\n );\n\n if (!nextResponse.ok) {\n throw await RequestError.fromResponse(nextResponse);\n }\n\n return nextResponse;\n }\n );\n } catch (error) {\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n error,\n });\n throw error;\n }\n\n const data: Gemini.GenContent.GenerateContentResponse =\n await response.json();\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n data,\n url: response.url,\n headers: Array.from(response.headers.entries()),\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 const serviceTier: ServiceTier = iife((): ServiceTier => {\n // @ts-expect-error - trafficType is defined on Vertex, so isn't in the OpenAPI spec\n const trafficType: string | undefined = data.usageMetadata?.trafficType;\n\n // AI Studio replies with actual service type in the header\n const serviceTierHeader: string | null = response.headers.get(\n \"x-gemini-service-tier\"\n );\n\n if (trafficType?.startsWith(\"ON_DEMAND_\")) {\n return trafficType?.substring(\"ON_DEMAND_\".length).toLowerCase();\n }\n return serviceTierHeader || \"standard\";\n });\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: usageMetadataToTokenUsage(usageMetadata),\n model: data.modelVersion,\n responseId: data.responseId,\n usageMetadata,\n serviceTier,\n },\n };\n }\n\n async *streamResponseChunks(\n messages: BaseMessage[],\n options?: BaseChatGoogleCallOptions,\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const streamUsage: boolean =\n options?.streamUsage ?? this.params.streamUsage ?? false;\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 headers = this.getHeaders(options);\n const moduleName = this.constructor.name;\n await runManager?.handleCustomEvent(`google-request-${moduleName}`, {\n url,\n headers,\n body,\n });\n\n let response: Response;\n try {\n response = await this.params.caller.callWithOptions(\n { signal: options?.signal, maxRetries: options?.maxRetries },\n async () => {\n const nextResponse = await this.params.apiClient.fetch(\n new Request(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: options?.signal,\n })\n );\n\n if (!nextResponse.ok) {\n throw await RequestError.fromResponse(nextResponse);\n }\n\n return nextResponse;\n }\n );\n } catch (error) {\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n error,\n });\n throw error;\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.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.GenContent.GenerateContentResponse>()\n )\n .pipeThrough(\n new TransformStream<\n Gemini.GenContent.GenerateContentResponse,\n ChatGenerationChunk\n >({\n transform(chunk, controller) {\n // oxlint-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 if (chunk.usageMetadata && streamUsage) {\n const cumulative =\n convertGeminiGenerateContentResponseToUsageMetadata(chunk);\n controller.enqueue(\n new ChatGenerationChunk({\n text: \"\",\n message: new AIMessageChunk({\n content: \"\",\n response_metadata: { model_provider: \"google\" },\n usage_metadata: subtractUsageMetadata(\n cumulative,\n previousUsage\n ),\n }),\n })\n );\n previousUsage = cumulative;\n }\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 ...(candidate.citationMetadata && {\n citationMetadata: candidate.citationMetadata,\n }),\n ...(candidate.groundingMetadata && {\n groundingMetadata: candidate.groundingMetadata,\n // Support entries for the first content part only (matches messages.ts).\n groundingSupport:\n candidate.groundingMetadata.groundingSupports?.filter(\n (s) => (s?.segment?.partIndex ?? 0) === 0\n ),\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 async *streamChatModelEvents(\n messages: BaseMessage[],\n options?: BaseChatGoogleCallOptions,\n _runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatModelStreamEvent> {\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 headers = this.getHeaders(options);\n\n const response = await this.params.apiClient.fetch(\n new Request(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: options?.signal,\n })\n );\n\n if (!response.ok) {\n throw await RequestError.fromResponse(response);\n }\n\n if (!response.body) {\n return;\n }\n\n const eventStream = response.body\n .pipeThrough(new TextDecoderStream())\n .pipeThrough(new EventSourceParserStream())\n .pipeThrough(\n new SafeJsonEventParserStream<Gemini.GenContent.GenerateContentResponse>()\n );\n\n const shouldStreamUsage =\n this.params.streamUsage !== false && options?.streamUsage !== false;\n\n async function* geminiChunks(\n stream: ReadableStream<Gemini.GenContent.GenerateContentResponse | null>,\n signal?: AbortSignal\n ) {\n const reader = stream.getReader();\n try {\n while (true) {\n if (signal?.aborted) {\n return;\n }\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n if (value !== null) {\n yield value;\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n yield* convertGoogleGeminiStream(\n geminiChunks(eventStream, options?.signal),\n {\n streamUsage: shouldStreamUsage,\n }\n );\n }\n\n invocationParams(\n options?: BaseChatGoogleCallOptions\n ): GenerateContentInvocationParams {\n const fields = combineGoogleChatModelFields(this.params, options ?? {});\n const mediaResolution =\n fields.mediaResolution ?? mapDetailToMediaResolution(fields.detail);\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 let toolConfig = convertToolChoiceToGeminiConfig(\n options?.tool_choice,\n !!(tools && tools.length > 0)\n );\n\n // Gemini rejects a mix of built-in and function-declaration tools unless\n // this is set. See mixesBuiltinAndFunctionTools's docstring.\n if (tools && mixesBuiltinAndFunctionTools(tools)) {\n toolConfig = {\n ...toolConfig,\n includeServerSideToolInvocations: true,\n };\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 (\n isInteropZodSchema(fields.responseSchema) ||\n isSerializableSchema(fields.responseSchema)\n ) {\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(\n this.params.model,\n fields\n ),\n speechConfig: convertFieldsToSpeechConfig(fields),\n ...(fields.imageConfig ? { imageConfig: fields.imageConfig } : {}),\n ...(mediaResolution ? { mediaResolution } : {}),\n },\n ...convertFieldsToServiceTier(this.params.platform, fields),\n };\n }\n\n formatStructuredOutputTool(\n schema: InteropZodType | SerializableSchema | Record<string, unknown>,\n options?: { name?: string; description?: string }\n ): { tools: BindToolsInput[]; toolChoice: string; functionName: string } {\n let functionName = options?.name ?? \"extract\";\n let geminiFunctionDeclaration: Gemini.GenContent.Tools.FunctionDeclaration;\n\n if (isInteropZodSchema(schema) || isSerializableSchema(schema)) {\n const jsonSchema = schemaToGeminiParameters(schema);\n const description =\n options?.description ??\n (typeof jsonSchema.description === \"string\"\n ? jsonSchema.description\n : \"A function available to call.\");\n geminiFunctionDeclaration = {\n name: functionName,\n description,\n parameters: jsonSchema as Gemini.GenContent.Tools.Schema,\n };\n } else if (\n typeof (schema as { name?: unknown }).name === \"string\" &&\n typeof (schema as { parameters?: unknown }).parameters === \"object\" &&\n (schema as { parameters?: unknown }).parameters != null\n ) {\n geminiFunctionDeclaration =\n schema as unknown as Gemini.GenContent.Tools.FunctionDeclaration;\n functionName = (schema as { name: string }).name;\n } else {\n // We are providing the schema for *just* the parameters\n const parameters = schemaToGeminiParameters(schema);\n geminiFunctionDeclaration = {\n name: functionName,\n description:\n options?.description ??\n (schema as { description?: string }).description ??\n \"\",\n parameters,\n };\n }\n\n return {\n tools: [\n {\n functionDeclarations: [geminiFunctionDeclaration],\n },\n ],\n toolChoice: functionName,\n functionName,\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"generate_content.cjs","names":["GoogleChatApiHandler","combineGoogleChatModelFields","settableServiceTier","convertMessagesToGeminiSystemInstruction","convertMessagesToGeminiContents","RequestError","promptBlockedError","NoCandidatesError","convertGeminiCandidateToAIMessage","convertAIMessageToText","convertGeminiGenerateContentResponseToUsageMetadata","iife","usageMetadataToTokenUsage","EventSourceParserStream","SafeJsonEventParserStream","ChatGenerationChunk","AIMessageChunk","subtractUsageMetadata","convertGeminiPartsToToolCalls","convertGoogleGeminiStream","mapDetailToMediaResolution","convertToolsToGeminiTools","convertToolChoiceToGeminiConfig","mixesBuiltinAndFunctionTools","isInteropZodSchema","isSerializableSchema","toJsonSchema","convertFieldsToThinkingConfig","convertFieldsToSpeechConfig","convertFieldsToServiceTier","schemaToGeminiParameters"],"sources":["../../../src/chat_models/handlers/generate_content.ts"],"sourcesContent":["import {\n AIMessageChunk,\n type AIMessageChunkFields,\n type BaseMessage,\n type UsageMetadata,\n} from \"@langchain/core/messages\";\nimport { ChatGenerationChunk, type ChatResult } from \"@langchain/core/outputs\";\nimport type { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport type { BindToolsInput } from \"@langchain/core/language_models/chat_models\";\nimport type { ChatModelStreamEvent } from \"@langchain/core/language_models/event\";\nimport {\n type InteropZodType,\n isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\nimport {\n type SerializableSchema,\n isSerializableSchema,\n} from \"@langchain/core/utils/standard_schema\";\nimport {\n toJsonSchema,\n type JsonSchema7Type,\n} from \"@langchain/core/utils/json_schema\";\nimport { EventSourceParserStream } from \"eventsource-parser/stream\";\nimport { GoogleChatApiHandler } from \"./base.js\";\nimport { SafeJsonEventParserStream } from \"../../utils/stream.js\";\nimport {\n subtractUsageMetadata,\n usageMetadataToTokenUsage,\n} from \"../../utils/metadata.js\";\nimport { iife } from \"../../utils/misc.js\";\nimport {\n NoCandidatesError,\n promptBlockedError,\n RequestError,\n} from \"../../utils/errors.js\";\nimport {\n convertAIMessageToText,\n convertGeminiCandidateToAIMessage,\n convertGeminiGenerateContentResponseToUsageMetadata,\n convertGeminiPartsToToolCalls,\n convertMessagesToGeminiContents,\n convertMessagesToGeminiSystemInstruction,\n} from \"../../converters/generate_content/messages.js\";\nimport {\n convertToolsToGeminiTools,\n convertToolChoiceToGeminiConfig,\n mixesBuiltinAndFunctionTools,\n schemaToGeminiParameters,\n} from \"../../converters/generate_content/tools.js\";\nimport {\n combineGoogleChatModelFields,\n convertFieldsToSpeechConfig,\n convertFieldsToThinkingConfig,\n convertFieldsToServiceTier,\n mapDetailToMediaResolution,\n} from \"../../converters/generate_content/params.js\";\nimport { convertGoogleGeminiStream } from \"../../converters/generate_content/stream_events.js\";\nimport type {\n BaseChatGoogleCallOptions,\n GenerateContentApiHandlerParams,\n GenerateContentInvocationParams,\n Gemini,\n} from \"../types.js\";\nimport { settableServiceTier } from \"../types.js\";\n\ntype ServiceTier = Gemini.ServiceTier;\n\n/**\n * Concrete wire protocol handler for Google's Generate Content API\n * (`/v1beta/models/{model}:generateContent` and `:streamGenerateContent`).\n */\nexport class GenerateContentApiHandler extends GoogleChatApiHandler<\n GenerateContentInvocationParams,\n GenerateContentApiHandlerParams\n> {\n constructor(params: GenerateContentApiHandlerParams) {\n super(params);\n }\n\n protected get urlMethod(): string {\n return this.params.streaming\n ? \"streamGenerateContent?alt=sse\"\n : \"generateContent\";\n }\n\n protected getUrlSuffix(urlMethod?: string): string {\n const method = urlMethod ?? this.urlMethod;\n return `/models/${this.params.model}:${method}`;\n }\n\n override getHeaders(\n options?: BaseChatGoogleCallOptions\n ): Record<string, string> {\n const fields = combineGoogleChatModelFields(this.params, options ?? {});\n\n // The priority type is set via header only for Vertex\n const priorityHeaders: Record<string, string> =\n this.params.platform === \"gcp\" &&\n typeof fields.serviceTier !== \"undefined\" &&\n settableServiceTier.includes(fields.serviceTier)\n ? { \"X-Vertex-AI-LLM-Shared-Request-Type\": fields.serviceTier }\n : {};\n\n return {\n ...priorityHeaders,\n ...super.getHeaders(options),\n };\n }\n\n async generate(\n messages: BaseMessage[],\n options?: BaseChatGoogleCallOptions,\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n const url = await this.buildUrl(\"generateContent\");\n const headers = this.getHeaders(options);\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 headers,\n body,\n });\n\n let response: Response;\n try {\n response = await this.params.caller.callWithOptions(\n { signal: options?.signal, maxRetries: options?.maxRetries },\n async () => {\n const nextResponse = await this.params.apiClient.fetch(\n new Request(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: options?.signal,\n })\n );\n\n if (!nextResponse.ok) {\n throw await RequestError.fromResponse(nextResponse);\n }\n\n return nextResponse;\n }\n );\n } catch (error) {\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n error,\n });\n throw error;\n }\n\n const data: Gemini.GenContent.GenerateContentResponse =\n await response.json();\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n data,\n url: response.url,\n headers: Array.from(response.headers.entries()),\n status: response.status,\n statusText: response.statusText,\n });\n\n // Check for prompt feedback errors\n if (data.promptFeedback?.blockReason) {\n throw promptBlockedError(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 const serviceTier: ServiceTier = iife((): ServiceTier => {\n // @ts-expect-error - trafficType is defined on Vertex, so isn't in the OpenAPI spec\n const trafficType: string | undefined = data.usageMetadata?.trafficType;\n\n // AI Studio replies with actual service type in the header\n const serviceTierHeader: string | null = response.headers.get(\n \"x-gemini-service-tier\"\n );\n\n if (trafficType?.startsWith(\"ON_DEMAND_\")) {\n return trafficType?.substring(\"ON_DEMAND_\".length).toLowerCase();\n }\n return serviceTierHeader || \"standard\";\n });\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: usageMetadataToTokenUsage(usageMetadata),\n model: data.modelVersion,\n responseId: data.responseId,\n usageMetadata,\n serviceTier,\n },\n };\n }\n\n async *streamResponseChunks(\n messages: BaseMessage[],\n options?: BaseChatGoogleCallOptions,\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const streamUsage: boolean =\n options?.streamUsage ?? this.params.streamUsage ?? false;\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 headers = this.getHeaders(options);\n const moduleName = this.constructor.name;\n await runManager?.handleCustomEvent(`google-request-${moduleName}`, {\n url,\n headers,\n body,\n });\n\n let response: Response;\n try {\n response = await this.params.caller.callWithOptions(\n { signal: options?.signal, maxRetries: options?.maxRetries },\n async () => {\n const nextResponse = await this.params.apiClient.fetch(\n new Request(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: options?.signal,\n })\n );\n\n if (!nextResponse.ok) {\n throw await RequestError.fromResponse(nextResponse);\n }\n\n return nextResponse;\n }\n );\n } catch (error) {\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n error,\n });\n throw error;\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.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.GenContent.GenerateContentResponse>()\n )\n .pipeThrough(\n new TransformStream<\n Gemini.GenContent.GenerateContentResponse,\n ChatGenerationChunk\n >({\n transform(chunk, controller) {\n // oxlint-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 if (chunk.promptFeedback?.blockReason) {\n throw promptBlockedError(chunk.promptFeedback);\n }\n\n // Extract text delta from the chunk\n const candidate = chunk.candidates?.[0];\n if (!candidate) {\n if (chunk.usageMetadata && streamUsage) {\n const cumulative =\n convertGeminiGenerateContentResponseToUsageMetadata(chunk);\n controller.enqueue(\n new ChatGenerationChunk({\n text: \"\",\n message: new AIMessageChunk({\n content: \"\",\n response_metadata: { model_provider: \"google\" },\n usage_metadata: subtractUsageMetadata(\n cumulative,\n previousUsage\n ),\n }),\n })\n );\n previousUsage = cumulative;\n }\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 ...(candidate.citationMetadata && {\n citationMetadata: candidate.citationMetadata,\n }),\n ...(candidate.groundingMetadata && {\n groundingMetadata: candidate.groundingMetadata,\n // Support entries for the first content part only (matches messages.ts).\n groundingSupport:\n candidate.groundingMetadata.groundingSupports?.filter(\n (s) => (s?.segment?.partIndex ?? 0) === 0\n ),\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 async *streamChatModelEvents(\n messages: BaseMessage[],\n options?: BaseChatGoogleCallOptions,\n _runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatModelStreamEvent> {\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 headers = this.getHeaders(options);\n\n const response = await this.params.apiClient.fetch(\n new Request(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: options?.signal,\n })\n );\n\n if (!response.ok) {\n throw await RequestError.fromResponse(response);\n }\n\n if (!response.body) {\n return;\n }\n\n const eventStream = response.body\n .pipeThrough(new TextDecoderStream())\n .pipeThrough(new EventSourceParserStream())\n .pipeThrough(\n new SafeJsonEventParserStream<Gemini.GenContent.GenerateContentResponse>()\n );\n\n const shouldStreamUsage =\n this.params.streamUsage !== false && options?.streamUsage !== false;\n\n async function* geminiChunks(\n stream: ReadableStream<Gemini.GenContent.GenerateContentResponse | null>,\n signal?: AbortSignal\n ) {\n const reader = stream.getReader();\n try {\n while (true) {\n if (signal?.aborted) {\n return;\n }\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n if (value !== null) {\n yield value;\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n yield* convertGoogleGeminiStream(\n geminiChunks(eventStream, options?.signal),\n {\n streamUsage: shouldStreamUsage,\n }\n );\n }\n\n invocationParams(\n options?: BaseChatGoogleCallOptions\n ): GenerateContentInvocationParams {\n const fields = combineGoogleChatModelFields(this.params, options ?? {});\n const mediaResolution =\n fields.mediaResolution ?? mapDetailToMediaResolution(fields.detail);\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 let toolConfig = convertToolChoiceToGeminiConfig(\n options?.tool_choice,\n !!(tools && tools.length > 0)\n );\n\n // Gemini rejects a mix of built-in and function-declaration tools unless\n // this is set. See mixesBuiltinAndFunctionTools's docstring.\n if (tools && mixesBuiltinAndFunctionTools(tools)) {\n toolConfig = {\n ...toolConfig,\n includeServerSideToolInvocations: true,\n };\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 (\n isInteropZodSchema(fields.responseSchema) ||\n isSerializableSchema(fields.responseSchema)\n ) {\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(\n this.params.model,\n fields\n ),\n speechConfig: convertFieldsToSpeechConfig(fields),\n ...(fields.imageConfig ? { imageConfig: fields.imageConfig } : {}),\n ...(mediaResolution ? { mediaResolution } : {}),\n },\n ...convertFieldsToServiceTier(this.params.platform, fields),\n };\n }\n\n formatStructuredOutputTool(\n schema: InteropZodType | SerializableSchema | Record<string, unknown>,\n options?: { name?: string; description?: string }\n ): { tools: BindToolsInput[]; toolChoice: string; functionName: string } {\n let functionName = options?.name ?? \"extract\";\n let geminiFunctionDeclaration: Gemini.GenContent.Tools.FunctionDeclaration;\n\n if (isInteropZodSchema(schema) || isSerializableSchema(schema)) {\n const jsonSchema = schemaToGeminiParameters(schema);\n const description =\n options?.description ??\n (typeof jsonSchema.description === \"string\"\n ? jsonSchema.description\n : \"A function available to call.\");\n geminiFunctionDeclaration = {\n name: functionName,\n description,\n parameters: jsonSchema as Gemini.GenContent.Tools.Schema,\n };\n } else if (\n typeof (schema as { name?: unknown }).name === \"string\" &&\n typeof (schema as { parameters?: unknown }).parameters === \"object\" &&\n (schema as { parameters?: unknown }).parameters != null\n ) {\n geminiFunctionDeclaration =\n schema as unknown as Gemini.GenContent.Tools.FunctionDeclaration;\n functionName = (schema as { name: string }).name;\n } else {\n // We are providing the schema for *just* the parameters\n const parameters = schemaToGeminiParameters(schema);\n geminiFunctionDeclaration = {\n name: functionName,\n description:\n options?.description ??\n (schema as { description?: string }).description ??\n \"\",\n parameters,\n };\n }\n\n return {\n tools: [\n {\n functionDeclarations: [geminiFunctionDeclaration],\n },\n ],\n toolChoice: functionName,\n functionName,\n };\n }\n}\n"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { GoogleChatApiHandler } from "./base.js";
|
|
|
2
2
|
import { SafeJsonEventParserStream } from "../../utils/stream.js";
|
|
3
3
|
import { subtractUsageMetadata, usageMetadataToTokenUsage } from "../../utils/metadata.js";
|
|
4
4
|
import { iife } from "../../utils/misc.js";
|
|
5
|
-
import { NoCandidatesError,
|
|
5
|
+
import { NoCandidatesError, RequestError, promptBlockedError } from "../../utils/errors.js";
|
|
6
6
|
import { convertAIMessageToText, convertGeminiCandidateToAIMessage, convertGeminiGenerateContentResponseToUsageMetadata, convertGeminiPartsToToolCalls, convertMessagesToGeminiContents, convertMessagesToGeminiSystemInstruction } from "../../converters/generate_content/messages.js";
|
|
7
7
|
import { convertToolChoiceToGeminiConfig, convertToolsToGeminiTools, mixesBuiltinAndFunctionTools, schemaToGeminiParameters } from "../../converters/generate_content/tools.js";
|
|
8
8
|
import { combineGoogleChatModelFields, convertFieldsToServiceTier, convertFieldsToSpeechConfig, convertFieldsToThinkingConfig, mapDetailToMediaResolution } from "../../converters/generate_content/params.js";
|
|
@@ -78,7 +78,7 @@ var GenerateContentApiHandler = class extends GoogleChatApiHandler {
|
|
|
78
78
|
status: response.status,
|
|
79
79
|
statusText: response.statusText
|
|
80
80
|
});
|
|
81
|
-
if (data.promptFeedback?.blockReason) throw
|
|
81
|
+
if (data.promptFeedback?.blockReason) throw promptBlockedError(data.promptFeedback);
|
|
82
82
|
if (!data.candidates || data.candidates.length === 0) throw new NoCandidatesError();
|
|
83
83
|
const candidate = data.candidates[0];
|
|
84
84
|
const message = convertGeminiCandidateToAIMessage(candidate);
|
|
@@ -164,6 +164,7 @@ var GenerateContentApiHandler = class extends GoogleChatApiHandler {
|
|
|
164
164
|
}));
|
|
165
165
|
return;
|
|
166
166
|
}
|
|
167
|
+
if (chunk.promptFeedback?.blockReason) throw promptBlockedError(chunk.promptFeedback);
|
|
167
168
|
const candidate = chunk.candidates?.[0];
|
|
168
169
|
if (!candidate) {
|
|
169
170
|
if (chunk.usageMetadata && streamUsage) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate_content.js","names":[],"sources":["../../../src/chat_models/handlers/generate_content.ts"],"sourcesContent":["import {\n AIMessageChunk,\n type AIMessageChunkFields,\n type BaseMessage,\n type UsageMetadata,\n} from \"@langchain/core/messages\";\nimport { ChatGenerationChunk, type ChatResult } from \"@langchain/core/outputs\";\nimport type { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport type { BindToolsInput } from \"@langchain/core/language_models/chat_models\";\nimport type { ChatModelStreamEvent } from \"@langchain/core/language_models/event\";\nimport {\n type InteropZodType,\n isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\nimport {\n type SerializableSchema,\n isSerializableSchema,\n} from \"@langchain/core/utils/standard_schema\";\nimport {\n toJsonSchema,\n type JsonSchema7Type,\n} from \"@langchain/core/utils/json_schema\";\nimport { EventSourceParserStream } from \"eventsource-parser/stream\";\nimport { GoogleChatApiHandler } from \"./base.js\";\nimport { SafeJsonEventParserStream } from \"../../utils/stream.js\";\nimport {\n subtractUsageMetadata,\n usageMetadataToTokenUsage,\n} from \"../../utils/metadata.js\";\nimport { iife } from \"../../utils/misc.js\";\nimport {\n PromptBlockedError,\n NoCandidatesError,\n RequestError,\n} from \"../../utils/errors.js\";\nimport {\n convertAIMessageToText,\n convertGeminiCandidateToAIMessage,\n convertGeminiGenerateContentResponseToUsageMetadata,\n convertGeminiPartsToToolCalls,\n convertMessagesToGeminiContents,\n convertMessagesToGeminiSystemInstruction,\n} from \"../../converters/generate_content/messages.js\";\nimport {\n convertToolsToGeminiTools,\n convertToolChoiceToGeminiConfig,\n mixesBuiltinAndFunctionTools,\n schemaToGeminiParameters,\n} from \"../../converters/generate_content/tools.js\";\nimport {\n combineGoogleChatModelFields,\n convertFieldsToSpeechConfig,\n convertFieldsToThinkingConfig,\n convertFieldsToServiceTier,\n mapDetailToMediaResolution,\n} from \"../../converters/generate_content/params.js\";\nimport { convertGoogleGeminiStream } from \"../../converters/generate_content/stream_events.js\";\nimport type {\n BaseChatGoogleCallOptions,\n GenerateContentApiHandlerParams,\n GenerateContentInvocationParams,\n Gemini,\n} from \"../types.js\";\nimport { settableServiceTier } from \"../types.js\";\n\ntype ServiceTier = Gemini.ServiceTier;\n\n/**\n * Concrete wire protocol handler for Google's Generate Content API\n * (`/v1beta/models/{model}:generateContent` and `:streamGenerateContent`).\n */\nexport class GenerateContentApiHandler extends GoogleChatApiHandler<\n GenerateContentInvocationParams,\n GenerateContentApiHandlerParams\n> {\n constructor(params: GenerateContentApiHandlerParams) {\n super(params);\n }\n\n protected get urlMethod(): string {\n return this.params.streaming\n ? \"streamGenerateContent?alt=sse\"\n : \"generateContent\";\n }\n\n protected getUrlSuffix(urlMethod?: string): string {\n const method = urlMethod ?? this.urlMethod;\n return `/models/${this.params.model}:${method}`;\n }\n\n override getHeaders(\n options?: BaseChatGoogleCallOptions\n ): Record<string, string> {\n const fields = combineGoogleChatModelFields(this.params, options ?? {});\n\n // The priority type is set via header only for Vertex\n const priorityHeaders: Record<string, string> =\n this.params.platform === \"gcp\" &&\n typeof fields.serviceTier !== \"undefined\" &&\n settableServiceTier.includes(fields.serviceTier)\n ? { \"X-Vertex-AI-LLM-Shared-Request-Type\": fields.serviceTier }\n : {};\n\n return {\n ...priorityHeaders,\n ...super.getHeaders(options),\n };\n }\n\n async generate(\n messages: BaseMessage[],\n options?: BaseChatGoogleCallOptions,\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n const url = await this.buildUrl(\"generateContent\");\n const headers = this.getHeaders(options);\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 headers,\n body,\n });\n\n let response: Response;\n try {\n response = await this.params.caller.callWithOptions(\n { signal: options?.signal, maxRetries: options?.maxRetries },\n async () => {\n const nextResponse = await this.params.apiClient.fetch(\n new Request(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: options?.signal,\n })\n );\n\n if (!nextResponse.ok) {\n throw await RequestError.fromResponse(nextResponse);\n }\n\n return nextResponse;\n }\n );\n } catch (error) {\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n error,\n });\n throw error;\n }\n\n const data: Gemini.GenContent.GenerateContentResponse =\n await response.json();\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n data,\n url: response.url,\n headers: Array.from(response.headers.entries()),\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 const serviceTier: ServiceTier = iife((): ServiceTier => {\n // @ts-expect-error - trafficType is defined on Vertex, so isn't in the OpenAPI spec\n const trafficType: string | undefined = data.usageMetadata?.trafficType;\n\n // AI Studio replies with actual service type in the header\n const serviceTierHeader: string | null = response.headers.get(\n \"x-gemini-service-tier\"\n );\n\n if (trafficType?.startsWith(\"ON_DEMAND_\")) {\n return trafficType?.substring(\"ON_DEMAND_\".length).toLowerCase();\n }\n return serviceTierHeader || \"standard\";\n });\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: usageMetadataToTokenUsage(usageMetadata),\n model: data.modelVersion,\n responseId: data.responseId,\n usageMetadata,\n serviceTier,\n },\n };\n }\n\n async *streamResponseChunks(\n messages: BaseMessage[],\n options?: BaseChatGoogleCallOptions,\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const streamUsage: boolean =\n options?.streamUsage ?? this.params.streamUsage ?? false;\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 headers = this.getHeaders(options);\n const moduleName = this.constructor.name;\n await runManager?.handleCustomEvent(`google-request-${moduleName}`, {\n url,\n headers,\n body,\n });\n\n let response: Response;\n try {\n response = await this.params.caller.callWithOptions(\n { signal: options?.signal, maxRetries: options?.maxRetries },\n async () => {\n const nextResponse = await this.params.apiClient.fetch(\n new Request(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: options?.signal,\n })\n );\n\n if (!nextResponse.ok) {\n throw await RequestError.fromResponse(nextResponse);\n }\n\n return nextResponse;\n }\n );\n } catch (error) {\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n error,\n });\n throw error;\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.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.GenContent.GenerateContentResponse>()\n )\n .pipeThrough(\n new TransformStream<\n Gemini.GenContent.GenerateContentResponse,\n ChatGenerationChunk\n >({\n transform(chunk, controller) {\n // oxlint-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 if (chunk.usageMetadata && streamUsage) {\n const cumulative =\n convertGeminiGenerateContentResponseToUsageMetadata(chunk);\n controller.enqueue(\n new ChatGenerationChunk({\n text: \"\",\n message: new AIMessageChunk({\n content: \"\",\n response_metadata: { model_provider: \"google\" },\n usage_metadata: subtractUsageMetadata(\n cumulative,\n previousUsage\n ),\n }),\n })\n );\n previousUsage = cumulative;\n }\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 ...(candidate.citationMetadata && {\n citationMetadata: candidate.citationMetadata,\n }),\n ...(candidate.groundingMetadata && {\n groundingMetadata: candidate.groundingMetadata,\n // Support entries for the first content part only (matches messages.ts).\n groundingSupport:\n candidate.groundingMetadata.groundingSupports?.filter(\n (s) => (s?.segment?.partIndex ?? 0) === 0\n ),\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 async *streamChatModelEvents(\n messages: BaseMessage[],\n options?: BaseChatGoogleCallOptions,\n _runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatModelStreamEvent> {\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 headers = this.getHeaders(options);\n\n const response = await this.params.apiClient.fetch(\n new Request(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: options?.signal,\n })\n );\n\n if (!response.ok) {\n throw await RequestError.fromResponse(response);\n }\n\n if (!response.body) {\n return;\n }\n\n const eventStream = response.body\n .pipeThrough(new TextDecoderStream())\n .pipeThrough(new EventSourceParserStream())\n .pipeThrough(\n new SafeJsonEventParserStream<Gemini.GenContent.GenerateContentResponse>()\n );\n\n const shouldStreamUsage =\n this.params.streamUsage !== false && options?.streamUsage !== false;\n\n async function* geminiChunks(\n stream: ReadableStream<Gemini.GenContent.GenerateContentResponse | null>,\n signal?: AbortSignal\n ) {\n const reader = stream.getReader();\n try {\n while (true) {\n if (signal?.aborted) {\n return;\n }\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n if (value !== null) {\n yield value;\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n yield* convertGoogleGeminiStream(\n geminiChunks(eventStream, options?.signal),\n {\n streamUsage: shouldStreamUsage,\n }\n );\n }\n\n invocationParams(\n options?: BaseChatGoogleCallOptions\n ): GenerateContentInvocationParams {\n const fields = combineGoogleChatModelFields(this.params, options ?? {});\n const mediaResolution =\n fields.mediaResolution ?? mapDetailToMediaResolution(fields.detail);\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 let toolConfig = convertToolChoiceToGeminiConfig(\n options?.tool_choice,\n !!(tools && tools.length > 0)\n );\n\n // Gemini rejects a mix of built-in and function-declaration tools unless\n // this is set. See mixesBuiltinAndFunctionTools's docstring.\n if (tools && mixesBuiltinAndFunctionTools(tools)) {\n toolConfig = {\n ...toolConfig,\n includeServerSideToolInvocations: true,\n };\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 (\n isInteropZodSchema(fields.responseSchema) ||\n isSerializableSchema(fields.responseSchema)\n ) {\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(\n this.params.model,\n fields\n ),\n speechConfig: convertFieldsToSpeechConfig(fields),\n ...(fields.imageConfig ? { imageConfig: fields.imageConfig } : {}),\n ...(mediaResolution ? { mediaResolution } : {}),\n },\n ...convertFieldsToServiceTier(this.params.platform, fields),\n };\n }\n\n formatStructuredOutputTool(\n schema: InteropZodType | SerializableSchema | Record<string, unknown>,\n options?: { name?: string; description?: string }\n ): { tools: BindToolsInput[]; toolChoice: string; functionName: string } {\n let functionName = options?.name ?? \"extract\";\n let geminiFunctionDeclaration: Gemini.GenContent.Tools.FunctionDeclaration;\n\n if (isInteropZodSchema(schema) || isSerializableSchema(schema)) {\n const jsonSchema = schemaToGeminiParameters(schema);\n const description =\n options?.description ??\n (typeof jsonSchema.description === \"string\"\n ? jsonSchema.description\n : \"A function available to call.\");\n geminiFunctionDeclaration = {\n name: functionName,\n description,\n parameters: jsonSchema as Gemini.GenContent.Tools.Schema,\n };\n } else if (\n typeof (schema as { name?: unknown }).name === \"string\" &&\n typeof (schema as { parameters?: unknown }).parameters === \"object\" &&\n (schema as { parameters?: unknown }).parameters != null\n ) {\n geminiFunctionDeclaration =\n schema as unknown as Gemini.GenContent.Tools.FunctionDeclaration;\n functionName = (schema as { name: string }).name;\n } else {\n // We are providing the schema for *just* the parameters\n const parameters = schemaToGeminiParameters(schema);\n geminiFunctionDeclaration = {\n name: functionName,\n description:\n options?.description ??\n (schema as { description?: string }).description ??\n \"\",\n parameters,\n };\n }\n\n return {\n tools: [\n {\n functionDeclarations: [geminiFunctionDeclaration],\n },\n ],\n toolChoice: functionName,\n functionName,\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"generate_content.js","names":[],"sources":["../../../src/chat_models/handlers/generate_content.ts"],"sourcesContent":["import {\n AIMessageChunk,\n type AIMessageChunkFields,\n type BaseMessage,\n type UsageMetadata,\n} from \"@langchain/core/messages\";\nimport { ChatGenerationChunk, type ChatResult } from \"@langchain/core/outputs\";\nimport type { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport type { BindToolsInput } from \"@langchain/core/language_models/chat_models\";\nimport type { ChatModelStreamEvent } from \"@langchain/core/language_models/event\";\nimport {\n type InteropZodType,\n isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\nimport {\n type SerializableSchema,\n isSerializableSchema,\n} from \"@langchain/core/utils/standard_schema\";\nimport {\n toJsonSchema,\n type JsonSchema7Type,\n} from \"@langchain/core/utils/json_schema\";\nimport { EventSourceParserStream } from \"eventsource-parser/stream\";\nimport { GoogleChatApiHandler } from \"./base.js\";\nimport { SafeJsonEventParserStream } from \"../../utils/stream.js\";\nimport {\n subtractUsageMetadata,\n usageMetadataToTokenUsage,\n} from \"../../utils/metadata.js\";\nimport { iife } from \"../../utils/misc.js\";\nimport {\n NoCandidatesError,\n promptBlockedError,\n RequestError,\n} from \"../../utils/errors.js\";\nimport {\n convertAIMessageToText,\n convertGeminiCandidateToAIMessage,\n convertGeminiGenerateContentResponseToUsageMetadata,\n convertGeminiPartsToToolCalls,\n convertMessagesToGeminiContents,\n convertMessagesToGeminiSystemInstruction,\n} from \"../../converters/generate_content/messages.js\";\nimport {\n convertToolsToGeminiTools,\n convertToolChoiceToGeminiConfig,\n mixesBuiltinAndFunctionTools,\n schemaToGeminiParameters,\n} from \"../../converters/generate_content/tools.js\";\nimport {\n combineGoogleChatModelFields,\n convertFieldsToSpeechConfig,\n convertFieldsToThinkingConfig,\n convertFieldsToServiceTier,\n mapDetailToMediaResolution,\n} from \"../../converters/generate_content/params.js\";\nimport { convertGoogleGeminiStream } from \"../../converters/generate_content/stream_events.js\";\nimport type {\n BaseChatGoogleCallOptions,\n GenerateContentApiHandlerParams,\n GenerateContentInvocationParams,\n Gemini,\n} from \"../types.js\";\nimport { settableServiceTier } from \"../types.js\";\n\ntype ServiceTier = Gemini.ServiceTier;\n\n/**\n * Concrete wire protocol handler for Google's Generate Content API\n * (`/v1beta/models/{model}:generateContent` and `:streamGenerateContent`).\n */\nexport class GenerateContentApiHandler extends GoogleChatApiHandler<\n GenerateContentInvocationParams,\n GenerateContentApiHandlerParams\n> {\n constructor(params: GenerateContentApiHandlerParams) {\n super(params);\n }\n\n protected get urlMethod(): string {\n return this.params.streaming\n ? \"streamGenerateContent?alt=sse\"\n : \"generateContent\";\n }\n\n protected getUrlSuffix(urlMethod?: string): string {\n const method = urlMethod ?? this.urlMethod;\n return `/models/${this.params.model}:${method}`;\n }\n\n override getHeaders(\n options?: BaseChatGoogleCallOptions\n ): Record<string, string> {\n const fields = combineGoogleChatModelFields(this.params, options ?? {});\n\n // The priority type is set via header only for Vertex\n const priorityHeaders: Record<string, string> =\n this.params.platform === \"gcp\" &&\n typeof fields.serviceTier !== \"undefined\" &&\n settableServiceTier.includes(fields.serviceTier)\n ? { \"X-Vertex-AI-LLM-Shared-Request-Type\": fields.serviceTier }\n : {};\n\n return {\n ...priorityHeaders,\n ...super.getHeaders(options),\n };\n }\n\n async generate(\n messages: BaseMessage[],\n options?: BaseChatGoogleCallOptions,\n runManager?: CallbackManagerForLLMRun\n ): Promise<ChatResult> {\n const url = await this.buildUrl(\"generateContent\");\n const headers = this.getHeaders(options);\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 headers,\n body,\n });\n\n let response: Response;\n try {\n response = await this.params.caller.callWithOptions(\n { signal: options?.signal, maxRetries: options?.maxRetries },\n async () => {\n const nextResponse = await this.params.apiClient.fetch(\n new Request(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: options?.signal,\n })\n );\n\n if (!nextResponse.ok) {\n throw await RequestError.fromResponse(nextResponse);\n }\n\n return nextResponse;\n }\n );\n } catch (error) {\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n error,\n });\n throw error;\n }\n\n const data: Gemini.GenContent.GenerateContentResponse =\n await response.json();\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n data,\n url: response.url,\n headers: Array.from(response.headers.entries()),\n status: response.status,\n statusText: response.statusText,\n });\n\n // Check for prompt feedback errors\n if (data.promptFeedback?.blockReason) {\n throw promptBlockedError(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 const serviceTier: ServiceTier = iife((): ServiceTier => {\n // @ts-expect-error - trafficType is defined on Vertex, so isn't in the OpenAPI spec\n const trafficType: string | undefined = data.usageMetadata?.trafficType;\n\n // AI Studio replies with actual service type in the header\n const serviceTierHeader: string | null = response.headers.get(\n \"x-gemini-service-tier\"\n );\n\n if (trafficType?.startsWith(\"ON_DEMAND_\")) {\n return trafficType?.substring(\"ON_DEMAND_\".length).toLowerCase();\n }\n return serviceTierHeader || \"standard\";\n });\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: usageMetadataToTokenUsage(usageMetadata),\n model: data.modelVersion,\n responseId: data.responseId,\n usageMetadata,\n serviceTier,\n },\n };\n }\n\n async *streamResponseChunks(\n messages: BaseMessage[],\n options?: BaseChatGoogleCallOptions,\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const streamUsage: boolean =\n options?.streamUsage ?? this.params.streamUsage ?? false;\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 headers = this.getHeaders(options);\n const moduleName = this.constructor.name;\n await runManager?.handleCustomEvent(`google-request-${moduleName}`, {\n url,\n headers,\n body,\n });\n\n let response: Response;\n try {\n response = await this.params.caller.callWithOptions(\n { signal: options?.signal, maxRetries: options?.maxRetries },\n async () => {\n const nextResponse = await this.params.apiClient.fetch(\n new Request(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: options?.signal,\n })\n );\n\n if (!nextResponse.ok) {\n throw await RequestError.fromResponse(nextResponse);\n }\n\n return nextResponse;\n }\n );\n } catch (error) {\n await runManager?.handleCustomEvent(`google-response-${moduleName}`, {\n error,\n });\n throw error;\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.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.GenContent.GenerateContentResponse>()\n )\n .pipeThrough(\n new TransformStream<\n Gemini.GenContent.GenerateContentResponse,\n ChatGenerationChunk\n >({\n transform(chunk, controller) {\n // oxlint-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 if (chunk.promptFeedback?.blockReason) {\n throw promptBlockedError(chunk.promptFeedback);\n }\n\n // Extract text delta from the chunk\n const candidate = chunk.candidates?.[0];\n if (!candidate) {\n if (chunk.usageMetadata && streamUsage) {\n const cumulative =\n convertGeminiGenerateContentResponseToUsageMetadata(chunk);\n controller.enqueue(\n new ChatGenerationChunk({\n text: \"\",\n message: new AIMessageChunk({\n content: \"\",\n response_metadata: { model_provider: \"google\" },\n usage_metadata: subtractUsageMetadata(\n cumulative,\n previousUsage\n ),\n }),\n })\n );\n previousUsage = cumulative;\n }\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 ...(candidate.citationMetadata && {\n citationMetadata: candidate.citationMetadata,\n }),\n ...(candidate.groundingMetadata && {\n groundingMetadata: candidate.groundingMetadata,\n // Support entries for the first content part only (matches messages.ts).\n groundingSupport:\n candidate.groundingMetadata.groundingSupports?.filter(\n (s) => (s?.segment?.partIndex ?? 0) === 0\n ),\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 async *streamChatModelEvents(\n messages: BaseMessage[],\n options?: BaseChatGoogleCallOptions,\n _runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatModelStreamEvent> {\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 headers = this.getHeaders(options);\n\n const response = await this.params.apiClient.fetch(\n new Request(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n signal: options?.signal,\n })\n );\n\n if (!response.ok) {\n throw await RequestError.fromResponse(response);\n }\n\n if (!response.body) {\n return;\n }\n\n const eventStream = response.body\n .pipeThrough(new TextDecoderStream())\n .pipeThrough(new EventSourceParserStream())\n .pipeThrough(\n new SafeJsonEventParserStream<Gemini.GenContent.GenerateContentResponse>()\n );\n\n const shouldStreamUsage =\n this.params.streamUsage !== false && options?.streamUsage !== false;\n\n async function* geminiChunks(\n stream: ReadableStream<Gemini.GenContent.GenerateContentResponse | null>,\n signal?: AbortSignal\n ) {\n const reader = stream.getReader();\n try {\n while (true) {\n if (signal?.aborted) {\n return;\n }\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n if (value !== null) {\n yield value;\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n yield* convertGoogleGeminiStream(\n geminiChunks(eventStream, options?.signal),\n {\n streamUsage: shouldStreamUsage,\n }\n );\n }\n\n invocationParams(\n options?: BaseChatGoogleCallOptions\n ): GenerateContentInvocationParams {\n const fields = combineGoogleChatModelFields(this.params, options ?? {});\n const mediaResolution =\n fields.mediaResolution ?? mapDetailToMediaResolution(fields.detail);\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 let toolConfig = convertToolChoiceToGeminiConfig(\n options?.tool_choice,\n !!(tools && tools.length > 0)\n );\n\n // Gemini rejects a mix of built-in and function-declaration tools unless\n // this is set. See mixesBuiltinAndFunctionTools's docstring.\n if (tools && mixesBuiltinAndFunctionTools(tools)) {\n toolConfig = {\n ...toolConfig,\n includeServerSideToolInvocations: true,\n };\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 (\n isInteropZodSchema(fields.responseSchema) ||\n isSerializableSchema(fields.responseSchema)\n ) {\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(\n this.params.model,\n fields\n ),\n speechConfig: convertFieldsToSpeechConfig(fields),\n ...(fields.imageConfig ? { imageConfig: fields.imageConfig } : {}),\n ...(mediaResolution ? { mediaResolution } : {}),\n },\n ...convertFieldsToServiceTier(this.params.platform, fields),\n };\n }\n\n formatStructuredOutputTool(\n schema: InteropZodType | SerializableSchema | Record<string, unknown>,\n options?: { name?: string; description?: string }\n ): { tools: BindToolsInput[]; toolChoice: string; functionName: string } {\n let functionName = options?.name ?? \"extract\";\n let geminiFunctionDeclaration: Gemini.GenContent.Tools.FunctionDeclaration;\n\n if (isInteropZodSchema(schema) || isSerializableSchema(schema)) {\n const jsonSchema = schemaToGeminiParameters(schema);\n const description =\n options?.description ??\n (typeof jsonSchema.description === \"string\"\n ? jsonSchema.description\n : \"A function available to call.\");\n geminiFunctionDeclaration = {\n name: functionName,\n description,\n parameters: jsonSchema as Gemini.GenContent.Tools.Schema,\n };\n } else if (\n typeof (schema as { name?: unknown }).name === \"string\" &&\n typeof (schema as { parameters?: unknown }).parameters === \"object\" &&\n (schema as { parameters?: unknown }).parameters != null\n ) {\n geminiFunctionDeclaration =\n schema as unknown as Gemini.GenContent.Tools.FunctionDeclaration;\n functionName = (schema as { name: string }).name;\n } else {\n // We are providing the schema for *just* the parameters\n const parameters = schemaToGeminiParameters(schema);\n geminiFunctionDeclaration = {\n name: functionName,\n description:\n options?.description ??\n (schema as { description?: string }).description ??\n \"\",\n parameters,\n };\n }\n\n return {\n tools: [\n {\n functionDeclarations: [geminiFunctionDeclaration],\n },\n ],\n toolChoice: functionName,\n functionName,\n };\n }\n}\n"],"mappings":"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"}
|
|
@@ -393,6 +393,7 @@ function convertLegacyContentMessageToGeminiContent(message, messages) {
|
|
|
393
393
|
if (typeof message.content === "string") {
|
|
394
394
|
if (message.content.trim()) parts.push({ text: message.content });
|
|
395
395
|
} else if (Array.isArray(message.content)) for (const item of message.content) {
|
|
396
|
+
if (typeof item === "object" && item?.type === "refusal") continue;
|
|
396
397
|
const part = convertLegacyPartToGeminiPart(item);
|
|
397
398
|
parts.push(part);
|
|
398
399
|
}
|