@nhtio/adk 1.20260924.0 → 1.20260928.0
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 +87 -0
- package/artifact_methods-Cg0go7Q4.mjs +1 -0
- package/artifact_methods-CxeKTocm.cjs +1 -0
- package/batteries/artifacts/ecmascript.cjs +1 -1
- package/batteries/artifacts/ecmascript.mjs +1 -1
- package/batteries/artifacts/toon.cjs +1 -1
- package/batteries/artifacts/toon.mjs +1 -1
- package/batteries/artifacts/xml.cjs +1 -1
- package/batteries/artifacts/xml.mjs +1 -1
- package/batteries/artifacts/yaml.cjs +1 -1
- package/batteries/artifacts/yaml.mjs +1 -1
- package/batteries/artifacts.cjs +4 -4
- package/batteries/artifacts.mjs +4 -4
- package/batteries/dev-tools/forge.cjs +3 -3
- package/batteries/dev-tools/forge.mjs +3 -3
- package/batteries/dev-tools.cjs +3 -3
- package/batteries/dev-tools.mjs +3 -3
- package/batteries/encoding.cjs +7 -7
- package/batteries/encoding.mjs +7 -7
- package/batteries/generation/gemini/adapter.cjs +1 -1
- package/batteries/generation/gemini/adapter.mjs +1 -1
- package/batteries/generation/local_diffusion/adapter.cjs +1 -1
- package/batteries/generation/local_diffusion/adapter.mjs +1 -1
- package/batteries/generation/openai/adapter.cjs +1 -1
- package/batteries/generation/openai/adapter.mjs +1 -1
- package/batteries/llm/anthropic_messages/adapter.cjs +6 -6
- package/batteries/llm/anthropic_messages/adapter.mjs +6 -6
- package/batteries/llm/anthropic_messages/count_tokens.cjs +1 -1
- package/batteries/llm/anthropic_messages/count_tokens.mjs +1 -1
- package/batteries/llm/anthropic_messages/helpers.cjs +3 -3
- package/batteries/llm/anthropic_messages/helpers.mjs +3 -3
- package/batteries/llm/anthropic_messages/validation.cjs +2 -2
- package/batteries/llm/anthropic_messages/validation.mjs +2 -2
- package/batteries/llm/anthropic_messages.cjs +2 -2
- package/batteries/llm/anthropic_messages.mjs +2 -2
- package/batteries/llm/bedrock_converse/adapter.cjs +162 -21
- package/batteries/llm/bedrock_converse/adapter.cjs.map +1 -1
- package/batteries/llm/bedrock_converse/adapter.mjs +162 -21
- package/batteries/llm/bedrock_converse/adapter.mjs.map +1 -1
- package/batteries/llm/bedrock_converse/helpers.cjs +1 -1
- package/batteries/llm/bedrock_converse/helpers.mjs +1 -1
- package/batteries/llm/bedrock_converse/validation.cjs +2 -2
- package/batteries/llm/bedrock_converse/validation.mjs +2 -2
- package/batteries/llm/bedrock_converse.cjs +2 -2
- package/batteries/llm/bedrock_converse.mjs +2 -2
- package/batteries/llm/claude_code_cli/adapter.cjs +66 -25
- package/batteries/llm/claude_code_cli/adapter.cjs.map +1 -1
- package/batteries/llm/claude_code_cli/adapter.mjs +66 -25
- package/batteries/llm/claude_code_cli/adapter.mjs.map +1 -1
- package/batteries/llm/claude_code_cli/helpers.cjs +3 -3
- package/batteries/llm/claude_code_cli/helpers.mjs +3 -3
- package/batteries/llm/claude_code_cli/line_queue.d.ts +39 -0
- package/batteries/llm/claude_code_cli/message_id_state.d.ts +48 -0
- package/batteries/llm/claude_code_cli/types.d.ts +76 -0
- package/batteries/llm/claude_code_cli/validation.cjs +5 -2
- package/batteries/llm/claude_code_cli/validation.cjs.map +1 -1
- package/batteries/llm/claude_code_cli/validation.mjs +5 -2
- package/batteries/llm/claude_code_cli/validation.mjs.map +1 -1
- package/batteries/llm/claude_code_cli/wire.cjs.map +1 -1
- package/batteries/llm/claude_code_cli/wire.d.ts +45 -1
- package/batteries/llm/claude_code_cli/wire.mjs.map +1 -1
- package/batteries/llm/claude_code_cli/wrapper.d.ts +5 -4
- package/batteries/llm/claude_code_cli.cjs +2 -2
- package/batteries/llm/claude_code_cli.mjs +2 -2
- package/batteries/llm/gemini_generate_content/adapter.cjs +160 -19
- package/batteries/llm/gemini_generate_content/adapter.cjs.map +1 -1
- package/batteries/llm/gemini_generate_content/adapter.mjs +160 -19
- package/batteries/llm/gemini_generate_content/adapter.mjs.map +1 -1
- package/batteries/llm/gemini_generate_content/helpers.cjs +1 -1
- package/batteries/llm/gemini_generate_content/helpers.mjs +1 -1
- package/batteries/llm/gemini_generate_content/validation.cjs +2 -2
- package/batteries/llm/gemini_generate_content/validation.mjs +2 -2
- package/batteries/llm/gemini_generate_content.cjs +1 -1
- package/batteries/llm/gemini_generate_content.mjs +1 -1
- package/batteries/llm/litert_lm/adapter.cjs +6 -6
- package/batteries/llm/litert_lm/adapter.mjs +6 -6
- package/batteries/llm/litert_lm/helpers.cjs +3 -3
- package/batteries/llm/litert_lm/helpers.mjs +3 -3
- package/batteries/llm/litert_lm/validation.cjs +2 -2
- package/batteries/llm/litert_lm/validation.mjs +2 -2
- package/batteries/llm/litert_lm.cjs +1 -1
- package/batteries/llm/litert_lm.mjs +1 -1
- package/batteries/llm/ollama/adapter.cjs +6 -6
- package/batteries/llm/ollama/adapter.mjs +6 -6
- package/batteries/llm/ollama/helpers.cjs +4 -4
- package/batteries/llm/ollama/helpers.mjs +4 -4
- package/batteries/llm/ollama/validation.cjs +2 -2
- package/batteries/llm/ollama/validation.mjs +2 -2
- package/batteries/llm/ollama.cjs +2 -2
- package/batteries/llm/ollama.mjs +2 -2
- package/batteries/llm/openai_chat_completions/adapter.cjs +6 -6
- package/batteries/llm/openai_chat_completions/adapter.mjs +6 -6
- package/batteries/llm/openai_chat_completions/helpers.cjs +4 -4
- package/batteries/llm/openai_chat_completions/helpers.mjs +4 -4
- package/batteries/llm/openai_chat_completions/validation.cjs +2 -2
- package/batteries/llm/openai_chat_completions/validation.mjs +2 -2
- package/batteries/llm/openai_chat_completions.cjs +2 -2
- package/batteries/llm/openai_chat_completions.mjs +2 -2
- package/batteries/llm/openai_responses/adapter.cjs +6 -6
- package/batteries/llm/openai_responses/adapter.mjs +6 -6
- package/batteries/llm/openai_responses/helpers.cjs +3 -3
- package/batteries/llm/openai_responses/helpers.mjs +3 -3
- package/batteries/llm/openai_responses/validation.cjs +2 -2
- package/batteries/llm/openai_responses/validation.mjs +2 -2
- package/batteries/llm/openai_responses.cjs +2 -2
- package/batteries/llm/openai_responses.mjs +2 -2
- package/batteries/llm/transformers_js/adapter.cjs +6 -6
- package/batteries/llm/transformers_js/adapter.mjs +6 -6
- package/batteries/llm/transformers_js/helpers.cjs +3 -3
- package/batteries/llm/transformers_js/helpers.mjs +3 -3
- package/batteries/llm/transformers_js/validation.cjs +2 -2
- package/batteries/llm/transformers_js/validation.mjs +2 -2
- package/batteries/llm/transformers_js.cjs +1 -1
- package/batteries/llm/transformers_js.mjs +1 -1
- package/batteries/llm/webllm_chat_completions/adapter.cjs +6 -6
- package/batteries/llm/webllm_chat_completions/adapter.mjs +6 -6
- package/batteries/llm/webllm_chat_completions/helpers.cjs +1 -1
- package/batteries/llm/webllm_chat_completions/helpers.mjs +1 -1
- package/batteries/llm/webllm_chat_completions/validation.cjs +2 -2
- package/batteries/llm/webllm_chat_completions/validation.mjs +2 -2
- package/batteries/llm/webllm_chat_completions.cjs +2 -2
- package/batteries/llm/webllm_chat_completions.mjs +2 -2
- package/batteries/llm.cjs +2 -2
- package/batteries/llm.mjs +2 -2
- package/batteries/media/forge.cjs +4 -4
- package/batteries/media/forge.mjs +4 -4
- package/batteries/media/lint.cjs +1 -1
- package/batteries/media/lint.mjs +1 -1
- package/batteries/orchestration/dispatch_reasoner.cjs +4 -4
- package/batteries/orchestration/dispatch_reasoner.mjs +4 -4
- package/batteries/orchestration/executor.cjs +2 -2
- package/batteries/orchestration/executor.mjs +2 -2
- package/batteries/orchestration/forge.cjs +4 -4
- package/batteries/orchestration/forge.mjs +4 -4
- package/batteries/orchestration/validation.cjs +2 -2
- package/batteries/orchestration/validation.mjs +2 -2
- package/batteries/orchestration.cjs +4 -4
- package/batteries/orchestration.mjs +4 -4
- package/batteries/sandbox/js.cjs +1 -1
- package/batteries/sandbox/js.mjs +1 -1
- package/batteries/sandbox/tools.cjs +1 -1
- package/batteries/sandbox/tools.mjs +1 -1
- package/batteries/sandbox.cjs +3 -3
- package/batteries/sandbox.mjs +3 -3
- package/batteries/skills.cjs +9 -9
- package/batteries/skills.mjs +9 -9
- package/batteries/tools/_shared.cjs +1 -1
- package/batteries/tools/_shared.mjs +1 -1
- package/batteries/tools/color.cjs +2 -2
- package/batteries/tools/color.mjs +2 -2
- package/batteries/tools/comparison.cjs +2 -2
- package/batteries/tools/comparison.mjs +2 -2
- package/batteries/tools/data_structure.cjs +2 -2
- package/batteries/tools/data_structure.mjs +2 -2
- package/batteries/tools/datetime_extended.cjs +3 -3
- package/batteries/tools/datetime_extended.mjs +3 -3
- package/batteries/tools/datetime_math.cjs +3 -3
- package/batteries/tools/datetime_math.mjs +3 -3
- package/batteries/tools/encoding.cjs +2 -2
- package/batteries/tools/encoding.mjs +2 -2
- package/batteries/tools/formatting.cjs +2 -2
- package/batteries/tools/formatting.mjs +2 -2
- package/batteries/tools/geo_basics.cjs +2 -2
- package/batteries/tools/geo_basics.mjs +2 -2
- package/batteries/tools/math.cjs +2 -2
- package/batteries/tools/math.mjs +2 -2
- package/batteries/tools/memory.cjs +5 -5
- package/batteries/tools/memory.mjs +5 -5
- package/batteries/tools/parsing.cjs +3 -3
- package/batteries/tools/parsing.mjs +3 -3
- package/batteries/tools/retrievables.cjs +5 -5
- package/batteries/tools/retrievables.mjs +5 -5
- package/batteries/tools/scrapper.cjs +1 -1
- package/batteries/tools/scrapper.mjs +1 -1
- package/batteries/tools/searxng.cjs +1 -1
- package/batteries/tools/searxng.mjs +1 -1
- package/batteries/tools/standing_instructions.cjs +3 -3
- package/batteries/tools/standing_instructions.mjs +3 -3
- package/batteries/tools/statistics.cjs +3 -3
- package/batteries/tools/statistics.mjs +3 -3
- package/batteries/tools/string_processing.cjs +2 -2
- package/batteries/tools/string_processing.mjs +2 -2
- package/batteries/tools/structured_data.cjs +2 -2
- package/batteries/tools/structured_data.mjs +2 -2
- package/batteries/tools/text_analysis.cjs +3 -3
- package/batteries/tools/text_analysis.mjs +3 -3
- package/batteries/tools/text_comparison.cjs +2 -2
- package/batteries/tools/text_comparison.mjs +2 -2
- package/batteries/tools/time.cjs +3 -3
- package/batteries/tools/time.mjs +3 -3
- package/batteries/tools/unit_conversion.cjs +2 -2
- package/batteries/tools/unit_conversion.mjs +2 -2
- package/batteries/tools.cjs +2 -2
- package/batteries/tools.mjs +2 -2
- package/batteries/validation.cjs +4 -4
- package/batteries/validation.mjs +4 -4
- package/batteries/vector/conformance.cjs +59 -0
- package/batteries/vector/conformance.cjs.map +1 -1
- package/batteries/vector/conformance.mjs +59 -0
- package/batteries/vector/conformance.mjs.map +1 -1
- package/batteries/vector/lancedb.cjs +1 -1
- package/batteries/vector/lancedb.cjs.map +1 -1
- package/batteries/vector/lancedb.mjs +1 -1
- package/batteries/vector/lancedb.mjs.map +1 -1
- package/batteries/vector/retrievable.cjs +1 -1
- package/batteries/vector/retrievable.mjs +1 -1
- package/batteries/vector/sqlite_vec/index.d.ts +1 -1
- package/batteries/vector/sqlite_vec.cjs +19 -30
- package/batteries/vector/sqlite_vec.cjs.map +1 -1
- package/batteries/vector/sqlite_vec.mjs +20 -31
- package/batteries/vector/sqlite_vec.mjs.map +1 -1
- package/batteries.cjs +4 -4
- package/batteries.mjs +4 -4
- package/{chat_common-B7fvGTKv.cjs → chat_common-CNayzS1V.cjs} +2 -2
- package/{chat_common-B7fvGTKv.cjs.map → chat_common-CNayzS1V.cjs.map} +1 -1
- package/{chat_common-CeoHwSsz.mjs → chat_common-DKw8FDol.mjs} +2 -2
- package/{chat_common-CeoHwSsz.mjs.map → chat_common-DKw8FDol.mjs.map} +1 -1
- package/claude-code-cli-wrapper.cjs +104 -22
- package/claude-code-cli-wrapper.cjs.map +1 -1
- package/claude-code-cli-wrapper.mjs +104 -22
- package/claude-code-cli-wrapper.mjs.map +1 -1
- package/{common-7gCR3zQu.cjs → common-CqetsItm.cjs} +7 -7
- package/{common-7gCR3zQu.cjs.map → common-CqetsItm.cjs.map} +1 -1
- package/{common-B5maOoF_.mjs → common-oI1niK9Z.mjs} +7 -7
- package/{common-B5maOoF_.mjs.map → common-oI1niK9Z.mjs.map} +1 -1
- package/common.cjs +7 -7
- package/common.mjs +7 -7
- package/{dispatch_runner-DO7jo_gl.mjs → dispatch_runner-BZDXUe0G.mjs} +5 -5
- package/{dispatch_runner-DO7jo_gl.mjs.map → dispatch_runner-BZDXUe0G.mjs.map} +1 -1
- package/{dispatch_runner-FlriTyoq.cjs → dispatch_runner-DDUxXJC3.cjs} +5 -5
- package/{dispatch_runner-FlriTyoq.cjs.map → dispatch_runner-DDUxXJC3.cjs.map} +1 -1
- package/dispatch_runner.cjs +1 -1
- package/dispatch_runner.mjs +1 -1
- package/{ecmascript-bgwVyZG1.mjs → ecmascript-B9Z2C24U.mjs} +3 -3
- package/{ecmascript-bgwVyZG1.mjs.map → ecmascript-B9Z2C24U.mjs.map} +1 -1
- package/{ecmascript-BydSB03Y.cjs → ecmascript-BYfmjg7y.cjs} +3 -3
- package/{ecmascript-BydSB03Y.cjs.map → ecmascript-BYfmjg7y.cjs.map} +1 -1
- package/eslint/rules.cjs +1 -1
- package/eslint/rules.mjs +1 -1
- package/eslint.cjs +2 -2
- package/eslint.mjs +2 -2
- package/exceptions.cjs +1 -1
- package/exceptions.mjs +1 -1
- package/forge.cjs +2 -2
- package/forge.mjs +2 -2
- package/guards.cjs +7 -7
- package/guards.mjs +7 -7
- package/{helpers-Dcp4CrOz.cjs → helpers-DPlh_7Bn.cjs} +3 -3
- package/{helpers-Dcp4CrOz.cjs.map → helpers-DPlh_7Bn.cjs.map} +1 -1
- package/{helpers-C1T0DV8Q.mjs → helpers-mbn_EsDV.mjs} +3 -3
- package/{helpers-C1T0DV8Q.mjs.map → helpers-mbn_EsDV.mjs.map} +1 -1
- package/index.cjs +11 -11
- package/index.mjs +11 -11
- package/mcp/adk-docs-corpus.json +2 -2
- package/package.json +425 -425
- package/{retrievable-BBwiACtw.cjs → retrievable-Bq-O3k6r.cjs} +3 -3
- package/{retrievable-BBwiACtw.cjs.map → retrievable-Bq-O3k6r.cjs.map} +1 -1
- package/{retrievable-CrGKx4sc.mjs → retrievable-CXTAUuuv.mjs} +3 -3
- package/{retrievable-CrGKx4sc.mjs.map → retrievable-CXTAUuuv.mjs.map} +1 -1
- package/{scrapper-BibKj8qE.cjs → scrapper-B8xG9lTD.cjs} +4 -4
- package/{scrapper-BibKj8qE.cjs.map → scrapper-B8xG9lTD.cjs.map} +1 -1
- package/{scrapper-_JzgbLG5.mjs → scrapper-DiQ5FfDL.mjs} +4 -4
- package/{scrapper-_JzgbLG5.mjs.map → scrapper-DiQ5FfDL.mjs.map} +1 -1
- package/{searxng-D-nA2gEI.mjs → searxng-BFTJ6rTE.mjs} +4 -4
- package/{searxng-D-nA2gEI.mjs.map → searxng-BFTJ6rTE.mjs.map} +1 -1
- package/{searxng-C6xrLW-v.cjs → searxng-EJhWRnIE.cjs} +4 -4
- package/{searxng-C6xrLW-v.cjs.map → searxng-EJhWRnIE.cjs.map} +1 -1
- package/server.json +2 -2
- package/skills/adk-assembly/SKILL.md +2 -2
- package/{spooled_artifact-BLgbGT8b.cjs → spooled_artifact---DmicFW.cjs} +384 -384
- package/spooled_artifact---DmicFW.cjs.map +1 -0
- package/{spooled_artifact-BkOe4-j-.mjs → spooled_artifact-Bw_7swIp.mjs} +385 -385
- package/spooled_artifact-Bw_7swIp.mjs.map +1 -0
- package/spooled_artifact.cjs +2 -2
- package/spooled_artifact.mjs +2 -2
- package/{spooled_markdown_artifact-8zdejfcJ.cjs → spooled_markdown_artifact-Rjzj-kyh.cjs} +3 -3
- package/{spooled_markdown_artifact-8zdejfcJ.cjs.map → spooled_markdown_artifact-Rjzj-kyh.cjs.map} +1 -1
- package/{spooled_markdown_artifact-Dnl-lCGv.mjs → spooled_markdown_artifact-vd6eNtIP.mjs} +3 -3
- package/{spooled_markdown_artifact-Dnl-lCGv.mjs.map → spooled_markdown_artifact-vd6eNtIP.mjs.map} +1 -1
- package/{thought-BrQt6HAb.mjs → thought-CxSaF6Xf.mjs} +3 -3
- package/{thought-BrQt6HAb.mjs.map → thought-CxSaF6Xf.mjs.map} +1 -1
- package/{thought-COeZTQ-B.cjs → thought-Dp3sMWW6.cjs} +3 -3
- package/{thought-COeZTQ-B.cjs.map → thought-Dp3sMWW6.cjs.map} +1 -1
- package/{tokenizable-DDIdXbJN.cjs → tokenizable-BcodRtoW.cjs} +29 -29
- package/{tokenizable-DDIdXbJN.cjs.map → tokenizable-BcodRtoW.cjs.map} +1 -1
- package/{tokenizable-xPXj1AQX.mjs → tokenizable-VB4Av8GF.mjs} +30 -30
- package/{tokenizable-xPXj1AQX.mjs.map → tokenizable-VB4Av8GF.mjs.map} +1 -1
- package/{tool_call-JbjeUpRK.cjs → tool_call-B9px4W9k.cjs} +4 -4
- package/{tool_call-JbjeUpRK.cjs.map → tool_call-B9px4W9k.cjs.map} +1 -1
- package/{tool_call-8crmZsO8.mjs → tool_call-Cfaj-6zK.mjs} +4 -4
- package/{tool_call-8crmZsO8.mjs.map → tool_call-Cfaj-6zK.mjs.map} +1 -1
- package/{tools-BC4NJqZD.mjs → tools-D0MBDh2R.mjs} +6 -6
- package/{tools-BC4NJqZD.mjs.map → tools-D0MBDh2R.mjs.map} +1 -1
- package/{tools-D4mdzi0a.cjs → tools-aNbi6JyA.cjs} +6 -6
- package/{tools-D4mdzi0a.cjs.map → tools-aNbi6JyA.cjs.map} +1 -1
- package/{toon-BA9Q7NHG.mjs → toon-BSTQnHed.mjs} +5 -5
- package/{toon-BA9Q7NHG.mjs.map → toon-BSTQnHed.mjs.map} +1 -1
- package/{toon-b-0pFKZ8.cjs → toon-DmLwZ6H1.cjs} +5 -5
- package/{toon-b-0pFKZ8.cjs.map → toon-DmLwZ6H1.cjs.map} +1 -1
- package/{turn_runner-BmVXcBZ2.mjs → turn_runner-BHHD6h77.mjs} +5 -5
- package/{turn_runner-BmVXcBZ2.mjs.map → turn_runner-BHHD6h77.mjs.map} +1 -1
- package/{turn_runner-DX-3s3ih.cjs → turn_runner-Dj7JsUTQ.cjs} +5 -5
- package/{turn_runner-DX-3s3ih.cjs.map → turn_runner-Dj7JsUTQ.cjs.map} +1 -1
- package/turn_runner.cjs +1 -1
- package/turn_runner.mjs +1 -1
- package/{xml-B1JIGLpU.mjs → xml-CYseDztH.mjs} +5 -5
- package/{xml-B1JIGLpU.mjs.map → xml-CYseDztH.mjs.map} +1 -1
- package/{xml-fvwTsoRv.cjs → xml-zJul8jMQ.cjs} +5 -5
- package/{xml-fvwTsoRv.cjs.map → xml-zJul8jMQ.cjs.map} +1 -1
- package/{yaml-1mP4uxdf.mjs → yaml-BPBoiOjx.mjs} +5 -5
- package/{yaml-1mP4uxdf.mjs.map → yaml-BPBoiOjx.mjs.map} +1 -1
- package/{yaml-DPUTumla.cjs → yaml-D0PzoRAr.cjs} +5 -5
- package/{yaml-DPUTumla.cjs.map → yaml-D0PzoRAr.cjs.map} +1 -1
- package/artifact_methods-7KatxCSd.cjs +0 -1
- package/artifact_methods-q52ETLwI.mjs +0 -1
- package/spooled_artifact-BLgbGT8b.cjs.map +0 -1
- package/spooled_artifact-BkOe4-j-.mjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
require("../../chunk-Cek0wNdY.cjs");
|
|
3
|
-
const require_helpers = require("../../helpers-
|
|
4
|
-
const require_chat_common = require("../../chat_common-
|
|
3
|
+
const require_helpers = require("../../helpers-DPlh_7Bn.cjs");
|
|
4
|
+
const require_chat_common = require("../../chat_common-CNayzS1V.cjs");
|
|
5
5
|
const require_batteries_llm_claude_code_cli_exceptions = require("./claude_code_cli/exceptions.cjs");
|
|
6
6
|
const require_batteries_llm_claude_code_cli_validation = require("./claude_code_cli/validation.cjs");
|
|
7
7
|
const require_batteries_llm_claude_code_cli_helpers = require("./claude_code_cli/helpers.cjs");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as renderMemories, D as renderArtifactHandleBody, F as renderThirdPartyPrivateRetrievables, G as toolsToChatCompletionsTools, I as renderThirdPartyPublicRetrievables, L as renderThought, M as renderRetrievableSafetyDirective, N as renderRetrievables, O as renderChatCompletionsSystemPrompt, P as renderStandingInstructions, R as renderTrustedContent, _ as defaultRenderUntrustedContent, a as defaultRenderArtifactHandleBody, c as defaultRenderMemories, d as defaultRenderRetrievables, f as defaultRenderStandingInstructions, g as defaultRenderTrustedContent, h as defaultRenderThought, i as defaultFilterThoughts, j as renderRetrievableHandleBody, k as renderFirstPartyRetrievables, l as defaultRenderRetrievableHandleBody, m as defaultRenderThirdPartyPublicRetrievables, o as defaultRenderChatCompletionsSystemPrompt, p as defaultRenderThirdPartyPrivateRetrievables, r as defaultDescriptionToChatCompletionsJsonSchema, s as defaultRenderFirstPartyRetrievables, u as defaultRenderRetrievableSafetyDirective, v as defaultToolsToChatCompletionsTools, x as filterThoughts, y as descriptionToChatCompletionsJsonSchema, z as renderUntrustedContent } from "../../helpers-
|
|
2
|
-
import { t as deCollideToolCallIds } from "../../chat_common-
|
|
1
|
+
import { A as renderMemories, D as renderArtifactHandleBody, F as renderThirdPartyPrivateRetrievables, G as toolsToChatCompletionsTools, I as renderThirdPartyPublicRetrievables, L as renderThought, M as renderRetrievableSafetyDirective, N as renderRetrievables, O as renderChatCompletionsSystemPrompt, P as renderStandingInstructions, R as renderTrustedContent, _ as defaultRenderUntrustedContent, a as defaultRenderArtifactHandleBody, c as defaultRenderMemories, d as defaultRenderRetrievables, f as defaultRenderStandingInstructions, g as defaultRenderTrustedContent, h as defaultRenderThought, i as defaultFilterThoughts, j as renderRetrievableHandleBody, k as renderFirstPartyRetrievables, l as defaultRenderRetrievableHandleBody, m as defaultRenderThirdPartyPublicRetrievables, o as defaultRenderChatCompletionsSystemPrompt, p as defaultRenderThirdPartyPrivateRetrievables, r as defaultDescriptionToChatCompletionsJsonSchema, s as defaultRenderFirstPartyRetrievables, u as defaultRenderRetrievableSafetyDirective, v as defaultToolsToChatCompletionsTools, x as filterThoughts, y as descriptionToChatCompletionsJsonSchema, z as renderUntrustedContent } from "../../helpers-mbn_EsDV.mjs";
|
|
2
|
+
import { t as deCollideToolCallIds } from "../../chat_common-DKw8FDol.mjs";
|
|
3
3
|
import { E_CLAUDE_CODE_CLI_BINARY_NOT_FOUND, E_CLAUDE_CODE_CLI_CONTEXT_OVERFLOW, E_CLAUDE_CODE_CLI_MCP_BRIDGE_STARTUP_FAILED, E_CLAUDE_CODE_CLI_PROCESS_EXITED_NONZERO, E_CLAUDE_CODE_CLI_STARTUP_TIMEOUT, E_CLAUDE_CODE_CLI_STREAM_ERROR, E_CLAUDE_CODE_CLI_STREAM_STALLED, E_CLAUDE_CODE_CLI_TURN_FAILED, E_CLAUDE_CODE_CLI_UNSUPPORTED_MEDIA_MODALITY, E_CLAUDE_CODE_CLI_WRAPPER_CRASHED, E_CLAUDE_CODE_CLI_WRAPPER_NOT_FOUND, E_CLAUDE_CODE_CLI_WRAPPER_SPAWN_ERROR, E_INVALID_CLAUDE_CODE_CLI_OPTIONS } from "./claude_code_cli/exceptions.mjs";
|
|
4
4
|
import { claudeCodeCliOptionsSchema, validateOptions } from "./claude_code_cli/validation.mjs";
|
|
5
5
|
import { buildClaudeCodeCliPrompt, defaultBuildClaudeCodeCliPrompt, defaultRenderClaudeCodeCliTimelineMessage, defaultRenderClaudeCodeCliToolCallResult, renderClaudeCodeCliTimelineMessage, renderClaudeCodeCliToolCallResult } from "./claude_code_cli/helpers.mjs";
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
require("../../../chunk-Cek0wNdY.cjs");
|
|
3
3
|
const require_guards = require("../../../guards-5-XmJgD2.cjs");
|
|
4
|
-
const require_tokenizable = require("../../../tokenizable-
|
|
5
|
-
const require_spooled_artifact = require("../../../spooled_artifact
|
|
6
|
-
const require_thought = require("../../../thought-
|
|
7
|
-
const require_tool_call = require("../../../tool_call-
|
|
8
|
-
require("../../../common-
|
|
4
|
+
const require_tokenizable = require("../../../tokenizable-BcodRtoW.cjs");
|
|
5
|
+
const require_spooled_artifact = require("../../../spooled_artifact---DmicFW.cjs");
|
|
6
|
+
const require_thought = require("../../../thought-Dp3sMWW6.cjs");
|
|
7
|
+
const require_tool_call = require("../../../tool_call-B9px4W9k.cjs");
|
|
8
|
+
require("../../../common-CqetsItm.cjs");
|
|
9
9
|
require("../../../guards.cjs");
|
|
10
|
+
const require_lib_utils_retry = require("../../../lib/utils/retry.cjs");
|
|
10
11
|
const require_tool_parsers = require("../../../tool_parsers-8_qO0a_F.cjs");
|
|
11
|
-
const require_helpers = require("../../../helpers-
|
|
12
|
+
const require_helpers = require("../../../helpers-DPlh_7Bn.cjs");
|
|
12
13
|
const require_batteries_llm_gemini_generate_content_exceptions = require("./exceptions.cjs");
|
|
13
14
|
const require_batteries_llm_gemini_generate_content_validation = require("./validation.cjs");
|
|
14
15
|
const require_batteries_llm_gemini_generate_content_helpers = require("./helpers.cjs");
|
|
@@ -206,28 +207,168 @@ var GeminiGenerateContentAdapter = class GeminiGenerateContentAdapter {
|
|
|
206
207
|
const headers = { "Content-Type": "application/json" };
|
|
207
208
|
if (merged.apiKey) if (merged.useBearerAuth === true) headers.Authorization = `Bearer ${merged.apiKey}`;
|
|
208
209
|
else headers["x-goog-api-key"] = merged.apiKey;
|
|
210
|
+
const retryCfg = {
|
|
211
|
+
maxAttempts: merged.retry?.maxAttempts ?? 1,
|
|
212
|
+
baseDelayMs: merged.retry?.baseDelayMs ?? 500,
|
|
213
|
+
maxDelayMs: merged.retry?.maxDelayMs ?? 3e4,
|
|
214
|
+
retriableStatuses: merged.retry?.retriableStatuses ?? [
|
|
215
|
+
429,
|
|
216
|
+
502,
|
|
217
|
+
503,
|
|
218
|
+
504
|
|
219
|
+
],
|
|
220
|
+
honorRetryAfter: merged.retry?.honorRetryAfter ?? true
|
|
221
|
+
};
|
|
209
222
|
const doFetch = merged.fetch ?? globalThis.fetch;
|
|
223
|
+
const maxAttempts = retryCfg.maxAttempts ?? 1;
|
|
224
|
+
let res;
|
|
225
|
+
let attempt = 1;
|
|
226
|
+
let disposeLink = () => {};
|
|
227
|
+
let rawText = "";
|
|
210
228
|
let parsed;
|
|
211
229
|
try {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
signal:
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
if (
|
|
221
|
-
|
|
230
|
+
while (attempt <= maxAttempts) {
|
|
231
|
+
if (ctx.abortSignal.aborted) return;
|
|
232
|
+
const internalController = new AbortController();
|
|
233
|
+
disposeLink();
|
|
234
|
+
const { signal: linkedSignal, dispose: disposeCurrentLink } = require_lib_utils_retry.linkAbortSignals([ctx.abortSignal, internalController.signal]);
|
|
235
|
+
disposeLink = disposeCurrentLink;
|
|
236
|
+
let timeoutHandle;
|
|
237
|
+
const timeoutMs = merged.timeoutMs ?? 0;
|
|
238
|
+
if (timeoutMs > 0) timeoutHandle = setTimeout(() => internalController.abort(), timeoutMs);
|
|
239
|
+
try {
|
|
240
|
+
res = await doFetch(url, {
|
|
241
|
+
method: "POST",
|
|
242
|
+
headers,
|
|
243
|
+
body: JSON.stringify(body),
|
|
244
|
+
signal: linkedSignal
|
|
245
|
+
});
|
|
246
|
+
rawText = await res.text();
|
|
247
|
+
if (timeoutHandle !== void 0) clearTimeout(timeoutHandle);
|
|
248
|
+
} catch (err) {
|
|
249
|
+
if (timeoutHandle !== void 0) clearTimeout(timeoutHandle);
|
|
250
|
+
if (ctx.abortSignal.aborted) return;
|
|
251
|
+
if (internalController.signal.aborted) {
|
|
252
|
+
helpers.log.warn({
|
|
253
|
+
kind: "request-timeout",
|
|
254
|
+
message: `Request timed out after ${timeoutMs}ms on attempt ${attempt}/${maxAttempts}`,
|
|
255
|
+
payload: {
|
|
256
|
+
timeoutMs,
|
|
257
|
+
attempt,
|
|
258
|
+
maxAttempts
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
if (attempt < maxAttempts) {
|
|
262
|
+
const delay = require_lib_utils_retry.computeBackoff(attempt, retryCfg);
|
|
263
|
+
helpers.log.debug({
|
|
264
|
+
kind: "retry-attempt",
|
|
265
|
+
message: `Retrying after request timeout in ~${delay}ms (attempt ${attempt + 1}/${maxAttempts})`,
|
|
266
|
+
payload: {
|
|
267
|
+
reason: "request-timeout",
|
|
268
|
+
delayMs: delay,
|
|
269
|
+
attempt: attempt + 1,
|
|
270
|
+
maxAttempts
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
await require_lib_utils_retry.sleepWithJitter(delay, ctx.abortSignal);
|
|
274
|
+
attempt += 1;
|
|
275
|
+
continue;
|
|
276
|
+
}
|
|
277
|
+
ctx.nack(new require_batteries_llm_gemini_generate_content_exceptions.E_GEMINI_STREAM_ERROR([`Request timed out after ${timeoutMs}ms`]));
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
helpers.log.error({
|
|
281
|
+
kind: "transport-error",
|
|
282
|
+
message: `Transport failure on attempt ${attempt}/${maxAttempts}: ${require_guards.isError(err) ? err.message : String(err)}`,
|
|
283
|
+
payload: {
|
|
284
|
+
attempt,
|
|
285
|
+
maxAttempts,
|
|
286
|
+
detail: require_guards.isError(err) ? err.message : String(err)
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
if (attempt < maxAttempts) {
|
|
290
|
+
const delay = require_lib_utils_retry.computeBackoff(attempt, retryCfg);
|
|
291
|
+
helpers.log.debug({
|
|
292
|
+
kind: "retry-attempt",
|
|
293
|
+
message: `Retrying after transport failure in ~${delay}ms (attempt ${attempt + 1}/${maxAttempts})`,
|
|
294
|
+
payload: {
|
|
295
|
+
reason: "transport-error",
|
|
296
|
+
delayMs: delay,
|
|
297
|
+
attempt: attempt + 1,
|
|
298
|
+
maxAttempts
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
await require_lib_utils_retry.sleepWithJitter(delay, ctx.abortSignal);
|
|
302
|
+
attempt += 1;
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
ctx.nack(new require_batteries_llm_gemini_generate_content_exceptions.E_GEMINI_STREAM_ERROR([require_guards.isError(err) ? err.message : String(err)]));
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
if (!res.ok) {
|
|
309
|
+
if (/thought_signature|thoughtSignature/i.test(rawText)) {
|
|
310
|
+
ctx.nack(new require_batteries_llm_gemini_generate_content_exceptions.E_GEMINI_MISSING_THOUGHT_SIGNATURE([rawText.slice(0, 400)]));
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
const status = res.status;
|
|
314
|
+
const retriable = (retryCfg.retriableStatuses ?? [
|
|
315
|
+
429,
|
|
316
|
+
502,
|
|
317
|
+
503,
|
|
318
|
+
504
|
|
319
|
+
]).includes(status);
|
|
320
|
+
if (retriable && attempt < maxAttempts) {
|
|
321
|
+
let delay = require_lib_utils_retry.computeBackoff(attempt, retryCfg);
|
|
322
|
+
let retryAfterMs;
|
|
323
|
+
if (retryCfg.honorRetryAfter !== false) {
|
|
324
|
+
const ra = res.headers.get("Retry-After");
|
|
325
|
+
if (ra) {
|
|
326
|
+
const raMs = require_lib_utils_retry.parseRetryAfter(ra);
|
|
327
|
+
if (raMs > 0) {
|
|
328
|
+
retryAfterMs = raMs;
|
|
329
|
+
delay = Math.min(Math.max(delay, raMs), retryCfg.maxDelayMs ?? 3e4);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
helpers.log.warn({
|
|
334
|
+
kind: "retry-attempt",
|
|
335
|
+
message: `HTTP ${status} on attempt ${attempt}/${maxAttempts}; retrying in ~${delay}ms`,
|
|
336
|
+
payload: {
|
|
337
|
+
reason: "http-status",
|
|
338
|
+
status,
|
|
339
|
+
delayMs: delay,
|
|
340
|
+
...retryAfterMs !== void 0 ? { retryAfterMs } : {},
|
|
341
|
+
attempt: attempt + 1,
|
|
342
|
+
maxAttempts
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
await require_lib_utils_retry.sleepWithJitter(delay, ctx.abortSignal);
|
|
346
|
+
attempt += 1;
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
helpers.log.error({
|
|
350
|
+
kind: "http-error",
|
|
351
|
+
message: `HTTP ${status} (terminal): ${rawText.slice(0, 256)}`,
|
|
352
|
+
payload: {
|
|
353
|
+
status,
|
|
354
|
+
body: rawText,
|
|
355
|
+
attempt,
|
|
356
|
+
maxAttempts,
|
|
357
|
+
retriable
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
ctx.nack(new require_batteries_llm_gemini_generate_content_exceptions.E_GEMINI_REQUEST_FAILED([status, rawText.slice(0, 400)]));
|
|
222
361
|
return;
|
|
223
362
|
}
|
|
224
|
-
|
|
225
|
-
return;
|
|
363
|
+
break;
|
|
226
364
|
}
|
|
227
|
-
|
|
365
|
+
if (!res) return;
|
|
366
|
+
parsed = JSON.parse(rawText);
|
|
228
367
|
} catch (err) {
|
|
229
368
|
ctx.nack(new require_batteries_llm_gemini_generate_content_exceptions.E_GEMINI_STREAM_ERROR([require_guards.isError(err) ? err.message : String(err)]));
|
|
230
369
|
return;
|
|
370
|
+
} finally {
|
|
371
|
+
disposeLink();
|
|
231
372
|
}
|
|
232
373
|
const { text, reasoning, functionCalls, finishReason } = require_batteries_llm_gemini_generate_content_helpers.extractGeminiGeneration(parsed);
|
|
233
374
|
const responseId = (0, uuid.v6)();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.cjs","names":["#baseline"],"sources":["../../../../src/batteries/llm/gemini_generate_content/adapter.ts"],"sourcesContent":["/**\n * Cross-environment executor adapter for Google's native Gemini `generateContent` endpoint.\n *\n * @module @nhtio/adk/batteries/llm/gemini_generate_content/adapter\n *\n * @remarks\n * Targets `POST {baseURL}/models/{model}:generateContent` (and `:streamGenerateContent` when\n * `stream` is set) — Gemini's OWN wire format, not an OpenAI-compatible façade in front of it.\n *\n * That distinction is the reason this battery exists. Pointing `openai_chat_completions` at a\n * Gemini-compatible gateway means some translator, not the ADK, decides how your primitives become\n * `contents[]` — including whether a `thoughtSignature` is stamped, whether consecutive same-role\n * turns get merged, and how a tool result is correlated to its call. For ordinary use that is fine.\n * For anything that needs to reason about what the VENDOR actually received — an ordering guard, a\n * wire-shape audit, a bug report against Google — the translation has to be ours and observable.\n * See the validation battery's \"Which API surface a rule applies to\" guide.\n *\n * Options layer exactly as the other batteries: constructor baseline → `executor()` overrides →\n * per-iteration `ctx.stash.geminiGenerateContent`, re-validated each iteration.\n */\n\nimport { DateTime } from 'luxon'\nimport { sha256 } from 'js-sha256'\nimport { v6 as uuidv6 } from 'uuid'\nimport { validateOptions } from './validation'\nimport { normalizeToolName } from '../chat_common/helpers'\nimport { isError, isObject, isInstanceOf } from '@nhtio/adk/guards'\nimport { resolveToolCallParser } from '../chat_common/tool_parsers'\nimport { canonicalStringify } from '../../../lib/utils/canonical_json'\nimport { ArtifactTool, Media, Message, Thought, Tokenizable, ToolCall } from '@nhtio/adk/common'\nimport {\n DEFAULT_GEMINI_BUCKET_ORDER,\n buildGeminiRequest,\n extractGeminiGeneration,\n mediaToGeminiInlineData,\n renderGeminiToolResult,\n toolsToGeminiTools,\n} from './helpers'\nimport {\n E_GEMINI_GENERATE_CONTENT_CONTEXT_OVERFLOW,\n E_INVALID_GEMINI_GENERATE_CONTENT_OPTIONS,\n E_GEMINI_INVALID_TOOL_CALL_ARGS,\n E_GEMINI_MISSING_THOUGHT_SIGNATURE,\n E_GEMINI_REQUEST_FAILED,\n E_GEMINI_STREAM_ERROR,\n} from './exceptions'\nimport {\n descriptionToChatCompletionsJsonSchema,\n filterThoughts,\n renderChatCompletionsSystemPrompt,\n renderFirstPartyRetrievables,\n renderMemories,\n renderRetrievableSafetyDirective,\n renderRetrievables,\n renderStandingInstructions,\n renderThirdPartyPrivateRetrievables,\n renderThirdPartyPublicRetrievables,\n renderThought,\n renderTrustedContent,\n renderUntrustedContent,\n} from '../chat_common/helpers'\nimport type { DispatchContext } from '@nhtio/adk/types'\nimport type { Memory, SpooledArtifact, Tool } from '@nhtio/adk/common'\nimport type { TokenEncoding, TokenEncodingId } from '@nhtio/adk/types'\nimport type { DispatchExecutorFn, DispatchExecutorHelpers } from '@nhtio/adk/types'\nimport type {\n GeminiGenerateContentAdapterOptions,\n GeminiGenerateContentHelpers,\n GeminiGenerateContentResponse,\n} from './types'\n\nconst nowIso = (): string => DateTime.now().toISO() ?? new Date().toISOString()\n\nconst DEFAULT_BASE_URL = 'https://generativelanguage.googleapis.com/v1beta'\n/**\n * Google's documented portable sentinel for replaying tool history that did not originate from a\n * Gemini reasoning session. See the option's TSDoc for why this is the default.\n */\nconst DEFAULT_SENTINEL = 'skip_thought_signature_validator'\n\nconst estimateTokensOf = async (\n value: { estimateTokens: (encoding: TokenEncoding) => number | Promise<number> },\n encoding: TokenEncodingId\n): Promise<number> => Promise.resolve(value.estimateTokens(encoding as TokenEncoding))\n\nconst computeChecksum = (tool: string, args: Record<string, unknown>): string =>\n sha256(`${tool}:${canonicalStringify(args)}`)\n\n/** Merge the three option layers, later winning. */\nconst mergeOptions = (\n ...layers: Array<Partial<GeminiGenerateContentAdapterOptions> | undefined>\n): Partial<GeminiGenerateContentAdapterOptions> => {\n const out: Record<string, unknown> = {}\n for (const layer of layers) {\n if (!layer) continue\n for (const [k, v] of Object.entries(layer)) if (v !== undefined) out[k] = v\n }\n return out as Partial<GeminiGenerateContentAdapterOptions>\n}\n\n/** Fill every injectable helper, preferring the caller's override. */\nconst resolveHelpers = (\n overrides: Partial<GeminiGenerateContentHelpers> | undefined\n): GeminiGenerateContentHelpers => {\n const src = (overrides ?? {}) as Record<string, unknown>\n const pick = <T>(key: string, fallback: T): T => (src[key] as T | undefined) ?? fallback\n return {\n descriptionToChatCompletionsJsonSchema: pick(\n 'descriptionToChatCompletionsJsonSchema',\n descriptionToChatCompletionsJsonSchema\n ),\n renderUntrustedContent: pick('renderUntrustedContent', renderUntrustedContent),\n renderTrustedContent: pick('renderTrustedContent', renderTrustedContent),\n renderStandingInstructions: pick('renderStandingInstructions', renderStandingInstructions),\n renderMemories: pick('renderMemories', renderMemories),\n renderRetrievables: pick('renderRetrievables', renderRetrievables),\n renderRetrievableSafetyDirective: pick(\n 'renderRetrievableSafetyDirective',\n renderRetrievableSafetyDirective\n ),\n renderFirstPartyRetrievables: pick(\n 'renderFirstPartyRetrievables',\n renderFirstPartyRetrievables\n ),\n renderThirdPartyPublicRetrievables: pick(\n 'renderThirdPartyPublicRetrievables',\n renderThirdPartyPublicRetrievables\n ),\n renderThirdPartyPrivateRetrievables: pick(\n 'renderThirdPartyPrivateRetrievables',\n renderThirdPartyPrivateRetrievables\n ),\n renderThought: pick('renderThought', renderThought),\n filterThoughts: pick('filterThoughts', filterThoughts),\n renderChatCompletionsSystemPrompt: pick(\n 'renderChatCompletionsSystemPrompt',\n renderChatCompletionsSystemPrompt\n ),\n toolsToGeminiTools: pick('toolsToGeminiTools', toolsToGeminiTools),\n renderGeminiToolResult: pick('renderGeminiToolResult', renderGeminiToolResult),\n buildGeminiRequest: pick('buildGeminiRequest', buildGeminiRequest),\n } as GeminiGenerateContentHelpers\n}\n\n/**\n * Native Gemini `generateContent` executor adapter.\n *\n * @example\n * ```ts\n * const adapter = new GeminiGenerateContentAdapter({\n * model: 'gemini-2.5-flash-lite',\n * apiKey: process.env.GEMINI_API_KEY,\n * })\n * const runner = new TurnRunner({ executorCallback: adapter.executor(), ... })\n * ```\n */\nexport class GeminiGenerateContentAdapter {\n /** Per-iteration override key on `ctx.stash`. */\n public static readonly STASH_KEY = 'geminiGenerateContent' as const\n\n readonly #baseline: GeminiGenerateContentAdapterOptions\n\n /**\n * @param options - Constructor-baseline options, re-validated每 iteration after overrides merge.\n * @throws {@link E_INVALID_GEMINI_GENERATE_CONTENT_OPTIONS} when `options` is invalid.\n */\n constructor(options: unknown) {\n this.#baseline = validateOptions(options)\n }\n\n /** Narrowing guard for cross-realm instances. */\n public static isGeminiGenerateContentAdapter(\n value: unknown\n ): value is GeminiGenerateContentAdapter {\n return isInstanceOf(value, 'GeminiGenerateContentAdapter', GeminiGenerateContentAdapter)\n }\n\n /**\n * Build a {@link DispatchExecutorFn} bound to the baseline plus optional executor-scope overrides.\n *\n * @param overrides - Higher precedence than the baseline, lower than `ctx.stash`.\n */\n executor(overrides?: Partial<GeminiGenerateContentAdapterOptions>): DispatchExecutorFn {\n const baseline = this.#baseline\n const adapterClass = GeminiGenerateContentAdapter\n return async (ctx: DispatchContext, helpers: DispatchExecutorHelpers): Promise<void> => {\n const warn = (message: string): void => {\n helpers.log.warn({ kind: 'helper-warning', message })\n }\n\n // ── merge & validate ────────────────────────────────────────────────\n const stashRaw = ctx.stash.get(adapterClass.STASH_KEY, {}) as unknown\n const stashOverrides = isObject(stashRaw)\n ? (stashRaw as Partial<GeminiGenerateContentAdapterOptions>)\n : {}\n const merged = validateOptions(mergeOptions(baseline, overrides, stashOverrides))\n if (\n merged.tokenEncoding !== undefined &&\n merged.tokenEncoding !== null &&\n merged.contextWindow === undefined\n ) {\n throw new E_INVALID_GEMINI_GENERATE_CONTENT_OPTIONS([\n 'tokenEncoding is non-null but contextWindow is undefined',\n ])\n }\n const resolved = resolveHelpers(merged.helpers)\n const selfIdentity = 'assistant'\n const dispatchStreamId = uuidv6()\n\n // ── pre-render tool results ─────────────────────────────────────────\n // Gemini wants an OBJECT in functionResponse.response, so results are rendered ahead of\n // assembly and keyed by the live ToolCall instance. Keying by id lets a duplicate id\n // overwrite an earlier result before assembly.\n const renderedToolCallResults = new Map<ToolCall, Record<string, unknown>>()\n for (const tc of ctx.turnToolCalls) {\n renderedToolCallResults.set(\n tc,\n await resolved.renderGeminiToolResult({\n toolCall: tc,\n results: tc.results as never,\n tool: ctx.tools.get(tc.tool) as Tool | ArtifactTool | undefined,\n renderUntrustedContent: resolved.renderUntrustedContent,\n renderTrustedContent: resolved.renderTrustedContent,\n unsupportedMediaPolicy: merged.unsupportedMediaPolicy ?? 'throw',\n warn,\n })\n )\n }\n\n // ── context window enforcement ───────────────────────────────────────\n if (\n merged.tokenEncoding !== undefined &&\n merged.tokenEncoding !== null &&\n merged.contextWindow !== undefined\n ) {\n const encoding = merged.tokenEncoding\n let total = await estimateTokensOf(ctx.systemPrompt, encoding)\n for (const value of ctx.standingInstructions)\n total += await estimateTokensOf(value, encoding)\n for (const memory of ctx.turnMemories as Set<Memory>) {\n total += await estimateTokensOf(memory.content, encoding)\n }\n for (const retrievable of ctx.turnRetrievables) {\n total += await estimateTokensOf(\n retrievable.inline\n ? (retrievable.content as any)\n : new Tokenizable(`[Reference available: ${retrievable.id}]`),\n encoding\n )\n }\n for (const message of ctx.turnMessages) {\n if (message.content !== undefined)\n total += await estimateTokensOf(message.content, encoding)\n }\n for (const thought of ctx.turnThoughts)\n total += await estimateTokensOf(thought.content, encoding)\n for (const result of renderedToolCallResults.values()) {\n total += await estimateTokensOf(new Tokenizable(JSON.stringify(result)), encoding)\n }\n const tools = ctx.tools.visible()\n // Tool DECLARATIONS: the Gemini wire ships tools as an array, which the PROVIDER\n // serializes server-side into the model's own format. Tally the tokens of the wire\n // tools JSON (`JSON.stringify`) as an honest FLOOR — a truthful lower bound. We add\n // a highly conservative 50% margin to cover JSON structural overhead and nested formatting.\n if (tools.length > 0) {\n const toolTokens = await estimateTokensOf(\n new Tokenizable(JSON.stringify(resolved.toolsToGeminiTools(tools))),\n encoding\n )\n total += Math.ceil(toolTokens * 1.5)\n }\n if (total + (merged.maxOutputTokens ?? 0) > merged.contextWindow) {\n throw new E_GEMINI_GENERATE_CONTENT_CONTEXT_OVERFLOW([\n total + (merged.maxOutputTokens ?? 0),\n merged.contextWindow,\n encoding,\n ])\n }\n }\n\n // ── assemble ────────────────────────────────────────────────────────\n const request = await resolved.buildGeminiRequest({\n systemPrompt: ctx.systemPrompt,\n standingInstructions: ctx.standingInstructions,\n memories: ctx.turnMemories,\n retrievables: ctx.turnRetrievables,\n messages: ctx.turnMessages,\n thoughts: ctx.turnThoughts,\n toolCalls: ctx.turnToolCalls,\n tools: ctx.tools,\n renderedToolCallResults,\n bucketOrder: merged.bucketOrder ?? (DEFAULT_GEMINI_BUCKET_ORDER as never),\n selfIdentity,\n thoughtSurfacing: merged.thoughtSurfacing ?? 'all-self',\n replayCompatibility: [],\n thoughtSignatureSentinel:\n merged.thoughtSignatureSentinel === undefined\n ? DEFAULT_SENTINEL\n : merged.thoughtSignatureSentinel,\n helpers: resolved,\n decodeMedia: mediaToGeminiInlineData,\n unsupportedMediaPolicy: merged.unsupportedMediaPolicy,\n warn,\n })\n\n const generationConfig = {\n ...(merged.maxOutputTokens !== undefined\n ? { maxOutputTokens: merged.maxOutputTokens }\n : {}),\n ...(merged.temperature !== undefined ? { temperature: merged.temperature } : {}),\n ...(merged.topP !== undefined ? { topP: merged.topP } : {}),\n ...(merged.topK !== undefined ? { topK: merged.topK } : {}),\n ...(merged.stopSequences ? { stopSequences: merged.stopSequences } : {}),\n ...(merged.thinkingConfig ? { thinkingConfig: merged.thinkingConfig } : {}),\n }\n const body = {\n ...request,\n ...(Object.keys(generationConfig).length > 0 ? { generationConfig } : {}),\n ...(merged.toolConfig ? { toolConfig: merged.toolConfig } : {}),\n ...(merged.safetySettings ? { safetySettings: merged.safetySettings } : {}),\n }\n\n // Prompt-assembled tap: the EXACT body about to be POSTed. An ADK-control key — stripped\n // from the wire request, never sent. Observer errors are swallowed so a tap can never\n // corrupt a generation.\n if (merged.onPromptAssembled) {\n try {\n merged.onPromptAssembled({\n battery: 'gemini_generate_content',\n kind: 'request-body',\n messages: body.contents,\n tools: body.tools,\n requestBody: body,\n streamed: merged.stream === true,\n streamId: dispatchStreamId,\n })\n } catch {\n /* observer errors are non-fatal */\n }\n }\n\n // ── dispatch ────────────────────────────────────────────────────────\n const base = (merged.baseURL ?? DEFAULT_BASE_URL).replace(/\\/$/, '')\n const action = merged.stream === true ? 'streamGenerateContent' : 'generateContent'\n const url = `${base}/models/${merged.model}:${action}`\n const headers: Record<string, string> = { 'Content-Type': 'application/json' }\n if (merged.apiKey) {\n // Google's own endpoint wants x-goog-api-key; several gateways in front of it accept only\n // Authorization, hence the switch rather than sending both.\n if (merged.useBearerAuth === true) headers.Authorization = `Bearer ${merged.apiKey}`\n else headers['x-goog-api-key'] = merged.apiKey\n }\n\n const doFetch = merged.fetch ?? globalThis.fetch\n let parsed: GeminiGenerateContentResponse\n try {\n const res = await doFetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: merged.timeoutMs ? AbortSignal.timeout(merged.timeoutMs) : ctx.abortSignal,\n })\n const text = await res.text()\n if (!res.ok) {\n // Classify the vendor's own signature rejection separately — it is actionable, and\n // Gemini's generic INVALID_ARGUMENT body gives a caller nothing to act on.\n if (/thought_signature|thoughtSignature/i.test(text)) {\n ctx.nack(new E_GEMINI_MISSING_THOUGHT_SIGNATURE([text.slice(0, 400)]))\n return\n }\n ctx.nack(new E_GEMINI_REQUEST_FAILED([res.status, text.slice(0, 400)]))\n return\n }\n parsed = JSON.parse(text) as GeminiGenerateContentResponse\n } catch (err) {\n ctx.nack(new E_GEMINI_STREAM_ERROR([isError(err) ? err.message : String(err)]))\n return\n }\n\n // ── interpret ───────────────────────────────────────────────────────\n const { text, reasoning, functionCalls, finishReason } = extractGeminiGeneration(parsed)\n const responseId = uuidv6()\n\n if (text.length > 0) {\n const messageId = `${responseId}:message`\n helpers.reportMessage(messageId, text, { isComplete: true })\n await ctx.storeMessage(\n new Message({\n id: messageId,\n role: 'assistant',\n content: text,\n identity: selfIdentity,\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n }\n if (reasoning.length > 0) {\n const thoughtId = `${responseId}:thought`\n helpers.reportThought(thoughtId, reasoning, { isComplete: true })\n await ctx.storeThought(\n new Thought({\n id: thoughtId,\n content: reasoning,\n identity: selfIdentity,\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n }\n\n // Fallback recovery: only consulted when the provider returned NO structured calls, so a\n // native functionCall always wins over a parsed one.\n let calls = functionCalls.map((c) => ({ id: uuidv6(), name: c.name, args: c.args }))\n if (calls.length === 0 && merged.localToolCallParser !== undefined && text.length > 0) {\n const parser = resolveToolCallParser(merged.localToolCallParser)\n // The parser returns { calls, cleanedText } — not an iterable of calls — and the\n // second argument carries the tool names actually offered this turn so a parser can\n // reject a hallucinated name rather than manufacture a call for it.\n const recovered = parser(text, { toolNames: ctx.tools.all().map((t) => t.name) })\n for (const call of recovered.calls) {\n calls.push({\n id: uuidv6(),\n name: call.name,\n args: (call.arguments ?? {}) as Record<string, unknown>,\n })\n }\n }\n\n if (merged.onRawGeneration) {\n try {\n merged.onRawGeneration({\n rawText: text,\n cleanedText: text,\n reasoning: reasoning.length > 0 ? [reasoning] : [],\n toolCalls: calls.map((c) => ({ name: c.name, arguments: c.args as never })),\n streamed: merged.stream === true,\n streamId: dispatchStreamId,\n })\n } catch {\n /* observer errors are non-fatal */\n }\n }\n\n if (calls.length === 0) {\n // `finishReason` is recorded for the caller; an empty generation is NOT an error here —\n // it is a real vendor outcome and the runner decides what to do with it.\n helpers.log.trace({\n kind: 'gemini-finish',\n message: `generation ended with finishReason=${finishReason ?? 'unknown'} and no function calls`,\n payload: { finishReason: finishReason ?? 'unknown' },\n })\n if (merged.autoAck) ctx.ack()\n return\n }\n\n for (const call of calls) {\n if (ctx.abortSignal.aborted) return\n const toolName = normalizeToolName(call.name)\n const tool = ctx.tools.get(toolName) as Tool | ArtifactTool | undefined\n const completedAt = nowIso()\n\n if (!isObject(call.args)) {\n const results = new Tokenizable(\n new E_GEMINI_INVALID_TOOL_CALL_ARGS([JSON.stringify(call.args)]).message\n )\n helpers.reportToolCall(call.id, { tool: toolName, args: {} })\n helpers.reportToolCall(call.id, { results, isError: true, isComplete: true })\n await ctx.storeToolCall(\n new ToolCall({\n id: call.id,\n tool: toolName,\n args: {},\n checksum: computeChecksum(toolName, {}),\n isComplete: true,\n isError: true,\n results,\n createdAt: completedAt,\n updatedAt: completedAt,\n completedAt,\n })\n )\n continue\n }\n\n if (!tool) {\n const available = ctx.tools\n .all()\n .map((t) => t.name)\n .sort()\n const results = new Tokenizable(\n available.length > 0\n ? `Tool not found: ${toolName}. Available tools: ${available.join(', ')}.`\n : `Tool not found: ${toolName}. No tools are available this turn.`\n )\n helpers.reportToolCall(call.id, { tool: toolName, args: call.args })\n helpers.reportToolCall(call.id, { results, isError: true, isComplete: true })\n await ctx.storeToolCall(\n new ToolCall({\n id: call.id,\n tool: toolName,\n args: call.args,\n checksum: computeChecksum(toolName, call.args),\n isComplete: true,\n isError: true,\n results,\n createdAt: completedAt,\n updatedAt: completedAt,\n completedAt,\n })\n )\n continue\n }\n\n helpers.reportToolCall(call.id, { tool: tool.name, args: call.args })\n let results: Tokenizable | SpooledArtifact | SpooledArtifact[] | Media | Media[] =\n new Tokenizable('')\n let isToolError = false\n try {\n const raw = await tool.executor(ctx)(call.args)\n results = Tokenizable.isTokenizable(raw)\n ? raw\n : new Tokenizable(typeof raw === 'string' ? raw : JSON.stringify(raw ?? ''))\n } catch (err) {\n isToolError = true\n results = new Tokenizable(isError(err) ? err.message : String(err))\n }\n const finishedAt = nowIso()\n helpers.reportToolCall(call.id, { results, isError: isToolError, isComplete: true })\n await ctx.storeToolCall(\n new ToolCall({\n id: call.id,\n tool: tool.name,\n args: call.args,\n checksum: computeChecksum(tool.name, call.args),\n isComplete: true,\n isError: isToolError,\n results,\n createdAt: finishedAt,\n updatedAt: finishedAt,\n completedAt: finishedAt,\n })\n )\n }\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"adapter.cjs","names":["#baseline"],"sources":["../../../../src/batteries/llm/gemini_generate_content/adapter.ts"],"sourcesContent":["/**\n * Cross-environment executor adapter for Google's native Gemini `generateContent` endpoint.\n *\n * @module @nhtio/adk/batteries/llm/gemini_generate_content/adapter\n *\n * @remarks\n * Targets `POST {baseURL}/models/{model}:generateContent` (and `:streamGenerateContent` when\n * `stream` is set) — Gemini's OWN wire format, not an OpenAI-compatible façade in front of it.\n *\n * That distinction is the reason this battery exists. Pointing `openai_chat_completions` at a\n * Gemini-compatible gateway means some translator, not the ADK, decides how your primitives become\n * `contents[]` — including whether a `thoughtSignature` is stamped, whether consecutive same-role\n * turns get merged, and how a tool result is correlated to its call. For ordinary use that is fine.\n * For anything that needs to reason about what the VENDOR actually received — an ordering guard, a\n * wire-shape audit, a bug report against Google — the translation has to be ours and observable.\n * See the validation battery's \"Which API surface a rule applies to\" guide.\n *\n * Options layer exactly as the other batteries: constructor baseline → `executor()` overrides →\n * per-iteration `ctx.stash.geminiGenerateContent`, re-validated each iteration.\n */\n\nimport { DateTime } from 'luxon'\nimport { sha256 } from 'js-sha256'\nimport { v6 as uuidv6 } from 'uuid'\nimport { validateOptions } from './validation'\nimport { normalizeToolName } from '../chat_common/helpers'\nimport { isError, isObject, isInstanceOf } from '@nhtio/adk/guards'\nimport { resolveToolCallParser } from '../chat_common/tool_parsers'\nimport { canonicalStringify } from '../../../lib/utils/canonical_json'\nimport { ArtifactTool, Media, Message, Thought, Tokenizable, ToolCall } from '@nhtio/adk/common'\nimport {\n computeBackoff,\n sleepWithJitter,\n parseRetryAfter,\n linkAbortSignals,\n} from '../../../lib/utils/retry'\nimport {\n DEFAULT_GEMINI_BUCKET_ORDER,\n buildGeminiRequest,\n extractGeminiGeneration,\n mediaToGeminiInlineData,\n renderGeminiToolResult,\n toolsToGeminiTools,\n} from './helpers'\nimport {\n E_GEMINI_GENERATE_CONTENT_CONTEXT_OVERFLOW,\n E_INVALID_GEMINI_GENERATE_CONTENT_OPTIONS,\n E_GEMINI_INVALID_TOOL_CALL_ARGS,\n E_GEMINI_MISSING_THOUGHT_SIGNATURE,\n E_GEMINI_REQUEST_FAILED,\n E_GEMINI_STREAM_ERROR,\n} from './exceptions'\nimport {\n descriptionToChatCompletionsJsonSchema,\n filterThoughts,\n renderChatCompletionsSystemPrompt,\n renderFirstPartyRetrievables,\n renderMemories,\n renderRetrievableSafetyDirective,\n renderRetrievables,\n renderStandingInstructions,\n renderThirdPartyPrivateRetrievables,\n renderThirdPartyPublicRetrievables,\n renderThought,\n renderTrustedContent,\n renderUntrustedContent,\n} from '../chat_common/helpers'\nimport type { DispatchContext } from '@nhtio/adk/types'\nimport type { Memory, SpooledArtifact, Tool } from '@nhtio/adk/common'\nimport type { TokenEncoding, TokenEncodingId } from '@nhtio/adk/types'\nimport type { DispatchExecutorFn, DispatchExecutorHelpers } from '@nhtio/adk/types'\nimport type {\n ChatCompletionsRetryConfig,\n GeminiGenerateContentAdapterOptions,\n GeminiGenerateContentHelpers,\n GeminiGenerateContentResponse,\n} from './types'\n\nconst nowIso = (): string => DateTime.now().toISO() ?? new Date().toISOString()\n\nconst DEFAULT_BASE_URL = 'https://generativelanguage.googleapis.com/v1beta'\n/**\n * Google's documented portable sentinel for replaying tool history that did not originate from a\n * Gemini reasoning session. See the option's TSDoc for why this is the default.\n */\nconst DEFAULT_SENTINEL = 'skip_thought_signature_validator'\n\nconst estimateTokensOf = async (\n value: { estimateTokens: (encoding: TokenEncoding) => number | Promise<number> },\n encoding: TokenEncodingId\n): Promise<number> => Promise.resolve(value.estimateTokens(encoding as TokenEncoding))\n\nconst computeChecksum = (tool: string, args: Record<string, unknown>): string =>\n sha256(`${tool}:${canonicalStringify(args)}`)\n\n/** Merge the three option layers, later winning. */\nconst mergeOptions = (\n ...layers: Array<Partial<GeminiGenerateContentAdapterOptions> | undefined>\n): Partial<GeminiGenerateContentAdapterOptions> => {\n const out: Record<string, unknown> = {}\n for (const layer of layers) {\n if (!layer) continue\n for (const [k, v] of Object.entries(layer)) if (v !== undefined) out[k] = v\n }\n return out as Partial<GeminiGenerateContentAdapterOptions>\n}\n\n/** Fill every injectable helper, preferring the caller's override. */\nconst resolveHelpers = (\n overrides: Partial<GeminiGenerateContentHelpers> | undefined\n): GeminiGenerateContentHelpers => {\n const src = (overrides ?? {}) as Record<string, unknown>\n const pick = <T>(key: string, fallback: T): T => (src[key] as T | undefined) ?? fallback\n return {\n descriptionToChatCompletionsJsonSchema: pick(\n 'descriptionToChatCompletionsJsonSchema',\n descriptionToChatCompletionsJsonSchema\n ),\n renderUntrustedContent: pick('renderUntrustedContent', renderUntrustedContent),\n renderTrustedContent: pick('renderTrustedContent', renderTrustedContent),\n renderStandingInstructions: pick('renderStandingInstructions', renderStandingInstructions),\n renderMemories: pick('renderMemories', renderMemories),\n renderRetrievables: pick('renderRetrievables', renderRetrievables),\n renderRetrievableSafetyDirective: pick(\n 'renderRetrievableSafetyDirective',\n renderRetrievableSafetyDirective\n ),\n renderFirstPartyRetrievables: pick(\n 'renderFirstPartyRetrievables',\n renderFirstPartyRetrievables\n ),\n renderThirdPartyPublicRetrievables: pick(\n 'renderThirdPartyPublicRetrievables',\n renderThirdPartyPublicRetrievables\n ),\n renderThirdPartyPrivateRetrievables: pick(\n 'renderThirdPartyPrivateRetrievables',\n renderThirdPartyPrivateRetrievables\n ),\n renderThought: pick('renderThought', renderThought),\n filterThoughts: pick('filterThoughts', filterThoughts),\n renderChatCompletionsSystemPrompt: pick(\n 'renderChatCompletionsSystemPrompt',\n renderChatCompletionsSystemPrompt\n ),\n toolsToGeminiTools: pick('toolsToGeminiTools', toolsToGeminiTools),\n renderGeminiToolResult: pick('renderGeminiToolResult', renderGeminiToolResult),\n buildGeminiRequest: pick('buildGeminiRequest', buildGeminiRequest),\n } as GeminiGenerateContentHelpers\n}\n\n/**\n * Native Gemini `generateContent` executor adapter.\n *\n * @example\n * ```ts\n * const adapter = new GeminiGenerateContentAdapter({\n * model: 'gemini-2.5-flash-lite',\n * apiKey: process.env.GEMINI_API_KEY,\n * })\n * const runner = new TurnRunner({ executorCallback: adapter.executor(), ... })\n * ```\n */\nexport class GeminiGenerateContentAdapter {\n /** Per-iteration override key on `ctx.stash`. */\n public static readonly STASH_KEY = 'geminiGenerateContent' as const\n\n readonly #baseline: GeminiGenerateContentAdapterOptions\n\n /**\n * @param options - Constructor-baseline options, re-validated每 iteration after overrides merge.\n * @throws {@link E_INVALID_GEMINI_GENERATE_CONTENT_OPTIONS} when `options` is invalid.\n */\n constructor(options: unknown) {\n this.#baseline = validateOptions(options)\n }\n\n /** Narrowing guard for cross-realm instances. */\n public static isGeminiGenerateContentAdapter(\n value: unknown\n ): value is GeminiGenerateContentAdapter {\n return isInstanceOf(value, 'GeminiGenerateContentAdapter', GeminiGenerateContentAdapter)\n }\n\n /**\n * Build a {@link DispatchExecutorFn} bound to the baseline plus optional executor-scope overrides.\n *\n * @param overrides - Higher precedence than the baseline, lower than `ctx.stash`.\n */\n executor(overrides?: Partial<GeminiGenerateContentAdapterOptions>): DispatchExecutorFn {\n const baseline = this.#baseline\n const adapterClass = GeminiGenerateContentAdapter\n return async (ctx: DispatchContext, helpers: DispatchExecutorHelpers): Promise<void> => {\n const warn = (message: string): void => {\n helpers.log.warn({ kind: 'helper-warning', message })\n }\n\n // ── merge & validate ────────────────────────────────────────────────\n const stashRaw = ctx.stash.get(adapterClass.STASH_KEY, {}) as unknown\n const stashOverrides = isObject(stashRaw)\n ? (stashRaw as Partial<GeminiGenerateContentAdapterOptions>)\n : {}\n const merged = validateOptions(mergeOptions(baseline, overrides, stashOverrides))\n if (\n merged.tokenEncoding !== undefined &&\n merged.tokenEncoding !== null &&\n merged.contextWindow === undefined\n ) {\n throw new E_INVALID_GEMINI_GENERATE_CONTENT_OPTIONS([\n 'tokenEncoding is non-null but contextWindow is undefined',\n ])\n }\n const resolved = resolveHelpers(merged.helpers)\n const selfIdentity = 'assistant'\n const dispatchStreamId = uuidv6()\n\n // ── pre-render tool results ─────────────────────────────────────────\n // Gemini wants an OBJECT in functionResponse.response, so results are rendered ahead of\n // assembly and keyed by the live ToolCall instance. Keying by id lets a duplicate id\n // overwrite an earlier result before assembly.\n const renderedToolCallResults = new Map<ToolCall, Record<string, unknown>>()\n for (const tc of ctx.turnToolCalls) {\n renderedToolCallResults.set(\n tc,\n await resolved.renderGeminiToolResult({\n toolCall: tc,\n results: tc.results as never,\n tool: ctx.tools.get(tc.tool) as Tool | ArtifactTool | undefined,\n renderUntrustedContent: resolved.renderUntrustedContent,\n renderTrustedContent: resolved.renderTrustedContent,\n unsupportedMediaPolicy: merged.unsupportedMediaPolicy ?? 'throw',\n warn,\n })\n )\n }\n\n // ── context window enforcement ───────────────────────────────────────\n if (\n merged.tokenEncoding !== undefined &&\n merged.tokenEncoding !== null &&\n merged.contextWindow !== undefined\n ) {\n const encoding = merged.tokenEncoding\n let total = await estimateTokensOf(ctx.systemPrompt, encoding)\n for (const value of ctx.standingInstructions)\n total += await estimateTokensOf(value, encoding)\n for (const memory of ctx.turnMemories as Set<Memory>) {\n total += await estimateTokensOf(memory.content, encoding)\n }\n for (const retrievable of ctx.turnRetrievables) {\n total += await estimateTokensOf(\n retrievable.inline\n ? (retrievable.content as any)\n : new Tokenizable(`[Reference available: ${retrievable.id}]`),\n encoding\n )\n }\n for (const message of ctx.turnMessages) {\n if (message.content !== undefined)\n total += await estimateTokensOf(message.content, encoding)\n }\n for (const thought of ctx.turnThoughts)\n total += await estimateTokensOf(thought.content, encoding)\n for (const result of renderedToolCallResults.values()) {\n total += await estimateTokensOf(new Tokenizable(JSON.stringify(result)), encoding)\n }\n const tools = ctx.tools.visible()\n // Tool DECLARATIONS: the Gemini wire ships tools as an array, which the PROVIDER\n // serializes server-side into the model's own format. Tally the tokens of the wire\n // tools JSON (`JSON.stringify`) as an honest FLOOR — a truthful lower bound. We add\n // a highly conservative 50% margin to cover JSON structural overhead and nested formatting.\n if (tools.length > 0) {\n const toolTokens = await estimateTokensOf(\n new Tokenizable(JSON.stringify(resolved.toolsToGeminiTools(tools))),\n encoding\n )\n total += Math.ceil(toolTokens * 1.5)\n }\n if (total + (merged.maxOutputTokens ?? 0) > merged.contextWindow) {\n throw new E_GEMINI_GENERATE_CONTENT_CONTEXT_OVERFLOW([\n total + (merged.maxOutputTokens ?? 0),\n merged.contextWindow,\n encoding,\n ])\n }\n }\n\n // ── assemble ────────────────────────────────────────────────────────\n const request = await resolved.buildGeminiRequest({\n systemPrompt: ctx.systemPrompt,\n standingInstructions: ctx.standingInstructions,\n memories: ctx.turnMemories,\n retrievables: ctx.turnRetrievables,\n messages: ctx.turnMessages,\n thoughts: ctx.turnThoughts,\n toolCalls: ctx.turnToolCalls,\n tools: ctx.tools,\n renderedToolCallResults,\n bucketOrder: merged.bucketOrder ?? (DEFAULT_GEMINI_BUCKET_ORDER as never),\n selfIdentity,\n thoughtSurfacing: merged.thoughtSurfacing ?? 'all-self',\n replayCompatibility: [],\n thoughtSignatureSentinel:\n merged.thoughtSignatureSentinel === undefined\n ? DEFAULT_SENTINEL\n : merged.thoughtSignatureSentinel,\n helpers: resolved,\n decodeMedia: mediaToGeminiInlineData,\n unsupportedMediaPolicy: merged.unsupportedMediaPolicy,\n warn,\n })\n\n const generationConfig = {\n ...(merged.maxOutputTokens !== undefined\n ? { maxOutputTokens: merged.maxOutputTokens }\n : {}),\n ...(merged.temperature !== undefined ? { temperature: merged.temperature } : {}),\n ...(merged.topP !== undefined ? { topP: merged.topP } : {}),\n ...(merged.topK !== undefined ? { topK: merged.topK } : {}),\n ...(merged.stopSequences ? { stopSequences: merged.stopSequences } : {}),\n ...(merged.thinkingConfig ? { thinkingConfig: merged.thinkingConfig } : {}),\n }\n const body = {\n ...request,\n ...(Object.keys(generationConfig).length > 0 ? { generationConfig } : {}),\n ...(merged.toolConfig ? { toolConfig: merged.toolConfig } : {}),\n ...(merged.safetySettings ? { safetySettings: merged.safetySettings } : {}),\n }\n\n // Prompt-assembled tap: the EXACT body about to be POSTed. An ADK-control key — stripped\n // from the wire request, never sent. Observer errors are swallowed so a tap can never\n // corrupt a generation.\n if (merged.onPromptAssembled) {\n try {\n merged.onPromptAssembled({\n battery: 'gemini_generate_content',\n kind: 'request-body',\n messages: body.contents,\n tools: body.tools,\n requestBody: body,\n streamed: merged.stream === true,\n streamId: dispatchStreamId,\n })\n } catch {\n /* observer errors are non-fatal */\n }\n }\n\n // ── dispatch ────────────────────────────────────────────────────────\n const base = (merged.baseURL ?? DEFAULT_BASE_URL).replace(/\\/$/, '')\n const action = merged.stream === true ? 'streamGenerateContent' : 'generateContent'\n const url = `${base}/models/${merged.model}:${action}`\n const headers: Record<string, string> = { 'Content-Type': 'application/json' }\n if (merged.apiKey) {\n // Google's own endpoint wants x-goog-api-key; several gateways in front of it accept only\n // Authorization, hence the switch rather than sending both.\n if (merged.useBearerAuth === true) headers.Authorization = `Bearer ${merged.apiKey}`\n else headers['x-goog-api-key'] = merged.apiKey\n }\n\n // retry / timeout loop — mirrors openai_chat_completions/adapter.ts and\n // anthropic_messages/adapter.ts: same defaults, same backoff, same Retry-After handling,\n // same log shape. This battery has no dedicated request-timeout exception class, so an\n // exhausted timeout and an exhausted generic transport failure both nack with the\n // existing E_GEMINI_STREAM_ERROR — only the log `kind` distinguishes them.\n const retryCfg: ChatCompletionsRetryConfig = {\n maxAttempts: merged.retry?.maxAttempts ?? 1,\n baseDelayMs: merged.retry?.baseDelayMs ?? 500,\n maxDelayMs: merged.retry?.maxDelayMs ?? 30_000,\n retriableStatuses: merged.retry?.retriableStatuses ?? [429, 502, 503, 504],\n honorRetryAfter: merged.retry?.honorRetryAfter ?? true,\n }\n\n const doFetch = merged.fetch ?? globalThis.fetch\n const maxAttempts = retryCfg.maxAttempts ?? 1\n\n let res: Response | undefined\n let attempt = 1\n // Each retry attempt re-links to the long-lived ctx.abortSignal — dispose the PRIOR\n // attempt's link before making a new one, else N retries leave N stale listeners on\n // ctx.abortSignal for the rest of the turn. The outer `finally` below disposes the LAST\n // attempt's link too, on every exit path (success, terminal error, or abort) — without it\n // the fallback path's listener (used when native AbortSignal.any is unavailable) never\n // detaches from ctx.abortSignal after the final attempt.\n let disposeLink: () => void = () => {}\n let rawText = ''\n let parsed: GeminiGenerateContentResponse\n try {\n while (attempt <= maxAttempts) {\n if (ctx.abortSignal.aborted) return\n\n const internalController = new AbortController()\n disposeLink()\n const { signal: linkedSignal, dispose: disposeCurrentLink } = linkAbortSignals([\n ctx.abortSignal,\n internalController.signal,\n ])\n disposeLink = disposeCurrentLink\n // Start the per-attempt timer only AFTER the signal link is built. `disposeLink()` and\n // `linkAbortSignals()` can throw synchronously; if the timer were already running, the\n // outer `finally` would dispose the link but leave this attempt's timer armed. Nothing\n // that can throw runs between this `setTimeout` and the `try` below, whose completion\n // and rejection paths both clear it.\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined\n const timeoutMs = merged.timeoutMs ?? 0\n if (timeoutMs > 0) {\n timeoutHandle = setTimeout(() => internalController.abort(), timeoutMs)\n }\n\n try {\n // The per-attempt timeout/abort link must stay live through BOTH the fetch call and\n // the body read below — this battery has no incremental SSE parsing, so `res.text()`\n // buffering the entire body is the only phase a stalled upstream can hang in, and it\n // needs the same bound the fetch phase gets (previously the timeout was cleared right\n // after headers arrived, leaving the body read unbounded).\n res = await doFetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: linkedSignal,\n })\n rawText = await res.text()\n if (timeoutHandle !== undefined) clearTimeout(timeoutHandle)\n } catch (err) {\n if (timeoutHandle !== undefined) clearTimeout(timeoutHandle)\n if (ctx.abortSignal.aborted) return\n if (internalController.signal.aborted) {\n helpers.log.warn({\n kind: 'request-timeout',\n message: `Request timed out after ${timeoutMs}ms on attempt ${attempt}/${maxAttempts}`,\n payload: { timeoutMs, attempt, maxAttempts },\n })\n if (attempt < maxAttempts) {\n const delay = computeBackoff(attempt, retryCfg)\n helpers.log.debug({\n kind: 'retry-attempt',\n message: `Retrying after request timeout in ~${delay}ms (attempt ${attempt + 1}/${maxAttempts})`,\n payload: {\n reason: 'request-timeout',\n delayMs: delay,\n attempt: attempt + 1,\n maxAttempts,\n },\n })\n await sleepWithJitter(delay, ctx.abortSignal)\n attempt += 1\n continue\n }\n ctx.nack(new E_GEMINI_STREAM_ERROR([`Request timed out after ${timeoutMs}ms`]))\n return\n }\n helpers.log.error({\n kind: 'transport-error',\n message: `Transport failure on attempt ${attempt}/${maxAttempts}: ${isError(err) ? err.message : String(err)}`,\n payload: {\n attempt,\n maxAttempts,\n detail: isError(err) ? err.message : String(err),\n },\n })\n if (attempt < maxAttempts) {\n const delay = computeBackoff(attempt, retryCfg)\n helpers.log.debug({\n kind: 'retry-attempt',\n message: `Retrying after transport failure in ~${delay}ms (attempt ${attempt + 1}/${maxAttempts})`,\n payload: {\n reason: 'transport-error',\n delayMs: delay,\n attempt: attempt + 1,\n maxAttempts,\n },\n })\n await sleepWithJitter(delay, ctx.abortSignal)\n attempt += 1\n continue\n }\n ctx.nack(new E_GEMINI_STREAM_ERROR([isError(err) ? err.message : String(err)]))\n return\n }\n\n if (!res.ok) {\n // Classify the vendor's own signature rejection separately, and BEFORE the generic\n // retriable-status check — it is a terminal, actionable error regardless of status\n // code, and Gemini's generic INVALID_ARGUMENT body gives a caller nothing to act on.\n if (/thought_signature|thoughtSignature/i.test(rawText)) {\n ctx.nack(new E_GEMINI_MISSING_THOUGHT_SIGNATURE([rawText.slice(0, 400)]))\n return\n }\n const status = res.status\n const retriable = (retryCfg.retriableStatuses ?? [429, 502, 503, 504]).includes(status)\n if (retriable && attempt < maxAttempts) {\n let delay = computeBackoff(attempt, retryCfg)\n let retryAfterMs: number | undefined\n if (retryCfg.honorRetryAfter !== false) {\n const ra = res.headers.get('Retry-After')\n if (ra) {\n const raMs = parseRetryAfter(ra)\n if (raMs > 0) {\n retryAfterMs = raMs\n delay = Math.min(Math.max(delay, raMs), retryCfg.maxDelayMs ?? 30_000)\n }\n }\n }\n helpers.log.warn({\n kind: 'retry-attempt',\n message: `HTTP ${status} on attempt ${attempt}/${maxAttempts}; retrying in ~${delay}ms`,\n payload: {\n reason: 'http-status',\n status,\n delayMs: delay,\n ...(retryAfterMs !== undefined ? { retryAfterMs } : {}),\n attempt: attempt + 1,\n maxAttempts,\n },\n })\n await sleepWithJitter(delay, ctx.abortSignal)\n attempt += 1\n continue\n }\n helpers.log.error({\n kind: 'http-error',\n message: `HTTP ${status} (terminal): ${rawText.slice(0, 256)}`,\n payload: { status, body: rawText, attempt, maxAttempts, retriable },\n })\n ctx.nack(new E_GEMINI_REQUEST_FAILED([status, rawText.slice(0, 400)]))\n return\n }\n break\n }\n if (!res) return\n parsed = JSON.parse(rawText) as GeminiGenerateContentResponse\n } catch (err) {\n ctx.nack(new E_GEMINI_STREAM_ERROR([isError(err) ? err.message : String(err)]))\n return\n } finally {\n // Runs on every exit from the loop above — success, an early `return` inside a `try`\n // still runs its enclosing `finally` — so the LAST attempt's link is disposed too, not\n // just the intermediate ones handled by the per-iteration `disposeLink()` call.\n disposeLink()\n }\n\n // ── interpret ───────────────────────────────────────────────────────\n const { text, reasoning, functionCalls, finishReason } = extractGeminiGeneration(parsed)\n const responseId = uuidv6()\n\n if (text.length > 0) {\n const messageId = `${responseId}:message`\n helpers.reportMessage(messageId, text, { isComplete: true })\n await ctx.storeMessage(\n new Message({\n id: messageId,\n role: 'assistant',\n content: text,\n identity: selfIdentity,\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n }\n if (reasoning.length > 0) {\n const thoughtId = `${responseId}:thought`\n helpers.reportThought(thoughtId, reasoning, { isComplete: true })\n await ctx.storeThought(\n new Thought({\n id: thoughtId,\n content: reasoning,\n identity: selfIdentity,\n createdAt: nowIso(),\n updatedAt: nowIso(),\n })\n )\n }\n\n // Fallback recovery: only consulted when the provider returned NO structured calls, so a\n // native functionCall always wins over a parsed one.\n let calls = functionCalls.map((c) => ({ id: uuidv6(), name: c.name, args: c.args }))\n if (calls.length === 0 && merged.localToolCallParser !== undefined && text.length > 0) {\n const parser = resolveToolCallParser(merged.localToolCallParser)\n // The parser returns { calls, cleanedText } — not an iterable of calls — and the\n // second argument carries the tool names actually offered this turn so a parser can\n // reject a hallucinated name rather than manufacture a call for it.\n const recovered = parser(text, { toolNames: ctx.tools.all().map((t) => t.name) })\n for (const call of recovered.calls) {\n calls.push({\n id: uuidv6(),\n name: call.name,\n args: (call.arguments ?? {}) as Record<string, unknown>,\n })\n }\n }\n\n if (merged.onRawGeneration) {\n try {\n merged.onRawGeneration({\n rawText: text,\n cleanedText: text,\n reasoning: reasoning.length > 0 ? [reasoning] : [],\n toolCalls: calls.map((c) => ({ name: c.name, arguments: c.args as never })),\n streamed: merged.stream === true,\n streamId: dispatchStreamId,\n })\n } catch {\n /* observer errors are non-fatal */\n }\n }\n\n if (calls.length === 0) {\n // `finishReason` is recorded for the caller; an empty generation is NOT an error here —\n // it is a real vendor outcome and the runner decides what to do with it.\n helpers.log.trace({\n kind: 'gemini-finish',\n message: `generation ended with finishReason=${finishReason ?? 'unknown'} and no function calls`,\n payload: { finishReason: finishReason ?? 'unknown' },\n })\n if (merged.autoAck) ctx.ack()\n return\n }\n\n for (const call of calls) {\n if (ctx.abortSignal.aborted) return\n const toolName = normalizeToolName(call.name)\n const tool = ctx.tools.get(toolName) as Tool | ArtifactTool | undefined\n const completedAt = nowIso()\n\n if (!isObject(call.args)) {\n const results = new Tokenizable(\n new E_GEMINI_INVALID_TOOL_CALL_ARGS([JSON.stringify(call.args)]).message\n )\n helpers.reportToolCall(call.id, { tool: toolName, args: {} })\n helpers.reportToolCall(call.id, { results, isError: true, isComplete: true })\n await ctx.storeToolCall(\n new ToolCall({\n id: call.id,\n tool: toolName,\n args: {},\n checksum: computeChecksum(toolName, {}),\n isComplete: true,\n isError: true,\n results,\n createdAt: completedAt,\n updatedAt: completedAt,\n completedAt,\n })\n )\n continue\n }\n\n if (!tool) {\n const available = ctx.tools\n .all()\n .map((t) => t.name)\n .sort()\n const results = new Tokenizable(\n available.length > 0\n ? `Tool not found: ${toolName}. Available tools: ${available.join(', ')}.`\n : `Tool not found: ${toolName}. No tools are available this turn.`\n )\n helpers.reportToolCall(call.id, { tool: toolName, args: call.args })\n helpers.reportToolCall(call.id, { results, isError: true, isComplete: true })\n await ctx.storeToolCall(\n new ToolCall({\n id: call.id,\n tool: toolName,\n args: call.args,\n checksum: computeChecksum(toolName, call.args),\n isComplete: true,\n isError: true,\n results,\n createdAt: completedAt,\n updatedAt: completedAt,\n completedAt,\n })\n )\n continue\n }\n\n helpers.reportToolCall(call.id, { tool: tool.name, args: call.args })\n let results: Tokenizable | SpooledArtifact | SpooledArtifact[] | Media | Media[] =\n new Tokenizable('')\n let isToolError = false\n try {\n const raw = await tool.executor(ctx)(call.args)\n results = Tokenizable.isTokenizable(raw)\n ? raw\n : new Tokenizable(typeof raw === 'string' ? raw : JSON.stringify(raw ?? ''))\n } catch (err) {\n isToolError = true\n results = new Tokenizable(isError(err) ? err.message : String(err))\n }\n const finishedAt = nowIso()\n helpers.reportToolCall(call.id, { results, isError: isToolError, isComplete: true })\n await ctx.storeToolCall(\n new ToolCall({\n id: call.id,\n tool: tool.name,\n args: call.args,\n checksum: computeChecksum(tool.name, call.args),\n isComplete: true,\n isError: isToolError,\n results,\n createdAt: finishedAt,\n updatedAt: finishedAt,\n completedAt: finishedAt,\n })\n )\n }\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { n as isInstanceOf, r as isObject, t as isError } from "../../../guards-BEpY7lBI.mjs";
|
|
2
|
-
import { r as Tokenizable } from "../../../tokenizable-
|
|
3
|
-
import { h as canonicalStringify } from "../../../spooled_artifact-
|
|
4
|
-
import { n as Message, t as Thought } from "../../../thought-
|
|
5
|
-
import { t as ToolCall } from "../../../tool_call-
|
|
6
|
-
import "../../../common-
|
|
2
|
+
import { r as Tokenizable } from "../../../tokenizable-VB4Av8GF.mjs";
|
|
3
|
+
import { h as canonicalStringify } from "../../../spooled_artifact-Bw_7swIp.mjs";
|
|
4
|
+
import { n as Message, t as Thought } from "../../../thought-CxSaF6Xf.mjs";
|
|
5
|
+
import { t as ToolCall } from "../../../tool_call-Cfaj-6zK.mjs";
|
|
6
|
+
import "../../../common-oI1niK9Z.mjs";
|
|
7
7
|
import "../../../guards.mjs";
|
|
8
|
+
import { computeBackoff, linkAbortSignals, parseRetryAfter, sleepWithJitter } from "../../../lib/utils/retry.mjs";
|
|
8
9
|
import { O as resolveToolCallParser } from "../../../tool_parsers-DgZhgxV8.mjs";
|
|
9
|
-
import { A as renderMemories, E as normalizeToolName, F as renderThirdPartyPrivateRetrievables, I as renderThirdPartyPublicRetrievables, L as renderThought, M as renderRetrievableSafetyDirective, N as renderRetrievables, O as renderChatCompletionsSystemPrompt, P as renderStandingInstructions, R as renderTrustedContent, k as renderFirstPartyRetrievables, x as filterThoughts, y as descriptionToChatCompletionsJsonSchema, z as renderUntrustedContent } from "../../../helpers-
|
|
10
|
+
import { A as renderMemories, E as normalizeToolName, F as renderThirdPartyPrivateRetrievables, I as renderThirdPartyPublicRetrievables, L as renderThought, M as renderRetrievableSafetyDirective, N as renderRetrievables, O as renderChatCompletionsSystemPrompt, P as renderStandingInstructions, R as renderTrustedContent, k as renderFirstPartyRetrievables, x as filterThoughts, y as descriptionToChatCompletionsJsonSchema, z as renderUntrustedContent } from "../../../helpers-mbn_EsDV.mjs";
|
|
10
11
|
import { E_GEMINI_GENERATE_CONTENT_CONTEXT_OVERFLOW, E_GEMINI_INVALID_TOOL_CALL_ARGS, E_GEMINI_MISSING_THOUGHT_SIGNATURE, E_GEMINI_REQUEST_FAILED, E_GEMINI_STREAM_ERROR, E_INVALID_GEMINI_GENERATE_CONTENT_OPTIONS } from "./exceptions.mjs";
|
|
11
12
|
import { validateOptions } from "./validation.mjs";
|
|
12
13
|
import { DEFAULT_GEMINI_BUCKET_ORDER, buildGeminiRequest, extractGeminiGeneration, mediaToGeminiInlineData, renderGeminiToolResult, toolsToGeminiTools } from "./helpers.mjs";
|
|
@@ -204,28 +205,168 @@ var GeminiGenerateContentAdapter = class GeminiGenerateContentAdapter {
|
|
|
204
205
|
const headers = { "Content-Type": "application/json" };
|
|
205
206
|
if (merged.apiKey) if (merged.useBearerAuth === true) headers.Authorization = `Bearer ${merged.apiKey}`;
|
|
206
207
|
else headers["x-goog-api-key"] = merged.apiKey;
|
|
208
|
+
const retryCfg = {
|
|
209
|
+
maxAttempts: merged.retry?.maxAttempts ?? 1,
|
|
210
|
+
baseDelayMs: merged.retry?.baseDelayMs ?? 500,
|
|
211
|
+
maxDelayMs: merged.retry?.maxDelayMs ?? 3e4,
|
|
212
|
+
retriableStatuses: merged.retry?.retriableStatuses ?? [
|
|
213
|
+
429,
|
|
214
|
+
502,
|
|
215
|
+
503,
|
|
216
|
+
504
|
|
217
|
+
],
|
|
218
|
+
honorRetryAfter: merged.retry?.honorRetryAfter ?? true
|
|
219
|
+
};
|
|
207
220
|
const doFetch = merged.fetch ?? globalThis.fetch;
|
|
221
|
+
const maxAttempts = retryCfg.maxAttempts ?? 1;
|
|
222
|
+
let res;
|
|
223
|
+
let attempt = 1;
|
|
224
|
+
let disposeLink = () => {};
|
|
225
|
+
let rawText = "";
|
|
208
226
|
let parsed;
|
|
209
227
|
try {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
signal:
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
if (
|
|
219
|
-
|
|
228
|
+
while (attempt <= maxAttempts) {
|
|
229
|
+
if (ctx.abortSignal.aborted) return;
|
|
230
|
+
const internalController = new AbortController();
|
|
231
|
+
disposeLink();
|
|
232
|
+
const { signal: linkedSignal, dispose: disposeCurrentLink } = linkAbortSignals([ctx.abortSignal, internalController.signal]);
|
|
233
|
+
disposeLink = disposeCurrentLink;
|
|
234
|
+
let timeoutHandle;
|
|
235
|
+
const timeoutMs = merged.timeoutMs ?? 0;
|
|
236
|
+
if (timeoutMs > 0) timeoutHandle = setTimeout(() => internalController.abort(), timeoutMs);
|
|
237
|
+
try {
|
|
238
|
+
res = await doFetch(url, {
|
|
239
|
+
method: "POST",
|
|
240
|
+
headers,
|
|
241
|
+
body: JSON.stringify(body),
|
|
242
|
+
signal: linkedSignal
|
|
243
|
+
});
|
|
244
|
+
rawText = await res.text();
|
|
245
|
+
if (timeoutHandle !== void 0) clearTimeout(timeoutHandle);
|
|
246
|
+
} catch (err) {
|
|
247
|
+
if (timeoutHandle !== void 0) clearTimeout(timeoutHandle);
|
|
248
|
+
if (ctx.abortSignal.aborted) return;
|
|
249
|
+
if (internalController.signal.aborted) {
|
|
250
|
+
helpers.log.warn({
|
|
251
|
+
kind: "request-timeout",
|
|
252
|
+
message: `Request timed out after ${timeoutMs}ms on attempt ${attempt}/${maxAttempts}`,
|
|
253
|
+
payload: {
|
|
254
|
+
timeoutMs,
|
|
255
|
+
attempt,
|
|
256
|
+
maxAttempts
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
if (attempt < maxAttempts) {
|
|
260
|
+
const delay = computeBackoff(attempt, retryCfg);
|
|
261
|
+
helpers.log.debug({
|
|
262
|
+
kind: "retry-attempt",
|
|
263
|
+
message: `Retrying after request timeout in ~${delay}ms (attempt ${attempt + 1}/${maxAttempts})`,
|
|
264
|
+
payload: {
|
|
265
|
+
reason: "request-timeout",
|
|
266
|
+
delayMs: delay,
|
|
267
|
+
attempt: attempt + 1,
|
|
268
|
+
maxAttempts
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
await sleepWithJitter(delay, ctx.abortSignal);
|
|
272
|
+
attempt += 1;
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
ctx.nack(new E_GEMINI_STREAM_ERROR([`Request timed out after ${timeoutMs}ms`]));
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
helpers.log.error({
|
|
279
|
+
kind: "transport-error",
|
|
280
|
+
message: `Transport failure on attempt ${attempt}/${maxAttempts}: ${isError(err) ? err.message : String(err)}`,
|
|
281
|
+
payload: {
|
|
282
|
+
attempt,
|
|
283
|
+
maxAttempts,
|
|
284
|
+
detail: isError(err) ? err.message : String(err)
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
if (attempt < maxAttempts) {
|
|
288
|
+
const delay = computeBackoff(attempt, retryCfg);
|
|
289
|
+
helpers.log.debug({
|
|
290
|
+
kind: "retry-attempt",
|
|
291
|
+
message: `Retrying after transport failure in ~${delay}ms (attempt ${attempt + 1}/${maxAttempts})`,
|
|
292
|
+
payload: {
|
|
293
|
+
reason: "transport-error",
|
|
294
|
+
delayMs: delay,
|
|
295
|
+
attempt: attempt + 1,
|
|
296
|
+
maxAttempts
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
await sleepWithJitter(delay, ctx.abortSignal);
|
|
300
|
+
attempt += 1;
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
ctx.nack(new E_GEMINI_STREAM_ERROR([isError(err) ? err.message : String(err)]));
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
if (!res.ok) {
|
|
307
|
+
if (/thought_signature|thoughtSignature/i.test(rawText)) {
|
|
308
|
+
ctx.nack(new E_GEMINI_MISSING_THOUGHT_SIGNATURE([rawText.slice(0, 400)]));
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
const status = res.status;
|
|
312
|
+
const retriable = (retryCfg.retriableStatuses ?? [
|
|
313
|
+
429,
|
|
314
|
+
502,
|
|
315
|
+
503,
|
|
316
|
+
504
|
|
317
|
+
]).includes(status);
|
|
318
|
+
if (retriable && attempt < maxAttempts) {
|
|
319
|
+
let delay = computeBackoff(attempt, retryCfg);
|
|
320
|
+
let retryAfterMs;
|
|
321
|
+
if (retryCfg.honorRetryAfter !== false) {
|
|
322
|
+
const ra = res.headers.get("Retry-After");
|
|
323
|
+
if (ra) {
|
|
324
|
+
const raMs = parseRetryAfter(ra);
|
|
325
|
+
if (raMs > 0) {
|
|
326
|
+
retryAfterMs = raMs;
|
|
327
|
+
delay = Math.min(Math.max(delay, raMs), retryCfg.maxDelayMs ?? 3e4);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
helpers.log.warn({
|
|
332
|
+
kind: "retry-attempt",
|
|
333
|
+
message: `HTTP ${status} on attempt ${attempt}/${maxAttempts}; retrying in ~${delay}ms`,
|
|
334
|
+
payload: {
|
|
335
|
+
reason: "http-status",
|
|
336
|
+
status,
|
|
337
|
+
delayMs: delay,
|
|
338
|
+
...retryAfterMs !== void 0 ? { retryAfterMs } : {},
|
|
339
|
+
attempt: attempt + 1,
|
|
340
|
+
maxAttempts
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
await sleepWithJitter(delay, ctx.abortSignal);
|
|
344
|
+
attempt += 1;
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
helpers.log.error({
|
|
348
|
+
kind: "http-error",
|
|
349
|
+
message: `HTTP ${status} (terminal): ${rawText.slice(0, 256)}`,
|
|
350
|
+
payload: {
|
|
351
|
+
status,
|
|
352
|
+
body: rawText,
|
|
353
|
+
attempt,
|
|
354
|
+
maxAttempts,
|
|
355
|
+
retriable
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
ctx.nack(new E_GEMINI_REQUEST_FAILED([status, rawText.slice(0, 400)]));
|
|
220
359
|
return;
|
|
221
360
|
}
|
|
222
|
-
|
|
223
|
-
return;
|
|
361
|
+
break;
|
|
224
362
|
}
|
|
225
|
-
|
|
363
|
+
if (!res) return;
|
|
364
|
+
parsed = JSON.parse(rawText);
|
|
226
365
|
} catch (err) {
|
|
227
366
|
ctx.nack(new E_GEMINI_STREAM_ERROR([isError(err) ? err.message : String(err)]));
|
|
228
367
|
return;
|
|
368
|
+
} finally {
|
|
369
|
+
disposeLink();
|
|
229
370
|
}
|
|
230
371
|
const { text, reasoning, functionCalls, finishReason } = extractGeminiGeneration(parsed);
|
|
231
372
|
const responseId = v6();
|