@copilotkit/aimock 1.45.1 → 1.47.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +25 -1
- package/README.md +11 -2
- package/dist/agui-mock.cjs +25 -25
- package/dist/agui-mock.cjs.map +1 -1
- package/dist/agui-mock.d.cts.map +1 -1
- package/dist/agui-mock.d.ts.map +1 -1
- package/dist/agui-mock.js +25 -25
- package/dist/agui-mock.js.map +1 -1
- package/dist/agui-types.d.cts.map +1 -1
- package/dist/aimock-cli.cjs +15 -1
- package/dist/aimock-cli.cjs.map +1 -1
- package/dist/aimock-cli.d.cts.map +1 -1
- package/dist/aimock-cli.d.ts.map +1 -1
- package/dist/aimock-cli.js +16 -2
- package/dist/aimock-cli.js.map +1 -1
- package/dist/api-key-auth.cjs +10 -9
- package/dist/api-key-auth.cjs.map +1 -1
- package/dist/api-key-auth.d.cts.map +1 -1
- package/dist/api-key-auth.d.ts.map +1 -1
- package/dist/api-key-auth.js +11 -10
- package/dist/api-key-auth.js.map +1 -1
- package/dist/aws-event-stream.cjs +20 -23
- package/dist/aws-event-stream.cjs.map +1 -1
- package/dist/aws-event-stream.d.cts +0 -1
- package/dist/aws-event-stream.d.ts +0 -1
- package/dist/aws-event-stream.js +20 -24
- package/dist/aws-event-stream.js.map +1 -1
- package/dist/batches.cjs +2 -4
- package/dist/batches.cjs.map +1 -1
- package/dist/batches.d.cts.map +1 -1
- package/dist/batches.d.ts.map +1 -1
- package/dist/batches.js +2 -4
- package/dist/batches.js.map +1 -1
- package/dist/bedrock-converse.cjs +139 -161
- package/dist/bedrock-converse.cjs.map +1 -1
- package/dist/bedrock-converse.d.cts.map +1 -1
- package/dist/bedrock-converse.d.ts.map +1 -1
- package/dist/bedrock-converse.js +137 -159
- package/dist/bedrock-converse.js.map +1 -1
- package/dist/bedrock.cjs +175 -216
- package/dist/bedrock.cjs.map +1 -1
- package/dist/bedrock.d.cts.map +1 -1
- package/dist/bedrock.d.ts.map +1 -1
- package/dist/bedrock.js +172 -213
- package/dist/bedrock.js.map +1 -1
- package/dist/byteplus-video.cjs +11 -10
- package/dist/byteplus-video.cjs.map +1 -1
- package/dist/byteplus-video.d.cts.map +1 -1
- package/dist/byteplus-video.d.ts.map +1 -1
- package/dist/byteplus-video.js +5 -4
- package/dist/byteplus-video.js.map +1 -1
- package/dist/chaos.cjs +5 -4
- package/dist/chaos.cjs.map +1 -1
- package/dist/chaos.d.cts.map +1 -1
- package/dist/chaos.d.ts.map +1 -1
- package/dist/chaos.js +5 -4
- package/dist/chaos.js.map +1 -1
- package/dist/cli.cjs +15 -0
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +15 -0
- package/dist/cli.js.map +1 -1
- package/dist/cohere.cjs +107 -180
- package/dist/cohere.cjs.map +1 -1
- package/dist/cohere.d.cts.map +1 -1
- package/dist/cohere.d.ts.map +1 -1
- package/dist/cohere.js +106 -179
- package/dist/cohere.js.map +1 -1
- package/dist/config-loader.cjs +29 -1
- package/dist/config-loader.cjs.map +1 -1
- package/dist/config-loader.d.cts +7 -1
- package/dist/config-loader.d.cts.map +1 -1
- package/dist/config-loader.d.ts +7 -1
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/config-loader.js +29 -2
- package/dist/config-loader.js.map +1 -1
- package/dist/count-tokens.cjs +146 -0
- package/dist/count-tokens.cjs.map +1 -0
- package/dist/count-tokens.js +146 -0
- package/dist/count-tokens.js.map +1 -0
- package/dist/elevenlabs-audio.cjs +36 -34
- package/dist/elevenlabs-audio.cjs.map +1 -1
- package/dist/elevenlabs-audio.d.cts.map +1 -1
- package/dist/elevenlabs-audio.d.ts.map +1 -1
- package/dist/elevenlabs-audio.js +33 -31
- package/dist/elevenlabs-audio.js.map +1 -1
- package/dist/elevenlabs-voice.cjs +38 -37
- package/dist/elevenlabs-voice.cjs.map +1 -1
- package/dist/elevenlabs-voice.d.cts.map +1 -1
- package/dist/elevenlabs-voice.d.ts.map +1 -1
- package/dist/elevenlabs-voice.js +33 -32
- package/dist/elevenlabs-voice.js.map +1 -1
- package/dist/embedding-request.cjs +16 -0
- package/dist/embedding-request.cjs.map +1 -0
- package/dist/embedding-request.js +14 -0
- package/dist/embedding-request.js.map +1 -0
- package/dist/embeddings.cjs +30 -20
- package/dist/embeddings.cjs.map +1 -1
- package/dist/embeddings.d.cts.map +1 -1
- package/dist/embeddings.d.ts.map +1 -1
- package/dist/embeddings.js +30 -20
- package/dist/embeddings.js.map +1 -1
- package/dist/fal-audio.cjs +45 -43
- package/dist/fal-audio.cjs.map +1 -1
- package/dist/fal-audio.d.cts.map +1 -1
- package/dist/fal-audio.d.ts.map +1 -1
- package/dist/fal-audio.js +42 -40
- package/dist/fal-audio.js.map +1 -1
- package/dist/fal.cjs +17 -15
- package/dist/fal.cjs.map +1 -1
- package/dist/fal.js +16 -14
- package/dist/fal.js.map +1 -1
- package/dist/files.cjs +2 -4
- package/dist/files.cjs.map +1 -1
- package/dist/files.d.cts.map +1 -1
- package/dist/files.d.ts.map +1 -1
- package/dist/files.js +2 -4
- package/dist/files.js.map +1 -1
- package/dist/fine-tuning.cjs +2 -4
- package/dist/fine-tuning.cjs.map +1 -1
- package/dist/fine-tuning.d.cts.map +1 -1
- package/dist/fine-tuning.d.ts.map +1 -1
- package/dist/fine-tuning.js +2 -4
- package/dist/fine-tuning.js.map +1 -1
- package/dist/fixture-loader.cjs +140 -44
- package/dist/fixture-loader.cjs.map +1 -1
- package/dist/fixture-loader.d.cts.map +1 -1
- package/dist/fixture-loader.d.ts.map +1 -1
- package/dist/fixture-loader.js +141 -46
- package/dist/fixture-loader.js.map +1 -1
- package/dist/gemini-embeddings.cjs +26 -24
- package/dist/gemini-embeddings.cjs.map +1 -1
- package/dist/gemini-embeddings.js +26 -24
- package/dist/gemini-embeddings.js.map +1 -1
- package/dist/gemini-interactions.cjs +113 -156
- package/dist/gemini-interactions.cjs.map +1 -1
- package/dist/gemini-interactions.d.cts +0 -1
- package/dist/gemini-interactions.d.cts.map +1 -1
- package/dist/gemini-interactions.d.ts +0 -1
- package/dist/gemini-interactions.d.ts.map +1 -1
- package/dist/gemini-interactions.js +113 -156
- package/dist/gemini-interactions.js.map +1 -1
- package/dist/gemini.cjs +295 -218
- package/dist/gemini.cjs.map +1 -1
- package/dist/gemini.d.cts.map +1 -1
- package/dist/gemini.d.ts.map +1 -1
- package/dist/gemini.js +295 -219
- package/dist/gemini.js.map +1 -1
- package/dist/grok-video.cjs +14 -12
- package/dist/grok-video.cjs.map +1 -1
- package/dist/grok-video.d.cts.map +1 -1
- package/dist/grok-video.d.ts.map +1 -1
- package/dist/grok-video.js +8 -6
- package/dist/grok-video.js.map +1 -1
- package/dist/helpers.cjs +411 -75
- package/dist/helpers.cjs.map +1 -1
- package/dist/helpers.d.cts +51 -1
- package/dist/helpers.d.cts.map +1 -1
- package/dist/helpers.d.ts +51 -1
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +402 -74
- package/dist/helpers.js.map +1 -1
- package/dist/images.cjs +30 -28
- package/dist/images.cjs.map +1 -1
- package/dist/images.d.cts.map +1 -1
- package/dist/images.d.ts.map +1 -1
- package/dist/images.js +27 -25
- package/dist/images.js.map +1 -1
- package/dist/index.cjs +4 -2
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -4
- package/dist/journal.cjs +3 -1
- package/dist/journal.cjs.map +1 -1
- package/dist/journal.d.cts.map +1 -1
- package/dist/journal.d.ts.map +1 -1
- package/dist/journal.js +2 -1
- package/dist/journal.js.map +1 -1
- package/dist/llmock.cjs +3 -0
- package/dist/llmock.cjs.map +1 -1
- package/dist/llmock.d.cts.map +1 -1
- package/dist/llmock.d.ts.map +1 -1
- package/dist/llmock.js +3 -0
- package/dist/llmock.js.map +1 -1
- package/dist/mcp-fakes.d.cts.map +1 -1
- package/dist/mcp-handler.cjs +7 -3
- package/dist/mcp-handler.cjs.map +1 -1
- package/dist/mcp-handler.js +7 -3
- package/dist/mcp-handler.js.map +1 -1
- package/dist/mcp-recorder.cjs +2 -1
- package/dist/mcp-recorder.cjs.map +1 -1
- package/dist/mcp-recorder.js +3 -2
- package/dist/mcp-recorder.js.map +1 -1
- package/dist/messages.cjs +235 -202
- package/dist/messages.cjs.map +1 -1
- package/dist/messages.d.cts.map +1 -1
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +234 -202
- package/dist/messages.js.map +1 -1
- package/dist/metrics.cjs +5 -2
- package/dist/metrics.cjs.map +1 -1
- package/dist/metrics.d.cts.map +1 -1
- package/dist/metrics.d.ts.map +1 -1
- package/dist/metrics.js +6 -3
- package/dist/metrics.js.map +1 -1
- package/dist/misbehavior.cjs +62 -3
- package/dist/misbehavior.cjs.map +1 -1
- package/dist/misbehavior.d.cts.map +1 -1
- package/dist/misbehavior.d.ts.map +1 -1
- package/dist/misbehavior.js +63 -4
- package/dist/misbehavior.js.map +1 -1
- package/dist/model-utils.cjs +1 -0
- package/dist/model-utils.cjs.map +1 -1
- package/dist/model-utils.js +1 -1
- package/dist/model-utils.js.map +1 -1
- package/dist/moderation.cjs +15 -12
- package/dist/moderation.cjs.map +1 -1
- package/dist/moderation.js +14 -11
- package/dist/moderation.js.map +1 -1
- package/dist/ndjson-writer.cjs +21 -23
- package/dist/ndjson-writer.cjs.map +1 -1
- package/dist/ndjson-writer.d.cts +0 -1
- package/dist/ndjson-writer.d.cts.map +1 -1
- package/dist/ndjson-writer.d.ts +0 -1
- package/dist/ndjson-writer.d.ts.map +1 -1
- package/dist/ndjson-writer.js +21 -24
- package/dist/ndjson-writer.js.map +1 -1
- package/dist/ollama.cjs +276 -210
- package/dist/ollama.cjs.map +1 -1
- package/dist/ollama.d.cts.map +1 -1
- package/dist/ollama.d.ts.map +1 -1
- package/dist/ollama.js +273 -207
- package/dist/ollama.js.map +1 -1
- package/dist/openapi.cjs +323 -3
- package/dist/openapi.cjs.map +1 -1
- package/dist/openapi.d.cts.map +1 -1
- package/dist/openapi.d.ts.map +1 -1
- package/dist/openapi.js +324 -4
- package/dist/openapi.js.map +1 -1
- package/dist/openrouter-chat.cjs +11 -155
- package/dist/openrouter-chat.cjs.map +1 -1
- package/dist/openrouter-chat.js +11 -155
- package/dist/openrouter-chat.js.map +1 -1
- package/dist/openrouter-video.cjs +51 -74
- package/dist/openrouter-video.cjs.map +1 -1
- package/dist/openrouter-video.d.cts.map +1 -1
- package/dist/openrouter-video.d.ts.map +1 -1
- package/dist/openrouter-video.js +37 -60
- package/dist/openrouter-video.js.map +1 -1
- package/dist/raw-validation.cjs +177 -0
- package/dist/raw-validation.cjs.map +1 -0
- package/dist/raw-validation.js +176 -0
- package/dist/raw-validation.js.map +1 -0
- package/dist/recorder.cjs +176 -95
- package/dist/recorder.cjs.map +1 -1
- package/dist/recorder.d.cts.map +1 -1
- package/dist/recorder.d.ts.map +1 -1
- package/dist/recorder.js +176 -95
- package/dist/recorder.js.map +1 -1
- package/dist/rerank.cjs +13 -11
- package/dist/rerank.cjs.map +1 -1
- package/dist/rerank.js +12 -10
- package/dist/rerank.js.map +1 -1
- package/dist/response/catalog/anthropic-page.cjs +39 -0
- package/dist/response/catalog/anthropic-page.cjs.map +1 -0
- package/dist/response/catalog/anthropic-page.js +38 -0
- package/dist/response/catalog/anthropic-page.js.map +1 -0
- package/dist/response/catalog/collect.cjs +61 -0
- package/dist/response/catalog/collect.cjs.map +1 -0
- package/dist/response/catalog/collect.js +59 -0
- package/dist/response/catalog/collect.js.map +1 -0
- package/dist/response/catalog/gemini-page.cjs +25 -0
- package/dist/response/catalog/gemini-page.cjs.map +1 -0
- package/dist/response/catalog/gemini-page.js +24 -0
- package/dist/response/catalog/gemini-page.js.map +1 -0
- package/dist/response/catalog/render.cjs +182 -0
- package/dist/response/catalog/render.cjs.map +1 -0
- package/dist/response/catalog/render.js +171 -0
- package/dist/response/catalog/render.js.map +1 -0
- package/dist/response/deliver.cjs +144 -0
- package/dist/response/deliver.cjs.map +1 -0
- package/dist/response/deliver.js +143 -0
- package/dist/response/deliver.js.map +1 -0
- package/dist/response/errors.cjs +225 -0
- package/dist/response/errors.cjs.map +1 -0
- package/dist/response/errors.js +224 -0
- package/dist/response/errors.js.map +1 -0
- package/dist/response/finish.cjs +39 -0
- package/dist/response/finish.cjs.map +1 -0
- package/dist/response/finish.js +35 -0
- package/dist/response/finish.js.map +1 -0
- package/dist/response/frame-loop.cjs +102 -0
- package/dist/response/frame-loop.cjs.map +1 -0
- package/dist/response/frame-loop.js +100 -0
- package/dist/response/frame-loop.js.map +1 -0
- package/dist/response/lifecycle.cjs +223 -0
- package/dist/response/lifecycle.cjs.map +1 -0
- package/dist/response/lifecycle.js +211 -0
- package/dist/response/lifecycle.js.map +1 -0
- package/dist/response/policy.cjs +126 -0
- package/dist/response/policy.cjs.map +1 -0
- package/dist/response/policy.js +120 -0
- package/dist/response/policy.js.map +1 -0
- package/dist/response/profiles.cjs +69 -0
- package/dist/response/profiles.cjs.map +1 -0
- package/dist/response/profiles.js +65 -0
- package/dist/response/profiles.js.map +1 -0
- package/dist/response/proxy.cjs +71 -0
- package/dist/response/proxy.cjs.map +1 -0
- package/dist/response/proxy.js +70 -0
- package/dist/response/proxy.js.map +1 -0
- package/dist/response/raw.cjs +228 -0
- package/dist/response/raw.cjs.map +1 -0
- package/dist/response/raw.js +227 -0
- package/dist/response/raw.js.map +1 -0
- package/dist/response/timing.cjs +157 -0
- package/dist/response/timing.cjs.map +1 -0
- package/dist/response/timing.js +150 -0
- package/dist/response/timing.js.map +1 -0
- package/dist/response/usage/codecs/anthropic.cjs +52 -0
- package/dist/response/usage/codecs/anthropic.cjs.map +1 -0
- package/dist/response/usage/codecs/anthropic.js +50 -0
- package/dist/response/usage/codecs/anthropic.js.map +1 -0
- package/dist/response/usage/codecs/cohere.cjs +36 -0
- package/dist/response/usage/codecs/cohere.cjs.map +1 -0
- package/dist/response/usage/codecs/cohere.js +35 -0
- package/dist/response/usage/codecs/cohere.js.map +1 -0
- package/dist/response/usage/codecs/converse.cjs +16 -0
- package/dist/response/usage/codecs/converse.cjs.map +1 -0
- package/dist/response/usage/codecs/converse.js +15 -0
- package/dist/response/usage/codecs/converse.js.map +1 -0
- package/dist/response/usage/codecs/gemini.cjs +31 -0
- package/dist/response/usage/codecs/gemini.cjs.map +1 -0
- package/dist/response/usage/codecs/gemini.js +31 -0
- package/dist/response/usage/codecs/gemini.js.map +1 -0
- package/dist/response/usage/codecs/interactions.cjs +22 -0
- package/dist/response/usage/codecs/interactions.cjs.map +1 -0
- package/dist/response/usage/codecs/interactions.js +21 -0
- package/dist/response/usage/codecs/interactions.js.map +1 -0
- package/dist/response/usage/codecs/ollama.cjs +17 -0
- package/dist/response/usage/codecs/ollama.cjs.map +1 -0
- package/dist/response/usage/codecs/ollama.js +17 -0
- package/dist/response/usage/codecs/ollama.js.map +1 -0
- package/dist/response/usage/codecs/openai.cjs +52 -0
- package/dist/response/usage/codecs/openai.cjs.map +1 -0
- package/dist/response/usage/codecs/openai.js +50 -0
- package/dist/response/usage/codecs/openai.js.map +1 -0
- package/dist/response/usage/codecs/openrouter.cjs +68 -0
- package/dist/response/usage/codecs/openrouter.cjs.map +1 -0
- package/dist/response/usage/codecs/openrouter.js +67 -0
- package/dist/response/usage/codecs/openrouter.js.map +1 -0
- package/dist/response/usage/codecs/realtime.cjs +19 -0
- package/dist/response/usage/codecs/realtime.cjs.map +1 -0
- package/dist/response/usage/codecs/realtime.js +18 -0
- package/dist/response/usage/codecs/realtime.js.map +1 -0
- package/dist/response/usage/codecs/responses.cjs +21 -0
- package/dist/response/usage/codecs/responses.cjs.map +1 -0
- package/dist/response/usage/codecs/responses.js +20 -0
- package/dist/response/usage/codecs/responses.js.map +1 -0
- package/dist/response/usage/estimate.cjs +23 -0
- package/dist/response/usage/estimate.cjs.map +1 -0
- package/dist/response/usage/estimate.js +21 -0
- package/dist/response/usage/estimate.js.map +1 -0
- package/dist/response/usage/fields.cjs +72 -0
- package/dist/response/usage/fields.cjs.map +1 -0
- package/dist/response/usage/fields.js +70 -0
- package/dist/response/usage/fields.js.map +1 -0
- package/dist/response/usage/recording.cjs +52 -0
- package/dist/response/usage/recording.cjs.map +1 -0
- package/dist/response/usage/recording.js +52 -0
- package/dist/response/usage/recording.js.map +1 -0
- package/dist/responses.cjs +304 -196
- package/dist/responses.cjs.map +1 -1
- package/dist/responses.d.cts.map +1 -1
- package/dist/responses.d.ts.map +1 -1
- package/dist/responses.js +303 -195
- package/dist/responses.js.map +1 -1
- package/dist/route-registry.cjs +45 -0
- package/dist/route-registry.cjs.map +1 -1
- package/dist/route-registry.d.cts.map +1 -1
- package/dist/route-registry.d.ts.map +1 -1
- package/dist/route-registry.js +41 -1
- package/dist/route-registry.js.map +1 -1
- package/dist/router.cjs +24 -4
- package/dist/router.cjs.map +1 -1
- package/dist/router.d.cts +7 -1
- package/dist/router.d.cts.map +1 -1
- package/dist/router.d.ts +7 -1
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +24 -5
- package/dist/router.js.map +1 -1
- package/dist/search.cjs +13 -11
- package/dist/search.cjs.map +1 -1
- package/dist/search.js +12 -10
- package/dist/search.js.map +1 -1
- package/dist/server.cjs +293 -248
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +294 -249
- package/dist/server.js.map +1 -1
- package/dist/speech.cjs +20 -18
- package/dist/speech.cjs.map +1 -1
- package/dist/speech.d.cts.map +1 -1
- package/dist/speech.d.ts.map +1 -1
- package/dist/speech.js +19 -17
- package/dist/speech.js.map +1 -1
- package/dist/sse-writer.cjs +56 -30
- package/dist/sse-writer.cjs.map +1 -1
- package/dist/sse-writer.d.cts +0 -1
- package/dist/sse-writer.d.cts.map +1 -1
- package/dist/sse-writer.d.ts +0 -1
- package/dist/sse-writer.d.ts.map +1 -1
- package/dist/sse-writer.js +55 -31
- package/dist/sse-writer.js.map +1 -1
- package/dist/stream-collapse.cjs +118 -11
- package/dist/stream-collapse.cjs.map +1 -1
- package/dist/stream-collapse.d.cts +10 -9
- package/dist/stream-collapse.d.cts.map +1 -1
- package/dist/stream-collapse.d.ts +10 -9
- package/dist/stream-collapse.d.ts.map +1 -1
- package/dist/stream-collapse.js +118 -11
- package/dist/stream-collapse.js.map +1 -1
- package/dist/transcription.cjs +31 -43
- package/dist/transcription.cjs.map +1 -1
- package/dist/transcription.d.cts.map +1 -1
- package/dist/transcription.d.ts.map +1 -1
- package/dist/transcription.js +31 -43
- package/dist/transcription.js.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +231 -9
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.ts +231 -9
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/vector-mock.cjs +3 -8
- package/dist/vector-mock.cjs.map +1 -1
- package/dist/vector-mock.d.cts.map +1 -1
- package/dist/vector-mock.d.ts.map +1 -1
- package/dist/vector-mock.js +3 -8
- package/dist/vector-mock.js.map +1 -1
- package/dist/vector-stores.cjs +2 -4
- package/dist/vector-stores.cjs.map +1 -1
- package/dist/vector-stores.d.cts.map +1 -1
- package/dist/vector-stores.d.ts.map +1 -1
- package/dist/vector-stores.js +2 -4
- package/dist/vector-stores.js.map +1 -1
- package/dist/veo-video.cjs +16 -14
- package/dist/veo-video.cjs.map +1 -1
- package/dist/veo-video.js +10 -8
- package/dist/veo-video.js.map +1 -1
- package/dist/video.cjs +21 -19
- package/dist/video.cjs.map +1 -1
- package/dist/video.d.cts.map +1 -1
- package/dist/video.d.ts.map +1 -1
- package/dist/video.js +20 -18
- package/dist/video.js.map +1 -1
- package/dist/ws-framing.cjs +12 -6
- package/dist/ws-framing.cjs.map +1 -1
- package/dist/ws-framing.d.cts +2 -0
- package/dist/ws-framing.d.cts.map +1 -1
- package/dist/ws-framing.d.ts +2 -0
- package/dist/ws-framing.d.ts.map +1 -1
- package/dist/ws-framing.js +12 -6
- package/dist/ws-framing.js.map +1 -1
- package/dist/ws-gemini-live.cjs +131 -96
- package/dist/ws-gemini-live.cjs.map +1 -1
- package/dist/ws-gemini-live.d.cts +0 -1
- package/dist/ws-gemini-live.d.cts.map +1 -1
- package/dist/ws-gemini-live.d.ts +0 -1
- package/dist/ws-gemini-live.d.ts.map +1 -1
- package/dist/ws-gemini-live.js +130 -95
- package/dist/ws-gemini-live.js.map +1 -1
- package/dist/ws-live.cjs +6 -5
- package/dist/ws-live.cjs.map +1 -1
- package/dist/ws-live.js +5 -4
- package/dist/ws-live.js.map +1 -1
- package/dist/ws-realtime.cjs +108 -124
- package/dist/ws-realtime.cjs.map +1 -1
- package/dist/ws-realtime.d.cts.map +1 -1
- package/dist/ws-realtime.d.ts.map +1 -1
- package/dist/ws-realtime.js +105 -121
- package/dist/ws-realtime.js.map +1 -1
- package/dist/ws-responses.cjs +80 -59
- package/dist/ws-responses.cjs.map +1 -1
- package/dist/ws-responses.d.cts.map +1 -1
- package/dist/ws-responses.d.ts.map +1 -1
- package/dist/ws-responses.js +79 -58
- package/dist/ws-responses.js.map +1 -1
- package/package.json +4 -1
- package/skills/write-fixtures/SKILL.md +57 -16
package/dist/gemini.cjs
CHANGED
|
@@ -1,13 +1,28 @@
|
|
|
1
|
+
const require_errors = require('./response/errors.cjs');
|
|
2
|
+
const require_policy = require('./response/policy.cjs');
|
|
1
3
|
const require_helpers = require('./helpers.cjs');
|
|
2
4
|
const require_sse_writer = require('./sse-writer.cjs');
|
|
3
5
|
const require_chaos = require('./chaos.cjs');
|
|
4
6
|
const require_misbehavior = require('./misbehavior.cjs');
|
|
5
7
|
const require_router = require('./router.cjs');
|
|
6
8
|
const require_recorder = require('./recorder.cjs');
|
|
7
|
-
const
|
|
9
|
+
const require_logger = require('./logger.cjs');
|
|
10
|
+
const require_timing = require('./response/timing.cjs');
|
|
11
|
+
const require_deliver = require('./response/deliver.cjs');
|
|
12
|
+
const require_proxy = require('./response/proxy.cjs');
|
|
13
|
+
const require_raw = require('./response/raw.cjs');
|
|
14
|
+
const require_finish = require('./response/finish.cjs');
|
|
15
|
+
const require_gemini = require('./response/usage/codecs/gemini.cjs');
|
|
8
16
|
|
|
9
17
|
//#region src/gemini.ts
|
|
10
18
|
/**
|
|
19
|
+
* Google Gemini GenerateContent API support.
|
|
20
|
+
*
|
|
21
|
+
* Translates incoming Gemini requests into the ChatCompletionRequest format
|
|
22
|
+
* used by the fixture router, and converts fixture responses back into the
|
|
23
|
+
* Gemini GenerateContent streaming (or non-streaming) format.
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
11
26
|
* Validate the shape of a Gemini `generateContent` body.
|
|
12
27
|
*
|
|
13
28
|
* Returns an error detail string when the shape is wrong, or null when
|
|
@@ -133,26 +148,115 @@ function geminiToCompletionRequest(req, model, stream) {
|
|
|
133
148
|
}
|
|
134
149
|
function geminiFinishReason(finishReason, defaultReason) {
|
|
135
150
|
if (!finishReason) return defaultReason;
|
|
136
|
-
|
|
137
|
-
if (finishReason === "tool_calls") return "FUNCTION_CALL";
|
|
138
|
-
if (finishReason === "length") return "MAX_TOKENS";
|
|
139
|
-
if (finishReason === "content_filter") return "SAFETY";
|
|
140
|
-
return finishReason;
|
|
151
|
+
return require_finish.mapGeminiFinish(finishReason);
|
|
141
152
|
}
|
|
142
153
|
function geminiUsageMetadata(overrides) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
154
|
+
return require_gemini.render(overrides);
|
|
155
|
+
}
|
|
156
|
+
function geminiWholeTextPart(text, partIndex) {
|
|
157
|
+
return [{
|
|
158
|
+
partIndex,
|
|
159
|
+
start: 0,
|
|
160
|
+
end: text.length
|
|
161
|
+
}];
|
|
162
|
+
}
|
|
163
|
+
function geminiGroundingSupports(text, citations, textParts) {
|
|
164
|
+
const segment = (part, from, to) => {
|
|
165
|
+
const partText = text.slice(part.start, part.end);
|
|
166
|
+
const start = Math.min(Math.max(from - part.start, 0), partText.length);
|
|
167
|
+
const end = Math.min(Math.max(to - part.start, start), partText.length);
|
|
168
|
+
const byteOffset = (charIndex) => Buffer.byteLength(partText.slice(0, charIndex), "utf8");
|
|
169
|
+
return {
|
|
170
|
+
partIndex: part.partIndex,
|
|
171
|
+
startIndex: byteOffset(start),
|
|
172
|
+
endIndex: byteOffset(end),
|
|
173
|
+
text: partText.slice(start, end)
|
|
174
|
+
};
|
|
147
175
|
};
|
|
148
|
-
|
|
149
|
-
|
|
176
|
+
return citations.flatMap((c, i) => {
|
|
177
|
+
const spanned = textParts.filter((p) => Math.max(c.startIndex, p.start) < Math.min(c.endIndex, p.end));
|
|
178
|
+
return (spanned.length > 0 ? spanned : [textParts.find((p) => c.startIndex < p.end) ?? textParts[textParts.length - 1]]).map((p) => ({
|
|
179
|
+
segment: segment(p, c.startIndex, c.endIndex),
|
|
180
|
+
groundingChunkIndices: [i]
|
|
181
|
+
}));
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
function geminiGroundingMetadata(text, overrides, textParts) {
|
|
185
|
+
const citations = require_helpers.resolveCitations(text, overrides?.citations);
|
|
186
|
+
if (citations.length === 0 || textParts.length === 0) return void 0;
|
|
150
187
|
return {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
totalTokenCount: overrides.usage.totalTokenCount ?? prompt + candidates
|
|
188
|
+
groundingChunks: geminiGroundingChunks(citations),
|
|
189
|
+
groundingSupports: geminiGroundingSupports(text, citations, textParts)
|
|
154
190
|
};
|
|
155
191
|
}
|
|
192
|
+
function geminiGroundingChunks(citations) {
|
|
193
|
+
return citations.map((c) => ({ web: {
|
|
194
|
+
uri: c.url,
|
|
195
|
+
title: c.title
|
|
196
|
+
} }));
|
|
197
|
+
}
|
|
198
|
+
function geminiGroundingField(text, overrides, textParts) {
|
|
199
|
+
const groundingMetadata = geminiGroundingMetadata(text, overrides, textParts);
|
|
200
|
+
return groundingMetadata ? { groundingMetadata } : {};
|
|
201
|
+
}
|
|
202
|
+
function geminiStreamGroundingFields(text, overrides, spans) {
|
|
203
|
+
const fields = spans.map(() => ({}));
|
|
204
|
+
const citations = require_helpers.resolveCitations(text, overrides?.citations);
|
|
205
|
+
if (citations.length === 0 || spans.length === 0) return fields;
|
|
206
|
+
const textParts = spans.map((s, k) => ({
|
|
207
|
+
partIndex: k,
|
|
208
|
+
start: s.start,
|
|
209
|
+
end: s.end
|
|
210
|
+
}));
|
|
211
|
+
const groundingChunks = geminiGroundingChunks(citations);
|
|
212
|
+
for (const support of geminiGroundingSupports(text, citations, textParts)) {
|
|
213
|
+
const k = support.segment.partIndex;
|
|
214
|
+
(fields[k].groundingMetadata ??= {
|
|
215
|
+
groundingChunks,
|
|
216
|
+
groundingSupports: []
|
|
217
|
+
}).groundingSupports.push({
|
|
218
|
+
...support,
|
|
219
|
+
segment: {
|
|
220
|
+
...support.segment,
|
|
221
|
+
partIndex: 0
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
return fields;
|
|
226
|
+
}
|
|
227
|
+
function geminiTextChunkSpans(text, chunkSize, offset = 0) {
|
|
228
|
+
if (text.length === 0) return [{
|
|
229
|
+
start: offset,
|
|
230
|
+
end: offset
|
|
231
|
+
}];
|
|
232
|
+
const spans = [];
|
|
233
|
+
let start = offset;
|
|
234
|
+
for (const slice of require_helpers.surrogateSafeChunks(text, chunkSize)) {
|
|
235
|
+
spans.push({
|
|
236
|
+
start,
|
|
237
|
+
end: start + slice.length
|
|
238
|
+
});
|
|
239
|
+
start += slice.length;
|
|
240
|
+
}
|
|
241
|
+
return spans;
|
|
242
|
+
}
|
|
243
|
+
function geminiFileParts(overrides) {
|
|
244
|
+
return require_helpers.fixtureFiles(overrides?.files).map((f) => ({ inlineData: {
|
|
245
|
+
mimeType: f.mimeType,
|
|
246
|
+
data: f.data
|
|
247
|
+
} }));
|
|
248
|
+
}
|
|
249
|
+
function geminiFileChunks(overrides) {
|
|
250
|
+
const parts = geminiFileParts(overrides);
|
|
251
|
+
if (parts.length === 0) return [];
|
|
252
|
+
return [{ candidates: [{
|
|
253
|
+
content: {
|
|
254
|
+
role: "model",
|
|
255
|
+
parts
|
|
256
|
+
},
|
|
257
|
+
index: 0
|
|
258
|
+
}] }];
|
|
259
|
+
}
|
|
156
260
|
function buildGeminiTextStreamChunks(content, chunkSize, reasoning, overrides) {
|
|
157
261
|
const chunks = [];
|
|
158
262
|
const effectiveFinish = geminiFinishReason(overrides?.finishReason, "STOP");
|
|
@@ -170,9 +274,11 @@ function buildGeminiTextStreamChunks(content, chunkSize, reasoning, overrides) {
|
|
|
170
274
|
index: 0
|
|
171
275
|
}] });
|
|
172
276
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
277
|
+
chunks.push(...geminiFileChunks(overrides));
|
|
278
|
+
const grounding = geminiStreamGroundingFields(content, overrides, geminiTextChunkSpans(content, chunkSize));
|
|
279
|
+
const contentSlices = require_helpers.surrogateSafeChunks(content, chunkSize);
|
|
280
|
+
contentSlices.forEach((slice, k) => {
|
|
281
|
+
const isLast = k === contentSlices.length - 1;
|
|
176
282
|
const chunk = {
|
|
177
283
|
candidates: [{
|
|
178
284
|
content: {
|
|
@@ -180,12 +286,13 @@ function buildGeminiTextStreamChunks(content, chunkSize, reasoning, overrides) {
|
|
|
180
286
|
parts: [{ text: slice }]
|
|
181
287
|
},
|
|
182
288
|
index: 0,
|
|
183
|
-
...isLast ? { finishReason: effectiveFinish } : {}
|
|
289
|
+
...isLast ? { finishReason: effectiveFinish } : {},
|
|
290
|
+
...grounding[k]
|
|
184
291
|
}],
|
|
185
292
|
...isLast ? { usageMetadata: usage } : {}
|
|
186
293
|
};
|
|
187
294
|
chunks.push(chunk);
|
|
188
|
-
}
|
|
295
|
+
});
|
|
189
296
|
if (content.length === 0) chunks.push({
|
|
190
297
|
candidates: [{
|
|
191
298
|
content: {
|
|
@@ -193,6 +300,7 @@ function buildGeminiTextStreamChunks(content, chunkSize, reasoning, overrides) {
|
|
|
193
300
|
parts: [{ text: "" }]
|
|
194
301
|
},
|
|
195
302
|
finishReason: effectiveFinish,
|
|
303
|
+
...grounding[0],
|
|
196
304
|
index: 0
|
|
197
305
|
}],
|
|
198
306
|
usageMetadata: usage
|
|
@@ -223,6 +331,8 @@ function buildGeminiToolCallStreamChunks(toolCalls, chunkSize, logger, reasoning
|
|
|
223
331
|
index: 0
|
|
224
332
|
}] });
|
|
225
333
|
}
|
|
334
|
+
chunks.push(...geminiFileChunks(overrides));
|
|
335
|
+
require_helpers.resolveCitations("", overrides?.citations);
|
|
226
336
|
const parts = toolCalls.map((tc) => parseToolCallPart(tc, logger));
|
|
227
337
|
chunks.push({
|
|
228
338
|
candidates: [{
|
|
@@ -243,6 +353,8 @@ function buildGeminiTextResponse(content, reasoning, overrides) {
|
|
|
243
353
|
text: reasoning,
|
|
244
354
|
thought: true
|
|
245
355
|
});
|
|
356
|
+
parts.push(...geminiFileParts(overrides));
|
|
357
|
+
const textParts = geminiWholeTextPart(content, parts.length);
|
|
246
358
|
parts.push({ text: content });
|
|
247
359
|
return {
|
|
248
360
|
candidates: [{
|
|
@@ -251,17 +363,20 @@ function buildGeminiTextResponse(content, reasoning, overrides) {
|
|
|
251
363
|
parts
|
|
252
364
|
},
|
|
253
365
|
finishReason: geminiFinishReason(overrides?.finishReason, "STOP"),
|
|
366
|
+
...geminiGroundingField(content, overrides, textParts),
|
|
254
367
|
index: 0
|
|
255
368
|
}],
|
|
256
369
|
usageMetadata: geminiUsageMetadata(overrides)
|
|
257
370
|
};
|
|
258
371
|
}
|
|
259
372
|
function buildGeminiToolCallResponse(toolCalls, logger, reasoning, overrides) {
|
|
373
|
+
require_helpers.resolveCitations("", overrides?.citations);
|
|
260
374
|
const parts = [];
|
|
261
375
|
if (reasoning) parts.push({
|
|
262
376
|
text: reasoning,
|
|
263
377
|
thought: true
|
|
264
378
|
});
|
|
379
|
+
parts.push(...geminiFileParts(overrides));
|
|
265
380
|
parts.push(...toolCalls.map((tc) => parseToolCallPart(tc, logger)));
|
|
266
381
|
return {
|
|
267
382
|
candidates: [{
|
|
@@ -290,9 +405,19 @@ function buildGeminiContentWithToolCallsStreamChunks(content, toolCalls, chunkSi
|
|
|
290
405
|
index: 0
|
|
291
406
|
}] });
|
|
292
407
|
}
|
|
408
|
+
chunks.push(...geminiFileChunks(overrides));
|
|
293
409
|
if (blocks && blocks.length > 0) {
|
|
294
410
|
const outcome = require_helpers.resolveFixtureBlockOutcome(blocks);
|
|
295
411
|
const resolved = outcome.ordered;
|
|
412
|
+
const spans = [];
|
|
413
|
+
let offset = 0;
|
|
414
|
+
for (const block of resolved) {
|
|
415
|
+
if (block.type !== "text") continue;
|
|
416
|
+
spans.push(...geminiTextChunkSpans(block.text, chunkSize, offset));
|
|
417
|
+
offset += block.text.length;
|
|
418
|
+
}
|
|
419
|
+
const grounding = geminiStreamGroundingFields(outcome.content, overrides, spans);
|
|
420
|
+
let textChunk = 0;
|
|
296
421
|
resolved.forEach((block, i) => {
|
|
297
422
|
const isLast = i === resolved.length - 1;
|
|
298
423
|
const finishReason = isLast ? geminiFinishReason(overrides?.finishReason, outcome.hasToolCalls ? "FUNCTION_CALL" : "STOP") : void 0;
|
|
@@ -322,47 +447,53 @@ function buildGeminiContentWithToolCallsStreamChunks(content, toolCalls, chunkSi
|
|
|
322
447
|
parts: [{ text: "" }]
|
|
323
448
|
},
|
|
324
449
|
...finishReason ? { finishReason } : {},
|
|
450
|
+
...grounding[textChunk++],
|
|
325
451
|
index: 0
|
|
326
452
|
}],
|
|
327
453
|
...isLast ? { usageMetadata: geminiUsageMetadata(overrides) } : {}
|
|
328
454
|
});
|
|
329
|
-
else
|
|
330
|
-
const
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
455
|
+
else {
|
|
456
|
+
const slices = require_helpers.surrogateSafeChunks(text, chunkSize);
|
|
457
|
+
slices.forEach((slice, j) => {
|
|
458
|
+
const lastSlice = j === slices.length - 1;
|
|
459
|
+
const sliceFinish = isLast && lastSlice ? finishReason : void 0;
|
|
460
|
+
chunks.push({
|
|
461
|
+
candidates: [{
|
|
462
|
+
content: {
|
|
463
|
+
role: "model",
|
|
464
|
+
parts: [{ text: slice }]
|
|
465
|
+
},
|
|
466
|
+
...sliceFinish ? { finishReason: sliceFinish } : {},
|
|
467
|
+
...grounding[textChunk++],
|
|
468
|
+
index: 0
|
|
469
|
+
}],
|
|
470
|
+
...isLast && lastSlice ? { usageMetadata: geminiUsageMetadata(overrides) } : {}
|
|
471
|
+
});
|
|
343
472
|
});
|
|
344
473
|
}
|
|
345
474
|
}
|
|
346
475
|
});
|
|
347
476
|
return chunks;
|
|
348
477
|
}
|
|
478
|
+
const grounding = geminiStreamGroundingFields(content, overrides, geminiTextChunkSpans(content, chunkSize));
|
|
349
479
|
if (content.length === 0) chunks.push({ candidates: [{
|
|
350
480
|
content: {
|
|
351
481
|
role: "model",
|
|
352
482
|
parts: [{ text: "" }]
|
|
353
483
|
},
|
|
484
|
+
...grounding[0],
|
|
354
485
|
index: 0
|
|
355
486
|
}] });
|
|
356
|
-
else
|
|
357
|
-
const slice = content.slice(i, i + chunkSize);
|
|
487
|
+
else require_helpers.surrogateSafeChunks(content, chunkSize).forEach((slice, k) => {
|
|
358
488
|
chunks.push({ candidates: [{
|
|
359
489
|
content: {
|
|
360
490
|
role: "model",
|
|
361
491
|
parts: [{ text: slice }]
|
|
362
492
|
},
|
|
493
|
+
...grounding[k],
|
|
363
494
|
index: 0
|
|
364
495
|
}] });
|
|
365
|
-
}
|
|
496
|
+
});
|
|
366
497
|
const parts = toolCalls.map((tc) => parseToolCallPart(tc, logger));
|
|
367
498
|
chunks.push({
|
|
368
499
|
candidates: [{
|
|
@@ -383,18 +514,31 @@ function buildGeminiContentWithToolCallsResponse(content, toolCalls, logger, rea
|
|
|
383
514
|
text: reasoning,
|
|
384
515
|
thought: true
|
|
385
516
|
});
|
|
517
|
+
parts.push(...geminiFileParts(overrides));
|
|
386
518
|
let blockHasTools;
|
|
519
|
+
let groundingText = content;
|
|
520
|
+
const textParts = [];
|
|
387
521
|
if (blocks && blocks.length > 0) {
|
|
388
522
|
const outcome = require_helpers.resolveFixtureBlockOutcome(blocks);
|
|
389
523
|
const resolved = outcome.ordered;
|
|
390
524
|
blockHasTools = outcome.hasToolCalls;
|
|
525
|
+
groundingText = outcome.content;
|
|
391
526
|
for (const block of resolved) if (block.type === "toolCall") parts.push(parseToolCallPart({
|
|
392
527
|
name: block.name,
|
|
393
528
|
arguments: block.arguments,
|
|
394
529
|
id: block.id
|
|
395
530
|
}, logger));
|
|
396
|
-
else
|
|
531
|
+
else {
|
|
532
|
+
const start = textParts.length > 0 ? textParts[textParts.length - 1].end : 0;
|
|
533
|
+
textParts.push({
|
|
534
|
+
partIndex: parts.length,
|
|
535
|
+
start,
|
|
536
|
+
end: start + block.text.length
|
|
537
|
+
});
|
|
538
|
+
parts.push({ text: block.text });
|
|
539
|
+
}
|
|
397
540
|
} else {
|
|
541
|
+
textParts.push(...geminiWholeTextPart(content, parts.length));
|
|
398
542
|
parts.push({ text: content });
|
|
399
543
|
parts.push(...toolCalls.map((tc) => parseToolCallPart(tc, logger)));
|
|
400
544
|
}
|
|
@@ -405,6 +549,7 @@ function buildGeminiContentWithToolCallsResponse(content, toolCalls, logger, rea
|
|
|
405
549
|
parts
|
|
406
550
|
},
|
|
407
551
|
finishReason: geminiFinishReason(overrides?.finishReason, blockHasTools === false ? "STOP" : "FUNCTION_CALL"),
|
|
552
|
+
...geminiGroundingField(groundingText, overrides, textParts),
|
|
408
553
|
index: 0
|
|
409
554
|
}],
|
|
410
555
|
usageMetadata: geminiUsageMetadata(overrides)
|
|
@@ -440,11 +585,7 @@ function buildGeminiAudioResponse(audio, toolCalls, logger, effReasoning) {
|
|
|
440
585
|
finishReason: toolCalls.length ? "FUNCTION_CALL" : "STOP",
|
|
441
586
|
index: 0
|
|
442
587
|
}],
|
|
443
|
-
usageMetadata:
|
|
444
|
-
promptTokenCount: 0,
|
|
445
|
-
candidatesTokenCount: 0,
|
|
446
|
-
totalTokenCount: 0
|
|
447
|
-
}
|
|
588
|
+
usageMetadata: require_gemini.render()
|
|
448
589
|
};
|
|
449
590
|
}
|
|
450
591
|
function buildGeminiAudioStreamChunks(audio, toolCalls, logger, effReasoning) {
|
|
@@ -457,37 +598,22 @@ function buildGeminiAudioStreamChunks(audio, toolCalls, logger, effReasoning) {
|
|
|
457
598
|
finishReason: toolCalls.length ? "FUNCTION_CALL" : "STOP",
|
|
458
599
|
index: 0
|
|
459
600
|
}],
|
|
460
|
-
usageMetadata:
|
|
461
|
-
promptTokenCount: 0,
|
|
462
|
-
candidatesTokenCount: 0,
|
|
463
|
-
totalTokenCount: 0
|
|
464
|
-
}
|
|
601
|
+
usageMetadata: require_gemini.render()
|
|
465
602
|
}];
|
|
466
603
|
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
const chunkDelay = require_sse_writer.calculateDelay(chunkIndex, profile, latency, recordedTimings, replaySpeed);
|
|
481
|
-
if (chunkDelay > 0) await require_sse_writer.delay(chunkDelay, signal);
|
|
482
|
-
if (signal?.aborted) return false;
|
|
483
|
-
if (res.writableEnded) return true;
|
|
484
|
-
res.write(`data: ${JSON.stringify(chunk)}\n\n`);
|
|
485
|
-
onChunkSent?.();
|
|
486
|
-
if (signal?.aborted) return false;
|
|
487
|
-
chunkIndex++;
|
|
488
|
-
}
|
|
489
|
-
if (!res.writableEnded) res.end();
|
|
490
|
-
return true;
|
|
604
|
+
const GEMINI_SSE = require_sse_writer.sseCodec({ done: false });
|
|
605
|
+
const SILENT_LOGGER = new require_logger.Logger("silent");
|
|
606
|
+
/**
|
|
607
|
+
* The reasoning a misbehavior reply's non-streaming wait is sized with: the
|
|
608
|
+
* plan response's reasoning through the same model and strict gate the
|
|
609
|
+
* builders apply. The gate runs with a silent logger, so the builder's own
|
|
610
|
+
* warning stays the only one. A reasoning-only plan carries its reasoning on
|
|
611
|
+
* the plan, and `misbehaviorPayloadLength` reads it there.
|
|
612
|
+
*/
|
|
613
|
+
function misbehaviorPayloadReasoning(plan, model, strict) {
|
|
614
|
+
const response = plan.response;
|
|
615
|
+
if (plan.reasoning !== void 0 || !(require_helpers.isCombinedFixtureResponse(response) || require_helpers.isTextResponse(response) || require_helpers.isToolCallResponse(response))) return;
|
|
616
|
+
return require_helpers.resolveReasoningForModel(response.reasoning, model, strict, SILENT_LOGGER);
|
|
491
617
|
}
|
|
492
618
|
/** Prepare native fault output once; the journal describes these exact parts. */
|
|
493
619
|
function prepareGeminiMisbehavior(plan, request, streaming, chunkSize, logger, strict) {
|
|
@@ -520,7 +646,11 @@ function prepareGeminiMisbehavior(plan, request, streaming, chunkSize, logger, s
|
|
|
520
646
|
candidate.finishReason = "UNEXPECTED_TOOL_CALL";
|
|
521
647
|
chunks = [{ candidates: [candidate] }];
|
|
522
648
|
} else if (fault === "stop-length-mid-tool") {
|
|
523
|
-
|
|
649
|
+
const parts = geminiFileParts(overrides);
|
|
650
|
+
const textPartIndex = parts.length;
|
|
651
|
+
if (content) parts.push({ text: content });
|
|
652
|
+
candidate.content.parts = parts;
|
|
653
|
+
if (content) Object.assign(candidate, geminiGroundingField(content, overrides, geminiWholeTextPart(content, textPartIndex)));
|
|
524
654
|
candidate.finishReason = "MAX_TOKENS";
|
|
525
655
|
chunks = [{ candidates: [candidate] }];
|
|
526
656
|
} else if (fault === "empty-response") {
|
|
@@ -555,13 +685,14 @@ function prepareGeminiMisbehavior(plan, request, streaming, chunkSize, logger, s
|
|
|
555
685
|
arguments: JSON.stringify(part.functionCall.args),
|
|
556
686
|
...part.functionCall.id ? { id: part.functionCall.id } : {}
|
|
557
687
|
}] : []);
|
|
558
|
-
const
|
|
688
|
+
const prompt = request.messages.map((message) => typeof message.content === "string" ? message.content : (message.content ?? []).map((part) => part.text ?? "").join("")).join("");
|
|
689
|
+
const output = parts.map((part) => part.text ?? (part.functionCall ? part.functionCall.name + JSON.stringify(part.functionCall.args) : "")).join("");
|
|
559
690
|
for (const chunk of chunks) delete chunk.usageMetadata;
|
|
560
|
-
chunks[chunks.length - 1].usageMetadata = {
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
};
|
|
691
|
+
chunks[chunks.length - 1].usageMetadata = require_gemini.render(void 0, {
|
|
692
|
+
kind: "applied-misbehavior",
|
|
693
|
+
promptText: prompt,
|
|
694
|
+
completionText: output
|
|
695
|
+
});
|
|
565
696
|
return {
|
|
566
697
|
chunks,
|
|
567
698
|
summary: {
|
|
@@ -589,11 +720,11 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
589
720
|
fixture: null
|
|
590
721
|
}
|
|
591
722
|
});
|
|
592
|
-
require_sse_writer.writeErrorResponse(res, 400,
|
|
723
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("gemini", "validation", {
|
|
593
724
|
message: `Malformed JSON body: ${detail}`,
|
|
594
|
-
|
|
725
|
+
bodyCode: 400,
|
|
595
726
|
status: "INVALID_ARGUMENT"
|
|
596
|
-
}
|
|
727
|
+
}).body);
|
|
597
728
|
return;
|
|
598
729
|
}
|
|
599
730
|
if (!require_helpers.isJsonObject(geminiReq)) {
|
|
@@ -607,11 +738,11 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
607
738
|
fixture: null
|
|
608
739
|
}
|
|
609
740
|
});
|
|
610
|
-
require_sse_writer.writeErrorResponse(res, 400,
|
|
741
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("gemini", "validation", {
|
|
611
742
|
message: "Request body must be a JSON object",
|
|
612
|
-
|
|
743
|
+
bodyCode: 400,
|
|
613
744
|
status: "INVALID_ARGUMENT"
|
|
614
|
-
}
|
|
745
|
+
}).body);
|
|
615
746
|
return;
|
|
616
747
|
}
|
|
617
748
|
const geminiShapeError = validateGeminiBody(geminiReq);
|
|
@@ -626,18 +757,21 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
626
757
|
fixture: null
|
|
627
758
|
}
|
|
628
759
|
});
|
|
629
|
-
require_sse_writer.writeErrorResponse(res, 400,
|
|
760
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("gemini", "validation", {
|
|
630
761
|
message: `Invalid argument: ${geminiShapeError}`,
|
|
631
|
-
|
|
762
|
+
bodyCode: 400,
|
|
632
763
|
status: "INVALID_ARGUMENT"
|
|
633
|
-
}
|
|
764
|
+
}).body);
|
|
634
765
|
return;
|
|
635
766
|
}
|
|
636
767
|
const completionReq = geminiToCompletionRequest(geminiReq, model, streaming);
|
|
637
768
|
completionReq._endpointType = "chat";
|
|
638
769
|
completionReq._context = require_helpers.getContext(req);
|
|
639
770
|
const testId = require_helpers.getTestId(req);
|
|
640
|
-
const { fixture, skippedBySequenceOrTurn } = require_router.matchFixtureDiagnostic(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform,
|
|
771
|
+
const { fixture, skippedBySequenceOrTurn } = require_router.matchFixtureDiagnostic(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform, {
|
|
772
|
+
...require_router.recordMatchOptions(!!defaults.record, defaults.logger),
|
|
773
|
+
wire: "gemini"
|
|
774
|
+
});
|
|
641
775
|
const path = req.url ?? `/v1beta/models/${model}:generateContent`;
|
|
642
776
|
if (fixture) logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);
|
|
643
777
|
else logger.debug(`No fixture matched for request`);
|
|
@@ -649,7 +783,8 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
649
783
|
body: completionReq
|
|
650
784
|
}, fixture ? "fixture" : "proxy", defaults.registry, defaults.logger)) return;
|
|
651
785
|
if (!fixture) {
|
|
652
|
-
|
|
786
|
+
const decisions = require_policy.resolveRequestDecisions(defaults.strict, req.headers);
|
|
787
|
+
if (decisions.fixtureMiss) {
|
|
653
788
|
const strictMessage = require_helpers.strictNoMatchMessage(skippedBySequenceOrTurn);
|
|
654
789
|
logger.error(require_helpers.strictNoMatchLogLine(req.method ?? "POST", path, skippedBySequenceOrTurn));
|
|
655
790
|
journal.add({
|
|
@@ -660,18 +795,18 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
660
795
|
response: {
|
|
661
796
|
status: 503,
|
|
662
797
|
fixture: null,
|
|
663
|
-
...
|
|
798
|
+
...require_policy.strictOverrideField(defaults.strict, req.headers)
|
|
664
799
|
}
|
|
665
800
|
});
|
|
666
|
-
require_sse_writer.writeErrorResponse(res, 503,
|
|
801
|
+
require_sse_writer.writeErrorResponse(res, 503, require_errors.renderError("gemini", "strict-miss", {
|
|
667
802
|
message: strictMessage,
|
|
668
|
-
|
|
803
|
+
bodyCode: 503,
|
|
669
804
|
status: "UNAVAILABLE"
|
|
670
|
-
}
|
|
805
|
+
}).body);
|
|
671
806
|
return;
|
|
672
807
|
}
|
|
673
|
-
if (defaults.record) {
|
|
674
|
-
const outcome = await require_recorder.proxyAndRecord(req, res, completionReq, providerKey, path, fixtures, defaults, raw);
|
|
808
|
+
if (decisions.upstream && defaults.record) {
|
|
809
|
+
const { outcome, clientHungUp } = await require_proxy.withHangUpDetection(req, res, () => require_recorder.proxyAndRecord(req, res, completionReq, providerKey, path, fixtures, defaults, raw));
|
|
675
810
|
if (outcome === "handled_by_hook") return;
|
|
676
811
|
if (outcome !== "not_configured") {
|
|
677
812
|
journal.add({
|
|
@@ -682,7 +817,8 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
682
817
|
response: {
|
|
683
818
|
status: res.statusCode ?? 200,
|
|
684
819
|
fixture: null,
|
|
685
|
-
source: "proxy"
|
|
820
|
+
source: "proxy",
|
|
821
|
+
...require_proxy.proxyInterruption(res, clientHungUp)
|
|
686
822
|
}
|
|
687
823
|
});
|
|
688
824
|
return;
|
|
@@ -696,14 +832,14 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
696
832
|
response: {
|
|
697
833
|
status: 404,
|
|
698
834
|
fixture: null,
|
|
699
|
-
...
|
|
835
|
+
...require_policy.strictOverrideField(defaults.strict, req.headers)
|
|
700
836
|
}
|
|
701
837
|
});
|
|
702
|
-
require_sse_writer.writeErrorResponse(res, 404,
|
|
838
|
+
require_sse_writer.writeErrorResponse(res, 404, require_errors.renderError("gemini", "fixture-miss", {
|
|
703
839
|
message: "No fixture matched",
|
|
704
|
-
|
|
840
|
+
bodyCode: 404,
|
|
705
841
|
status: "NOT_FOUND"
|
|
706
|
-
}
|
|
842
|
+
}).body);
|
|
707
843
|
return;
|
|
708
844
|
}
|
|
709
845
|
const response = await require_helpers.resolveResponse(fixture, completionReq);
|
|
@@ -736,18 +872,31 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
736
872
|
testId
|
|
737
873
|
});
|
|
738
874
|
if (misbehavior.summary?.evaluations.length === 0) logger.error(`${req.method ?? "POST"} ${path}: ${misbehavior.message}`);
|
|
739
|
-
require_sse_writer.writeErrorResponse(res, misbehavior.status,
|
|
740
|
-
|
|
875
|
+
require_sse_writer.writeErrorResponse(res, misbehavior.status, require_errors.renderError("gemini", "misbehavior", {
|
|
876
|
+
bodyCode: misbehavior.status,
|
|
741
877
|
message: misbehavior.message,
|
|
742
878
|
status: misbehavior.status === 400 ? "INVALID_ARGUMENT" : "UNIMPLEMENTED"
|
|
743
|
-
}
|
|
879
|
+
}).body);
|
|
744
880
|
return;
|
|
745
881
|
}
|
|
746
882
|
const latency = fixture.latency ?? defaults.latency;
|
|
747
883
|
const chunkSize = Math.max(1, fixture.chunkSize ?? defaults.chunkSize);
|
|
748
884
|
const replaySpeed = fixture.replaySpeed ?? defaults.replaySpeed;
|
|
885
|
+
const streamTiming = {
|
|
886
|
+
latency,
|
|
887
|
+
streamingProfile: fixture.streamingProfile,
|
|
888
|
+
recordedTimings: fixture.recordedTimings,
|
|
889
|
+
replaySpeed
|
|
890
|
+
};
|
|
891
|
+
const jsonOpts = (payloadLength, duplicateId = false) => ({
|
|
892
|
+
surface: "other",
|
|
893
|
+
payloadLength,
|
|
894
|
+
chunkSize,
|
|
895
|
+
recordedTimings: fixture.recordedTimings,
|
|
896
|
+
duplicateId,
|
|
897
|
+
replaySpeed
|
|
898
|
+
});
|
|
749
899
|
if (misbehavior.kind === "applied") {
|
|
750
|
-
const prepared = prepareGeminiMisbehavior(misbehavior, completionReq, streaming, chunkSize, logger, require_helpers.resolveStrictMode(defaults.strict, req.headers));
|
|
751
900
|
const entry = journal.add({
|
|
752
901
|
method: req.method ?? "POST",
|
|
753
902
|
path,
|
|
@@ -758,6 +907,8 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
758
907
|
fixture
|
|
759
908
|
}
|
|
760
909
|
});
|
|
910
|
+
const strictReasoning = require_policy.resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
|
|
911
|
+
const prepared = prepareGeminiMisbehavior(misbehavior, completionReq, streaming, chunkSize, logger, strictReasoning);
|
|
761
912
|
require_misbehavior.recordMisbehaviorOutcome({
|
|
762
913
|
entry,
|
|
763
914
|
summary: prepared.summary,
|
|
@@ -765,24 +916,26 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
765
916
|
testId
|
|
766
917
|
});
|
|
767
918
|
if (!streaming) {
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
} else
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
919
|
+
const preparedBody = prepared.chunks[0];
|
|
920
|
+
await require_deliver.deliverJson(res, entry, fixture, () => preparedBody, jsonOpts(require_timing.misbehaviorPayloadLength(misbehavior, misbehaviorPayloadReasoning(misbehavior, completionReq.model, strictReasoning)), !!misbehavior.duplicateId));
|
|
921
|
+
} else await require_deliver.deliverStream(res, entry, fixture, GEMINI_SSE, prepared.chunks, streamTiming);
|
|
922
|
+
return;
|
|
923
|
+
}
|
|
924
|
+
if (require_helpers.isRawResponse(response)) {
|
|
925
|
+
await require_raw.serveRawResponse({
|
|
926
|
+
wire: "gemini",
|
|
927
|
+
stream: streaming,
|
|
928
|
+
req,
|
|
929
|
+
res,
|
|
930
|
+
fixture,
|
|
931
|
+
response,
|
|
932
|
+
body: completionReq,
|
|
933
|
+
journal,
|
|
934
|
+
defaults,
|
|
935
|
+
testId,
|
|
936
|
+
misbehaviorSummary: misbehavior.summary,
|
|
937
|
+
errorWire: "gemini"
|
|
938
|
+
});
|
|
786
939
|
return;
|
|
787
940
|
}
|
|
788
941
|
if (require_helpers.isErrorResponse(response)) {
|
|
@@ -802,16 +955,15 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
802
955
|
defaults,
|
|
803
956
|
testId
|
|
804
957
|
});
|
|
805
|
-
|
|
806
|
-
|
|
958
|
+
require_sse_writer.writeErrorResponse(res, status, require_errors.renderError("gemini", "fixture", {
|
|
959
|
+
bodyCode: status,
|
|
807
960
|
message: response.error.message,
|
|
808
961
|
status: response.error.type ?? "ERROR"
|
|
809
|
-
} };
|
|
810
|
-
require_sse_writer.writeErrorResponse(res, status, JSON.stringify(geminiError), { retryAfter: response.retryAfter });
|
|
962
|
+
}).body, { retryAfter: response.retryAfter });
|
|
811
963
|
return;
|
|
812
964
|
}
|
|
813
965
|
if (require_helpers.isAudioResponse(response)) {
|
|
814
|
-
const effectiveStrict =
|
|
966
|
+
const effectiveStrict = require_policy.resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
|
|
815
967
|
const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, model, effectiveStrict, defaults.logger);
|
|
816
968
|
const journalEntry = journal.add({
|
|
817
969
|
method: req.method ?? "POST",
|
|
@@ -830,33 +982,14 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
830
982
|
testId
|
|
831
983
|
});
|
|
832
984
|
const audioToolCalls = Array.isArray(response.toolCalls) ? require_helpers.requireServedFunctionToolCalls(response, wire) : [];
|
|
833
|
-
if (!streaming)
|
|
834
|
-
|
|
835
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
836
|
-
res.end(JSON.stringify(body));
|
|
837
|
-
} else {
|
|
838
|
-
const chunks = buildGeminiAudioStreamChunks(response, audioToolCalls, logger, effReasoning);
|
|
839
|
-
const interruption = require_interruption.createInterruptionSignal(fixture);
|
|
840
|
-
if (!await writeGeminiSSEStream(res, chunks, {
|
|
841
|
-
latency,
|
|
842
|
-
streamingProfile: fixture.streamingProfile,
|
|
843
|
-
recordedTimings: fixture.recordedTimings,
|
|
844
|
-
replaySpeed,
|
|
845
|
-
signal: interruption?.signal,
|
|
846
|
-
onChunkSent: interruption?.tick
|
|
847
|
-
})) {
|
|
848
|
-
if (!res.writableEnded) res.destroy();
|
|
849
|
-
journalEntry.response.interrupted = true;
|
|
850
|
-
journalEntry.response.interruptReason = interruption?.reason();
|
|
851
|
-
}
|
|
852
|
-
interruption?.cleanup();
|
|
853
|
-
}
|
|
985
|
+
if (!streaming) await require_deliver.deliverJson(res, journalEntry, fixture, () => buildGeminiAudioResponse(response, audioToolCalls, logger, effReasoning), jsonOpts(require_timing.servedPayloadLength(response, effReasoning)));
|
|
986
|
+
else await require_deliver.deliverStream(res, journalEntry, fixture, GEMINI_SSE, buildGeminiAudioStreamChunks(response, audioToolCalls, logger, effReasoning), streamTiming);
|
|
854
987
|
return;
|
|
855
988
|
}
|
|
856
989
|
if (require_helpers.isCombinedFixtureResponse(response)) {
|
|
857
990
|
if (response.webSearches?.length) logger.warn("webSearches in fixture response are not supported for Gemini API — ignoring");
|
|
858
991
|
const overrides = require_helpers.extractOverrides(response);
|
|
859
|
-
const effectiveStrict =
|
|
992
|
+
const effectiveStrict = require_policy.resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
|
|
860
993
|
const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, model, effectiveStrict, defaults.logger);
|
|
861
994
|
const journalEntry = journal.add({
|
|
862
995
|
method: req.method ?? "POST",
|
|
@@ -875,33 +1008,14 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
875
1008
|
testId
|
|
876
1009
|
});
|
|
877
1010
|
const functionToolCalls = require_helpers.requireEmittedFunctionToolCalls(response, wire);
|
|
878
|
-
if (!streaming)
|
|
879
|
-
|
|
880
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
881
|
-
res.end(JSON.stringify(body));
|
|
882
|
-
} else {
|
|
883
|
-
const chunks = buildGeminiContentWithToolCallsStreamChunks(response.content ?? "", functionToolCalls, chunkSize, logger, effReasoning, overrides, response.blocks);
|
|
884
|
-
const interruption = require_interruption.createInterruptionSignal(fixture);
|
|
885
|
-
if (!await writeGeminiSSEStream(res, chunks, {
|
|
886
|
-
latency,
|
|
887
|
-
streamingProfile: fixture.streamingProfile,
|
|
888
|
-
recordedTimings: fixture.recordedTimings,
|
|
889
|
-
replaySpeed,
|
|
890
|
-
signal: interruption?.signal,
|
|
891
|
-
onChunkSent: interruption?.tick
|
|
892
|
-
})) {
|
|
893
|
-
if (!res.writableEnded) res.destroy();
|
|
894
|
-
journalEntry.response.interrupted = true;
|
|
895
|
-
journalEntry.response.interruptReason = interruption?.reason();
|
|
896
|
-
}
|
|
897
|
-
interruption?.cleanup();
|
|
898
|
-
}
|
|
1011
|
+
if (!streaming) await require_deliver.deliverJson(res, journalEntry, fixture, () => buildGeminiContentWithToolCallsResponse(response.content ?? "", functionToolCalls, logger, effReasoning, overrides, response.blocks), jsonOpts(require_timing.servedPayloadLength(response, effReasoning)));
|
|
1012
|
+
else await require_deliver.deliverStream(res, journalEntry, fixture, GEMINI_SSE, buildGeminiContentWithToolCallsStreamChunks(response.content ?? "", functionToolCalls, chunkSize, logger, effReasoning, overrides, response.blocks), streamTiming);
|
|
899
1013
|
return;
|
|
900
1014
|
}
|
|
901
1015
|
if (require_helpers.isTextResponse(response)) {
|
|
902
1016
|
if (response.webSearches?.length) logger.warn("webSearches in fixture response are not supported for Gemini API — ignoring");
|
|
903
1017
|
const overrides = require_helpers.extractOverrides(response);
|
|
904
|
-
const effectiveStrict =
|
|
1018
|
+
const effectiveStrict = require_policy.resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
|
|
905
1019
|
const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, model, effectiveStrict, defaults.logger);
|
|
906
1020
|
const journalEntry = journal.add({
|
|
907
1021
|
method: req.method ?? "POST",
|
|
@@ -919,33 +1033,14 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
919
1033
|
defaults,
|
|
920
1034
|
testId
|
|
921
1035
|
});
|
|
922
|
-
if (!streaming)
|
|
923
|
-
|
|
924
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
925
|
-
res.end(JSON.stringify(body));
|
|
926
|
-
} else {
|
|
927
|
-
const chunks = buildGeminiTextStreamChunks(response.content, chunkSize, effReasoning, overrides);
|
|
928
|
-
const interruption = require_interruption.createInterruptionSignal(fixture);
|
|
929
|
-
if (!await writeGeminiSSEStream(res, chunks, {
|
|
930
|
-
latency,
|
|
931
|
-
streamingProfile: fixture.streamingProfile,
|
|
932
|
-
recordedTimings: fixture.recordedTimings,
|
|
933
|
-
replaySpeed,
|
|
934
|
-
signal: interruption?.signal,
|
|
935
|
-
onChunkSent: interruption?.tick
|
|
936
|
-
})) {
|
|
937
|
-
if (!res.writableEnded) res.destroy();
|
|
938
|
-
journalEntry.response.interrupted = true;
|
|
939
|
-
journalEntry.response.interruptReason = interruption?.reason();
|
|
940
|
-
}
|
|
941
|
-
interruption?.cleanup();
|
|
942
|
-
}
|
|
1036
|
+
if (!streaming) await require_deliver.deliverJson(res, journalEntry, fixture, () => buildGeminiTextResponse(response.content, effReasoning, overrides), jsonOpts(require_timing.servedPayloadLength(response, effReasoning)));
|
|
1037
|
+
else await require_deliver.deliverStream(res, journalEntry, fixture, GEMINI_SSE, buildGeminiTextStreamChunks(response.content, chunkSize, effReasoning, overrides), streamTiming);
|
|
943
1038
|
return;
|
|
944
1039
|
}
|
|
945
1040
|
if (require_helpers.isToolCallResponse(response)) {
|
|
946
1041
|
if (response.webSearches?.length) logger.warn("webSearches in fixture response are not supported for Gemini API — ignoring");
|
|
947
1042
|
const overrides = require_helpers.extractOverrides(response);
|
|
948
|
-
const effectiveStrict =
|
|
1043
|
+
const effectiveStrict = require_policy.resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
|
|
949
1044
|
const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, model, effectiveStrict, defaults.logger);
|
|
950
1045
|
const journalEntry = journal.add({
|
|
951
1046
|
method: req.method ?? "POST",
|
|
@@ -964,27 +1059,8 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
964
1059
|
testId
|
|
965
1060
|
});
|
|
966
1061
|
const functionToolCalls = require_helpers.requireEmittedFunctionToolCalls(response, wire);
|
|
967
|
-
if (!streaming)
|
|
968
|
-
|
|
969
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
970
|
-
res.end(JSON.stringify(body));
|
|
971
|
-
} else {
|
|
972
|
-
const chunks = buildGeminiToolCallStreamChunks(functionToolCalls, chunkSize, logger, effReasoning, overrides);
|
|
973
|
-
const interruption = require_interruption.createInterruptionSignal(fixture);
|
|
974
|
-
if (!await writeGeminiSSEStream(res, chunks, {
|
|
975
|
-
latency,
|
|
976
|
-
streamingProfile: fixture.streamingProfile,
|
|
977
|
-
recordedTimings: fixture.recordedTimings,
|
|
978
|
-
replaySpeed,
|
|
979
|
-
signal: interruption?.signal,
|
|
980
|
-
onChunkSent: interruption?.tick
|
|
981
|
-
})) {
|
|
982
|
-
if (!res.writableEnded) res.destroy();
|
|
983
|
-
journalEntry.response.interrupted = true;
|
|
984
|
-
journalEntry.response.interruptReason = interruption?.reason();
|
|
985
|
-
}
|
|
986
|
-
interruption?.cleanup();
|
|
987
|
-
}
|
|
1062
|
+
if (!streaming) await require_deliver.deliverJson(res, journalEntry, fixture, () => buildGeminiToolCallResponse(functionToolCalls, logger, effReasoning, overrides), jsonOpts(require_timing.servedPayloadLength(response, effReasoning)));
|
|
1063
|
+
else await require_deliver.deliverStream(res, journalEntry, fixture, GEMINI_SSE, buildGeminiToolCallStreamChunks(functionToolCalls, chunkSize, logger, effReasoning, overrides), streamTiming);
|
|
988
1064
|
return;
|
|
989
1065
|
}
|
|
990
1066
|
require_misbehavior.recordMisbehaviorOutcome({
|
|
@@ -1002,13 +1078,14 @@ async function handleGemini(req, res, raw, model, streaming, fixtures, journal,
|
|
|
1002
1078
|
defaults,
|
|
1003
1079
|
testId
|
|
1004
1080
|
});
|
|
1005
|
-
require_sse_writer.writeErrorResponse(res, 500,
|
|
1081
|
+
require_sse_writer.writeErrorResponse(res, 500, require_errors.renderError("gemini", "unknown-response", {
|
|
1006
1082
|
message: "Fixture response did not match any known type",
|
|
1007
|
-
|
|
1083
|
+
bodyCode: 500,
|
|
1008
1084
|
status: "INTERNAL"
|
|
1009
|
-
}
|
|
1085
|
+
}).body);
|
|
1010
1086
|
}
|
|
1011
1087
|
|
|
1012
1088
|
//#endregion
|
|
1089
|
+
exports.geminiToCompletionRequest = geminiToCompletionRequest;
|
|
1013
1090
|
exports.handleGemini = handleGemini;
|
|
1014
1091
|
//# sourceMappingURL=gemini.cjs.map
|