@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
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
const require_openai = require('./openai.cjs');
|
|
2
|
+
|
|
3
|
+
//#region src/response/usage/codecs/openrouter.ts
|
|
4
|
+
/** Explicit extras follow canonical tokens; own prototype keys never pass through. */
|
|
5
|
+
const SHAPED_OR_CANONICAL_USAGE_KEYS = new Set([
|
|
6
|
+
...require_openai.OPENAI_TOKEN_KEYS,
|
|
7
|
+
"cost",
|
|
8
|
+
"cost_details",
|
|
9
|
+
"prompt_tokens_details",
|
|
10
|
+
"completion_tokens_details",
|
|
11
|
+
"is_byok"
|
|
12
|
+
]);
|
|
13
|
+
/**
|
|
14
|
+
* Keys that must never flow through the passthrough assignment below: a
|
|
15
|
+
* JSON-parsed usage frame (fixtures are attacker-adjacent — they mirror upstream
|
|
16
|
+
* provider responses) can carry a real own `__proto__`/`constructor`/`prototype`
|
|
17
|
+
* key, and a plain `usageExtras[key] = value` for one of those hits the
|
|
18
|
+
* prototype setter, corrupting the emitted object's prototype chain instead of
|
|
19
|
+
* emitting a data field. Real providers never send these, so skipping is safe.
|
|
20
|
+
*/
|
|
21
|
+
const UNSAFE_PROTO_KEYS = new Set([
|
|
22
|
+
"__proto__",
|
|
23
|
+
"constructor",
|
|
24
|
+
"prototype"
|
|
25
|
+
]);
|
|
26
|
+
/** Keep suppliedness, required nested defaults and original unknown-key insertion order. */
|
|
27
|
+
function resolve(overrides) {
|
|
28
|
+
const u = overrides?.usage;
|
|
29
|
+
const usageExtras = {};
|
|
30
|
+
if (u?.cost !== void 0) {
|
|
31
|
+
usageExtras.cost = u.cost;
|
|
32
|
+
const cd = u.cost_details;
|
|
33
|
+
usageExtras.cost_details = {
|
|
34
|
+
...cd ?? {},
|
|
35
|
+
upstream_inference_cost: cd?.upstream_inference_cost ?? 0,
|
|
36
|
+
upstream_inference_prompt_cost: cd?.upstream_inference_prompt_cost ?? 0,
|
|
37
|
+
upstream_inference_completions_cost: cd?.upstream_inference_completions_cost ?? 0
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
if (u?.prompt_tokens_details !== void 0) usageExtras.prompt_tokens_details = {
|
|
41
|
+
...u.prompt_tokens_details,
|
|
42
|
+
cached_tokens: u.prompt_tokens_details.cached_tokens ?? 0
|
|
43
|
+
};
|
|
44
|
+
if (u?.completion_tokens_details !== void 0) usageExtras.completion_tokens_details = {
|
|
45
|
+
...u.completion_tokens_details,
|
|
46
|
+
reasoning_tokens: u.completion_tokens_details.reasoning_tokens ?? 0
|
|
47
|
+
};
|
|
48
|
+
if (u?.is_byok !== void 0) usageExtras.is_byok = u.is_byok;
|
|
49
|
+
for (const [key, value] of Object.entries(u ?? {})) {
|
|
50
|
+
if (value === void 0) continue;
|
|
51
|
+
if (SHAPED_OR_CANONICAL_USAGE_KEYS.has(key)) continue;
|
|
52
|
+
if (UNSAFE_PROTO_KEYS.has(key)) continue;
|
|
53
|
+
usageExtras[key] = value;
|
|
54
|
+
}
|
|
55
|
+
return usageExtras;
|
|
56
|
+
}
|
|
57
|
+
/** Wrap the rendered OpenAI usage without dropping fields on compatibility callers. */
|
|
58
|
+
function render(usage, extras) {
|
|
59
|
+
return {
|
|
60
|
+
...usage,
|
|
61
|
+
...extras
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
//#endregion
|
|
66
|
+
exports.render = render;
|
|
67
|
+
exports.resolve = resolve;
|
|
68
|
+
//# sourceMappingURL=openrouter.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openrouter.cjs","names":["OPENAI_TOKEN_KEYS"],"sources":["../../../../src/response/usage/codecs/openrouter.ts"],"sourcesContent":["import type { OpenRouterUsageExtras, ResponseOverrides } from \"../../../types.js\";\nimport { OPENAI_TOKEN_KEYS } from \"./openai.js\";\n\n/** Explicit extras follow canonical tokens; own prototype keys never pass through. */\nconst SHAPED_OR_CANONICAL_USAGE_KEYS = new Set([\n ...OPENAI_TOKEN_KEYS,\n \"cost\",\n \"cost_details\",\n \"prompt_tokens_details\",\n \"completion_tokens_details\",\n \"is_byok\",\n]);\n\n/**\n * Keys that must never flow through the passthrough assignment below: a\n * JSON-parsed usage frame (fixtures are attacker-adjacent — they mirror upstream\n * provider responses) can carry a real own `__proto__`/`constructor`/`prototype`\n * key, and a plain `usageExtras[key] = value` for one of those hits the\n * prototype setter, corrupting the emitted object's prototype chain instead of\n * emitting a data field. Real providers never send these, so skipping is safe.\n */\nconst UNSAFE_PROTO_KEYS = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n\n/** Keep suppliedness, required nested defaults and original unknown-key insertion order. */\nexport function resolve(overrides: ResponseOverrides | undefined): OpenRouterUsageExtras {\n const u = overrides?.usage;\n const usageExtras: OpenRouterUsageExtras = {};\n if (u?.cost !== undefined) {\n usageExtras.cost = u.cost;\n const cd = u.cost_details;\n usageExtras.cost_details = {\n ...(cd ?? {}),\n upstream_inference_cost: cd?.upstream_inference_cost ?? 0,\n upstream_inference_prompt_cost: cd?.upstream_inference_prompt_cost ?? 0,\n upstream_inference_completions_cost: cd?.upstream_inference_completions_cost ?? 0,\n };\n }\n if (u?.prompt_tokens_details !== undefined) {\n usageExtras.prompt_tokens_details = {\n ...u.prompt_tokens_details,\n cached_tokens: u.prompt_tokens_details.cached_tokens ?? 0,\n };\n }\n if (u?.completion_tokens_details !== undefined) {\n usageExtras.completion_tokens_details = {\n ...u.completion_tokens_details,\n reasoning_tokens: u.completion_tokens_details.reasoning_tokens ?? 0,\n };\n }\n if (u?.is_byok !== undefined) {\n usageExtras.is_byok = u.is_byok;\n }\n // Forward-compat passthrough (#368): a fixture's `usage` may carry provider\n // fields aimock does not model — typically written by the recorder straight\n // from a real upstream usage frame (OpenRouter `native_tokens_prompt`,\n // `native_tokens_completion`, …). Emit them verbatim rather than silently\n // dropping them, so a recorded usage object round-trips on replay. The\n // canonical token counts and every field shaped above are excluded: those are\n // already resolved onto the base usage object (see helpers.ts `resolveUsage`)\n // or handled with their own required-member defaults.\n for (const [key, value] of Object.entries(u ?? {})) {\n if (value === undefined) continue;\n if (SHAPED_OR_CANONICAL_USAGE_KEYS.has(key)) continue;\n if (UNSAFE_PROTO_KEYS.has(key)) continue;\n usageExtras[key] = value;\n }\n return usageExtras;\n}\n\n/** Wrap the rendered OpenAI usage without dropping fields on compatibility callers. */\nexport function render<T extends object>(\n usage: T,\n extras: OpenRouterUsageExtras,\n): T & OpenRouterUsageExtras {\n return { ...usage, ...extras };\n}\n"],"mappings":";;;;AAIA,MAAM,iCAAiC,IAAI,IAAI;CAC7C,GAAGA;CACH;CACA;CACA;CACA;CACA;CACD,CAAC;;;;;;;;;AAUF,MAAM,oBAAoB,IAAI,IAAI;CAAC;CAAa;CAAe;CAAY,CAAC;;AAG5E,SAAgB,QAAQ,WAAiE;CACvF,MAAM,IAAI,WAAW;CACrB,MAAM,cAAqC,EAAE;AAC7C,KAAI,GAAG,SAAS,QAAW;AACzB,cAAY,OAAO,EAAE;EACrB,MAAM,KAAK,EAAE;AACb,cAAY,eAAe;GACzB,GAAI,MAAM,EAAE;GACZ,yBAAyB,IAAI,2BAA2B;GACxD,gCAAgC,IAAI,kCAAkC;GACtE,qCAAqC,IAAI,uCAAuC;GACjF;;AAEH,KAAI,GAAG,0BAA0B,OAC/B,aAAY,wBAAwB;EAClC,GAAG,EAAE;EACL,eAAe,EAAE,sBAAsB,iBAAiB;EACzD;AAEH,KAAI,GAAG,8BAA8B,OACnC,aAAY,4BAA4B;EACtC,GAAG,EAAE;EACL,kBAAkB,EAAE,0BAA0B,oBAAoB;EACnE;AAEH,KAAI,GAAG,YAAY,OACjB,aAAY,UAAU,EAAE;AAU1B,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,EAAE,CAAC,EAAE;AAClD,MAAI,UAAU,OAAW;AACzB,MAAI,+BAA+B,IAAI,IAAI,CAAE;AAC7C,MAAI,kBAAkB,IAAI,IAAI,CAAE;AAChC,cAAY,OAAO;;AAErB,QAAO;;;AAIT,SAAgB,OACd,OACA,QAC2B;AAC3B,QAAO;EAAE,GAAG;EAAO,GAAG;EAAQ"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { OPENAI_TOKEN_KEYS } from "./openai.js";
|
|
2
|
+
|
|
3
|
+
//#region src/response/usage/codecs/openrouter.ts
|
|
4
|
+
/** Explicit extras follow canonical tokens; own prototype keys never pass through. */
|
|
5
|
+
const SHAPED_OR_CANONICAL_USAGE_KEYS = new Set([
|
|
6
|
+
...OPENAI_TOKEN_KEYS,
|
|
7
|
+
"cost",
|
|
8
|
+
"cost_details",
|
|
9
|
+
"prompt_tokens_details",
|
|
10
|
+
"completion_tokens_details",
|
|
11
|
+
"is_byok"
|
|
12
|
+
]);
|
|
13
|
+
/**
|
|
14
|
+
* Keys that must never flow through the passthrough assignment below: a
|
|
15
|
+
* JSON-parsed usage frame (fixtures are attacker-adjacent — they mirror upstream
|
|
16
|
+
* provider responses) can carry a real own `__proto__`/`constructor`/`prototype`
|
|
17
|
+
* key, and a plain `usageExtras[key] = value` for one of those hits the
|
|
18
|
+
* prototype setter, corrupting the emitted object's prototype chain instead of
|
|
19
|
+
* emitting a data field. Real providers never send these, so skipping is safe.
|
|
20
|
+
*/
|
|
21
|
+
const UNSAFE_PROTO_KEYS = new Set([
|
|
22
|
+
"__proto__",
|
|
23
|
+
"constructor",
|
|
24
|
+
"prototype"
|
|
25
|
+
]);
|
|
26
|
+
/** Keep suppliedness, required nested defaults and original unknown-key insertion order. */
|
|
27
|
+
function resolve(overrides) {
|
|
28
|
+
const u = overrides?.usage;
|
|
29
|
+
const usageExtras = {};
|
|
30
|
+
if (u?.cost !== void 0) {
|
|
31
|
+
usageExtras.cost = u.cost;
|
|
32
|
+
const cd = u.cost_details;
|
|
33
|
+
usageExtras.cost_details = {
|
|
34
|
+
...cd ?? {},
|
|
35
|
+
upstream_inference_cost: cd?.upstream_inference_cost ?? 0,
|
|
36
|
+
upstream_inference_prompt_cost: cd?.upstream_inference_prompt_cost ?? 0,
|
|
37
|
+
upstream_inference_completions_cost: cd?.upstream_inference_completions_cost ?? 0
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
if (u?.prompt_tokens_details !== void 0) usageExtras.prompt_tokens_details = {
|
|
41
|
+
...u.prompt_tokens_details,
|
|
42
|
+
cached_tokens: u.prompt_tokens_details.cached_tokens ?? 0
|
|
43
|
+
};
|
|
44
|
+
if (u?.completion_tokens_details !== void 0) usageExtras.completion_tokens_details = {
|
|
45
|
+
...u.completion_tokens_details,
|
|
46
|
+
reasoning_tokens: u.completion_tokens_details.reasoning_tokens ?? 0
|
|
47
|
+
};
|
|
48
|
+
if (u?.is_byok !== void 0) usageExtras.is_byok = u.is_byok;
|
|
49
|
+
for (const [key, value] of Object.entries(u ?? {})) {
|
|
50
|
+
if (value === void 0) continue;
|
|
51
|
+
if (SHAPED_OR_CANONICAL_USAGE_KEYS.has(key)) continue;
|
|
52
|
+
if (UNSAFE_PROTO_KEYS.has(key)) continue;
|
|
53
|
+
usageExtras[key] = value;
|
|
54
|
+
}
|
|
55
|
+
return usageExtras;
|
|
56
|
+
}
|
|
57
|
+
/** Wrap the rendered OpenAI usage without dropping fields on compatibility callers. */
|
|
58
|
+
function render(usage, extras) {
|
|
59
|
+
return {
|
|
60
|
+
...usage,
|
|
61
|
+
...extras
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
//#endregion
|
|
66
|
+
export { render, resolve };
|
|
67
|
+
//# sourceMappingURL=openrouter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openrouter.js","names":[],"sources":["../../../../src/response/usage/codecs/openrouter.ts"],"sourcesContent":["import type { OpenRouterUsageExtras, ResponseOverrides } from \"../../../types.js\";\nimport { OPENAI_TOKEN_KEYS } from \"./openai.js\";\n\n/** Explicit extras follow canonical tokens; own prototype keys never pass through. */\nconst SHAPED_OR_CANONICAL_USAGE_KEYS = new Set([\n ...OPENAI_TOKEN_KEYS,\n \"cost\",\n \"cost_details\",\n \"prompt_tokens_details\",\n \"completion_tokens_details\",\n \"is_byok\",\n]);\n\n/**\n * Keys that must never flow through the passthrough assignment below: a\n * JSON-parsed usage frame (fixtures are attacker-adjacent — they mirror upstream\n * provider responses) can carry a real own `__proto__`/`constructor`/`prototype`\n * key, and a plain `usageExtras[key] = value` for one of those hits the\n * prototype setter, corrupting the emitted object's prototype chain instead of\n * emitting a data field. Real providers never send these, so skipping is safe.\n */\nconst UNSAFE_PROTO_KEYS = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n\n/** Keep suppliedness, required nested defaults and original unknown-key insertion order. */\nexport function resolve(overrides: ResponseOverrides | undefined): OpenRouterUsageExtras {\n const u = overrides?.usage;\n const usageExtras: OpenRouterUsageExtras = {};\n if (u?.cost !== undefined) {\n usageExtras.cost = u.cost;\n const cd = u.cost_details;\n usageExtras.cost_details = {\n ...(cd ?? {}),\n upstream_inference_cost: cd?.upstream_inference_cost ?? 0,\n upstream_inference_prompt_cost: cd?.upstream_inference_prompt_cost ?? 0,\n upstream_inference_completions_cost: cd?.upstream_inference_completions_cost ?? 0,\n };\n }\n if (u?.prompt_tokens_details !== undefined) {\n usageExtras.prompt_tokens_details = {\n ...u.prompt_tokens_details,\n cached_tokens: u.prompt_tokens_details.cached_tokens ?? 0,\n };\n }\n if (u?.completion_tokens_details !== undefined) {\n usageExtras.completion_tokens_details = {\n ...u.completion_tokens_details,\n reasoning_tokens: u.completion_tokens_details.reasoning_tokens ?? 0,\n };\n }\n if (u?.is_byok !== undefined) {\n usageExtras.is_byok = u.is_byok;\n }\n // Forward-compat passthrough (#368): a fixture's `usage` may carry provider\n // fields aimock does not model — typically written by the recorder straight\n // from a real upstream usage frame (OpenRouter `native_tokens_prompt`,\n // `native_tokens_completion`, …). Emit them verbatim rather than silently\n // dropping them, so a recorded usage object round-trips on replay. The\n // canonical token counts and every field shaped above are excluded: those are\n // already resolved onto the base usage object (see helpers.ts `resolveUsage`)\n // or handled with their own required-member defaults.\n for (const [key, value] of Object.entries(u ?? {})) {\n if (value === undefined) continue;\n if (SHAPED_OR_CANONICAL_USAGE_KEYS.has(key)) continue;\n if (UNSAFE_PROTO_KEYS.has(key)) continue;\n usageExtras[key] = value;\n }\n return usageExtras;\n}\n\n/** Wrap the rendered OpenAI usage without dropping fields on compatibility callers. */\nexport function render<T extends object>(\n usage: T,\n extras: OpenRouterUsageExtras,\n): T & OpenRouterUsageExtras {\n return { ...usage, ...extras };\n}\n"],"mappings":";;;;AAIA,MAAM,iCAAiC,IAAI,IAAI;CAC7C,GAAG;CACH;CACA;CACA;CACA;CACA;CACD,CAAC;;;;;;;;;AAUF,MAAM,oBAAoB,IAAI,IAAI;CAAC;CAAa;CAAe;CAAY,CAAC;;AAG5E,SAAgB,QAAQ,WAAiE;CACvF,MAAM,IAAI,WAAW;CACrB,MAAM,cAAqC,EAAE;AAC7C,KAAI,GAAG,SAAS,QAAW;AACzB,cAAY,OAAO,EAAE;EACrB,MAAM,KAAK,EAAE;AACb,cAAY,eAAe;GACzB,GAAI,MAAM,EAAE;GACZ,yBAAyB,IAAI,2BAA2B;GACxD,gCAAgC,IAAI,kCAAkC;GACtE,qCAAqC,IAAI,uCAAuC;GACjF;;AAEH,KAAI,GAAG,0BAA0B,OAC/B,aAAY,wBAAwB;EAClC,GAAG,EAAE;EACL,eAAe,EAAE,sBAAsB,iBAAiB;EACzD;AAEH,KAAI,GAAG,8BAA8B,OACnC,aAAY,4BAA4B;EACtC,GAAG,EAAE;EACL,kBAAkB,EAAE,0BAA0B,oBAAoB;EACnE;AAEH,KAAI,GAAG,YAAY,OACjB,aAAY,UAAU,EAAE;AAU1B,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,EAAE,CAAC,EAAE;AAClD,MAAI,UAAU,OAAW;AACzB,MAAI,+BAA+B,IAAI,IAAI,CAAE;AAC7C,MAAI,kBAAkB,IAAI,IAAI,CAAE;AAChC,cAAY,OAAO;;AAErB,QAAO;;;AAIT,SAAgB,OACd,OACA,QAC2B;AAC3B,QAAO;EAAE,GAAG;EAAO,GAAG;EAAQ"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/response/usage/codecs/realtime.ts
|
|
3
|
+
/** Render chat usage only; transcription retains its model-dependent discriminator. */
|
|
4
|
+
function render(state) {
|
|
5
|
+
if (state.kind === "applied-misbehavior") return {
|
|
6
|
+
input_tokens: state.usage.prompt_tokens,
|
|
7
|
+
output_tokens: state.usage.completion_tokens,
|
|
8
|
+
total_tokens: state.usage.total_tokens
|
|
9
|
+
};
|
|
10
|
+
return {
|
|
11
|
+
total_tokens: 0,
|
|
12
|
+
input_tokens: 0,
|
|
13
|
+
output_tokens: 0
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
exports.render = render;
|
|
19
|
+
//# sourceMappingURL=realtime.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realtime.cjs","names":[],"sources":["../../../../src/response/usage/codecs/realtime.ts"],"sourcesContent":["type RealtimeChatUsage =\n | { kind: \"ordinary-zero\" }\n | {\n kind: \"applied-misbehavior\";\n usage: { prompt_tokens: number; completion_tokens: number; total_tokens: number };\n };\n\n/** Render chat usage only; transcription retains its model-dependent discriminator. */\nexport function render(state: RealtimeChatUsage) {\n if (state.kind === \"applied-misbehavior\") {\n return {\n input_tokens: state.usage.prompt_tokens,\n output_tokens: state.usage.completion_tokens,\n total_tokens: state.usage.total_tokens,\n };\n }\n return { total_tokens: 0, input_tokens: 0, output_tokens: 0 };\n}\n"],"mappings":";;;AAQA,SAAgB,OAAO,OAA0B;AAC/C,KAAI,MAAM,SAAS,sBACjB,QAAO;EACL,cAAc,MAAM,MAAM;EAC1B,eAAe,MAAM,MAAM;EAC3B,cAAc,MAAM,MAAM;EAC3B;AAEH,QAAO;EAAE,cAAc;EAAG,cAAc;EAAG,eAAe;EAAG"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/response/usage/codecs/realtime.ts
|
|
2
|
+
/** Render chat usage only; transcription retains its model-dependent discriminator. */
|
|
3
|
+
function render(state) {
|
|
4
|
+
if (state.kind === "applied-misbehavior") return {
|
|
5
|
+
input_tokens: state.usage.prompt_tokens,
|
|
6
|
+
output_tokens: state.usage.completion_tokens,
|
|
7
|
+
total_tokens: state.usage.total_tokens
|
|
8
|
+
};
|
|
9
|
+
return {
|
|
10
|
+
total_tokens: 0,
|
|
11
|
+
input_tokens: 0,
|
|
12
|
+
output_tokens: 0
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
//#endregion
|
|
17
|
+
export { render };
|
|
18
|
+
//# sourceMappingURL=realtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"realtime.js","names":[],"sources":["../../../../src/response/usage/codecs/realtime.ts"],"sourcesContent":["type RealtimeChatUsage =\n | { kind: \"ordinary-zero\" }\n | {\n kind: \"applied-misbehavior\";\n usage: { prompt_tokens: number; completion_tokens: number; total_tokens: number };\n };\n\n/** Render chat usage only; transcription retains its model-dependent discriminator. */\nexport function render(state: RealtimeChatUsage) {\n if (state.kind === \"applied-misbehavior\") {\n return {\n input_tokens: state.usage.prompt_tokens,\n output_tokens: state.usage.completion_tokens,\n total_tokens: state.usage.total_tokens,\n };\n }\n return { total_tokens: 0, input_tokens: 0, output_tokens: 0 };\n}\n"],"mappings":";;AAQA,SAAgB,OAAO,OAA0B;AAC/C,KAAI,MAAM,SAAS,sBACjB,QAAO;EACL,cAAc,MAAM,MAAM;EAC1B,eAAe,MAAM,MAAM;EAC3B,cAAc,MAAM,MAAM;EAC3B;AAEH,QAAO;EAAE,cAAc;EAAG,cAAc;EAAG,eAAe;EAAG"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/response/usage/codecs/responses.ts
|
|
3
|
+
/** Responses keeps native aliases first and emits all three counts, including absent zeros. */
|
|
4
|
+
function render(overrides) {
|
|
5
|
+
if (!overrides?.usage) return {
|
|
6
|
+
input_tokens: 0,
|
|
7
|
+
output_tokens: 0,
|
|
8
|
+
total_tokens: 0
|
|
9
|
+
};
|
|
10
|
+
const input = overrides.usage.input_tokens ?? overrides.usage.prompt_tokens ?? 0;
|
|
11
|
+
const output = overrides.usage.output_tokens ?? overrides.usage.completion_tokens ?? 0;
|
|
12
|
+
return {
|
|
13
|
+
input_tokens: input,
|
|
14
|
+
output_tokens: output,
|
|
15
|
+
total_tokens: overrides.usage.total_tokens ?? input + output
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
//#endregion
|
|
20
|
+
exports.render = render;
|
|
21
|
+
//# sourceMappingURL=responses.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"responses.cjs","names":[],"sources":["../../../../src/response/usage/codecs/responses.ts"],"sourcesContent":["import type { ResponseOverrides } from \"../../../types.js\";\n\n/** Responses keeps native aliases first and emits all three counts, including absent zeros. */\nexport function render(overrides?: ResponseOverrides): {\n input_tokens: number;\n output_tokens: number;\n total_tokens: number;\n} {\n if (!overrides?.usage) return { input_tokens: 0, output_tokens: 0, total_tokens: 0 };\n const input = overrides.usage.input_tokens ?? overrides.usage.prompt_tokens ?? 0;\n const output = overrides.usage.output_tokens ?? overrides.usage.completion_tokens ?? 0;\n return {\n input_tokens: input,\n output_tokens: output,\n total_tokens: overrides.usage.total_tokens ?? input + output,\n };\n}\n"],"mappings":";;;AAGA,SAAgB,OAAO,WAIrB;AACA,KAAI,CAAC,WAAW,MAAO,QAAO;EAAE,cAAc;EAAG,eAAe;EAAG,cAAc;EAAG;CACpF,MAAM,QAAQ,UAAU,MAAM,gBAAgB,UAAU,MAAM,iBAAiB;CAC/E,MAAM,SAAS,UAAU,MAAM,iBAAiB,UAAU,MAAM,qBAAqB;AACrF,QAAO;EACL,cAAc;EACd,eAAe;EACf,cAAc,UAAU,MAAM,gBAAgB,QAAQ;EACvD"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//#region src/response/usage/codecs/responses.ts
|
|
2
|
+
/** Responses keeps native aliases first and emits all three counts, including absent zeros. */
|
|
3
|
+
function render(overrides) {
|
|
4
|
+
if (!overrides?.usage) return {
|
|
5
|
+
input_tokens: 0,
|
|
6
|
+
output_tokens: 0,
|
|
7
|
+
total_tokens: 0
|
|
8
|
+
};
|
|
9
|
+
const input = overrides.usage.input_tokens ?? overrides.usage.prompt_tokens ?? 0;
|
|
10
|
+
const output = overrides.usage.output_tokens ?? overrides.usage.completion_tokens ?? 0;
|
|
11
|
+
return {
|
|
12
|
+
input_tokens: input,
|
|
13
|
+
output_tokens: output,
|
|
14
|
+
total_tokens: overrides.usage.total_tokens ?? input + output
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
export { render };
|
|
20
|
+
//# sourceMappingURL=responses.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"responses.js","names":[],"sources":["../../../../src/response/usage/codecs/responses.ts"],"sourcesContent":["import type { ResponseOverrides } from \"../../../types.js\";\n\n/** Responses keeps native aliases first and emits all three counts, including absent zeros. */\nexport function render(overrides?: ResponseOverrides): {\n input_tokens: number;\n output_tokens: number;\n total_tokens: number;\n} {\n if (!overrides?.usage) return { input_tokens: 0, output_tokens: 0, total_tokens: 0 };\n const input = overrides.usage.input_tokens ?? overrides.usage.prompt_tokens ?? 0;\n const output = overrides.usage.output_tokens ?? overrides.usage.completion_tokens ?? 0;\n return {\n input_tokens: input,\n output_tokens: output,\n total_tokens: overrides.usage.total_tokens ?? input + output,\n };\n}\n"],"mappings":";;AAGA,SAAgB,OAAO,WAIrB;AACA,KAAI,CAAC,WAAW,MAAO,QAAO;EAAE,cAAc;EAAG,eAAe;EAAG,cAAc;EAAG;CACpF,MAAM,QAAQ,UAAU,MAAM,gBAAgB,UAAU,MAAM,iBAAiB;CAC/E,MAAM,SAAS,UAAU,MAAM,iBAAiB,UAAU,MAAM,qBAAqB;AACrF,QAAO;EACL,cAAc;EACd,eAAe;EACf,cAAc,UAAU,MAAM,gBAAgB,QAAQ;EACvD"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/response/usage/estimate.ts
|
|
3
|
+
/**
|
|
4
|
+
* Rough token count estimation based on character length.
|
|
5
|
+
* Uses the ~4 characters per token heuristic common for English text.
|
|
6
|
+
*/
|
|
7
|
+
function estimateTokens(text) {
|
|
8
|
+
return Math.max(1, Math.ceil(text.length / 4));
|
|
9
|
+
}
|
|
10
|
+
/** Estimate prompt tokens from a request's messages array. */
|
|
11
|
+
function estimatePromptTokens(messages) {
|
|
12
|
+
let totalChars = 0;
|
|
13
|
+
for (const msg of messages) if (typeof msg.content === "string") totalChars += msg.content.length;
|
|
14
|
+
else if (Array.isArray(msg.content)) {
|
|
15
|
+
for (const part of msg.content) if (part.text) totalChars += part.text.length;
|
|
16
|
+
}
|
|
17
|
+
return Math.max(1, Math.ceil(totalChars / 4));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
//#endregion
|
|
21
|
+
exports.estimatePromptTokens = estimatePromptTokens;
|
|
22
|
+
exports.estimateTokens = estimateTokens;
|
|
23
|
+
//# sourceMappingURL=estimate.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"estimate.cjs","names":[],"sources":["../../../src/response/usage/estimate.ts"],"sourcesContent":["import type { ChatCompletionRequest } from \"../../types.js\";\n\n/**\n * Rough token count estimation based on character length.\n * Uses the ~4 characters per token heuristic common for English text.\n */\nexport function estimateTokens(text: string): number {\n return Math.max(1, Math.ceil(text.length / 4));\n}\n\n/** Estimate prompt tokens from a request's messages array. */\nexport function estimatePromptTokens(messages: ChatCompletionRequest[\"messages\"]): number {\n let totalChars = 0;\n for (const msg of messages) {\n if (typeof msg.content === \"string\") {\n totalChars += msg.content.length;\n } else if (Array.isArray(msg.content)) {\n for (const part of msg.content) {\n if (part.text) totalChars += part.text.length;\n }\n }\n }\n return Math.max(1, Math.ceil(totalChars / 4));\n}\n"],"mappings":";;;;;;AAMA,SAAgB,eAAe,MAAsB;AACnD,QAAO,KAAK,IAAI,GAAG,KAAK,KAAK,KAAK,SAAS,EAAE,CAAC;;;AAIhD,SAAgB,qBAAqB,UAAqD;CACxF,IAAI,aAAa;AACjB,MAAK,MAAM,OAAO,SAChB,KAAI,OAAO,IAAI,YAAY,SACzB,eAAc,IAAI,QAAQ;UACjB,MAAM,QAAQ,IAAI,QAAQ,EACnC;OAAK,MAAM,QAAQ,IAAI,QACrB,KAAI,KAAK,KAAM,eAAc,KAAK,KAAK;;AAI7C,QAAO,KAAK,IAAI,GAAG,KAAK,KAAK,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/response/usage/estimate.ts
|
|
2
|
+
/**
|
|
3
|
+
* Rough token count estimation based on character length.
|
|
4
|
+
* Uses the ~4 characters per token heuristic common for English text.
|
|
5
|
+
*/
|
|
6
|
+
function estimateTokens(text) {
|
|
7
|
+
return Math.max(1, Math.ceil(text.length / 4));
|
|
8
|
+
}
|
|
9
|
+
/** Estimate prompt tokens from a request's messages array. */
|
|
10
|
+
function estimatePromptTokens(messages) {
|
|
11
|
+
let totalChars = 0;
|
|
12
|
+
for (const msg of messages) if (typeof msg.content === "string") totalChars += msg.content.length;
|
|
13
|
+
else if (Array.isArray(msg.content)) {
|
|
14
|
+
for (const part of msg.content) if (part.text) totalChars += part.text.length;
|
|
15
|
+
}
|
|
16
|
+
return Math.max(1, Math.ceil(totalChars / 4));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
//#endregion
|
|
20
|
+
export { estimatePromptTokens, estimateTokens };
|
|
21
|
+
//# sourceMappingURL=estimate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"estimate.js","names":[],"sources":["../../../src/response/usage/estimate.ts"],"sourcesContent":["import type { ChatCompletionRequest } from \"../../types.js\";\n\n/**\n * Rough token count estimation based on character length.\n * Uses the ~4 characters per token heuristic common for English text.\n */\nexport function estimateTokens(text: string): number {\n return Math.max(1, Math.ceil(text.length / 4));\n}\n\n/** Estimate prompt tokens from a request's messages array. */\nexport function estimatePromptTokens(messages: ChatCompletionRequest[\"messages\"]): number {\n let totalChars = 0;\n for (const msg of messages) {\n if (typeof msg.content === \"string\") {\n totalChars += msg.content.length;\n } else if (Array.isArray(msg.content)) {\n for (const part of msg.content) {\n if (part.text) totalChars += part.text.length;\n }\n }\n }\n return Math.max(1, Math.ceil(totalChars / 4));\n}\n"],"mappings":";;;;;AAMA,SAAgB,eAAe,MAAsB;AACnD,QAAO,KAAK,IAAI,GAAG,KAAK,KAAK,KAAK,SAAS,EAAE,CAAC;;;AAIhD,SAAgB,qBAAqB,UAAqD;CACxF,IAAI,aAAa;AACjB,MAAK,MAAM,OAAO,SAChB,KAAI,OAAO,IAAI,YAAY,SACzB,eAAc,IAAI,QAAQ;UACjB,MAAM,QAAQ,IAAI,QAAQ,EACnC;OAAK,MAAM,QAAQ,IAAI,QACrB,KAAI,KAAK,KAAM,eAAc,KAAK,KAAK;;AAI7C,QAAO,KAAK,IAAI,GAAG,KAAK,KAAK,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/response/usage/fields.ts
|
|
3
|
+
/** Shared classification; validation checks only the documented inner members. */
|
|
4
|
+
const USAGE_FIELD_DEFINITIONS = {
|
|
5
|
+
cache_creation: {
|
|
6
|
+
kind: "number-or-object",
|
|
7
|
+
numericMembers: ["ephemeral_5m_input_tokens", "ephemeral_1h_input_tokens"]
|
|
8
|
+
},
|
|
9
|
+
cost_details: {
|
|
10
|
+
kind: "object",
|
|
11
|
+
numericMembers: [
|
|
12
|
+
"upstream_inference_cost",
|
|
13
|
+
"upstream_inference_prompt_cost",
|
|
14
|
+
"upstream_inference_completions_cost"
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
prompt_tokens_details: {
|
|
18
|
+
kind: "object",
|
|
19
|
+
numericMembers: [
|
|
20
|
+
"cached_tokens",
|
|
21
|
+
"cache_write_tokens",
|
|
22
|
+
"audio_tokens"
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
completion_tokens_details: {
|
|
26
|
+
kind: "object",
|
|
27
|
+
numericMembers: ["reasoning_tokens"]
|
|
28
|
+
},
|
|
29
|
+
is_byok: { kind: "boolean" }
|
|
30
|
+
};
|
|
31
|
+
const NUMERIC_FIELD = { kind: "number" };
|
|
32
|
+
/** Unknown keys, including prototype names, retain numeric-scalar classification. */
|
|
33
|
+
function getUsageFieldDefinition(key) {
|
|
34
|
+
return Object.hasOwn(USAGE_FIELD_DEFINITIONS, key) ? USAGE_FIELD_DEFINITIONS[key] : NUMERIC_FIELD;
|
|
35
|
+
}
|
|
36
|
+
/** Recording retains finite numbers, including members of recognized usage objects. */
|
|
37
|
+
function sanitizeUsage(raw) {
|
|
38
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) return void 0;
|
|
39
|
+
const out = {};
|
|
40
|
+
for (const [key, val] of Object.entries(raw)) {
|
|
41
|
+
if (val === void 0 || val === null) continue;
|
|
42
|
+
const definition = getUsageFieldDefinition(key);
|
|
43
|
+
if (definition.kind === "number-or-object" && typeof val === "number") {
|
|
44
|
+
if (Number.isFinite(val)) out[key] = val;
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (definition.kind === "object" || definition.kind === "number-or-object") {
|
|
48
|
+
if (typeof val !== "object" || val === null || Array.isArray(val)) continue;
|
|
49
|
+
const inner = {};
|
|
50
|
+
for (const [innerKey, innerVal] of Object.entries(val)) if (typeof innerVal === "number" && Number.isFinite(innerVal)) if (key === "cache_creation") Object.defineProperty(inner, innerKey, {
|
|
51
|
+
value: innerVal,
|
|
52
|
+
enumerable: true,
|
|
53
|
+
configurable: true,
|
|
54
|
+
writable: true
|
|
55
|
+
});
|
|
56
|
+
else inner[innerKey] = innerVal;
|
|
57
|
+
if (Object.keys(inner).length > 0) out[key] = inner;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (definition.kind === "boolean") {
|
|
61
|
+
if (typeof val === "boolean") out[key] = val;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (typeof val === "number" && Number.isFinite(val)) out[key] = val;
|
|
65
|
+
}
|
|
66
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
//#endregion
|
|
70
|
+
exports.getUsageFieldDefinition = getUsageFieldDefinition;
|
|
71
|
+
exports.sanitizeUsage = sanitizeUsage;
|
|
72
|
+
//# sourceMappingURL=fields.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields.cjs","names":[],"sources":["../../../src/response/usage/fields.ts"],"sourcesContent":["import type { ResponseOverrides } from \"../../types.js\";\n\ntype UsageFieldDefinition =\n | { readonly kind: \"number\" }\n | { readonly kind: \"boolean\" }\n | { readonly kind: \"object\" | \"number-or-object\"; readonly numericMembers: readonly string[] };\n\n/** Shared classification; validation checks only the documented inner members. */\nconst USAGE_FIELD_DEFINITIONS = {\n cache_creation: {\n kind: \"number-or-object\",\n numericMembers: [\"ephemeral_5m_input_tokens\", \"ephemeral_1h_input_tokens\"],\n },\n cost_details: {\n kind: \"object\",\n numericMembers: [\n \"upstream_inference_cost\",\n \"upstream_inference_prompt_cost\",\n \"upstream_inference_completions_cost\",\n ],\n },\n prompt_tokens_details: {\n kind: \"object\",\n numericMembers: [\"cached_tokens\", \"cache_write_tokens\", \"audio_tokens\"],\n },\n completion_tokens_details: { kind: \"object\", numericMembers: [\"reasoning_tokens\"] },\n is_byok: { kind: \"boolean\" },\n} as const satisfies Readonly<Record<string, UsageFieldDefinition>>;\n\nconst NUMERIC_FIELD: UsageFieldDefinition = { kind: \"number\" };\n\n/** Unknown keys, including prototype names, retain numeric-scalar classification. */\nexport function getUsageFieldDefinition(key: string): UsageFieldDefinition {\n return Object.hasOwn(USAGE_FIELD_DEFINITIONS, key)\n ? USAGE_FIELD_DEFINITIONS[key as keyof typeof USAGE_FIELD_DEFINITIONS]\n : NUMERIC_FIELD;\n}\n\n/** Recording retains finite numbers, including members of recognized usage objects. */\nexport function sanitizeUsage(raw: unknown): ResponseOverrides[\"usage\"] | undefined {\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) return undefined;\n const out: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(raw as Record<string, unknown>)) {\n if (val === undefined || val === null) continue;\n const definition = getUsageFieldDefinition(key);\n if (definition.kind === \"number-or-object\" && typeof val === \"number\") {\n if (Number.isFinite(val)) out[key] = val;\n continue;\n }\n if (definition.kind === \"object\" || definition.kind === \"number-or-object\") {\n if (typeof val !== \"object\" || val === null || Array.isArray(val)) continue;\n const inner: Record<string, unknown> = {};\n for (const [innerKey, innerVal] of Object.entries(val as Record<string, unknown>)) {\n if (typeof innerVal === \"number\" && Number.isFinite(innerVal)) {\n if (key === \"cache_creation\") {\n // Cache members parsed from JSON include own names such as __proto__.\n Object.defineProperty(inner, innerKey, {\n value: innerVal,\n enumerable: true,\n configurable: true,\n writable: true,\n });\n } else inner[innerKey] = innerVal;\n }\n }\n if (Object.keys(inner).length > 0) out[key] = inner;\n continue;\n }\n if (definition.kind === \"boolean\") {\n if (typeof val === \"boolean\") out[key] = val;\n continue;\n }\n if (typeof val === \"number\" && Number.isFinite(val)) out[key] = val;\n }\n return Object.keys(out).length > 0 ? (out as ResponseOverrides[\"usage\"]) : undefined;\n}\n"],"mappings":";;;AAQA,MAAM,0BAA0B;CAC9B,gBAAgB;EACd,MAAM;EACN,gBAAgB,CAAC,6BAA6B,4BAA4B;EAC3E;CACD,cAAc;EACZ,MAAM;EACN,gBAAgB;GACd;GACA;GACA;GACD;EACF;CACD,uBAAuB;EACrB,MAAM;EACN,gBAAgB;GAAC;GAAiB;GAAsB;GAAe;EACxE;CACD,2BAA2B;EAAE,MAAM;EAAU,gBAAgB,CAAC,mBAAmB;EAAE;CACnF,SAAS,EAAE,MAAM,WAAW;CAC7B;AAED,MAAM,gBAAsC,EAAE,MAAM,UAAU;;AAG9D,SAAgB,wBAAwB,KAAmC;AACzE,QAAO,OAAO,OAAO,yBAAyB,IAAI,GAC9C,wBAAwB,OACxB;;;AAIN,SAAgB,cAAc,KAAsD;AAClF,KAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,MAAM,QAAQ,IAAI,CAAE,QAAO;CAC1E,MAAM,MAA+B,EAAE;AACvC,MAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,IAA+B,EAAE;AACvE,MAAI,QAAQ,UAAa,QAAQ,KAAM;EACvC,MAAM,aAAa,wBAAwB,IAAI;AAC/C,MAAI,WAAW,SAAS,sBAAsB,OAAO,QAAQ,UAAU;AACrE,OAAI,OAAO,SAAS,IAAI,CAAE,KAAI,OAAO;AACrC;;AAEF,MAAI,WAAW,SAAS,YAAY,WAAW,SAAS,oBAAoB;AAC1E,OAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,MAAM,QAAQ,IAAI,CAAE;GACnE,MAAM,QAAiC,EAAE;AACzC,QAAK,MAAM,CAAC,UAAU,aAAa,OAAO,QAAQ,IAA+B,CAC/E,KAAI,OAAO,aAAa,YAAY,OAAO,SAAS,SAAS,CAC3D,KAAI,QAAQ,iBAEV,QAAO,eAAe,OAAO,UAAU;IACrC,OAAO;IACP,YAAY;IACZ,cAAc;IACd,UAAU;IACX,CAAC;OACG,OAAM,YAAY;AAG7B,OAAI,OAAO,KAAK,MAAM,CAAC,SAAS,EAAG,KAAI,OAAO;AAC9C;;AAEF,MAAI,WAAW,SAAS,WAAW;AACjC,OAAI,OAAO,QAAQ,UAAW,KAAI,OAAO;AACzC;;AAEF,MAAI,OAAO,QAAQ,YAAY,OAAO,SAAS,IAAI,CAAE,KAAI,OAAO;;AAElE,QAAO,OAAO,KAAK,IAAI,CAAC,SAAS,IAAK,MAAqC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
//#region src/response/usage/fields.ts
|
|
2
|
+
/** Shared classification; validation checks only the documented inner members. */
|
|
3
|
+
const USAGE_FIELD_DEFINITIONS = {
|
|
4
|
+
cache_creation: {
|
|
5
|
+
kind: "number-or-object",
|
|
6
|
+
numericMembers: ["ephemeral_5m_input_tokens", "ephemeral_1h_input_tokens"]
|
|
7
|
+
},
|
|
8
|
+
cost_details: {
|
|
9
|
+
kind: "object",
|
|
10
|
+
numericMembers: [
|
|
11
|
+
"upstream_inference_cost",
|
|
12
|
+
"upstream_inference_prompt_cost",
|
|
13
|
+
"upstream_inference_completions_cost"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
prompt_tokens_details: {
|
|
17
|
+
kind: "object",
|
|
18
|
+
numericMembers: [
|
|
19
|
+
"cached_tokens",
|
|
20
|
+
"cache_write_tokens",
|
|
21
|
+
"audio_tokens"
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
completion_tokens_details: {
|
|
25
|
+
kind: "object",
|
|
26
|
+
numericMembers: ["reasoning_tokens"]
|
|
27
|
+
},
|
|
28
|
+
is_byok: { kind: "boolean" }
|
|
29
|
+
};
|
|
30
|
+
const NUMERIC_FIELD = { kind: "number" };
|
|
31
|
+
/** Unknown keys, including prototype names, retain numeric-scalar classification. */
|
|
32
|
+
function getUsageFieldDefinition(key) {
|
|
33
|
+
return Object.hasOwn(USAGE_FIELD_DEFINITIONS, key) ? USAGE_FIELD_DEFINITIONS[key] : NUMERIC_FIELD;
|
|
34
|
+
}
|
|
35
|
+
/** Recording retains finite numbers, including members of recognized usage objects. */
|
|
36
|
+
function sanitizeUsage(raw) {
|
|
37
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) return void 0;
|
|
38
|
+
const out = {};
|
|
39
|
+
for (const [key, val] of Object.entries(raw)) {
|
|
40
|
+
if (val === void 0 || val === null) continue;
|
|
41
|
+
const definition = getUsageFieldDefinition(key);
|
|
42
|
+
if (definition.kind === "number-or-object" && typeof val === "number") {
|
|
43
|
+
if (Number.isFinite(val)) out[key] = val;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (definition.kind === "object" || definition.kind === "number-or-object") {
|
|
47
|
+
if (typeof val !== "object" || val === null || Array.isArray(val)) continue;
|
|
48
|
+
const inner = {};
|
|
49
|
+
for (const [innerKey, innerVal] of Object.entries(val)) if (typeof innerVal === "number" && Number.isFinite(innerVal)) if (key === "cache_creation") Object.defineProperty(inner, innerKey, {
|
|
50
|
+
value: innerVal,
|
|
51
|
+
enumerable: true,
|
|
52
|
+
configurable: true,
|
|
53
|
+
writable: true
|
|
54
|
+
});
|
|
55
|
+
else inner[innerKey] = innerVal;
|
|
56
|
+
if (Object.keys(inner).length > 0) out[key] = inner;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (definition.kind === "boolean") {
|
|
60
|
+
if (typeof val === "boolean") out[key] = val;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (typeof val === "number" && Number.isFinite(val)) out[key] = val;
|
|
64
|
+
}
|
|
65
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
//#endregion
|
|
69
|
+
export { getUsageFieldDefinition, sanitizeUsage };
|
|
70
|
+
//# sourceMappingURL=fields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields.js","names":[],"sources":["../../../src/response/usage/fields.ts"],"sourcesContent":["import type { ResponseOverrides } from \"../../types.js\";\n\ntype UsageFieldDefinition =\n | { readonly kind: \"number\" }\n | { readonly kind: \"boolean\" }\n | { readonly kind: \"object\" | \"number-or-object\"; readonly numericMembers: readonly string[] };\n\n/** Shared classification; validation checks only the documented inner members. */\nconst USAGE_FIELD_DEFINITIONS = {\n cache_creation: {\n kind: \"number-or-object\",\n numericMembers: [\"ephemeral_5m_input_tokens\", \"ephemeral_1h_input_tokens\"],\n },\n cost_details: {\n kind: \"object\",\n numericMembers: [\n \"upstream_inference_cost\",\n \"upstream_inference_prompt_cost\",\n \"upstream_inference_completions_cost\",\n ],\n },\n prompt_tokens_details: {\n kind: \"object\",\n numericMembers: [\"cached_tokens\", \"cache_write_tokens\", \"audio_tokens\"],\n },\n completion_tokens_details: { kind: \"object\", numericMembers: [\"reasoning_tokens\"] },\n is_byok: { kind: \"boolean\" },\n} as const satisfies Readonly<Record<string, UsageFieldDefinition>>;\n\nconst NUMERIC_FIELD: UsageFieldDefinition = { kind: \"number\" };\n\n/** Unknown keys, including prototype names, retain numeric-scalar classification. */\nexport function getUsageFieldDefinition(key: string): UsageFieldDefinition {\n return Object.hasOwn(USAGE_FIELD_DEFINITIONS, key)\n ? USAGE_FIELD_DEFINITIONS[key as keyof typeof USAGE_FIELD_DEFINITIONS]\n : NUMERIC_FIELD;\n}\n\n/** Recording retains finite numbers, including members of recognized usage objects. */\nexport function sanitizeUsage(raw: unknown): ResponseOverrides[\"usage\"] | undefined {\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) return undefined;\n const out: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(raw as Record<string, unknown>)) {\n if (val === undefined || val === null) continue;\n const definition = getUsageFieldDefinition(key);\n if (definition.kind === \"number-or-object\" && typeof val === \"number\") {\n if (Number.isFinite(val)) out[key] = val;\n continue;\n }\n if (definition.kind === \"object\" || definition.kind === \"number-or-object\") {\n if (typeof val !== \"object\" || val === null || Array.isArray(val)) continue;\n const inner: Record<string, unknown> = {};\n for (const [innerKey, innerVal] of Object.entries(val as Record<string, unknown>)) {\n if (typeof innerVal === \"number\" && Number.isFinite(innerVal)) {\n if (key === \"cache_creation\") {\n // Cache members parsed from JSON include own names such as __proto__.\n Object.defineProperty(inner, innerKey, {\n value: innerVal,\n enumerable: true,\n configurable: true,\n writable: true,\n });\n } else inner[innerKey] = innerVal;\n }\n }\n if (Object.keys(inner).length > 0) out[key] = inner;\n continue;\n }\n if (definition.kind === \"boolean\") {\n if (typeof val === \"boolean\") out[key] = val;\n continue;\n }\n if (typeof val === \"number\" && Number.isFinite(val)) out[key] = val;\n }\n return Object.keys(out).length > 0 ? (out as ResponseOverrides[\"usage\"]) : undefined;\n}\n"],"mappings":";;AAQA,MAAM,0BAA0B;CAC9B,gBAAgB;EACd,MAAM;EACN,gBAAgB,CAAC,6BAA6B,4BAA4B;EAC3E;CACD,cAAc;EACZ,MAAM;EACN,gBAAgB;GACd;GACA;GACA;GACD;EACF;CACD,uBAAuB;EACrB,MAAM;EACN,gBAAgB;GAAC;GAAiB;GAAsB;GAAe;EACxE;CACD,2BAA2B;EAAE,MAAM;EAAU,gBAAgB,CAAC,mBAAmB;EAAE;CACnF,SAAS,EAAE,MAAM,WAAW;CAC7B;AAED,MAAM,gBAAsC,EAAE,MAAM,UAAU;;AAG9D,SAAgB,wBAAwB,KAAmC;AACzE,QAAO,OAAO,OAAO,yBAAyB,IAAI,GAC9C,wBAAwB,OACxB;;;AAIN,SAAgB,cAAc,KAAsD;AAClF,KAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,MAAM,QAAQ,IAAI,CAAE,QAAO;CAC1E,MAAM,MAA+B,EAAE;AACvC,MAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,IAA+B,EAAE;AACvE,MAAI,QAAQ,UAAa,QAAQ,KAAM;EACvC,MAAM,aAAa,wBAAwB,IAAI;AAC/C,MAAI,WAAW,SAAS,sBAAsB,OAAO,QAAQ,UAAU;AACrE,OAAI,OAAO,SAAS,IAAI,CAAE,KAAI,OAAO;AACrC;;AAEF,MAAI,WAAW,SAAS,YAAY,WAAW,SAAS,oBAAoB;AAC1E,OAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,MAAM,QAAQ,IAAI,CAAE;GACnE,MAAM,QAAiC,EAAE;AACzC,QAAK,MAAM,CAAC,UAAU,aAAa,OAAO,QAAQ,IAA+B,CAC/E,KAAI,OAAO,aAAa,YAAY,OAAO,SAAS,SAAS,CAC3D,KAAI,QAAQ,iBAEV,QAAO,eAAe,OAAO,UAAU;IACrC,OAAO;IACP,YAAY;IACZ,cAAc;IACd,UAAU;IACX,CAAC;OACG,OAAM,YAAY;AAG7B,OAAI,OAAO,KAAK,MAAM,CAAC,SAAS,EAAG,KAAI,OAAO;AAC9C;;AAEF,MAAI,WAAW,SAAS,WAAW;AACjC,OAAI,OAAO,QAAQ,UAAW,KAAI,OAAO;AACzC;;AAEF,MAAI,OAAO,QAAQ,YAAY,OAAO,SAAS,IAAI,CAAE,KAAI,OAAO;;AAElE,QAAO,OAAO,KAAK,IAAI,CAAC,SAAS,IAAK,MAAqC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const require_fields = require('./fields.cjs');
|
|
2
|
+
const require_anthropic = require('./codecs/anthropic.cjs');
|
|
3
|
+
|
|
4
|
+
//#region src/response/usage/recording.ts
|
|
5
|
+
/** Content-type precedence matches the content dispatcher, including its SSE fallback. */
|
|
6
|
+
function selectedFamily(context) {
|
|
7
|
+
if (context.family !== "stream-dispatch") return context.family;
|
|
8
|
+
const ct = context.contentType?.toLowerCase() ?? "";
|
|
9
|
+
if (ct.includes("application/vnd.amazon.eventstream")) return "bedrock-invoke";
|
|
10
|
+
if (ct.includes("application/x-ndjson")) return "ollama";
|
|
11
|
+
if (!ct.includes("text/event-stream")) return void 0;
|
|
12
|
+
switch (context.provider) {
|
|
13
|
+
case "anthropic":
|
|
14
|
+
case "bedrock": return "anthropic";
|
|
15
|
+
case "gemini":
|
|
16
|
+
case "vertexai": return "gemini";
|
|
17
|
+
case "gemini-interactions": return "interactions";
|
|
18
|
+
case "cohere": return "cohere";
|
|
19
|
+
default: return "openai";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function mode(context, stage) {
|
|
23
|
+
if (stage === "final") return "sanitize";
|
|
24
|
+
switch (selectedFamily(context)) {
|
|
25
|
+
case "openai": return stage === "nonstream" ? "sanitize" : "last-nonempty";
|
|
26
|
+
case "transcription": return stage === "nonstream" ? "transcription-object" : "last-nonempty";
|
|
27
|
+
case "anthropic":
|
|
28
|
+
case "bedrock-invoke": return "anthropic-merge";
|
|
29
|
+
default: return "omit";
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function captureUsage(context) {
|
|
33
|
+
const { observation, previous, stage } = context;
|
|
34
|
+
const raw = stage === "final" ? observation : observation?.usage;
|
|
35
|
+
switch (mode(context, stage)) {
|
|
36
|
+
case "sanitize": return require_fields.sanitizeUsage(raw);
|
|
37
|
+
case "last-nonempty": return raw && typeof raw === "object" && !Array.isArray(raw) && Object.keys(raw).length > 0 ? raw : previous;
|
|
38
|
+
case "transcription-object": return raw && typeof raw === "object" ? raw : void 0;
|
|
39
|
+
case "anthropic-merge": {
|
|
40
|
+
if (stage !== "stream") return require_anthropic.capture(previous, raw);
|
|
41
|
+
const event = observation;
|
|
42
|
+
if (event?.type === "message_start") return require_anthropic.capture(previous, event.message?.usage, "start");
|
|
43
|
+
if (event?.type === "message_delta") return require_anthropic.capture(previous, raw, "delta");
|
|
44
|
+
return previous;
|
|
45
|
+
}
|
|
46
|
+
case "omit": return;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
//#endregion
|
|
51
|
+
exports.captureUsage = captureUsage;
|
|
52
|
+
//# sourceMappingURL=recording.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recording.cjs","names":["sanitizeUsage","captureAnthropicUsage"],"sources":["../../../src/response/usage/recording.ts"],"sourcesContent":["import type { RecordProviderKey, ResponseOverrides } from \"../../types.js\";\nimport { capture as captureAnthropicUsage } from \"./codecs/anthropic.js\";\nimport { sanitizeUsage } from \"./fields.js\";\n\ntype BodyFamily =\n | \"openai\"\n | \"anthropic\"\n | \"gemini\"\n | \"ollama\"\n | \"cohere\"\n | \"bedrock-invoke\"\n | \"bedrock-converse\"\n | \"interactions\"\n | \"transcription\"\n | \"stream-dispatch\"\n | \"final\";\ninterface CaptureContext {\n provider?: RecordProviderKey;\n contentType?: string;\n /** Recognition remains with content readers; operation does not override their family. */\n operation?: string;\n family: BodyFamily;\n previous?: Record<string, unknown>;\n observation: unknown;\n}\ntype CaptureMode =\n | \"last-nonempty\"\n | \"transcription-object\"\n | \"sanitize\"\n | \"anthropic-merge\"\n | \"omit\";\n\n/** Content-type precedence matches the content dispatcher, including its SSE fallback. */\nfunction selectedFamily(context: CaptureContext): BodyFamily | undefined {\n if (context.family !== \"stream-dispatch\") return context.family;\n const ct = context.contentType?.toLowerCase() ?? \"\";\n if (ct.includes(\"application/vnd.amazon.eventstream\")) return \"bedrock-invoke\";\n if (ct.includes(\"application/x-ndjson\")) return \"ollama\";\n if (!ct.includes(\"text/event-stream\")) return undefined;\n switch (context.provider) {\n case \"anthropic\":\n case \"bedrock\":\n return \"anthropic\";\n case \"gemini\":\n case \"vertexai\":\n return \"gemini\";\n case \"gemini-interactions\":\n return \"interactions\";\n case \"cohere\":\n return \"cohere\";\n default:\n return \"openai\";\n }\n}\n\nfunction mode(\n context: CaptureContext,\n stage: \"stream\" | \"nonstream\" | \"collapsed\" | \"final\",\n): CaptureMode {\n if (stage === \"final\") return \"sanitize\";\n switch (selectedFamily(context)) {\n case \"openai\":\n return stage === \"nonstream\" ? \"sanitize\" : \"last-nonempty\";\n case \"transcription\":\n return stage === \"nonstream\" ? \"transcription-object\" : \"last-nonempty\";\n case \"anthropic\":\n case \"bedrock-invoke\":\n return \"anthropic-merge\";\n // These families intentionally do not acquire usage during extraction.\n case \"gemini\":\n case \"ollama\":\n case \"cohere\":\n case \"bedrock-converse\":\n case \"interactions\":\n default:\n return \"omit\";\n }\n}\n\n/** @internal Capture preserves the recognized wire's existing recording contract. */\nexport function captureUsage(\n context: CaptureContext & { family: \"transcription\"; stage: \"nonstream\" },\n): Record<string, unknown> | undefined;\nexport function captureUsage(\n context: CaptureContext & { stage: \"final\" | \"nonstream\" },\n): ResponseOverrides[\"usage\"] | undefined;\nexport function captureUsage(\n context: CaptureContext & { stage: \"stream\" | \"collapsed\" },\n): Record<string, unknown> | undefined;\nexport function captureUsage(\n context: CaptureContext & { stage: \"stream\" | \"nonstream\" | \"collapsed\" | \"final\" },\n): Record<string, unknown> | undefined {\n const { observation, previous, stage } = context;\n // Final fixture sanitation receives raw usage; other stages receive the\n // recognized envelope/event, leaving body recognition with the content reader.\n const raw = stage === \"final\" ? observation : (observation as { usage?: unknown } | null)?.usage;\n switch (mode(context, stage)) {\n case \"sanitize\":\n return sanitizeUsage(raw);\n case \"last-nonempty\":\n return raw && typeof raw === \"object\" && !Array.isArray(raw) && Object.keys(raw).length > 0\n ? (raw as Record<string, unknown>)\n : previous;\n case \"transcription-object\":\n // Nonstream transcription historically retains arrays and empty objects;\n // its discriminator contract is separate from chat fixture sanitation.\n return raw && typeof raw === \"object\" ? (raw as Record<string, unknown>) : undefined;\n case \"anthropic-merge\": {\n if (stage !== \"stream\") return captureAnthropicUsage(previous, raw);\n const event = observation as { type?: unknown; message?: { usage?: unknown } } | null;\n if (event?.type === \"message_start\")\n return captureAnthropicUsage(previous, event.message?.usage, \"start\");\n if (event?.type === \"message_delta\") return captureAnthropicUsage(previous, raw, \"delta\");\n return previous;\n }\n case \"omit\":\n return undefined;\n }\n}\n"],"mappings":";;;;;AAiCA,SAAS,eAAe,SAAiD;AACvE,KAAI,QAAQ,WAAW,kBAAmB,QAAO,QAAQ;CACzD,MAAM,KAAK,QAAQ,aAAa,aAAa,IAAI;AACjD,KAAI,GAAG,SAAS,qCAAqC,CAAE,QAAO;AAC9D,KAAI,GAAG,SAAS,uBAAuB,CAAE,QAAO;AAChD,KAAI,CAAC,GAAG,SAAS,oBAAoB,CAAE,QAAO;AAC9C,SAAQ,QAAQ,UAAhB;EACE,KAAK;EACL,KAAK,UACH,QAAO;EACT,KAAK;EACL,KAAK,WACH,QAAO;EACT,KAAK,sBACH,QAAO;EACT,KAAK,SACH,QAAO;EACT,QACE,QAAO;;;AAIb,SAAS,KACP,SACA,OACa;AACb,KAAI,UAAU,QAAS,QAAO;AAC9B,SAAQ,eAAe,QAAQ,EAA/B;EACE,KAAK,SACH,QAAO,UAAU,cAAc,aAAa;EAC9C,KAAK,gBACH,QAAO,UAAU,cAAc,yBAAyB;EAC1D,KAAK;EACL,KAAK,iBACH,QAAO;EAOT,QACE,QAAO;;;AAcb,SAAgB,aACd,SACqC;CACrC,MAAM,EAAE,aAAa,UAAU,UAAU;CAGzC,MAAM,MAAM,UAAU,UAAU,cAAe,aAA4C;AAC3F,SAAQ,KAAK,SAAS,MAAM,EAA5B;EACE,KAAK,WACH,QAAOA,6BAAc,IAAI;EAC3B,KAAK,gBACH,QAAO,OAAO,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,IAAI,IAAI,OAAO,KAAK,IAAI,CAAC,SAAS,IACrF,MACD;EACN,KAAK,uBAGH,QAAO,OAAO,OAAO,QAAQ,WAAY,MAAkC;EAC7E,KAAK,mBAAmB;AACtB,OAAI,UAAU,SAAU,QAAOC,0BAAsB,UAAU,IAAI;GACnE,MAAM,QAAQ;AACd,OAAI,OAAO,SAAS,gBAClB,QAAOA,0BAAsB,UAAU,MAAM,SAAS,OAAO,QAAQ;AACvE,OAAI,OAAO,SAAS,gBAAiB,QAAOA,0BAAsB,UAAU,KAAK,QAAQ;AACzF,UAAO;;EAET,KAAK,OACH"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { sanitizeUsage } from "./fields.js";
|
|
2
|
+
import { capture } from "./codecs/anthropic.js";
|
|
3
|
+
|
|
4
|
+
//#region src/response/usage/recording.ts
|
|
5
|
+
/** Content-type precedence matches the content dispatcher, including its SSE fallback. */
|
|
6
|
+
function selectedFamily(context) {
|
|
7
|
+
if (context.family !== "stream-dispatch") return context.family;
|
|
8
|
+
const ct = context.contentType?.toLowerCase() ?? "";
|
|
9
|
+
if (ct.includes("application/vnd.amazon.eventstream")) return "bedrock-invoke";
|
|
10
|
+
if (ct.includes("application/x-ndjson")) return "ollama";
|
|
11
|
+
if (!ct.includes("text/event-stream")) return void 0;
|
|
12
|
+
switch (context.provider) {
|
|
13
|
+
case "anthropic":
|
|
14
|
+
case "bedrock": return "anthropic";
|
|
15
|
+
case "gemini":
|
|
16
|
+
case "vertexai": return "gemini";
|
|
17
|
+
case "gemini-interactions": return "interactions";
|
|
18
|
+
case "cohere": return "cohere";
|
|
19
|
+
default: return "openai";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function mode(context, stage) {
|
|
23
|
+
if (stage === "final") return "sanitize";
|
|
24
|
+
switch (selectedFamily(context)) {
|
|
25
|
+
case "openai": return stage === "nonstream" ? "sanitize" : "last-nonempty";
|
|
26
|
+
case "transcription": return stage === "nonstream" ? "transcription-object" : "last-nonempty";
|
|
27
|
+
case "anthropic":
|
|
28
|
+
case "bedrock-invoke": return "anthropic-merge";
|
|
29
|
+
default: return "omit";
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function captureUsage(context) {
|
|
33
|
+
const { observation, previous, stage } = context;
|
|
34
|
+
const raw = stage === "final" ? observation : observation?.usage;
|
|
35
|
+
switch (mode(context, stage)) {
|
|
36
|
+
case "sanitize": return sanitizeUsage(raw);
|
|
37
|
+
case "last-nonempty": return raw && typeof raw === "object" && !Array.isArray(raw) && Object.keys(raw).length > 0 ? raw : previous;
|
|
38
|
+
case "transcription-object": return raw && typeof raw === "object" ? raw : void 0;
|
|
39
|
+
case "anthropic-merge": {
|
|
40
|
+
if (stage !== "stream") return capture(previous, raw);
|
|
41
|
+
const event = observation;
|
|
42
|
+
if (event?.type === "message_start") return capture(previous, event.message?.usage, "start");
|
|
43
|
+
if (event?.type === "message_delta") return capture(previous, raw, "delta");
|
|
44
|
+
return previous;
|
|
45
|
+
}
|
|
46
|
+
case "omit": return;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
//#endregion
|
|
51
|
+
export { captureUsage };
|
|
52
|
+
//# sourceMappingURL=recording.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recording.js","names":["captureAnthropicUsage"],"sources":["../../../src/response/usage/recording.ts"],"sourcesContent":["import type { RecordProviderKey, ResponseOverrides } from \"../../types.js\";\nimport { capture as captureAnthropicUsage } from \"./codecs/anthropic.js\";\nimport { sanitizeUsage } from \"./fields.js\";\n\ntype BodyFamily =\n | \"openai\"\n | \"anthropic\"\n | \"gemini\"\n | \"ollama\"\n | \"cohere\"\n | \"bedrock-invoke\"\n | \"bedrock-converse\"\n | \"interactions\"\n | \"transcription\"\n | \"stream-dispatch\"\n | \"final\";\ninterface CaptureContext {\n provider?: RecordProviderKey;\n contentType?: string;\n /** Recognition remains with content readers; operation does not override their family. */\n operation?: string;\n family: BodyFamily;\n previous?: Record<string, unknown>;\n observation: unknown;\n}\ntype CaptureMode =\n | \"last-nonempty\"\n | \"transcription-object\"\n | \"sanitize\"\n | \"anthropic-merge\"\n | \"omit\";\n\n/** Content-type precedence matches the content dispatcher, including its SSE fallback. */\nfunction selectedFamily(context: CaptureContext): BodyFamily | undefined {\n if (context.family !== \"stream-dispatch\") return context.family;\n const ct = context.contentType?.toLowerCase() ?? \"\";\n if (ct.includes(\"application/vnd.amazon.eventstream\")) return \"bedrock-invoke\";\n if (ct.includes(\"application/x-ndjson\")) return \"ollama\";\n if (!ct.includes(\"text/event-stream\")) return undefined;\n switch (context.provider) {\n case \"anthropic\":\n case \"bedrock\":\n return \"anthropic\";\n case \"gemini\":\n case \"vertexai\":\n return \"gemini\";\n case \"gemini-interactions\":\n return \"interactions\";\n case \"cohere\":\n return \"cohere\";\n default:\n return \"openai\";\n }\n}\n\nfunction mode(\n context: CaptureContext,\n stage: \"stream\" | \"nonstream\" | \"collapsed\" | \"final\",\n): CaptureMode {\n if (stage === \"final\") return \"sanitize\";\n switch (selectedFamily(context)) {\n case \"openai\":\n return stage === \"nonstream\" ? \"sanitize\" : \"last-nonempty\";\n case \"transcription\":\n return stage === \"nonstream\" ? \"transcription-object\" : \"last-nonempty\";\n case \"anthropic\":\n case \"bedrock-invoke\":\n return \"anthropic-merge\";\n // These families intentionally do not acquire usage during extraction.\n case \"gemini\":\n case \"ollama\":\n case \"cohere\":\n case \"bedrock-converse\":\n case \"interactions\":\n default:\n return \"omit\";\n }\n}\n\n/** @internal Capture preserves the recognized wire's existing recording contract. */\nexport function captureUsage(\n context: CaptureContext & { family: \"transcription\"; stage: \"nonstream\" },\n): Record<string, unknown> | undefined;\nexport function captureUsage(\n context: CaptureContext & { stage: \"final\" | \"nonstream\" },\n): ResponseOverrides[\"usage\"] | undefined;\nexport function captureUsage(\n context: CaptureContext & { stage: \"stream\" | \"collapsed\" },\n): Record<string, unknown> | undefined;\nexport function captureUsage(\n context: CaptureContext & { stage: \"stream\" | \"nonstream\" | \"collapsed\" | \"final\" },\n): Record<string, unknown> | undefined {\n const { observation, previous, stage } = context;\n // Final fixture sanitation receives raw usage; other stages receive the\n // recognized envelope/event, leaving body recognition with the content reader.\n const raw = stage === \"final\" ? observation : (observation as { usage?: unknown } | null)?.usage;\n switch (mode(context, stage)) {\n case \"sanitize\":\n return sanitizeUsage(raw);\n case \"last-nonempty\":\n return raw && typeof raw === \"object\" && !Array.isArray(raw) && Object.keys(raw).length > 0\n ? (raw as Record<string, unknown>)\n : previous;\n case \"transcription-object\":\n // Nonstream transcription historically retains arrays and empty objects;\n // its discriminator contract is separate from chat fixture sanitation.\n return raw && typeof raw === \"object\" ? (raw as Record<string, unknown>) : undefined;\n case \"anthropic-merge\": {\n if (stage !== \"stream\") return captureAnthropicUsage(previous, raw);\n const event = observation as { type?: unknown; message?: { usage?: unknown } } | null;\n if (event?.type === \"message_start\")\n return captureAnthropicUsage(previous, event.message?.usage, \"start\");\n if (event?.type === \"message_delta\") return captureAnthropicUsage(previous, raw, \"delta\");\n return previous;\n }\n case \"omit\":\n return undefined;\n }\n}\n"],"mappings":";;;;;AAiCA,SAAS,eAAe,SAAiD;AACvE,KAAI,QAAQ,WAAW,kBAAmB,QAAO,QAAQ;CACzD,MAAM,KAAK,QAAQ,aAAa,aAAa,IAAI;AACjD,KAAI,GAAG,SAAS,qCAAqC,CAAE,QAAO;AAC9D,KAAI,GAAG,SAAS,uBAAuB,CAAE,QAAO;AAChD,KAAI,CAAC,GAAG,SAAS,oBAAoB,CAAE,QAAO;AAC9C,SAAQ,QAAQ,UAAhB;EACE,KAAK;EACL,KAAK,UACH,QAAO;EACT,KAAK;EACL,KAAK,WACH,QAAO;EACT,KAAK,sBACH,QAAO;EACT,KAAK,SACH,QAAO;EACT,QACE,QAAO;;;AAIb,SAAS,KACP,SACA,OACa;AACb,KAAI,UAAU,QAAS,QAAO;AAC9B,SAAQ,eAAe,QAAQ,EAA/B;EACE,KAAK,SACH,QAAO,UAAU,cAAc,aAAa;EAC9C,KAAK,gBACH,QAAO,UAAU,cAAc,yBAAyB;EAC1D,KAAK;EACL,KAAK,iBACH,QAAO;EAOT,QACE,QAAO;;;AAcb,SAAgB,aACd,SACqC;CACrC,MAAM,EAAE,aAAa,UAAU,UAAU;CAGzC,MAAM,MAAM,UAAU,UAAU,cAAe,aAA4C;AAC3F,SAAQ,KAAK,SAAS,MAAM,EAA5B;EACE,KAAK,WACH,QAAO,cAAc,IAAI;EAC3B,KAAK,gBACH,QAAO,OAAO,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,IAAI,IAAI,OAAO,KAAK,IAAI,CAAC,SAAS,IACrF,MACD;EACN,KAAK,uBAGH,QAAO,OAAO,OAAO,QAAQ,WAAY,MAAkC;EAC7E,KAAK,mBAAmB;AACtB,OAAI,UAAU,SAAU,QAAOA,QAAsB,UAAU,IAAI;GACnE,MAAM,QAAQ;AACd,OAAI,OAAO,SAAS,gBAClB,QAAOA,QAAsB,UAAU,MAAM,SAAS,OAAO,QAAQ;AACvE,OAAI,OAAO,SAAS,gBAAiB,QAAOA,QAAsB,UAAU,KAAK,QAAQ;AACzF,UAAO;;EAET,KAAK,OACH"}
|