@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"elevenlabs-audio.js","names":[],"sources":["../src/elevenlabs-audio.ts"],"sourcesContent":["import type http from \"node:http\";\nimport type { ChatCompletionRequest, Fixture, HandlerDefaults } from \"./types.js\";\nimport {\n isAudioResponse,\n isTextResponse,\n isErrorResponse,\n isJsonObject,\n serializeErrorResponse,\n flattenHeaders,\n FORMAT_TO_CONTENT_TYPE,\n getContext,\n getTestId,\n resolveResponse,\n resolveStrictMode,\n strictOverrideField,\n strictNoMatchMessage,\n strictNoMatchLogLine,\n} from \"./helpers.js\";\nimport { matchFixtureDiagnostic } from \"./router.js\";\nimport { writeErrorResponse } from \"./sse-writer.js\";\nimport { proxyAndRecord } from \"./recorder.js\";\nimport type { Journal } from \"./journal.js\";\nimport { applyChaosAsync } from \"./chaos.js\";\n\nexport async function handleElevenLabsTTS(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n body: string,\n fixtures: Fixture[],\n defaults: HandlerDefaults,\n journal: Journal,\n voiceId: string,\n): Promise<void> {\n const path = req.url ?? `/v1/text-to-speech/${voiceId}`;\n const method = req.method ?? \"POST\";\n\n // Parse JSON body\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(body) as Record<string, unknown>;\n } catch (parseErr) {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: {\n message: `Malformed JSON: ${detail}`,\n type: \"invalid_request_error\",\n code: \"invalid_json\",\n },\n }),\n );\n return;\n }\n\n // Reject bodies that parsed but are not a JSON object (e.g. `null`) before\n // touching fields — otherwise `parsed.text` throws a TypeError that surfaces\n // as a 500 instead of a 400.\n if (!isJsonObject(parsed)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: {\n message: \"Request body must be a JSON object\",\n type: \"invalid_request_error\",\n },\n }),\n );\n return;\n }\n\n // Extract text from request body\n const promptText = typeof parsed.text === \"string\" && parsed.text ? parsed.text : undefined;\n\n // Build synthetic ChatCompletionRequest for fixture matching\n const syntheticReq: ChatCompletionRequest = {\n model: (parsed.model_id as string) ?? \"eleven_multilingual_v2\",\n messages: [{ role: \"user\", content: promptText ?? \"\" }],\n _endpointType: \"elevenlabs-tts\",\n _context: getContext(req),\n };\n\n // Validate required field\n if (!promptText) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: {\n message: \"Missing required parameter: 'text'\",\n type: \"invalid_request_error\",\n },\n }),\n );\n return;\n }\n\n // Match fixture\n const testId = getTestId(req);\n const matchCounts = journal.getFixtureMatchCountsForTest(testId);\n const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n fixtures,\n syntheticReq,\n matchCounts,\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n }\n\n if (\n await applyChaosAsync(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n req.url,\n journal,\n { method, path, headers: flattenHeaders(req.headers), body: syntheticReq },\n fixture ? \"fixture\" : \"proxy\",\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n // No fixture match\n if (!fixture) {\n const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n if (effectiveStrict) {\n const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n defaults.logger.error(strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 503,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 503,\n JSON.stringify({\n error: {\n message: strictMessage,\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n if (defaults.record) {\n const outcome = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n \"elevenlabs\",\n req.url ?? `/v1/text-to-speech/${voiceId}`,\n fixtures,\n defaults,\n body,\n );\n if (outcome === \"handled_by_hook\") return;\n if (outcome !== \"not_configured\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n });\n return;\n }\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 404,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 404,\n JSON.stringify({\n error: {\n message: \"No fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n\n const response = await resolveResponse(fixture, syntheticReq);\n\n // Error fixture\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, serializeErrorResponse(response), {\n retryAfter: response.retryAfter,\n });\n return;\n }\n\n // Expect audio response\n if (!isAudioResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: { message: \"Fixture response is not an audio type\", type: \"server_error\" },\n }),\n );\n return;\n }\n\n // Decode audio bytes and determine content type\n let audioBytes: Buffer;\n let contentType: string;\n\n if (typeof response.audio === \"string\") {\n audioBytes = Buffer.from(response.audio, \"base64\");\n const format = response.format ?? \"mp3\";\n contentType = FORMAT_TO_CONTENT_TYPE[format] ?? \"audio/mpeg\";\n } else {\n audioBytes = Buffer.from(response.audio.b64Json, \"base64\");\n contentType = response.audio.contentType ?? \"audio/mpeg\";\n }\n\n // Standard binary response\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n res.writeHead(200, { \"Content-Type\": contentType });\n res.end(audioBytes);\n}\n\nexport async function handleElevenLabsAudio(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n body: string,\n fixtures: Fixture[],\n defaults: HandlerDefaults,\n journal: Journal,\n subType: string, // \"sound-generation\" | \"music\" | \"stream\" | \"plan\"\n): Promise<void> {\n const path = req.url ?? \"/v1/sound-generation\";\n const method = req.method ?? \"POST\";\n\n // Parse JSON body\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(body) as Record<string, unknown>;\n } catch (parseErr) {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: {\n message: `Malformed JSON: ${detail}`,\n type: \"invalid_request_error\",\n code: \"invalid_json\",\n },\n }),\n );\n return;\n }\n\n // Reject bodies that parsed but are not a JSON object (e.g. `null`) before\n // touching fields — otherwise `parsed.text` throws a TypeError that surfaces\n // as a 500 instead of a 400.\n if (!isJsonObject(parsed)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: {\n message: \"Request body must be a JSON object\",\n type: \"invalid_request_error\",\n },\n }),\n );\n return;\n }\n\n // Extract prompt text based on subType\n let promptText: string | undefined;\n if (subType === \"sound-generation\") {\n if (typeof parsed.text === \"string\" && parsed.text) {\n promptText = parsed.text;\n }\n } else {\n // music, music-stream, music-plan all use \"prompt\" (or composition_plan fallback)\n if (typeof parsed.prompt === \"string\" && parsed.prompt) {\n promptText = parsed.prompt;\n } else if (parsed.composition_plan != null) {\n promptText =\n typeof parsed.composition_plan === \"string\"\n ? parsed.composition_plan\n : JSON.stringify(parsed.composition_plan);\n }\n }\n\n // Build synthetic ChatCompletionRequest for fixture matching (needed for journal even on validation failure)\n const syntheticReq: ChatCompletionRequest = {\n model:\n (parsed.model_id as string) ??\n (subType === \"sound-generation\" ? \"eleven_text_to_sound_v2\" : \"music_v1\"),\n messages: [{ role: \"user\", content: promptText ?? \"\" }],\n _endpointType: \"audio-gen\",\n _context: getContext(req),\n };\n\n // Validate required field\n if (!promptText) {\n const field = subType === \"sound-generation\" ? \"text\" : \"prompt\";\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: {\n message: `Missing required parameter: '${field}'`,\n type: \"invalid_request_error\",\n },\n }),\n );\n return;\n }\n\n // Match fixture\n const testId = getTestId(req);\n const matchCounts = journal.getFixtureMatchCountsForTest(testId);\n const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n fixtures,\n syntheticReq,\n matchCounts,\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n }\n\n if (\n await applyChaosAsync(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n req.url,\n journal,\n { method, path, headers: flattenHeaders(req.headers), body: syntheticReq },\n fixture ? \"fixture\" : \"proxy\",\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n // No fixture match\n if (!fixture) {\n const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n if (effectiveStrict) {\n const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n defaults.logger.error(strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 503,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 503,\n JSON.stringify({\n error: {\n message: strictMessage,\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n if (defaults.record) {\n const outcome = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n \"elevenlabs\",\n req.url ?? \"/v1/sound-generation\",\n fixtures,\n defaults,\n body,\n );\n if (outcome === \"handled_by_hook\") return;\n if (outcome !== \"not_configured\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n });\n return;\n }\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 404,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 404,\n JSON.stringify({\n error: {\n message: \"No fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n\n const response = await resolveResponse(fixture, syntheticReq);\n\n // Error fixture\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, serializeErrorResponse(response), {\n retryAfter: response.retryAfter,\n });\n return;\n }\n\n // plan returns JSON text, not audio\n if (subType === \"plan\") {\n if (!isTextResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: {\n message: \"Fixture response is not a text type for plan endpoint\",\n type: \"server_error\",\n },\n }),\n );\n return;\n }\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(response.content);\n return;\n }\n\n // All other subTypes expect audio\n if (!isAudioResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: { message: \"Fixture response is not an audio type\", type: \"server_error\" },\n }),\n );\n return;\n }\n\n // Decode audio bytes and determine content type\n let audioBytes: Buffer;\n let contentType: string;\n\n if (typeof response.audio === \"string\") {\n audioBytes = Buffer.from(response.audio, \"base64\");\n const format = response.format ?? \"mp3\";\n contentType = FORMAT_TO_CONTENT_TYPE[format] ?? \"audio/mpeg\";\n } else {\n audioBytes = Buffer.from(response.audio.b64Json, \"base64\");\n contentType = response.audio.contentType ?? \"audio/mpeg\";\n }\n\n // Music endpoints get a song-id header\n if (subType === \"music\" || subType === \"stream\") {\n res.setHeader(\"song-id\", \"mock-song-\" + Date.now());\n }\n\n // Stream uses chunked transfer encoding\n if (subType === \"stream\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n res.writeHead(200, {\n \"Content-Type\": contentType,\n \"Transfer-Encoding\": \"chunked\",\n });\n res.end(audioBytes);\n return;\n }\n\n // Standard binary response for sound-generation and music\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n res.writeHead(200, { \"Content-Type\": contentType });\n res.end(audioBytes);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"elevenlabs-audio.js","names":[],"sources":["../src/elevenlabs-audio.ts"],"sourcesContent":["import { renderError } from \"./response/errors.js\";\nimport { resolveRequestDecisions, strictOverrideField } from \"./response/policy.js\";\nimport type http from \"node:http\";\nimport type { ChatCompletionRequest, Fixture, HandlerDefaults } from \"./types.js\";\nimport {\n isAudioResponse,\n isTextResponse,\n isErrorResponse,\n isJsonObject,\n flattenHeaders,\n FORMAT_TO_CONTENT_TYPE,\n getContext,\n getTestId,\n resolveResponse,\n strictNoMatchMessage,\n strictNoMatchLogLine,\n} from \"./helpers.js\";\nimport { matchFixtureDiagnostic } from \"./router.js\";\nimport { writeErrorResponse } from \"./sse-writer.js\";\nimport { proxyAndRecord } from \"./recorder.js\";\nimport type { Journal } from \"./journal.js\";\nimport { applyChaosAsync } from \"./chaos.js\";\n\nexport async function handleElevenLabsTTS(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n body: string,\n fixtures: Fixture[],\n defaults: HandlerDefaults,\n journal: Journal,\n voiceId: string,\n): Promise<void> {\n const path = req.url ?? `/v1/text-to-speech/${voiceId}`;\n const method = req.method ?? \"POST\";\n\n // Parse JSON body\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(body) as Record<string, unknown>;\n } catch (parseErr) {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n renderError(\"openai\", \"validation\", {\n message: `Malformed JSON: ${detail}`,\n type: \"invalid_request_error\",\n code: \"invalid_json\",\n }).body,\n );\n return;\n }\n\n // Reject bodies that parsed but are not a JSON object (e.g. `null`) before\n // touching fields — otherwise `parsed.text` throws a TypeError that surfaces\n // as a 500 instead of a 400.\n if (!isJsonObject(parsed)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n renderError(\"openai\", \"validation\", {\n message: \"Request body must be a JSON object\",\n type: \"invalid_request_error\",\n }).body,\n );\n return;\n }\n\n // Extract text from request body\n const promptText = typeof parsed.text === \"string\" && parsed.text ? parsed.text : undefined;\n\n // Build synthetic ChatCompletionRequest for fixture matching\n const syntheticReq: ChatCompletionRequest = {\n model: (parsed.model_id as string) ?? \"eleven_multilingual_v2\",\n messages: [{ role: \"user\", content: promptText ?? \"\" }],\n _endpointType: \"elevenlabs-tts\",\n _context: getContext(req),\n };\n\n // Validate required field\n if (!promptText) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n renderError(\"openai\", \"validation\", {\n message: \"Missing required parameter: 'text'\",\n type: \"invalid_request_error\",\n }).body,\n );\n return;\n }\n\n // Match fixture\n const testId = getTestId(req);\n const matchCounts = journal.getFixtureMatchCountsForTest(testId);\n const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n fixtures,\n syntheticReq,\n matchCounts,\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n }\n\n if (\n await applyChaosAsync(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n req.url,\n journal,\n { method, path, headers: flattenHeaders(req.headers), body: syntheticReq },\n fixture ? \"fixture\" : \"proxy\",\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n // No fixture match\n if (!fixture) {\n const effectiveStrict = resolveRequestDecisions(defaults.strict, req.headers).fixtureMiss;\n if (effectiveStrict) {\n const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n defaults.logger.error(strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 503,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 503,\n renderError(\"openai\", \"strict-miss\", {\n message: strictMessage,\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n }).body,\n );\n return;\n }\n if (defaults.record) {\n const outcome = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n \"elevenlabs\",\n req.url ?? `/v1/text-to-speech/${voiceId}`,\n fixtures,\n defaults,\n body,\n );\n if (outcome === \"handled_by_hook\") return;\n if (outcome !== \"not_configured\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n });\n return;\n }\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 404,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 404,\n renderError(\"openai\", \"fixture-miss\", {\n message: \"No fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n }).body,\n );\n return;\n }\n\n const response = await resolveResponse(fixture, syntheticReq);\n\n // Error fixture\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, renderError(\"openai\", \"fixture\", response.error).body, {\n retryAfter: response.retryAfter,\n });\n return;\n }\n\n // Expect audio response\n if (!isAudioResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n renderError(\"openai\", \"unknown-response\", {\n message: \"Fixture response is not an audio type\",\n type: \"server_error\",\n }).body,\n );\n return;\n }\n\n // Decode audio bytes and determine content type\n let audioBytes: Buffer;\n let contentType: string;\n\n if (typeof response.audio === \"string\") {\n audioBytes = Buffer.from(response.audio, \"base64\");\n const format = response.format ?? \"mp3\";\n contentType = FORMAT_TO_CONTENT_TYPE[format] ?? \"audio/mpeg\";\n } else {\n audioBytes = Buffer.from(response.audio.b64Json, \"base64\");\n contentType = response.audio.contentType ?? \"audio/mpeg\";\n }\n\n // Standard binary response\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n res.writeHead(200, { \"Content-Type\": contentType });\n res.end(audioBytes);\n}\n\nexport async function handleElevenLabsAudio(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n body: string,\n fixtures: Fixture[],\n defaults: HandlerDefaults,\n journal: Journal,\n subType: string, // \"sound-generation\" | \"music\" | \"stream\" | \"plan\"\n): Promise<void> {\n const path = req.url ?? \"/v1/sound-generation\";\n const method = req.method ?? \"POST\";\n\n // Parse JSON body\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(body) as Record<string, unknown>;\n } catch (parseErr) {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n renderError(\"openai\", \"validation\", {\n message: `Malformed JSON: ${detail}`,\n type: \"invalid_request_error\",\n code: \"invalid_json\",\n }).body,\n );\n return;\n }\n\n // Reject bodies that parsed but are not a JSON object (e.g. `null`) before\n // touching fields — otherwise `parsed.text` throws a TypeError that surfaces\n // as a 500 instead of a 400.\n if (!isJsonObject(parsed)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n renderError(\"openai\", \"validation\", {\n message: \"Request body must be a JSON object\",\n type: \"invalid_request_error\",\n }).body,\n );\n return;\n }\n\n // Extract prompt text based on subType\n let promptText: string | undefined;\n if (subType === \"sound-generation\") {\n if (typeof parsed.text === \"string\" && parsed.text) {\n promptText = parsed.text;\n }\n } else {\n // music, music-stream, music-plan all use \"prompt\" (or composition_plan fallback)\n if (typeof parsed.prompt === \"string\" && parsed.prompt) {\n promptText = parsed.prompt;\n } else if (parsed.composition_plan != null) {\n promptText =\n typeof parsed.composition_plan === \"string\"\n ? parsed.composition_plan\n : JSON.stringify(parsed.composition_plan);\n }\n }\n\n // Build synthetic ChatCompletionRequest for fixture matching (needed for journal even on validation failure)\n const syntheticReq: ChatCompletionRequest = {\n model:\n (parsed.model_id as string) ??\n (subType === \"sound-generation\" ? \"eleven_text_to_sound_v2\" : \"music_v1\"),\n messages: [{ role: \"user\", content: promptText ?? \"\" }],\n _endpointType: \"audio-gen\",\n _context: getContext(req),\n };\n\n // Validate required field\n if (!promptText) {\n const field = subType === \"sound-generation\" ? \"text\" : \"prompt\";\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n renderError(\"openai\", \"validation\", {\n message: `Missing required parameter: '${field}'`,\n type: \"invalid_request_error\",\n }).body,\n );\n return;\n }\n\n // Match fixture\n const testId = getTestId(req);\n const matchCounts = journal.getFixtureMatchCountsForTest(testId);\n const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n fixtures,\n syntheticReq,\n matchCounts,\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n }\n\n if (\n await applyChaosAsync(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n req.url,\n journal,\n { method, path, headers: flattenHeaders(req.headers), body: syntheticReq },\n fixture ? \"fixture\" : \"proxy\",\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n // No fixture match\n if (!fixture) {\n const effectiveStrict = resolveRequestDecisions(defaults.strict, req.headers).fixtureMiss;\n if (effectiveStrict) {\n const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n defaults.logger.error(strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 503,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 503,\n renderError(\"openai\", \"strict-miss\", {\n message: strictMessage,\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n }).body,\n );\n return;\n }\n if (defaults.record) {\n const outcome = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n \"elevenlabs\",\n req.url ?? \"/v1/sound-generation\",\n fixtures,\n defaults,\n body,\n );\n if (outcome === \"handled_by_hook\") return;\n if (outcome !== \"not_configured\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n });\n return;\n }\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 404,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 404,\n renderError(\"openai\", \"fixture-miss\", {\n message: \"No fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n }).body,\n );\n return;\n }\n\n const response = await resolveResponse(fixture, syntheticReq);\n\n // Error fixture\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, renderError(\"openai\", \"fixture\", response.error).body, {\n retryAfter: response.retryAfter,\n });\n return;\n }\n\n // plan returns JSON text, not audio\n if (subType === \"plan\") {\n if (!isTextResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n renderError(\"openai\", \"unknown-response\", {\n message: \"Fixture response is not a text type for plan endpoint\",\n type: \"server_error\",\n }).body,\n );\n return;\n }\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(response.content);\n return;\n }\n\n // All other subTypes expect audio\n if (!isAudioResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n renderError(\"openai\", \"unknown-response\", {\n message: \"Fixture response is not an audio type\",\n type: \"server_error\",\n }).body,\n );\n return;\n }\n\n // Decode audio bytes and determine content type\n let audioBytes: Buffer;\n let contentType: string;\n\n if (typeof response.audio === \"string\") {\n audioBytes = Buffer.from(response.audio, \"base64\");\n const format = response.format ?? \"mp3\";\n contentType = FORMAT_TO_CONTENT_TYPE[format] ?? \"audio/mpeg\";\n } else {\n audioBytes = Buffer.from(response.audio.b64Json, \"base64\");\n contentType = response.audio.contentType ?? \"audio/mpeg\";\n }\n\n // Music endpoints get a song-id header\n if (subType === \"music\" || subType === \"stream\") {\n res.setHeader(\"song-id\", \"mock-song-\" + Date.now());\n }\n\n // Stream uses chunked transfer encoding\n if (subType === \"stream\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n res.writeHead(200, {\n \"Content-Type\": contentType,\n \"Transfer-Encoding\": \"chunked\",\n });\n res.end(audioBytes);\n return;\n }\n\n // Standard binary response for sound-generation and music\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n res.writeHead(200, { \"Content-Type\": contentType });\n res.end(audioBytes);\n}\n"],"mappings":"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"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const require_errors = require('./response/errors.cjs');
|
|
2
|
+
const require_policy = require('./response/policy.cjs');
|
|
1
3
|
const require_helpers = require('./helpers.cjs');
|
|
2
4
|
const require_sse_writer = require('./sse-writer.cjs');
|
|
3
5
|
const require_chaos = require('./chaos.cjs');
|
|
@@ -289,19 +291,18 @@ function writeJson(res, status, payload) {
|
|
|
289
291
|
* proxy the very same miss.
|
|
290
292
|
*/
|
|
291
293
|
function noFixtureSource(defaults, headers) {
|
|
292
|
-
return require_helpers.wouldProxyMiss(
|
|
294
|
+
return require_helpers.wouldProxyMiss(!require_policy.resolveRequestDecisions(defaults.strict, headers).upstream, defaults.record, "elevenlabs") ? "proxy" : "internal";
|
|
293
295
|
}
|
|
294
296
|
function parseJsonObject(body, req, res, journal, path, method) {
|
|
295
297
|
let parsed;
|
|
296
298
|
try {
|
|
297
299
|
parsed = JSON.parse(body);
|
|
298
300
|
} catch (parseErr) {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
message: `Malformed JSON: ${detail}`,
|
|
301
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "validation", {
|
|
302
|
+
message: `Malformed JSON: ${parseErr instanceof Error ? parseErr.message : "unknown"}`,
|
|
302
303
|
type: "invalid_request_error",
|
|
303
304
|
code: "invalid_json"
|
|
304
|
-
}
|
|
305
|
+
}).body);
|
|
305
306
|
journal.add({
|
|
306
307
|
method,
|
|
307
308
|
path,
|
|
@@ -316,10 +317,10 @@ function parseJsonObject(body, req, res, journal, path, method) {
|
|
|
316
317
|
return null;
|
|
317
318
|
}
|
|
318
319
|
if (!require_helpers.isJsonObject(parsed)) {
|
|
319
|
-
require_sse_writer.writeErrorResponse(res, 400,
|
|
320
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "validation", {
|
|
320
321
|
message: "Request body must be a JSON object",
|
|
321
322
|
type: "invalid_request_error"
|
|
322
|
-
}
|
|
323
|
+
}).body);
|
|
323
324
|
journal.add({
|
|
324
325
|
method,
|
|
325
326
|
path,
|
|
@@ -347,14 +348,14 @@ function buildSyntheticReq(parsed, matchText, endpoint, modelFallback, req) {
|
|
|
347
348
|
};
|
|
348
349
|
}
|
|
349
350
|
async function missPath(req, res, syntheticReq, fixtures, defaults, journal, path, method, body, skippedBySequenceOrTurn, proxyOptions) {
|
|
350
|
-
if (
|
|
351
|
+
if (require_policy.resolveRequestDecisions(defaults.strict, req.headers).fixtureMiss) {
|
|
351
352
|
const strictMessage = require_helpers.strictNoMatchMessage(skippedBySequenceOrTurn);
|
|
352
353
|
defaults.logger.error(require_helpers.strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));
|
|
353
|
-
require_sse_writer.writeErrorResponse(res, 503,
|
|
354
|
+
require_sse_writer.writeErrorResponse(res, 503, require_errors.renderError("openai", "strict-miss", {
|
|
354
355
|
message: strictMessage,
|
|
355
356
|
type: "invalid_request_error",
|
|
356
357
|
code: "no_fixture_match"
|
|
357
|
-
}
|
|
358
|
+
}).body);
|
|
358
359
|
journal.add({
|
|
359
360
|
method,
|
|
360
361
|
path,
|
|
@@ -364,7 +365,7 @@ async function missPath(req, res, syntheticReq, fixtures, defaults, journal, pat
|
|
|
364
365
|
response: {
|
|
365
366
|
status: 503,
|
|
366
367
|
fixture: null,
|
|
367
|
-
...
|
|
368
|
+
...require_policy.strictOverrideField(defaults.strict, req.headers)
|
|
368
369
|
}
|
|
369
370
|
});
|
|
370
371
|
return "handled";
|
|
@@ -391,11 +392,11 @@ async function missPath(req, res, syntheticReq, fixtures, defaults, journal, pat
|
|
|
391
392
|
return "miss";
|
|
392
393
|
}
|
|
393
394
|
function writeNoMatch(req, res, syntheticReq, defaults, journal, path, method) {
|
|
394
|
-
require_sse_writer.writeErrorResponse(res, 404,
|
|
395
|
+
require_sse_writer.writeErrorResponse(res, 404, require_errors.renderError("openai", "fixture-miss", {
|
|
395
396
|
message: "No fixture matched",
|
|
396
397
|
type: "invalid_request_error",
|
|
397
398
|
code: "no_fixture_match"
|
|
398
|
-
}
|
|
399
|
+
}).body);
|
|
399
400
|
journal.add({
|
|
400
401
|
method,
|
|
401
402
|
path,
|
|
@@ -405,7 +406,7 @@ function writeNoMatch(req, res, syntheticReq, defaults, journal, path, method) {
|
|
|
405
406
|
response: {
|
|
406
407
|
status: 404,
|
|
407
408
|
fixture: null,
|
|
408
|
-
...
|
|
409
|
+
...require_policy.strictOverrideField(defaults.strict, req.headers)
|
|
409
410
|
}
|
|
410
411
|
});
|
|
411
412
|
}
|
|
@@ -478,10 +479,10 @@ async function handleElevenLabsVoiceDesign(req, res, body, fixtures, defaults, j
|
|
|
478
479
|
const description = typeof parsed.voice_description === "string" ? parsed.voice_description : void 0;
|
|
479
480
|
const syntheticReq = buildSyntheticReq(parsed, description ?? "", "elevenlabs-voice-design", "eleven_multilingual_ttv_v2", req);
|
|
480
481
|
if (description === void 0) {
|
|
481
|
-
require_sse_writer.writeErrorResponse(res, 400,
|
|
482
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "validation", {
|
|
482
483
|
message: "Missing required parameter: 'voice_description'",
|
|
483
484
|
type: "invalid_request_error"
|
|
484
|
-
}
|
|
485
|
+
}).body);
|
|
485
486
|
journal.add({
|
|
486
487
|
method,
|
|
487
488
|
path,
|
|
@@ -531,7 +532,7 @@ async function handleElevenLabsVoiceDesign(req, res, body, fixtures, defaults, j
|
|
|
531
532
|
const response = await require_helpers.resolveResponse(fixture, syntheticReq);
|
|
532
533
|
if (require_helpers.isErrorResponse(response)) {
|
|
533
534
|
const status = response.status ?? 500;
|
|
534
|
-
require_sse_writer.writeErrorResponse(res, status,
|
|
535
|
+
require_sse_writer.writeErrorResponse(res, status, require_errors.renderError("openai", "fixture", response.error).body, { retryAfter: response.retryAfter });
|
|
535
536
|
journal.add({
|
|
536
537
|
method,
|
|
537
538
|
path,
|
|
@@ -546,10 +547,10 @@ async function handleElevenLabsVoiceDesign(req, res, body, fixtures, defaults, j
|
|
|
546
547
|
return;
|
|
547
548
|
}
|
|
548
549
|
if (!require_helpers.isJSONResponse(response)) {
|
|
549
|
-
require_sse_writer.writeErrorResponse(res, 500,
|
|
550
|
+
require_sse_writer.writeErrorResponse(res, 500, require_errors.renderError("openai", "unknown-response", {
|
|
550
551
|
message: "Fixture response is not a JSON type for voice design",
|
|
551
552
|
type: "server_error"
|
|
552
|
-
}
|
|
553
|
+
}).body);
|
|
553
554
|
journal.add({
|
|
554
555
|
method,
|
|
555
556
|
path,
|
|
@@ -586,10 +587,10 @@ async function handleElevenLabsVoiceCreate(req, res, body, fixtures, defaults, j
|
|
|
586
587
|
const tooShort = parsed.voice_name === "" ? "voice_name" : parsed.voice_description === "" ? "voice_description" : parsed.generated_voice_id === "" ? "generated_voice_id" : null;
|
|
587
588
|
const syntheticReq = buildSyntheticReq(parsed, typeof parsed.generated_voice_id === "string" ? parsed.generated_voice_id : "", "elevenlabs-voice", "eleven_multilingual_ttv_v2", req);
|
|
588
589
|
if (missing) {
|
|
589
|
-
require_sse_writer.writeErrorResponse(res, 400,
|
|
590
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("openai", "validation", {
|
|
590
591
|
message: `Missing required parameter: '${missing}'`,
|
|
591
592
|
type: "invalid_request_error"
|
|
592
|
-
}
|
|
593
|
+
}).body);
|
|
593
594
|
journal.add({
|
|
594
595
|
method,
|
|
595
596
|
path,
|
|
@@ -652,7 +653,7 @@ async function handleElevenLabsVoiceCreate(req, res, body, fixtures, defaults, j
|
|
|
652
653
|
const response = await require_helpers.resolveResponse(fixture, syntheticReq);
|
|
653
654
|
if (require_helpers.isErrorResponse(response)) {
|
|
654
655
|
const status = response.status ?? 500;
|
|
655
|
-
require_sse_writer.writeErrorResponse(res, status,
|
|
656
|
+
require_sse_writer.writeErrorResponse(res, status, require_errors.renderError("openai", "fixture", response.error).body, { retryAfter: response.retryAfter });
|
|
656
657
|
journal.add({
|
|
657
658
|
method,
|
|
658
659
|
path,
|
|
@@ -667,10 +668,10 @@ async function handleElevenLabsVoiceCreate(req, res, body, fixtures, defaults, j
|
|
|
667
668
|
return;
|
|
668
669
|
}
|
|
669
670
|
if (!require_helpers.isJSONResponse(response)) {
|
|
670
|
-
require_sse_writer.writeErrorResponse(res, 500,
|
|
671
|
+
require_sse_writer.writeErrorResponse(res, 500, require_errors.renderError("openai", "unknown-response", {
|
|
671
672
|
message: "Fixture response is not a JSON type for voice create",
|
|
672
673
|
type: "server_error"
|
|
673
|
-
}
|
|
674
|
+
}).body);
|
|
674
675
|
journal.add({
|
|
675
676
|
method,
|
|
676
677
|
path,
|
|
@@ -769,11 +770,11 @@ async function gateVoiceSlotChaos(req, res, syntheticReq, fixture, defaults, jou
|
|
|
769
770
|
*/
|
|
770
771
|
function writeVoiceSlotStrictRefusal(req, res, syntheticReq, defaults, journal, path, method, voiceId, skippedBySequenceOrTurn) {
|
|
771
772
|
defaults.logger.error(require_helpers.strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));
|
|
772
|
-
require_sse_writer.writeErrorResponse(res, 503,
|
|
773
|
+
require_sse_writer.writeErrorResponse(res, 503, require_errors.renderError("openai", "strict-miss", {
|
|
773
774
|
message: skippedBySequenceOrTurn > 0 ? require_helpers.strictNoMatchMessage(skippedBySequenceOrTurn) : `Strict mode: voice '${voiceId}' not found`,
|
|
774
775
|
type: "invalid_request_error",
|
|
775
776
|
code: "no_fixture_match"
|
|
776
|
-
}
|
|
777
|
+
}).body);
|
|
777
778
|
journal.add({
|
|
778
779
|
method,
|
|
779
780
|
path,
|
|
@@ -783,7 +784,7 @@ function writeVoiceSlotStrictRefusal(req, res, syntheticReq, defaults, journal,
|
|
|
783
784
|
response: {
|
|
784
785
|
status: 503,
|
|
785
786
|
fixture: null,
|
|
786
|
-
...
|
|
787
|
+
...require_policy.strictOverrideField(defaults.strict, req.headers)
|
|
787
788
|
}
|
|
788
789
|
});
|
|
789
790
|
}
|
|
@@ -830,7 +831,7 @@ async function replayVoiceSlotFixture(req, res, syntheticReq, fixture, journal,
|
|
|
830
831
|
const response = await require_helpers.resolveResponse(fixture, syntheticReq);
|
|
831
832
|
if (require_helpers.isErrorResponse(response)) {
|
|
832
833
|
const status = response.status ?? 500;
|
|
833
|
-
require_sse_writer.writeErrorResponse(res, status,
|
|
834
|
+
require_sse_writer.writeErrorResponse(res, status, require_errors.renderError("openai", "fixture", response.error).body, { retryAfter: response.retryAfter });
|
|
834
835
|
journal.add({
|
|
835
836
|
method,
|
|
836
837
|
path,
|
|
@@ -845,10 +846,10 @@ async function replayVoiceSlotFixture(req, res, syntheticReq, fixture, journal,
|
|
|
845
846
|
return null;
|
|
846
847
|
}
|
|
847
848
|
if (!require_helpers.isJSONResponse(response)) {
|
|
848
|
-
require_sse_writer.writeErrorResponse(res, 500,
|
|
849
|
+
require_sse_writer.writeErrorResponse(res, 500, require_errors.renderError("openai", "unknown-response", {
|
|
849
850
|
message: `Fixture response is not a JSON type for ${routeLabel}`,
|
|
850
851
|
type: "server_error"
|
|
851
|
-
}
|
|
852
|
+
}).body);
|
|
852
853
|
journal.add({
|
|
853
854
|
method,
|
|
854
855
|
path,
|
|
@@ -929,7 +930,7 @@ async function handleElevenLabsVoiceGet(req, res, voiceId, fixtures, defaults, j
|
|
|
929
930
|
serveStored(stored);
|
|
930
931
|
return;
|
|
931
932
|
}
|
|
932
|
-
if (
|
|
933
|
+
if (require_policy.resolveRequestDecisions(defaults.strict, req.headers).fixtureMiss) {
|
|
933
934
|
writeVoiceSlotStrictRefusal(req, res, syntheticReq, defaults, journal, path, method, voiceId, skippedBySequenceOrTurn);
|
|
934
935
|
return;
|
|
935
936
|
}
|
|
@@ -940,11 +941,11 @@ async function handleElevenLabsVoiceGet(req, res, voiceId, fixtures, defaults, j
|
|
|
940
941
|
return;
|
|
941
942
|
}
|
|
942
943
|
}
|
|
943
|
-
require_sse_writer.writeErrorResponse(res, 404,
|
|
944
|
+
require_sse_writer.writeErrorResponse(res, 404, require_errors.renderError("openai", "fixture-miss", {
|
|
944
945
|
message: `Voice '${voiceId}' not found`,
|
|
945
946
|
type: "invalid_request_error",
|
|
946
947
|
code: "voice_not_found"
|
|
947
|
-
}
|
|
948
|
+
}).body);
|
|
948
949
|
journal.add({
|
|
949
950
|
method,
|
|
950
951
|
path,
|
|
@@ -954,7 +955,7 @@ async function handleElevenLabsVoiceGet(req, res, voiceId, fixtures, defaults, j
|
|
|
954
955
|
response: {
|
|
955
956
|
status: 404,
|
|
956
957
|
fixture: null,
|
|
957
|
-
...
|
|
958
|
+
...require_policy.strictOverrideField(defaults.strict, req.headers)
|
|
958
959
|
}
|
|
959
960
|
});
|
|
960
961
|
}
|
|
@@ -1012,12 +1013,12 @@ async function handleElevenLabsVoiceDelete(req, res, voiceId, fixtures, defaults
|
|
|
1012
1013
|
response: {
|
|
1013
1014
|
status: 200,
|
|
1014
1015
|
fixture: null,
|
|
1015
|
-
...
|
|
1016
|
+
...require_policy.strictOverrideField(defaults.strict, req.headers)
|
|
1016
1017
|
}
|
|
1017
1018
|
});
|
|
1018
1019
|
return;
|
|
1019
1020
|
}
|
|
1020
|
-
if (
|
|
1021
|
+
if (require_policy.resolveRequestDecisions(defaults.strict, req.headers).fixtureMiss) {
|
|
1021
1022
|
writeVoiceSlotStrictRefusal(req, res, syntheticReq, defaults, journal, path, method, voiceId, skippedBySequenceOrTurn);
|
|
1022
1023
|
return;
|
|
1023
1024
|
}
|
|
@@ -1038,7 +1039,7 @@ async function handleElevenLabsVoiceDelete(req, res, voiceId, fixtures, defaults
|
|
|
1038
1039
|
response: {
|
|
1039
1040
|
status: 200,
|
|
1040
1041
|
fixture: null,
|
|
1041
|
-
...
|
|
1042
|
+
...require_policy.strictOverrideField(defaults.strict, req.headers)
|
|
1042
1043
|
}
|
|
1043
1044
|
});
|
|
1044
1045
|
}
|