@bastani/pi-ai 0.9.14
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/CHANGELOG.md +9 -0
- package/LICENSE +22 -0
- package/NOTICE.md +16 -0
- package/README.md +1672 -0
- package/dist/api/anthropic-messages.d.ts +71 -0
- package/dist/api/anthropic-messages.d.ts.map +1 -0
- package/dist/api/anthropic-messages.js +1060 -0
- package/dist/api/anthropic-messages.js.map +1 -0
- package/dist/api/anthropic-messages.lazy.d.ts +3 -0
- package/dist/api/anthropic-messages.lazy.d.ts.map +1 -0
- package/dist/api/anthropic-messages.lazy.js +3 -0
- package/dist/api/anthropic-messages.lazy.js.map +1 -0
- package/dist/api/azure-openai-responses.d.ts +15 -0
- package/dist/api/azure-openai-responses.d.ts.map +1 -0
- package/dist/api/azure-openai-responses.js +242 -0
- package/dist/api/azure-openai-responses.js.map +1 -0
- package/dist/api/azure-openai-responses.lazy.d.ts +3 -0
- package/dist/api/azure-openai-responses.lazy.d.ts.map +1 -0
- package/dist/api/azure-openai-responses.lazy.js +3 -0
- package/dist/api/azure-openai-responses.lazy.js.map +1 -0
- package/dist/api/bedrock-converse-stream.d.ts +38 -0
- package/dist/api/bedrock-converse-stream.d.ts.map +1 -0
- package/dist/api/bedrock-converse-stream.js +967 -0
- package/dist/api/bedrock-converse-stream.js.map +1 -0
- package/dist/api/bedrock-converse-stream.lazy.d.ts +9 -0
- package/dist/api/bedrock-converse-stream.lazy.d.ts.map +1 -0
- package/dist/api/bedrock-converse-stream.lazy.js +30 -0
- package/dist/api/bedrock-converse-stream.lazy.js.map +1 -0
- package/dist/api/cloudflare-gateway-binding.d.ts +69 -0
- package/dist/api/cloudflare-gateway-binding.d.ts.map +1 -0
- package/dist/api/cloudflare-gateway-binding.js +159 -0
- package/dist/api/cloudflare-gateway-binding.js.map +1 -0
- package/dist/api/cloudflare.d.ts +9 -0
- package/dist/api/cloudflare.d.ts.map +1 -0
- package/dist/api/cloudflare.js +9 -0
- package/dist/api/cloudflare.js.map +1 -0
- package/dist/api/constrained-sampling.d.ts +20 -0
- package/dist/api/constrained-sampling.d.ts.map +1 -0
- package/dist/api/constrained-sampling.js +222 -0
- package/dist/api/constrained-sampling.js.map +1 -0
- package/dist/api/github-copilot-headers.d.ts +8 -0
- package/dist/api/github-copilot-headers.d.ts.map +1 -0
- package/dist/api/github-copilot-headers.js +29 -0
- package/dist/api/github-copilot-headers.js.map +1 -0
- package/dist/api/google-generative-ai.d.ts +13 -0
- package/dist/api/google-generative-ai.d.ts.map +1 -0
- package/dist/api/google-generative-ai.js +417 -0
- package/dist/api/google-generative-ai.js.map +1 -0
- package/dist/api/google-generative-ai.lazy.d.ts +3 -0
- package/dist/api/google-generative-ai.lazy.d.ts.map +1 -0
- package/dist/api/google-generative-ai.lazy.js +3 -0
- package/dist/api/google-generative-ai.lazy.js.map +1 -0
- package/dist/api/google-shared.d.ts +81 -0
- package/dist/api/google-shared.d.ts.map +1 -0
- package/dist/api/google-shared.js +384 -0
- package/dist/api/google-shared.js.map +1 -0
- package/dist/api/google-vertex.d.ts +15 -0
- package/dist/api/google-vertex.d.ts.map +1 -0
- package/dist/api/google-vertex.js +466 -0
- package/dist/api/google-vertex.js.map +1 -0
- package/dist/api/google-vertex.lazy.d.ts +3 -0
- package/dist/api/google-vertex.lazy.d.ts.map +1 -0
- package/dist/api/google-vertex.lazy.js +3 -0
- package/dist/api/google-vertex.lazy.js.map +1 -0
- package/dist/api/lazy.d.ts +19 -0
- package/dist/api/lazy.d.ts.map +1 -0
- package/dist/api/lazy.js +70 -0
- package/dist/api/lazy.js.map +1 -0
- package/dist/api/mistral-conversations.d.ts +25 -0
- package/dist/api/mistral-conversations.d.ts.map +1 -0
- package/dist/api/mistral-conversations.js +736 -0
- package/dist/api/mistral-conversations.js.map +1 -0
- package/dist/api/mistral-conversations.lazy.d.ts +3 -0
- package/dist/api/mistral-conversations.lazy.d.ts.map +1 -0
- package/dist/api/mistral-conversations.lazy.js +3 -0
- package/dist/api/mistral-conversations.lazy.js.map +1 -0
- package/dist/api/openai-codex-responses.d.ts +31 -0
- package/dist/api/openai-codex-responses.d.ts.map +1 -0
- package/dist/api/openai-codex-responses.js +1294 -0
- package/dist/api/openai-codex-responses.js.map +1 -0
- package/dist/api/openai-codex-responses.lazy.d.ts +3 -0
- package/dist/api/openai-codex-responses.lazy.d.ts.map +1 -0
- package/dist/api/openai-codex-responses.lazy.js +3 -0
- package/dist/api/openai-codex-responses.lazy.js.map +1 -0
- package/dist/api/openai-completions.d.ts +22 -0
- package/dist/api/openai-completions.d.ts.map +1 -0
- package/dist/api/openai-completions.js +1279 -0
- package/dist/api/openai-completions.js.map +1 -0
- package/dist/api/openai-completions.lazy.d.ts +3 -0
- package/dist/api/openai-completions.lazy.d.ts.map +1 -0
- package/dist/api/openai-completions.lazy.js +3 -0
- package/dist/api/openai-completions.lazy.js.map +1 -0
- package/dist/api/openai-prompt-cache.d.ts +3 -0
- package/dist/api/openai-prompt-cache.d.ts.map +1 -0
- package/dist/api/openai-prompt-cache.js +10 -0
- package/dist/api/openai-prompt-cache.js.map +1 -0
- package/dist/api/openai-responses-shared.d.ts +26 -0
- package/dist/api/openai-responses-shared.d.ts.map +1 -0
- package/dist/api/openai-responses-shared.js +686 -0
- package/dist/api/openai-responses-shared.js.map +1 -0
- package/dist/api/openai-responses.d.ts +14 -0
- package/dist/api/openai-responses.d.ts.map +1 -0
- package/dist/api/openai-responses.js +283 -0
- package/dist/api/openai-responses.js.map +1 -0
- package/dist/api/openai-responses.lazy.d.ts +3 -0
- package/dist/api/openai-responses.lazy.d.ts.map +1 -0
- package/dist/api/openai-responses.lazy.js +3 -0
- package/dist/api/openai-responses.lazy.js.map +1 -0
- package/dist/api/openrouter-images.d.ts +3 -0
- package/dist/api/openrouter-images.d.ts.map +1 -0
- package/dist/api/openrouter-images.js +132 -0
- package/dist/api/openrouter-images.js.map +1 -0
- package/dist/api/openrouter-images.lazy.d.ts +3 -0
- package/dist/api/openrouter-images.lazy.d.ts.map +1 -0
- package/dist/api/openrouter-images.lazy.js +4 -0
- package/dist/api/openrouter-images.lazy.js.map +1 -0
- package/dist/api/pi-messages.d.ts +97 -0
- package/dist/api/pi-messages.d.ts.map +1 -0
- package/dist/api/pi-messages.js +307 -0
- package/dist/api/pi-messages.js.map +1 -0
- package/dist/api/pi-messages.lazy.d.ts +3 -0
- package/dist/api/pi-messages.lazy.d.ts.map +1 -0
- package/dist/api/pi-messages.lazy.js +3 -0
- package/dist/api/pi-messages.lazy.js.map +1 -0
- package/dist/api/simple-options.d.ts +11 -0
- package/dist/api/simple-options.d.ts.map +1 -0
- package/dist/api/simple-options.js +59 -0
- package/dist/api/simple-options.js.map +1 -0
- package/dist/api/transform-messages.d.ts +8 -0
- package/dist/api/transform-messages.d.ts.map +1 -0
- package/dist/api/transform-messages.js +187 -0
- package/dist/api/transform-messages.js.map +1 -0
- package/dist/auth/context.d.ts +7 -0
- package/dist/auth/context.d.ts.map +1 -0
- package/dist/auth/context.js +42 -0
- package/dist/auth/context.js.map +1 -0
- package/dist/auth/credential-store.d.ts +17 -0
- package/dist/auth/credential-store.d.ts.map +1 -0
- package/dist/auth/credential-store.js +51 -0
- package/dist/auth/credential-store.js.map +1 -0
- package/dist/auth/helpers.d.ts +22 -0
- package/dist/auth/helpers.d.ts.map +1 -0
- package/dist/auth/helpers.js +53 -0
- package/dist/auth/helpers.js.map +1 -0
- package/dist/auth/oauth/anthropic.d.ts +9 -0
- package/dist/auth/oauth/anthropic.d.ts.map +1 -0
- package/dist/auth/oauth/anthropic.js +308 -0
- package/dist/auth/oauth/anthropic.js.map +1 -0
- package/dist/auth/oauth/device-code.d.ts +23 -0
- package/dist/auth/oauth/device-code.d.ts.map +1 -0
- package/dist/auth/oauth/device-code.js +69 -0
- package/dist/auth/oauth/device-code.js.map +1 -0
- package/dist/auth/oauth/github-copilot.d.ts +6 -0
- package/dist/auth/oauth/github-copilot.d.ts.map +1 -0
- package/dist/auth/oauth/github-copilot.js +328 -0
- package/dist/auth/oauth/github-copilot.js.map +1 -0
- package/dist/auth/oauth/kimi-coding.d.ts +10 -0
- package/dist/auth/oauth/kimi-coding.d.ts.map +1 -0
- package/dist/auth/oauth/kimi-coding.js +261 -0
- package/dist/auth/oauth/kimi-coding.js.map +1 -0
- package/dist/auth/oauth/load.d.ts +27 -0
- package/dist/auth/oauth/load.d.ts.map +1 -0
- package/dist/auth/oauth/load.js +59 -0
- package/dist/auth/oauth/load.js.map +1 -0
- package/dist/auth/oauth/oauth-page.d.ts +3 -0
- package/dist/auth/oauth/oauth-page.d.ts.map +1 -0
- package/dist/auth/oauth/oauth-page.js +105 -0
- package/dist/auth/oauth/oauth-page.js.map +1 -0
- package/dist/auth/oauth/openai-codex.d.ts +9 -0
- package/dist/auth/oauth/openai-codex.d.ts.map +1 -0
- package/dist/auth/oauth/openai-codex.js +450 -0
- package/dist/auth/oauth/openai-codex.js.map +1 -0
- package/dist/auth/oauth/openrouter.d.ts +15 -0
- package/dist/auth/oauth/openrouter.d.ts.map +1 -0
- package/dist/auth/oauth/openrouter.js +277 -0
- package/dist/auth/oauth/openrouter.js.map +1 -0
- package/dist/auth/oauth/pkce.d.ts +13 -0
- package/dist/auth/oauth/pkce.d.ts.map +1 -0
- package/dist/auth/oauth/pkce.js +31 -0
- package/dist/auth/oauth/pkce.js.map +1 -0
- package/dist/auth/oauth/radius.d.ts +17 -0
- package/dist/auth/oauth/radius.d.ts.map +1 -0
- package/dist/auth/oauth/radius.js +321 -0
- package/dist/auth/oauth/radius.js.map +1 -0
- package/dist/auth/oauth/xai.d.ts +6 -0
- package/dist/auth/oauth/xai.d.ts.map +1 -0
- package/dist/auth/oauth/xai.js +190 -0
- package/dist/auth/oauth/xai.js.map +1 -0
- package/dist/auth/resolve.d.ts +27 -0
- package/dist/auth/resolve.d.ts.map +1 -0
- package/dist/auth/resolve.js +132 -0
- package/dist/auth/resolve.js.map +1 -0
- package/dist/auth/types.d.ts +231 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +2 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/bedrock-provider.d.ts +5 -0
- package/dist/bedrock-provider.d.ts.map +1 -0
- package/dist/bedrock-provider.js +6 -0
- package/dist/bedrock-provider.js.map +1 -0
- package/dist/bun-oauth.d.ts +3 -0
- package/dist/bun-oauth.d.ts.map +1 -0
- package/dist/bun-oauth.js +21 -0
- package/dist/bun-oauth.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +113 -0
- package/dist/cli.js.map +1 -0
- package/dist/compat/extension-oauth-types.d.ts +39 -0
- package/dist/compat/extension-oauth-types.d.ts.map +1 -0
- package/dist/compat/extension-oauth-types.js +2 -0
- package/dist/compat/extension-oauth-types.js.map +1 -0
- package/dist/compat.d.ts +67 -0
- package/dist/compat.d.ts.map +1 -0
- package/dist/compat.js +199 -0
- package/dist/compat.js.map +1 -0
- package/dist/env-api-keys.d.ts +21 -0
- package/dist/env-api-keys.d.ts.map +1 -0
- package/dist/env-api-keys.js +156 -0
- package/dist/env-api-keys.js.map +1 -0
- package/dist/image-models.d.ts +10 -0
- package/dist/image-models.d.ts.map +1 -0
- package/dist/image-models.generated.d.ts +680 -0
- package/dist/image-models.generated.d.ts.map +1 -0
- package/dist/image-models.generated.js +682 -0
- package/dist/image-models.generated.js.map +1 -0
- package/dist/image-models.js +23 -0
- package/dist/image-models.js.map +1 -0
- package/dist/images-api-registry.d.ts +14 -0
- package/dist/images-api-registry.d.ts.map +1 -0
- package/dist/images-api-registry.js +22 -0
- package/dist/images-api-registry.js.map +1 -0
- package/dist/images-models.d.ts +95 -0
- package/dist/images-models.d.ts.map +1 -0
- package/dist/images-models.js +143 -0
- package/dist/images-models.js.map +1 -0
- package/dist/images.d.ts +4 -0
- package/dist/images.d.ts.map +1 -0
- package/dist/images.js +14 -0
- package/dist/images.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/legacy-api-aliases.d.ts +42 -0
- package/dist/legacy-api-aliases.d.ts.map +1 -0
- package/dist/legacy-api-aliases.js +49 -0
- package/dist/legacy-api-aliases.js.map +1 -0
- package/dist/model-catalog.d.ts +17 -0
- package/dist/model-catalog.d.ts.map +1 -0
- package/dist/model-catalog.js +4 -0
- package/dist/model-catalog.js.map +1 -0
- package/dist/models-store.d.ts +29 -0
- package/dist/models-store.d.ts.map +1 -0
- package/dist/models-store.js +17 -0
- package/dist/models-store.js.map +1 -0
- package/dist/models.d.ts +200 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.generated.d.ts +81 -0
- package/dist/models.generated.d.ts.map +1 -0
- package/dist/models.generated.js +83 -0
- package/dist/models.generated.js.map +1 -0
- package/dist/models.js +588 -0
- package/dist/models.js.map +1 -0
- package/dist/oauth.d.ts +3 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +2 -0
- package/dist/oauth.js.map +1 -0
- package/dist/providers/all.d.ts +28 -0
- package/dist/providers/all.d.ts.map +1 -0
- package/dist/providers/all.js +131 -0
- package/dist/providers/all.js.map +1 -0
- package/dist/providers/amazon-bedrock.d.ts +3 -0
- package/dist/providers/amazon-bedrock.d.ts.map +1 -0
- package/dist/providers/amazon-bedrock.js +93 -0
- package/dist/providers/amazon-bedrock.js.map +1 -0
- package/dist/providers/amazon-bedrock.models.d.ts +4 -0
- package/dist/providers/amazon-bedrock.models.d.ts.map +1 -0
- package/dist/providers/amazon-bedrock.models.js +6 -0
- package/dist/providers/amazon-bedrock.models.js.map +1 -0
- package/dist/providers/ant-ling.d.ts +3 -0
- package/dist/providers/ant-ling.d.ts.map +1 -0
- package/dist/providers/ant-ling.js +15 -0
- package/dist/providers/ant-ling.js.map +1 -0
- package/dist/providers/ant-ling.models.d.ts +4 -0
- package/dist/providers/ant-ling.models.d.ts.map +1 -0
- package/dist/providers/ant-ling.models.js +6 -0
- package/dist/providers/ant-ling.models.js.map +1 -0
- package/dist/providers/anthropic.d.ts +3 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +56 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/anthropic.models.d.ts +4 -0
- package/dist/providers/anthropic.models.d.ts.map +1 -0
- package/dist/providers/anthropic.models.js +6 -0
- package/dist/providers/anthropic.models.js.map +1 -0
- package/dist/providers/azure-openai-responses.d.ts +3 -0
- package/dist/providers/azure-openai-responses.d.ts.map +1 -0
- package/dist/providers/azure-openai-responses.js +14 -0
- package/dist/providers/azure-openai-responses.js.map +1 -0
- package/dist/providers/azure-openai-responses.models.d.ts +4 -0
- package/dist/providers/azure-openai-responses.models.d.ts.map +1 -0
- package/dist/providers/azure-openai-responses.models.js +6 -0
- package/dist/providers/azure-openai-responses.models.js.map +1 -0
- package/dist/providers/baseten.d.ts +3 -0
- package/dist/providers/baseten.d.ts.map +1 -0
- package/dist/providers/baseten.js +15 -0
- package/dist/providers/baseten.js.map +1 -0
- package/dist/providers/baseten.models.d.ts +4 -0
- package/dist/providers/baseten.models.d.ts.map +1 -0
- package/dist/providers/baseten.models.js +6 -0
- package/dist/providers/baseten.models.js.map +1 -0
- package/dist/providers/cerebras.d.ts +3 -0
- package/dist/providers/cerebras.d.ts.map +1 -0
- package/dist/providers/cerebras.js +15 -0
- package/dist/providers/cerebras.js.map +1 -0
- package/dist/providers/cerebras.models.d.ts +4 -0
- package/dist/providers/cerebras.models.d.ts.map +1 -0
- package/dist/providers/cerebras.models.js +6 -0
- package/dist/providers/cerebras.models.js.map +1 -0
- package/dist/providers/cloudflare-ai-gateway.d.ts +3 -0
- package/dist/providers/cloudflare-ai-gateway.d.ts.map +1 -0
- package/dist/providers/cloudflare-ai-gateway.js +21 -0
- package/dist/providers/cloudflare-ai-gateway.js.map +1 -0
- package/dist/providers/cloudflare-ai-gateway.models.d.ts +4 -0
- package/dist/providers/cloudflare-ai-gateway.models.d.ts.map +1 -0
- package/dist/providers/cloudflare-ai-gateway.models.js +6 -0
- package/dist/providers/cloudflare-ai-gateway.models.js.map +1 -0
- package/dist/providers/cloudflare-auth.d.ts +4 -0
- package/dist/providers/cloudflare-auth.d.ts.map +1 -0
- package/dist/providers/cloudflare-auth.js +86 -0
- package/dist/providers/cloudflare-auth.js.map +1 -0
- package/dist/providers/cloudflare-stream.d.ts +8 -0
- package/dist/providers/cloudflare-stream.d.ts.map +1 -0
- package/dist/providers/cloudflare-stream.js +21 -0
- package/dist/providers/cloudflare-stream.js.map +1 -0
- package/dist/providers/cloudflare-workers-ai.d.ts +3 -0
- package/dist/providers/cloudflare-workers-ai.d.ts.map +1 -0
- package/dist/providers/cloudflare-workers-ai.js +15 -0
- package/dist/providers/cloudflare-workers-ai.js.map +1 -0
- package/dist/providers/cloudflare-workers-ai.models.d.ts +4 -0
- package/dist/providers/cloudflare-workers-ai.models.d.ts.map +1 -0
- package/dist/providers/cloudflare-workers-ai.models.js +6 -0
- package/dist/providers/cloudflare-workers-ai.models.js.map +1 -0
- package/dist/providers/data/.manifest.json +1 -0
- package/dist/providers/data/amazon-bedrock.json +1 -0
- package/dist/providers/data/ant-ling.json +1 -0
- package/dist/providers/data/anthropic.json +1 -0
- package/dist/providers/data/azure-openai-responses.json +1 -0
- package/dist/providers/data/baseten.json +1 -0
- package/dist/providers/data/cerebras.json +1 -0
- package/dist/providers/data/cloudflare-ai-gateway.json +1 -0
- package/dist/providers/data/cloudflare-workers-ai.json +1 -0
- package/dist/providers/data/deepseek.json +1 -0
- package/dist/providers/data/fireworks.json +1 -0
- package/dist/providers/data/github-copilot.json +1 -0
- package/dist/providers/data/google-vertex.json +1 -0
- package/dist/providers/data/google.json +1 -0
- package/dist/providers/data/groq.json +1 -0
- package/dist/providers/data/huggingface.json +1 -0
- package/dist/providers/data/kimi-coding.json +1 -0
- package/dist/providers/data/minimax-cn.json +1 -0
- package/dist/providers/data/minimax.json +1 -0
- package/dist/providers/data/mistral.json +1 -0
- package/dist/providers/data/moonshotai-cn.json +1 -0
- package/dist/providers/data/moonshotai.json +1 -0
- package/dist/providers/data/nvidia.json +1 -0
- package/dist/providers/data/openai-codex.json +1 -0
- package/dist/providers/data/openai.json +1 -0
- package/dist/providers/data/opencode-go.json +1 -0
- package/dist/providers/data/opencode.json +1 -0
- package/dist/providers/data/openrouter.json +1 -0
- package/dist/providers/data/qwen-token-plan-cn.json +1 -0
- package/dist/providers/data/qwen-token-plan-individual.json +1 -0
- package/dist/providers/data/qwen-token-plan.json +1 -0
- package/dist/providers/data/together.json +1 -0
- package/dist/providers/data/vercel-ai-gateway.json +1 -0
- package/dist/providers/data/xai.json +1 -0
- package/dist/providers/data/xiaomi-token-plan-ams.json +1 -0
- package/dist/providers/data/xiaomi-token-plan-cn.json +1 -0
- package/dist/providers/data/xiaomi-token-plan-sgp.json +1 -0
- package/dist/providers/data/xiaomi.json +1 -0
- package/dist/providers/data/zai-coding-cn.json +1 -0
- package/dist/providers/data/zai.json +1 -0
- package/dist/providers/deepseek.d.ts +3 -0
- package/dist/providers/deepseek.d.ts.map +1 -0
- package/dist/providers/deepseek.js +15 -0
- package/dist/providers/deepseek.js.map +1 -0
- package/dist/providers/deepseek.models.d.ts +4 -0
- package/dist/providers/deepseek.models.d.ts.map +1 -0
- package/dist/providers/deepseek.models.js +6 -0
- package/dist/providers/deepseek.models.js.map +1 -0
- package/dist/providers/faux.d.ts +102 -0
- package/dist/providers/faux.d.ts.map +1 -0
- package/dist/providers/faux.js +488 -0
- package/dist/providers/faux.js.map +1 -0
- package/dist/providers/fireworks.d.ts +3 -0
- package/dist/providers/fireworks.d.ts.map +1 -0
- package/dist/providers/fireworks.js +19 -0
- package/dist/providers/fireworks.js.map +1 -0
- package/dist/providers/fireworks.models.d.ts +4 -0
- package/dist/providers/fireworks.models.d.ts.map +1 -0
- package/dist/providers/fireworks.models.js +6 -0
- package/dist/providers/fireworks.models.js.map +1 -0
- package/dist/providers/github-copilot.d.ts +3 -0
- package/dist/providers/github-copilot.d.ts.map +1 -0
- package/dist/providers/github-copilot.js +35 -0
- package/dist/providers/github-copilot.js.map +1 -0
- package/dist/providers/github-copilot.models.d.ts +4 -0
- package/dist/providers/github-copilot.models.d.ts.map +1 -0
- package/dist/providers/github-copilot.models.js +6 -0
- package/dist/providers/github-copilot.models.js.map +1 -0
- package/dist/providers/google-vertex.d.ts +3 -0
- package/dist/providers/google-vertex.d.ts.map +1 -0
- package/dist/providers/google-vertex.js +94 -0
- package/dist/providers/google-vertex.js.map +1 -0
- package/dist/providers/google-vertex.models.d.ts +4 -0
- package/dist/providers/google-vertex.models.d.ts.map +1 -0
- package/dist/providers/google-vertex.models.js +6 -0
- package/dist/providers/google-vertex.models.js.map +1 -0
- package/dist/providers/google.d.ts +3 -0
- package/dist/providers/google.d.ts.map +1 -0
- package/dist/providers/google.js +15 -0
- package/dist/providers/google.js.map +1 -0
- package/dist/providers/google.models.d.ts +4 -0
- package/dist/providers/google.models.d.ts.map +1 -0
- package/dist/providers/google.models.js +6 -0
- package/dist/providers/google.models.js.map +1 -0
- package/dist/providers/groq.d.ts +3 -0
- package/dist/providers/groq.d.ts.map +1 -0
- package/dist/providers/groq.js +15 -0
- package/dist/providers/groq.js.map +1 -0
- package/dist/providers/groq.models.d.ts +4 -0
- package/dist/providers/groq.models.d.ts.map +1 -0
- package/dist/providers/groq.models.js +6 -0
- package/dist/providers/groq.models.js.map +1 -0
- package/dist/providers/huggingface.d.ts +3 -0
- package/dist/providers/huggingface.d.ts.map +1 -0
- package/dist/providers/huggingface.js +15 -0
- package/dist/providers/huggingface.js.map +1 -0
- package/dist/providers/huggingface.models.d.ts +4 -0
- package/dist/providers/huggingface.models.d.ts.map +1 -0
- package/dist/providers/huggingface.models.js +6 -0
- package/dist/providers/huggingface.models.js.map +1 -0
- package/dist/providers/images/register-builtins.d.ts +4 -0
- package/dist/providers/images/register-builtins.d.ts.map +1 -0
- package/dist/providers/images/register-builtins.js +34 -0
- package/dist/providers/images/register-builtins.js.map +1 -0
- package/dist/providers/kimi-coding.d.ts +3 -0
- package/dist/providers/kimi-coding.d.ts.map +1 -0
- package/dist/providers/kimi-coding.js +24 -0
- package/dist/providers/kimi-coding.js.map +1 -0
- package/dist/providers/kimi-coding.models.d.ts +4 -0
- package/dist/providers/kimi-coding.models.d.ts.map +1 -0
- package/dist/providers/kimi-coding.models.js +6 -0
- package/dist/providers/kimi-coding.models.js.map +1 -0
- package/dist/providers/minimax-cn.d.ts +3 -0
- package/dist/providers/minimax-cn.d.ts.map +1 -0
- package/dist/providers/minimax-cn.js +15 -0
- package/dist/providers/minimax-cn.js.map +1 -0
- package/dist/providers/minimax-cn.models.d.ts +4 -0
- package/dist/providers/minimax-cn.models.d.ts.map +1 -0
- package/dist/providers/minimax-cn.models.js +6 -0
- package/dist/providers/minimax-cn.models.js.map +1 -0
- package/dist/providers/minimax.d.ts +3 -0
- package/dist/providers/minimax.d.ts.map +1 -0
- package/dist/providers/minimax.js +15 -0
- package/dist/providers/minimax.js.map +1 -0
- package/dist/providers/minimax.models.d.ts +4 -0
- package/dist/providers/minimax.models.d.ts.map +1 -0
- package/dist/providers/minimax.models.js +6 -0
- package/dist/providers/minimax.models.js.map +1 -0
- package/dist/providers/mistral.d.ts +3 -0
- package/dist/providers/mistral.d.ts.map +1 -0
- package/dist/providers/mistral.js +15 -0
- package/dist/providers/mistral.js.map +1 -0
- package/dist/providers/mistral.models.d.ts +4 -0
- package/dist/providers/mistral.models.d.ts.map +1 -0
- package/dist/providers/mistral.models.js +6 -0
- package/dist/providers/mistral.models.js.map +1 -0
- package/dist/providers/moonshotai-cn.d.ts +3 -0
- package/dist/providers/moonshotai-cn.d.ts.map +1 -0
- package/dist/providers/moonshotai-cn.js +15 -0
- package/dist/providers/moonshotai-cn.js.map +1 -0
- package/dist/providers/moonshotai-cn.models.d.ts +4 -0
- package/dist/providers/moonshotai-cn.models.d.ts.map +1 -0
- package/dist/providers/moonshotai-cn.models.js +6 -0
- package/dist/providers/moonshotai-cn.models.js.map +1 -0
- package/dist/providers/moonshotai.d.ts +3 -0
- package/dist/providers/moonshotai.d.ts.map +1 -0
- package/dist/providers/moonshotai.js +15 -0
- package/dist/providers/moonshotai.js.map +1 -0
- package/dist/providers/moonshotai.models.d.ts +4 -0
- package/dist/providers/moonshotai.models.d.ts.map +1 -0
- package/dist/providers/moonshotai.models.js +6 -0
- package/dist/providers/moonshotai.models.js.map +1 -0
- package/dist/providers/nvidia.d.ts +3 -0
- package/dist/providers/nvidia.d.ts.map +1 -0
- package/dist/providers/nvidia.js +15 -0
- package/dist/providers/nvidia.js.map +1 -0
- package/dist/providers/nvidia.models.d.ts +4 -0
- package/dist/providers/nvidia.models.d.ts.map +1 -0
- package/dist/providers/nvidia.models.js +6 -0
- package/dist/providers/nvidia.models.js.map +1 -0
- package/dist/providers/openai-codex.d.ts +3 -0
- package/dist/providers/openai-codex.d.ts.map +1 -0
- package/dist/providers/openai-codex.js +22 -0
- package/dist/providers/openai-codex.js.map +1 -0
- package/dist/providers/openai-codex.models.d.ts +4 -0
- package/dist/providers/openai-codex.models.d.ts.map +1 -0
- package/dist/providers/openai-codex.models.js +6 -0
- package/dist/providers/openai-codex.models.js.map +1 -0
- package/dist/providers/openai.d.ts +3 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +15 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/providers/openai.models.d.ts +4 -0
- package/dist/providers/openai.models.d.ts.map +1 -0
- package/dist/providers/openai.models.js +6 -0
- package/dist/providers/openai.models.js.map +1 -0
- package/dist/providers/opencode-go.d.ts +3 -0
- package/dist/providers/opencode-go.d.ts.map +1 -0
- package/dist/providers/opencode-go.js +20 -0
- package/dist/providers/opencode-go.js.map +1 -0
- package/dist/providers/opencode-go.models.d.ts +4 -0
- package/dist/providers/opencode-go.models.d.ts.map +1 -0
- package/dist/providers/opencode-go.models.js +6 -0
- package/dist/providers/opencode-go.models.js.map +1 -0
- package/dist/providers/opencode.d.ts +3 -0
- package/dist/providers/opencode.d.ts.map +1 -0
- package/dist/providers/opencode.js +22 -0
- package/dist/providers/opencode.js.map +1 -0
- package/dist/providers/opencode.models.d.ts +4 -0
- package/dist/providers/opencode.models.d.ts.map +1 -0
- package/dist/providers/opencode.models.js +6 -0
- package/dist/providers/opencode.models.js.map +1 -0
- package/dist/providers/openrouter-images.d.ts +3 -0
- package/dist/providers/openrouter-images.d.ts.map +1 -0
- package/dist/providers/openrouter-images.js +22 -0
- package/dist/providers/openrouter-images.js.map +1 -0
- package/dist/providers/openrouter.d.ts +3 -0
- package/dist/providers/openrouter.d.ts.map +1 -0
- package/dist/providers/openrouter.js +23 -0
- package/dist/providers/openrouter.js.map +1 -0
- package/dist/providers/openrouter.models.d.ts +4 -0
- package/dist/providers/openrouter.models.d.ts.map +1 -0
- package/dist/providers/openrouter.models.js +6 -0
- package/dist/providers/openrouter.models.js.map +1 -0
- package/dist/providers/qwen-token-plan-cn.d.ts +3 -0
- package/dist/providers/qwen-token-plan-cn.d.ts.map +1 -0
- package/dist/providers/qwen-token-plan-cn.js +15 -0
- package/dist/providers/qwen-token-plan-cn.js.map +1 -0
- package/dist/providers/qwen-token-plan-cn.models.d.ts +4 -0
- package/dist/providers/qwen-token-plan-cn.models.d.ts.map +1 -0
- package/dist/providers/qwen-token-plan-cn.models.js +6 -0
- package/dist/providers/qwen-token-plan-cn.models.js.map +1 -0
- package/dist/providers/qwen-token-plan-individual.d.ts +3 -0
- package/dist/providers/qwen-token-plan-individual.d.ts.map +1 -0
- package/dist/providers/qwen-token-plan-individual.js +15 -0
- package/dist/providers/qwen-token-plan-individual.js.map +1 -0
- package/dist/providers/qwen-token-plan-individual.models.d.ts +4 -0
- package/dist/providers/qwen-token-plan-individual.models.d.ts.map +1 -0
- package/dist/providers/qwen-token-plan-individual.models.js +6 -0
- package/dist/providers/qwen-token-plan-individual.models.js.map +1 -0
- package/dist/providers/qwen-token-plan.d.ts +3 -0
- package/dist/providers/qwen-token-plan.d.ts.map +1 -0
- package/dist/providers/qwen-token-plan.js +15 -0
- package/dist/providers/qwen-token-plan.js.map +1 -0
- package/dist/providers/qwen-token-plan.models.d.ts +4 -0
- package/dist/providers/qwen-token-plan.models.d.ts.map +1 -0
- package/dist/providers/qwen-token-plan.models.js +6 -0
- package/dist/providers/qwen-token-plan.models.js.map +1 -0
- package/dist/providers/radius-config.d.ts +26 -0
- package/dist/providers/radius-config.d.ts.map +1 -0
- package/dist/providers/radius-config.js +63 -0
- package/dist/providers/radius-config.js.map +1 -0
- package/dist/providers/radius.d.ts +9 -0
- package/dist/providers/radius.d.ts.map +1 -0
- package/dist/providers/radius.js +64 -0
- package/dist/providers/radius.js.map +1 -0
- package/dist/providers/together.d.ts +3 -0
- package/dist/providers/together.d.ts.map +1 -0
- package/dist/providers/together.js +15 -0
- package/dist/providers/together.js.map +1 -0
- package/dist/providers/together.models.d.ts +4 -0
- package/dist/providers/together.models.d.ts.map +1 -0
- package/dist/providers/together.models.js +6 -0
- package/dist/providers/together.models.js.map +1 -0
- package/dist/providers/vercel-ai-gateway.d.ts +3 -0
- package/dist/providers/vercel-ai-gateway.d.ts.map +1 -0
- package/dist/providers/vercel-ai-gateway.js +15 -0
- package/dist/providers/vercel-ai-gateway.js.map +1 -0
- package/dist/providers/vercel-ai-gateway.models.d.ts +4 -0
- package/dist/providers/vercel-ai-gateway.models.d.ts.map +1 -0
- package/dist/providers/vercel-ai-gateway.models.js +6 -0
- package/dist/providers/vercel-ai-gateway.models.js.map +1 -0
- package/dist/providers/xai.d.ts +3 -0
- package/dist/providers/xai.d.ts.map +1 -0
- package/dist/providers/xai.js +28 -0
- package/dist/providers/xai.js.map +1 -0
- package/dist/providers/xai.models.d.ts +4 -0
- package/dist/providers/xai.models.d.ts.map +1 -0
- package/dist/providers/xai.models.js +6 -0
- package/dist/providers/xai.models.js.map +1 -0
- package/dist/providers/xiaomi-token-plan-ams.d.ts +3 -0
- package/dist/providers/xiaomi-token-plan-ams.d.ts.map +1 -0
- package/dist/providers/xiaomi-token-plan-ams.js +15 -0
- package/dist/providers/xiaomi-token-plan-ams.js.map +1 -0
- package/dist/providers/xiaomi-token-plan-ams.models.d.ts +4 -0
- package/dist/providers/xiaomi-token-plan-ams.models.d.ts.map +1 -0
- package/dist/providers/xiaomi-token-plan-ams.models.js +6 -0
- package/dist/providers/xiaomi-token-plan-ams.models.js.map +1 -0
- package/dist/providers/xiaomi-token-plan-cn.d.ts +3 -0
- package/dist/providers/xiaomi-token-plan-cn.d.ts.map +1 -0
- package/dist/providers/xiaomi-token-plan-cn.js +15 -0
- package/dist/providers/xiaomi-token-plan-cn.js.map +1 -0
- package/dist/providers/xiaomi-token-plan-cn.models.d.ts +4 -0
- package/dist/providers/xiaomi-token-plan-cn.models.d.ts.map +1 -0
- package/dist/providers/xiaomi-token-plan-cn.models.js +6 -0
- package/dist/providers/xiaomi-token-plan-cn.models.js.map +1 -0
- package/dist/providers/xiaomi-token-plan-sgp.d.ts +3 -0
- package/dist/providers/xiaomi-token-plan-sgp.d.ts.map +1 -0
- package/dist/providers/xiaomi-token-plan-sgp.js +15 -0
- package/dist/providers/xiaomi-token-plan-sgp.js.map +1 -0
- package/dist/providers/xiaomi-token-plan-sgp.models.d.ts +4 -0
- package/dist/providers/xiaomi-token-plan-sgp.models.d.ts.map +1 -0
- package/dist/providers/xiaomi-token-plan-sgp.models.js +6 -0
- package/dist/providers/xiaomi-token-plan-sgp.models.js.map +1 -0
- package/dist/providers/xiaomi.d.ts +3 -0
- package/dist/providers/xiaomi.d.ts.map +1 -0
- package/dist/providers/xiaomi.js +15 -0
- package/dist/providers/xiaomi.js.map +1 -0
- package/dist/providers/xiaomi.models.d.ts +4 -0
- package/dist/providers/xiaomi.models.d.ts.map +1 -0
- package/dist/providers/xiaomi.models.js +6 -0
- package/dist/providers/xiaomi.models.js.map +1 -0
- package/dist/providers/zai-coding-cn.d.ts +3 -0
- package/dist/providers/zai-coding-cn.d.ts.map +1 -0
- package/dist/providers/zai-coding-cn.js +15 -0
- package/dist/providers/zai-coding-cn.js.map +1 -0
- package/dist/providers/zai-coding-cn.models.d.ts +4 -0
- package/dist/providers/zai-coding-cn.models.d.ts.map +1 -0
- package/dist/providers/zai-coding-cn.models.js +6 -0
- package/dist/providers/zai-coding-cn.models.js.map +1 -0
- package/dist/providers/zai.d.ts +3 -0
- package/dist/providers/zai.d.ts.map +1 -0
- package/dist/providers/zai.js +15 -0
- package/dist/providers/zai.js.map +1 -0
- package/dist/providers/zai.models.d.ts +4 -0
- package/dist/providers/zai.models.d.ts.map +1 -0
- package/dist/providers/zai.models.js +6 -0
- package/dist/providers/zai.models.js.map +1 -0
- package/dist/session-resources.d.ts +4 -0
- package/dist/session-resources.d.ts.map +1 -0
- package/dist/session-resources.js +22 -0
- package/dist/session-resources.js.map +1 -0
- package/dist/types.d.ts +697 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/abort-signals.d.ts +6 -0
- package/dist/utils/abort-signals.d.ts.map +1 -0
- package/dist/utils/abort-signals.js +34 -0
- package/dist/utils/abort-signals.js.map +1 -0
- package/dist/utils/abort.d.ts +8 -0
- package/dist/utils/abort.d.ts.map +1 -0
- package/dist/utils/abort.js +49 -0
- package/dist/utils/abort.js.map +1 -0
- package/dist/utils/deferred-tools.d.ts +9 -0
- package/dist/utils/deferred-tools.d.ts.map +1 -0
- package/dist/utils/deferred-tools.js +36 -0
- package/dist/utils/deferred-tools.js.map +1 -0
- package/dist/utils/diagnostics.d.ts +19 -0
- package/dist/utils/diagnostics.d.ts.map +1 -0
- package/dist/utils/diagnostics.js +25 -0
- package/dist/utils/diagnostics.js.map +1 -0
- package/dist/utils/error-body.d.ts +25 -0
- package/dist/utils/error-body.d.ts.map +1 -0
- package/dist/utils/error-body.js +133 -0
- package/dist/utils/error-body.js.map +1 -0
- package/dist/utils/estimate.d.ts +17 -0
- package/dist/utils/estimate.d.ts.map +1 -0
- package/dist/utils/estimate.js +116 -0
- package/dist/utils/estimate.js.map +1 -0
- package/dist/utils/event-stream.d.ts +21 -0
- package/dist/utils/event-stream.d.ts.map +1 -0
- package/dist/utils/event-stream.js +81 -0
- package/dist/utils/event-stream.js.map +1 -0
- package/dist/utils/hash.d.ts +3 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +14 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/headers.d.ts +4 -0
- package/dist/utils/headers.d.ts.map +1 -0
- package/dist/utils/headers.js +18 -0
- package/dist/utils/headers.js.map +1 -0
- package/dist/utils/json-parse.d.ts +16 -0
- package/dist/utils/json-parse.d.ts.map +1 -0
- package/dist/utils/json-parse.js +113 -0
- package/dist/utils/json-parse.js.map +1 -0
- package/dist/utils/node-http-proxy.d.ts +4 -0
- package/dist/utils/node-http-proxy.d.ts.map +1 -0
- package/dist/utils/node-http-proxy.js +92 -0
- package/dist/utils/node-http-proxy.js.map +1 -0
- package/dist/utils/overflow.d.ts +68 -0
- package/dist/utils/overflow.d.ts.map +1 -0
- package/dist/utils/overflow.js +172 -0
- package/dist/utils/overflow.js.map +1 -0
- package/dist/utils/pi-user-agent.d.ts +2 -0
- package/dist/utils/pi-user-agent.d.ts.map +1 -0
- package/dist/utils/pi-user-agent.js +12 -0
- package/dist/utils/pi-user-agent.js.map +1 -0
- package/dist/utils/provider-env.d.ts +7 -0
- package/dist/utils/provider-env.d.ts.map +1 -0
- package/dist/utils/provider-env.js +44 -0
- package/dist/utils/provider-env.js.map +1 -0
- package/dist/utils/provider-retry.d.ts +16 -0
- package/dist/utils/provider-retry.d.ts.map +1 -0
- package/dist/utils/provider-retry.js +94 -0
- package/dist/utils/provider-retry.js.map +1 -0
- package/dist/utils/retry.d.ts +53 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +174 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/sanitize-unicode.d.ts +22 -0
- package/dist/utils/sanitize-unicode.d.ts.map +1 -0
- package/dist/utils/sanitize-unicode.js +26 -0
- package/dist/utils/sanitize-unicode.js.map +1 -0
- package/dist/utils/text.d.ts +6 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +10 -0
- package/dist/utils/text.js.map +1 -0
- package/dist/utils/typebox-helpers.d.ts +17 -0
- package/dist/utils/typebox-helpers.d.ts.map +1 -0
- package/dist/utils/typebox-helpers.js +21 -0
- package/dist/utils/typebox-helpers.js.map +1 -0
- package/dist/utils/uuid.d.ts +3 -0
- package/dist/utils/uuid.d.ts.map +1 -0
- package/dist/utils/uuid.js +46 -0
- package/dist/utils/uuid.js.map +1 -0
- package/dist/utils/validation.d.ts +18 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +309 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +122 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi-messages.js","sourceRoot":"","sources":["../../src/api/pi-messages.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * pi-messages API implementation.\n *\n * Streams pi's own message protocol directly to a backend: the request is a\n * single POST of `{ model, context, options }` to `<baseUrl>/messages`, the\n * response is an SSE stream of serialized assistant-message events plus a\n * terminal `done`/`error` event. This is the wire protocol spoken by the\n * Radius gateway, but any backend implementing it can be used, e.g. via a\n * models.json custom provider with `\"api\": \"pi-messages\"`.\n */\n\nimport type {\n\tAssistantMessage,\n\tAssistantMessageEvent,\n\tCacheRetention,\n\tContext,\n\tModel,\n\tProviderEnv,\n\tSimpleStreamOptions,\n\tStreamFunction,\n\tStreamOptions,\n\tThinkingLevel,\n\tToolCall,\n} from \"../types.ts\";\nimport { appendAssistantMessageDiagnostic, createAssistantMessageDiagnostic } from \"../utils/diagnostics.ts\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.ts\";\nimport { headersToRecord, providerHeadersToRecord } from \"../utils/headers.ts\";\nimport { parseStreamingJson } from \"../utils/json-parse.ts\";\nimport { getProviderEnvValue } from \"../utils/provider-env.ts\";\n\nexport interface PiMessagesOptions extends StreamOptions {\n\treasoning?: ThinkingLevel;\n\ttoolChoice?: \"auto\" | \"none\" | \"required\" | { type: \"function\"; function: { name: string } };\n\t/** Ask the backend for debug metadata (e.g. routing response headers). */\n\tdebug?: boolean;\n}\n\ntype PiMessagesUsage = AssistantMessage[\"usage\"];\ntype PiMessagesStopReason = AssistantMessage[\"stopReason\"];\n\n/** Impact summary of a server-side message rewrite (e.g. a gateway policy). */\nexport type PiMessagesRewriteImpact = {\n\tpolicyId: string;\n\tpolicyVersion: number;\n\tchanged: boolean;\n\ttokenCountChange: number;\n\tmessageCountChange: number;\n\tsystemPromptChanged: boolean;\n};\n\n/** Serialized assistant-message event as sent by a pi-messages backend. */\nexport type PiMessagesEvent =\n\t| { type: \"start\" }\n\t| { type: \"text_start\"; contentIndex: number }\n\t| { type: \"text_delta\"; contentIndex: number; delta: string }\n\t| { type: \"text_end\"; contentIndex: number; content: string; contentSignature?: string }\n\t| { type: \"thinking_start\"; contentIndex: number }\n\t| { type: \"thinking_delta\"; contentIndex: number; delta: string }\n\t| {\n\t\t\ttype: \"thinking_end\";\n\t\t\tcontentIndex: number;\n\t\t\tcontent: string;\n\t\t\tcontentSignature?: string;\n\t\t\tredacted?: boolean;\n\t }\n\t| { type: \"toolcall_start\"; contentIndex: number; id: string; toolName: string }\n\t| { type: \"toolcall_delta\"; contentIndex: number; delta: string }\n\t| { type: \"toolcall_end\"; contentIndex: number; toolCall: ToolCall }\n\t| {\n\t\t\ttype: \"done\";\n\t\t\treason: Extract<PiMessagesStopReason, \"stop\" | \"length\" | \"toolUse\">;\n\t\t\tusage: PiMessagesUsage;\n\t\t\tresponseId?: string;\n\t\t\trewrite?: PiMessagesRewriteImpact;\n\t }\n\t| {\n\t\t\ttype: \"error\";\n\t\t\treason: Extract<PiMessagesStopReason, \"aborted\" | \"error\">;\n\t\t\tusage: PiMessagesUsage;\n\t\t\terrorMessage?: string;\n\t\t\tresponseId?: string;\n\t\t\trewrite?: PiMessagesRewriteImpact;\n\t };\n\ntype PiMessagesErrorBody = {\n\terror?: {\n\t\tmessage?: unknown;\n\t\tcode?: unknown;\n\t\tdetails?: unknown;\n\t\t[key: string]: unknown;\n\t};\n};\n\nexport class PiMessagesResponseError extends Error {\n\tcode?: string;\n\treadonly diagnosticDetails: Record<string, unknown>;\n\n\tconstructor(message: string, code: string | undefined, diagnosticDetails: Record<string, unknown>) {\n\t\tsuper(message);\n\t\tthis.name = \"PiMessagesResponseError\";\n\t\tthis.code = code;\n\t\tthis.diagnosticDetails = diagnosticDetails;\n\t}\n}\n\nfunction parsePiMessagesErrorBody(body: string): PiMessagesErrorBody | undefined {\n\ttry {\n\t\tconst parsed = JSON.parse(body) as PiMessagesErrorBody | null;\n\t\tconst error = parsed?.error;\n\t\treturn parsed && typeof error === \"object\" && error !== null && !Array.isArray(error) ? parsed : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction truncateDiagnosticString(value: string): string {\n\tconst maxLength = 8192;\n\treturn value.length > maxLength ? `${value.slice(0, maxLength)}…` : value;\n}\n\nfunction formatPiMessagesResponseError(\n\tresponse: Response,\n\tbody: string,\n\terrorBody: PiMessagesErrorBody | undefined,\n): string {\n\tconst message = typeof errorBody?.error?.message === \"string\" ? errorBody.error.message : undefined;\n\tconst code = typeof errorBody?.error?.code === \"string\" ? errorBody.error.code : undefined;\n\tconst suffix = message ?? body;\n\tconst codeSuffix = code ? ` (${code})` : \"\";\n\treturn `${response.status} ${response.statusText}: ${suffix}${codeSuffix}`;\n}\n\nfunction createPiMessagesResponseError(\n\tmodel: Model<\"pi-messages\">,\n\turl: URL,\n\tresponse: Response,\n\tbody: string,\n): PiMessagesResponseError {\n\tconst errorBody = parsePiMessagesErrorBody(body);\n\tconst code = typeof errorBody?.error?.code === \"string\" ? errorBody.error.code : undefined;\n\treturn new PiMessagesResponseError(formatPiMessagesResponseError(response, body, errorBody), code, {\n\t\tversion: 1,\n\t\tprovider: model.provider,\n\t\tmodel: model.id,\n\t\turl: url.toString(),\n\t\tstatus: response.status,\n\t\tstatusText: response.statusText,\n\t\terror: errorBody?.error,\n\t\tbody: errorBody ? undefined : truncateDiagnosticString(body),\n\t\ttimestampMs: Date.now(),\n\t});\n}\n\nfunction createEmptyUsage(): PiMessagesUsage {\n\treturn {\n\t\tinput: 0,\n\t\toutput: 0,\n\t\tcacheRead: 0,\n\t\tcacheWrite: 0,\n\t\ttotalTokens: 0,\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t};\n}\n\nfunction appendRewriteDiagnostic(message: AssistantMessage, rewrite: PiMessagesRewriteImpact | undefined): void {\n\tif (!rewrite) {\n\t\treturn;\n\t}\n\tappendAssistantMessageDiagnostic(message, {\n\t\ttype: \"pi_messages_rewrite\",\n\t\ttimestamp: Date.now(),\n\t\tdetails: { ...rewrite },\n\t});\n}\n\nfunction createEventConverter(model: Model<\"pi-messages\">) {\n\tconst partial: AssistantMessage = {\n\t\trole: \"assistant\",\n\t\tcontent: [],\n\t\tapi: model.api,\n\t\tprovider: model.provider,\n\t\tmodel: model.id,\n\t\tusage: createEmptyUsage(),\n\t\tstopReason: \"pending\",\n\t\ttimestamp: Date.now(),\n\t};\n\tconst toolJson = new Map<number, string>();\n\n\treturn (event: PiMessagesEvent): AssistantMessageEvent => {\n\t\tswitch (event.type) {\n\t\t\tcase \"done\":\n\t\t\t\tObject.assign(partial, {\n\t\t\t\t\tstopReason: event.reason,\n\t\t\t\t\tusage: event.usage,\n\t\t\t\t\tresponseId: event.responseId,\n\t\t\t\t});\n\t\t\t\tappendRewriteDiagnostic(partial, event.rewrite);\n\t\t\t\treturn { type: \"done\", reason: event.reason, message: partial };\n\t\t\tcase \"error\":\n\t\t\t\tObject.assign(partial, {\n\t\t\t\t\tstopReason: event.reason,\n\t\t\t\t\tusage: event.usage,\n\t\t\t\t\terrorMessage: event.errorMessage,\n\t\t\t\t\tresponseId: event.responseId,\n\t\t\t\t});\n\t\t\t\tappendRewriteDiagnostic(partial, event.rewrite);\n\t\t\t\treturn { type: \"error\", reason: event.reason, error: partial };\n\t\t\tcase \"start\":\n\t\t\t\tbreak;\n\t\t\tcase \"text_start\":\n\t\t\t\tpartial.content[event.contentIndex] = { type: \"text\", text: \"\" };\n\t\t\t\tbreak;\n\t\t\tcase \"text_delta\":\n\t\t\t\t(partial.content[event.contentIndex] as { text: string }).text += event.delta;\n\t\t\t\tbreak;\n\t\t\tcase \"text_end\":\n\t\t\t\tObject.assign(partial.content[event.contentIndex]!, {\n\t\t\t\t\ttext: event.content,\n\t\t\t\t\ttextSignature: event.contentSignature,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"thinking_start\":\n\t\t\t\tpartial.content[event.contentIndex] = { type: \"thinking\", thinking: \"\" };\n\t\t\t\tbreak;\n\t\t\tcase \"thinking_delta\":\n\t\t\t\t(partial.content[event.contentIndex] as { thinking: string }).thinking += event.delta;\n\t\t\t\tbreak;\n\t\t\tcase \"thinking_end\":\n\t\t\t\tObject.assign(partial.content[event.contentIndex]!, {\n\t\t\t\t\tthinking: event.content,\n\t\t\t\t\tthinkingSignature: event.contentSignature,\n\t\t\t\t\tredacted: event.redacted,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\tcase \"toolcall_start\":\n\t\t\t\tpartial.content[event.contentIndex] = {\n\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\tid: event.id,\n\t\t\t\t\tname: event.toolName,\n\t\t\t\t\targuments: {},\n\t\t\t\t};\n\t\t\t\ttoolJson.set(event.contentIndex, \"\");\n\t\t\t\tbreak;\n\t\t\tcase \"toolcall_delta\": {\n\t\t\t\tconst json = `${toolJson.get(event.contentIndex) ?? \"\"}${event.delta}`;\n\t\t\t\ttoolJson.set(event.contentIndex, json);\n\t\t\t\t(partial.content[event.contentIndex] as ToolCall).arguments =\n\t\t\t\t\tparseStreamingJson<ToolCall[\"arguments\"]>(json);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"toolcall_end\":\n\t\t\t\tObject.assign(partial.content[event.contentIndex]!, event.toolCall);\n\t\t\t\ttoolJson.delete(event.contentIndex);\n\t\t\t\treturn {\n\t\t\t\t\ttype: \"toolcall_end\",\n\t\t\t\t\tcontentIndex: event.contentIndex,\n\t\t\t\t\ttoolCall: partial.content[event.contentIndex] as ToolCall,\n\t\t\t\t\tpartial,\n\t\t\t\t};\n\t\t}\n\n\t\treturn { ...event, partial } as AssistantMessageEvent;\n\t};\n}\n\nasync function* readPiMessagesEvents(stream: ReadableStream<Uint8Array>): AsyncGenerator<PiMessagesEvent> {\n\tconst decoder = new TextDecoder();\n\tconst reader = stream.getReader();\n\tlet buffer = \"\";\n\n\ttry {\n\t\twhile (true) {\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tbuffer += done ? decoder.decode() : decoder.decode(value, { stream: true });\n\t\t\tbuffer = buffer.replace(/\\r\\n/g, \"\\n\");\n\n\t\t\tlet split = buffer.indexOf(\"\\n\\n\");\n\t\t\twhile (split !== -1) {\n\t\t\t\tconst event = parsePiMessagesEvent(buffer.slice(0, split));\n\t\t\t\tif (event) {\n\t\t\t\t\tyield event;\n\t\t\t\t}\n\t\t\t\tbuffer = buffer.slice(split + 2);\n\t\t\t\tsplit = buffer.indexOf(\"\\n\\n\");\n\t\t\t}\n\n\t\t\tif (done) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (buffer.trim()) {\n\t\t\tconst event = parsePiMessagesEvent(buffer);\n\t\t\tif (event) {\n\t\t\t\tyield event;\n\t\t\t}\n\t\t}\n\t} finally {\n\t\treader.releaseLock();\n\t}\n}\n\nfunction parsePiMessagesEvent(raw: string): PiMessagesEvent | undefined {\n\tconst data = raw\n\t\t.split(\"\\n\")\n\t\t.find((line) => line.startsWith(\"data:\"))\n\t\t?.slice(5)\n\t\t.trim();\n\n\treturn data && data !== \"[DONE]\" ? (JSON.parse(data) as PiMessagesEvent) : undefined;\n}\n\nfunction createErrorEvent(model: Model<\"pi-messages\">, error: unknown, aborted: boolean): AssistantMessageEvent {\n\tconst reason = aborted ? \"aborted\" : \"error\";\n\tconst assistantMessage: AssistantMessage = {\n\t\trole: \"assistant\",\n\t\tcontent: [],\n\t\tapi: model.api,\n\t\tprovider: model.provider,\n\t\tmodel: model.id,\n\t\tusage: createEmptyUsage(),\n\t\tstopReason: reason,\n\t\terrorMessage: error instanceof Error ? error.message : String(error),\n\t\ttimestamp: Date.now(),\n\t};\n\n\tif (!aborted && error instanceof PiMessagesResponseError) {\n\t\tappendAssistantMessageDiagnostic(\n\t\t\tassistantMessage,\n\t\t\tcreateAssistantMessageDiagnostic(\"pi_messages_response_failure\", error, error.diagnosticDetails),\n\t\t);\n\t}\n\n\treturn { type: \"error\", reason, error: assistantMessage };\n}\n\nfunction resolveCacheRetention(cacheRetention?: CacheRetention, env?: ProviderEnv): CacheRetention | undefined {\n\tif (cacheRetention) {\n\t\treturn cacheRetention;\n\t}\n\t// Backend defaults apply when unset; only the legacy env opt-in is mapped.\n\treturn getProviderEnvValue(\"PI_CACHE_RETENTION\", env) === \"long\" ? \"long\" : undefined;\n}\n\nexport const stream: StreamFunction<\"pi-messages\", PiMessagesOptions> = (\n\tmodel: Model<\"pi-messages\">,\n\tcontext: Context,\n\toptions?: PiMessagesOptions,\n): AssistantMessageEventStream => {\n\tconst eventStream = new AssistantMessageEventStream();\n\tconst convertEvent = createEventConverter(model);\n\n\tvoid (async () => {\n\t\ttry {\n\t\t\tconst apiKey = options?.apiKey;\n\t\t\tif (!apiKey) {\n\t\t\t\tthrow new Error(`No API key provided for provider \"${model.provider}\"`);\n\t\t\t}\n\n\t\t\tconst url = new URL(`${model.baseUrl.replace(/\\/+$/u, \"\")}/messages`);\n\t\t\tif (options?.debug) {\n\t\t\t\turl.searchParams.set(\"debug\", \"1\");\n\t\t\t}\n\n\t\t\tlet payload: unknown = {\n\t\t\t\tmodel: model.id,\n\t\t\t\tcontext,\n\t\t\t\toptions: {\n\t\t\t\t\ttemperature: options?.temperature,\n\t\t\t\t\tmaxTokens: options?.maxTokens,\n\t\t\t\t\treasoning: options?.reasoning,\n\t\t\t\t\tcacheRetention: resolveCacheRetention(options?.cacheRetention, options?.env),\n\t\t\t\t\tsessionId: options?.sessionId,\n\t\t\t\t\ttoolChoice: options?.toolChoice,\n\t\t\t\t},\n\t\t\t};\n\t\t\tconst nextPayload = await options?.onPayload?.(payload, model);\n\t\t\tif (nextPayload !== undefined) {\n\t\t\t\tpayload = nextPayload;\n\t\t\t}\n\n\t\t\tconst response = await (options?.fetch ?? globalThis.fetch)(url, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: {\n\t\t\t\t\tauthorization: `Bearer ${apiKey}`,\n\t\t\t\t\taccept: \"text/event-stream\",\n\t\t\t\t\t\"content-type\": \"application/json\",\n\t\t\t\t\t...providerHeadersToRecord(options?.headers),\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify(payload),\n\t\t\t\tsignal: options?.signal,\n\t\t\t});\n\n\t\t\tawait options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);\n\n\t\t\tif (!response.ok) {\n\t\t\t\tconst body = await response.text();\n\t\t\t\tthrow createPiMessagesResponseError(model, url, response, body);\n\t\t\t}\n\t\t\tif (!response.body) {\n\t\t\t\tthrow new Error(`${model.provider} response has no body`);\n\t\t\t}\n\n\t\t\tfor await (const piEvent of readPiMessagesEvents(response.body)) {\n\t\t\t\tconst event = convertEvent(piEvent);\n\t\t\t\teventStream.push(event);\n\t\t\t\tif (event.type === \"done\" || event.type === \"error\") {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthrow new Error(`${model.provider} stream ended without a terminal event`);\n\t\t} catch (error) {\n\t\t\teventStream.push(createErrorEvent(model, error, options?.signal?.aborted ?? false));\n\t\t}\n\t})();\n\n\treturn eventStream;\n};\n\nexport const streamSimple: StreamFunction<\"pi-messages\", SimpleStreamOptions> = (\n\tmodel: Model<\"pi-messages\">,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream => {\n\tconst extra = options as PiMessagesOptions | undefined;\n\treturn stream(model, context, {\n\t\t...options,\n\t\treasoning: options?.reasoning,\n\t\ttoolChoice: extra?.toolChoice,\n\t\tdebug: extra?.debug,\n\t});\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi-messages.lazy.d.ts","sourceRoot":"","sources":["../../src/api/pi-messages.lazy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD,eAAO,MAAM,aAAa,uBAAmE,CAAC","sourcesContent":["import type { ProviderStreams } from \"../types.ts\";\nimport { lazyApi } from \"./lazy.ts\";\n\nexport const piMessagesApi = (): ProviderStreams => lazyApi(() => import(\"./pi-messages.ts\"));\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pi-messages.lazy.js","sourceRoot":"","sources":["../../src/api/pi-messages.lazy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,CAAC,MAAM,aAAa,GAAG,GAAoB,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC","sourcesContent":["import type { ProviderStreams } from \"../types.ts\";\nimport { lazyApi } from \"./lazy.ts\";\n\nexport const piMessagesApi = (): ProviderStreams => lazyApi(() => import(\"./pi-messages.ts\"));\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Api, Context, Model, SimpleStreamOptions, StreamOptions, ThinkingBudgets, ThinkingLevel } from "../types.ts";
|
|
2
|
+
export declare function clampMaxTokensToContext(model: Model<Api>, context: Context, maxTokens: number): number;
|
|
3
|
+
export declare function buildBaseOptions(model: Model<Api>, context: Context, options?: SimpleStreamOptions, apiKey?: string): StreamOptions;
|
|
4
|
+
/** Tokens always left for the answer when a thinking budget shares the response ceiling. */
|
|
5
|
+
export declare const MIN_ANSWER_TOKENS = 1024;
|
|
6
|
+
export declare function clampReasoning(effort: ThinkingLevel | undefined): Exclude<ThinkingLevel, "xhigh" | "max"> | undefined;
|
|
7
|
+
export declare function adjustMaxTokensForThinking(baseMaxTokens: number | undefined, modelMaxTokens: number, reasoningLevel: ThinkingLevel, customBudgets?: ThinkingBudgets): {
|
|
8
|
+
maxTokens: number;
|
|
9
|
+
thinkingBudget: number;
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=simple-options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simple-options.d.ts","sourceRoot":"","sources":["../../src/api/simple-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,GAAG,EACH,OAAO,EACP,KAAK,EACL,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,aAAa,EACb,MAAM,aAAa,CAAC;AAMrB,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAItG;AAED,wBAAgB,gBAAgB,CAC/B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,mBAAmB,EAC7B,MAAM,CAAC,EAAE,MAAM,GACb,aAAa,CA0Bf;AAED,4FAA4F;AAC5F,eAAO,MAAM,iBAAiB,OAAO,CAAC;AAEtC,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,GAAG,OAAO,CAAC,aAAa,EAAE,OAAO,GAAG,KAAK,CAAC,GAAG,SAAS,CAErH;AAED,wBAAgB,0BAA0B,CAEzC,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,aAAa,EAC7B,aAAa,CAAC,EAAE,eAAe,GAC7B;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAmB/C","sourcesContent":["import type {\n\tApi,\n\tContext,\n\tModel,\n\tSimpleStreamOptions,\n\tStreamOptions,\n\tThinkingBudgets,\n\tThinkingLevel,\n} from \"../types.ts\";\nimport { estimateContextTokens } from \"../utils/estimate.ts\";\n\nconst CONTEXT_SAFETY_TOKENS = 4096;\nconst MIN_MAX_TOKENS = 1;\n\nexport function clampMaxTokensToContext(model: Model<Api>, context: Context, maxTokens: number): number {\n\tif (model.contextWindow <= 0) return Math.max(MIN_MAX_TOKENS, maxTokens);\n\tconst available = model.contextWindow - estimateContextTokens(context).tokens - CONTEXT_SAFETY_TOKENS;\n\treturn Math.min(maxTokens, Math.max(MIN_MAX_TOKENS, available));\n}\n\nexport function buildBaseOptions(\n\tmodel: Model<Api>,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n\tapiKey?: string,\n): StreamOptions {\n\tconst samplingParams =\n\t\tmodel.samplingParams || options?.samplingParams\n\t\t\t? { ...model.samplingParams, ...options?.samplingParams }\n\t\t\t: undefined;\n\treturn {\n\t\ttemperature: options?.temperature,\n\t\tsamplingParams,\n\t\tmaxTokens: clampMaxTokensToContext(model, context, options?.maxTokens ?? model.maxTokens),\n\t\tsignal: options?.signal,\n\t\ttelemetryContext: options?.telemetryContext,\n\t\tapiKey: apiKey || options?.apiKey,\n\t\tfetch: options?.fetch,\n\t\ttransport: options?.transport,\n\t\tcacheRetention: options?.cacheRetention,\n\t\tsessionId: options?.sessionId,\n\t\theaders: options?.headers,\n\t\tonPayload: options?.onPayload,\n\t\tonResponse: options?.onResponse,\n\t\ttimeoutMs: options?.timeoutMs,\n\t\twebsocketConnectTimeoutMs: options?.websocketConnectTimeoutMs,\n\t\tmaxRetries: options?.maxRetries,\n\t\tmaxRetryDelayMs: options?.maxRetryDelayMs,\n\t\tmetadata: options?.metadata,\n\t\tenv: options?.env,\n\t};\n}\n\n/** Tokens always left for the answer when a thinking budget shares the response ceiling. */\nexport const MIN_ANSWER_TOKENS = 1024;\n\nexport function clampReasoning(effort: ThinkingLevel | undefined): Exclude<ThinkingLevel, \"xhigh\" | \"max\"> | undefined {\n\treturn effort === \"xhigh\" || effort === \"max\" ? \"high\" : effort;\n}\n\nexport function adjustMaxTokensForThinking(\n\t// Undefined means no explicit caller cap. Use the model cap and fit thinking inside it.\n\tbaseMaxTokens: number | undefined,\n\tmodelMaxTokens: number,\n\treasoningLevel: ThinkingLevel,\n\tcustomBudgets?: ThinkingBudgets,\n): { maxTokens: number; thinkingBudget: number } {\n\tconst defaultBudgets: ThinkingBudgets = {\n\t\tminimal: 1024,\n\t\tlow: 2048,\n\t\tmedium: 8192,\n\t\thigh: 16384,\n\t};\n\tconst budgets = { ...defaultBudgets, ...customBudgets };\n\n\tconst level = clampReasoning(reasoningLevel)!;\n\tlet thinkingBudget = budgets[level]!;\n\tconst maxTokens =\n\t\tbaseMaxTokens === undefined ? modelMaxTokens : Math.min(baseMaxTokens + thinkingBudget, modelMaxTokens);\n\n\tif (maxTokens <= thinkingBudget) {\n\t\tthinkingBudget = Math.max(0, maxTokens - MIN_ANSWER_TOKENS);\n\t}\n\n\treturn { maxTokens, thinkingBudget };\n}\n"]}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { estimateContextTokens } from "../utils/estimate.js";
|
|
2
|
+
const CONTEXT_SAFETY_TOKENS = 4096;
|
|
3
|
+
const MIN_MAX_TOKENS = 1;
|
|
4
|
+
export function clampMaxTokensToContext(model, context, maxTokens) {
|
|
5
|
+
if (model.contextWindow <= 0)
|
|
6
|
+
return Math.max(MIN_MAX_TOKENS, maxTokens);
|
|
7
|
+
const available = model.contextWindow - estimateContextTokens(context).tokens - CONTEXT_SAFETY_TOKENS;
|
|
8
|
+
return Math.min(maxTokens, Math.max(MIN_MAX_TOKENS, available));
|
|
9
|
+
}
|
|
10
|
+
export function buildBaseOptions(model, context, options, apiKey) {
|
|
11
|
+
const samplingParams = model.samplingParams || options?.samplingParams
|
|
12
|
+
? { ...model.samplingParams, ...options?.samplingParams }
|
|
13
|
+
: undefined;
|
|
14
|
+
return {
|
|
15
|
+
temperature: options?.temperature,
|
|
16
|
+
samplingParams,
|
|
17
|
+
maxTokens: clampMaxTokensToContext(model, context, options?.maxTokens ?? model.maxTokens),
|
|
18
|
+
signal: options?.signal,
|
|
19
|
+
telemetryContext: options?.telemetryContext,
|
|
20
|
+
apiKey: apiKey || options?.apiKey,
|
|
21
|
+
fetch: options?.fetch,
|
|
22
|
+
transport: options?.transport,
|
|
23
|
+
cacheRetention: options?.cacheRetention,
|
|
24
|
+
sessionId: options?.sessionId,
|
|
25
|
+
headers: options?.headers,
|
|
26
|
+
onPayload: options?.onPayload,
|
|
27
|
+
onResponse: options?.onResponse,
|
|
28
|
+
timeoutMs: options?.timeoutMs,
|
|
29
|
+
websocketConnectTimeoutMs: options?.websocketConnectTimeoutMs,
|
|
30
|
+
maxRetries: options?.maxRetries,
|
|
31
|
+
maxRetryDelayMs: options?.maxRetryDelayMs,
|
|
32
|
+
metadata: options?.metadata,
|
|
33
|
+
env: options?.env,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** Tokens always left for the answer when a thinking budget shares the response ceiling. */
|
|
37
|
+
export const MIN_ANSWER_TOKENS = 1024;
|
|
38
|
+
export function clampReasoning(effort) {
|
|
39
|
+
return effort === "xhigh" || effort === "max" ? "high" : effort;
|
|
40
|
+
}
|
|
41
|
+
export function adjustMaxTokensForThinking(
|
|
42
|
+
// Undefined means no explicit caller cap. Use the model cap and fit thinking inside it.
|
|
43
|
+
baseMaxTokens, modelMaxTokens, reasoningLevel, customBudgets) {
|
|
44
|
+
const defaultBudgets = {
|
|
45
|
+
minimal: 1024,
|
|
46
|
+
low: 2048,
|
|
47
|
+
medium: 8192,
|
|
48
|
+
high: 16384,
|
|
49
|
+
};
|
|
50
|
+
const budgets = { ...defaultBudgets, ...customBudgets };
|
|
51
|
+
const level = clampReasoning(reasoningLevel);
|
|
52
|
+
let thinkingBudget = budgets[level];
|
|
53
|
+
const maxTokens = baseMaxTokens === undefined ? modelMaxTokens : Math.min(baseMaxTokens + thinkingBudget, modelMaxTokens);
|
|
54
|
+
if (maxTokens <= thinkingBudget) {
|
|
55
|
+
thinkingBudget = Math.max(0, maxTokens - MIN_ANSWER_TOKENS);
|
|
56
|
+
}
|
|
57
|
+
return { maxTokens, thinkingBudget };
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=simple-options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simple-options.js","sourceRoot":"","sources":["../../src/api/simple-options.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tApi,\n\tContext,\n\tModel,\n\tSimpleStreamOptions,\n\tStreamOptions,\n\tThinkingBudgets,\n\tThinkingLevel,\n} from \"../types.ts\";\nimport { estimateContextTokens } from \"../utils/estimate.ts\";\n\nconst CONTEXT_SAFETY_TOKENS = 4096;\nconst MIN_MAX_TOKENS = 1;\n\nexport function clampMaxTokensToContext(model: Model<Api>, context: Context, maxTokens: number): number {\n\tif (model.contextWindow <= 0) return Math.max(MIN_MAX_TOKENS, maxTokens);\n\tconst available = model.contextWindow - estimateContextTokens(context).tokens - CONTEXT_SAFETY_TOKENS;\n\treturn Math.min(maxTokens, Math.max(MIN_MAX_TOKENS, available));\n}\n\nexport function buildBaseOptions(\n\tmodel: Model<Api>,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n\tapiKey?: string,\n): StreamOptions {\n\tconst samplingParams =\n\t\tmodel.samplingParams || options?.samplingParams\n\t\t\t? { ...model.samplingParams, ...options?.samplingParams }\n\t\t\t: undefined;\n\treturn {\n\t\ttemperature: options?.temperature,\n\t\tsamplingParams,\n\t\tmaxTokens: clampMaxTokensToContext(model, context, options?.maxTokens ?? model.maxTokens),\n\t\tsignal: options?.signal,\n\t\ttelemetryContext: options?.telemetryContext,\n\t\tapiKey: apiKey || options?.apiKey,\n\t\tfetch: options?.fetch,\n\t\ttransport: options?.transport,\n\t\tcacheRetention: options?.cacheRetention,\n\t\tsessionId: options?.sessionId,\n\t\theaders: options?.headers,\n\t\tonPayload: options?.onPayload,\n\t\tonResponse: options?.onResponse,\n\t\ttimeoutMs: options?.timeoutMs,\n\t\twebsocketConnectTimeoutMs: options?.websocketConnectTimeoutMs,\n\t\tmaxRetries: options?.maxRetries,\n\t\tmaxRetryDelayMs: options?.maxRetryDelayMs,\n\t\tmetadata: options?.metadata,\n\t\tenv: options?.env,\n\t};\n}\n\n/** Tokens always left for the answer when a thinking budget shares the response ceiling. */\nexport const MIN_ANSWER_TOKENS = 1024;\n\nexport function clampReasoning(effort: ThinkingLevel | undefined): Exclude<ThinkingLevel, \"xhigh\" | \"max\"> | undefined {\n\treturn effort === \"xhigh\" || effort === \"max\" ? \"high\" : effort;\n}\n\nexport function adjustMaxTokensForThinking(\n\t// Undefined means no explicit caller cap. Use the model cap and fit thinking inside it.\n\tbaseMaxTokens: number | undefined,\n\tmodelMaxTokens: number,\n\treasoningLevel: ThinkingLevel,\n\tcustomBudgets?: ThinkingBudgets,\n): { maxTokens: number; thinkingBudget: number } {\n\tconst defaultBudgets: ThinkingBudgets = {\n\t\tminimal: 1024,\n\t\tlow: 2048,\n\t\tmedium: 8192,\n\t\thigh: 16384,\n\t};\n\tconst budgets = { ...defaultBudgets, ...customBudgets };\n\n\tconst level = clampReasoning(reasoningLevel)!;\n\tlet thinkingBudget = budgets[level]!;\n\tconst maxTokens =\n\t\tbaseMaxTokens === undefined ? modelMaxTokens : Math.min(baseMaxTokens + thinkingBudget, modelMaxTokens);\n\n\tif (maxTokens <= thinkingBudget) {\n\t\tthinkingBudget = Math.max(0, maxTokens - MIN_ANSWER_TOKENS);\n\t}\n\n\treturn { maxTokens, thinkingBudget };\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Api, AssistantMessage, Message, Model } from "../types.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Normalize tool call ID for cross-provider compatibility.
|
|
4
|
+
* OpenAI Responses API generates IDs that are 450+ chars with special characters like `|`.
|
|
5
|
+
* Anthropic APIs require IDs matching ^[a-zA-Z0-9_-]+$ (max 64 chars).
|
|
6
|
+
*/
|
|
7
|
+
export declare function transformMessages<TApi extends Api>(messages: Message[], model: Model<TApi>, normalizeToolCallId?: (id: string, model: Model<TApi>, source: AssistantMessage) => string): Message[];
|
|
8
|
+
//# sourceMappingURL=transform-messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transform-messages.d.ts","sourceRoot":"","sources":["../../src/api/transform-messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,GAAG,EACH,gBAAgB,EAEhB,OAAO,EACP,KAAK,EAIL,MAAM,aAAa,CAAC;AAiDrB;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,SAAS,GAAG,EACjD,QAAQ,EAAE,OAAO,EAAE,EACnB,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,EAClB,mBAAmB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,gBAAgB,KAAK,MAAM,GACxF,OAAO,EAAE,CA2JX","sourcesContent":["import type {\n\tApi,\n\tAssistantMessage,\n\tImageContent,\n\tMessage,\n\tModel,\n\tTextContent,\n\tToolCall,\n\tToolResultMessage,\n} from \"../types.ts\";\n\nconst NON_VISION_USER_IMAGE_PLACEHOLDER = \"(image omitted: model does not support images)\";\nconst NON_VISION_TOOL_IMAGE_PLACEHOLDER = \"(tool image omitted: model does not support images)\";\n\nfunction replaceImagesWithPlaceholder(content: (TextContent | ImageContent)[], placeholder: string): TextContent[] {\n\tconst result: TextContent[] = [];\n\tlet previousWasPlaceholder = false;\n\n\tfor (const block of content) {\n\t\tif (block.type === \"image\") {\n\t\t\tif (!previousWasPlaceholder) {\n\t\t\t\tresult.push({ type: \"text\", text: placeholder });\n\t\t\t}\n\t\t\tpreviousWasPlaceholder = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tresult.push(block);\n\t\tpreviousWasPlaceholder = block.text === placeholder;\n\t}\n\n\treturn result;\n}\n\nfunction downgradeUnsupportedImages<TApi extends Api>(messages: Message[], model: Model<TApi>): Message[] {\n\tif (model.input.includes(\"image\")) {\n\t\treturn messages;\n\t}\n\n\treturn messages.map((msg) => {\n\t\tif (msg.role === \"user\" && Array.isArray(msg.content)) {\n\t\t\treturn {\n\t\t\t\t...msg,\n\t\t\t\tcontent: replaceImagesWithPlaceholder(msg.content, NON_VISION_USER_IMAGE_PLACEHOLDER),\n\t\t\t};\n\t\t}\n\n\t\tif (msg.role === \"toolResult\") {\n\t\t\treturn {\n\t\t\t\t...msg,\n\t\t\t\tcontent: replaceImagesWithPlaceholder(msg.content, NON_VISION_TOOL_IMAGE_PLACEHOLDER),\n\t\t\t};\n\t\t}\n\n\t\treturn msg;\n\t});\n}\n\n/**\n * Normalize tool call ID for cross-provider compatibility.\n * OpenAI Responses API generates IDs that are 450+ chars with special characters like `|`.\n * Anthropic APIs require IDs matching ^[a-zA-Z0-9_-]+$ (max 64 chars).\n */\nexport function transformMessages<TApi extends Api>(\n\tmessages: Message[],\n\tmodel: Model<TApi>,\n\tnormalizeToolCallId?: (id: string, model: Model<TApi>, source: AssistantMessage) => string,\n): Message[] {\n\t// Build a map of original tool call IDs to normalized IDs\n\tconst toolCallIdMap = new Map<string, string>();\n\t// Normalize null/undefined content from untyped callers (custom tools, hand-built\n\t// histories, old session files) so downstream code can rely on the type contract.\n\tconst normalizedMessages = messages.map((msg) => (msg.content == null ? { ...msg, content: [] } : msg));\n\tconst imageAwareMessages = downgradeUnsupportedImages(normalizedMessages, model);\n\n\t// First pass: transform messages (unsupported image downgrade, thinking blocks, tool call ID normalization)\n\tconst transformed = imageAwareMessages.map((msg) => {\n\t\t// User messages pass through unchanged\n\t\tif (msg.role === \"user\") {\n\t\t\treturn msg;\n\t\t}\n\n\t\t// Handle toolResult messages - normalize toolCallId if we have a mapping\n\t\tif (msg.role === \"toolResult\") {\n\t\t\tconst normalizedId = toolCallIdMap.get(msg.toolCallId);\n\t\t\tif (normalizedId && normalizedId !== msg.toolCallId) {\n\t\t\t\treturn { ...msg, toolCallId: normalizedId };\n\t\t\t}\n\t\t\treturn msg;\n\t\t}\n\n\t\t// Assistant messages need transformation check\n\t\tif (msg.role === \"assistant\") {\n\t\t\tconst assistantMsg = msg as AssistantMessage;\n\t\t\tconst isSameModel =\n\t\t\t\tassistantMsg.provider === model.provider &&\n\t\t\t\tassistantMsg.api === model.api &&\n\t\t\t\tassistantMsg.model === model.id;\n\n\t\t\tconst transformedContent = assistantMsg.content.flatMap((block) => {\n\t\t\t\tif (block.type === \"thinking\") {\n\t\t\t\t\t// Redacted thinking is opaque encrypted content, only valid for the same model.\n\t\t\t\t\t// Drop it for cross-model to avoid API errors.\n\t\t\t\t\tif (block.redacted) {\n\t\t\t\t\t\treturn isSameModel ? block : [];\n\t\t\t\t\t}\n\t\t\t\t\t// For same model: keep thinking blocks with signatures (needed for replay)\n\t\t\t\t\t// even if the thinking text is empty (OpenAI encrypted reasoning)\n\t\t\t\t\tif (isSameModel && block.thinkingSignature) return block;\n\t\t\t\t\t// Skip empty thinking blocks, convert others to plain text\n\t\t\t\t\tif (!block.thinking || block.thinking.trim() === \"\") return [];\n\t\t\t\t\tif (isSameModel) return block;\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\ttext: block.thinking,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tif (block.type === \"text\") {\n\t\t\t\t\tif (isSameModel) return block;\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\ttext: block.text,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tif (block.type === \"toolCall\") {\n\t\t\t\t\tconst toolCall = block as ToolCall;\n\t\t\t\t\tlet normalizedToolCall: ToolCall = toolCall;\n\n\t\t\t\t\tif (!isSameModel && toolCall.thoughtSignature) {\n\t\t\t\t\t\tnormalizedToolCall = { ...toolCall };\n\t\t\t\t\t\tdelete (normalizedToolCall as { thoughtSignature?: string }).thoughtSignature;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!isSameModel && normalizeToolCallId) {\n\t\t\t\t\t\tconst normalizedId = normalizeToolCallId(toolCall.id, model, assistantMsg);\n\t\t\t\t\t\tif (normalizedId !== toolCall.id) {\n\t\t\t\t\t\t\ttoolCallIdMap.set(toolCall.id, normalizedId);\n\t\t\t\t\t\t\tnormalizedToolCall = { ...normalizedToolCall, id: normalizedId };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn normalizedToolCall;\n\t\t\t\t}\n\n\t\t\t\treturn block;\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\t...assistantMsg,\n\t\t\t\tcontent: transformedContent,\n\t\t\t};\n\t\t}\n\t\treturn msg;\n\t});\n\n\t// Second pass: insert synthetic empty tool results for orphaned tool calls\n\t// This preserves thinking signatures and satisfies API requirements\n\tconst result: Message[] = [];\n\tlet pendingToolCalls: ToolCall[] = [];\n\tlet existingToolResultIds = new Set<string>();\n\tconst insertSyntheticToolResults = () => {\n\t\tif (pendingToolCalls.length > 0) {\n\t\t\tfor (const tc of pendingToolCalls) {\n\t\t\t\tif (!existingToolResultIds.has(tc.id)) {\n\t\t\t\t\tresult.push({\n\t\t\t\t\t\trole: \"toolResult\",\n\t\t\t\t\t\ttoolCallId: tc.id,\n\t\t\t\t\t\ttoolName: tc.name,\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"No result provided\" }],\n\t\t\t\t\t\tisError: true,\n\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t} as ToolResultMessage);\n\t\t\t\t}\n\t\t\t}\n\t\t\tpendingToolCalls = [];\n\t\t\texistingToolResultIds = new Set();\n\t\t}\n\t};\n\n\tfor (let i = 0; i < transformed.length; i++) {\n\t\tconst msg = transformed[i];\n\n\t\tif (msg.role === \"assistant\") {\n\t\t\t// If we have pending orphaned tool calls from a previous assistant, insert synthetic results now\n\t\t\tinsertSyntheticToolResults();\n\n\t\t\t// Skip errored/aborted assistant messages entirely.\n\t\t\t// These are incomplete turns that shouldn't be replayed:\n\t\t\t// - May have partial content (reasoning without message, incomplete tool calls)\n\t\t\t// - Replaying them can cause API errors (e.g., OpenAI \"reasoning without following item\")\n\t\t\t// - The model should retry from the last valid state\n\t\t\tconst assistantMsg = msg as AssistantMessage;\n\t\t\tif (assistantMsg.stopReason === \"error\" || assistantMsg.stopReason === \"aborted\") {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Track tool calls from this assistant message\n\t\t\tconst toolCalls = assistantMsg.content.filter((b) => b.type === \"toolCall\") as ToolCall[];\n\t\t\tif (toolCalls.length > 0) {\n\t\t\t\tpendingToolCalls = toolCalls;\n\t\t\t\texistingToolResultIds = new Set();\n\t\t\t}\n\n\t\t\tresult.push(msg);\n\t\t} else if (msg.role === \"toolResult\") {\n\t\t\texistingToolResultIds.add(msg.toolCallId);\n\t\t\tresult.push(msg);\n\t\t} else if (msg.role === \"user\") {\n\t\t\t// User message interrupts tool flow - insert synthetic results for orphaned calls\n\t\t\tinsertSyntheticToolResults();\n\t\t\tresult.push(msg);\n\t\t} else {\n\t\t\tresult.push(msg);\n\t\t}\n\t}\n\n\t// If the conversation ends with unresolved tool calls, synthesize results now.\n\tinsertSyntheticToolResults();\n\n\treturn result;\n}\n"]}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
const NON_VISION_USER_IMAGE_PLACEHOLDER = "(image omitted: model does not support images)";
|
|
2
|
+
const NON_VISION_TOOL_IMAGE_PLACEHOLDER = "(tool image omitted: model does not support images)";
|
|
3
|
+
function replaceImagesWithPlaceholder(content, placeholder) {
|
|
4
|
+
const result = [];
|
|
5
|
+
let previousWasPlaceholder = false;
|
|
6
|
+
for (const block of content) {
|
|
7
|
+
if (block.type === "image") {
|
|
8
|
+
if (!previousWasPlaceholder) {
|
|
9
|
+
result.push({ type: "text", text: placeholder });
|
|
10
|
+
}
|
|
11
|
+
previousWasPlaceholder = true;
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
result.push(block);
|
|
15
|
+
previousWasPlaceholder = block.text === placeholder;
|
|
16
|
+
}
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
function downgradeUnsupportedImages(messages, model) {
|
|
20
|
+
if (model.input.includes("image")) {
|
|
21
|
+
return messages;
|
|
22
|
+
}
|
|
23
|
+
return messages.map((msg) => {
|
|
24
|
+
if (msg.role === "user" && Array.isArray(msg.content)) {
|
|
25
|
+
return {
|
|
26
|
+
...msg,
|
|
27
|
+
content: replaceImagesWithPlaceholder(msg.content, NON_VISION_USER_IMAGE_PLACEHOLDER),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
if (msg.role === "toolResult") {
|
|
31
|
+
return {
|
|
32
|
+
...msg,
|
|
33
|
+
content: replaceImagesWithPlaceholder(msg.content, NON_VISION_TOOL_IMAGE_PLACEHOLDER),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return msg;
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Normalize tool call ID for cross-provider compatibility.
|
|
41
|
+
* OpenAI Responses API generates IDs that are 450+ chars with special characters like `|`.
|
|
42
|
+
* Anthropic APIs require IDs matching ^[a-zA-Z0-9_-]+$ (max 64 chars).
|
|
43
|
+
*/
|
|
44
|
+
export function transformMessages(messages, model, normalizeToolCallId) {
|
|
45
|
+
// Build a map of original tool call IDs to normalized IDs
|
|
46
|
+
const toolCallIdMap = new Map();
|
|
47
|
+
// Normalize null/undefined content from untyped callers (custom tools, hand-built
|
|
48
|
+
// histories, old session files) so downstream code can rely on the type contract.
|
|
49
|
+
const normalizedMessages = messages.map((msg) => (msg.content == null ? { ...msg, content: [] } : msg));
|
|
50
|
+
const imageAwareMessages = downgradeUnsupportedImages(normalizedMessages, model);
|
|
51
|
+
// First pass: transform messages (unsupported image downgrade, thinking blocks, tool call ID normalization)
|
|
52
|
+
const transformed = imageAwareMessages.map((msg) => {
|
|
53
|
+
// User messages pass through unchanged
|
|
54
|
+
if (msg.role === "user") {
|
|
55
|
+
return msg;
|
|
56
|
+
}
|
|
57
|
+
// Handle toolResult messages - normalize toolCallId if we have a mapping
|
|
58
|
+
if (msg.role === "toolResult") {
|
|
59
|
+
const normalizedId = toolCallIdMap.get(msg.toolCallId);
|
|
60
|
+
if (normalizedId && normalizedId !== msg.toolCallId) {
|
|
61
|
+
return { ...msg, toolCallId: normalizedId };
|
|
62
|
+
}
|
|
63
|
+
return msg;
|
|
64
|
+
}
|
|
65
|
+
// Assistant messages need transformation check
|
|
66
|
+
if (msg.role === "assistant") {
|
|
67
|
+
const assistantMsg = msg;
|
|
68
|
+
const isSameModel = assistantMsg.provider === model.provider &&
|
|
69
|
+
assistantMsg.api === model.api &&
|
|
70
|
+
assistantMsg.model === model.id;
|
|
71
|
+
const transformedContent = assistantMsg.content.flatMap((block) => {
|
|
72
|
+
if (block.type === "thinking") {
|
|
73
|
+
// Redacted thinking is opaque encrypted content, only valid for the same model.
|
|
74
|
+
// Drop it for cross-model to avoid API errors.
|
|
75
|
+
if (block.redacted) {
|
|
76
|
+
return isSameModel ? block : [];
|
|
77
|
+
}
|
|
78
|
+
// For same model: keep thinking blocks with signatures (needed for replay)
|
|
79
|
+
// even if the thinking text is empty (OpenAI encrypted reasoning)
|
|
80
|
+
if (isSameModel && block.thinkingSignature)
|
|
81
|
+
return block;
|
|
82
|
+
// Skip empty thinking blocks, convert others to plain text
|
|
83
|
+
if (!block.thinking || block.thinking.trim() === "")
|
|
84
|
+
return [];
|
|
85
|
+
if (isSameModel)
|
|
86
|
+
return block;
|
|
87
|
+
return {
|
|
88
|
+
type: "text",
|
|
89
|
+
text: block.thinking,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
if (block.type === "text") {
|
|
93
|
+
if (isSameModel)
|
|
94
|
+
return block;
|
|
95
|
+
return {
|
|
96
|
+
type: "text",
|
|
97
|
+
text: block.text,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
if (block.type === "toolCall") {
|
|
101
|
+
const toolCall = block;
|
|
102
|
+
let normalizedToolCall = toolCall;
|
|
103
|
+
if (!isSameModel && toolCall.thoughtSignature) {
|
|
104
|
+
normalizedToolCall = { ...toolCall };
|
|
105
|
+
delete normalizedToolCall.thoughtSignature;
|
|
106
|
+
}
|
|
107
|
+
if (!isSameModel && normalizeToolCallId) {
|
|
108
|
+
const normalizedId = normalizeToolCallId(toolCall.id, model, assistantMsg);
|
|
109
|
+
if (normalizedId !== toolCall.id) {
|
|
110
|
+
toolCallIdMap.set(toolCall.id, normalizedId);
|
|
111
|
+
normalizedToolCall = { ...normalizedToolCall, id: normalizedId };
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return normalizedToolCall;
|
|
115
|
+
}
|
|
116
|
+
return block;
|
|
117
|
+
});
|
|
118
|
+
return {
|
|
119
|
+
...assistantMsg,
|
|
120
|
+
content: transformedContent,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return msg;
|
|
124
|
+
});
|
|
125
|
+
// Second pass: insert synthetic empty tool results for orphaned tool calls
|
|
126
|
+
// This preserves thinking signatures and satisfies API requirements
|
|
127
|
+
const result = [];
|
|
128
|
+
let pendingToolCalls = [];
|
|
129
|
+
let existingToolResultIds = new Set();
|
|
130
|
+
const insertSyntheticToolResults = () => {
|
|
131
|
+
if (pendingToolCalls.length > 0) {
|
|
132
|
+
for (const tc of pendingToolCalls) {
|
|
133
|
+
if (!existingToolResultIds.has(tc.id)) {
|
|
134
|
+
result.push({
|
|
135
|
+
role: "toolResult",
|
|
136
|
+
toolCallId: tc.id,
|
|
137
|
+
toolName: tc.name,
|
|
138
|
+
content: [{ type: "text", text: "No result provided" }],
|
|
139
|
+
isError: true,
|
|
140
|
+
timestamp: Date.now(),
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
pendingToolCalls = [];
|
|
145
|
+
existingToolResultIds = new Set();
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
for (let i = 0; i < transformed.length; i++) {
|
|
149
|
+
const msg = transformed[i];
|
|
150
|
+
if (msg.role === "assistant") {
|
|
151
|
+
// If we have pending orphaned tool calls from a previous assistant, insert synthetic results now
|
|
152
|
+
insertSyntheticToolResults();
|
|
153
|
+
// Skip errored/aborted assistant messages entirely.
|
|
154
|
+
// These are incomplete turns that shouldn't be replayed:
|
|
155
|
+
// - May have partial content (reasoning without message, incomplete tool calls)
|
|
156
|
+
// - Replaying them can cause API errors (e.g., OpenAI "reasoning without following item")
|
|
157
|
+
// - The model should retry from the last valid state
|
|
158
|
+
const assistantMsg = msg;
|
|
159
|
+
if (assistantMsg.stopReason === "error" || assistantMsg.stopReason === "aborted") {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
// Track tool calls from this assistant message
|
|
163
|
+
const toolCalls = assistantMsg.content.filter((b) => b.type === "toolCall");
|
|
164
|
+
if (toolCalls.length > 0) {
|
|
165
|
+
pendingToolCalls = toolCalls;
|
|
166
|
+
existingToolResultIds = new Set();
|
|
167
|
+
}
|
|
168
|
+
result.push(msg);
|
|
169
|
+
}
|
|
170
|
+
else if (msg.role === "toolResult") {
|
|
171
|
+
existingToolResultIds.add(msg.toolCallId);
|
|
172
|
+
result.push(msg);
|
|
173
|
+
}
|
|
174
|
+
else if (msg.role === "user") {
|
|
175
|
+
// User message interrupts tool flow - insert synthetic results for orphaned calls
|
|
176
|
+
insertSyntheticToolResults();
|
|
177
|
+
result.push(msg);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
result.push(msg);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// If the conversation ends with unresolved tool calls, synthesize results now.
|
|
184
|
+
insertSyntheticToolResults();
|
|
185
|
+
return result;
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=transform-messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transform-messages.js","sourceRoot":"","sources":["../../src/api/transform-messages.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tApi,\n\tAssistantMessage,\n\tImageContent,\n\tMessage,\n\tModel,\n\tTextContent,\n\tToolCall,\n\tToolResultMessage,\n} from \"../types.ts\";\n\nconst NON_VISION_USER_IMAGE_PLACEHOLDER = \"(image omitted: model does not support images)\";\nconst NON_VISION_TOOL_IMAGE_PLACEHOLDER = \"(tool image omitted: model does not support images)\";\n\nfunction replaceImagesWithPlaceholder(content: (TextContent | ImageContent)[], placeholder: string): TextContent[] {\n\tconst result: TextContent[] = [];\n\tlet previousWasPlaceholder = false;\n\n\tfor (const block of content) {\n\t\tif (block.type === \"image\") {\n\t\t\tif (!previousWasPlaceholder) {\n\t\t\t\tresult.push({ type: \"text\", text: placeholder });\n\t\t\t}\n\t\t\tpreviousWasPlaceholder = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tresult.push(block);\n\t\tpreviousWasPlaceholder = block.text === placeholder;\n\t}\n\n\treturn result;\n}\n\nfunction downgradeUnsupportedImages<TApi extends Api>(messages: Message[], model: Model<TApi>): Message[] {\n\tif (model.input.includes(\"image\")) {\n\t\treturn messages;\n\t}\n\n\treturn messages.map((msg) => {\n\t\tif (msg.role === \"user\" && Array.isArray(msg.content)) {\n\t\t\treturn {\n\t\t\t\t...msg,\n\t\t\t\tcontent: replaceImagesWithPlaceholder(msg.content, NON_VISION_USER_IMAGE_PLACEHOLDER),\n\t\t\t};\n\t\t}\n\n\t\tif (msg.role === \"toolResult\") {\n\t\t\treturn {\n\t\t\t\t...msg,\n\t\t\t\tcontent: replaceImagesWithPlaceholder(msg.content, NON_VISION_TOOL_IMAGE_PLACEHOLDER),\n\t\t\t};\n\t\t}\n\n\t\treturn msg;\n\t});\n}\n\n/**\n * Normalize tool call ID for cross-provider compatibility.\n * OpenAI Responses API generates IDs that are 450+ chars with special characters like `|`.\n * Anthropic APIs require IDs matching ^[a-zA-Z0-9_-]+$ (max 64 chars).\n */\nexport function transformMessages<TApi extends Api>(\n\tmessages: Message[],\n\tmodel: Model<TApi>,\n\tnormalizeToolCallId?: (id: string, model: Model<TApi>, source: AssistantMessage) => string,\n): Message[] {\n\t// Build a map of original tool call IDs to normalized IDs\n\tconst toolCallIdMap = new Map<string, string>();\n\t// Normalize null/undefined content from untyped callers (custom tools, hand-built\n\t// histories, old session files) so downstream code can rely on the type contract.\n\tconst normalizedMessages = messages.map((msg) => (msg.content == null ? { ...msg, content: [] } : msg));\n\tconst imageAwareMessages = downgradeUnsupportedImages(normalizedMessages, model);\n\n\t// First pass: transform messages (unsupported image downgrade, thinking blocks, tool call ID normalization)\n\tconst transformed = imageAwareMessages.map((msg) => {\n\t\t// User messages pass through unchanged\n\t\tif (msg.role === \"user\") {\n\t\t\treturn msg;\n\t\t}\n\n\t\t// Handle toolResult messages - normalize toolCallId if we have a mapping\n\t\tif (msg.role === \"toolResult\") {\n\t\t\tconst normalizedId = toolCallIdMap.get(msg.toolCallId);\n\t\t\tif (normalizedId && normalizedId !== msg.toolCallId) {\n\t\t\t\treturn { ...msg, toolCallId: normalizedId };\n\t\t\t}\n\t\t\treturn msg;\n\t\t}\n\n\t\t// Assistant messages need transformation check\n\t\tif (msg.role === \"assistant\") {\n\t\t\tconst assistantMsg = msg as AssistantMessage;\n\t\t\tconst isSameModel =\n\t\t\t\tassistantMsg.provider === model.provider &&\n\t\t\t\tassistantMsg.api === model.api &&\n\t\t\t\tassistantMsg.model === model.id;\n\n\t\t\tconst transformedContent = assistantMsg.content.flatMap((block) => {\n\t\t\t\tif (block.type === \"thinking\") {\n\t\t\t\t\t// Redacted thinking is opaque encrypted content, only valid for the same model.\n\t\t\t\t\t// Drop it for cross-model to avoid API errors.\n\t\t\t\t\tif (block.redacted) {\n\t\t\t\t\t\treturn isSameModel ? block : [];\n\t\t\t\t\t}\n\t\t\t\t\t// For same model: keep thinking blocks with signatures (needed for replay)\n\t\t\t\t\t// even if the thinking text is empty (OpenAI encrypted reasoning)\n\t\t\t\t\tif (isSameModel && block.thinkingSignature) return block;\n\t\t\t\t\t// Skip empty thinking blocks, convert others to plain text\n\t\t\t\t\tif (!block.thinking || block.thinking.trim() === \"\") return [];\n\t\t\t\t\tif (isSameModel) return block;\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\ttext: block.thinking,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tif (block.type === \"text\") {\n\t\t\t\t\tif (isSameModel) return block;\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\t\ttext: block.text,\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\tif (block.type === \"toolCall\") {\n\t\t\t\t\tconst toolCall = block as ToolCall;\n\t\t\t\t\tlet normalizedToolCall: ToolCall = toolCall;\n\n\t\t\t\t\tif (!isSameModel && toolCall.thoughtSignature) {\n\t\t\t\t\t\tnormalizedToolCall = { ...toolCall };\n\t\t\t\t\t\tdelete (normalizedToolCall as { thoughtSignature?: string }).thoughtSignature;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!isSameModel && normalizeToolCallId) {\n\t\t\t\t\t\tconst normalizedId = normalizeToolCallId(toolCall.id, model, assistantMsg);\n\t\t\t\t\t\tif (normalizedId !== toolCall.id) {\n\t\t\t\t\t\t\ttoolCallIdMap.set(toolCall.id, normalizedId);\n\t\t\t\t\t\t\tnormalizedToolCall = { ...normalizedToolCall, id: normalizedId };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn normalizedToolCall;\n\t\t\t\t}\n\n\t\t\t\treturn block;\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\t...assistantMsg,\n\t\t\t\tcontent: transformedContent,\n\t\t\t};\n\t\t}\n\t\treturn msg;\n\t});\n\n\t// Second pass: insert synthetic empty tool results for orphaned tool calls\n\t// This preserves thinking signatures and satisfies API requirements\n\tconst result: Message[] = [];\n\tlet pendingToolCalls: ToolCall[] = [];\n\tlet existingToolResultIds = new Set<string>();\n\tconst insertSyntheticToolResults = () => {\n\t\tif (pendingToolCalls.length > 0) {\n\t\t\tfor (const tc of pendingToolCalls) {\n\t\t\t\tif (!existingToolResultIds.has(tc.id)) {\n\t\t\t\t\tresult.push({\n\t\t\t\t\t\trole: \"toolResult\",\n\t\t\t\t\t\ttoolCallId: tc.id,\n\t\t\t\t\t\ttoolName: tc.name,\n\t\t\t\t\t\tcontent: [{ type: \"text\", text: \"No result provided\" }],\n\t\t\t\t\t\tisError: true,\n\t\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t\t} as ToolResultMessage);\n\t\t\t\t}\n\t\t\t}\n\t\t\tpendingToolCalls = [];\n\t\t\texistingToolResultIds = new Set();\n\t\t}\n\t};\n\n\tfor (let i = 0; i < transformed.length; i++) {\n\t\tconst msg = transformed[i];\n\n\t\tif (msg.role === \"assistant\") {\n\t\t\t// If we have pending orphaned tool calls from a previous assistant, insert synthetic results now\n\t\t\tinsertSyntheticToolResults();\n\n\t\t\t// Skip errored/aborted assistant messages entirely.\n\t\t\t// These are incomplete turns that shouldn't be replayed:\n\t\t\t// - May have partial content (reasoning without message, incomplete tool calls)\n\t\t\t// - Replaying them can cause API errors (e.g., OpenAI \"reasoning without following item\")\n\t\t\t// - The model should retry from the last valid state\n\t\t\tconst assistantMsg = msg as AssistantMessage;\n\t\t\tif (assistantMsg.stopReason === \"error\" || assistantMsg.stopReason === \"aborted\") {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Track tool calls from this assistant message\n\t\t\tconst toolCalls = assistantMsg.content.filter((b) => b.type === \"toolCall\") as ToolCall[];\n\t\t\tif (toolCalls.length > 0) {\n\t\t\t\tpendingToolCalls = toolCalls;\n\t\t\t\texistingToolResultIds = new Set();\n\t\t\t}\n\n\t\t\tresult.push(msg);\n\t\t} else if (msg.role === \"toolResult\") {\n\t\t\texistingToolResultIds.add(msg.toolCallId);\n\t\t\tresult.push(msg);\n\t\t} else if (msg.role === \"user\") {\n\t\t\t// User message interrupts tool flow - insert synthetic results for orphaned calls\n\t\t\tinsertSyntheticToolResults();\n\t\t\tresult.push(msg);\n\t\t} else {\n\t\t\tresult.push(msg);\n\t\t}\n\t}\n\n\t// If the conversation ends with unresolved tool calls, synthesize results now.\n\tinsertSyntheticToolResults();\n\n\treturn result;\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AuthContext } from "./types.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Default auth context: env vars from `process.env` (undefined in browsers),
|
|
4
|
+
* file existence via node:fs (always false in browsers).
|
|
5
|
+
*/
|
|
6
|
+
export declare function defaultProviderAuthContext(): AuthContext;
|
|
7
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/auth/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAkB9C;;;GAGG;AACH,wBAAgB,0BAA0B,IAAI,WAAW,CAsBxD","sourcesContent":["import type { AuthContext } from \"./types.ts\";\n\ninterface NodeFsModule {\n\taccess(path: string): Promise<void>;\n}\n\ninterface NodeOsModule {\n\thomedir(): string;\n}\n\n// Variable specifier so browser bundlers do not try to resolve node builtins.\nconst importNodeModule = (specifier: string): Promise<unknown> => import(specifier);\n\nfunction getProcessEnv(): Record<string, string | undefined> | undefined {\n\tconst proc = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process;\n\treturn proc?.env;\n}\n\n/**\n * Default auth context: env vars from `process.env` (undefined in browsers),\n * file existence via node:fs (always false in browsers).\n */\nexport function defaultProviderAuthContext(): AuthContext {\n\treturn {\n\t\tasync env(name: string): Promise<string | undefined> {\n\t\t\tconst value = getProcessEnv()?.[name];\n\t\t\treturn typeof value === \"string\" && value.trim().length > 0 ? value : undefined;\n\t\t},\n\n\t\tasync fileExists(path: string): Promise<boolean> {\n\t\t\ttry {\n\t\t\t\tconst fs = (await importNodeModule(\"node:fs/promises\")) as NodeFsModule;\n\t\t\t\tlet resolved = path;\n\t\t\t\tif (resolved.startsWith(\"~\")) {\n\t\t\t\t\tconst os = (await importNodeModule(\"node:os\")) as NodeOsModule;\n\t\t\t\t\tresolved = os.homedir() + resolved.slice(1);\n\t\t\t\t}\n\t\t\t\tawait fs.access(resolved);\n\t\t\t\treturn true;\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t};\n}\n"]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
9
|
+
// Variable specifier so browser bundlers do not try to resolve node builtins.
|
|
10
|
+
const importNodeModule = (specifier) => import(__rewriteRelativeImportExtension(specifier));
|
|
11
|
+
function getProcessEnv() {
|
|
12
|
+
const proc = globalThis.process;
|
|
13
|
+
return proc?.env;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Default auth context: env vars from `process.env` (undefined in browsers),
|
|
17
|
+
* file existence via node:fs (always false in browsers).
|
|
18
|
+
*/
|
|
19
|
+
export function defaultProviderAuthContext() {
|
|
20
|
+
return {
|
|
21
|
+
async env(name) {
|
|
22
|
+
const value = getProcessEnv()?.[name];
|
|
23
|
+
return typeof value === "string" && value.trim().length > 0 ? value : undefined;
|
|
24
|
+
},
|
|
25
|
+
async fileExists(path) {
|
|
26
|
+
try {
|
|
27
|
+
const fs = (await importNodeModule("node:fs/promises"));
|
|
28
|
+
let resolved = path;
|
|
29
|
+
if (resolved.startsWith("~")) {
|
|
30
|
+
const os = (await importNodeModule("node:os"));
|
|
31
|
+
resolved = os.homedir() + resolved.slice(1);
|
|
32
|
+
}
|
|
33
|
+
await fs.access(resolved);
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/auth/context.ts"],"names":[],"mappings":";;;;;;;;AAUA,8EAA8E;AAC9E,MAAM,gBAAgB,GAAG,CAAC,SAAiB,EAAoB,EAAE,CAAC,MAAM,kCAAC,SAAS,EAAC,CAAC;AAEpF,SAAS,aAAa,GAAmD;IACxE,MAAM,IAAI,GAAI,UAAyE,CAAC,OAAO,CAAC;IAChG,OAAO,IAAI,EAAE,GAAG,CAAC;AAAA,CACjB;AAED;;;GAGG;AACH,MAAM,UAAU,0BAA0B,GAAgB;IACzD,OAAO;QACN,KAAK,CAAC,GAAG,CAAC,IAAY,EAA+B;YACpD,MAAM,KAAK,GAAG,aAAa,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;YACtC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QAAA,CAChF;QAED,KAAK,CAAC,UAAU,CAAC,IAAY,EAAoB;YAChD,IAAI,CAAC;gBACJ,MAAM,EAAE,GAAG,CAAC,MAAM,gBAAgB,CAAC,kBAAkB,CAAC,CAAiB,CAAC;gBACxE,IAAI,QAAQ,GAAG,IAAI,CAAC;gBACpB,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC9B,MAAM,EAAE,GAAG,CAAC,MAAM,gBAAgB,CAAC,SAAS,CAAC,CAAiB,CAAC;oBAC/D,QAAQ,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC7C,CAAC;gBACD,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAC1B,OAAO,IAAI,CAAC;YACb,CAAC;YAAC,MAAM,CAAC;gBACR,OAAO,KAAK,CAAC;YACd,CAAC;QAAA,CACD;KACD,CAAC;AAAA,CACF","sourcesContent":["import type { AuthContext } from \"./types.ts\";\n\ninterface NodeFsModule {\n\taccess(path: string): Promise<void>;\n}\n\ninterface NodeOsModule {\n\thomedir(): string;\n}\n\n// Variable specifier so browser bundlers do not try to resolve node builtins.\nconst importNodeModule = (specifier: string): Promise<unknown> => import(specifier);\n\nfunction getProcessEnv(): Record<string, string | undefined> | undefined {\n\tconst proc = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process;\n\treturn proc?.env;\n}\n\n/**\n * Default auth context: env vars from `process.env` (undefined in browsers),\n * file existence via node:fs (always false in browsers).\n */\nexport function defaultProviderAuthContext(): AuthContext {\n\treturn {\n\t\tasync env(name: string): Promise<string | undefined> {\n\t\t\tconst value = getProcessEnv()?.[name];\n\t\t\treturn typeof value === \"string\" && value.trim().length > 0 ? value : undefined;\n\t\t},\n\n\t\tasync fileExists(path: string): Promise<boolean> {\n\t\t\ttry {\n\t\t\t\tconst fs = (await importNodeModule(\"node:fs/promises\")) as NodeFsModule;\n\t\t\t\tlet resolved = path;\n\t\t\t\tif (resolved.startsWith(\"~\")) {\n\t\t\t\t\tconst os = (await importNodeModule(\"node:os\")) as NodeOsModule;\n\t\t\t\t\tresolved = os.homedir() + resolved.slice(1);\n\t\t\t\t}\n\t\t\t\tawait fs.access(resolved);\n\t\t\t\treturn true;\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t};\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { AuthOperationOptions, Credential, CredentialInfo, CredentialStore } from "./types.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Default in-memory credential store. Apps inject persistent stores.
|
|
4
|
+
* Keyed by `Provider.id`, one credential per provider; see `CredentialStore`.
|
|
5
|
+
* Writes are serialized per provider through a promise chain.
|
|
6
|
+
*/
|
|
7
|
+
export declare class InMemoryCredentialStore implements CredentialStore {
|
|
8
|
+
private credentials;
|
|
9
|
+
private chains;
|
|
10
|
+
/** Serialize tasks per provider id without releasing the chain before active work settles. */
|
|
11
|
+
private enqueue;
|
|
12
|
+
read(providerId: string, options?: AuthOperationOptions): Promise<Credential | undefined>;
|
|
13
|
+
list(options?: AuthOperationOptions): Promise<readonly CredentialInfo[]>;
|
|
14
|
+
modify(providerId: string, fn: (current: Credential | undefined) => Promise<Credential | undefined>, options?: AuthOperationOptions): Promise<Credential | undefined>;
|
|
15
|
+
delete(providerId: string, options?: AuthOperationOptions): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=credential-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-store.d.ts","sourceRoot":"","sources":["../../src/auth/credential-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEpG;;;;GAIG;AACH,qBAAa,uBAAwB,YAAW,eAAe;IAC9D,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,MAAM,CAAuC;IAErD,8FAA8F;IAC9F,OAAO,CAAC,OAAO;IAgBT,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAG9F;IAEK,IAAI,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC,CAG7E;IAED,MAAM,CACL,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,CAAC,OAAO,EAAE,UAAU,GAAG,SAAS,KAAK,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,EACxE,OAAO,CAAC,EAAE,oBAAoB,GAC5B,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAYjC;IAED,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAQxE;CACD","sourcesContent":["import { operationSignal, raceWithAbortSignal } from \"../utils/abort.ts\";\nimport type { AuthOperationOptions, Credential, CredentialInfo, CredentialStore } from \"./types.ts\";\n\n/**\n * Default in-memory credential store. Apps inject persistent stores.\n * Keyed by `Provider.id`, one credential per provider; see `CredentialStore`.\n * Writes are serialized per provider through a promise chain.\n */\nexport class InMemoryCredentialStore implements CredentialStore {\n\tprivate credentials = new Map<string, Credential>();\n\tprivate chains = new Map<string, Promise<unknown>>();\n\n\t/** Serialize tasks per provider id without releasing the chain before active work settles. */\n\tprivate enqueue<T>(providerId: string, task: () => Promise<T>, options?: AuthOperationOptions): Promise<T> {\n\t\tconst signal = operationSignal(options?.signal);\n\t\tconst previous = this.chains.get(providerId) ?? Promise.resolve();\n\t\tconst queued = (async () => {\n\t\t\tawait previous.catch(() => {});\n\t\t\tsignal.throwIfAborted();\n\t\t\treturn task();\n\t\t})();\n\t\tconst tail = queued.catch(() => {});\n\t\tthis.chains.set(providerId, tail);\n\t\tvoid tail.then(() => {\n\t\t\tif (this.chains.get(providerId) === tail) this.chains.delete(providerId);\n\t\t});\n\t\treturn raceWithAbortSignal(queued, signal);\n\t}\n\n\tasync read(providerId: string, options?: AuthOperationOptions): Promise<Credential | undefined> {\n\t\toptions?.signal?.throwIfAborted();\n\t\treturn this.credentials.get(providerId);\n\t}\n\n\tasync list(options?: AuthOperationOptions): Promise<readonly CredentialInfo[]> {\n\t\toptions?.signal?.throwIfAborted();\n\t\treturn [...this.credentials].map(([providerId, credential]) => ({ providerId, type: credential.type }));\n\t}\n\n\tmodify(\n\t\tproviderId: string,\n\t\tfn: (current: Credential | undefined) => Promise<Credential | undefined>,\n\t\toptions?: AuthOperationOptions,\n\t): Promise<Credential | undefined> {\n\t\treturn this.enqueue(\n\t\t\tproviderId,\n\t\t\tasync () => {\n\t\t\t\tconst current = this.credentials.get(providerId);\n\t\t\t\tconst next = await fn(current);\n\t\t\t\toptions?.signal?.throwIfAborted();\n\t\t\t\tif (next !== undefined) this.credentials.set(providerId, next);\n\t\t\t\treturn next ?? current;\n\t\t\t},\n\t\t\toptions,\n\t\t);\n\t}\n\n\tdelete(providerId: string, options?: AuthOperationOptions): Promise<void> {\n\t\treturn this.enqueue(\n\t\t\tproviderId,\n\t\t\tasync () => {\n\t\t\t\tthis.credentials.delete(providerId);\n\t\t\t},\n\t\t\toptions,\n\t\t);\n\t}\n}\n"]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { operationSignal, raceWithAbortSignal } from "../utils/abort.js";
|
|
2
|
+
/**
|
|
3
|
+
* Default in-memory credential store. Apps inject persistent stores.
|
|
4
|
+
* Keyed by `Provider.id`, one credential per provider; see `CredentialStore`.
|
|
5
|
+
* Writes are serialized per provider through a promise chain.
|
|
6
|
+
*/
|
|
7
|
+
export class InMemoryCredentialStore {
|
|
8
|
+
credentials = new Map();
|
|
9
|
+
chains = new Map();
|
|
10
|
+
/** Serialize tasks per provider id without releasing the chain before active work settles. */
|
|
11
|
+
enqueue(providerId, task, options) {
|
|
12
|
+
const signal = operationSignal(options?.signal);
|
|
13
|
+
const previous = this.chains.get(providerId) ?? Promise.resolve();
|
|
14
|
+
const queued = (async () => {
|
|
15
|
+
await previous.catch(() => { });
|
|
16
|
+
signal.throwIfAborted();
|
|
17
|
+
return task();
|
|
18
|
+
})();
|
|
19
|
+
const tail = queued.catch(() => { });
|
|
20
|
+
this.chains.set(providerId, tail);
|
|
21
|
+
void tail.then(() => {
|
|
22
|
+
if (this.chains.get(providerId) === tail)
|
|
23
|
+
this.chains.delete(providerId);
|
|
24
|
+
});
|
|
25
|
+
return raceWithAbortSignal(queued, signal);
|
|
26
|
+
}
|
|
27
|
+
async read(providerId, options) {
|
|
28
|
+
options?.signal?.throwIfAborted();
|
|
29
|
+
return this.credentials.get(providerId);
|
|
30
|
+
}
|
|
31
|
+
async list(options) {
|
|
32
|
+
options?.signal?.throwIfAborted();
|
|
33
|
+
return [...this.credentials].map(([providerId, credential]) => ({ providerId, type: credential.type }));
|
|
34
|
+
}
|
|
35
|
+
modify(providerId, fn, options) {
|
|
36
|
+
return this.enqueue(providerId, async () => {
|
|
37
|
+
const current = this.credentials.get(providerId);
|
|
38
|
+
const next = await fn(current);
|
|
39
|
+
options?.signal?.throwIfAborted();
|
|
40
|
+
if (next !== undefined)
|
|
41
|
+
this.credentials.set(providerId, next);
|
|
42
|
+
return next ?? current;
|
|
43
|
+
}, options);
|
|
44
|
+
}
|
|
45
|
+
delete(providerId, options) {
|
|
46
|
+
return this.enqueue(providerId, async () => {
|
|
47
|
+
this.credentials.delete(providerId);
|
|
48
|
+
}, options);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=credential-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-store.js","sourceRoot":"","sources":["../../src/auth/credential-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAGzE;;;;GAIG;AACH,MAAM,OAAO,uBAAuB;IAC3B,WAAW,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC5C,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;IAErD,8FAA8F;IACtF,OAAO,CAAI,UAAkB,EAAE,IAAsB,EAAE,OAA8B,EAAc;QAC1G,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QAClE,MAAM,MAAM,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;YAC3B,MAAM,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,CAAC,cAAc,EAAE,CAAC;YACxB,OAAO,IAAI,EAAE,CAAC;QAAA,CACd,CAAC,EAAE,CAAC;QACL,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAC,CAAC,CAAC,CAAC;QACpC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAClC,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACpB,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,IAAI;gBAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAAA,CACzE,CAAC,CAAC;QACH,OAAO,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAA,CAC3C;IAED,KAAK,CAAC,IAAI,CAAC,UAAkB,EAAE,OAA8B,EAAmC;QAC/F,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAAA,CACxC;IAED,KAAK,CAAC,IAAI,CAAC,OAA8B,EAAsC;QAC9E,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAAA,CACxG;IAED,MAAM,CACL,UAAkB,EAClB,EAAwE,EACxE,OAA8B,EACI;QAClC,OAAO,IAAI,CAAC,OAAO,CAClB,UAAU,EACV,KAAK,IAAI,EAAE,CAAC;YACX,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACjD,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC;YAC/B,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;YAClC,IAAI,IAAI,KAAK,SAAS;gBAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YAC/D,OAAO,IAAI,IAAI,OAAO,CAAC;QAAA,CACvB,EACD,OAAO,CACP,CAAC;IAAA,CACF;IAED,MAAM,CAAC,UAAkB,EAAE,OAA8B,EAAiB;QACzE,OAAO,IAAI,CAAC,OAAO,CAClB,UAAU,EACV,KAAK,IAAI,EAAE,CAAC;YACX,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAAA,CACpC,EACD,OAAO,CACP,CAAC;IAAA,CACF;CACD","sourcesContent":["import { operationSignal, raceWithAbortSignal } from \"../utils/abort.ts\";\nimport type { AuthOperationOptions, Credential, CredentialInfo, CredentialStore } from \"./types.ts\";\n\n/**\n * Default in-memory credential store. Apps inject persistent stores.\n * Keyed by `Provider.id`, one credential per provider; see `CredentialStore`.\n * Writes are serialized per provider through a promise chain.\n */\nexport class InMemoryCredentialStore implements CredentialStore {\n\tprivate credentials = new Map<string, Credential>();\n\tprivate chains = new Map<string, Promise<unknown>>();\n\n\t/** Serialize tasks per provider id without releasing the chain before active work settles. */\n\tprivate enqueue<T>(providerId: string, task: () => Promise<T>, options?: AuthOperationOptions): Promise<T> {\n\t\tconst signal = operationSignal(options?.signal);\n\t\tconst previous = this.chains.get(providerId) ?? Promise.resolve();\n\t\tconst queued = (async () => {\n\t\t\tawait previous.catch(() => {});\n\t\t\tsignal.throwIfAborted();\n\t\t\treturn task();\n\t\t})();\n\t\tconst tail = queued.catch(() => {});\n\t\tthis.chains.set(providerId, tail);\n\t\tvoid tail.then(() => {\n\t\t\tif (this.chains.get(providerId) === tail) this.chains.delete(providerId);\n\t\t});\n\t\treturn raceWithAbortSignal(queued, signal);\n\t}\n\n\tasync read(providerId: string, options?: AuthOperationOptions): Promise<Credential | undefined> {\n\t\toptions?.signal?.throwIfAborted();\n\t\treturn this.credentials.get(providerId);\n\t}\n\n\tasync list(options?: AuthOperationOptions): Promise<readonly CredentialInfo[]> {\n\t\toptions?.signal?.throwIfAborted();\n\t\treturn [...this.credentials].map(([providerId, credential]) => ({ providerId, type: credential.type }));\n\t}\n\n\tmodify(\n\t\tproviderId: string,\n\t\tfn: (current: Credential | undefined) => Promise<Credential | undefined>,\n\t\toptions?: AuthOperationOptions,\n\t): Promise<Credential | undefined> {\n\t\treturn this.enqueue(\n\t\t\tproviderId,\n\t\t\tasync () => {\n\t\t\t\tconst current = this.credentials.get(providerId);\n\t\t\t\tconst next = await fn(current);\n\t\t\t\toptions?.signal?.throwIfAborted();\n\t\t\t\tif (next !== undefined) this.credentials.set(providerId, next);\n\t\t\t\treturn next ?? current;\n\t\t\t},\n\t\t\toptions,\n\t\t);\n\t}\n\n\tdelete(providerId: string, options?: AuthOperationOptions): Promise<void> {\n\t\treturn this.enqueue(\n\t\t\tproviderId,\n\t\t\tasync () => {\n\t\t\t\tthis.credentials.delete(providerId);\n\t\t\t},\n\t\t\toptions,\n\t\t);\n\t}\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ApiKeyAuth, OAuthAuth } from "./types.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Standard api-key auth: a stored credential key wins, otherwise the first
|
|
4
|
+
* set env var resolves. Includes a `login` that prompts for the key.
|
|
5
|
+
* Providers with non-standard resolution (provider env, ambient files, IAM)
|
|
6
|
+
* write their own `ApiKeyAuth`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function envApiKeyAuth(name: string, envVars: readonly string[]): ApiKeyAuth;
|
|
9
|
+
/**
|
|
10
|
+
* Wraps a dynamically imported `OAuthAuth` so provider definitions can
|
|
11
|
+
* advertise OAuth without importing the implementation. The flow loads on
|
|
12
|
+
* first `login`/`refresh`/`toAuth` call; callers keep Node-only flow code out
|
|
13
|
+
* of bundles by loading through a bundler-opaque dynamic import (variable
|
|
14
|
+
* specifier, see the bedrock lazy wrapper).
|
|
15
|
+
*/
|
|
16
|
+
export declare function lazyOAuth(input: {
|
|
17
|
+
name: string;
|
|
18
|
+
isSubscription?: boolean;
|
|
19
|
+
loginLabel?: string;
|
|
20
|
+
load: () => Promise<OAuthAuth>;
|
|
21
|
+
}): OAuthAuth;
|
|
22
|
+
//# sourceMappingURL=helpers.d.ts.map
|