@linxiraos/pi-ai 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5066 -0
- package/README.md +1195 -0
- package/dist/types/api-registry.d.ts +30 -0
- package/dist/types/auth/sqlite-credential-store.d.ts +117 -0
- package/dist/types/auth-broker/client.d.ts +93 -0
- package/dist/types/auth-broker/discover.d.ts +39 -0
- package/dist/types/auth-broker/index.d.ts +7 -0
- package/dist/types/auth-broker/refresher.d.ts +25 -0
- package/dist/types/auth-broker/remote-store.d.ts +136 -0
- package/dist/types/auth-broker/server.d.ts +48 -0
- package/dist/types/auth-broker/snapshot-cache.d.ts +17 -0
- package/dist/types/auth-broker/types.d.ts +152 -0
- package/dist/types/auth-broker/wire-schema-resource.d.ts +53 -0
- package/dist/types/auth-broker/wire-schemas.d.ts +5 -0
- package/dist/types/auth-gateway/http.d.ts +56 -0
- package/dist/types/auth-gateway/index.d.ts +3 -0
- package/dist/types/auth-gateway/server.d.ts +36 -0
- package/dist/types/auth-gateway/types.d.ts +127 -0
- package/dist/types/auth-retry.d.ts +150 -0
- package/dist/types/auth-storage.d.ts +1258 -0
- package/dist/types/dialect/anthropic.d.ts +15 -0
- package/dist/types/dialect/catalog.d.ts +3 -0
- package/dist/types/dialect/coercion.d.ts +23 -0
- package/dist/types/dialect/deepseek.d.ts +14 -0
- package/dist/types/dialect/demotion.d.ts +30 -0
- package/dist/types/dialect/examples.d.ts +18 -0
- package/dist/types/dialect/factory.d.ts +3 -0
- package/dist/types/dialect/fenced-thinking.d.ts +53 -0
- package/dist/types/dialect/gemini.d.ts +17 -0
- package/dist/types/dialect/gemma.d.ts +15 -0
- package/dist/types/dialect/glm.d.ts +9 -0
- package/dist/types/dialect/harmony.d.ts +8 -0
- package/dist/types/dialect/hermes.d.ts +9 -0
- package/dist/types/dialect/history.d.ts +3 -0
- package/dist/types/dialect/index.d.ts +11 -0
- package/dist/types/dialect/inventory.d.ts +9 -0
- package/dist/types/dialect/kimi.d.ts +14 -0
- package/dist/types/dialect/minimax.d.ts +3 -0
- package/dist/types/dialect/owned-stream.d.ts +4 -0
- package/dist/types/dialect/qwen3.d.ts +9 -0
- package/dist/types/dialect/rendering.d.ts +54 -0
- package/dist/types/dialect/thinking.d.ts +6 -0
- package/dist/types/dialect/types.d.ts +68 -0
- package/dist/types/dialect/xml.d.ts +9 -0
- package/dist/types/error/abort.d.ts +14 -0
- package/dist/types/error/auth-classify.d.ts +20 -0
- package/dist/types/error/auth.d.ts +27 -0
- package/dist/types/error/aws.d.ts +27 -0
- package/dist/types/error/classes.d.ts +106 -0
- package/dist/types/error/finalize.d.ts +39 -0
- package/dist/types/error/flags.d.ts +94 -0
- package/dist/types/error/format.d.ts +20 -0
- package/dist/types/error/gateway.d.ts +20 -0
- package/dist/types/error/index.d.ts +14 -0
- package/dist/types/error/oauth.d.ts +43 -0
- package/dist/types/error/provider.d.ts +42 -0
- package/dist/types/error/rate-limit.d.ts +80 -0
- package/dist/types/error/retryable.d.ts +27 -0
- package/dist/types/error/validation.d.ts +32 -0
- package/dist/types/index.d.ts +51 -0
- package/dist/types/provider-details.d.ts +24 -0
- package/dist/types/providers/amazon-bedrock.d.ts +39 -0
- package/dist/types/providers/anthropic-client.d.ts +106 -0
- package/dist/types/providers/anthropic-messages-server-schema.d.ts +937 -0
- package/dist/types/providers/anthropic-messages-server.d.ts +17 -0
- package/dist/types/providers/anthropic-wire.d.ts +345 -0
- package/dist/types/providers/anthropic.d.ts +261 -0
- package/dist/types/providers/aws-credentials.d.ts +48 -0
- package/dist/types/providers/aws-eventstream.d.ts +39 -0
- package/dist/types/providers/aws-sigv4.d.ts +55 -0
- package/dist/types/providers/azure-openai-responses.d.ts +16 -0
- package/dist/types/providers/bedrock-mantle.d.ts +13 -0
- package/dist/types/providers/claude-code-fingerprint.d.ts +19 -0
- package/dist/types/providers/cowork-fetch.d.ts +3 -0
- package/dist/types/providers/cursor/exec-modern.d.ts +98 -0
- package/dist/types/providers/cursor-pi-args.d.ts +105 -0
- package/dist/types/providers/cursor.d.ts +221 -0
- package/dist/types/providers/devin.d.ts +12 -0
- package/dist/types/providers/error-message.d.ts +25 -0
- package/dist/types/providers/github-copilot-headers.d.ts +40 -0
- package/dist/types/providers/gitlab-duo-workflow.d.ts +254 -0
- package/dist/types/providers/gitlab-duo.d.ts +27 -0
- package/dist/types/providers/google-auth.d.ts +24 -0
- package/dist/types/providers/google-gemini-cli.d.ts +120 -0
- package/dist/types/providers/google-shared.d.ts +203 -0
- package/dist/types/providers/google-types.d.ts +155 -0
- package/dist/types/providers/google-vertex.d.ts +7 -0
- package/dist/types/providers/google.d.ts +4 -0
- package/dist/types/providers/grammar.d.ts +1 -0
- package/dist/types/providers/kimi.d.ts +27 -0
- package/dist/types/providers/mock.d.ts +179 -0
- package/dist/types/providers/ollama.d.ts +8 -0
- package/dist/types/providers/openai-anthropic-shim.d.ts +35 -0
- package/dist/types/providers/openai-chat-server-schema.d.ts +1311 -0
- package/dist/types/providers/openai-chat-server.d.ts +16 -0
- package/dist/types/providers/openai-chat-wire.d.ts +669 -0
- package/dist/types/providers/openai-codex/request-transformer.d.ts +109 -0
- package/dist/types/providers/openai-codex/response-handler.d.ts +26 -0
- package/dist/types/providers/openai-codex-responses.d.ts +238 -0
- package/dist/types/providers/openai-completions.d.ts +48 -0
- package/dist/types/providers/openai-reasoning-fallback.d.ts +25 -0
- package/dist/types/providers/openai-responses-server-schema.d.ts +1314 -0
- package/dist/types/providers/openai-responses-server.d.ts +17 -0
- package/dist/types/providers/openai-responses-wire.d.ts +6099 -0
- package/dist/types/providers/openai-responses.d.ts +131 -0
- package/dist/types/providers/openai-shared.d.ts +624 -0
- package/dist/types/providers/pi-native-client.d.ts +13 -0
- package/dist/types/providers/pi-native-server.d.ts +69 -0
- package/dist/types/providers/register-builtins.d.ts +37 -0
- package/dist/types/providers/synthetic.d.ts +26 -0
- package/dist/types/providers/transform-messages.d.ts +32 -0
- package/dist/types/providers/vision-guard.d.ts +20 -0
- package/dist/types/registry/aiand.d.ts +7 -0
- package/dist/types/registry/aimlapi.d.ts +4 -0
- package/dist/types/registry/alibaba-coding-plan.d.ts +8 -0
- package/dist/types/registry/alibaba-token-plan.d.ts +18 -0
- package/dist/types/registry/amazon-bedrock.d.ts +5 -0
- package/dist/types/registry/anthropic.d.ts +10 -0
- package/dist/types/registry/api-key-login.d.ts +42 -0
- package/dist/types/registry/api-key-validation.d.ts +43 -0
- package/dist/types/registry/aws.d.ts +13 -0
- package/dist/types/registry/azure.d.ts +4 -0
- package/dist/types/registry/baseten.d.ts +7 -0
- package/dist/types/registry/bedrock-mantle.d.ts +22 -0
- package/dist/types/registry/cerebras.d.ts +7 -0
- package/dist/types/registry/cloudflare-ai-gateway.d.ts +13 -0
- package/dist/types/registry/coreweave.d.ts +7 -0
- package/dist/types/registry/cursor.d.ts +7 -0
- package/dist/types/registry/deepseek.d.ts +8 -0
- package/dist/types/registry/derived.d.ts +5 -0
- package/dist/types/registry/devin.d.ts +8 -0
- package/dist/types/registry/exa.d.ts +8 -0
- package/dist/types/registry/firepass.d.ts +16 -0
- package/dist/types/registry/fireworks.d.ts +7 -0
- package/dist/types/registry/github-copilot.d.ts +7 -0
- package/dist/types/registry/gitlab-duo-workflow.d.ts +10 -0
- package/dist/types/registry/gitlab-duo.d.ts +9 -0
- package/dist/types/registry/gmi-cloud.d.ts +7 -0
- package/dist/types/registry/google-antigravity.d.ts +9 -0
- package/dist/types/registry/google-gemini-cli.d.ts +9 -0
- package/dist/types/registry/google-vertex.d.ts +5 -0
- package/dist/types/registry/google.d.ts +4 -0
- package/dist/types/registry/groq.d.ts +4 -0
- package/dist/types/registry/huggingface.d.ts +7 -0
- package/dist/types/registry/index.d.ts +4 -0
- package/dist/types/registry/kagi.d.ts +14 -0
- package/dist/types/registry/kilo.d.ts +7 -0
- package/dist/types/registry/kimi-code.d.ts +7 -0
- package/dist/types/registry/litellm.d.ts +13 -0
- package/dist/types/registry/llama-cpp.d.ts +8 -0
- package/dist/types/registry/lm-studio.d.ts +8 -0
- package/dist/types/registry/meta.d.ts +7 -0
- package/dist/types/registry/minimax-code-cn.d.ts +6 -0
- package/dist/types/registry/minimax-code.d.ts +6 -0
- package/dist/types/registry/minimax.d.ts +4 -0
- package/dist/types/registry/mistral.d.ts +4 -0
- package/dist/types/registry/moonshot.d.ts +7 -0
- package/dist/types/registry/nanogpt.d.ts +7 -0
- package/dist/types/registry/novita.d.ts +6 -0
- package/dist/types/registry/nvidia.d.ts +7 -0
- package/dist/types/registry/oauth/anthropic-constants.d.ts +12 -0
- package/dist/types/registry/oauth/anthropic.d.ts +24 -0
- package/dist/types/registry/oauth/callback-server.d.ts +74 -0
- package/dist/types/registry/oauth/cursor.d.ts +16 -0
- package/dist/types/registry/oauth/device-code.d.ts +25 -0
- package/dist/types/registry/oauth/devin.d.ts +5 -0
- package/dist/types/registry/oauth/github-copilot.d.ts +30 -0
- package/dist/types/registry/oauth/gitlab-duo-workflow.d.ts +6 -0
- package/dist/types/registry/oauth/gitlab-duo.d.ts +3 -0
- package/dist/types/registry/oauth/google-antigravity.d.ts +11 -0
- package/dist/types/registry/oauth/google-gemini-cli.d.ts +22 -0
- package/dist/types/registry/oauth/google-oauth-shared.d.ts +56 -0
- package/dist/types/registry/oauth/index.d.ts +45 -0
- package/dist/types/registry/oauth/kimi.d.ts +21 -0
- package/dist/types/registry/oauth/minimax-code.d.ts +27 -0
- package/dist/types/registry/oauth/openai-codex.d.ts +33 -0
- package/dist/types/registry/oauth/opencode.d.ts +18 -0
- package/dist/types/registry/oauth/perplexity.d.ts +9 -0
- package/dist/types/registry/oauth/pkce.d.ts +8 -0
- package/dist/types/registry/oauth/types.d.ts +87 -0
- package/dist/types/registry/oauth/wafer.d.ts +1 -0
- package/dist/types/registry/oauth/xai-oauth.d.ts +46 -0
- package/dist/types/registry/oauth/xiaomi.d.ts +25 -0
- package/dist/types/registry/oauth/zai.d.ts +25 -0
- package/dist/types/registry/ollama-cloud.d.ts +7 -0
- package/dist/types/registry/ollama.d.ts +12 -0
- package/dist/types/registry/openai-codex-device.d.ts +8 -0
- package/dist/types/registry/openai-codex.d.ts +9 -0
- package/dist/types/registry/openai.d.ts +4 -0
- package/dist/types/registry/opencode-go.d.ts +6 -0
- package/dist/types/registry/opencode-zen.d.ts +6 -0
- package/dist/types/registry/openrouter.d.ts +13 -0
- package/dist/types/registry/parallel.d.ts +14 -0
- package/dist/types/registry/perplexity.d.ts +7 -0
- package/dist/types/registry/qianfan.d.ts +7 -0
- package/dist/types/registry/qwen-portal.d.ts +7 -0
- package/dist/types/registry/registry.d.ts +367 -0
- package/dist/types/registry/sakana.d.ts +7 -0
- package/dist/types/registry/siliconflow-cn.d.ts +7 -0
- package/dist/types/registry/siliconflow.d.ts +7 -0
- package/dist/types/registry/synthetic.d.ts +6 -0
- package/dist/types/registry/tavily.d.ts +14 -0
- package/dist/types/registry/together.d.ts +6 -0
- package/dist/types/registry/types.d.ts +75 -0
- package/dist/types/registry/umans.d.ts +7 -0
- package/dist/types/registry/venice.d.ts +13 -0
- package/dist/types/registry/vercel-ai-gateway.d.ts +7 -0
- package/dist/types/registry/vllm.d.ts +7 -0
- package/dist/types/registry/wafer-serverless.d.ts +6 -0
- package/dist/types/registry/xai-oauth.d.ts +7 -0
- package/dist/types/registry/xai.d.ts +7 -0
- package/dist/types/registry/xiaomi-token-plan-ams.d.ts +6 -0
- package/dist/types/registry/xiaomi-token-plan-cn.d.ts +6 -0
- package/dist/types/registry/xiaomi-token-plan-sgp.d.ts +6 -0
- package/dist/types/registry/xiaomi.d.ts +6 -0
- package/dist/types/registry/zai.d.ts +15 -0
- package/dist/types/registry/zenmux.d.ts +7 -0
- package/dist/types/registry/zhipu-coding-plan.d.ts +7 -0
- package/dist/types/stream.d.ts +46 -0
- package/dist/types/types.d.ts +1064 -0
- package/dist/types/usage/alibaba-token-plan.d.ts +3 -0
- package/dist/types/usage/claude.d.ts +4 -0
- package/dist/types/usage/cursor.d.ts +4 -0
- package/dist/types/usage/gemini.d.ts +2 -0
- package/dist/types/usage/github-copilot.d.ts +7 -0
- package/dist/types/usage/google-antigravity.d.ts +15 -0
- package/dist/types/usage/kimi.d.ts +2 -0
- package/dist/types/usage/minimax-code.d.ts +3 -0
- package/dist/types/usage/ollama.d.ts +5 -0
- package/dist/types/usage/openai-codex-base-url.d.ts +18 -0
- package/dist/types/usage/openai-codex-reset.d.ts +88 -0
- package/dist/types/usage/openai-codex.d.ts +10 -0
- package/dist/types/usage/opencode-go.d.ts +2 -0
- package/dist/types/usage/shared.d.ts +1 -0
- package/dist/types/usage/synthetic.d.ts +2 -0
- package/dist/types/usage/umans.d.ts +2 -0
- package/dist/types/usage/xai-oauth.d.ts +12 -0
- package/dist/types/usage/zai.d.ts +3 -0
- package/dist/types/usage.d.ts +527 -0
- package/dist/types/utils/abort.d.ts +25 -0
- package/dist/types/utils/anthropic-auth.d.ts +35 -0
- package/dist/types/utils/aws-profile.d.ts +17 -0
- package/dist/types/utils/block-symbols.d.ts +62 -0
- package/dist/types/utils/deterministic-id.d.ts +16 -0
- package/dist/types/utils/empty-completion-retry.d.ts +21 -0
- package/dist/types/utils/event-stream.d.ts +39 -0
- package/dist/types/utils/foundry.d.ts +1 -0
- package/dist/types/utils/google-validation.d.ts +2 -0
- package/dist/types/utils/harmony-leak.d.ts +135 -0
- package/dist/types/utils/http-inspector.d.ts +49 -0
- package/dist/types/utils/idle-iterator.d.ts +149 -0
- package/dist/types/utils/leaked-thinking-stream.d.ts +33 -0
- package/dist/types/utils/openai-http.d.ts +48 -0
- package/dist/types/utils/openrouter-headers.d.ts +1 -0
- package/dist/types/utils/parse-bind.d.ts +23 -0
- package/dist/types/utils/provider-response.d.ts +3 -0
- package/dist/types/utils/proxy.d.ts +39 -0
- package/dist/types/utils/request-debug.d.ts +29 -0
- package/dist/types/utils/retry-after.d.ts +4 -0
- package/dist/types/utils/retry.d.ts +14 -0
- package/dist/types/utils/schema/adapt.d.ts +24 -0
- package/dist/types/utils/schema/compatibility.d.ts +30 -0
- package/dist/types/utils/schema/dereference.d.ts +11 -0
- package/dist/types/utils/schema/draft.d.ts +10 -0
- package/dist/types/utils/schema/equality.d.ts +4 -0
- package/dist/types/utils/schema/fields.d.ts +54 -0
- package/dist/types/utils/schema/index.d.ts +14 -0
- package/dist/types/utils/schema/json-schema-validator.d.ts +20 -0
- package/dist/types/utils/schema/meta-validator.d.ts +2 -0
- package/dist/types/utils/schema/normalize.d.ts +153 -0
- package/dist/types/utils/schema/spill.d.ts +8 -0
- package/dist/types/utils/schema/stamps.d.ts +17 -0
- package/dist/types/utils/schema/strict-tool-validation.d.ts +16 -0
- package/dist/types/utils/schema/types.d.ts +4 -0
- package/dist/types/utils/schema/typescript.d.ts +24 -0
- package/dist/types/utils/schema/wire.d.ts +52 -0
- package/dist/types/utils/sdk-stream-timeout.d.ts +33 -0
- package/dist/types/utils/sse-debug.d.ts +5 -0
- package/dist/types/utils/stream-markup-healing.d.ts +87 -0
- package/dist/types/utils/thinking-loop.d.ts +102 -0
- package/dist/types/utils/tool-call-loop-guard.d.ts +26 -0
- package/dist/types/utils/tool-choice.d.ts +52 -0
- package/dist/types/utils/validation.d.ts +28 -0
- package/dist/types/utils.d.ts +57 -0
- package/package.json +138 -0
- package/src/api-registry.ts +109 -0
- package/src/auth/sqlite-credential-store.ts +2066 -0
- package/src/auth-broker/client.ts +471 -0
- package/src/auth-broker/discover.ts +310 -0
- package/src/auth-broker/index.ts +7 -0
- package/src/auth-broker/refresher.ts +117 -0
- package/src/auth-broker/remote-store.ts +1332 -0
- package/src/auth-broker/server.ts +898 -0
- package/src/auth-broker/snapshot-cache.ts +200 -0
- package/src/auth-broker/types.ts +193 -0
- package/src/auth-broker/wire-schema-resource.ts +487 -0
- package/src/auth-broker/wire-schemas.ts +43 -0
- package/src/auth-gateway/http.ts +227 -0
- package/src/auth-gateway/index.ts +3 -0
- package/src/auth-gateway/server.ts +836 -0
- package/src/auth-gateway/types.ts +153 -0
- package/src/auth-retry.ts +401 -0
- package/src/auth-storage.ts +6540 -0
- package/src/dialect/anthropic.md +31 -0
- package/src/dialect/anthropic.ts +608 -0
- package/src/dialect/catalog.ts +29 -0
- package/src/dialect/coercion.ts +136 -0
- package/src/dialect/deepseek.md +24 -0
- package/src/dialect/deepseek.ts +609 -0
- package/src/dialect/demotion.ts +40 -0
- package/src/dialect/examples.ts +71 -0
- package/src/dialect/factory.ts +34 -0
- package/src/dialect/fenced-thinking.ts +184 -0
- package/src/dialect/gemini.md +44 -0
- package/src/dialect/gemini.ts +583 -0
- package/src/dialect/gemma.md +33 -0
- package/src/dialect/gemma.ts +387 -0
- package/src/dialect/glm.md +32 -0
- package/src/dialect/glm.ts +579 -0
- package/src/dialect/harmony.md +31 -0
- package/src/dialect/harmony.ts +345 -0
- package/src/dialect/hermes.md +25 -0
- package/src/dialect/hermes.ts +206 -0
- package/src/dialect/history.ts +81 -0
- package/src/dialect/index.ts +15 -0
- package/src/dialect/inventory.ts +30 -0
- package/src/dialect/kimi.md +24 -0
- package/src/dialect/kimi.ts +340 -0
- package/src/dialect/minimax.md +31 -0
- package/src/dialect/minimax.ts +95 -0
- package/src/dialect/owned-stream.ts +481 -0
- package/src/dialect/prompt-template.md +12 -0
- package/src/dialect/qwen3.md +28 -0
- package/src/dialect/qwen3.ts +240 -0
- package/src/dialect/rendering.ts +304 -0
- package/src/dialect/thinking.ts +292 -0
- package/src/dialect/types.ts +56 -0
- package/src/dialect/xml.md +22 -0
- package/src/dialect/xml.ts +90 -0
- package/src/error/abort.ts +18 -0
- package/src/error/auth-classify.ts +47 -0
- package/src/error/auth.ts +48 -0
- package/src/error/aws.ts +35 -0
- package/src/error/classes.ts +281 -0
- package/src/error/finalize.ts +69 -0
- package/src/error/flags.ts +602 -0
- package/src/error/format.ts +45 -0
- package/src/error/gateway.ts +96 -0
- package/src/error/index.ts +14 -0
- package/src/error/oauth.ts +58 -0
- package/src/error/provider.ts +63 -0
- package/src/error/rate-limit.ts +303 -0
- package/src/error/retryable.ts +70 -0
- package/src/error/validation.ts +44 -0
- package/src/index.ts +51 -0
- package/src/provider-details.ts +90 -0
- package/src/providers/amazon-bedrock.ts +1064 -0
- package/src/providers/anthropic-client.ts +317 -0
- package/src/providers/anthropic-messages-server-schema.ts +252 -0
- package/src/providers/anthropic-messages-server.ts +818 -0
- package/src/providers/anthropic-wire.ts +359 -0
- package/src/providers/anthropic.ts +4539 -0
- package/src/providers/aws-credentials.ts +772 -0
- package/src/providers/aws-eventstream.ts +181 -0
- package/src/providers/aws-sigv4.ts +218 -0
- package/src/providers/azure-openai-responses.ts +438 -0
- package/src/providers/bedrock-mantle.ts +110 -0
- package/src/providers/claude-code-fingerprint.ts +20 -0
- package/src/providers/cowork-fetch.ts +201 -0
- package/src/providers/cursor/exec-modern.ts +496 -0
- package/src/providers/cursor/proto/agent.proto +4533 -0
- package/src/providers/cursor/proto/buf.gen.yaml +6 -0
- package/src/providers/cursor/proto/buf.yaml +17 -0
- package/src/providers/cursor-pi-args.ts +165 -0
- package/src/providers/cursor.ts +4689 -0
- package/src/providers/devin/proto/buf/validate/validate.proto +468 -0
- package/src/providers/devin/proto/buf.gen.yaml +33 -0
- package/src/providers/devin/proto/buf.yaml +17 -0
- package/src/providers/devin/proto/cel/expr/checked.proto +103 -0
- package/src/providers/devin/proto/cel/expr/eval.proto +38 -0
- package/src/providers/devin/proto/cel/expr/explain.proto +15 -0
- package/src/providers/devin/proto/cel/expr/syntax.proto +113 -0
- package/src/providers/devin/proto/cel/expr/value.proto +41 -0
- package/src/providers/devin/proto/connectext/grpc/status/v1/status.proto +11 -0
- package/src/providers/devin/proto/errorspb/errors.proto +56 -0
- package/src/providers/devin/proto/errorspb/hintdetail.proto +7 -0
- package/src/providers/devin/proto/errorspb/markers.proto +10 -0
- package/src/providers/devin/proto/errorspb/tags.proto +12 -0
- package/src/providers/devin/proto/errorspb/testing.proto +6 -0
- package/src/providers/devin/proto/exa/analytics_pb/analytics.proto +188 -0
- package/src/providers/devin/proto/exa/api_server_pb/api_server.proto +2461 -0
- package/src/providers/devin/proto/exa/auth_pb/auth.proto +19 -0
- package/src/providers/devin/proto/exa/auto_cascade_common_pb/auto_cascade_common.proto +79 -0
- package/src/providers/devin/proto/exa/browser_preview_pb/browser_preview.proto +32 -0
- package/src/providers/devin/proto/exa/bug_checker_pb/bug_checker.proto +22 -0
- package/src/providers/devin/proto/exa/cascade_plugins_pb/cascade_plugins.proto +262 -0
- package/src/providers/devin/proto/exa/chat_client_server_pb/chat_client_server.proto +57 -0
- package/src/providers/devin/proto/exa/chat_pb/chat.proto +449 -0
- package/src/providers/devin/proto/exa/code_edit/code_edit_pb/code_edit.proto +186 -0
- package/src/providers/devin/proto/exa/codeium_common_pb/codeium_common.proto +4157 -0
- package/src/providers/devin/proto/exa/context_module_pb/context_module.proto +175 -0
- package/src/providers/devin/proto/exa/cortex_pb/cortex.proto +3268 -0
- package/src/providers/devin/proto/exa/dev_pb/dev.proto +26 -0
- package/src/providers/devin/proto/exa/diff_action_pb/diff_action.proto +75 -0
- package/src/providers/devin/proto/exa/eval/pr_eval/datasets_pb/datasets.proto +103 -0
- package/src/providers/devin/proto/exa/eval_pb/eval.proto +1315 -0
- package/src/providers/devin/proto/exa/extension_server_pb/extension_server.proto +556 -0
- package/src/providers/devin/proto/exa/file_system_provider_pb/file_system_provider.proto +75 -0
- package/src/providers/devin/proto/exa/index_pb/index.proto +461 -0
- package/src/providers/devin/proto/exa/knowledge_base_pb/knowledge_base.proto +144 -0
- package/src/providers/devin/proto/exa/language_server_pb/language_server.proto +2385 -0
- package/src/providers/devin/proto/exa/model_management_pb/model_management.proto +186 -0
- package/src/providers/devin/proto/exa/opensearch_clients_pb/opensearch_clients.proto +503 -0
- package/src/providers/devin/proto/exa/product_analytics_pb/product_analytics.proto +37 -0
- package/src/providers/devin/proto/exa/prompt_pb/prompt.proto +92 -0
- package/src/providers/devin/proto/exa/reactive_component_pb/reactive_component.proto +96 -0
- package/src/providers/devin/proto/exa/seat_management_pb/seat_management.proto +2680 -0
- package/src/providers/devin/proto/exa/tokenizer_pb/tokenizer.proto +37 -0
- package/src/providers/devin/proto/exa/trainer_pb/config.proto +647 -0
- package/src/providers/devin/proto/exa/tree_sitter/language_data_pb/language_data.proto +14 -0
- package/src/providers/devin/proto/exa/trust_pb/trust.proto +157 -0
- package/src/providers/devin/proto/exa/user_analytics_pb/user_analytics.proto +519 -0
- package/src/providers/devin/proto/google.golang.org/appengine/internal/base/api_base.proto +28 -0
- package/src/providers/devin/proto/google.golang.org/appengine/internal/datastore/datastore_v3.proto +484 -0
- package/src/providers/devin/proto/google.golang.org/appengine/internal/log/log_service.proto +136 -0
- package/src/providers/devin/proto/google.golang.org/appengine/internal/remote_api/remote_api.proto +42 -0
- package/src/providers/devin/proto/google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto +61 -0
- package/src/providers/devin/proto/grpc/binlog/v1/binarylog.proto +84 -0
- package/src/providers/devin/proto/io/prometheus/client/metrics.proto +98 -0
- package/src/providers/devin.ts +679 -0
- package/src/providers/error-message.ts +23 -0
- package/src/providers/github-copilot-headers.ts +141 -0
- package/src/providers/gitlab-duo-workflow-chatml-note.md +1 -0
- package/src/providers/gitlab-duo-workflow.ts +3135 -0
- package/src/providers/gitlab-duo.ts +399 -0
- package/src/providers/google-auth.ts +330 -0
- package/src/providers/google-gemini-cli.ts +1370 -0
- package/src/providers/google-shared.ts +1122 -0
- package/src/providers/google-types.ts +180 -0
- package/src/providers/google-vertex.ts +135 -0
- package/src/providers/google.ts +47 -0
- package/src/providers/grammar.ts +70 -0
- package/src/providers/kimi.ts +51 -0
- package/src/providers/mock.ts +514 -0
- package/src/providers/ollama.ts +776 -0
- package/src/providers/openai-anthropic-shim.ts +166 -0
- package/src/providers/openai-chat-server-schema.ts +243 -0
- package/src/providers/openai-chat-server.ts +752 -0
- package/src/providers/openai-chat-wire.ts +859 -0
- package/src/providers/openai-codex/request-transformer.ts +491 -0
- package/src/providers/openai-codex/response-handler.ts +102 -0
- package/src/providers/openai-codex-responses.ts +4716 -0
- package/src/providers/openai-completions.ts +2389 -0
- package/src/providers/openai-reasoning-fallback.ts +269 -0
- package/src/providers/openai-responses-server-schema.ts +397 -0
- package/src/providers/openai-responses-server.ts +1466 -0
- package/src/providers/openai-responses-wire.ts +6416 -0
- package/src/providers/openai-responses.ts +1393 -0
- package/src/providers/openai-shared.ts +3500 -0
- package/src/providers/pi-native-client.ts +275 -0
- package/src/providers/pi-native-server.ts +245 -0
- package/src/providers/register-builtins.ts +503 -0
- package/src/providers/synthetic.ts +50 -0
- package/src/providers/transform-messages.ts +1083 -0
- package/src/providers/vision-guard.ts +54 -0
- package/src/registry/aiand.ts +22 -0
- package/src/registry/aimlapi.ts +6 -0
- package/src/registry/alibaba-coding-plan.ts +104 -0
- package/src/registry/alibaba-token-plan.ts +125 -0
- package/src/registry/amazon-bedrock.ts +22 -0
- package/src/registry/anthropic.ts +26 -0
- package/src/registry/api-key-login.ts +115 -0
- package/src/registry/api-key-validation.ts +145 -0
- package/src/registry/aws.ts +57 -0
- package/src/registry/azure.ts +6 -0
- package/src/registry/baseten.ts +22 -0
- package/src/registry/bedrock-mantle.ts +34 -0
- package/src/registry/cerebras.ts +23 -0
- package/src/registry/cloudflare-ai-gateway.ts +45 -0
- package/src/registry/coreweave.ts +40 -0
- package/src/registry/cursor.ts +20 -0
- package/src/registry/deepseek.ts +46 -0
- package/src/registry/derived.ts +9 -0
- package/src/registry/devin.ts +15 -0
- package/src/registry/exa.ts +19 -0
- package/src/registry/firepass.ts +32 -0
- package/src/registry/fireworks.ts +28 -0
- package/src/registry/github-copilot.ts +22 -0
- package/src/registry/gitlab-duo-workflow.ts +20 -0
- package/src/registry/gitlab-duo.ts +19 -0
- package/src/registry/gmi-cloud.ts +22 -0
- package/src/registry/google-antigravity.ts +22 -0
- package/src/registry/google-gemini-cli.ts +22 -0
- package/src/registry/google-vertex.ts +38 -0
- package/src/registry/google.ts +6 -0
- package/src/registry/groq.ts +6 -0
- package/src/registry/huggingface.ts +29 -0
- package/src/registry/index.ts +4 -0
- package/src/registry/kagi.ts +46 -0
- package/src/registry/kilo.ts +114 -0
- package/src/registry/kimi-code.ts +17 -0
- package/src/registry/litellm.ts +45 -0
- package/src/registry/llama-cpp.ts +35 -0
- package/src/registry/lm-studio.ts +31 -0
- package/src/registry/meta.ts +22 -0
- package/src/registry/minimax-code-cn.ts +12 -0
- package/src/registry/minimax-code.ts +12 -0
- package/src/registry/minimax.ts +6 -0
- package/src/registry/mistral.ts +6 -0
- package/src/registry/moonshot.ts +28 -0
- package/src/registry/nanogpt.ts +22 -0
- package/src/registry/novita.ts +25 -0
- package/src/registry/nvidia.ts +61 -0
- package/src/registry/oauth/anthropic-constants.ts +12 -0
- package/src/registry/oauth/anthropic.ts +346 -0
- package/src/registry/oauth/callback-server.ts +438 -0
- package/src/registry/oauth/cursor.ts +187 -0
- package/src/registry/oauth/device-code.ts +92 -0
- package/src/registry/oauth/devin.ts +124 -0
- package/src/registry/oauth/github-copilot.ts +369 -0
- package/src/registry/oauth/gitlab-duo-workflow.ts +146 -0
- package/src/registry/oauth/gitlab-duo.ts +222 -0
- package/src/registry/oauth/google-antigravity.ts +225 -0
- package/src/registry/oauth/google-gemini-cli.ts +297 -0
- package/src/registry/oauth/google-oauth-shared.ts +211 -0
- package/src/registry/oauth/index.ts +187 -0
- package/src/registry/oauth/kimi.ts +297 -0
- package/src/registry/oauth/minimax-code.ts +53 -0
- package/src/registry/oauth/oauth.html +317 -0
- package/src/registry/oauth/openai-codex.ts +384 -0
- package/src/registry/oauth/opencode.ts +50 -0
- package/src/registry/oauth/perplexity.ts +228 -0
- package/src/registry/oauth/pkce.ts +18 -0
- package/src/registry/oauth/types.ts +96 -0
- package/src/registry/oauth/wafer.ts +24 -0
- package/src/registry/oauth/xai-oauth.ts +559 -0
- package/src/registry/oauth/xiaomi.ts +211 -0
- package/src/registry/oauth/zai.ts +285 -0
- package/src/registry/ollama-cloud.ts +36 -0
- package/src/registry/ollama.ts +43 -0
- package/src/registry/openai-codex-device.ts +18 -0
- package/src/registry/openai-codex.ts +19 -0
- package/src/registry/openai.ts +6 -0
- package/src/registry/opencode-go.ts +12 -0
- package/src/registry/opencode-zen.ts +12 -0
- package/src/registry/openrouter.ts +28 -0
- package/src/registry/parallel.ts +45 -0
- package/src/registry/perplexity.ts +13 -0
- package/src/registry/qianfan.ts +27 -0
- package/src/registry/qwen-portal.ts +50 -0
- package/src/registry/registry.ts +182 -0
- package/src/registry/sakana.ts +22 -0
- package/src/registry/siliconflow-cn.ts +22 -0
- package/src/registry/siliconflow.ts +22 -0
- package/src/registry/synthetic.ts +21 -0
- package/src/registry/tavily.ts +45 -0
- package/src/registry/together.ts +22 -0
- package/src/registry/types.ts +86 -0
- package/src/registry/umans.ts +23 -0
- package/src/registry/venice.ts +33 -0
- package/src/registry/vercel-ai-gateway.ts +38 -0
- package/src/registry/vllm.ts +34 -0
- package/src/registry/wafer-serverless.ts +12 -0
- package/src/registry/xai-oauth.ts +17 -0
- package/src/registry/xai.ts +22 -0
- package/src/registry/xiaomi-token-plan-ams.ts +12 -0
- package/src/registry/xiaomi-token-plan-cn.ts +12 -0
- package/src/registry/xiaomi-token-plan-sgp.ts +12 -0
- package/src/registry/xiaomi.ts +12 -0
- package/src/registry/zai.ts +41 -0
- package/src/registry/zenmux.ts +22 -0
- package/src/registry/zhipu-coding-plan.ts +27 -0
- package/src/stream.ts +1944 -0
- package/src/types.ts +1243 -0
- package/src/usage/alibaba-token-plan.ts +230 -0
- package/src/usage/claude.ts +830 -0
- package/src/usage/cursor.ts +335 -0
- package/src/usage/gemini.ts +258 -0
- package/src/usage/github-copilot.ts +424 -0
- package/src/usage/google-antigravity.ts +497 -0
- package/src/usage/kimi.ts +277 -0
- package/src/usage/minimax-code.ts +291 -0
- package/src/usage/ollama.ts +41 -0
- package/src/usage/openai-codex-base-url.ts +35 -0
- package/src/usage/openai-codex-reset.ts +205 -0
- package/src/usage/openai-codex.ts +627 -0
- package/src/usage/opencode-go.ts +89 -0
- package/src/usage/shared.ts +10 -0
- package/src/usage/synthetic.ts +180 -0
- package/src/usage/umans.ts +192 -0
- package/src/usage/xai-oauth.ts +414 -0
- package/src/usage/zai.ts +370 -0
- package/src/usage.ts +411 -0
- package/src/utils/abort.ts +67 -0
- package/src/utils/anthropic-auth.ts +93 -0
- package/src/utils/aws-profile.ts +88 -0
- package/src/utils/block-symbols.ts +78 -0
- package/src/utils/deterministic-id.ts +20 -0
- package/src/utils/empty-completion-retry.ts +161 -0
- package/src/utils/event-stream.ts +202 -0
- package/src/utils/foundry.ts +8 -0
- package/src/utils/google-validation.ts +25 -0
- package/src/utils/harmony-leak.ts +500 -0
- package/src/utils/http-inspector.ts +196 -0
- package/src/utils/idle-iterator.ts +531 -0
- package/src/utils/leaked-thinking-stream.ts +483 -0
- package/src/utils/openai-http.ts +119 -0
- package/src/utils/openrouter-headers.ts +12 -0
- package/src/utils/parse-bind.ts +56 -0
- package/src/utils/provider-response.ts +30 -0
- package/src/utils/proxy.ts +314 -0
- package/src/utils/request-debug.ts +351 -0
- package/src/utils/retry-after.ts +121 -0
- package/src/utils/retry.ts +77 -0
- package/src/utils/schema/CONSTRAINTS.md +168 -0
- package/src/utils/schema/adapt.ts +36 -0
- package/src/utils/schema/compatibility.ts +435 -0
- package/src/utils/schema/dereference.ts +98 -0
- package/src/utils/schema/draft.ts +341 -0
- package/src/utils/schema/equality.ts +97 -0
- package/src/utils/schema/fields.ts +210 -0
- package/src/utils/schema/index.ts +14 -0
- package/src/utils/schema/json-schema-validator.ts +595 -0
- package/src/utils/schema/meta-validator.ts +167 -0
- package/src/utils/schema/normalize.ts +2314 -0
- package/src/utils/schema/spill.ts +43 -0
- package/src/utils/schema/stamps.ts +109 -0
- package/src/utils/schema/strict-tool-validation.ts +117 -0
- package/src/utils/schema/types.ts +10 -0
- package/src/utils/schema/typescript.ts +212 -0
- package/src/utils/schema/wire.ts +662 -0
- package/src/utils/sdk-stream-timeout.ts +43 -0
- package/src/utils/sse-debug.ts +18 -0
- package/src/utils/stream-markup-healing.ts +247 -0
- package/src/utils/thinking-loop.ts +552 -0
- package/src/utils/tool-call-loop-guard.ts +107 -0
- package/src/utils/tool-choice.ts +101 -0
- package/src/utils/validation.ts +1932 -0
- package/src/utils.ts +492 -0
|
@@ -0,0 +1,662 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compute the wire (JSON Schema) representation of a tool's parameters.
|
|
3
|
+
*
|
|
4
|
+
* Tools may author parameters as ArkType schemas or legacy TypeBox / plain JSON
|
|
5
|
+
* Schema documents. Both are normalized at the boundary so providers and
|
|
6
|
+
* validators see the same JSON Schema dialect.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { Type } from "@linxiraos/pi-omptype";
|
|
10
|
+
import type { Tool, TSchema } from "../../types";
|
|
11
|
+
import { upgradeJsonSchemaTo202012 } from "./draft";
|
|
12
|
+
import { stamp } from "./stamps";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* True when `value` is a live ArkType schema instance.
|
|
16
|
+
*
|
|
17
|
+
* ArkType schemas are callable functions carrying `toJsonSchema`/`assert`
|
|
18
|
+
* methods, while raw JSON Schema is a plain object.
|
|
19
|
+
*/
|
|
20
|
+
export function isArkSchema(value: unknown): value is Type {
|
|
21
|
+
return (
|
|
22
|
+
typeof value === "function" &&
|
|
23
|
+
typeof (value as { toJsonSchema?: unknown }).toJsonSchema === "function" &&
|
|
24
|
+
typeof (value as { assert?: unknown }).assert === "function"
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function isArkJsonAst(value: unknown): boolean {
|
|
29
|
+
if (Array.isArray(value)) return value.some(isArkJsonAst);
|
|
30
|
+
if (!isSchemaRecord(value)) return false;
|
|
31
|
+
if (typeof value.domain === "string" || Object.hasOwn(value, "unit")) return true;
|
|
32
|
+
if (value.proto === "Array" && Object.hasOwn(value, "sequence")) return true;
|
|
33
|
+
const required = value.required;
|
|
34
|
+
return (
|
|
35
|
+
Array.isArray(required) &&
|
|
36
|
+
required.some(entry => isSchemaRecord(entry) && typeof entry.key === "string" && "value" in entry)
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function parseArkObjectKey(key: string): { name: string; description?: string } {
|
|
41
|
+
const match = /^(.*?)\s*\/\*\*\s*([\s\S]*?)\s*\*\/\s*$/.exec(key);
|
|
42
|
+
if (!match) return { name: key };
|
|
43
|
+
return { name: match[1].trim(), description: match[2].trim() };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function withArkKeyDescription(schema: unknown, description: string | undefined): unknown {
|
|
47
|
+
if (!description) return schema;
|
|
48
|
+
if (isSchemaRecord(schema)) {
|
|
49
|
+
if (typeof schema.description !== "string") schema.description = description;
|
|
50
|
+
return schema;
|
|
51
|
+
}
|
|
52
|
+
return { anyOf: [schema], description };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function arkJsonAstToWire(value: unknown): unknown {
|
|
56
|
+
if (typeof value === "string") {
|
|
57
|
+
switch (value) {
|
|
58
|
+
case "string":
|
|
59
|
+
case "number":
|
|
60
|
+
case "integer":
|
|
61
|
+
case "boolean":
|
|
62
|
+
case "object":
|
|
63
|
+
return { type: value };
|
|
64
|
+
case "unknown":
|
|
65
|
+
return {};
|
|
66
|
+
default:
|
|
67
|
+
return {};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (Array.isArray(value)) {
|
|
72
|
+
if (value.every(item => isSchemaRecord(item) && Object.hasOwn(item, "unit"))) {
|
|
73
|
+
return { enum: value.map(item => (item as { unit: unknown }).unit) };
|
|
74
|
+
}
|
|
75
|
+
return { anyOf: value.map(arkJsonAstToWire) };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (!isSchemaRecord(value)) return {};
|
|
79
|
+
|
|
80
|
+
if (Object.hasOwn(value, "unit")) return { const: value.unit };
|
|
81
|
+
|
|
82
|
+
if (value.proto === "Array" && Object.hasOwn(value, "sequence")) {
|
|
83
|
+
return { type: "array", items: arkJsonAstToWire(value.sequence) };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (value.domain === "object") {
|
|
87
|
+
const properties: Record<string, unknown> = {};
|
|
88
|
+
const required: string[] = [];
|
|
89
|
+
const addEntry = (entry: unknown, isRequired: boolean): void => {
|
|
90
|
+
if (!isSchemaRecord(entry) || typeof entry.key !== "string" || !("value" in entry)) return;
|
|
91
|
+
const key = parseArkObjectKey(entry.key);
|
|
92
|
+
properties[key.name] = withArkKeyDescription(arkJsonAstToWire(entry.value), key.description);
|
|
93
|
+
if (isRequired) required.push(key.name);
|
|
94
|
+
};
|
|
95
|
+
if (Array.isArray(value.required)) {
|
|
96
|
+
for (const entry of value.required) addEntry(entry, true);
|
|
97
|
+
}
|
|
98
|
+
if (Array.isArray(value.optional)) {
|
|
99
|
+
for (const entry of value.optional) addEntry(entry, false);
|
|
100
|
+
}
|
|
101
|
+
const schema: Record<string, unknown> = { type: "object", properties };
|
|
102
|
+
if (required.length > 0) schema.required = required;
|
|
103
|
+
return schema;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (typeof value.domain === "string") return { type: value.domain };
|
|
107
|
+
return {};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Symbol-stamped caches keyed by schema object identity. */
|
|
111
|
+
const kJsonWireSchema = Symbol("pi.schema.json.wire");
|
|
112
|
+
const kArkWireSchema = Symbol("pi.schema.ark.wire");
|
|
113
|
+
const kStrippedSchema = Symbol("pi.schema.descriptions.stripped");
|
|
114
|
+
|
|
115
|
+
function postProcessJsonSchema(schema: Record<string, unknown>): Record<string, unknown> {
|
|
116
|
+
walk(schema);
|
|
117
|
+
normalizeArkPropertyComments(schema);
|
|
118
|
+
normalizeEmptySchemas(schema);
|
|
119
|
+
return schema;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const NULLABLE_SCALAR_TYPES = new Set(["string", "number", "integer", "boolean"]);
|
|
123
|
+
|
|
124
|
+
const SCHEMA_DEFINING_SIBLING_KEYS = new Set([
|
|
125
|
+
"$ref",
|
|
126
|
+
"additionalProperties",
|
|
127
|
+
"allOf",
|
|
128
|
+
"anyOf",
|
|
129
|
+
"const",
|
|
130
|
+
"contains",
|
|
131
|
+
"enum",
|
|
132
|
+
"if",
|
|
133
|
+
"items",
|
|
134
|
+
"not",
|
|
135
|
+
"oneOf",
|
|
136
|
+
"patternProperties",
|
|
137
|
+
"prefixItems",
|
|
138
|
+
"properties",
|
|
139
|
+
"propertyNames",
|
|
140
|
+
"then",
|
|
141
|
+
"else",
|
|
142
|
+
"unevaluatedItems",
|
|
143
|
+
"unevaluatedProperties",
|
|
144
|
+
]);
|
|
145
|
+
|
|
146
|
+
function isSchemaRecord(value: unknown): value is Record<string, unknown> {
|
|
147
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function hasSchemaDefiningSibling(schema: Record<string, unknown>): boolean {
|
|
151
|
+
for (const key in schema) {
|
|
152
|
+
if (key !== "anyOf" && SCHEMA_DEFINING_SIBLING_KEYS.has(key)) return true;
|
|
153
|
+
}
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function isNullVariant(schema: Record<string, unknown>): boolean {
|
|
158
|
+
return schema.type === "null" && Object.keys(schema).length === 1;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function isScalarVariant(schema: Record<string, unknown>): schema is Record<string, unknown> & { type: string } {
|
|
162
|
+
return typeof schema.type === "string" && NULLABLE_SCALAR_TYPES.has(schema.type);
|
|
163
|
+
}
|
|
164
|
+
function copyNullableScalarConstraints(schema: Record<string, unknown>, scalarVariant: Record<string, unknown>): void {
|
|
165
|
+
for (const key in scalarVariant) {
|
|
166
|
+
if (key === "type" || key === "enum" || key === "const" || Object.hasOwn(schema, key)) continue;
|
|
167
|
+
schema[key] = scalarVariant[key];
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (Object.hasOwn(scalarVariant, "const")) {
|
|
171
|
+
schema.enum = [scalarVariant.const, null];
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const enumValues = scalarVariant.enum;
|
|
176
|
+
if (Array.isArray(enumValues)) {
|
|
177
|
+
schema.enum = enumValues.includes(null) ? enumValues : [...enumValues, null];
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function rewriteNullableScalarAnyOf(schema: Record<string, unknown>): void {
|
|
182
|
+
if (hasSchemaDefiningSibling(schema)) return;
|
|
183
|
+
const variants = schema.anyOf;
|
|
184
|
+
if (!Array.isArray(variants) || variants.length !== 2) return;
|
|
185
|
+
|
|
186
|
+
let scalarVariant: Record<string, unknown> | undefined;
|
|
187
|
+
let scalarType: string | undefined;
|
|
188
|
+
let sawNull = false;
|
|
189
|
+
for (const variant of variants) {
|
|
190
|
+
if (!isSchemaRecord(variant)) return;
|
|
191
|
+
if (isNullVariant(variant)) {
|
|
192
|
+
if (sawNull) return;
|
|
193
|
+
sawNull = true;
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
if (!isScalarVariant(variant) || scalarVariant) return;
|
|
197
|
+
scalarVariant = variant;
|
|
198
|
+
scalarType = variant.type;
|
|
199
|
+
}
|
|
200
|
+
if (!sawNull || !scalarVariant || !scalarType) return;
|
|
201
|
+
|
|
202
|
+
delete schema.anyOf;
|
|
203
|
+
copyNullableScalarConstraints(schema, scalarVariant);
|
|
204
|
+
schema.type = [scalarType, "null"];
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/** Keys whose values are a single JSON Schema (not an array or map). */
|
|
208
|
+
const SCHEMA_VALUE_KEYS = [
|
|
209
|
+
"additionalProperties",
|
|
210
|
+
"unevaluatedProperties",
|
|
211
|
+
"unevaluatedItems",
|
|
212
|
+
"items",
|
|
213
|
+
"contains",
|
|
214
|
+
"propertyNames",
|
|
215
|
+
"if",
|
|
216
|
+
"then",
|
|
217
|
+
"else",
|
|
218
|
+
"not",
|
|
219
|
+
] as const;
|
|
220
|
+
|
|
221
|
+
/** Keys whose values are a map of `{ key: Schema }` entries. */
|
|
222
|
+
const SCHEMA_MAP_KEYS = ["properties", "patternProperties", "$defs", "definitions"] as const;
|
|
223
|
+
|
|
224
|
+
/** Keys whose values are an array of schemas. */
|
|
225
|
+
const SCHEMA_ARRAY_KEYS = ["anyOf", "oneOf", "allOf", "prefixItems"] as const;
|
|
226
|
+
|
|
227
|
+
function normalizeArkPropertyComments(node: unknown): void {
|
|
228
|
+
if (Array.isArray(node)) {
|
|
229
|
+
for (const child of node) normalizeArkPropertyComments(child);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
if (!isSchemaRecord(node)) return;
|
|
233
|
+
const obj = node as Record<string, unknown>;
|
|
234
|
+
|
|
235
|
+
const properties = obj.properties;
|
|
236
|
+
if (isSchemaRecord(properties)) {
|
|
237
|
+
const required = Array.isArray(obj.required) ? obj.required : undefined;
|
|
238
|
+
if (required) {
|
|
239
|
+
obj.required = required.map(key => (typeof key === "string" ? parseArkObjectKey(key).name : key));
|
|
240
|
+
}
|
|
241
|
+
for (const key of Object.keys(properties)) {
|
|
242
|
+
const parsed = parseArkObjectKey(key);
|
|
243
|
+
const targetKey = parsed.name;
|
|
244
|
+
let propertySchema = properties[key];
|
|
245
|
+
if (parsed.description) {
|
|
246
|
+
propertySchema = withArkKeyDescription(propertySchema, parsed.description);
|
|
247
|
+
delete properties[key];
|
|
248
|
+
properties[targetKey] = propertySchema;
|
|
249
|
+
}
|
|
250
|
+
normalizeArkPropertyComments(propertySchema);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
for (const key of SCHEMA_VALUE_KEYS) {
|
|
255
|
+
if (Object.hasOwn(obj, key)) normalizeArkPropertyComments(obj[key]);
|
|
256
|
+
}
|
|
257
|
+
for (const mapKey of SCHEMA_MAP_KEYS) {
|
|
258
|
+
if (mapKey === "properties") continue;
|
|
259
|
+
const map = obj[mapKey];
|
|
260
|
+
if (isSchemaRecord(map)) {
|
|
261
|
+
for (const key in map) normalizeArkPropertyComments(map[key]);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
for (const arrayKey of SCHEMA_ARRAY_KEYS) {
|
|
265
|
+
const array = obj[arrayKey];
|
|
266
|
+
if (Array.isArray(array)) {
|
|
267
|
+
for (const child of array) normalizeArkPropertyComments(child);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/** True when `val` is a plain empty object `{}`. */
|
|
273
|
+
function isEmptyObject(val: unknown): val is Record<string, never> {
|
|
274
|
+
if (val === null || typeof val !== "object" || Array.isArray(val)) return false;
|
|
275
|
+
return Object.keys(val).length === 0;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* The single JSON Schema scalar `type` that describes every member of a
|
|
280
|
+
* homogeneous primitive enum, or `undefined` when the members are mixed,
|
|
281
|
+
* non-scalar (`null`/object/array), or the list is empty.
|
|
282
|
+
*/
|
|
283
|
+
function homogeneousEnumScalarType(values: readonly unknown[]): string | undefined {
|
|
284
|
+
if (values.length === 0) return undefined;
|
|
285
|
+
let inferred: string | undefined;
|
|
286
|
+
for (const value of values) {
|
|
287
|
+
let scalar: string | undefined;
|
|
288
|
+
switch (typeof value) {
|
|
289
|
+
case "string":
|
|
290
|
+
scalar = "string";
|
|
291
|
+
break;
|
|
292
|
+
case "boolean":
|
|
293
|
+
scalar = "boolean";
|
|
294
|
+
break;
|
|
295
|
+
case "number":
|
|
296
|
+
scalar = "number";
|
|
297
|
+
break;
|
|
298
|
+
default:
|
|
299
|
+
return undefined; // null / object / array — not a single scalar type
|
|
300
|
+
}
|
|
301
|
+
if (inferred === undefined) inferred = scalar;
|
|
302
|
+
else if (inferred !== scalar) return undefined; // mixed primitives
|
|
303
|
+
}
|
|
304
|
+
return inferred;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* ArkType emits string-literal unions (and raw JSON-Schema tools can declare
|
|
309
|
+
* enums) as a bare `{ enum: [...] }` with no `type`. That is valid JSON Schema
|
|
310
|
+
* and accepted by OpenAI/Anthropic, but Gemini/Vertex — including the
|
|
311
|
+
* OpenAI-compatible gateways fronting it — reject a function-declaration enum
|
|
312
|
+
* that omits `type` ("schema didn't specify the schema type field"). Complete
|
|
313
|
+
* the node by inferring the scalar `type` when every member shares one.
|
|
314
|
+
*/
|
|
315
|
+
function inferBareEnumScalarType(obj: Record<string, unknown>): void {
|
|
316
|
+
if ("type" in obj || !Array.isArray(obj.enum)) return;
|
|
317
|
+
const inferred = homogeneousEnumScalarType(obj.enum);
|
|
318
|
+
if (inferred !== undefined) obj.type = inferred;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* ArkType serializes a *described* literal union — `type.enumerated(...).describe(d)`
|
|
323
|
+
* or a `"a" | "b"` union carrying a description — as an `anyOf` of
|
|
324
|
+
* `{ const, description }` branches that repeat the description on every branch
|
|
325
|
+
* *and* the union root. The meta is distributed across the union's constituents
|
|
326
|
+
* at the type level (each `unit` node inherits it), so the duplication is baked
|
|
327
|
+
* in before serialization rather than added by this pipeline.
|
|
328
|
+
*
|
|
329
|
+
* Collapse such a homogeneous all-`const` union into one typed
|
|
330
|
+
* `{ type, enum, description }` node: a shorter wire and a single description in
|
|
331
|
+
* the place providers expect it. The collapse is conservative — applied only
|
|
332
|
+
* when it is lossless:
|
|
333
|
+
* - every branch is a bare `{ const }` (optionally `{ const, description }`),
|
|
334
|
+
* - all branch values share one scalar JSON type (so `enum` gets a `type`,
|
|
335
|
+
* which Gemini/Vertex require),
|
|
336
|
+
* - branch descriptions are either all absent or all identical,
|
|
337
|
+
* so a union whose branches carry *distinct* per-variant descriptions is left
|
|
338
|
+
* untouched (a flat `enum` has nowhere to keep them). The union root's own
|
|
339
|
+
* description wins when present; otherwise the shared branch description is kept.
|
|
340
|
+
*/
|
|
341
|
+
function collapseConstUnionAnyOf(obj: Record<string, unknown>): void {
|
|
342
|
+
// `hasSchemaDefiningSibling` already rejects a sibling `enum`/`const`/etc.; it
|
|
343
|
+
// does not list `type`, so guard it here — collapsing would overwrite a
|
|
344
|
+
// wrapper `type` constraint paired with the `anyOf`.
|
|
345
|
+
if (hasSchemaDefiningSibling(obj) || "type" in obj) return;
|
|
346
|
+
const variants = obj.anyOf;
|
|
347
|
+
if (!Array.isArray(variants) || variants.length < 2) return;
|
|
348
|
+
|
|
349
|
+
const values: unknown[] = [];
|
|
350
|
+
let branchDescription: string | undefined;
|
|
351
|
+
let describedCount = 0;
|
|
352
|
+
for (const variant of variants) {
|
|
353
|
+
if (!isSchemaRecord(variant) || !Object.hasOwn(variant, "const")) return;
|
|
354
|
+
for (const key in variant) {
|
|
355
|
+
if (key !== "const" && key !== "description") return; // extra constraints — not a bare const
|
|
356
|
+
}
|
|
357
|
+
const desc = variant.description;
|
|
358
|
+
if (typeof desc === "string") {
|
|
359
|
+
if (describedCount === 0) branchDescription = desc;
|
|
360
|
+
else if (desc !== branchDescription) return; // distinct per-variant descriptions — preserve them
|
|
361
|
+
describedCount++;
|
|
362
|
+
}
|
|
363
|
+
values.push(variant.const);
|
|
364
|
+
}
|
|
365
|
+
if (describedCount !== 0 && describedCount !== variants.length) return; // mixed described/undescribed
|
|
366
|
+
// A shared branch description that disagrees with the union root's own
|
|
367
|
+
// description would be silently dropped by the collapse — keep the anyOf so
|
|
368
|
+
// neither annotation is lost. (Equal descriptions, the ArkType case, collapse.)
|
|
369
|
+
if (
|
|
370
|
+
describedCount === variants.length &&
|
|
371
|
+
typeof obj.description === "string" &&
|
|
372
|
+
obj.description !== branchDescription
|
|
373
|
+
) {
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
const scalarType = homogeneousEnumScalarType(values);
|
|
378
|
+
if (scalarType === undefined) return; // mixed / non-scalar (incl. null) — leave as anyOf
|
|
379
|
+
|
|
380
|
+
delete obj.anyOf;
|
|
381
|
+
obj.type = scalarType;
|
|
382
|
+
obj.enum = values;
|
|
383
|
+
if (typeof obj.description !== "string" && branchDescription !== undefined) {
|
|
384
|
+
obj.description = branchDescription;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
function walk(node: unknown): void {
|
|
389
|
+
if (Array.isArray(node)) {
|
|
390
|
+
for (const child of node) walk(child);
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
if (!node || typeof node !== "object") return;
|
|
394
|
+
const obj = node as Record<string, unknown>;
|
|
395
|
+
rewriteNullableScalarAnyOf(obj);
|
|
396
|
+
inferBareEnumScalarType(obj);
|
|
397
|
+
collapseConstUnionAnyOf(obj);
|
|
398
|
+
for (const k in obj) walk(obj[k]);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Normalize `{}` (an unconstrained schema) to boolean `true` in every
|
|
403
|
+
* schema-valued position. JSON Schema draft 2020-12 §4.3.1 defines them as
|
|
404
|
+
* semantically equivalent. Grammar-constrained samplers often treat the object
|
|
405
|
+
* form as "generate an empty object" rather than "any JSON value".
|
|
406
|
+
*
|
|
407
|
+
* Mutates in place and applies to every tool wire schema.
|
|
408
|
+
*/
|
|
409
|
+
export function normalizeEmptySchemas(node: unknown): void {
|
|
410
|
+
if (Array.isArray(node)) {
|
|
411
|
+
for (const child of node) normalizeEmptySchemas(child);
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
if (!node || typeof node !== "object") return;
|
|
415
|
+
const obj = node as Record<string, unknown>;
|
|
416
|
+
|
|
417
|
+
for (const key of SCHEMA_VALUE_KEYS) {
|
|
418
|
+
if (Object.hasOwn(obj, key) && isEmptyObject(obj[key])) obj[key] = true;
|
|
419
|
+
}
|
|
420
|
+
for (const mapKey of SCHEMA_MAP_KEYS) {
|
|
421
|
+
const map = obj[mapKey];
|
|
422
|
+
if (map !== null && typeof map === "object" && !Array.isArray(map)) {
|
|
423
|
+
for (const k in map as Record<string, unknown>) {
|
|
424
|
+
if (isEmptyObject((map as Record<string, unknown>)[k])) (map as Record<string, unknown>)[k] = true;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
for (const arrKey of SCHEMA_ARRAY_KEYS) {
|
|
429
|
+
const arr = obj[arrKey];
|
|
430
|
+
if (Array.isArray(arr)) {
|
|
431
|
+
for (let i = 0; i < arr.length; i++) {
|
|
432
|
+
if (isEmptyObject(arr[i])) arr[i] = true;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
for (const k in obj) normalizeEmptySchemas(obj[k]);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Recursively set `additionalProperties: false` on declared object nodes so the
|
|
442
|
+
* model-facing wire is closed. Only nodes that declare `properties` and carry
|
|
443
|
+
* neither `additionalProperties` nor `patternProperties` are closed.
|
|
444
|
+
*
|
|
445
|
+
* Traverses only schema-valued positions via the shared traversal-key constants
|
|
446
|
+
* so it never descends into `default`/`examples`/`enum`/`const` instance data.
|
|
447
|
+
*/
|
|
448
|
+
function closeDeclaredObjects(node: unknown): void {
|
|
449
|
+
if (Array.isArray(node)) {
|
|
450
|
+
for (const child of node) closeDeclaredObjects(child);
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
if (!node || typeof node !== "object") return;
|
|
454
|
+
const obj = node as Record<string, unknown>;
|
|
455
|
+
|
|
456
|
+
const isObjectType = obj.type === "object" || (Array.isArray(obj.type) && obj.type.includes("object"));
|
|
457
|
+
if (
|
|
458
|
+
isObjectType &&
|
|
459
|
+
obj.properties !== undefined &&
|
|
460
|
+
!("additionalProperties" in obj) &&
|
|
461
|
+
!("patternProperties" in obj)
|
|
462
|
+
) {
|
|
463
|
+
obj.additionalProperties = false;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
for (const key of SCHEMA_VALUE_KEYS) {
|
|
467
|
+
if (Object.hasOwn(obj, key)) closeDeclaredObjects(obj[key]);
|
|
468
|
+
}
|
|
469
|
+
for (const mapKey of SCHEMA_MAP_KEYS) {
|
|
470
|
+
const map = obj[mapKey];
|
|
471
|
+
if (map !== null && typeof map === "object" && !Array.isArray(map)) {
|
|
472
|
+
for (const k in map as Record<string, unknown>) closeDeclaredObjects((map as Record<string, unknown>)[k]);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
for (const arrKey of SCHEMA_ARRAY_KEYS) {
|
|
476
|
+
const arr = obj[arrKey];
|
|
477
|
+
if (Array.isArray(arr)) for (const child of arr) closeDeclaredObjects(child);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/** A subschema admitting any JSON value: `{}` or boolean `true` (draft 2020-12 §4.3.1). */
|
|
482
|
+
function isUnconstrainedSchema(val: unknown): boolean {
|
|
483
|
+
return val === true || isEmptyObject(val);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* ArkType-only: prune the unconstrained branch ArkType emits for a `T | undefined`
|
|
488
|
+
* value-union (e.g. `{ id: "string | undefined" }`).
|
|
489
|
+
*
|
|
490
|
+
* `undefined` has no JSON Schema form, so `arkToWireSchema`'s `fallback` degrades the
|
|
491
|
+
* `undefined` arm to the unconstrained empty schema, producing
|
|
492
|
+
* `{ anyOf: [{ type: "string" }, {}] }`. That bare `{}`/`true` combiner branch makes
|
|
493
|
+
* the property match any value; strict providers (OpenAI/Codex) reject it ("Invalid
|
|
494
|
+
* schema for function ..."), and `enforceStrictSchema` waves the non-object `true`
|
|
495
|
+
* branch straight through, so the break only surfaces server-side. This drops the
|
|
496
|
+
* unconstrained branch(es) from every ArkType-emitted `anyOf`/`oneOf` and inlines the
|
|
497
|
+
* lone remaining concrete branch (keeping sibling keywords like `description`).
|
|
498
|
+
*
|
|
499
|
+
* `required` is deliberately left untouched: ArkType validates a `T | undefined` key
|
|
500
|
+
* as required-present (an absent key is rejected at runtime), so the wire must keep the
|
|
501
|
+
* key required to stay consistent with runtime validation — demoting it to optional
|
|
502
|
+
* would let the model omit the key (or, under strict-mode nullable wrapping, send
|
|
503
|
+
* `null`) and then fail ArkType validation.
|
|
504
|
+
*
|
|
505
|
+
* Scoped to `arkToWireSchema` and run before `normalizeEmptySchemas` so the
|
|
506
|
+
* provider-agnostic `{}`→`true` pass (issue #1179) still preserves intentional open
|
|
507
|
+
* unions in Zod / raw-JSON tools. Traverses only schema-valued positions so it never
|
|
508
|
+
* descends into `default`/`examples`/`enum`/`const` instance data.
|
|
509
|
+
*/
|
|
510
|
+
function pruneArkUndefinedUnionBranches(node: unknown): void {
|
|
511
|
+
if (Array.isArray(node)) {
|
|
512
|
+
for (const child of node) pruneArkUndefinedUnionBranches(child);
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
if (!node || typeof node !== "object") return;
|
|
516
|
+
const obj = node as Record<string, unknown>;
|
|
517
|
+
|
|
518
|
+
for (const unionKey of ["anyOf", "oneOf"] as const) {
|
|
519
|
+
const branches = obj[unionKey];
|
|
520
|
+
if (!Array.isArray(branches)) continue;
|
|
521
|
+
const concrete = branches.filter(branch => !isUnconstrainedSchema(branch));
|
|
522
|
+
if (concrete.length === branches.length || concrete.length === 0) continue;
|
|
523
|
+
const only = concrete.length === 1 ? concrete[0] : undefined;
|
|
524
|
+
if (only !== undefined && isSchemaRecord(only)) {
|
|
525
|
+
delete obj[unionKey];
|
|
526
|
+
for (const key in only) {
|
|
527
|
+
if (!(key in obj)) obj[key] = only[key];
|
|
528
|
+
}
|
|
529
|
+
} else {
|
|
530
|
+
obj[unionKey] = concrete;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
for (const key of SCHEMA_VALUE_KEYS) {
|
|
535
|
+
if (Object.hasOwn(obj, key)) pruneArkUndefinedUnionBranches(obj[key]);
|
|
536
|
+
}
|
|
537
|
+
for (const mapKey of SCHEMA_MAP_KEYS) {
|
|
538
|
+
const map = obj[mapKey];
|
|
539
|
+
if (map !== null && typeof map === "object" && !Array.isArray(map)) {
|
|
540
|
+
for (const key in map as Record<string, unknown>) {
|
|
541
|
+
pruneArkUndefinedUnionBranches((map as Record<string, unknown>)[key]);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
for (const arrKey of SCHEMA_ARRAY_KEYS) {
|
|
546
|
+
const arr = obj[arrKey];
|
|
547
|
+
if (Array.isArray(arr)) for (const child of arr) pruneArkUndefinedUnionBranches(child);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* Convert an ArkType schema into the JSON Schema shape providers consume.
|
|
553
|
+
*/
|
|
554
|
+
export function arkToWireSchema(schema: Type): Record<string, unknown> {
|
|
555
|
+
return stamp(schema, kArkWireSchema, s => {
|
|
556
|
+
const raw = s.toJsonSchema({ target: "draft-2020-12", fallback: ctx => ctx.base }) as Record<string, unknown>;
|
|
557
|
+
delete raw.$schema;
|
|
558
|
+
pruneArkUndefinedUnionBranches(raw);
|
|
559
|
+
const upgraded = postProcessJsonSchema(upgradeJsonSchemaTo202012(raw) as Record<string, unknown>);
|
|
560
|
+
closeDeclaredObjects(upgraded);
|
|
561
|
+
return upgraded;
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* Resolve a tool's parameters to a JSON Schema object suitable for sending
|
|
567
|
+
* over the wire. ArkType schemas are converted and cached; legacy TypeBox /
|
|
568
|
+
* raw JSON Schema parameters are upgraded to draft 2020-12 and cached.
|
|
569
|
+
*/
|
|
570
|
+
export function toolWireSchema(tool: Tool): Record<string, unknown> {
|
|
571
|
+
const params: TSchema = tool.parameters;
|
|
572
|
+
if (isArkSchema(params)) return arkToWireSchema(params);
|
|
573
|
+
return stamp(params as Record<string, unknown>, kJsonWireSchema, p => {
|
|
574
|
+
const raw = isArkJsonAst(p) ? arkJsonAstToWire(p) : p;
|
|
575
|
+
const upgraded = upgradeJsonSchemaTo202012(raw) as Record<string, unknown>;
|
|
576
|
+
return postProcessJsonSchema(upgraded);
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Schema-valued keywords whose value is a single subschema (or an array of
|
|
582
|
+
* subschemas — the recursion dispatches on array-ness, so tuple forms like
|
|
583
|
+
* draft-07 `items: []` are handled too). Covers the draft 2020-12 surface plus
|
|
584
|
+
* the legacy `additionalItems` that may survive an incomplete upgrade.
|
|
585
|
+
*/
|
|
586
|
+
const STRIP_SCHEMA_VALUE_KEYS = [
|
|
587
|
+
"additionalProperties",
|
|
588
|
+
"unevaluatedProperties",
|
|
589
|
+
"unevaluatedItems",
|
|
590
|
+
"items",
|
|
591
|
+
"additionalItems",
|
|
592
|
+
"contains",
|
|
593
|
+
"propertyNames",
|
|
594
|
+
"contentSchema",
|
|
595
|
+
"if",
|
|
596
|
+
"then",
|
|
597
|
+
"else",
|
|
598
|
+
"not",
|
|
599
|
+
"anyOf",
|
|
600
|
+
"oneOf",
|
|
601
|
+
"allOf",
|
|
602
|
+
"prefixItems",
|
|
603
|
+
] as const;
|
|
604
|
+
|
|
605
|
+
/** Keywords whose value is a `{ name: Schema }` map — names are NOT annotations. */
|
|
606
|
+
const STRIP_SCHEMA_MAP_KEYS = ["properties", "patternProperties", "$defs", "definitions", "dependentSchemas"] as const;
|
|
607
|
+
|
|
608
|
+
/**
|
|
609
|
+
* Recursively strip human-readable `description` annotations from a JSON Schema,
|
|
610
|
+
* descending only through schema-valued keywords so a property literally named
|
|
611
|
+
* `"description"` inside a `properties`/`$defs` map keeps its schema (only its own
|
|
612
|
+
* annotation is dropped), and data-bearing keywords (`default`/`const`/`examples`)
|
|
613
|
+
* are never traversed. Mutates `node` in place — callers pass a clone.
|
|
614
|
+
*/
|
|
615
|
+
function stripSchemaDescriptionsInPlace(node: unknown): void {
|
|
616
|
+
if (Array.isArray(node)) {
|
|
617
|
+
for (const child of node) stripSchemaDescriptionsInPlace(child);
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
if (!isSchemaRecord(node)) return;
|
|
621
|
+
delete node.description;
|
|
622
|
+
for (const key of STRIP_SCHEMA_VALUE_KEYS) {
|
|
623
|
+
if (Object.hasOwn(node, key)) stripSchemaDescriptionsInPlace(node[key]);
|
|
624
|
+
}
|
|
625
|
+
for (const mapKey of STRIP_SCHEMA_MAP_KEYS) {
|
|
626
|
+
const map = node[mapKey];
|
|
627
|
+
if (isSchemaRecord(map)) {
|
|
628
|
+
for (const key in map) stripSchemaDescriptionsInPlace(map[key]);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
/**
|
|
634
|
+
* Return a deep clone of `schema` with every `description` annotation removed.
|
|
635
|
+
* The result is memoized on the input via a non-enumerable symbol (`stamp`) so
|
|
636
|
+
* repeated provider requests reuse the same stripped object; the input is never
|
|
637
|
+
* mutated, so the stamped `toolWireSchema` cache stays intact for
|
|
638
|
+
* system-prompt/UI rendering.
|
|
639
|
+
*/
|
|
640
|
+
export function stripSchemaDescriptions(schema: Record<string, unknown>): Record<string, unknown> {
|
|
641
|
+
return stamp(schema, kStrippedSchema, source => {
|
|
642
|
+
const clone = structuredClone(source);
|
|
643
|
+
stripSchemaDescriptionsInPlace(clone);
|
|
644
|
+
return clone;
|
|
645
|
+
});
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* Strip a tool's human-readable text from its provider-bound spec: empties the
|
|
650
|
+
* top-level `description` and removes nested schema `description` annotations.
|
|
651
|
+
* Used when the full tool catalog is rendered into the system prompt instead, so
|
|
652
|
+
* the descriptions ride the wire once (in the prompt) rather than duplicated on
|
|
653
|
+
* every tool definition. Parameters are resolved to wire JSON Schema and cloned,
|
|
654
|
+
* leaving the original tool objects and the stamped schema cache untouched.
|
|
655
|
+
*/
|
|
656
|
+
export function stripToolDescriptions(tools: readonly Tool[]): Tool[] {
|
|
657
|
+
return tools.map(tool => ({
|
|
658
|
+
...tool,
|
|
659
|
+
description: "",
|
|
660
|
+
parameters: stripSchemaDescriptions(toolWireSchema(tool)),
|
|
661
|
+
}));
|
|
662
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helpers for mapping `StreamOptions.streamFirstEventTimeoutMs` onto
|
|
3
|
+
* underlying SDK request-timeout options.
|
|
4
|
+
*
|
|
5
|
+
* The hint is intentionally not a watchdog — it just narrows the SDK's
|
|
6
|
+
* "transport timeout" window so a stuck pre-stream request fails fast
|
|
7
|
+
* instead of hanging on the default (often multi-minute) SDK timeout. Once
|
|
8
|
+
* the stream actually starts, silence is not failure; callers must abort
|
|
9
|
+
* to interrupt a quiet stream.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Coerce a caller-supplied `streamFirstEventTimeoutMs` into a positive integer suitable
|
|
14
|
+
* for the SDK's `timeout` option. Returns `undefined` when the caller passed nothing,
|
|
15
|
+
* a non-finite value, or a non-positive value (preserving the SDK's default).
|
|
16
|
+
*/
|
|
17
|
+
export function resolveSdkTimeoutMs(streamFirstEventTimeoutMs: number | undefined): number | undefined {
|
|
18
|
+
if (streamFirstEventTimeoutMs === undefined) return undefined;
|
|
19
|
+
if (!Number.isFinite(streamFirstEventTimeoutMs)) return undefined;
|
|
20
|
+
if (streamFirstEventTimeoutMs <= 0) return undefined;
|
|
21
|
+
return Math.trunc(streamFirstEventTimeoutMs);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Build per-request SDK options that combine an abort signal with the optional
|
|
26
|
+
* `streamFirstEventTimeoutMs` request-timeout hint.
|
|
27
|
+
*
|
|
28
|
+
* The returned `{ signal, timeout?, maxRetries? }` shape is compatible with both
|
|
29
|
+
* OpenAI's and Anthropic's `RequestOptions` (and any other SDK that follows the
|
|
30
|
+
* Stainless conventions), so callers from any of those providers can spread the
|
|
31
|
+
* result directly into `client.X.create(params, requestOptions)`.
|
|
32
|
+
*
|
|
33
|
+
* When the hint is set, retries are forced to zero so the SDK does not silently
|
|
34
|
+
* extend the caller's explicit deadline by re-attempting after a timeout.
|
|
35
|
+
*/
|
|
36
|
+
export function createSdkStreamRequestOptions(
|
|
37
|
+
signal: AbortSignal,
|
|
38
|
+
streamFirstEventTimeoutMs: number | undefined,
|
|
39
|
+
): { signal: AbortSignal; timeout?: number; maxRetries?: number } {
|
|
40
|
+
const timeout = resolveSdkTimeoutMs(streamFirstEventTimeoutMs);
|
|
41
|
+
if (timeout === undefined) return { signal };
|
|
42
|
+
return { signal, timeout, maxRetries: 0 };
|
|
43
|
+
}
|