@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/responses.cjs
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
const require_runtime = require('./_virtual/_rolldown/runtime.cjs');
|
|
2
|
+
const require_errors = require('./response/errors.cjs');
|
|
2
3
|
const require_model_utils = require('./model-utils.cjs');
|
|
4
|
+
const require_policy = require('./response/policy.cjs');
|
|
3
5
|
const require_helpers = require('./helpers.cjs');
|
|
4
6
|
const require_sse_writer = require('./sse-writer.cjs');
|
|
5
7
|
const require_chaos = require('./chaos.cjs');
|
|
6
8
|
const require_misbehavior = require('./misbehavior.cjs');
|
|
7
9
|
const require_router = require('./router.cjs');
|
|
8
10
|
const require_recorder = require('./recorder.cjs');
|
|
9
|
-
const
|
|
11
|
+
const require_timing = require('./response/timing.cjs');
|
|
12
|
+
const require_deliver = require('./response/deliver.cjs');
|
|
13
|
+
const require_proxy = require('./response/proxy.cjs');
|
|
14
|
+
const require_raw = require('./response/raw.cjs');
|
|
15
|
+
const require_responses = require('./response/usage/codecs/responses.cjs');
|
|
16
|
+
const require_finish = require('./response/finish.cjs');
|
|
10
17
|
let node_crypto = require("node:crypto");
|
|
11
18
|
|
|
12
19
|
//#region src/responses.ts
|
|
@@ -311,25 +318,7 @@ function validateResponsesTools(tools) {
|
|
|
311
318
|
}
|
|
312
319
|
function responsesStatus(finishReason, defaultStatus) {
|
|
313
320
|
if (!finishReason) return defaultStatus;
|
|
314
|
-
|
|
315
|
-
if (finishReason === "tool_calls") return "completed";
|
|
316
|
-
if (finishReason === "length") return "incomplete";
|
|
317
|
-
if (finishReason === "content_filter") return "failed";
|
|
318
|
-
return finishReason;
|
|
319
|
-
}
|
|
320
|
-
function responsesUsage(overrides) {
|
|
321
|
-
if (!overrides?.usage) return {
|
|
322
|
-
input_tokens: 0,
|
|
323
|
-
output_tokens: 0,
|
|
324
|
-
total_tokens: 0
|
|
325
|
-
};
|
|
326
|
-
const input = overrides.usage.input_tokens ?? overrides.usage.prompt_tokens ?? 0;
|
|
327
|
-
const output = overrides.usage.output_tokens ?? overrides.usage.completion_tokens ?? 0;
|
|
328
|
-
return {
|
|
329
|
-
input_tokens: input,
|
|
330
|
-
output_tokens: output,
|
|
331
|
-
total_tokens: overrides.usage.total_tokens ?? input + output
|
|
332
|
-
};
|
|
321
|
+
return require_finish.mapResponsesFinish(finishReason);
|
|
333
322
|
}
|
|
334
323
|
function responseId() {
|
|
335
324
|
return require_helpers.generateId("resp");
|
|
@@ -339,7 +328,7 @@ function itemId() {
|
|
|
339
328
|
}
|
|
340
329
|
function buildTextStreamEvents(content, model, chunkSize, reasoning, webSearches, overrides, emitEncryptedReasoning = false, synthesizeSummarylessReasoning = false) {
|
|
341
330
|
const { respId, created, events, prefixOutputItems, nextOutputIndex } = buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrides, emitEncryptedReasoning, synthesizeSummarylessReasoning);
|
|
342
|
-
const { events: msgEvents, msgItem } = buildMessageOutputEvents(content, chunkSize, nextOutputIndex);
|
|
331
|
+
const { events: msgEvents, msgItem } = buildMessageOutputEvents(content, chunkSize, nextOutputIndex, overrides?.phase, buildAnnotations(content, overrides?.citations));
|
|
343
332
|
events.push(...msgEvents);
|
|
344
333
|
events.push({
|
|
345
334
|
type: "response.completed",
|
|
@@ -350,7 +339,7 @@ function buildTextStreamEvents(content, model, chunkSize, reasoning, webSearches
|
|
|
350
339
|
model: overrides?.model ?? model,
|
|
351
340
|
status: responsesStatus(overrides?.finishReason, "completed"),
|
|
352
341
|
output: [...prefixOutputItems, msgItem],
|
|
353
|
-
usage:
|
|
342
|
+
usage: require_responses.render(overrides)
|
|
354
343
|
}
|
|
355
344
|
});
|
|
356
345
|
return events;
|
|
@@ -448,6 +437,7 @@ function buildToolCallStreamEvents(toolCalls, model, chunkSize, reasoning, webSe
|
|
|
448
437
|
}
|
|
449
438
|
function toolCallStreamEvents(toolCalls, model, chunkSize, reasoning, webSearches, overrides, emitEncryptedReasoning = false, synthesizeSummarylessReasoning = false) {
|
|
450
439
|
require_helpers.assertResponsesToolCalls(toolCalls);
|
|
440
|
+
require_helpers.fixtureCitations("", overrides?.citations);
|
|
451
441
|
const { respId, created, events, prefixOutputItems, nextOutputIndex } = buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrides, emitEncryptedReasoning, synthesizeSummarylessReasoning);
|
|
452
442
|
const fcOutputItems = [];
|
|
453
443
|
for (let idx = 0; idx < toolCalls.length; idx++) {
|
|
@@ -464,7 +454,7 @@ function toolCallStreamEvents(toolCalls, model, chunkSize, reasoning, webSearche
|
|
|
464
454
|
model: overrides?.model ?? model,
|
|
465
455
|
status: responsesStatus(overrides?.finishReason, "completed"),
|
|
466
456
|
output: [...prefixOutputItems, ...fcOutputItems],
|
|
467
|
-
usage:
|
|
457
|
+
usage: require_responses.render(overrides)
|
|
468
458
|
}
|
|
469
459
|
});
|
|
470
460
|
return events;
|
|
@@ -684,6 +674,79 @@ function buildWebSearchStreamEvents(queries, startOutputIndex) {
|
|
|
684
674
|
}
|
|
685
675
|
return events;
|
|
686
676
|
}
|
|
677
|
+
/**
|
|
678
|
+
* A Responses `image_generation_call` output item for one fixture file (see
|
|
679
|
+
* `ResponseOutputItem.ImageGenerationCall` in the openai SDK): `result` holds
|
|
680
|
+
* the base64 bytes once completed and is null while in progress.
|
|
681
|
+
*/
|
|
682
|
+
function imageGenerationCallItem(id, file, status) {
|
|
683
|
+
return {
|
|
684
|
+
type: "image_generation_call",
|
|
685
|
+
id,
|
|
686
|
+
status,
|
|
687
|
+
result: status === "completed" ? file.data : null
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* A fixture file that is not `image/*` reached the Responses API, which
|
|
692
|
+
* carries generated files only as `image_generation_call` items. Surfaces as
|
|
693
|
+
* the same coded 500 (`aimock_unsupported_generated_file`), naming `mimeType`.
|
|
694
|
+
*/
|
|
695
|
+
var NonImageGeneratedFileError = class extends require_helpers.UnsupportedGeneratedFileError {
|
|
696
|
+
constructor(mimeType) {
|
|
697
|
+
super("the OpenAI Responses API");
|
|
698
|
+
this.message = `aimock: fixture "files" on the OpenAI Responses API carry only image/* files (as image_generation_call items); got mimeType "${mimeType}"`;
|
|
699
|
+
}
|
|
700
|
+
};
|
|
701
|
+
/**
|
|
702
|
+
* Throw {@link NonImageGeneratedFileError} for the first fixture file whose
|
|
703
|
+
* `mimeType` is not `image/*`. Called before any output item is built, so
|
|
704
|
+
* nothing reaches the client.
|
|
705
|
+
*/
|
|
706
|
+
function requireImageFiles(files) {
|
|
707
|
+
const nonImage = files.find((f) => !f.mimeType.toLowerCase().startsWith("image/"));
|
|
708
|
+
if (nonImage) throw new NonImageGeneratedFileError(nonImage.mimeType);
|
|
709
|
+
}
|
|
710
|
+
/** Fixture `files` as completed `image_generation_call` items (non-streaming). */
|
|
711
|
+
function imageGenerationCallItems(files) {
|
|
712
|
+
const validated = require_helpers.fixtureFiles(files);
|
|
713
|
+
requireImageFiles(validated);
|
|
714
|
+
return validated.map((f) => imageGenerationCallItem(require_helpers.generateId("ig"), f, "completed"));
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* Streamed form of {@link imageGenerationCallItems}: per file, the item's
|
|
718
|
+
* `output_item.added`, the `image_generation_call` `in_progress`,
|
|
719
|
+
* `generating` and `completed` events, then `output_item.done` carrying the
|
|
720
|
+
* completed item.
|
|
721
|
+
*/
|
|
722
|
+
function buildImageGenerationStreamEvents(files, startOutputIndex) {
|
|
723
|
+
requireImageFiles(files);
|
|
724
|
+
const events = [];
|
|
725
|
+
files.forEach((file, i) => {
|
|
726
|
+
const id = require_helpers.generateId("ig");
|
|
727
|
+
const outputIndex = startOutputIndex + i;
|
|
728
|
+
events.push({
|
|
729
|
+
type: "response.output_item.added",
|
|
730
|
+
output_index: outputIndex,
|
|
731
|
+
item: imageGenerationCallItem(id, file, "in_progress")
|
|
732
|
+
});
|
|
733
|
+
for (const phase of [
|
|
734
|
+
"in_progress",
|
|
735
|
+
"generating",
|
|
736
|
+
"completed"
|
|
737
|
+
]) events.push({
|
|
738
|
+
type: `response.image_generation_call.${phase}`,
|
|
739
|
+
output_index: outputIndex,
|
|
740
|
+
item_id: id
|
|
741
|
+
});
|
|
742
|
+
events.push({
|
|
743
|
+
type: "response.output_item.done",
|
|
744
|
+
output_index: outputIndex,
|
|
745
|
+
item: imageGenerationCallItem(id, file, "completed")
|
|
746
|
+
});
|
|
747
|
+
});
|
|
748
|
+
return events;
|
|
749
|
+
}
|
|
687
750
|
function buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrides, emitEncryptedReasoning = false, synthesizeSummarylessReasoning = false, forceReasoning = false) {
|
|
688
751
|
const respId = overrides?.id ?? responseId();
|
|
689
752
|
const created = overrides?.created ?? Math.floor(Date.now() / 1e3);
|
|
@@ -727,6 +790,13 @@ function buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrid
|
|
|
727
790
|
for (const de of doneEvents) prefixOutputItems.push(de.item);
|
|
728
791
|
nextOutputIndex += webSearches.length;
|
|
729
792
|
}
|
|
793
|
+
const files = require_helpers.fixtureFiles(overrides?.files);
|
|
794
|
+
if (files.length > 0) {
|
|
795
|
+
const fileEvents = buildImageGenerationStreamEvents(files, nextOutputIndex);
|
|
796
|
+
events.push(...fileEvents);
|
|
797
|
+
for (const e of fileEvents) if (e.type === "response.output_item.done") prefixOutputItems.push(e.item);
|
|
798
|
+
nextOutputIndex += files.length;
|
|
799
|
+
}
|
|
730
800
|
return {
|
|
731
801
|
respId,
|
|
732
802
|
created,
|
|
@@ -735,7 +805,84 @@ function buildResponsePreamble(model, chunkSize, reasoning, webSearches, overrid
|
|
|
735
805
|
nextOutputIndex
|
|
736
806
|
};
|
|
737
807
|
}
|
|
738
|
-
|
|
808
|
+
/**
|
|
809
|
+
* Fixture `citations` as `output_text` annotations for each text in `texts`
|
|
810
|
+
* (one per message item), in fixture order: a URL citation becomes
|
|
811
|
+
* `url_citation`, a file citation (`type: "file"`) becomes `file_citation`
|
|
812
|
+
* (`file_id`, `filename`, `index`; see `ResponseOutputText.FileCitation` in
|
|
813
|
+
* the openai SDK). Offsets index the joined text of all texts, as on every
|
|
814
|
+
* other provider. A URL citation is a range and goes only to the text holding
|
|
815
|
+
* its `startIndex`. A file citation is a point after the cited text, so it
|
|
816
|
+
* goes to the last text starting before its `index`: an `index` equal to a
|
|
817
|
+
* text's end stays at the end of that text (not at 0 of the next text), and
|
|
818
|
+
* an `index` of 0 goes to the first text. Each citation is rebased onto its
|
|
819
|
+
* text since Responses offsets are per `output_text`, with `end_index`
|
|
820
|
+
* clamped to it. Anthropic and Gemini need no point rule: they have no file
|
|
821
|
+
* citation. Anthropic URL citations follow the same start-owns-range rule;
|
|
822
|
+
* Gemini does not, and splits a citation that spans several text parts into
|
|
823
|
+
* one grounding support per part (see geminiGroundingSupports).
|
|
824
|
+
* Missing offsets take the defaults `resolveCitations` applies: a URL
|
|
825
|
+
* citation starts at 0 and ends at the end of the joined text, so one without
|
|
826
|
+
* offsets goes on the first text and covers all of it; a file citation's
|
|
827
|
+
* `index` defaults to the end of the joined text (the last text).
|
|
828
|
+
*/
|
|
829
|
+
function blockAnnotations(texts, citations) {
|
|
830
|
+
const perText = texts.map(() => []);
|
|
831
|
+
if (texts.length === 0) {
|
|
832
|
+
require_helpers.fixtureCitations("", citations);
|
|
833
|
+
return perText;
|
|
834
|
+
}
|
|
835
|
+
const starts = [];
|
|
836
|
+
let offset = 0;
|
|
837
|
+
for (const text of texts) {
|
|
838
|
+
starts.push(offset);
|
|
839
|
+
offset += text.length;
|
|
840
|
+
}
|
|
841
|
+
const joinedLength = offset;
|
|
842
|
+
const ownerOf = (start) => {
|
|
843
|
+
let owner = 0;
|
|
844
|
+
for (let k = 1; k < starts.length; k++) if (starts[k] <= start) owner = k;
|
|
845
|
+
return owner;
|
|
846
|
+
};
|
|
847
|
+
const pointOwnerOf = (index) => {
|
|
848
|
+
let owner = 0;
|
|
849
|
+
for (let k = 1; k < starts.length; k++) if (starts[k] < index) owner = k;
|
|
850
|
+
return owner;
|
|
851
|
+
};
|
|
852
|
+
for (const c of require_helpers.fixtureCitations(texts.join(""), citations)) {
|
|
853
|
+
if (c.type === "file") {
|
|
854
|
+
const index = c.index ?? joinedLength;
|
|
855
|
+
const owner = pointOwnerOf(index);
|
|
856
|
+
perText[owner].push({
|
|
857
|
+
type: "file_citation",
|
|
858
|
+
file_id: c.fileId,
|
|
859
|
+
filename: c.filename,
|
|
860
|
+
index: index - starts[owner]
|
|
861
|
+
});
|
|
862
|
+
continue;
|
|
863
|
+
}
|
|
864
|
+
const start = c.startIndex ?? 0;
|
|
865
|
+
const end = c.endIndex ?? joinedLength;
|
|
866
|
+
const owner = ownerOf(start);
|
|
867
|
+
perText[owner].push({
|
|
868
|
+
type: "url_citation",
|
|
869
|
+
url: c.url,
|
|
870
|
+
title: c.title ?? c.url,
|
|
871
|
+
start_index: start - starts[owner],
|
|
872
|
+
end_index: Math.min(end - starts[owner], texts[owner].length)
|
|
873
|
+
});
|
|
874
|
+
}
|
|
875
|
+
return perText;
|
|
876
|
+
}
|
|
877
|
+
/** {@link blockAnnotations} for a turn with a single text. */
|
|
878
|
+
function buildAnnotations(content, citations) {
|
|
879
|
+
return blockAnnotations([content], citations)[0];
|
|
880
|
+
}
|
|
881
|
+
/** The annotations of each text block in `blocks`, in block order. */
|
|
882
|
+
function orderedBlockAnnotations(blocks, citations) {
|
|
883
|
+
return blockAnnotations(blocks.flatMap((b) => b.type === "text" ? [b.text] : []), citations);
|
|
884
|
+
}
|
|
885
|
+
function buildMessageOutputEvents(content, chunkSize, outputIndex, phase, annotations) {
|
|
739
886
|
const msgId = itemId();
|
|
740
887
|
const events = [];
|
|
741
888
|
events.push({
|
|
@@ -746,6 +893,7 @@ function buildMessageOutputEvents(content, chunkSize, outputIndex) {
|
|
|
746
893
|
id: msgId,
|
|
747
894
|
status: "in_progress",
|
|
748
895
|
role: "assistant",
|
|
896
|
+
...phase !== void 0 ? { phase } : {},
|
|
749
897
|
content: []
|
|
750
898
|
}
|
|
751
899
|
});
|
|
@@ -774,6 +922,16 @@ function buildMessageOutputEvents(content, chunkSize, outputIndex) {
|
|
|
774
922
|
content_index: 0,
|
|
775
923
|
text: content
|
|
776
924
|
});
|
|
925
|
+
annotations.forEach((annotation, annotationIndex) => {
|
|
926
|
+
events.push({
|
|
927
|
+
type: "response.output_text.annotation.added",
|
|
928
|
+
item_id: msgId,
|
|
929
|
+
output_index: outputIndex,
|
|
930
|
+
content_index: 0,
|
|
931
|
+
annotation_index: annotationIndex,
|
|
932
|
+
annotation
|
|
933
|
+
});
|
|
934
|
+
});
|
|
777
935
|
events.push({
|
|
778
936
|
type: "response.content_part.done",
|
|
779
937
|
item_id: msgId,
|
|
@@ -782,7 +940,7 @@ function buildMessageOutputEvents(content, chunkSize, outputIndex) {
|
|
|
782
940
|
part: {
|
|
783
941
|
type: "output_text",
|
|
784
942
|
text: content,
|
|
785
|
-
annotations
|
|
943
|
+
annotations
|
|
786
944
|
}
|
|
787
945
|
});
|
|
788
946
|
const msgItem = {
|
|
@@ -790,10 +948,11 @@ function buildMessageOutputEvents(content, chunkSize, outputIndex) {
|
|
|
790
948
|
id: msgId,
|
|
791
949
|
status: "completed",
|
|
792
950
|
role: "assistant",
|
|
951
|
+
...phase !== void 0 ? { phase } : {},
|
|
793
952
|
content: [{
|
|
794
953
|
type: "output_text",
|
|
795
954
|
text: content,
|
|
796
|
-
annotations
|
|
955
|
+
annotations
|
|
797
956
|
}]
|
|
798
957
|
};
|
|
799
958
|
events.push({
|
|
@@ -848,24 +1007,6 @@ function buildFunctionCallOutputEvents(toolCall, chunkSize, outputIndex) {
|
|
|
848
1007
|
};
|
|
849
1008
|
}
|
|
850
1009
|
/**
|
|
851
|
-
* `text` cut into slices of at most `chunkSize` UTF-16 units, never between
|
|
852
|
-
* the two halves of a surrogate pair: a cut that would land inside a pair
|
|
853
|
-
* moves back before it, or, when that would leave the slice empty
|
|
854
|
-
* (`chunkSize` 1), forward past it. The slices rejoin to `text` exactly.
|
|
855
|
-
*/
|
|
856
|
-
function surrogateSafeChunks(text, chunkSize) {
|
|
857
|
-
const chunks = [];
|
|
858
|
-
for (let i = 0; i < text.length;) {
|
|
859
|
-
let end = Math.min(i + chunkSize, text.length);
|
|
860
|
-
const high = text.charCodeAt(end - 1);
|
|
861
|
-
const low = text.charCodeAt(end);
|
|
862
|
-
if (high >= 55296 && high <= 56319 && low >= 56320 && low <= 57343) end = end - 1 > i ? end - 1 : end + 1;
|
|
863
|
-
chunks.push(text.slice(i, end));
|
|
864
|
-
i = end;
|
|
865
|
-
}
|
|
866
|
-
return chunks;
|
|
867
|
-
}
|
|
868
|
-
/**
|
|
869
1010
|
* Emit output_item.added → custom_tool_call_input.delta×N →
|
|
870
1011
|
* custom_tool_call_input.done → output_item.done for one `custom_tool_call` at
|
|
871
1012
|
* `outputIndex`, returning the completed item. An empty `input`
|
|
@@ -881,7 +1022,7 @@ function buildCustomToolCallOutputEvents(call, chunkSize, outputIndex) {
|
|
|
881
1022
|
output_index: outputIndex,
|
|
882
1023
|
item: customToolCallItem(call, ctcId, callId, "", "in_progress")
|
|
883
1024
|
});
|
|
884
|
-
for (const delta of surrogateSafeChunks(input, chunkSize)) events.push({
|
|
1025
|
+
for (const delta of require_helpers.surrogateSafeChunks(input, chunkSize)) events.push({
|
|
885
1026
|
type: "response.custom_tool_call_input.delta",
|
|
886
1027
|
item_id: ctcId,
|
|
887
1028
|
output_index: outputIndex,
|
|
@@ -908,7 +1049,7 @@ function buildCustomToolCallOutputEvents(call, chunkSize, outputIndex) {
|
|
|
908
1049
|
function buildToolCallOutputEvents(call, chunkSize, outputIndex) {
|
|
909
1050
|
return isCustomEmittable(call) ? buildCustomToolCallOutputEvents(call, chunkSize, outputIndex) : buildFunctionCallOutputEvents(call, chunkSize, outputIndex);
|
|
910
1051
|
}
|
|
911
|
-
function buildOutputPrefix(content, model, reasoning, webSearches, emitEncryptedReasoning = false, synthesizeSummarylessReasoning = false) {
|
|
1052
|
+
function buildOutputPrefix(content, model, reasoning, webSearches, emitEncryptedReasoning = false, synthesizeSummarylessReasoning = false, phase, citations, files) {
|
|
912
1053
|
const output = [];
|
|
913
1054
|
if (reasoning || shouldSynthesizeBlobOnlyReasoning(reasoning, model, synthesizeSummarylessReasoning)) output.push(buildReasoningOutputItem(require_helpers.generateId("rs"), {
|
|
914
1055
|
summaryText: reasoning,
|
|
@@ -923,15 +1064,17 @@ function buildOutputPrefix(content, model, reasoning, webSearches, emitEncrypted
|
|
|
923
1064
|
query
|
|
924
1065
|
}
|
|
925
1066
|
});
|
|
1067
|
+
output.push(...imageGenerationCallItems(files));
|
|
926
1068
|
output.push({
|
|
927
1069
|
type: "message",
|
|
928
1070
|
id: itemId(),
|
|
929
1071
|
status: "completed",
|
|
930
1072
|
role: "assistant",
|
|
1073
|
+
...phase !== void 0 ? { phase } : {},
|
|
931
1074
|
content: [{
|
|
932
1075
|
type: "output_text",
|
|
933
1076
|
text: content,
|
|
934
|
-
annotations:
|
|
1077
|
+
annotations: buildAnnotations(content, citations)
|
|
935
1078
|
}]
|
|
936
1079
|
});
|
|
937
1080
|
return output;
|
|
@@ -944,14 +1087,15 @@ function buildResponseEnvelope(model, output, overrides) {
|
|
|
944
1087
|
model: overrides?.model ?? model,
|
|
945
1088
|
status: responsesStatus(overrides?.finishReason, "completed"),
|
|
946
1089
|
output,
|
|
947
|
-
usage:
|
|
1090
|
+
usage: require_responses.render(overrides)
|
|
948
1091
|
};
|
|
949
1092
|
}
|
|
950
1093
|
function buildTextResponse(content, model, reasoning, webSearches, overrides, emitEncryptedReasoning = false, synthesizeSummarylessReasoning = false) {
|
|
951
|
-
return buildResponseEnvelope(model, buildOutputPrefix(content, model, reasoning, webSearches, emitEncryptedReasoning, synthesizeSummarylessReasoning), overrides);
|
|
1094
|
+
return buildResponseEnvelope(model, buildOutputPrefix(content, model, reasoning, webSearches, emitEncryptedReasoning, synthesizeSummarylessReasoning, overrides?.phase, overrides?.citations, overrides?.files), overrides);
|
|
952
1095
|
}
|
|
953
1096
|
function buildToolCallResponse(toolCalls, model, reasoning, webSearches, overrides, emitEncryptedReasoning = false, synthesizeSummarylessReasoning = false) {
|
|
954
1097
|
require_helpers.assertResponsesToolCalls(toolCalls);
|
|
1098
|
+
require_helpers.fixtureCitations("", overrides?.citations);
|
|
955
1099
|
const output = [];
|
|
956
1100
|
if (reasoning || shouldSynthesizeBlobOnlyReasoning(reasoning, model, synthesizeSummarylessReasoning)) output.push(buildReasoningOutputItem(require_helpers.generateId("rs"), {
|
|
957
1101
|
summaryText: reasoning,
|
|
@@ -966,6 +1110,7 @@ function buildToolCallResponse(toolCalls, model, reasoning, webSearches, overrid
|
|
|
966
1110
|
query
|
|
967
1111
|
}
|
|
968
1112
|
});
|
|
1113
|
+
output.push(...imageGenerationCallItems(overrides?.files));
|
|
969
1114
|
for (const tc of toolCalls) output.push(buildToolCallOutputItem(tc));
|
|
970
1115
|
return buildResponseEnvelope(model, output, overrides);
|
|
971
1116
|
}
|
|
@@ -983,9 +1128,11 @@ function contentWithToolCallsStreamEvents(content, toolCalls, model, chunkSize,
|
|
|
983
1128
|
const orderedOutputItems = [];
|
|
984
1129
|
if (ordered && ordered.length > 0) {
|
|
985
1130
|
let outputIndex = nextOutputIndex;
|
|
1131
|
+
const textAnnotations = orderedBlockAnnotations(ordered, overrides?.citations);
|
|
1132
|
+
let textPos = 0;
|
|
986
1133
|
for (const block of ordered) {
|
|
987
1134
|
if (block.type === "text") {
|
|
988
|
-
const { events: msgEvents, msgItem } = buildMessageOutputEvents(block.text, chunkSize, outputIndex);
|
|
1135
|
+
const { events: msgEvents, msgItem } = buildMessageOutputEvents(block.text, chunkSize, outputIndex, overrides?.phase, textAnnotations[textPos++]);
|
|
989
1136
|
events.push(...msgEvents);
|
|
990
1137
|
orderedOutputItems.push(msgItem);
|
|
991
1138
|
} else {
|
|
@@ -997,7 +1144,7 @@ function contentWithToolCallsStreamEvents(content, toolCalls, model, chunkSize,
|
|
|
997
1144
|
}
|
|
998
1145
|
} else {
|
|
999
1146
|
require_helpers.assertResponsesToolCalls(toolCalls);
|
|
1000
|
-
const { events: msgEvents, msgItem } = buildMessageOutputEvents(content, chunkSize, nextOutputIndex);
|
|
1147
|
+
const { events: msgEvents, msgItem } = buildMessageOutputEvents(content, chunkSize, nextOutputIndex, overrides?.phase, buildAnnotations(content, overrides?.citations));
|
|
1001
1148
|
events.push(...msgEvents);
|
|
1002
1149
|
orderedOutputItems.push(msgItem);
|
|
1003
1150
|
for (let idx = 0; idx < toolCalls.length; idx++) {
|
|
@@ -1015,7 +1162,7 @@ function contentWithToolCallsStreamEvents(content, toolCalls, model, chunkSize,
|
|
|
1015
1162
|
model: overrides?.model ?? model,
|
|
1016
1163
|
status: responsesStatus(overrides?.finishReason, "completed"),
|
|
1017
1164
|
output: [...prefixOutputItems, ...orderedOutputItems],
|
|
1018
|
-
usage:
|
|
1165
|
+
usage: require_responses.render(overrides)
|
|
1019
1166
|
}
|
|
1020
1167
|
});
|
|
1021
1168
|
return events;
|
|
@@ -1025,16 +1172,17 @@ function buildToolCallOutputItem(tc) {
|
|
|
1025
1172
|
if (isCustomEmittable(tc)) return customToolCallItem(tc, customToolCallItemId(), tc.id || require_helpers.generateToolCallId(), requireFixtureToolInput(tc.input), "completed");
|
|
1026
1173
|
return functionCallItem(tc, require_helpers.generateId("fc"), tc.id || require_helpers.generateToolCallId(), requireFixtureToolArguments(tc.arguments), "completed");
|
|
1027
1174
|
}
|
|
1028
|
-
function buildMessageOutputItem(content) {
|
|
1175
|
+
function buildMessageOutputItem(content, phase, annotations) {
|
|
1029
1176
|
return {
|
|
1030
1177
|
type: "message",
|
|
1031
1178
|
id: itemId(),
|
|
1032
1179
|
status: "completed",
|
|
1033
1180
|
role: "assistant",
|
|
1181
|
+
...phase !== void 0 ? { phase } : {},
|
|
1034
1182
|
content: [{
|
|
1035
1183
|
type: "output_text",
|
|
1036
1184
|
text: content,
|
|
1037
|
-
annotations
|
|
1185
|
+
annotations
|
|
1038
1186
|
}]
|
|
1039
1187
|
};
|
|
1040
1188
|
}
|
|
@@ -1054,40 +1202,18 @@ function buildContentWithToolCallsResponse(content, toolCalls, model, reasoning,
|
|
|
1054
1202
|
query
|
|
1055
1203
|
}
|
|
1056
1204
|
});
|
|
1057
|
-
|
|
1205
|
+
output.push(...imageGenerationCallItems(overrides?.files));
|
|
1206
|
+
const textAnnotations = orderedBlockAnnotations(ordered, overrides?.citations);
|
|
1207
|
+
let textPos = 0;
|
|
1208
|
+
for (const block of ordered) if (block.type === "text") output.push(buildMessageOutputItem(block.text, overrides?.phase, textAnnotations[textPos++]));
|
|
1058
1209
|
else output.push(buildToolCallOutputItem(block));
|
|
1059
1210
|
return buildResponseEnvelope(model, output, overrides);
|
|
1060
1211
|
}
|
|
1061
1212
|
require_helpers.assertResponsesToolCalls(toolCalls);
|
|
1062
|
-
const output = buildOutputPrefix(content, model, reasoning, webSearches, emitEncryptedReasoning, synthesizeSummarylessReasoning);
|
|
1213
|
+
const output = buildOutputPrefix(content, model, reasoning, webSearches, emitEncryptedReasoning, synthesizeSummarylessReasoning, overrides?.phase, overrides?.citations, overrides?.files);
|
|
1063
1214
|
for (const tc of toolCalls) output.push(buildToolCallOutputItem(tc));
|
|
1064
1215
|
return buildResponseEnvelope(model, output, overrides);
|
|
1065
1216
|
}
|
|
1066
|
-
async function writeResponsesSSEStream(res, events, optionsOrLatency) {
|
|
1067
|
-
const opts = typeof optionsOrLatency === "number" ? { latency: optionsOrLatency } : optionsOrLatency ?? {};
|
|
1068
|
-
const latency = opts.latency ?? 0;
|
|
1069
|
-
const profile = opts.streamingProfile;
|
|
1070
|
-
const { recordedTimings, replaySpeed } = opts;
|
|
1071
|
-
const signal = opts.signal;
|
|
1072
|
-
const onChunkSent = opts.onChunkSent;
|
|
1073
|
-
if (res.writableEnded) return true;
|
|
1074
|
-
res.setHeader("Content-Type", "text/event-stream");
|
|
1075
|
-
res.setHeader("Cache-Control", "no-cache");
|
|
1076
|
-
res.setHeader("Connection", "keep-alive");
|
|
1077
|
-
let chunkIndex = 0;
|
|
1078
|
-
for (const event of events) {
|
|
1079
|
-
const chunkDelay = require_sse_writer.calculateDelay(chunkIndex, profile, latency, recordedTimings, replaySpeed);
|
|
1080
|
-
if (chunkDelay > 0) await require_sse_writer.delay(chunkDelay, signal);
|
|
1081
|
-
if (signal?.aborted) return false;
|
|
1082
|
-
if (res.writableEnded) return true;
|
|
1083
|
-
res.write(`event: ${event.type}\ndata: ${JSON.stringify(event)}\n\n`);
|
|
1084
|
-
onChunkSent?.();
|
|
1085
|
-
if (signal?.aborted) return false;
|
|
1086
|
-
chunkIndex++;
|
|
1087
|
-
}
|
|
1088
|
-
if (!res.writableEnded) res.end();
|
|
1089
|
-
return true;
|
|
1090
|
-
}
|
|
1091
1217
|
async function handleResponses(req, res, raw, fixtures, journal, defaults, setCorsHeaders) {
|
|
1092
1218
|
setCorsHeaders(res);
|
|
1093
1219
|
let responsesReq;
|
|
@@ -1105,11 +1231,11 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
|
|
|
1105
1231
|
fixture: null
|
|
1106
1232
|
}
|
|
1107
1233
|
});
|
|
1108
|
-
require_sse_writer.writeErrorResponse(res, 400,
|
|
1234
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "validation", {
|
|
1109
1235
|
message: `Malformed JSON: ${detail}`,
|
|
1110
1236
|
type: "invalid_request_error",
|
|
1111
1237
|
code: "invalid_json"
|
|
1112
|
-
}
|
|
1238
|
+
}).body);
|
|
1113
1239
|
return;
|
|
1114
1240
|
}
|
|
1115
1241
|
if (!require_helpers.isJsonObject(responsesReq)) {
|
|
@@ -1123,10 +1249,10 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
|
|
|
1123
1249
|
fixture: null
|
|
1124
1250
|
}
|
|
1125
1251
|
});
|
|
1126
|
-
require_sse_writer.writeErrorResponse(res, 400,
|
|
1252
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "validation", {
|
|
1127
1253
|
message: "Request body must be a JSON object",
|
|
1128
1254
|
type: "invalid_request_error"
|
|
1129
|
-
}
|
|
1255
|
+
}).body);
|
|
1130
1256
|
return;
|
|
1131
1257
|
}
|
|
1132
1258
|
let inputError;
|
|
@@ -1153,10 +1279,10 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
|
|
|
1153
1279
|
fixture: null
|
|
1154
1280
|
}
|
|
1155
1281
|
});
|
|
1156
|
-
require_sse_writer.writeErrorResponse(res, 400,
|
|
1282
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "validation", {
|
|
1157
1283
|
message: validationError,
|
|
1158
1284
|
type: "invalid_request_error"
|
|
1159
|
-
}
|
|
1285
|
+
}).body);
|
|
1160
1286
|
return;
|
|
1161
1287
|
}
|
|
1162
1288
|
const extendedTools = defaults.responsesTools === "extended";
|
|
@@ -1169,7 +1295,10 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
|
|
|
1169
1295
|
const emitEncryptedReasoning = requestWantsEncryptedReasoning(responsesReq);
|
|
1170
1296
|
const synthesizeSummarylessReasoning = requestIncludesEncryptedReasoning(responsesReq);
|
|
1171
1297
|
const testId = require_helpers.getTestId(req);
|
|
1172
|
-
const { fixture, skippedBySequenceOrTurn } = require_router.matchFixtureDiagnostic(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform,
|
|
1298
|
+
const { fixture, skippedBySequenceOrTurn } = require_router.matchFixtureDiagnostic(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform, {
|
|
1299
|
+
...require_router.recordMatchOptions(!!defaults.record, defaults.logger),
|
|
1300
|
+
wire: "openai-responses"
|
|
1301
|
+
});
|
|
1173
1302
|
if (fixture) {
|
|
1174
1303
|
defaults.logger.debug(`Responses fixture matched for ${req.method ?? "POST"} ${req.url ?? "/v1/responses"}`);
|
|
1175
1304
|
journal.incrementFixtureMatchCount(fixture, fixtures, testId);
|
|
@@ -1181,7 +1310,7 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
|
|
|
1181
1310
|
body: completionReq
|
|
1182
1311
|
}, fixture ? "fixture" : "proxy", defaults.registry, defaults.logger)) return;
|
|
1183
1312
|
if (!fixture) {
|
|
1184
|
-
if (
|
|
1313
|
+
if (require_policy.resolveRequestDecisions(defaults.strict, req.headers).fixtureMiss) {
|
|
1185
1314
|
const strictStatus = 503;
|
|
1186
1315
|
const strictMessage = require_helpers.strictNoMatchMessage(skippedBySequenceOrTurn);
|
|
1187
1316
|
defaults.logger.error(require_helpers.strictNoMatchLogLine(req.method ?? "POST", req.url ?? "/v1/responses", skippedBySequenceOrTurn));
|
|
@@ -1193,18 +1322,18 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
|
|
|
1193
1322
|
response: {
|
|
1194
1323
|
status: strictStatus,
|
|
1195
1324
|
fixture: null,
|
|
1196
|
-
...
|
|
1325
|
+
...require_policy.strictOverrideField(defaults.strict, req.headers)
|
|
1197
1326
|
}
|
|
1198
1327
|
});
|
|
1199
|
-
require_sse_writer.writeErrorResponse(res, strictStatus,
|
|
1328
|
+
require_sse_writer.writeErrorResponse(res, strictStatus, require_errors.renderError("openai", "strict-miss", {
|
|
1200
1329
|
message: strictMessage,
|
|
1201
1330
|
type: "invalid_request_error",
|
|
1202
1331
|
code: "no_fixture_match"
|
|
1203
|
-
}
|
|
1332
|
+
}).body);
|
|
1204
1333
|
return;
|
|
1205
1334
|
}
|
|
1206
1335
|
if (defaults.record) {
|
|
1207
|
-
const outcome = await require_recorder.proxyAndRecord(req, res, completionReq, "openai", req.url ?? "/v1/responses", fixtures, defaults, raw);
|
|
1336
|
+
const { outcome, clientHungUp } = await require_proxy.withHangUpDetection(req, res, () => require_recorder.proxyAndRecord(req, res, completionReq, "openai", req.url ?? "/v1/responses", fixtures, defaults, raw));
|
|
1208
1337
|
if (outcome === "handled_by_hook") return;
|
|
1209
1338
|
if (outcome !== "not_configured") {
|
|
1210
1339
|
journal.add({
|
|
@@ -1215,7 +1344,8 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
|
|
|
1215
1344
|
response: {
|
|
1216
1345
|
status: res.statusCode ?? 200,
|
|
1217
1346
|
fixture: null,
|
|
1218
|
-
source: "proxy"
|
|
1347
|
+
source: "proxy",
|
|
1348
|
+
...require_proxy.proxyInterruption(res, clientHungUp)
|
|
1219
1349
|
}
|
|
1220
1350
|
});
|
|
1221
1351
|
return;
|
|
@@ -1229,14 +1359,14 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
|
|
|
1229
1359
|
response: {
|
|
1230
1360
|
status: 404,
|
|
1231
1361
|
fixture: null,
|
|
1232
|
-
...
|
|
1362
|
+
...require_policy.strictOverrideField(defaults.strict, req.headers)
|
|
1233
1363
|
}
|
|
1234
1364
|
});
|
|
1235
|
-
require_sse_writer.writeErrorResponse(res, 404,
|
|
1365
|
+
require_sse_writer.writeErrorResponse(res, 404, require_errors.renderError("openai", "fixture-miss", {
|
|
1236
1366
|
message: "No fixture matched",
|
|
1237
1367
|
type: "invalid_request_error",
|
|
1238
1368
|
code: "no_fixture_match"
|
|
1239
|
-
}
|
|
1369
|
+
}).body);
|
|
1240
1370
|
return;
|
|
1241
1371
|
}
|
|
1242
1372
|
const resolvedResponse = await require_helpers.resolveResponse(fixture, completionReq);
|
|
@@ -1269,20 +1399,34 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
|
|
|
1269
1399
|
testId
|
|
1270
1400
|
});
|
|
1271
1401
|
if (!misbehavior.summary?.evaluations.some((evaluation) => evaluation.outcome === "error")) defaults.logger.error(misbehavior.message);
|
|
1272
|
-
require_sse_writer.writeErrorResponse(res, misbehavior.status,
|
|
1402
|
+
require_sse_writer.writeErrorResponse(res, misbehavior.status, require_errors.renderError("openai", "misbehavior", {
|
|
1273
1403
|
message: misbehavior.message,
|
|
1274
1404
|
type: "invalid_request_error",
|
|
1275
1405
|
code: misbehavior.code
|
|
1276
|
-
}
|
|
1406
|
+
}).body);
|
|
1277
1407
|
return;
|
|
1278
1408
|
}
|
|
1279
1409
|
const latency = fixture.latency ?? defaults.latency;
|
|
1280
1410
|
const chunkSize = Math.max(1, fixture.chunkSize ?? defaults.chunkSize);
|
|
1281
1411
|
const fixtureTimings = fixture.recordedTimings;
|
|
1282
1412
|
const effectiveReplaySpeed = fixture.replaySpeed ?? defaults.replaySpeed;
|
|
1413
|
+
const streamTiming = {
|
|
1414
|
+
latency,
|
|
1415
|
+
streamingProfile: fixture.streamingProfile,
|
|
1416
|
+
recordedTimings: fixtureTimings,
|
|
1417
|
+
replaySpeed: effectiveReplaySpeed
|
|
1418
|
+
};
|
|
1419
|
+
const timedJson = require_timing.nonStreamingTimingEnabled(fixture, "other");
|
|
1420
|
+
const jsonPayloadLength = (r, reasoning) => require_timing.responsesPayloadLength(r, reasoning) + require_timing.responsesOutputFrames(r) * chunkSize;
|
|
1421
|
+
const jsonOpts = (payloadLength, duplicateId = false) => ({
|
|
1422
|
+
surface: "other",
|
|
1423
|
+
payloadLength: timedJson ? payloadLength() : 0,
|
|
1424
|
+
chunkSize,
|
|
1425
|
+
recordedTimings: fixtureTimings,
|
|
1426
|
+
duplicateId,
|
|
1427
|
+
replaySpeed: effectiveReplaySpeed
|
|
1428
|
+
});
|
|
1283
1429
|
if (misbehavior.kind === "applied") {
|
|
1284
|
-
const prepared = prepareResponsesMisbehavior(misbehavior);
|
|
1285
|
-
const output = buildResponsesMisbehavior(prepared, completionReq, chunkSize, emitEncryptedReasoning);
|
|
1286
1430
|
const entry = journal.add({
|
|
1287
1431
|
method: req.method ?? "POST",
|
|
1288
1432
|
path: req.url ?? "/v1/responses",
|
|
@@ -1293,41 +1437,50 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
|
|
|
1293
1437
|
fixture
|
|
1294
1438
|
}
|
|
1295
1439
|
});
|
|
1296
|
-
|
|
1440
|
+
const prepared = prepareResponsesMisbehavior(misbehavior);
|
|
1441
|
+
const build = () => buildResponsesMisbehavior(prepared, completionReq, chunkSize, emitEncryptedReasoning);
|
|
1442
|
+
const record = () => require_misbehavior.recordMisbehaviorOutcome({
|
|
1297
1443
|
entry,
|
|
1298
1444
|
summary: prepared.summary,
|
|
1299
1445
|
defaults,
|
|
1300
1446
|
testId
|
|
1301
1447
|
});
|
|
1448
|
+
const output = timedJson && responsesReq.stream !== true ? void 0 : build();
|
|
1449
|
+
if (output) record();
|
|
1302
1450
|
if (responsesReq.stream !== true) {
|
|
1303
|
-
|
|
1304
|
-
|
|
1451
|
+
const servedReasoning = prepared.reasoning ?? ("reasoning" in prepared.response ? prepared.response.reasoning : void 0);
|
|
1452
|
+
await require_deliver.deliverJson(res, entry, fixture, () => {
|
|
1453
|
+
if (output) return output.response;
|
|
1454
|
+
const built = build();
|
|
1455
|
+
record();
|
|
1456
|
+
return built.response;
|
|
1457
|
+
}, jsonOpts(() => require_timing.misbehaviorPayloadLength(prepared, servedReasoning, jsonPayloadLength), !!prepared.duplicateId));
|
|
1305
1458
|
} else {
|
|
1306
|
-
const
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
const lastGap = appliedTimings.interChunkDelaysMs.at(-1) ?? 0;
|
|
1312
|
-
while (appliedTimings.interChunkDelaysMs.length < output.events.length - 1) appliedTimings.interChunkDelaysMs.push(lastGap);
|
|
1313
|
-
}
|
|
1314
|
-
const interruption = require_interruption.createInterruptionSignal(fixture);
|
|
1315
|
-
if (!await writeResponsesSSEStream(res, output.events, {
|
|
1316
|
-
latency,
|
|
1317
|
-
streamingProfile: fixture.streamingProfile,
|
|
1318
|
-
recordedTimings: appliedTimings,
|
|
1319
|
-
replaySpeed: effectiveReplaySpeed,
|
|
1320
|
-
signal: interruption?.signal,
|
|
1321
|
-
onChunkSent: interruption?.tick
|
|
1322
|
-
})) {
|
|
1323
|
-
if (!res.writableEnded) res.destroy();
|
|
1324
|
-
entry.response.interrupted = true;
|
|
1325
|
-
entry.response.interruptReason = interruption?.reason();
|
|
1326
|
-
}
|
|
1327
|
-
interruption?.cleanup();
|
|
1459
|
+
const { events } = output ?? build();
|
|
1460
|
+
await require_deliver.deliverStream(res, entry, fixture, require_sse_writer.typedSseCodec(), events, {
|
|
1461
|
+
...streamTiming,
|
|
1462
|
+
recordedTimings: require_timing.extendRecordedTimings(fixtureTimings, events.length, !!prepared.duplicateId)
|
|
1463
|
+
});
|
|
1328
1464
|
}
|
|
1329
1465
|
return;
|
|
1330
1466
|
}
|
|
1467
|
+
if (require_helpers.isRawResponse(response)) {
|
|
1468
|
+
await require_raw.serveRawResponse({
|
|
1469
|
+
wire: "openai-responses",
|
|
1470
|
+
stream: responsesReq.stream === true,
|
|
1471
|
+
req,
|
|
1472
|
+
res,
|
|
1473
|
+
fixture,
|
|
1474
|
+
response,
|
|
1475
|
+
body: completionReq,
|
|
1476
|
+
journal,
|
|
1477
|
+
defaults,
|
|
1478
|
+
testId,
|
|
1479
|
+
misbehaviorSummary: misbehavior.summary,
|
|
1480
|
+
errorWire: "openai"
|
|
1481
|
+
});
|
|
1482
|
+
return;
|
|
1483
|
+
}
|
|
1331
1484
|
if (require_helpers.isErrorResponse(response)) {
|
|
1332
1485
|
const status = response.status ?? 500;
|
|
1333
1486
|
require_misbehavior.recordMisbehaviorOutcome({
|
|
@@ -1350,7 +1503,7 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
|
|
|
1350
1503
|
}
|
|
1351
1504
|
if (require_helpers.isCombinedFixtureResponse(response)) {
|
|
1352
1505
|
const overrides = require_helpers.extractOverrides(response);
|
|
1353
|
-
const effectiveStrict =
|
|
1506
|
+
const effectiveStrict = require_policy.resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
|
|
1354
1507
|
const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, completionReq.model, effectiveStrict, defaults.logger);
|
|
1355
1508
|
const journalEntry = journal.add({
|
|
1356
1509
|
method: req.method ?? "POST",
|
|
@@ -1371,32 +1524,16 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
|
|
|
1371
1524
|
const ordered = require_helpers.resolveServedBlockOutcome(response)?.ordered;
|
|
1372
1525
|
if (!ordered) require_helpers.assertCustomToolCalls(response);
|
|
1373
1526
|
const toolCalls = require_helpers.servedToolCalls(response);
|
|
1374
|
-
if (responsesReq.stream !== true)
|
|
1375
|
-
|
|
1376
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1377
|
-
res.end(JSON.stringify(body));
|
|
1378
|
-
} else {
|
|
1527
|
+
if (responsesReq.stream !== true) await require_deliver.deliverJson(res, journalEntry, fixture, () => buildContentWithToolCallsResponse(response.content ?? "", toolCalls, completionReq.model, effReasoning, response.webSearches, overrides, ordered, emitEncryptedReasoning, synthesizeSummarylessReasoning), jsonOpts(() => jsonPayloadLength(response, effReasoning)));
|
|
1528
|
+
else {
|
|
1379
1529
|
const events = contentWithToolCallsStreamEvents(response.content ?? "", toolCalls, completionReq.model, chunkSize, effReasoning, response.webSearches, overrides, ordered, emitEncryptedReasoning, synthesizeSummarylessReasoning);
|
|
1380
|
-
|
|
1381
|
-
if (!await writeResponsesSSEStream(res, events, {
|
|
1382
|
-
latency,
|
|
1383
|
-
streamingProfile: fixture.streamingProfile,
|
|
1384
|
-
recordedTimings: fixtureTimings,
|
|
1385
|
-
replaySpeed: effectiveReplaySpeed,
|
|
1386
|
-
signal: interruption?.signal,
|
|
1387
|
-
onChunkSent: interruption?.tick
|
|
1388
|
-
})) {
|
|
1389
|
-
if (!res.writableEnded) res.destroy();
|
|
1390
|
-
journalEntry.response.interrupted = true;
|
|
1391
|
-
journalEntry.response.interruptReason = interruption?.reason();
|
|
1392
|
-
}
|
|
1393
|
-
interruption?.cleanup();
|
|
1530
|
+
await require_deliver.deliverStream(res, journalEntry, fixture, require_sse_writer.typedSseCodec(), events, streamTiming);
|
|
1394
1531
|
}
|
|
1395
1532
|
return;
|
|
1396
1533
|
}
|
|
1397
1534
|
if (require_helpers.isTextResponse(response)) {
|
|
1398
1535
|
const overrides = require_helpers.extractOverrides(response);
|
|
1399
|
-
const effectiveStrict =
|
|
1536
|
+
const effectiveStrict = require_policy.resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
|
|
1400
1537
|
const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, completionReq.model, effectiveStrict, defaults.logger);
|
|
1401
1538
|
const journalEntry = journal.add({
|
|
1402
1539
|
method: req.method ?? "POST",
|
|
@@ -1414,32 +1551,16 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
|
|
|
1414
1551
|
defaults,
|
|
1415
1552
|
testId
|
|
1416
1553
|
});
|
|
1417
|
-
if (responsesReq.stream !== true)
|
|
1418
|
-
|
|
1419
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1420
|
-
res.end(JSON.stringify(body));
|
|
1421
|
-
} else {
|
|
1554
|
+
if (responsesReq.stream !== true) await require_deliver.deliverJson(res, journalEntry, fixture, () => buildTextResponse(response.content, completionReq.model, effReasoning, response.webSearches, overrides, emitEncryptedReasoning, synthesizeSummarylessReasoning), jsonOpts(() => jsonPayloadLength(response, effReasoning)));
|
|
1555
|
+
else {
|
|
1422
1556
|
const events = buildTextStreamEvents(response.content, completionReq.model, chunkSize, effReasoning, response.webSearches, overrides, emitEncryptedReasoning, synthesizeSummarylessReasoning);
|
|
1423
|
-
|
|
1424
|
-
if (!await writeResponsesSSEStream(res, events, {
|
|
1425
|
-
latency,
|
|
1426
|
-
streamingProfile: fixture.streamingProfile,
|
|
1427
|
-
recordedTimings: fixtureTimings,
|
|
1428
|
-
replaySpeed: effectiveReplaySpeed,
|
|
1429
|
-
signal: interruption?.signal,
|
|
1430
|
-
onChunkSent: interruption?.tick
|
|
1431
|
-
})) {
|
|
1432
|
-
if (!res.writableEnded) res.destroy();
|
|
1433
|
-
journalEntry.response.interrupted = true;
|
|
1434
|
-
journalEntry.response.interruptReason = interruption?.reason();
|
|
1435
|
-
}
|
|
1436
|
-
interruption?.cleanup();
|
|
1557
|
+
await require_deliver.deliverStream(res, journalEntry, fixture, require_sse_writer.typedSseCodec(), events, streamTiming);
|
|
1437
1558
|
}
|
|
1438
1559
|
return;
|
|
1439
1560
|
}
|
|
1440
1561
|
if (require_helpers.isToolCallResponse(response)) {
|
|
1441
1562
|
const overrides = require_helpers.extractOverrides(response);
|
|
1442
|
-
const effectiveStrict =
|
|
1563
|
+
const effectiveStrict = require_policy.resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
|
|
1443
1564
|
const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, completionReq.model, effectiveStrict, defaults.logger);
|
|
1444
1565
|
const journalEntry = journal.add({
|
|
1445
1566
|
method: req.method ?? "POST",
|
|
@@ -1458,26 +1579,10 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
|
|
|
1458
1579
|
testId
|
|
1459
1580
|
});
|
|
1460
1581
|
require_helpers.assertCustomToolCalls(response);
|
|
1461
|
-
if (responsesReq.stream !== true)
|
|
1462
|
-
|
|
1463
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1464
|
-
res.end(JSON.stringify(body));
|
|
1465
|
-
} else {
|
|
1582
|
+
if (responsesReq.stream !== true) await require_deliver.deliverJson(res, journalEntry, fixture, () => buildToolCallResponse(require_helpers.servedToolCalls(response), completionReq.model, effReasoning, response.webSearches, overrides, emitEncryptedReasoning, synthesizeSummarylessReasoning), jsonOpts(() => jsonPayloadLength(response, effReasoning)));
|
|
1583
|
+
else {
|
|
1466
1584
|
const events = toolCallStreamEvents(require_helpers.servedToolCalls(response), completionReq.model, chunkSize, effReasoning, response.webSearches, overrides, emitEncryptedReasoning, synthesizeSummarylessReasoning);
|
|
1467
|
-
|
|
1468
|
-
if (!await writeResponsesSSEStream(res, events, {
|
|
1469
|
-
latency,
|
|
1470
|
-
streamingProfile: fixture.streamingProfile,
|
|
1471
|
-
recordedTimings: fixtureTimings,
|
|
1472
|
-
replaySpeed: effectiveReplaySpeed,
|
|
1473
|
-
signal: interruption?.signal,
|
|
1474
|
-
onChunkSent: interruption?.tick
|
|
1475
|
-
})) {
|
|
1476
|
-
if (!res.writableEnded) res.destroy();
|
|
1477
|
-
journalEntry.response.interrupted = true;
|
|
1478
|
-
journalEntry.response.interruptReason = interruption?.reason();
|
|
1479
|
-
}
|
|
1480
|
-
interruption?.cleanup();
|
|
1585
|
+
await require_deliver.deliverStream(res, journalEntry, fixture, require_sse_writer.typedSseCodec(), events, streamTiming);
|
|
1481
1586
|
}
|
|
1482
1587
|
return;
|
|
1483
1588
|
}
|
|
@@ -1496,10 +1601,10 @@ async function handleResponses(req, res, raw, fixtures, journal, defaults, setCo
|
|
|
1496
1601
|
defaults,
|
|
1497
1602
|
testId
|
|
1498
1603
|
});
|
|
1499
|
-
require_sse_writer.writeErrorResponse(res, 500,
|
|
1604
|
+
require_sse_writer.writeErrorResponse(res, 500, require_errors.renderError("openai", "unknown-response", {
|
|
1500
1605
|
message: "Fixture response did not match any known type",
|
|
1501
1606
|
type: "server_error"
|
|
1502
|
-
}
|
|
1607
|
+
}).body);
|
|
1503
1608
|
}
|
|
1504
1609
|
/** Prepare call IDs once, retaining the engine's effective blocks and exact served-call metadata. */
|
|
1505
1610
|
function prepareResponsesMisbehavior(plan) {
|
|
@@ -1512,7 +1617,11 @@ function buildResponsesMisbehavior(plan, request, chunkSize, emitEncryptedReason
|
|
|
1512
1617
|
const overrides = require_helpers.extractOverrides(response);
|
|
1513
1618
|
const reasoning = plan.reasoning ?? ("reasoning" in response ? response.reasoning : void 0);
|
|
1514
1619
|
const webSearches = "webSearches" in response ? response.webSearches : void 0;
|
|
1515
|
-
const
|
|
1620
|
+
const outputWithheld = plan.refusal !== void 0 || plan.summary.fault === "empty-response" || plan.stop === "content_filter" || plan.reasoning !== void 0;
|
|
1621
|
+
const { respId, created, events, prefixOutputItems, nextOutputIndex } = buildResponsePreamble(request.model, chunkSize, reasoning, webSearches, outputWithheld ? {
|
|
1622
|
+
...overrides,
|
|
1623
|
+
files: void 0
|
|
1624
|
+
} : overrides, emitEncryptedReasoning, false, plan.reasoning !== void 0);
|
|
1516
1625
|
const output = [...prefixOutputItems];
|
|
1517
1626
|
let outputIndex = nextOutputIndex;
|
|
1518
1627
|
const incomplete = plan.stop === "length" || plan.stop === "content_filter";
|
|
@@ -1527,6 +1636,7 @@ function buildResponsesMisbehavior(plan, request, chunkSize, emitEncryptedReason
|
|
|
1527
1636
|
type: "message",
|
|
1528
1637
|
role: "assistant",
|
|
1529
1638
|
status: "completed",
|
|
1639
|
+
...overrides.phase !== void 0 ? { phase: overrides.phase } : {},
|
|
1530
1640
|
content: [part]
|
|
1531
1641
|
};
|
|
1532
1642
|
const position = {
|
|
@@ -1569,16 +1679,18 @@ function buildResponsesMisbehavior(plan, request, chunkSize, emitEncryptedReason
|
|
|
1569
1679
|
item
|
|
1570
1680
|
});
|
|
1571
1681
|
output.push(item);
|
|
1572
|
-
} else if (
|
|
1682
|
+
} else if (!outputWithheld) {
|
|
1573
1683
|
const combined = require_helpers.isCombinedFixtureResponse(response);
|
|
1574
1684
|
const blocks = (combined ? require_helpers.resolveServedBlockOutcome(response) : void 0)?.ordered ?? [..."content" in response && typeof response.content === "string" ? [{
|
|
1575
1685
|
type: "text",
|
|
1576
1686
|
text: response.content
|
|
1577
1687
|
}] : [], ...combined || require_helpers.isToolCallResponse(response) ? require_helpers.servedToolCalls(response).map(require_helpers.toolCallFixtureBlock) : []];
|
|
1578
1688
|
let callIndex = 0;
|
|
1689
|
+
const textAnnotations = orderedBlockAnnotations(blocks, overrides.citations);
|
|
1690
|
+
let textPos = 0;
|
|
1579
1691
|
for (const block of blocks) {
|
|
1580
1692
|
if (block.type === "text") {
|
|
1581
|
-
const message = buildMessageOutputEvents(block.text, chunkSize, outputIndex);
|
|
1693
|
+
const message = buildMessageOutputEvents(block.text, chunkSize, outputIndex, overrides.phase, textAnnotations[textPos++]);
|
|
1582
1694
|
events.push(...message.events);
|
|
1583
1695
|
output.push(message.msgItem);
|
|
1584
1696
|
} else {
|
|
@@ -1607,11 +1719,7 @@ function buildResponsesMisbehavior(plan, request, chunkSize, emitEncryptedReason
|
|
|
1607
1719
|
status: incomplete ? "incomplete" : responsesStatus(overrides?.finishReason, "completed"),
|
|
1608
1720
|
...incomplete ? { incomplete_details: { reason: plan.stop === "content_filter" ? "content_filter" : "max_output_tokens" } } : {},
|
|
1609
1721
|
output,
|
|
1610
|
-
usage: {
|
|
1611
|
-
input_tokens: usage.prompt_tokens,
|
|
1612
|
-
output_tokens: usage.completion_tokens,
|
|
1613
|
-
total_tokens: usage.total_tokens
|
|
1614
|
-
}
|
|
1722
|
+
usage: require_responses.render({ usage })
|
|
1615
1723
|
};
|
|
1616
1724
|
events.push({
|
|
1617
1725
|
type: incomplete ? "response.incomplete" : "response.completed",
|