@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/messages.js
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { missingRequiredHeader } from "./response/profiles.js";
|
|
2
|
+
import { renderError } from "./response/errors.js";
|
|
3
|
+
import { resolvePolicy, resolveRequestDecisions, strictOverrideField } from "./response/policy.js";
|
|
4
|
+
import { estimatePromptTokens, estimateTokens, extractOverrides, flattenHeaders, generateMessageId, generateToolUseId, getContext, getTestId, isCombinedFixtureResponse, isErrorResponse, isJsonObject, isRawResponse, isTextResponse, isToolCallResponse, rejectGeneratedFiles, requireEmittedFunctionToolCalls, resolveCitations, resolveFixtureBlockOutcome, resolveReasoningArtifactsForModel, resolveReasoningForModel, resolveRequestId, resolveResponse, servedToolArgs, strictNoMatchLogLine, strictNoMatchMessage, toolArgsForWire } from "./helpers.js";
|
|
5
|
+
import { typedSseCodec, writeErrorResponse } from "./sse-writer.js";
|
|
3
6
|
import { applyChaosAsync } from "./chaos.js";
|
|
4
7
|
import { planMisbehavior, recordMisbehaviorOutcome } from "./misbehavior.js";
|
|
5
8
|
import { matchFixtureDiagnostic, recordMatchOptions } from "./router.js";
|
|
9
|
+
import { render, resolve } from "./response/usage/codecs/anthropic.js";
|
|
6
10
|
import { proxyAndRecord } from "./recorder.js";
|
|
7
|
-
import {
|
|
11
|
+
import { misbehaviorPayloadLength, servedPayloadLength } from "./response/timing.js";
|
|
12
|
+
import { deliverJson, deliverStream } from "./response/deliver.js";
|
|
13
|
+
import { proxyInterruption, withHangUpDetection } from "./response/proxy.js";
|
|
14
|
+
import { serveRawResponse } from "./response/raw.js";
|
|
15
|
+
import { mapAnthropicFinish } from "./response/finish.js";
|
|
8
16
|
|
|
9
17
|
//#region src/messages.ts
|
|
10
18
|
/**
|
|
@@ -191,20 +199,7 @@ function thinkingViolationMessage(v) {
|
|
|
191
199
|
}
|
|
192
200
|
function claudeStopReason(finishReason, defaultReason) {
|
|
193
201
|
if (!finishReason) return defaultReason;
|
|
194
|
-
|
|
195
|
-
if (finishReason === "tool_calls") return "tool_use";
|
|
196
|
-
if (finishReason === "length") return "max_tokens";
|
|
197
|
-
return finishReason;
|
|
198
|
-
}
|
|
199
|
-
function claudeUsage(overrides) {
|
|
200
|
-
if (!overrides?.usage) return {
|
|
201
|
-
input_tokens: 0,
|
|
202
|
-
output_tokens: 0
|
|
203
|
-
};
|
|
204
|
-
return {
|
|
205
|
-
input_tokens: overrides.usage.input_tokens ?? overrides.usage.prompt_tokens ?? 0,
|
|
206
|
-
output_tokens: overrides.usage.output_tokens ?? overrides.usage.completion_tokens ?? 0
|
|
207
|
-
};
|
|
202
|
+
return mapAnthropicFinish(finishReason);
|
|
208
203
|
}
|
|
209
204
|
/**
|
|
210
205
|
* Emit faithful Anthropic `redacted_thinking` content-block events at the head
|
|
@@ -240,6 +235,76 @@ function pushRedactedThinkingStreamEvents(events, startIndex, redactedThinking)
|
|
|
240
235
|
}
|
|
241
236
|
return blockIndex;
|
|
242
237
|
}
|
|
238
|
+
/**
|
|
239
|
+
* Fixture `citations` as Anthropic `web_search_result_location` citations, the
|
|
240
|
+
* URL-sourced citation type (see `CitationsWebSearchResultLocation` in
|
|
241
|
+
* `@anthropic-ai/sdk`), grouped per text block. `texts` are the turn's text
|
|
242
|
+
* blocks in order; citation offsets index their joined text, the same
|
|
243
|
+
* convention as Chat Completions and Gemini. Each citation goes only to the
|
|
244
|
+
* last text block whose start offset in the joined text is at or before the
|
|
245
|
+
* citation's `startIndex`, with `cited_text` sliced from that block's own text
|
|
246
|
+
* (cut off at the block's end).
|
|
247
|
+
* `web_search_result_location` carries no offsets, so nothing is rebased.
|
|
248
|
+
* `encrypted_index` is opaque on the real wire, so aimock fills a stable
|
|
249
|
+
* base64 placeholder. File citations are skipped (see {@link resolveCitations}):
|
|
250
|
+
* Anthropic has no citation type for an OpenAI file ID.
|
|
251
|
+
*/
|
|
252
|
+
function claudeBlockCitations(texts, overrides) {
|
|
253
|
+
const starts = [];
|
|
254
|
+
let offset = 0;
|
|
255
|
+
for (const text of texts) {
|
|
256
|
+
starts.push(offset);
|
|
257
|
+
offset += text.length;
|
|
258
|
+
}
|
|
259
|
+
const perBlock = texts.map(() => []);
|
|
260
|
+
if (texts.length === 0) {
|
|
261
|
+
resolveCitations("", overrides?.citations);
|
|
262
|
+
return perBlock;
|
|
263
|
+
}
|
|
264
|
+
resolveCitations(texts.join(""), overrides?.citations).forEach((c, i) => {
|
|
265
|
+
let owner = 0;
|
|
266
|
+
for (let k = 1; k < starts.length; k++) if (starts[k] <= c.startIndex) owner = k;
|
|
267
|
+
const start = starts[owner];
|
|
268
|
+
perBlock[owner].push({
|
|
269
|
+
type: "web_search_result_location",
|
|
270
|
+
cited_text: texts[owner].slice(c.startIndex - start, c.endIndex - start),
|
|
271
|
+
url: c.url,
|
|
272
|
+
title: c.title,
|
|
273
|
+
encrypted_index: Buffer.from(`aimock-citation:${i}:${c.url}`).toString("base64")
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
return perBlock;
|
|
277
|
+
}
|
|
278
|
+
/** {@link claudeBlockCitations} for a turn with a single text block. */
|
|
279
|
+
function claudeCitations(text, overrides) {
|
|
280
|
+
return claudeBlockCitations([text], overrides)[0];
|
|
281
|
+
}
|
|
282
|
+
/** A text content block; `citations` is added only when it has some. */
|
|
283
|
+
function claudeTextBlock(text, citations) {
|
|
284
|
+
return citations.length > 0 ? {
|
|
285
|
+
type: "text",
|
|
286
|
+
text,
|
|
287
|
+
citations
|
|
288
|
+
} : {
|
|
289
|
+
type: "text",
|
|
290
|
+
text
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Streamed form of a text block's citations: one `citations_delta` per
|
|
295
|
+
* citation, after the block's text deltas and before its `content_block_stop`,
|
|
296
|
+
* as in the Anthropic citations streaming example. Nothing when it has none.
|
|
297
|
+
*/
|
|
298
|
+
function claudeCitationDeltas(citations, index) {
|
|
299
|
+
return citations.map((citation) => ({
|
|
300
|
+
type: "content_block_delta",
|
|
301
|
+
index,
|
|
302
|
+
delta: {
|
|
303
|
+
type: "citations_delta",
|
|
304
|
+
citation
|
|
305
|
+
}
|
|
306
|
+
}));
|
|
307
|
+
}
|
|
243
308
|
function buildClaudeTextStreamEvents(content, model, chunkSize, reasoning, overrides, reasoningSignature, redactedThinking) {
|
|
244
309
|
const msgId = overrides?.id ?? generateMessageId();
|
|
245
310
|
const effectiveModel = overrides?.model ?? model;
|
|
@@ -255,7 +320,7 @@ function buildClaudeTextStreamEvents(content, model, chunkSize, reasoning, overr
|
|
|
255
320
|
model: effectiveModel,
|
|
256
321
|
stop_reason: null,
|
|
257
322
|
stop_sequence: null,
|
|
258
|
-
usage:
|
|
323
|
+
usage: render(resolve(overrides), "messages-start")
|
|
259
324
|
}
|
|
260
325
|
});
|
|
261
326
|
let blockIndex = 0;
|
|
@@ -314,6 +379,7 @@ function buildClaudeTextStreamEvents(content, model, chunkSize, reasoning, overr
|
|
|
314
379
|
}
|
|
315
380
|
});
|
|
316
381
|
}
|
|
382
|
+
events.push(...claudeCitationDeltas(claudeCitations(content, overrides), blockIndex));
|
|
317
383
|
events.push({
|
|
318
384
|
type: "content_block_stop",
|
|
319
385
|
index: blockIndex
|
|
@@ -324,12 +390,13 @@ function buildClaudeTextStreamEvents(content, model, chunkSize, reasoning, overr
|
|
|
324
390
|
stop_reason: claudeStopReason(overrides?.finishReason, "end_turn"),
|
|
325
391
|
stop_sequence: null
|
|
326
392
|
},
|
|
327
|
-
usage:
|
|
393
|
+
usage: render(resolve(overrides), "messages-delta")
|
|
328
394
|
});
|
|
329
395
|
events.push({ type: "message_stop" });
|
|
330
396
|
return events;
|
|
331
397
|
}
|
|
332
398
|
function buildClaudeToolCallStreamEvents(toolCalls, model, chunkSize, logger, reasoning, overrides, reasoningSignature, redactedThinking) {
|
|
399
|
+
resolveCitations("", overrides?.citations);
|
|
333
400
|
const msgId = overrides?.id ?? generateMessageId();
|
|
334
401
|
const effectiveModel = overrides?.model ?? model;
|
|
335
402
|
const signature = reasoningSignature ?? PLACEHOLDER_SIGNATURE;
|
|
@@ -344,7 +411,7 @@ function buildClaudeToolCallStreamEvents(toolCalls, model, chunkSize, logger, re
|
|
|
344
411
|
model: effectiveModel,
|
|
345
412
|
stop_reason: null,
|
|
346
413
|
stop_sequence: null,
|
|
347
|
-
usage:
|
|
414
|
+
usage: render(resolve(overrides), "messages-start")
|
|
348
415
|
}
|
|
349
416
|
});
|
|
350
417
|
let blockIndex = 0;
|
|
@@ -420,7 +487,7 @@ function buildClaudeToolCallStreamEvents(toolCalls, model, chunkSize, logger, re
|
|
|
420
487
|
stop_reason: claudeStopReason(overrides?.finishReason, "tool_use"),
|
|
421
488
|
stop_sequence: null
|
|
422
489
|
},
|
|
423
|
-
usage:
|
|
490
|
+
usage: render(resolve(overrides), "messages-delta")
|
|
424
491
|
});
|
|
425
492
|
events.push({ type: "message_stop" });
|
|
426
493
|
return events;
|
|
@@ -451,10 +518,7 @@ function buildClaudeTextResponse(content, model, reasoning, overrides, reasoning
|
|
|
451
518
|
thinking: reasoning,
|
|
452
519
|
signature: reasoningSignature ?? PLACEHOLDER_SIGNATURE
|
|
453
520
|
});
|
|
454
|
-
contentBlocks.push(
|
|
455
|
-
type: "text",
|
|
456
|
-
text: content
|
|
457
|
-
});
|
|
521
|
+
contentBlocks.push(claudeTextBlock(content, claudeCitations(content, overrides)));
|
|
458
522
|
return {
|
|
459
523
|
id: overrides?.id ?? generateMessageId(),
|
|
460
524
|
type: "message",
|
|
@@ -463,10 +527,11 @@ function buildClaudeTextResponse(content, model, reasoning, overrides, reasoning
|
|
|
463
527
|
model: overrides?.model ?? model,
|
|
464
528
|
stop_reason: claudeStopReason(overrides?.finishReason, "end_turn"),
|
|
465
529
|
stop_sequence: null,
|
|
466
|
-
usage:
|
|
530
|
+
usage: render(resolve(overrides), "messages-final")
|
|
467
531
|
};
|
|
468
532
|
}
|
|
469
533
|
function buildClaudeToolCallResponse(toolCalls, model, logger, reasoning, overrides, reasoningSignature, redactedThinking) {
|
|
534
|
+
resolveCitations("", overrides?.citations);
|
|
470
535
|
const contentBlocks = [];
|
|
471
536
|
pushRedactedThinkingBlocks(contentBlocks, redactedThinking);
|
|
472
537
|
if (reasoning) contentBlocks.push({
|
|
@@ -491,7 +556,7 @@ function buildClaudeToolCallResponse(toolCalls, model, logger, reasoning, overri
|
|
|
491
556
|
model: overrides?.model ?? model,
|
|
492
557
|
stop_reason: claudeStopReason(overrides?.finishReason, "tool_use"),
|
|
493
558
|
stop_sequence: null,
|
|
494
|
-
usage:
|
|
559
|
+
usage: render(resolve(overrides), "messages-final")
|
|
495
560
|
};
|
|
496
561
|
}
|
|
497
562
|
function buildClaudeContentWithToolCallsStreamEvents(content, toolCalls, model, chunkSize, logger, reasoning, overrides, reasoningSignature, redactedThinking, blocks) {
|
|
@@ -509,7 +574,7 @@ function buildClaudeContentWithToolCallsStreamEvents(content, toolCalls, model,
|
|
|
509
574
|
model: effectiveModel,
|
|
510
575
|
stop_reason: null,
|
|
511
576
|
stop_sequence: null,
|
|
512
|
-
usage:
|
|
577
|
+
usage: render(resolve(overrides), "messages-start")
|
|
513
578
|
}
|
|
514
579
|
});
|
|
515
580
|
let blockIndex = 0;
|
|
@@ -552,6 +617,8 @@ function buildClaudeContentWithToolCallsStreamEvents(content, toolCalls, model,
|
|
|
552
617
|
if (blocks && blocks.length > 0) {
|
|
553
618
|
const outcome = resolveFixtureBlockOutcome(blocks);
|
|
554
619
|
const ordered = outcome.ordered;
|
|
620
|
+
const textCitations = claudeBlockCitations(ordered.flatMap((b) => b.type === "text" ? [b.text] : []), overrides);
|
|
621
|
+
let textPos = 0;
|
|
555
622
|
for (const block of ordered) if (block.type === "text") {
|
|
556
623
|
events.push({
|
|
557
624
|
type: "content_block_start",
|
|
@@ -572,6 +639,7 @@ function buildClaudeContentWithToolCallsStreamEvents(content, toolCalls, model,
|
|
|
572
639
|
}
|
|
573
640
|
});
|
|
574
641
|
}
|
|
642
|
+
events.push(...claudeCitationDeltas(textCitations[textPos++] ?? [], blockIndex));
|
|
575
643
|
events.push({
|
|
576
644
|
type: "content_block_stop",
|
|
577
645
|
index: blockIndex
|
|
@@ -613,7 +681,7 @@ function buildClaudeContentWithToolCallsStreamEvents(content, toolCalls, model,
|
|
|
613
681
|
stop_reason: claudeStopReason(overrides?.finishReason, outcome.hasToolCalls ? "tool_use" : "end_turn"),
|
|
614
682
|
stop_sequence: null
|
|
615
683
|
},
|
|
616
|
-
usage:
|
|
684
|
+
usage: render(resolve(overrides), "messages-delta")
|
|
617
685
|
});
|
|
618
686
|
events.push({ type: "message_stop" });
|
|
619
687
|
return events;
|
|
@@ -637,6 +705,7 @@ function buildClaudeContentWithToolCallsStreamEvents(content, toolCalls, model,
|
|
|
637
705
|
}
|
|
638
706
|
});
|
|
639
707
|
}
|
|
708
|
+
events.push(...claudeCitationDeltas(claudeCitations(content, overrides), blockIndex));
|
|
640
709
|
events.push({
|
|
641
710
|
type: "content_block_stop",
|
|
642
711
|
index: blockIndex
|
|
@@ -678,7 +747,7 @@ function buildClaudeContentWithToolCallsStreamEvents(content, toolCalls, model,
|
|
|
678
747
|
stop_reason: claudeStopReason(overrides?.finishReason, "tool_use"),
|
|
679
748
|
stop_sequence: null
|
|
680
749
|
},
|
|
681
|
-
usage:
|
|
750
|
+
usage: render(resolve(overrides), "messages-delta")
|
|
682
751
|
});
|
|
683
752
|
events.push({ type: "message_stop" });
|
|
684
753
|
return events;
|
|
@@ -704,21 +773,17 @@ function buildClaudeContentWithToolCallsResponse(content, toolCalls, model, logg
|
|
|
704
773
|
if (blocks && blocks.length > 0) {
|
|
705
774
|
const outcome = resolveFixtureBlockOutcome(blocks);
|
|
706
775
|
const ordered = outcome.ordered;
|
|
776
|
+
const textCitations = claudeBlockCitations(ordered.flatMap((b) => b.type === "text" ? [b.text] : []), overrides);
|
|
777
|
+
let textPos = 0;
|
|
707
778
|
blockHasTools = outcome.hasToolCalls;
|
|
708
|
-
for (const block of ordered) if (block.type === "text") contentBlocks.push(
|
|
709
|
-
type: "text",
|
|
710
|
-
text: block.text
|
|
711
|
-
});
|
|
779
|
+
for (const block of ordered) if (block.type === "text") contentBlocks.push(claudeTextBlock(block.text, textCitations[textPos++] ?? []));
|
|
712
780
|
else contentBlocks.push(toolUseBlock({
|
|
713
781
|
name: block.name,
|
|
714
782
|
arguments: block.arguments,
|
|
715
783
|
id: block.id
|
|
716
784
|
}));
|
|
717
785
|
} else {
|
|
718
|
-
contentBlocks.push(
|
|
719
|
-
type: "text",
|
|
720
|
-
text: content
|
|
721
|
-
});
|
|
786
|
+
contentBlocks.push(claudeTextBlock(content, claudeCitations(content, overrides)));
|
|
722
787
|
for (const tc of toolCalls) contentBlocks.push(toolUseBlock(tc));
|
|
723
788
|
}
|
|
724
789
|
return {
|
|
@@ -729,7 +794,7 @@ function buildClaudeContentWithToolCallsResponse(content, toolCalls, model, logg
|
|
|
729
794
|
model: overrides?.model ?? model,
|
|
730
795
|
stop_reason: claudeStopReason(overrides?.finishReason, blockHasTools === false ? "end_turn" : "tool_use"),
|
|
731
796
|
stop_sequence: null,
|
|
732
|
-
usage:
|
|
797
|
+
usage: render(resolve(overrides), "messages-final")
|
|
733
798
|
};
|
|
734
799
|
}
|
|
735
800
|
/**
|
|
@@ -783,12 +848,15 @@ function prepareClaudeMisbehavior(plan, context) {
|
|
|
783
848
|
const reasoning = plan.summary.fault === "reasoning-only" ? plan.reasoning ?? "" : resolveReasoningForModel(response.reasoning, context.request.model, context.strict, context.logger);
|
|
784
849
|
const artifacts = resolveReasoningArtifactsForModel(response.reasoningSignature, response.redactedThinking, context.request.model, context.strict, context.logger);
|
|
785
850
|
const content = outcome?.content ?? ("content" in response ? response.content ?? "" : "");
|
|
786
|
-
const
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
};
|
|
851
|
+
const resolvedUsage = resolve(void 0, {
|
|
852
|
+
inputTokens: estimatePromptTokens(context.request.messages),
|
|
853
|
+
outputTokens: estimateTokens(content + servedToolCalls.map((call) => call.name + call.arguments).join("") + (reasoning ?? "") + (plan.refusal ?? ""))
|
|
854
|
+
});
|
|
855
|
+
const usage = render(resolvedUsage, "messages-final", "applied-misbehavior");
|
|
856
|
+
const { citations, ...rest } = extractOverrides(response);
|
|
790
857
|
const overrides = {
|
|
791
|
-
...
|
|
858
|
+
...rest,
|
|
859
|
+
...context.citations ? { citations } : {},
|
|
792
860
|
...plan.stop === "length" ? { finishReason: "length" } : {},
|
|
793
861
|
usage
|
|
794
862
|
};
|
|
@@ -811,6 +879,7 @@ function prepareClaudeMisbehavior(plan, context) {
|
|
|
811
879
|
usage
|
|
812
880
|
};
|
|
813
881
|
if (!context.stream) return {
|
|
882
|
+
reasoning,
|
|
814
883
|
stream: false,
|
|
815
884
|
body,
|
|
816
885
|
plan: preparedPlan,
|
|
@@ -857,9 +926,10 @@ function prepareClaudeMisbehavior(plan, context) {
|
|
|
857
926
|
stop_reason: "max_tokens",
|
|
858
927
|
stop_sequence: null
|
|
859
928
|
},
|
|
860
|
-
usage:
|
|
929
|
+
usage: render(resolvedUsage, "messages-delta", "applied-misbehavior")
|
|
861
930
|
}, { type: "message_stop" });
|
|
862
931
|
return {
|
|
932
|
+
reasoning,
|
|
863
933
|
stream: true,
|
|
864
934
|
events,
|
|
865
935
|
plan: preparedPlan,
|
|
@@ -885,12 +955,14 @@ function prepareClaudeMisbehavior(plan, context) {
|
|
|
885
955
|
usage
|
|
886
956
|
};
|
|
887
957
|
if (!context.stream) return {
|
|
958
|
+
reasoning,
|
|
888
959
|
stream: false,
|
|
889
960
|
body,
|
|
890
961
|
plan: preparedPlan,
|
|
891
962
|
usage
|
|
892
963
|
};
|
|
893
964
|
return {
|
|
965
|
+
reasoning,
|
|
894
966
|
stream: true,
|
|
895
967
|
events: [
|
|
896
968
|
{
|
|
@@ -908,7 +980,7 @@ function prepareClaudeMisbehavior(plan, context) {
|
|
|
908
980
|
stop_sequence: null,
|
|
909
981
|
...detail
|
|
910
982
|
},
|
|
911
|
-
usage:
|
|
983
|
+
usage: render(resolvedUsage, "messages-delta", "applied-misbehavior")
|
|
912
984
|
},
|
|
913
985
|
{ type: "message_stop" }
|
|
914
986
|
],
|
|
@@ -927,6 +999,7 @@ function prepareClaudeMisbehavior(plan, context) {
|
|
|
927
999
|
if (plan.summary.fault === "stop-length-mid-tool") {
|
|
928
1000
|
const cutIndex = events.filter((event) => event.type === "content_block_start" && isJsonObject(event.content_block) && event.content_block.type === "tool_use")[plan.target?.index ?? 0]?.index;
|
|
929
1001
|
return {
|
|
1002
|
+
reasoning,
|
|
930
1003
|
stream: true,
|
|
931
1004
|
events: events.filter((event) => !(event.type === "content_block_stop" && event.index === cutIndex)),
|
|
932
1005
|
plan: preparedPlan,
|
|
@@ -934,6 +1007,7 @@ function prepareClaudeMisbehavior(plan, context) {
|
|
|
934
1007
|
};
|
|
935
1008
|
}
|
|
936
1009
|
return {
|
|
1010
|
+
reasoning,
|
|
937
1011
|
stream: true,
|
|
938
1012
|
events,
|
|
939
1013
|
plan: preparedPlan,
|
|
@@ -947,40 +1021,39 @@ function prepareClaudeMisbehavior(plan, context) {
|
|
|
947
1021
|
artifacts.redactedThinking
|
|
948
1022
|
];
|
|
949
1023
|
return {
|
|
1024
|
+
reasoning,
|
|
950
1025
|
stream: false,
|
|
951
1026
|
body: isCombinedFixtureResponse(preparedResponse) ? buildClaudeContentWithToolCallsResponse(preparedResponse.content ?? "", toolCalls, model, context.logger, ...args, preparedResponse.blocks) : isToolCallResponse(preparedResponse) ? buildClaudeToolCallResponse(toolCalls, model, context.logger, ...args) : buildClaudeTextResponse(content, model, ...args),
|
|
952
1027
|
plan: preparedPlan,
|
|
953
1028
|
usage
|
|
954
1029
|
};
|
|
955
1030
|
}
|
|
956
|
-
async function writeClaudeSSEStream(res, events, optionsOrLatency) {
|
|
957
|
-
const opts = typeof optionsOrLatency === "number" ? { latency: optionsOrLatency } : optionsOrLatency ?? {};
|
|
958
|
-
const latency = opts.latency ?? 0;
|
|
959
|
-
const profile = opts.streamingProfile;
|
|
960
|
-
const { recordedTimings, replaySpeed } = opts;
|
|
961
|
-
const signal = opts.signal;
|
|
962
|
-
const onChunkSent = opts.onChunkSent;
|
|
963
|
-
if (res.writableEnded) return true;
|
|
964
|
-
res.setHeader("Content-Type", "text/event-stream");
|
|
965
|
-
res.setHeader("Cache-Control", "no-cache");
|
|
966
|
-
res.setHeader("Connection", "keep-alive");
|
|
967
|
-
let chunkIndex = 0;
|
|
968
|
-
for (const event of events) {
|
|
969
|
-
const chunkDelay = calculateDelay(chunkIndex, profile, latency, recordedTimings, replaySpeed);
|
|
970
|
-
if (chunkDelay > 0) await delay(chunkDelay, signal);
|
|
971
|
-
if (signal?.aborted) return false;
|
|
972
|
-
if (res.writableEnded) return true;
|
|
973
|
-
res.write(`event: ${event.type}\ndata: ${JSON.stringify(event)}\n\n`);
|
|
974
|
-
onChunkSent?.();
|
|
975
|
-
if (signal?.aborted) return false;
|
|
976
|
-
chunkIndex++;
|
|
977
|
-
}
|
|
978
|
-
if (!res.writableEnded) res.end();
|
|
979
|
-
return true;
|
|
980
|
-
}
|
|
981
1031
|
async function handleMessages(req, res, raw, fixtures, journal, defaults, setCorsHeaders) {
|
|
982
1032
|
const { logger } = defaults;
|
|
983
1033
|
setCorsHeaders(res);
|
|
1034
|
+
const missingHeader = resolvePolicy(defaults, req.headers).requiredHeaders === "enforce" ? missingRequiredHeader("messages", req.headers) : void 0;
|
|
1035
|
+
if (missingHeader) {
|
|
1036
|
+
const { id: requestId } = resolveRequestId(req.headers);
|
|
1037
|
+
req.headers["x-request-id"] = requestId;
|
|
1038
|
+
res.setHeader("X-Request-Id", requestId);
|
|
1039
|
+
journal.add({
|
|
1040
|
+
method: req.method ?? "POST",
|
|
1041
|
+
path: req.url ?? "/v1/messages",
|
|
1042
|
+
headers: flattenHeaders(req.headers),
|
|
1043
|
+
body: null,
|
|
1044
|
+
response: {
|
|
1045
|
+
status: 400,
|
|
1046
|
+
fixture: null,
|
|
1047
|
+
source: "internal",
|
|
1048
|
+
...strictOverrideField(defaults.strict, req.headers)
|
|
1049
|
+
}
|
|
1050
|
+
});
|
|
1051
|
+
writeErrorResponse(res, 400, renderError("messages", "thinking", {
|
|
1052
|
+
message: `${missingHeader}: header is required`,
|
|
1053
|
+
requestId
|
|
1054
|
+
}).body);
|
|
1055
|
+
return;
|
|
1056
|
+
}
|
|
984
1057
|
let claudeReq;
|
|
985
1058
|
try {
|
|
986
1059
|
claudeReq = JSON.parse(raw);
|
|
@@ -996,10 +1069,10 @@ async function handleMessages(req, res, raw, fixtures, journal, defaults, setCor
|
|
|
996
1069
|
fixture: null
|
|
997
1070
|
}
|
|
998
1071
|
});
|
|
999
|
-
writeErrorResponse(res, 400,
|
|
1072
|
+
writeErrorResponse(res, 400, renderError("messages", "validation", {
|
|
1000
1073
|
message: `Malformed JSON: ${detail}`,
|
|
1001
1074
|
type: "invalid_request_error"
|
|
1002
|
-
}
|
|
1075
|
+
}).body);
|
|
1003
1076
|
return;
|
|
1004
1077
|
}
|
|
1005
1078
|
if (!isJsonObject(claudeReq)) {
|
|
@@ -1013,10 +1086,10 @@ async function handleMessages(req, res, raw, fixtures, journal, defaults, setCor
|
|
|
1013
1086
|
fixture: null
|
|
1014
1087
|
}
|
|
1015
1088
|
});
|
|
1016
|
-
writeErrorResponse(res, 400,
|
|
1089
|
+
writeErrorResponse(res, 400, renderError("messages", "validation", {
|
|
1017
1090
|
message: "Request body must be a JSON object",
|
|
1018
1091
|
type: "invalid_request_error"
|
|
1019
|
-
}
|
|
1092
|
+
}).body);
|
|
1020
1093
|
return;
|
|
1021
1094
|
}
|
|
1022
1095
|
const messagesError = !Array.isArray(claudeReq.messages) ? "messages must be an array" : claudeReq.messages.some((message) => !isJsonObject(message)) ? "messages entries must be JSON objects" : claudeReq.messages.some((message) => (message.role === "user" || message.role === "assistant") && typeof message.content === "number") ? "messages content must be a string or an array of content blocks" : null;
|
|
@@ -1031,15 +1104,15 @@ async function handleMessages(req, res, raw, fixtures, journal, defaults, setCor
|
|
|
1031
1104
|
fixture: null
|
|
1032
1105
|
}
|
|
1033
1106
|
});
|
|
1034
|
-
writeErrorResponse(res, 400,
|
|
1107
|
+
writeErrorResponse(res, 400, renderError("messages", "validation", {
|
|
1035
1108
|
message: messagesError,
|
|
1036
1109
|
type: "invalid_request_error"
|
|
1037
|
-
}
|
|
1110
|
+
}).body);
|
|
1038
1111
|
return;
|
|
1039
1112
|
}
|
|
1040
1113
|
const thinkingViolation = validateThinkingInvariants(claudeReq);
|
|
1041
1114
|
if (thinkingViolation) {
|
|
1042
|
-
const effectiveStrict =
|
|
1115
|
+
const effectiveStrict = resolveRequestDecisions(defaults.strict, req.headers).thinkingRejection;
|
|
1043
1116
|
const violationMessage = thinkingViolationMessage(thinkingViolation);
|
|
1044
1117
|
if (effectiveStrict) {
|
|
1045
1118
|
logger.error(`THINKING: ${violationMessage}`);
|
|
@@ -1054,13 +1127,7 @@ async function handleMessages(req, res, raw, fixtures, journal, defaults, setCor
|
|
|
1054
1127
|
...strictOverrideField(defaults.strict, req.headers)
|
|
1055
1128
|
}
|
|
1056
1129
|
});
|
|
1057
|
-
writeErrorResponse(res, 400,
|
|
1058
|
-
type: "error",
|
|
1059
|
-
error: {
|
|
1060
|
-
type: "invalid_request_error",
|
|
1061
|
-
message: violationMessage
|
|
1062
|
-
}
|
|
1063
|
-
}));
|
|
1130
|
+
writeErrorResponse(res, 400, renderError("messages", "thinking", { message: violationMessage }).body);
|
|
1064
1131
|
return;
|
|
1065
1132
|
}
|
|
1066
1133
|
logger.warn(`THINKING: ${violationMessage} (strict off — replaying anyway)`);
|
|
@@ -1078,17 +1145,20 @@ async function handleMessages(req, res, raw, fixtures, journal, defaults, setCor
|
|
|
1078
1145
|
fixture: null
|
|
1079
1146
|
}
|
|
1080
1147
|
});
|
|
1081
|
-
writeErrorResponse(res, 400,
|
|
1148
|
+
writeErrorResponse(res, 400, renderError("messages", "validation", {
|
|
1082
1149
|
message: toolsError,
|
|
1083
1150
|
type: "invalid_request_error"
|
|
1084
|
-
}
|
|
1151
|
+
}).body);
|
|
1085
1152
|
return;
|
|
1086
1153
|
}
|
|
1087
1154
|
}
|
|
1088
1155
|
const completionReq = claudeToCompletionRequest(claudeReq);
|
|
1089
1156
|
completionReq._context = getContext(req);
|
|
1090
1157
|
const testId = getTestId(req);
|
|
1091
|
-
const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform,
|
|
1158
|
+
const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform, {
|
|
1159
|
+
...recordMatchOptions(!!defaults.record, defaults.logger),
|
|
1160
|
+
wire: "anthropic"
|
|
1161
|
+
});
|
|
1092
1162
|
if (fixture) {
|
|
1093
1163
|
journal.incrementFixtureMatchCount(fixture, fixtures, testId);
|
|
1094
1164
|
logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);
|
|
@@ -1104,7 +1174,7 @@ async function handleMessages(req, res, raw, fixtures, journal, defaults, setCor
|
|
|
1104
1174
|
body: completionReq
|
|
1105
1175
|
}, fixture ? "fixture" : "proxy", defaults.registry, defaults.logger)) return;
|
|
1106
1176
|
if (!fixture) {
|
|
1107
|
-
if (
|
|
1177
|
+
if (resolveRequestDecisions(defaults.strict, req.headers).fixtureMiss) {
|
|
1108
1178
|
const strictStatus = 503;
|
|
1109
1179
|
const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);
|
|
1110
1180
|
logger.error(strictNoMatchLogLine(req.method ?? "POST", req.url ?? "/v1/messages", skippedBySequenceOrTurn));
|
|
@@ -1119,14 +1189,14 @@ async function handleMessages(req, res, raw, fixtures, journal, defaults, setCor
|
|
|
1119
1189
|
...strictOverrideField(defaults.strict, req.headers)
|
|
1120
1190
|
}
|
|
1121
1191
|
});
|
|
1122
|
-
writeErrorResponse(res, strictStatus,
|
|
1192
|
+
writeErrorResponse(res, strictStatus, renderError("messages", "strict-miss", {
|
|
1123
1193
|
message: strictMessage,
|
|
1124
1194
|
type: "invalid_request_error"
|
|
1125
|
-
}
|
|
1195
|
+
}).body);
|
|
1126
1196
|
return;
|
|
1127
1197
|
}
|
|
1128
1198
|
if (defaults.record) {
|
|
1129
|
-
const outcome = await proxyAndRecord(req, res, completionReq, "anthropic", req.url ?? "/v1/messages", fixtures, defaults, raw);
|
|
1199
|
+
const { outcome, clientHungUp } = await withHangUpDetection(req, res, () => proxyAndRecord(req, res, completionReq, "anthropic", req.url ?? "/v1/messages", fixtures, defaults, raw));
|
|
1130
1200
|
if (outcome === "handled_by_hook") return;
|
|
1131
1201
|
if (outcome !== "not_configured") {
|
|
1132
1202
|
journal.add({
|
|
@@ -1137,7 +1207,8 @@ async function handleMessages(req, res, raw, fixtures, journal, defaults, setCor
|
|
|
1137
1207
|
response: {
|
|
1138
1208
|
status: res.statusCode ?? 200,
|
|
1139
1209
|
fixture: null,
|
|
1140
|
-
source: "proxy"
|
|
1210
|
+
source: "proxy",
|
|
1211
|
+
...proxyInterruption(res, clientHungUp)
|
|
1141
1212
|
}
|
|
1142
1213
|
});
|
|
1143
1214
|
return;
|
|
@@ -1154,10 +1225,10 @@ async function handleMessages(req, res, raw, fixtures, journal, defaults, setCor
|
|
|
1154
1225
|
...strictOverrideField(defaults.strict, req.headers)
|
|
1155
1226
|
}
|
|
1156
1227
|
});
|
|
1157
|
-
writeErrorResponse(res, 404,
|
|
1228
|
+
writeErrorResponse(res, 404, renderError("messages", "fixture-miss", {
|
|
1158
1229
|
message: "No fixture matched",
|
|
1159
1230
|
type: "invalid_request_error"
|
|
1160
|
-
}
|
|
1231
|
+
}).body);
|
|
1161
1232
|
return;
|
|
1162
1233
|
}
|
|
1163
1234
|
const response = await resolveResponse(fixture, completionReq);
|
|
@@ -1189,26 +1260,31 @@ async function handleMessages(req, res, raw, fixtures, journal, defaults, setCor
|
|
|
1189
1260
|
testId
|
|
1190
1261
|
});
|
|
1191
1262
|
if (!misbehavior.summary?.evaluations.length) logger.error(`POST /v1/messages: ${misbehavior.message}`);
|
|
1192
|
-
writeErrorResponse(res, misbehavior.status,
|
|
1193
|
-
type: "
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
message: misbehavior.message
|
|
1198
|
-
}
|
|
1199
|
-
}));
|
|
1263
|
+
writeErrorResponse(res, misbehavior.status, renderError("messages", "misbehavior", {
|
|
1264
|
+
type: misbehavior.status === 400 ? "invalid_request_error" : "api_error",
|
|
1265
|
+
code: misbehavior.code,
|
|
1266
|
+
message: misbehavior.message
|
|
1267
|
+
}).body);
|
|
1200
1268
|
return;
|
|
1201
1269
|
}
|
|
1202
1270
|
const latency = fixture.latency ?? defaults.latency;
|
|
1203
1271
|
const chunkSize = Math.max(1, fixture.chunkSize ?? defaults.chunkSize);
|
|
1272
|
+
const replaySpeed = fixture.replaySpeed ?? defaults.replaySpeed;
|
|
1273
|
+
const streamTiming = {
|
|
1274
|
+
latency,
|
|
1275
|
+
streamingProfile: fixture.streamingProfile,
|
|
1276
|
+
recordedTimings: fixture.recordedTimings,
|
|
1277
|
+
replaySpeed
|
|
1278
|
+
};
|
|
1279
|
+
const jsonOpts = (payloadLength, duplicateId = false) => ({
|
|
1280
|
+
surface: "other",
|
|
1281
|
+
payloadLength,
|
|
1282
|
+
chunkSize,
|
|
1283
|
+
recordedTimings: fixture.recordedTimings,
|
|
1284
|
+
duplicateId,
|
|
1285
|
+
replaySpeed
|
|
1286
|
+
});
|
|
1204
1287
|
if (misbehavior.kind === "applied") {
|
|
1205
|
-
const prepared = prepareClaudeMisbehavior(misbehavior, {
|
|
1206
|
-
request: completionReq,
|
|
1207
|
-
stream: claudeReq.stream === true,
|
|
1208
|
-
chunkSize,
|
|
1209
|
-
logger,
|
|
1210
|
-
strict: resolveStrictMode(defaults.strict, req.headers)
|
|
1211
|
-
});
|
|
1212
1288
|
const entry = journal.add({
|
|
1213
1289
|
method: req.method ?? "POST",
|
|
1214
1290
|
path: req.url ?? "/v1/messages",
|
|
@@ -1219,6 +1295,15 @@ async function handleMessages(req, res, raw, fixtures, journal, defaults, setCor
|
|
|
1219
1295
|
fixture
|
|
1220
1296
|
}
|
|
1221
1297
|
});
|
|
1298
|
+
rejectGeneratedFiles(misbehavior.response, "Anthropic Messages");
|
|
1299
|
+
const prepared = prepareClaudeMisbehavior(misbehavior, {
|
|
1300
|
+
request: completionReq,
|
|
1301
|
+
stream: claudeReq.stream === true,
|
|
1302
|
+
chunkSize,
|
|
1303
|
+
logger,
|
|
1304
|
+
strict: resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression,
|
|
1305
|
+
citations: true
|
|
1306
|
+
});
|
|
1222
1307
|
recordMisbehaviorOutcome({
|
|
1223
1308
|
entry,
|
|
1224
1309
|
summary: prepared.plan.summary,
|
|
@@ -1226,27 +1311,26 @@ async function handleMessages(req, res, raw, fixtures, journal, defaults, setCor
|
|
|
1226
1311
|
testId
|
|
1227
1312
|
});
|
|
1228
1313
|
if (!prepared.stream) {
|
|
1229
|
-
|
|
1230
|
-
res
|
|
1231
|
-
} else
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
}
|
|
1314
|
+
const preparedBody = prepared.body;
|
|
1315
|
+
await deliverJson(res, entry, fixture, () => preparedBody, jsonOpts(misbehaviorPayloadLength(misbehavior, misbehavior.reasoning === void 0 ? prepared.reasoning : void 0), !!misbehavior.duplicateId));
|
|
1316
|
+
} else await deliverStream(res, entry, fixture, typedSseCodec(), prepared.events, streamTiming);
|
|
1317
|
+
return;
|
|
1318
|
+
}
|
|
1319
|
+
if (isRawResponse(response)) {
|
|
1320
|
+
await serveRawResponse({
|
|
1321
|
+
wire: "anthropic",
|
|
1322
|
+
stream: claudeReq.stream === true,
|
|
1323
|
+
req,
|
|
1324
|
+
res,
|
|
1325
|
+
fixture,
|
|
1326
|
+
response,
|
|
1327
|
+
body: completionReq,
|
|
1328
|
+
journal,
|
|
1329
|
+
defaults,
|
|
1330
|
+
testId,
|
|
1331
|
+
misbehaviorSummary: misbehavior.summary,
|
|
1332
|
+
errorWire: "messages"
|
|
1333
|
+
});
|
|
1250
1334
|
return;
|
|
1251
1335
|
}
|
|
1252
1336
|
if (isErrorResponse(response)) {
|
|
@@ -1266,20 +1350,13 @@ async function handleMessages(req, res, raw, fixtures, journal, defaults, setCor
|
|
|
1266
1350
|
defaults,
|
|
1267
1351
|
testId
|
|
1268
1352
|
});
|
|
1269
|
-
|
|
1270
|
-
type: "error",
|
|
1271
|
-
error: {
|
|
1272
|
-
type: response.error.type ?? "api_error",
|
|
1273
|
-
message: response.error.message
|
|
1274
|
-
}
|
|
1275
|
-
};
|
|
1276
|
-
writeErrorResponse(res, status, JSON.stringify(anthropicError), { retryAfter: response.retryAfter });
|
|
1353
|
+
writeErrorResponse(res, status, renderError("messages", "fixture", response.error).body, { retryAfter: response.retryAfter });
|
|
1277
1354
|
return;
|
|
1278
1355
|
}
|
|
1279
1356
|
if (isCombinedFixtureResponse(response)) {
|
|
1280
1357
|
if (response.webSearches?.length) logger.warn("webSearches in fixture response are not supported for Claude Messages API — ignoring");
|
|
1281
1358
|
const overrides = extractOverrides(response);
|
|
1282
|
-
const effectiveStrict =
|
|
1359
|
+
const effectiveStrict = resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
|
|
1283
1360
|
const effReasoning = resolveReasoningForModel(response.reasoning, completionReq.model, effectiveStrict, defaults.logger);
|
|
1284
1361
|
const { reasoningSignature: effReasoningSignature, redactedThinking: effRedactedThinking } = resolveReasoningArtifactsForModel(response.reasoningSignature, response.redactedThinking, completionReq.model, effectiveStrict, defaults.logger);
|
|
1285
1362
|
const journalEntry = journal.add({
|
|
@@ -1298,34 +1375,19 @@ async function handleMessages(req, res, raw, fixtures, journal, defaults, setCor
|
|
|
1298
1375
|
defaults,
|
|
1299
1376
|
testId
|
|
1300
1377
|
});
|
|
1378
|
+
rejectGeneratedFiles(response, "Anthropic Messages");
|
|
1301
1379
|
const functionToolCalls = requireEmittedFunctionToolCalls(response, "Anthropic Messages");
|
|
1302
|
-
if (claudeReq.stream !== true)
|
|
1303
|
-
|
|
1304
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1305
|
-
res.end(JSON.stringify(body));
|
|
1306
|
-
} else {
|
|
1380
|
+
if (claudeReq.stream !== true) await deliverJson(res, journalEntry, fixture, () => buildClaudeContentWithToolCallsResponse(response.content ?? "", functionToolCalls, completionReq.model, logger, effReasoning, overrides, effReasoningSignature, effRedactedThinking, response.blocks), jsonOpts(servedPayloadLength(response, effReasoning)));
|
|
1381
|
+
else {
|
|
1307
1382
|
const events = buildClaudeContentWithToolCallsStreamEvents(response.content ?? "", functionToolCalls, completionReq.model, chunkSize, logger, effReasoning, overrides, effReasoningSignature, effRedactedThinking, response.blocks);
|
|
1308
|
-
|
|
1309
|
-
if (!await writeClaudeSSEStream(res, events, {
|
|
1310
|
-
latency,
|
|
1311
|
-
streamingProfile: fixture.streamingProfile,
|
|
1312
|
-
recordedTimings: fixture.recordedTimings,
|
|
1313
|
-
replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,
|
|
1314
|
-
signal: interruption?.signal,
|
|
1315
|
-
onChunkSent: interruption?.tick
|
|
1316
|
-
})) {
|
|
1317
|
-
if (!res.writableEnded) res.destroy();
|
|
1318
|
-
journalEntry.response.interrupted = true;
|
|
1319
|
-
journalEntry.response.interruptReason = interruption?.reason();
|
|
1320
|
-
}
|
|
1321
|
-
interruption?.cleanup();
|
|
1383
|
+
await deliverStream(res, journalEntry, fixture, typedSseCodec(), events, streamTiming);
|
|
1322
1384
|
}
|
|
1323
1385
|
return;
|
|
1324
1386
|
}
|
|
1325
1387
|
if (isTextResponse(response)) {
|
|
1326
1388
|
if (response.webSearches?.length) logger.warn("webSearches in fixture response are not supported for Claude Messages API — ignoring");
|
|
1327
1389
|
const overrides = extractOverrides(response);
|
|
1328
|
-
const effectiveStrict =
|
|
1390
|
+
const effectiveStrict = resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
|
|
1329
1391
|
const effReasoning = resolveReasoningForModel(response.reasoning, completionReq.model, effectiveStrict, defaults.logger);
|
|
1330
1392
|
const { reasoningSignature: effReasoningSignature, redactedThinking: effRedactedThinking } = resolveReasoningArtifactsForModel(response.reasoningSignature, response.redactedThinking, completionReq.model, effectiveStrict, defaults.logger);
|
|
1331
1393
|
const journalEntry = journal.add({
|
|
@@ -1344,33 +1406,18 @@ async function handleMessages(req, res, raw, fixtures, journal, defaults, setCor
|
|
|
1344
1406
|
defaults,
|
|
1345
1407
|
testId
|
|
1346
1408
|
});
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
res.end(JSON.stringify(body));
|
|
1351
|
-
} else {
|
|
1409
|
+
rejectGeneratedFiles(response, "Anthropic Messages");
|
|
1410
|
+
if (claudeReq.stream !== true) await deliverJson(res, journalEntry, fixture, () => buildClaudeTextResponse(response.content, completionReq.model, effReasoning, overrides, effReasoningSignature, effRedactedThinking), jsonOpts(servedPayloadLength(response, effReasoning)));
|
|
1411
|
+
else {
|
|
1352
1412
|
const events = buildClaudeTextStreamEvents(response.content, completionReq.model, chunkSize, effReasoning, overrides, effReasoningSignature, effRedactedThinking);
|
|
1353
|
-
|
|
1354
|
-
if (!await writeClaudeSSEStream(res, events, {
|
|
1355
|
-
latency,
|
|
1356
|
-
streamingProfile: fixture.streamingProfile,
|
|
1357
|
-
recordedTimings: fixture.recordedTimings,
|
|
1358
|
-
replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,
|
|
1359
|
-
signal: interruption?.signal,
|
|
1360
|
-
onChunkSent: interruption?.tick
|
|
1361
|
-
})) {
|
|
1362
|
-
if (!res.writableEnded) res.destroy();
|
|
1363
|
-
journalEntry.response.interrupted = true;
|
|
1364
|
-
journalEntry.response.interruptReason = interruption?.reason();
|
|
1365
|
-
}
|
|
1366
|
-
interruption?.cleanup();
|
|
1413
|
+
await deliverStream(res, journalEntry, fixture, typedSseCodec(), events, streamTiming);
|
|
1367
1414
|
}
|
|
1368
1415
|
return;
|
|
1369
1416
|
}
|
|
1370
1417
|
if (isToolCallResponse(response)) {
|
|
1371
1418
|
if (response.webSearches?.length) logger.warn("webSearches in fixture response are not supported for Claude Messages API — ignoring");
|
|
1372
1419
|
const overrides = extractOverrides(response);
|
|
1373
|
-
const effectiveStrict =
|
|
1420
|
+
const effectiveStrict = resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
|
|
1374
1421
|
const effReasoning = resolveReasoningForModel(response.reasoning, completionReq.model, effectiveStrict, defaults.logger);
|
|
1375
1422
|
const { reasoningSignature: effReasoningSignature, redactedThinking: effRedactedThinking } = resolveReasoningArtifactsForModel(response.reasoningSignature, response.redactedThinking, completionReq.model, effectiveStrict, defaults.logger);
|
|
1376
1423
|
const journalEntry = journal.add({
|
|
@@ -1389,27 +1436,12 @@ async function handleMessages(req, res, raw, fixtures, journal, defaults, setCor
|
|
|
1389
1436
|
defaults,
|
|
1390
1437
|
testId
|
|
1391
1438
|
});
|
|
1439
|
+
rejectGeneratedFiles(response, "Anthropic Messages");
|
|
1392
1440
|
const functionToolCalls = requireEmittedFunctionToolCalls(response, "Anthropic Messages");
|
|
1393
|
-
if (claudeReq.stream !== true)
|
|
1394
|
-
|
|
1395
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1396
|
-
res.end(JSON.stringify(body));
|
|
1397
|
-
} else {
|
|
1441
|
+
if (claudeReq.stream !== true) await deliverJson(res, journalEntry, fixture, () => buildClaudeToolCallResponse(functionToolCalls, completionReq.model, logger, effReasoning, overrides, effReasoningSignature, effRedactedThinking), jsonOpts(servedPayloadLength(response, effReasoning)));
|
|
1442
|
+
else {
|
|
1398
1443
|
const events = buildClaudeToolCallStreamEvents(functionToolCalls, completionReq.model, chunkSize, logger, effReasoning, overrides, effReasoningSignature, effRedactedThinking);
|
|
1399
|
-
|
|
1400
|
-
if (!await writeClaudeSSEStream(res, events, {
|
|
1401
|
-
latency,
|
|
1402
|
-
streamingProfile: fixture.streamingProfile,
|
|
1403
|
-
recordedTimings: fixture.recordedTimings,
|
|
1404
|
-
replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,
|
|
1405
|
-
signal: interruption?.signal,
|
|
1406
|
-
onChunkSent: interruption?.tick
|
|
1407
|
-
})) {
|
|
1408
|
-
if (!res.writableEnded) res.destroy();
|
|
1409
|
-
journalEntry.response.interrupted = true;
|
|
1410
|
-
journalEntry.response.interruptReason = interruption?.reason();
|
|
1411
|
-
}
|
|
1412
|
-
interruption?.cleanup();
|
|
1444
|
+
await deliverStream(res, journalEntry, fixture, typedSseCodec(), events, streamTiming);
|
|
1413
1445
|
}
|
|
1414
1446
|
return;
|
|
1415
1447
|
}
|
|
@@ -1428,12 +1460,12 @@ async function handleMessages(req, res, raw, fixtures, journal, defaults, setCor
|
|
|
1428
1460
|
defaults,
|
|
1429
1461
|
testId
|
|
1430
1462
|
});
|
|
1431
|
-
writeErrorResponse(res, 500,
|
|
1463
|
+
writeErrorResponse(res, 500, renderError("messages", "unknown-response", {
|
|
1432
1464
|
message: "Fixture response did not match any known type",
|
|
1433
1465
|
type: "server_error"
|
|
1434
|
-
}
|
|
1466
|
+
}).body);
|
|
1435
1467
|
}
|
|
1436
1468
|
|
|
1437
1469
|
//#endregion
|
|
1438
|
-
export { handleMessages, prepareClaudeMisbehavior };
|
|
1470
|
+
export { claudeToCompletionRequest, handleMessages, prepareClaudeMisbehavior };
|
|
1439
1471
|
//# sourceMappingURL=messages.js.map
|