@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/ollama.cjs
CHANGED
|
@@ -1,20 +1,27 @@
|
|
|
1
|
+
const require_errors = require('./response/errors.cjs');
|
|
2
|
+
const require_policy = require('./response/policy.cjs');
|
|
1
3
|
const require_helpers = require('./helpers.cjs');
|
|
2
4
|
const require_sse_writer = require('./sse-writer.cjs');
|
|
3
5
|
const require_chaos = require('./chaos.cjs');
|
|
4
6
|
const require_misbehavior = require('./misbehavior.cjs');
|
|
7
|
+
const require_embedding_request = require('./embedding-request.cjs');
|
|
5
8
|
const require_router = require('./router.cjs');
|
|
6
9
|
const require_recorder = require('./recorder.cjs');
|
|
7
|
-
const
|
|
10
|
+
const require_timing = require('./response/timing.cjs');
|
|
11
|
+
const require_deliver = require('./response/deliver.cjs');
|
|
12
|
+
const require_proxy = require('./response/proxy.cjs');
|
|
8
13
|
const require_ndjson_writer = require('./ndjson-writer.cjs');
|
|
14
|
+
const require_raw = require('./response/raw.cjs');
|
|
15
|
+
const require_ollama = require('./response/usage/codecs/ollama.cjs');
|
|
9
16
|
|
|
10
17
|
//#region src/ollama.ts
|
|
11
18
|
const DURATION_FIELDS = {
|
|
12
19
|
done_reason: "stop",
|
|
13
20
|
total_duration: 0,
|
|
14
21
|
load_duration: 0,
|
|
15
|
-
|
|
22
|
+
...require_ollama.render({ kind: "ordinary-zero" }, "prompt"),
|
|
16
23
|
prompt_eval_duration: 0,
|
|
17
|
-
|
|
24
|
+
...require_ollama.render({ kind: "ordinary-zero" }, "completion"),
|
|
18
25
|
eval_duration: 0
|
|
19
26
|
};
|
|
20
27
|
function ollamaToCompletionRequest(req) {
|
|
@@ -326,8 +333,10 @@ function prepareOllamaMisbehavior(plan, request, stream, chunkSize, effectiveStr
|
|
|
326
333
|
for (const block of outcome.ordered) if (block.type === "text") priorContent += block.text;
|
|
327
334
|
else if (index++ === plan.target?.index) break;
|
|
328
335
|
}
|
|
336
|
+
const chunks = stream ? [...buildOllamaChatTextChunks(priorContent, model, chunkSize).slice(0, -1), { error }] : [{ error }];
|
|
329
337
|
return {
|
|
330
|
-
|
|
338
|
+
build: () => chunks,
|
|
339
|
+
reasoning: void 0,
|
|
331
340
|
status: stream ? 200 : 500,
|
|
332
341
|
summary: {
|
|
333
342
|
...plan.summary,
|
|
@@ -343,61 +352,64 @@ function prepareOllamaMisbehavior(plan, request, stream, chunkSize, effectiveStr
|
|
|
343
352
|
arguments: parsed.text
|
|
344
353
|
};
|
|
345
354
|
});
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
355
|
+
const reasoning = plan.summary.fault === "reasoning-only" ? plan.reasoning ?? "" : require_helpers.resolveReasoningForModel("reasoning" in response ? response.reasoning : void 0, model, effectiveStrict, logger) ?? "";
|
|
356
|
+
const completion = content + reasoning + servedToolCalls.map((call) => call.name + call.arguments).join("");
|
|
357
|
+
const build = () => {
|
|
358
|
+
let chunks;
|
|
359
|
+
if (plan.summary.fault === "reasoning-only") {
|
|
360
|
+
const base = {
|
|
361
|
+
model,
|
|
362
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
363
|
+
};
|
|
364
|
+
if (stream) {
|
|
365
|
+
chunks = [];
|
|
366
|
+
for (let i = 0; i < reasoning.length; i += chunkSize) chunks.push({
|
|
367
|
+
...base,
|
|
368
|
+
message: {
|
|
369
|
+
role: "assistant",
|
|
370
|
+
content: "",
|
|
371
|
+
thinking: reasoning.slice(i, i + chunkSize)
|
|
372
|
+
},
|
|
373
|
+
done: false
|
|
374
|
+
});
|
|
375
|
+
chunks.push({
|
|
376
|
+
...base,
|
|
377
|
+
message: {
|
|
378
|
+
role: "assistant",
|
|
379
|
+
content: ""
|
|
380
|
+
},
|
|
381
|
+
done: true,
|
|
382
|
+
...DURATION_FIELDS,
|
|
383
|
+
done_reason: "length"
|
|
384
|
+
});
|
|
385
|
+
} else chunks = [{
|
|
357
386
|
...base,
|
|
358
387
|
message: {
|
|
359
388
|
role: "assistant",
|
|
360
389
|
content: "",
|
|
361
|
-
thinking: reasoning
|
|
362
|
-
},
|
|
363
|
-
done: false
|
|
364
|
-
});
|
|
365
|
-
chunks.push({
|
|
366
|
-
...base,
|
|
367
|
-
message: {
|
|
368
|
-
role: "assistant",
|
|
369
|
-
content: ""
|
|
390
|
+
thinking: reasoning
|
|
370
391
|
},
|
|
371
392
|
done: true,
|
|
372
393
|
...DURATION_FIELDS,
|
|
373
394
|
done_reason: "length"
|
|
374
|
-
}
|
|
375
|
-
} else chunks = [
|
|
376
|
-
...base,
|
|
377
|
-
message: {
|
|
378
|
-
role: "assistant",
|
|
379
|
-
content: "",
|
|
380
|
-
thinking: reasoning
|
|
381
|
-
},
|
|
382
|
-
done: true,
|
|
383
|
-
...DURATION_FIELDS,
|
|
384
|
-
done_reason: "length"
|
|
385
|
-
}];
|
|
386
|
-
} else {
|
|
387
|
-
reasoning = require_helpers.resolveReasoningForModel("reasoning" in response ? response.reasoning : void 0, model, effectiveStrict, logger) ?? "";
|
|
388
|
-
if (combined) chunks = stream ? buildOllamaChatContentWithToolCallsChunks(content, calls, model, chunkSize, reasoning, response.blocks) : [buildOllamaChatContentWithToolCallsResponse(content, calls, model, reasoning, response.blocks)];
|
|
395
|
+
}];
|
|
396
|
+
} else if (combined) chunks = stream ? buildOllamaChatContentWithToolCallsChunks(content, calls, model, chunkSize, reasoning, response.blocks) : [buildOllamaChatContentWithToolCallsResponse(content, calls, model, reasoning, response.blocks)];
|
|
389
397
|
else if (require_helpers.isToolCallResponse(response)) chunks = stream ? buildOllamaChatToolCallChunks(calls, model, chunkSize, reasoning) : [buildOllamaChatToolCallResponse(calls, model, reasoning)];
|
|
390
398
|
else chunks = stream ? buildOllamaChatTextChunks(content, model, chunkSize, reasoning) : [buildOllamaChatTextResponse(content, model, reasoning)];
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
399
|
+
const terminal = chunks.length - 1;
|
|
400
|
+
chunks[terminal] = {
|
|
401
|
+
...chunks[terminal],
|
|
402
|
+
...require_ollama.render({
|
|
403
|
+
kind: "applied-chat-estimate",
|
|
404
|
+
messages: request.messages,
|
|
405
|
+
completion
|
|
406
|
+
})
|
|
407
|
+
};
|
|
408
|
+
return chunks;
|
|
398
409
|
};
|
|
399
410
|
return {
|
|
400
|
-
|
|
411
|
+
build,
|
|
412
|
+
reasoning,
|
|
401
413
|
status: 200,
|
|
402
414
|
summary: {
|
|
403
415
|
...plan.summary,
|
|
@@ -467,10 +479,10 @@ async function handleOllama(req, res, raw, fixtures, journal, defaults, setCorsH
|
|
|
467
479
|
fixture: null
|
|
468
480
|
}
|
|
469
481
|
});
|
|
470
|
-
require_sse_writer.writeErrorResponse(res, 400,
|
|
482
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("ollama", "validation", {
|
|
471
483
|
message: `Malformed JSON body: ${detail}`,
|
|
472
484
|
type: "invalid_request_error"
|
|
473
|
-
}
|
|
485
|
+
}).body);
|
|
474
486
|
return;
|
|
475
487
|
}
|
|
476
488
|
if (!require_helpers.isJsonObject(ollamaReq)) {
|
|
@@ -484,10 +496,10 @@ async function handleOllama(req, res, raw, fixtures, journal, defaults, setCorsH
|
|
|
484
496
|
fixture: null
|
|
485
497
|
}
|
|
486
498
|
});
|
|
487
|
-
require_sse_writer.writeErrorResponse(res, 400,
|
|
499
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("ollama", "validation", {
|
|
488
500
|
message: "Request body must be a JSON object",
|
|
489
501
|
type: "invalid_request_error"
|
|
490
|
-
}
|
|
502
|
+
}).body);
|
|
491
503
|
return;
|
|
492
504
|
}
|
|
493
505
|
let chatShapeError = require_helpers.validateChatMessages(ollamaReq.messages) ?? require_helpers.validateToolsField(ollamaReq.tools);
|
|
@@ -506,17 +518,20 @@ async function handleOllama(req, res, raw, fixtures, journal, defaults, setCorsH
|
|
|
506
518
|
fixture: null
|
|
507
519
|
}
|
|
508
520
|
});
|
|
509
|
-
require_sse_writer.writeErrorResponse(res, 400,
|
|
521
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("ollama", "validation", {
|
|
510
522
|
message: `Invalid request: ${chatShapeError}`,
|
|
511
523
|
type: "invalid_request_error"
|
|
512
|
-
}
|
|
524
|
+
}).body);
|
|
513
525
|
return;
|
|
514
526
|
}
|
|
515
527
|
const completionReq = ollamaToCompletionRequest(ollamaReq);
|
|
516
528
|
completionReq._endpointType = "chat";
|
|
517
529
|
completionReq._context = require_helpers.getContext(req);
|
|
518
530
|
const testId = require_helpers.getTestId(req);
|
|
519
|
-
const { fixture, skippedBySequenceOrTurn } = require_router.matchFixtureDiagnostic(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform,
|
|
531
|
+
const { fixture, skippedBySequenceOrTurn } = require_router.matchFixtureDiagnostic(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform, {
|
|
532
|
+
...require_router.recordMatchOptions(!!defaults.record, defaults.logger),
|
|
533
|
+
wire: "ollama"
|
|
534
|
+
});
|
|
520
535
|
if (fixture) {
|
|
521
536
|
journal.incrementFixtureMatchCount(fixture, fixtures, testId);
|
|
522
537
|
logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);
|
|
@@ -528,7 +543,7 @@ async function handleOllama(req, res, raw, fixtures, journal, defaults, setCorsH
|
|
|
528
543
|
body: completionReq
|
|
529
544
|
}, fixture ? "fixture" : "proxy", defaults.registry, defaults.logger)) return;
|
|
530
545
|
if (!fixture) {
|
|
531
|
-
if (
|
|
546
|
+
if (require_policy.resolveRequestDecisions(defaults.strict, req.headers).fixtureMiss) {
|
|
532
547
|
const strictStatus = 503;
|
|
533
548
|
const strictMessage = require_helpers.strictNoMatchMessage(skippedBySequenceOrTurn);
|
|
534
549
|
logger.error(require_helpers.strictNoMatchLogLine(req.method ?? "POST", urlPath, skippedBySequenceOrTurn));
|
|
@@ -540,17 +555,17 @@ async function handleOllama(req, res, raw, fixtures, journal, defaults, setCorsH
|
|
|
540
555
|
response: {
|
|
541
556
|
status: strictStatus,
|
|
542
557
|
fixture: null,
|
|
543
|
-
...
|
|
558
|
+
...require_policy.strictOverrideField(defaults.strict, req.headers)
|
|
544
559
|
}
|
|
545
560
|
});
|
|
546
|
-
require_sse_writer.writeErrorResponse(res, strictStatus,
|
|
561
|
+
require_sse_writer.writeErrorResponse(res, strictStatus, require_errors.renderError("ollama", "strict-miss", {
|
|
547
562
|
message: strictMessage,
|
|
548
563
|
type: "invalid_request_error"
|
|
549
|
-
}
|
|
564
|
+
}).body);
|
|
550
565
|
return;
|
|
551
566
|
}
|
|
552
567
|
if (defaults.record) {
|
|
553
|
-
const outcome = await require_recorder.proxyAndRecord(req, res, completionReq, "ollama", urlPath, fixtures, defaults, raw);
|
|
568
|
+
const { outcome, clientHungUp } = await require_proxy.withHangUpDetection(req, res, () => require_recorder.proxyAndRecord(req, res, completionReq, "ollama", urlPath, fixtures, defaults, raw));
|
|
554
569
|
if (outcome === "handled_by_hook") return;
|
|
555
570
|
if (outcome !== "not_configured") {
|
|
556
571
|
journal.add({
|
|
@@ -561,7 +576,8 @@ async function handleOllama(req, res, raw, fixtures, journal, defaults, setCorsH
|
|
|
561
576
|
response: {
|
|
562
577
|
status: res.statusCode ?? 200,
|
|
563
578
|
fixture: null,
|
|
564
|
-
source: "proxy"
|
|
579
|
+
source: "proxy",
|
|
580
|
+
...require_proxy.proxyInterruption(res, clientHungUp)
|
|
565
581
|
}
|
|
566
582
|
});
|
|
567
583
|
return;
|
|
@@ -575,13 +591,13 @@ async function handleOllama(req, res, raw, fixtures, journal, defaults, setCorsH
|
|
|
575
591
|
response: {
|
|
576
592
|
status: 404,
|
|
577
593
|
fixture: null,
|
|
578
|
-
...
|
|
594
|
+
...require_policy.strictOverrideField(defaults.strict, req.headers)
|
|
579
595
|
}
|
|
580
596
|
});
|
|
581
|
-
require_sse_writer.writeErrorResponse(res, 404,
|
|
597
|
+
require_sse_writer.writeErrorResponse(res, 404, require_errors.renderError("ollama", "fixture-miss", {
|
|
582
598
|
message: "No fixture matched",
|
|
583
599
|
type: "invalid_request_error"
|
|
584
|
-
}
|
|
600
|
+
}).body);
|
|
585
601
|
return;
|
|
586
602
|
}
|
|
587
603
|
const response = await require_helpers.resolveResponse(fixture, completionReq);
|
|
@@ -613,14 +629,50 @@ async function handleOllama(req, res, raw, fixtures, journal, defaults, setCorsH
|
|
|
613
629
|
});
|
|
614
630
|
const message = `${misbehavior.code}: ${misbehavior.message}`;
|
|
615
631
|
if (!misbehavior.summary?.evaluations.length) defaults.logger.error(message);
|
|
616
|
-
require_sse_writer.writeErrorResponse(res, misbehavior.status,
|
|
632
|
+
require_sse_writer.writeErrorResponse(res, misbehavior.status, require_errors.renderError("ollama", "misbehavior", {
|
|
633
|
+
message: misbehavior.message,
|
|
634
|
+
code: misbehavior.code
|
|
635
|
+
}).body);
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
638
|
+
if (require_helpers.isRawResponse(response)) {
|
|
639
|
+
await require_raw.serveRawResponse({
|
|
640
|
+
wire: "ollama",
|
|
641
|
+
stream: ollamaReq.stream !== false,
|
|
642
|
+
req,
|
|
643
|
+
res,
|
|
644
|
+
fixture,
|
|
645
|
+
response,
|
|
646
|
+
body: completionReq,
|
|
647
|
+
journal,
|
|
648
|
+
defaults,
|
|
649
|
+
testId,
|
|
650
|
+
misbehaviorSummary: misbehavior.summary,
|
|
651
|
+
errorWire: "ollama"
|
|
652
|
+
});
|
|
617
653
|
return;
|
|
618
654
|
}
|
|
619
655
|
const latency = fixture.latency ?? defaults.latency;
|
|
620
656
|
const chunkSize = Math.max(1, fixture.chunkSize ?? defaults.chunkSize);
|
|
657
|
+
const replaySpeed = fixture.replaySpeed ?? defaults.replaySpeed;
|
|
658
|
+
const streamTiming = {
|
|
659
|
+
latency,
|
|
660
|
+
streamingProfile: fixture.streamingProfile,
|
|
661
|
+
recordedTimings: fixture.recordedTimings,
|
|
662
|
+
replaySpeed
|
|
663
|
+
};
|
|
664
|
+
const jsonOpts = (payloadLength, duplicateId = false) => ({
|
|
665
|
+
surface: "other",
|
|
666
|
+
payloadLength,
|
|
667
|
+
chunkSize,
|
|
668
|
+
recordedTimings: fixture.recordedTimings,
|
|
669
|
+
duplicateId,
|
|
670
|
+
replaySpeed
|
|
671
|
+
});
|
|
621
672
|
const streaming = ollamaReq.stream !== false;
|
|
622
673
|
if (misbehavior.kind === "applied") {
|
|
623
|
-
const prepared = prepareOllamaMisbehavior(misbehavior, completionReq, streaming, chunkSize,
|
|
674
|
+
const prepared = prepareOllamaMisbehavior(misbehavior, completionReq, streaming, chunkSize, require_policy.resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression, logger);
|
|
675
|
+
const chunks = !streaming && prepared.status === 200 && require_timing.nonStreamingTimingEnabled(fixture, "other") ? void 0 : prepared.build();
|
|
624
676
|
const journalEntry = journal.add({
|
|
625
677
|
method: req.method ?? "POST",
|
|
626
678
|
path: urlPath,
|
|
@@ -637,24 +689,16 @@ async function handleOllama(req, res, raw, fixtures, journal, defaults, setCorsH
|
|
|
637
689
|
defaults,
|
|
638
690
|
testId
|
|
639
691
|
});
|
|
640
|
-
if (!streaming) {
|
|
692
|
+
if (!streaming && prepared.status !== 200) {
|
|
641
693
|
res.writeHead(prepared.status, { "Content-Type": "application/json" });
|
|
642
|
-
res.end(JSON.stringify(prepared.
|
|
643
|
-
} else {
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
signal: interruption?.signal,
|
|
651
|
-
onChunkSent: interruption?.tick
|
|
652
|
-
})) {
|
|
653
|
-
if (!res.writableEnded) res.destroy();
|
|
654
|
-
journalEntry.response.interrupted = true;
|
|
655
|
-
journalEntry.response.interruptReason = interruption?.reason();
|
|
656
|
-
}
|
|
657
|
-
interruption?.cleanup();
|
|
694
|
+
res.end(JSON.stringify((chunks ?? prepared.build())[0]));
|
|
695
|
+
} else if (!streaming) await require_deliver.deliverJson(res, journalEntry, fixture, () => (chunks ?? prepared.build())[0], {
|
|
696
|
+
...jsonOpts(require_timing.misbehaviorPayloadLength(misbehavior, misbehavior.reasoning === void 0 ? prepared.reasoning : void 0), !!misbehavior.duplicateId),
|
|
697
|
+
status: prepared.status
|
|
698
|
+
});
|
|
699
|
+
else {
|
|
700
|
+
const frames = chunks ?? prepared.build();
|
|
701
|
+
await require_deliver.deliverStream(res, journalEntry, fixture, require_ndjson_writer.ndjsonCodec(), frames, streamTiming);
|
|
658
702
|
}
|
|
659
703
|
return;
|
|
660
704
|
}
|
|
@@ -675,7 +719,7 @@ async function handleOllama(req, res, raw, fixtures, journal, defaults, setCorsH
|
|
|
675
719
|
defaults,
|
|
676
720
|
testId
|
|
677
721
|
});
|
|
678
|
-
require_sse_writer.writeErrorResponse(res, status,
|
|
722
|
+
require_sse_writer.writeErrorResponse(res, status, require_errors.renderError("openai", "fixture", response.error).body, { retryAfter: response.retryAfter });
|
|
679
723
|
return;
|
|
680
724
|
}
|
|
681
725
|
if (require_helpers.isCombinedFixtureResponse(response)) {
|
|
@@ -697,28 +741,12 @@ async function handleOllama(req, res, raw, fixtures, journal, defaults, setCorsH
|
|
|
697
741
|
testId
|
|
698
742
|
});
|
|
699
743
|
const functionToolCalls = require_helpers.requireEmittedFunctionToolCalls(response, "Ollama");
|
|
700
|
-
const effectiveStrict =
|
|
744
|
+
const effectiveStrict = require_policy.resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
|
|
701
745
|
const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, completionReq.model, effectiveStrict, logger);
|
|
702
|
-
if (!streaming)
|
|
703
|
-
|
|
704
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
705
|
-
res.end(JSON.stringify(body));
|
|
706
|
-
} else {
|
|
746
|
+
if (!streaming) await require_deliver.deliverJson(res, journalEntry, fixture, () => buildOllamaChatContentWithToolCallsResponse(response.content ?? "", functionToolCalls, completionReq.model, effReasoning, response.blocks), jsonOpts(require_timing.servedPayloadLength(response, effReasoning)));
|
|
747
|
+
else {
|
|
707
748
|
const chunks = buildOllamaChatContentWithToolCallsChunks(response.content ?? "", functionToolCalls, completionReq.model, chunkSize, effReasoning, response.blocks);
|
|
708
|
-
|
|
709
|
-
if (!await require_ndjson_writer.writeNDJSONStream(res, chunks, {
|
|
710
|
-
latency,
|
|
711
|
-
streamingProfile: fixture.streamingProfile,
|
|
712
|
-
recordedTimings: fixture.recordedTimings,
|
|
713
|
-
replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,
|
|
714
|
-
signal: interruption?.signal,
|
|
715
|
-
onChunkSent: interruption?.tick
|
|
716
|
-
})) {
|
|
717
|
-
if (!res.writableEnded) res.destroy();
|
|
718
|
-
journalEntry.response.interrupted = true;
|
|
719
|
-
journalEntry.response.interruptReason = interruption?.reason();
|
|
720
|
-
}
|
|
721
|
-
interruption?.cleanup();
|
|
749
|
+
await require_deliver.deliverStream(res, journalEntry, fixture, require_ndjson_writer.ndjsonCodec(), chunks, streamTiming);
|
|
722
750
|
}
|
|
723
751
|
return;
|
|
724
752
|
}
|
|
@@ -740,28 +768,12 @@ async function handleOllama(req, res, raw, fixtures, journal, defaults, setCorsH
|
|
|
740
768
|
defaults,
|
|
741
769
|
testId
|
|
742
770
|
});
|
|
743
|
-
const effectiveStrict =
|
|
771
|
+
const effectiveStrict = require_policy.resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
|
|
744
772
|
const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, completionReq.model, effectiveStrict, logger);
|
|
745
|
-
if (!streaming)
|
|
746
|
-
|
|
747
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
748
|
-
res.end(JSON.stringify(body));
|
|
749
|
-
} else {
|
|
773
|
+
if (!streaming) await require_deliver.deliverJson(res, journalEntry, fixture, () => buildOllamaChatTextResponse(response.content, completionReq.model, effReasoning), jsonOpts(require_timing.servedPayloadLength(response, effReasoning)));
|
|
774
|
+
else {
|
|
750
775
|
const chunks = buildOllamaChatTextChunks(response.content, completionReq.model, chunkSize, effReasoning);
|
|
751
|
-
|
|
752
|
-
if (!await require_ndjson_writer.writeNDJSONStream(res, chunks, {
|
|
753
|
-
latency,
|
|
754
|
-
streamingProfile: fixture.streamingProfile,
|
|
755
|
-
recordedTimings: fixture.recordedTimings,
|
|
756
|
-
replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,
|
|
757
|
-
signal: interruption?.signal,
|
|
758
|
-
onChunkSent: interruption?.tick
|
|
759
|
-
})) {
|
|
760
|
-
if (!res.writableEnded) res.destroy();
|
|
761
|
-
journalEntry.response.interrupted = true;
|
|
762
|
-
journalEntry.response.interruptReason = interruption?.reason();
|
|
763
|
-
}
|
|
764
|
-
interruption?.cleanup();
|
|
776
|
+
await require_deliver.deliverStream(res, journalEntry, fixture, require_ndjson_writer.ndjsonCodec(), chunks, streamTiming);
|
|
765
777
|
}
|
|
766
778
|
return;
|
|
767
779
|
}
|
|
@@ -784,28 +796,12 @@ async function handleOllama(req, res, raw, fixtures, journal, defaults, setCorsH
|
|
|
784
796
|
testId
|
|
785
797
|
});
|
|
786
798
|
const functionToolCalls = require_helpers.requireEmittedFunctionToolCalls(response, "Ollama");
|
|
787
|
-
const effectiveStrict =
|
|
799
|
+
const effectiveStrict = require_policy.resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
|
|
788
800
|
const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, completionReq.model, effectiveStrict, logger);
|
|
789
|
-
if (!streaming)
|
|
790
|
-
|
|
791
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
792
|
-
res.end(JSON.stringify(body));
|
|
793
|
-
} else {
|
|
801
|
+
if (!streaming) await require_deliver.deliverJson(res, journalEntry, fixture, () => buildOllamaChatToolCallResponse(functionToolCalls, completionReq.model, effReasoning), jsonOpts(require_timing.servedPayloadLength(response, effReasoning)));
|
|
802
|
+
else {
|
|
794
803
|
const chunks = buildOllamaChatToolCallChunks(functionToolCalls, completionReq.model, chunkSize, effReasoning);
|
|
795
|
-
|
|
796
|
-
if (!await require_ndjson_writer.writeNDJSONStream(res, chunks, {
|
|
797
|
-
latency,
|
|
798
|
-
streamingProfile: fixture.streamingProfile,
|
|
799
|
-
recordedTimings: fixture.recordedTimings,
|
|
800
|
-
replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,
|
|
801
|
-
signal: interruption?.signal,
|
|
802
|
-
onChunkSent: interruption?.tick
|
|
803
|
-
})) {
|
|
804
|
-
if (!res.writableEnded) res.destroy();
|
|
805
|
-
journalEntry.response.interrupted = true;
|
|
806
|
-
journalEntry.response.interruptReason = interruption?.reason();
|
|
807
|
-
}
|
|
808
|
-
interruption?.cleanup();
|
|
804
|
+
await require_deliver.deliverStream(res, journalEntry, fixture, require_ndjson_writer.ndjsonCodec(), chunks, streamTiming);
|
|
809
805
|
}
|
|
810
806
|
return;
|
|
811
807
|
}
|
|
@@ -824,10 +820,10 @@ async function handleOllama(req, res, raw, fixtures, journal, defaults, setCorsH
|
|
|
824
820
|
defaults,
|
|
825
821
|
testId
|
|
826
822
|
});
|
|
827
|
-
require_sse_writer.writeErrorResponse(res, 500,
|
|
823
|
+
require_sse_writer.writeErrorResponse(res, 500, require_errors.renderError("ollama", "unknown-response", {
|
|
828
824
|
message: "Fixture response did not match any known type",
|
|
829
825
|
type: "server_error"
|
|
830
|
-
}
|
|
826
|
+
}).body);
|
|
831
827
|
}
|
|
832
828
|
async function handleOllamaGenerate(req, res, raw, fixtures, journal, defaults, setCorsHeaders) {
|
|
833
829
|
setCorsHeaders(res);
|
|
@@ -847,10 +843,10 @@ async function handleOllamaGenerate(req, res, raw, fixtures, journal, defaults,
|
|
|
847
843
|
fixture: null
|
|
848
844
|
}
|
|
849
845
|
});
|
|
850
|
-
require_sse_writer.writeErrorResponse(res, 400,
|
|
846
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("ollama", "validation", {
|
|
851
847
|
message: `Malformed JSON body: ${detail}`,
|
|
852
848
|
type: "invalid_request_error"
|
|
853
|
-
}
|
|
849
|
+
}).body);
|
|
854
850
|
return;
|
|
855
851
|
}
|
|
856
852
|
if (!require_helpers.isJsonObject(generateReq)) {
|
|
@@ -864,10 +860,10 @@ async function handleOllamaGenerate(req, res, raw, fixtures, journal, defaults,
|
|
|
864
860
|
fixture: null
|
|
865
861
|
}
|
|
866
862
|
});
|
|
867
|
-
require_sse_writer.writeErrorResponse(res, 400,
|
|
863
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("ollama", "validation", {
|
|
868
864
|
message: "Request body must be a JSON object",
|
|
869
865
|
type: "invalid_request_error"
|
|
870
|
-
}
|
|
866
|
+
}).body);
|
|
871
867
|
return;
|
|
872
868
|
}
|
|
873
869
|
if (!generateReq.prompt || typeof generateReq.prompt !== "string") {
|
|
@@ -881,17 +877,20 @@ async function handleOllamaGenerate(req, res, raw, fixtures, journal, defaults,
|
|
|
881
877
|
fixture: null
|
|
882
878
|
}
|
|
883
879
|
});
|
|
884
|
-
require_sse_writer.writeErrorResponse(res, 400,
|
|
880
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("ollama", "validation", {
|
|
885
881
|
message: "Invalid request: prompt field is required",
|
|
886
882
|
type: "invalid_request_error"
|
|
887
|
-
}
|
|
883
|
+
}).body);
|
|
888
884
|
return;
|
|
889
885
|
}
|
|
890
886
|
const completionReq = ollamaGenerateToCompletionRequest(generateReq);
|
|
891
887
|
completionReq._endpointType = "chat";
|
|
892
888
|
completionReq._context = require_helpers.getContext(req);
|
|
893
889
|
const testId = require_helpers.getTestId(req);
|
|
894
|
-
const { fixture, skippedBySequenceOrTurn } = require_router.matchFixtureDiagnostic(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform,
|
|
890
|
+
const { fixture, skippedBySequenceOrTurn } = require_router.matchFixtureDiagnostic(fixtures, completionReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform, {
|
|
891
|
+
...require_router.recordMatchOptions(!!defaults.record, defaults.logger),
|
|
892
|
+
wire: "ollama-generate"
|
|
893
|
+
});
|
|
895
894
|
if (fixture) {
|
|
896
895
|
journal.incrementFixtureMatchCount(fixture, fixtures, testId);
|
|
897
896
|
defaults.logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);
|
|
@@ -903,7 +902,7 @@ async function handleOllamaGenerate(req, res, raw, fixtures, journal, defaults,
|
|
|
903
902
|
body: completionReq
|
|
904
903
|
}, fixture ? "fixture" : "proxy", defaults.registry, defaults.logger)) return;
|
|
905
904
|
if (!fixture) {
|
|
906
|
-
if (
|
|
905
|
+
if (require_policy.resolveRequestDecisions(defaults.strict, req.headers).fixtureMiss) {
|
|
907
906
|
const strictStatus = 503;
|
|
908
907
|
const strictMessage = require_helpers.strictNoMatchMessage(skippedBySequenceOrTurn);
|
|
909
908
|
defaults.logger.error(require_helpers.strictNoMatchLogLine(req.method ?? "POST", urlPath, skippedBySequenceOrTurn));
|
|
@@ -915,17 +914,17 @@ async function handleOllamaGenerate(req, res, raw, fixtures, journal, defaults,
|
|
|
915
914
|
response: {
|
|
916
915
|
status: strictStatus,
|
|
917
916
|
fixture: null,
|
|
918
|
-
...
|
|
917
|
+
...require_policy.strictOverrideField(defaults.strict, req.headers)
|
|
919
918
|
}
|
|
920
919
|
});
|
|
921
|
-
require_sse_writer.writeErrorResponse(res, strictStatus,
|
|
920
|
+
require_sse_writer.writeErrorResponse(res, strictStatus, require_errors.renderError("ollama", "strict-miss", {
|
|
922
921
|
message: strictMessage,
|
|
923
922
|
type: "invalid_request_error"
|
|
924
|
-
}
|
|
923
|
+
}).body);
|
|
925
924
|
return;
|
|
926
925
|
}
|
|
927
926
|
if (defaults.record) {
|
|
928
|
-
const outcome = await require_recorder.proxyAndRecord(req, res, completionReq, "ollama", urlPath, fixtures, defaults, raw);
|
|
927
|
+
const { outcome, clientHungUp } = await require_proxy.withHangUpDetection(req, res, () => require_recorder.proxyAndRecord(req, res, completionReq, "ollama", urlPath, fixtures, defaults, raw));
|
|
929
928
|
if (outcome === "handled_by_hook") return;
|
|
930
929
|
if (outcome !== "not_configured") {
|
|
931
930
|
journal.add({
|
|
@@ -936,7 +935,8 @@ async function handleOllamaGenerate(req, res, raw, fixtures, journal, defaults,
|
|
|
936
935
|
response: {
|
|
937
936
|
status: res.statusCode ?? 200,
|
|
938
937
|
fixture: null,
|
|
939
|
-
source: "proxy"
|
|
938
|
+
source: "proxy",
|
|
939
|
+
...require_proxy.proxyInterruption(res, clientHungUp)
|
|
940
940
|
}
|
|
941
941
|
});
|
|
942
942
|
return;
|
|
@@ -950,13 +950,13 @@ async function handleOllamaGenerate(req, res, raw, fixtures, journal, defaults,
|
|
|
950
950
|
response: {
|
|
951
951
|
status: 404,
|
|
952
952
|
fixture: null,
|
|
953
|
-
...
|
|
953
|
+
...require_policy.strictOverrideField(defaults.strict, req.headers)
|
|
954
954
|
}
|
|
955
955
|
});
|
|
956
|
-
require_sse_writer.writeErrorResponse(res, 404,
|
|
956
|
+
require_sse_writer.writeErrorResponse(res, 404, require_errors.renderError("ollama", "fixture-miss", {
|
|
957
957
|
message: "No fixture matched",
|
|
958
958
|
type: "invalid_request_error"
|
|
959
|
-
}
|
|
959
|
+
}).body);
|
|
960
960
|
return;
|
|
961
961
|
}
|
|
962
962
|
const response = await require_helpers.resolveResponse(fixture, completionReq);
|
|
@@ -989,11 +989,46 @@ async function handleOllamaGenerate(req, res, raw, fixtures, journal, defaults,
|
|
|
989
989
|
});
|
|
990
990
|
const message = `${misbehavior.code}: ${misbehavior.message}`;
|
|
991
991
|
if (!misbehavior.summary?.evaluations.length) defaults.logger.error(message);
|
|
992
|
-
require_sse_writer.writeErrorResponse(res, misbehavior.status,
|
|
992
|
+
require_sse_writer.writeErrorResponse(res, misbehavior.status, require_errors.renderError("ollama", "misbehavior", {
|
|
993
|
+
message: misbehavior.message,
|
|
994
|
+
code: misbehavior.code
|
|
995
|
+
}).body);
|
|
996
|
+
return;
|
|
997
|
+
}
|
|
998
|
+
if (require_helpers.isRawResponse(response)) {
|
|
999
|
+
await require_raw.serveRawResponse({
|
|
1000
|
+
wire: "ollama-generate",
|
|
1001
|
+
stream: generateReq.stream !== false,
|
|
1002
|
+
req,
|
|
1003
|
+
res,
|
|
1004
|
+
fixture,
|
|
1005
|
+
response,
|
|
1006
|
+
body: completionReq,
|
|
1007
|
+
journal,
|
|
1008
|
+
defaults,
|
|
1009
|
+
testId,
|
|
1010
|
+
misbehaviorSummary: misbehavior.summary,
|
|
1011
|
+
errorWire: "ollama"
|
|
1012
|
+
});
|
|
993
1013
|
return;
|
|
994
1014
|
}
|
|
995
1015
|
const latency = fixture.latency ?? defaults.latency;
|
|
996
1016
|
const chunkSize = Math.max(1, fixture.chunkSize ?? defaults.chunkSize);
|
|
1017
|
+
const replaySpeed = fixture.replaySpeed ?? defaults.replaySpeed;
|
|
1018
|
+
const streamTiming = {
|
|
1019
|
+
latency,
|
|
1020
|
+
streamingProfile: fixture.streamingProfile,
|
|
1021
|
+
recordedTimings: fixture.recordedTimings,
|
|
1022
|
+
replaySpeed
|
|
1023
|
+
};
|
|
1024
|
+
const jsonOpts = (payloadLength, duplicateId = false) => ({
|
|
1025
|
+
surface: "other",
|
|
1026
|
+
payloadLength,
|
|
1027
|
+
chunkSize,
|
|
1028
|
+
recordedTimings: fixture.recordedTimings,
|
|
1029
|
+
duplicateId,
|
|
1030
|
+
replaySpeed
|
|
1031
|
+
});
|
|
997
1032
|
const streaming = generateReq.stream !== false;
|
|
998
1033
|
if (require_helpers.isErrorResponse(response)) {
|
|
999
1034
|
const status = response.status ?? 500;
|
|
@@ -1012,7 +1047,7 @@ async function handleOllamaGenerate(req, res, raw, fixtures, journal, defaults,
|
|
|
1012
1047
|
defaults,
|
|
1013
1048
|
testId
|
|
1014
1049
|
});
|
|
1015
|
-
require_sse_writer.writeErrorResponse(res, status,
|
|
1050
|
+
require_sse_writer.writeErrorResponse(res, status, require_errors.renderError("openai", "fixture", response.error).body, { retryAfter: response.retryAfter });
|
|
1016
1051
|
return;
|
|
1017
1052
|
}
|
|
1018
1053
|
if (require_helpers.isTextResponse(response)) {
|
|
@@ -1032,28 +1067,12 @@ async function handleOllamaGenerate(req, res, raw, fixtures, journal, defaults,
|
|
|
1032
1067
|
defaults,
|
|
1033
1068
|
testId
|
|
1034
1069
|
});
|
|
1035
|
-
const effectiveStrict =
|
|
1070
|
+
const effectiveStrict = require_policy.resolveRequestDecisions(defaults.strict, req.headers).reasoningSuppression;
|
|
1036
1071
|
const effReasoning = require_helpers.resolveReasoningForModel(response.reasoning, completionReq.model, effectiveStrict, defaults.logger);
|
|
1037
|
-
if (!streaming) {
|
|
1038
|
-
|
|
1039
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1040
|
-
res.end(JSON.stringify(body));
|
|
1041
|
-
} else {
|
|
1072
|
+
if (!streaming) await require_deliver.deliverJson(res, journalEntry, fixture, () => buildOllamaGenerateTextResponse(response.content, completionReq.model, effReasoning), jsonOpts(require_timing.servedPayloadLength({ content: response.content }, effReasoning)));
|
|
1073
|
+
else {
|
|
1042
1074
|
const chunks = buildOllamaGenerateTextChunks(response.content, completionReq.model, chunkSize, effReasoning);
|
|
1043
|
-
|
|
1044
|
-
if (!await require_ndjson_writer.writeNDJSONStream(res, chunks, {
|
|
1045
|
-
latency,
|
|
1046
|
-
streamingProfile: fixture.streamingProfile,
|
|
1047
|
-
recordedTimings: fixture.recordedTimings,
|
|
1048
|
-
replaySpeed: fixture.replaySpeed ?? defaults.replaySpeed,
|
|
1049
|
-
signal: interruption?.signal,
|
|
1050
|
-
onChunkSent: interruption?.tick
|
|
1051
|
-
})) {
|
|
1052
|
-
if (!res.writableEnded) res.destroy();
|
|
1053
|
-
journalEntry.response.interrupted = true;
|
|
1054
|
-
journalEntry.response.interruptReason = interruption?.reason();
|
|
1055
|
-
}
|
|
1056
|
-
interruption?.cleanup();
|
|
1075
|
+
await require_deliver.deliverStream(res, journalEntry, fixture, require_ndjson_writer.ndjsonCodec(), chunks, streamTiming);
|
|
1057
1076
|
}
|
|
1058
1077
|
return;
|
|
1059
1078
|
}
|
|
@@ -1073,10 +1092,10 @@ async function handleOllamaGenerate(req, res, raw, fixtures, journal, defaults,
|
|
|
1073
1092
|
defaults,
|
|
1074
1093
|
testId
|
|
1075
1094
|
});
|
|
1076
|
-
require_sse_writer.writeErrorResponse(res, 400,
|
|
1095
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError("ollama", "validation", {
|
|
1077
1096
|
message: "Tool call fixtures are not supported on /api/generate — use /api/chat instead",
|
|
1078
1097
|
type: "invalid_request_error"
|
|
1079
|
-
}
|
|
1098
|
+
}).body);
|
|
1080
1099
|
return;
|
|
1081
1100
|
}
|
|
1082
1101
|
require_misbehavior.recordMisbehaviorOutcome({
|
|
@@ -1094,15 +1113,17 @@ async function handleOllamaGenerate(req, res, raw, fixtures, journal, defaults,
|
|
|
1094
1113
|
defaults,
|
|
1095
1114
|
testId
|
|
1096
1115
|
});
|
|
1097
|
-
require_sse_writer.writeErrorResponse(res, 500,
|
|
1116
|
+
require_sse_writer.writeErrorResponse(res, 500, require_errors.renderError("ollama", "unknown-response", {
|
|
1098
1117
|
message: "Fixture response did not match any known type",
|
|
1099
1118
|
type: "server_error"
|
|
1100
|
-
}
|
|
1119
|
+
}).body);
|
|
1101
1120
|
}
|
|
1102
1121
|
async function handleOllamaEmbeddings(req, res, raw, fixtures, journal, defaults, setCorsHeaders) {
|
|
1103
1122
|
const { logger } = defaults;
|
|
1104
1123
|
setCorsHeaders(res);
|
|
1105
1124
|
const urlPath = req.url ?? "/api/embeddings";
|
|
1125
|
+
const currentEndpoint = urlPath.split("?")[0] === "/api/embed";
|
|
1126
|
+
const errorWire = currentEndpoint ? "ollama-embed" : "ollama";
|
|
1106
1127
|
let embReq;
|
|
1107
1128
|
try {
|
|
1108
1129
|
embReq = JSON.parse(raw);
|
|
@@ -1118,10 +1139,10 @@ async function handleOllamaEmbeddings(req, res, raw, fixtures, journal, defaults
|
|
|
1118
1139
|
fixture: null
|
|
1119
1140
|
}
|
|
1120
1141
|
});
|
|
1121
|
-
require_sse_writer.writeErrorResponse(res, 400,
|
|
1142
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError(errorWire, "validation", {
|
|
1122
1143
|
message: `Malformed JSON body: ${detail}`,
|
|
1123
1144
|
type: "invalid_request_error"
|
|
1124
|
-
}
|
|
1145
|
+
}).body);
|
|
1125
1146
|
return;
|
|
1126
1147
|
}
|
|
1127
1148
|
if (!require_helpers.isJsonObject(embReq)) {
|
|
@@ -1135,10 +1156,10 @@ async function handleOllamaEmbeddings(req, res, raw, fixtures, journal, defaults
|
|
|
1135
1156
|
fixture: null
|
|
1136
1157
|
}
|
|
1137
1158
|
});
|
|
1138
|
-
require_sse_writer.writeErrorResponse(res, 400,
|
|
1159
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError(errorWire, "validation", {
|
|
1139
1160
|
message: "Request body must be a JSON object",
|
|
1140
1161
|
type: "invalid_request_error"
|
|
1141
|
-
}
|
|
1162
|
+
}).body);
|
|
1142
1163
|
return;
|
|
1143
1164
|
}
|
|
1144
1165
|
const promptShapeError = embReq.prompt !== void 0 && embReq.prompt !== null && typeof embReq.prompt !== "string" ? "prompt field must be a string" : embReq.input !== void 0 && embReq.input !== null && require_helpers.normalizeEmbeddingInput(embReq.input) === null ? "input field must be a string or an array of strings" : null;
|
|
@@ -1153,14 +1174,15 @@ async function handleOllamaEmbeddings(req, res, raw, fixtures, journal, defaults
|
|
|
1153
1174
|
fixture: null
|
|
1154
1175
|
}
|
|
1155
1176
|
});
|
|
1156
|
-
require_sse_writer.writeErrorResponse(res, 400,
|
|
1177
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError(errorWire, "validation", {
|
|
1157
1178
|
message: `Invalid request: ${promptShapeError}`,
|
|
1158
1179
|
type: "invalid_request_error"
|
|
1159
|
-
}
|
|
1180
|
+
}).body);
|
|
1160
1181
|
return;
|
|
1161
1182
|
}
|
|
1162
|
-
const
|
|
1163
|
-
|
|
1183
|
+
const inputs = require_helpers.normalizeEmbeddingInput(currentEndpoint ? embReq.input ?? embReq.prompt : embReq.prompt ?? embReq.input);
|
|
1184
|
+
const inputText = currentEndpoint ? inputs?.join(" ") : embReq.prompt ?? (typeof embReq.input === "string" ? embReq.input : void 0) ?? (Array.isArray(embReq.input) ? embReq.input.join(" ") : void 0);
|
|
1185
|
+
if (!embReq.model || currentEndpoint && typeof embReq.model !== "string") {
|
|
1164
1186
|
journal.add({
|
|
1165
1187
|
method: req.method ?? "POST",
|
|
1166
1188
|
path: urlPath,
|
|
@@ -1171,10 +1193,10 @@ async function handleOllamaEmbeddings(req, res, raw, fixtures, journal, defaults
|
|
|
1171
1193
|
fixture: null
|
|
1172
1194
|
}
|
|
1173
1195
|
});
|
|
1174
|
-
require_sse_writer.writeErrorResponse(res, 400,
|
|
1196
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError(errorWire, "validation", {
|
|
1175
1197
|
message: "Invalid request: model field is required",
|
|
1176
1198
|
type: "invalid_request_error"
|
|
1177
|
-
}
|
|
1199
|
+
}).body);
|
|
1178
1200
|
return;
|
|
1179
1201
|
}
|
|
1180
1202
|
if (!inputText) {
|
|
@@ -1188,10 +1210,10 @@ async function handleOllamaEmbeddings(req, res, raw, fixtures, journal, defaults
|
|
|
1188
1210
|
fixture: null
|
|
1189
1211
|
}
|
|
1190
1212
|
});
|
|
1191
|
-
require_sse_writer.writeErrorResponse(res, 400,
|
|
1213
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError(errorWire, "validation", {
|
|
1192
1214
|
message: "Invalid request: prompt or input field is required",
|
|
1193
1215
|
type: "invalid_request_error"
|
|
1194
|
-
}
|
|
1216
|
+
}).body);
|
|
1195
1217
|
return;
|
|
1196
1218
|
}
|
|
1197
1219
|
const syntheticReq = {
|
|
@@ -1201,6 +1223,11 @@ async function handleOllamaEmbeddings(req, res, raw, fixtures, journal, defaults
|
|
|
1201
1223
|
_endpointType: "embedding",
|
|
1202
1224
|
_context: require_helpers.getContext(req)
|
|
1203
1225
|
};
|
|
1226
|
+
require_embedding_request.setEmbeddingRequest(syntheticReq, {
|
|
1227
|
+
operation: currentEndpoint ? "/api/embed" : "/api/embeddings",
|
|
1228
|
+
input: currentEndpoint ? embReq.input ?? embReq.prompt ?? "" : embReq.prompt ?? embReq.input ?? "",
|
|
1229
|
+
...embReq.dimensions !== void 0 && { dimensions: embReq.dimensions }
|
|
1230
|
+
});
|
|
1204
1231
|
const testId = require_helpers.getTestId(req);
|
|
1205
1232
|
const { fixture, skippedBySequenceOrTurn } = require_router.matchFixtureDiagnostic(fixtures, syntheticReq, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform, require_router.recordMatchOptions(!!defaults.record, defaults.logger));
|
|
1206
1233
|
if (fixture) {
|
|
@@ -1227,7 +1254,23 @@ async function handleOllamaEmbeddings(req, res, raw, fixtures, journal, defaults
|
|
|
1227
1254
|
fixture
|
|
1228
1255
|
}
|
|
1229
1256
|
});
|
|
1230
|
-
require_sse_writer.writeErrorResponse(res, status,
|
|
1257
|
+
require_sse_writer.writeErrorResponse(res, status, require_errors.renderError(currentEndpoint ? "ollama-embed" : "openai", "fixture", response.error).body, { retryAfter: response.retryAfter });
|
|
1258
|
+
return;
|
|
1259
|
+
}
|
|
1260
|
+
if (currentEndpoint && require_helpers.isJSONResponse(response)) {
|
|
1261
|
+
const status = response.status ?? 200;
|
|
1262
|
+
journal.add({
|
|
1263
|
+
method: req.method ?? "POST",
|
|
1264
|
+
path: urlPath,
|
|
1265
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
1266
|
+
body: syntheticReq,
|
|
1267
|
+
response: {
|
|
1268
|
+
status,
|
|
1269
|
+
fixture
|
|
1270
|
+
}
|
|
1271
|
+
});
|
|
1272
|
+
res.writeHead(status, { "Content-Type": "application/json" });
|
|
1273
|
+
res.end(JSON.stringify(response.json));
|
|
1231
1274
|
return;
|
|
1232
1275
|
}
|
|
1233
1276
|
if (require_helpers.isEmbeddingResponse(response)) {
|
|
@@ -1241,7 +1284,10 @@ async function handleOllamaEmbeddings(req, res, raw, fixtures, journal, defaults
|
|
|
1241
1284
|
fixture
|
|
1242
1285
|
}
|
|
1243
1286
|
});
|
|
1244
|
-
const body = {
|
|
1287
|
+
const body = currentEndpoint ? {
|
|
1288
|
+
model: embReq.model,
|
|
1289
|
+
embeddings: (inputs ?? []).map(() => [...response.embedding])
|
|
1290
|
+
} : {
|
|
1245
1291
|
model: embReq.model,
|
|
1246
1292
|
embedding: [...response.embedding]
|
|
1247
1293
|
};
|
|
@@ -1259,13 +1305,13 @@ async function handleOllamaEmbeddings(req, res, raw, fixtures, journal, defaults
|
|
|
1259
1305
|
fixture
|
|
1260
1306
|
}
|
|
1261
1307
|
});
|
|
1262
|
-
require_sse_writer.writeErrorResponse(res, 500,
|
|
1308
|
+
require_sse_writer.writeErrorResponse(res, 500, require_errors.renderError(errorWire, "unknown-response", {
|
|
1263
1309
|
message: "Fixture response did not match any known embedding type (must have embedding or error)",
|
|
1264
1310
|
type: "server_error"
|
|
1265
|
-
}
|
|
1311
|
+
}).body);
|
|
1266
1312
|
return;
|
|
1267
1313
|
}
|
|
1268
|
-
if (
|
|
1314
|
+
if (require_policy.resolveRequestDecisions(defaults.strict, req.headers).fixtureMiss) {
|
|
1269
1315
|
const strictMessage = require_helpers.strictNoMatchMessage(skippedBySequenceOrTurn);
|
|
1270
1316
|
logger.error(require_helpers.strictNoMatchLogLine(req.method ?? "POST", urlPath, skippedBySequenceOrTurn));
|
|
1271
1317
|
journal.add({
|
|
@@ -1276,13 +1322,13 @@ async function handleOllamaEmbeddings(req, res, raw, fixtures, journal, defaults
|
|
|
1276
1322
|
response: {
|
|
1277
1323
|
status: 503,
|
|
1278
1324
|
fixture: null,
|
|
1279
|
-
...
|
|
1325
|
+
...require_policy.strictOverrideField(defaults.strict, req.headers)
|
|
1280
1326
|
}
|
|
1281
1327
|
});
|
|
1282
|
-
require_sse_writer.writeErrorResponse(res, 503,
|
|
1328
|
+
require_sse_writer.writeErrorResponse(res, 503, require_errors.renderError(errorWire, "strict-miss", {
|
|
1283
1329
|
message: strictMessage,
|
|
1284
1330
|
type: "invalid_request_error"
|
|
1285
|
-
}
|
|
1331
|
+
}).body);
|
|
1286
1332
|
return;
|
|
1287
1333
|
}
|
|
1288
1334
|
if (defaults.record) {
|
|
@@ -1303,8 +1349,25 @@ async function handleOllamaEmbeddings(req, res, raw, fixtures, journal, defaults
|
|
|
1303
1349
|
return;
|
|
1304
1350
|
}
|
|
1305
1351
|
}
|
|
1352
|
+
const dimensions = currentEndpoint ? require_helpers.validateEmbeddingDimensions(embReq.dimensions) : 1536;
|
|
1353
|
+
if (dimensions === null) {
|
|
1354
|
+
journal.add({
|
|
1355
|
+
method: req.method ?? "POST",
|
|
1356
|
+
path: urlPath,
|
|
1357
|
+
headers: require_helpers.flattenHeaders(req.headers),
|
|
1358
|
+
body: syntheticReq,
|
|
1359
|
+
response: {
|
|
1360
|
+
status: 400,
|
|
1361
|
+
fixture: null
|
|
1362
|
+
}
|
|
1363
|
+
});
|
|
1364
|
+
require_sse_writer.writeErrorResponse(res, 400, require_errors.renderError(errorWire, "validation", {
|
|
1365
|
+
message: `Invalid request: dimensions must be an integer between 1 and ${require_helpers.MAX_EMBEDDING_DIMENSIONS}`,
|
|
1366
|
+
type: "invalid_request_error"
|
|
1367
|
+
}).body);
|
|
1368
|
+
return;
|
|
1369
|
+
}
|
|
1306
1370
|
logger.warn(`No embedding fixture matched for "${inputText.slice(0, 80)}" — returning deterministic fallback`);
|
|
1307
|
-
const embedding = require_helpers.generateDeterministicEmbedding(inputText);
|
|
1308
1371
|
journal.add({
|
|
1309
1372
|
method: req.method ?? "POST",
|
|
1310
1373
|
path: urlPath,
|
|
@@ -1315,9 +1378,12 @@ async function handleOllamaEmbeddings(req, res, raw, fixtures, journal, defaults
|
|
|
1315
1378
|
fixture: null
|
|
1316
1379
|
}
|
|
1317
1380
|
});
|
|
1318
|
-
const body = {
|
|
1381
|
+
const body = currentEndpoint ? {
|
|
1382
|
+
model: embReq.model,
|
|
1383
|
+
embeddings: (inputs ?? []).map((input) => require_helpers.generateDeterministicEmbedding(input, dimensions))
|
|
1384
|
+
} : {
|
|
1319
1385
|
model: embReq.model,
|
|
1320
|
-
embedding
|
|
1386
|
+
embedding: require_helpers.generateDeterministicEmbedding(inputText)
|
|
1321
1387
|
};
|
|
1322
1388
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
1323
1389
|
res.end(JSON.stringify(body));
|