jeopi-ai 16.2.13
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 +4347 -0
- package/README.md +1193 -0
- package/dist/types/api-registry.d.ts +30 -0
- package/dist/types/auth-broker/client.d.ts +73 -0
- package/dist/types/auth-broker/discover.d.ts +35 -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 +102 -0
- package/dist/types/auth-broker/server.d.ts +43 -0
- package/dist/types/auth-broker/snapshot-cache.d.ts +17 -0
- package/dist/types/auth-broker/types.d.ts +107 -0
- package/dist/types/auth-broker/wire-schemas.d.ts +411 -0
- package/dist/types/auth-gateway/http.d.ts +39 -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 +123 -0
- package/dist/types/auth-retry.d.ts +124 -0
- package/dist/types/auth-storage.d.ts +1026 -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 +23 -0
- package/dist/types/dialect/examples.d.ts +2 -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 +12 -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 +45 -0
- package/dist/types/dialect/thinking.d.ts +6 -0
- package/dist/types/dialect/types.d.ts +69 -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 +16 -0
- package/dist/types/error/auth.d.ts +27 -0
- package/dist/types/error/aws.d.ts +23 -0
- package/dist/types/error/classes.d.ts +102 -0
- package/dist/types/error/finalize.d.ts +39 -0
- package/dist/types/error/flags.d.ts +79 -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 +13 -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 +59 -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 +49 -0
- package/dist/types/provider-details.d.ts +24 -0
- package/dist/types/providers/__tests__/google-auth.test.d.ts +1 -0
- package/dist/types/providers/__tests__/kimi-code-thinking.test.d.ts +1 -0
- package/dist/types/providers/__tests__/openai-codex-error.test.d.ts +1 -0
- package/dist/types/providers/amazon-bedrock.d.ts +39 -0
- package/dist/types/providers/anthropic-client.d.ts +94 -0
- package/dist/types/providers/anthropic-messages-server-schema.d.ts +497 -0
- package/dist/types/providers/anthropic-messages-server.d.ts +17 -0
- package/dist/types/providers/anthropic-wire.d.ts +318 -0
- package/dist/types/providers/anthropic.d.ts +248 -0
- package/dist/types/providers/aws-credentials.d.ts +53 -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/cursor.d.ts +91 -0
- package/dist/types/providers/devin.d.ts +12 -0
- package/dist/types/providers/error-message.d.ts +27 -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 +32 -0
- package/dist/types/providers/google-gemini-cli.d.ts +118 -0
- package/dist/types/providers/google-interactions.d.ts +65 -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 +178 -0
- package/dist/types/providers/ollama.d.ts +7 -0
- package/dist/types/providers/openai-anthropic-shim.d.ts +31 -0
- package/dist/types/providers/openai-chat-server-schema.d.ts +695 -0
- package/dist/types/providers/openai-chat-server.d.ts +16 -0
- package/dist/types/providers/openai-chat-wire.d.ts +644 -0
- package/dist/types/providers/openai-codex/request-transformer.d.ts +54 -0
- package/dist/types/providers/openai-codex/response-handler.d.ts +26 -0
- package/dist/types/providers/openai-codex-responses.d.ts +108 -0
- package/dist/types/providers/openai-completions.d.ts +45 -0
- package/dist/types/providers/openai-reasoning-fallback.d.ts +25 -0
- package/dist/types/providers/openai-responses-server-schema.d.ts +349 -0
- package/dist/types/providers/openai-responses-server.d.ts +17 -0
- package/dist/types/providers/openai-responses-wire.d.ts +6065 -0
- package/dist/types/providers/openai-responses.d.ts +126 -0
- package/dist/types/providers/openai-shared.d.ts +506 -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 +32 -0
- package/dist/types/providers/synthetic.d.ts +26 -0
- package/dist/types/providers/transform-messages.d.ts +11 -0
- package/dist/types/providers/vision-guard.d.ts +20 -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/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/azure.d.ts +4 -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/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/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/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/nvidia.d.ts +7 -0
- package/dist/types/registry/oauth/__tests__/xai-oauth.test.d.ts +1 -0
- package/dist/types/registry/oauth/anthropic.d.ts +23 -0
- package/dist/types/registry/oauth/callback-server.d.ts +72 -0
- package/dist/types/registry/oauth/cursor.d.ts +15 -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 +10 -0
- package/dist/types/registry/oauth/google-oauth-shared.d.ts +22 -0
- package/dist/types/registry/oauth/index.d.ts +64 -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 +56 -0
- package/dist/types/registry/oauth/wafer.d.ts +1 -0
- package/dist/types/registry/oauth/xai-oauth.d.ts +52 -0
- package/dist/types/registry/oauth/xiaomi.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 +303 -0
- package/dist/types/registry/sakana.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 +51 -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 +4 -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 +7 -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 +44 -0
- package/dist/types/types.d.ts +715 -0
- package/dist/types/usage/claude.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 +2 -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 +79 -0
- package/dist/types/usage/openai-codex.d.ts +3 -0
- package/dist/types/usage/opencode-go.d.ts +2 -0
- package/dist/types/usage/shared.d.ts +1 -0
- package/dist/types/usage/zai.d.ts +2 -0
- package/dist/types/usage.d.ts +346 -0
- package/dist/types/utils/abort.d.ts +25 -0
- package/dist/types/utils/anthropic-auth.d.ts +35 -0
- package/dist/types/utils/block-symbols.d.ts +20 -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 +30 -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 +118 -0
- package/dist/types/utils/http-inspector.d.ts +30 -0
- package/dist/types/utils/idle-iterator.d.ts +137 -0
- package/dist/types/utils/leaked-thinking-stream.d.ts +29 -0
- package/dist/types/utils/openai-http.d.ts +54 -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 +29 -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 +15 -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 +124 -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 +18 -0
- package/dist/types/utils/schema/wire.d.ts +92 -0
- package/dist/types/utils/schema/zod-decontaminate.d.ts +31 -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 +50 -0
- package/dist/types/utils/validation.d.ts +42 -0
- package/dist/types/utils.d.ts +24 -0
- package/package.json +139 -0
- package/src/api-registry.ts +109 -0
- package/src/auth-broker/client.ts +359 -0
- package/src/auth-broker/discover.ts +222 -0
- package/src/auth-broker/index.ts +7 -0
- package/src/auth-broker/refresher.ts +117 -0
- package/src/auth-broker/remote-store.ts +657 -0
- package/src/auth-broker/server.ts +646 -0
- package/src/auth-broker/snapshot-cache.ts +191 -0
- package/src/auth-broker/types.ts +130 -0
- package/src/auth-broker/wire-schemas.ts +249 -0
- package/src/auth-gateway/http.ts +194 -0
- package/src/auth-gateway/index.ts +3 -0
- package/src/auth-gateway/server.ts +802 -0
- package/src/auth-gateway/types.ts +151 -0
- package/src/auth-retry.ts +250 -0
- package/src/auth-storage.ts +5576 -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 +36 -0
- package/src/dialect/examples.ts +33 -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 +597 -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 +456 -0
- package/src/dialect/harmony.md +31 -0
- package/src/dialect/harmony.ts +346 -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 +73 -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 +470 -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 +249 -0
- package/src/dialect/thinking.ts +122 -0
- package/src/dialect/types.ts +57 -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 +30 -0
- package/src/error/auth.ts +48 -0
- package/src/error/aws.ts +31 -0
- package/src/error/classes.ts +186 -0
- package/src/error/finalize.ts +69 -0
- package/src/error/flags.ts +506 -0
- package/src/error/format.ts +45 -0
- package/src/error/gateway.ts +96 -0
- package/src/error/index.ts +13 -0
- package/src/error/oauth.ts +58 -0
- package/src/error/provider.ts +62 -0
- package/src/error/rate-limit.ts +161 -0
- package/src/error/retryable.ts +70 -0
- package/src/error/validation.ts +44 -0
- package/src/index.ts +49 -0
- package/src/provider-details.ts +90 -0
- package/src/providers/__tests__/google-auth.test.ts +144 -0
- package/src/providers/__tests__/kimi-code-thinking.test.ts +112 -0
- package/src/providers/__tests__/openai-codex-error.test.ts +84 -0
- package/src/providers/amazon-bedrock.ts +1042 -0
- package/src/providers/anthropic-client.ts +295 -0
- package/src/providers/anthropic-messages-server-schema.ts +252 -0
- package/src/providers/anthropic-messages-server.ts +756 -0
- package/src/providers/anthropic-wire.ts +318 -0
- package/src/providers/anthropic.ts +4078 -0
- package/src/providers/aws-credentials.ts +586 -0
- package/src/providers/aws-eventstream.ts +181 -0
- package/src/providers/aws-sigv4.ts +218 -0
- package/src/providers/azure-openai-responses.ts +382 -0
- package/src/providers/cursor/proto/agent.proto +3526 -0
- package/src/providers/cursor/proto/buf.gen.yaml +6 -0
- package/src/providers/cursor/proto/buf.yaml +17 -0
- package/src/providers/cursor.ts +2695 -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 +577 -0
- package/src/providers/error-message.ts +21 -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 +3058 -0
- package/src/providers/gitlab-duo.ts +395 -0
- package/src/providers/google-auth.ts +350 -0
- package/src/providers/google-gemini-cli.ts +1362 -0
- package/src/providers/google-interactions.ts +753 -0
- package/src/providers/google-shared.ts +1103 -0
- package/src/providers/google-types.ts +180 -0
- package/src/providers/google-vertex.ts +183 -0
- package/src/providers/google.ts +87 -0
- package/src/providers/grammar.ts +70 -0
- package/src/providers/kimi.ts +52 -0
- package/src/providers/mock.ts +507 -0
- package/src/providers/ollama.ts +773 -0
- package/src/providers/openai-anthropic-shim.ts +152 -0
- package/src/providers/openai-chat-server-schema.ts +242 -0
- package/src/providers/openai-chat-server.ts +715 -0
- package/src/providers/openai-chat-wire.ts +847 -0
- package/src/providers/openai-codex/request-transformer.ts +295 -0
- package/src/providers/openai-codex/response-handler.ts +102 -0
- package/src/providers/openai-codex-responses.ts +3468 -0
- package/src/providers/openai-completions.ts +2173 -0
- package/src/providers/openai-reasoning-fallback.ts +269 -0
- package/src/providers/openai-responses-reasoning-suppression.md +1 -0
- package/src/providers/openai-responses-server-schema.ts +282 -0
- package/src/providers/openai-responses-server.ts +1280 -0
- package/src/providers/openai-responses-wire.ts +6391 -0
- package/src/providers/openai-responses.ts +1022 -0
- package/src/providers/openai-shared.ts +2648 -0
- package/src/providers/pi-native-client.ts +266 -0
- package/src/providers/pi-native-server.ts +242 -0
- package/src/providers/register-builtins.ts +475 -0
- package/src/providers/synthetic.ts +50 -0
- package/src/providers/transform-messages.ts +787 -0
- package/src/providers/vision-guard.ts +54 -0
- package/src/registry/aimlapi.ts +6 -0
- package/src/registry/alibaba-coding-plan.ts +95 -0
- package/src/registry/amazon-bedrock.ts +22 -0
- package/src/registry/anthropic.ts +26 -0
- package/src/registry/api-key-login.ts +112 -0
- package/src/registry/api-key-validation.ts +161 -0
- package/src/registry/azure.ts +6 -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/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/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/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 +22 -0
- package/src/registry/nanogpt.ts +22 -0
- package/src/registry/nvidia.ts +61 -0
- package/src/registry/oauth/__tests__/xai-oauth.test.ts +104 -0
- package/src/registry/oauth/anthropic.ts +311 -0
- package/src/registry/oauth/callback-server.ts +315 -0
- package/src/registry/oauth/cursor.ts +171 -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 +209 -0
- package/src/registry/oauth/google-gemini-cli.ts +273 -0
- package/src/registry/oauth/google-oauth-shared.ts +125 -0
- package/src/registry/oauth/index.ts +269 -0
- package/src/registry/oauth/kimi.ts +289 -0
- package/src/registry/oauth/minimax-code.ts +53 -0
- package/src/registry/oauth/oauth.html +311 -0
- package/src/registry/oauth/openai-codex.ts +364 -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 +65 -0
- package/src/registry/oauth/wafer.ts +24 -0
- package/src/registry/oauth/xai-oauth.ts +394 -0
- package/src/registry/oauth/xiaomi.ts +211 -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 +161 -0
- package/src/registry/sakana.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 +56 -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 +6 -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 +27 -0
- package/src/registry/zenmux.ts +22 -0
- package/src/registry/zhipu-coding-plan.ts +27 -0
- package/src/stream.ts +1778 -0
- package/src/types.ts +856 -0
- package/src/usage/claude.ts +485 -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 +271 -0
- package/src/usage/minimax-code.ts +30 -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 +174 -0
- package/src/usage/openai-codex.ts +535 -0
- package/src/usage/opencode-go.ts +89 -0
- package/src/usage/shared.ts +10 -0
- package/src/usage/zai.ts +321 -0
- package/src/usage.ts +333 -0
- package/src/utils/abort.ts +67 -0
- package/src/utils/anthropic-auth.ts +93 -0
- package/src/utils/block-symbols.ts +32 -0
- package/src/utils/deterministic-id.ts +20 -0
- package/src/utils/empty-completion-retry.ts +159 -0
- package/src/utils/event-stream.ts +171 -0
- package/src/utils/foundry.ts +8 -0
- package/src/utils/google-validation.ts +25 -0
- package/src/utils/harmony-leak.ts +456 -0
- package/src/utils/http-inspector.ts +168 -0
- package/src/utils/idle-iterator.ts +473 -0
- package/src/utils/leaked-thinking-stream.ts +294 -0
- package/src/utils/openai-http.ts +122 -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 +240 -0
- package/src/utils/request-debug.ts +351 -0
- package/src/utils/retry-after.ts +110 -0
- package/src/utils/retry.ts +59 -0
- package/src/utils/schema/CONSTRAINTS.md +166 -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 +207 -0
- package/src/utils/schema/index.ts +15 -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 +1901 -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 +198 -0
- package/src/utils/schema/wire.ts +789 -0
- package/src/utils/schema/zod-decontaminate.ts +331 -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 +99 -0
- package/src/utils/validation.ts +1507 -0
- package/src/utils.ts +171 -0
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defensive rewrite for nodes that look like `JSON.stringify(zodSchemaInstance)`
|
|
3
|
+
* output rather than JSON Schema. MCP servers using Zod 4 sometimes ship a
|
|
4
|
+
* serialised schema instance directly as a tool's `inputSchema`, because the
|
|
5
|
+
* fields Zod surfaces on its instances (`type`, `enum`, `options`, `def`) shadow
|
|
6
|
+
* (and clash with) JSON Schema keywords. The resulting payload is neither valid
|
|
7
|
+
* Zod nor valid JSON Schema 2020-12 and Anthropic's strict validator rejects
|
|
8
|
+
* the whole tool list.
|
|
9
|
+
*
|
|
10
|
+
* Symptoms we've observed (gitnexus_impact.direction):
|
|
11
|
+
* {
|
|
12
|
+
* def: { type: "enum", entries: { upstream: "upstream", ... } },
|
|
13
|
+
* type: "enum", // <- invalid `type` value
|
|
14
|
+
* enum: { upstream: "upstream", ... }, // <- `enum` MUST be an array
|
|
15
|
+
* options: ["upstream", "downstream"],
|
|
16
|
+
* }
|
|
17
|
+
*
|
|
18
|
+
* This module recognises the shape (`def.type === node.type` and `def.type` is
|
|
19
|
+
* a known Zod kind) and rewrites it to clean JSON Schema where deterministic.
|
|
20
|
+
* For Zod kinds we don't fully model, we strip the toxic siblings (`def`,
|
|
21
|
+
* `options`, object-shaped `enum`) and drop an invalid `type` so the remainder
|
|
22
|
+
* passes meta-schema validation as a permissive node.
|
|
23
|
+
*
|
|
24
|
+
* Pure / identity-preserving: returns the input reference when nothing changes.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { isJsonObject, type JsonObject } from "./types";
|
|
28
|
+
|
|
29
|
+
const VALID_JSON_SCHEMA_TYPES: Record<string, true> = {
|
|
30
|
+
string: true,
|
|
31
|
+
number: true,
|
|
32
|
+
integer: true,
|
|
33
|
+
boolean: true,
|
|
34
|
+
object: true,
|
|
35
|
+
array: true,
|
|
36
|
+
null: true,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Known Zod 4 schema kinds as surfaced on `_def.type` / `.type`. Matching this
|
|
41
|
+
* set (rather than just "has `def`") is what keeps us from rewriting legitimate
|
|
42
|
+
* JSON Schemas that happen to use `def` as a property name.
|
|
43
|
+
*/
|
|
44
|
+
const ZOD_KINDS: Record<string, true> = {
|
|
45
|
+
string: true,
|
|
46
|
+
number: true,
|
|
47
|
+
int: true,
|
|
48
|
+
boolean: true,
|
|
49
|
+
bigint: true,
|
|
50
|
+
null: true,
|
|
51
|
+
undefined: true,
|
|
52
|
+
void: true,
|
|
53
|
+
any: true,
|
|
54
|
+
unknown: true,
|
|
55
|
+
never: true,
|
|
56
|
+
date: true,
|
|
57
|
+
symbol: true,
|
|
58
|
+
nan: true,
|
|
59
|
+
enum: true,
|
|
60
|
+
literal: true,
|
|
61
|
+
object: true,
|
|
62
|
+
array: true,
|
|
63
|
+
tuple: true,
|
|
64
|
+
record: true,
|
|
65
|
+
map: true,
|
|
66
|
+
set: true,
|
|
67
|
+
union: true,
|
|
68
|
+
discriminatedUnion: true,
|
|
69
|
+
intersection: true,
|
|
70
|
+
lazy: true,
|
|
71
|
+
promise: true,
|
|
72
|
+
function: true,
|
|
73
|
+
file: true,
|
|
74
|
+
custom: true,
|
|
75
|
+
template_literal: true,
|
|
76
|
+
optional: true,
|
|
77
|
+
nullable: true,
|
|
78
|
+
default: true,
|
|
79
|
+
prefault: true,
|
|
80
|
+
catch: true,
|
|
81
|
+
pipe: true,
|
|
82
|
+
transform: true,
|
|
83
|
+
brand: true,
|
|
84
|
+
readonly: true,
|
|
85
|
+
success: true,
|
|
86
|
+
nonoptional: true,
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const ZOD_SCALAR_TO_JSON_TYPE: Record<string, string> = {
|
|
90
|
+
string: "string",
|
|
91
|
+
number: "number",
|
|
92
|
+
int: "integer",
|
|
93
|
+
boolean: "boolean",
|
|
94
|
+
null: "null",
|
|
95
|
+
bigint: "string",
|
|
96
|
+
date: "string",
|
|
97
|
+
nan: "number",
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const ZOD_NOISE_KEYS: Record<string, true> = {
|
|
101
|
+
def: true,
|
|
102
|
+
options: true,
|
|
103
|
+
_zod: true,
|
|
104
|
+
checks: true,
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* JSON Schema keywords where `null` is a legal value (literal payload positions).
|
|
109
|
+
* Anywhere else, a `null`-valued key is a meta-schema violation — Zod scalars
|
|
110
|
+
* leak `format: null`, `minLength: null`, etc. that we have to scrub.
|
|
111
|
+
*/
|
|
112
|
+
const KEYS_THAT_ACCEPT_NULL: Record<string, true> = {
|
|
113
|
+
default: true,
|
|
114
|
+
const: true,
|
|
115
|
+
examples: true,
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
function isZodLeak(node: JsonObject): boolean {
|
|
119
|
+
const def = node.def;
|
|
120
|
+
if (!isJsonObject(def)) return false;
|
|
121
|
+
const defType = def.type;
|
|
122
|
+
if (typeof defType !== "string" || !ZOD_KINDS[defType]) return false;
|
|
123
|
+
// Both surface and inner `.type` must agree — Zod always mirrors `_def.type`
|
|
124
|
+
// onto the instance, so this is a near-zero false-positive guard.
|
|
125
|
+
return node.type === defType;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function inferTypeFromValues(values: readonly unknown[]): string {
|
|
129
|
+
if (values.length === 0) return "string";
|
|
130
|
+
const first = values[0];
|
|
131
|
+
if (typeof first === "number") return Number.isInteger(first) ? "integer" : "number";
|
|
132
|
+
if (typeof first === "boolean") return "boolean";
|
|
133
|
+
if (first === null) return "null";
|
|
134
|
+
return "string";
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function unwrapInnerSchema(def: JsonObject): unknown {
|
|
138
|
+
// Zod uses different fields depending on the wrapper:
|
|
139
|
+
// optional/nullable/readonly/brand/default → `innerType`
|
|
140
|
+
// pipe → `in` (or `out`)
|
|
141
|
+
// lazy → `getter` (a function — gone after JSON.stringify); fall back to {}
|
|
142
|
+
return def.innerType ?? def.in ?? def.out ?? def.schema ?? def.element ?? {};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function copyWithoutNoise(node: JsonObject): JsonObject {
|
|
146
|
+
const out: JsonObject = {};
|
|
147
|
+
for (const key in node) {
|
|
148
|
+
if (ZOD_NOISE_KEYS[key]) continue;
|
|
149
|
+
const value = node[key];
|
|
150
|
+
if (value === null && !KEYS_THAT_ACCEPT_NULL[key]) continue;
|
|
151
|
+
out[key] = value;
|
|
152
|
+
}
|
|
153
|
+
return out;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function rewriteZodNode(node: JsonObject, seen: WeakSet<object>): unknown {
|
|
157
|
+
const def = node.def as JsonObject;
|
|
158
|
+
const kind = def.type as string;
|
|
159
|
+
|
|
160
|
+
switch (kind) {
|
|
161
|
+
case "enum": {
|
|
162
|
+
// Prefer node.options (array form Zod exposes) → def.entries values →
|
|
163
|
+
// object-shaped node.enum values. All three carry the same data.
|
|
164
|
+
const optionsArray = Array.isArray(node.options) ? (node.options as unknown[]) : null;
|
|
165
|
+
const entries = isJsonObject(def.entries) ? Object.values(def.entries) : null;
|
|
166
|
+
const enumObj = isJsonObject(node.enum) ? Object.values(node.enum) : null;
|
|
167
|
+
const values = optionsArray ?? entries ?? enumObj ?? [];
|
|
168
|
+
return { type: inferTypeFromValues(values), enum: values };
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
case "literal": {
|
|
172
|
+
const values = Array.isArray(def.values) ? (def.values as unknown[]) : [];
|
|
173
|
+
if (values.length === 1) {
|
|
174
|
+
return { const: values[0] };
|
|
175
|
+
}
|
|
176
|
+
if (values.length > 1) {
|
|
177
|
+
return { type: inferTypeFromValues(values), enum: values };
|
|
178
|
+
}
|
|
179
|
+
return {};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
case "union":
|
|
183
|
+
case "discriminatedUnion": {
|
|
184
|
+
const arms = Array.isArray(def.options)
|
|
185
|
+
? (def.options as unknown[])
|
|
186
|
+
: Array.isArray(node.options)
|
|
187
|
+
? (node.options as unknown[])
|
|
188
|
+
: [];
|
|
189
|
+
return { anyOf: arms.map(x => walk(x, seen)) };
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
case "intersection": {
|
|
193
|
+
return {
|
|
194
|
+
allOf: [walk(def.left, seen), walk(def.right, seen)],
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
case "array": {
|
|
199
|
+
return { type: "array", items: walk(def.element, seen) };
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
case "set": {
|
|
203
|
+
const element = def.valueType ?? def.element;
|
|
204
|
+
return { type: "array", uniqueItems: true, items: walk(element, seen) };
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
case "tuple": {
|
|
208
|
+
const items = Array.isArray(def.items) ? (def.items as unknown[]) : [];
|
|
209
|
+
const out: JsonObject = { type: "array", prefixItems: items.map(x => walk(x, seen)) };
|
|
210
|
+
const rest = def.rest;
|
|
211
|
+
if (rest != null) out.items = walk(rest, seen);
|
|
212
|
+
return out;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
case "record":
|
|
216
|
+
case "map": {
|
|
217
|
+
return { type: "object", additionalProperties: walk(def.valueType, seen) };
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
case "object": {
|
|
221
|
+
const shape = isJsonObject(def.shape) ? def.shape : ({} as JsonObject);
|
|
222
|
+
const properties: JsonObject = {};
|
|
223
|
+
const required: string[] = [];
|
|
224
|
+
for (const key in shape) {
|
|
225
|
+
const inner = walk(shape[key], seen);
|
|
226
|
+
properties[key] = inner;
|
|
227
|
+
if (!isOptionalEntry(shape[key])) required.push(key);
|
|
228
|
+
}
|
|
229
|
+
const out: JsonObject = { type: "object", properties };
|
|
230
|
+
if (required.length > 0) out.required = required;
|
|
231
|
+
return out;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
case "nonoptional":
|
|
235
|
+
case "optional":
|
|
236
|
+
case "nullable":
|
|
237
|
+
case "default":
|
|
238
|
+
case "prefault":
|
|
239
|
+
case "catch":
|
|
240
|
+
case "readonly":
|
|
241
|
+
case "brand":
|
|
242
|
+
case "lazy":
|
|
243
|
+
case "pipe":
|
|
244
|
+
case "transform": {
|
|
245
|
+
const inner = walk(unwrapInnerSchema(def), seen);
|
|
246
|
+
if (kind === "nullable" && isJsonObject(inner)) {
|
|
247
|
+
if (typeof inner.type === "string") {
|
|
248
|
+
return { ...inner, type: [inner.type, "null"] };
|
|
249
|
+
}
|
|
250
|
+
if (Array.isArray(inner.type)) {
|
|
251
|
+
return (inner.type as string[]).includes("null")
|
|
252
|
+
? inner
|
|
253
|
+
: { ...inner, type: [...(inner.type as string[]), "null"] };
|
|
254
|
+
}
|
|
255
|
+
// anyOf / allOf / $ref shapes — no scalar `type` field
|
|
256
|
+
return { anyOf: [inner, { type: "null" }] };
|
|
257
|
+
}
|
|
258
|
+
return inner;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
default: {
|
|
262
|
+
// Best-effort: drop the noise, map the kind to a JSON Schema type if
|
|
263
|
+
// we know one, otherwise drop `type` so the node validates as
|
|
264
|
+
// permissive.
|
|
265
|
+
const cleaned = copyWithoutNoise(node);
|
|
266
|
+
const mapped = ZOD_SCALAR_TO_JSON_TYPE[kind];
|
|
267
|
+
if (mapped) {
|
|
268
|
+
cleaned.type = mapped;
|
|
269
|
+
} else if (typeof cleaned.type === "string" && !VALID_JSON_SCHEMA_TYPES[cleaned.type]) {
|
|
270
|
+
delete cleaned.type;
|
|
271
|
+
}
|
|
272
|
+
// Object-shaped `enum` survives as a noise field — remove if present.
|
|
273
|
+
if (cleaned.enum !== undefined && !Array.isArray(cleaned.enum)) {
|
|
274
|
+
delete cleaned.enum;
|
|
275
|
+
}
|
|
276
|
+
return cleaned;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function isOptionalEntry(value: unknown): boolean {
|
|
282
|
+
if (!isJsonObject(value)) return false;
|
|
283
|
+
if (!isZodLeak(value)) return false;
|
|
284
|
+
const kind = (value.def as JsonObject).type;
|
|
285
|
+
return kind === "optional" || kind === "default" || kind === "prefault";
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Walks a JSON value and rewrites every Zod-instance-shaped node into clean
|
|
290
|
+
* JSON Schema 2020-12. Identity-preserving when no rewrite fires. Tolerates
|
|
291
|
+
* self-referential graphs — a revisited node returns as-is.
|
|
292
|
+
*/
|
|
293
|
+
export function decontaminateZodInstance(value: unknown): unknown {
|
|
294
|
+
return walk(value, new WeakSet());
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function walk(value: unknown, seen: WeakSet<object>): unknown {
|
|
298
|
+
if (Array.isArray(value)) {
|
|
299
|
+
if (seen.has(value)) return value;
|
|
300
|
+
seen.add(value);
|
|
301
|
+
let changed = false;
|
|
302
|
+
const out = value.map(entry => {
|
|
303
|
+
const rewritten = walk(entry, seen);
|
|
304
|
+
if (rewritten !== entry) changed = true;
|
|
305
|
+
return rewritten;
|
|
306
|
+
});
|
|
307
|
+
return changed ? out : value;
|
|
308
|
+
}
|
|
309
|
+
if (!isJsonObject(value)) return value;
|
|
310
|
+
if (seen.has(value)) return value;
|
|
311
|
+
seen.add(value);
|
|
312
|
+
|
|
313
|
+
if (isZodLeak(value)) {
|
|
314
|
+
// Rewrite the node itself, then recurse into the rewrite so any nested
|
|
315
|
+
// Zod-instance children get cleaned in the same pass.
|
|
316
|
+
const rewritten = rewriteZodNode(value, seen);
|
|
317
|
+
return rewritten === value ? value : walk(rewritten, seen);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Plain JSON Schema node: recurse into children, preserving identity when
|
|
321
|
+
// nothing under us changed.
|
|
322
|
+
let changed = false;
|
|
323
|
+
const out: JsonObject = {};
|
|
324
|
+
for (const key in value) {
|
|
325
|
+
const child = value[key];
|
|
326
|
+
const rewritten = walk(child, seen);
|
|
327
|
+
if (rewritten !== child) changed = true;
|
|
328
|
+
out[key] = rewritten;
|
|
329
|
+
}
|
|
330
|
+
return changed ? out : value;
|
|
331
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ServerSentEvent } from "jeopi-utils";
|
|
2
|
+
import type { RawSseEvent } from "../types";
|
|
3
|
+
|
|
4
|
+
type RawSseObserver = (event: RawSseEvent) => void;
|
|
5
|
+
|
|
6
|
+
export function notifyRawSseEvent(observer: RawSseObserver | undefined, event: ServerSentEvent | RawSseEvent): void {
|
|
7
|
+
if (!observer) return;
|
|
8
|
+
try {
|
|
9
|
+
// Pass the event through without cloning `raw`. The only wired observer
|
|
10
|
+
// (`RawSseDebugBuffer.recordEvent`) treats `raw` as owned and never
|
|
11
|
+
// mutates it; new observers must adhere to the same contract.
|
|
12
|
+
// `ServerSentEvent` and `RawSseEvent` are structurally identical
|
|
13
|
+
// (`event: string | null`, `data: string`, `raw: string[]`).
|
|
14
|
+
observer(event as RawSseEvent);
|
|
15
|
+
} catch {
|
|
16
|
+
// Raw stream observers are diagnostic only and must not affect generation.
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Streaming-safe filters for leaked chat-template tool-call and thinking markup.
|
|
3
|
+
*
|
|
4
|
+
* Hosted models sometimes leak raw template markup into visible `content` instead
|
|
5
|
+
* of returning structured events. Tool-call healing delegates to the same
|
|
6
|
+
* dialect scanners used by owned in-band tool calling; this file keeps the
|
|
7
|
+
* provider-facing compatibility wrapper and model/provider gating.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { isDeepseekModelIdOrName } from "jeopi-catalog/identity";
|
|
11
|
+
|
|
12
|
+
import { createInbandScanner } from "../dialect/factory";
|
|
13
|
+
import { ThinkingInbandScanner } from "../dialect/thinking";
|
|
14
|
+
import type { InbandScanEvent, InbandScanner } from "../dialect/types";
|
|
15
|
+
|
|
16
|
+
const KIMI_SECTION_END = "<|tool_calls_section_end|>";
|
|
17
|
+
const DSML_TOOL_CALLS_CLOSE_FULLWIDTH = "</|DSML|tool_calls>";
|
|
18
|
+
const DSML_TOOL_CALLS_CLOSE_ASCII = "</|DSML|tool_calls>";
|
|
19
|
+
|
|
20
|
+
export interface HealedToolCall {
|
|
21
|
+
readonly id: string;
|
|
22
|
+
readonly name: string;
|
|
23
|
+
readonly arguments: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type StreamMarkupHealingPattern = "kimi" | "dsml" | "thinking";
|
|
27
|
+
|
|
28
|
+
export interface StreamMarkupHealingOptions {
|
|
29
|
+
readonly pattern: StreamMarkupHealingPattern;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type StreamMarkupHealingEvent =
|
|
33
|
+
| { readonly type: "text"; readonly text: string }
|
|
34
|
+
| { readonly type: "thinking"; readonly thinking: string }
|
|
35
|
+
| { readonly type: "toolCall"; readonly call: HealedToolCall };
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* State machine that consumes streamed visible text and emits cleaned text,
|
|
39
|
+
* thinking deltas, and reconstructed tool calls.
|
|
40
|
+
*
|
|
41
|
+
* A {@link ThinkingInbandScanner} always heals leaked reasoning idioms
|
|
42
|
+
* (`<think>`, `<thinking>`, ` ```thinking `, Gemma/Harmony channels, …) out of
|
|
43
|
+
* the visible channel. For Kimi / DeepSeek-DSML the provider tool-call grammar
|
|
44
|
+
* runs first and its cleaned text is piped through that thinking healer, so a
|
|
45
|
+
* model can leak tool-call markup and reasoning in the same stream.
|
|
46
|
+
*
|
|
47
|
+
* Feed only one stream channel (usually `delta.content` / `message.content`).
|
|
48
|
+
* Mixing reasoning and visible text into the same instance can corrupt held-back
|
|
49
|
+
* partial tag buffers.
|
|
50
|
+
*/
|
|
51
|
+
export class StreamMarkupHealing {
|
|
52
|
+
readonly #pattern: StreamMarkupHealingPattern;
|
|
53
|
+
/** Provider tool-call grammar (Kimi tokens / DSML envelope); absent for plain text streams. */
|
|
54
|
+
readonly #toolScanner: InbandScanner | undefined;
|
|
55
|
+
/** Always-on healer for leaked reasoning idioms in the visible text channel. */
|
|
56
|
+
readonly #thinkingScanner = new ThinkingInbandScanner();
|
|
57
|
+
#sectionTerminated = false;
|
|
58
|
+
readonly #completed: HealedToolCall[] = [];
|
|
59
|
+
|
|
60
|
+
constructor(options: StreamMarkupHealingOptions) {
|
|
61
|
+
this.#pattern = options.pattern;
|
|
62
|
+
this.#toolScanner =
|
|
63
|
+
options.pattern === "kimi"
|
|
64
|
+
? createInbandScanner("kimi")
|
|
65
|
+
: options.pattern === "dsml"
|
|
66
|
+
? createInbandScanner("xml", { xmlTagset: "dsml" })
|
|
67
|
+
: undefined;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
get pattern(): StreamMarkupHealingPattern {
|
|
71
|
+
return this.#pattern;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Feed a chunk and return visible text only. Reconstructed tool calls are
|
|
76
|
+
* stored for {@link drainCompleted}; thinking blocks are intentionally not
|
|
77
|
+
* returned by this compatibility helper. Use {@link feedEvents} when the caller
|
|
78
|
+
* needs ordered text/thinking/tool-call events.
|
|
79
|
+
*/
|
|
80
|
+
feed(text: string): string {
|
|
81
|
+
let clean = "";
|
|
82
|
+
for (const event of this.feedEvents(text)) {
|
|
83
|
+
if (event.type === "text") {
|
|
84
|
+
clean += event.text;
|
|
85
|
+
} else if (event.type === "toolCall") {
|
|
86
|
+
this.#completed.push(event.call);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return clean;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Feed a chunk and return cleaned text/thinking/tool-call events in stream order. */
|
|
93
|
+
feedEvents(text: string): StreamMarkupHealingEvent[] {
|
|
94
|
+
if (text.length === 0) return [];
|
|
95
|
+
this.#markSectionClosed(text);
|
|
96
|
+
if (!this.#toolScanner) return this.#convertScannerEvents(this.#thinkingScanner.feed(text));
|
|
97
|
+
return this.#convertScannerEvents(this.#healThinking(this.#toolScanner.feed(text)));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Feed a chunk and return cleaned events, excluding synthesized tool calls.
|
|
102
|
+
* Used when the upstream chunk also carries structured `tool_calls`, keeping
|
|
103
|
+
* that structured payload as the single source of truth while preserving
|
|
104
|
+
* adjacent text and thinking events.
|
|
105
|
+
*/
|
|
106
|
+
feedEventsWithoutCalls(text: string): StreamMarkupHealingEvent[] {
|
|
107
|
+
const events = this.feedEvents(text);
|
|
108
|
+
let out: StreamMarkupHealingEvent[] | undefined;
|
|
109
|
+
for (let i = 0; i < events.length; i++) {
|
|
110
|
+
const event = events[i]!;
|
|
111
|
+
if (event.type === "toolCall") {
|
|
112
|
+
out ??= events.slice(0, i);
|
|
113
|
+
} else if (out) {
|
|
114
|
+
out.push(event);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return out ?? events;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Drain accumulated tool calls from calls to {@link feed}. */
|
|
121
|
+
drainCompleted(): HealedToolCall[] {
|
|
122
|
+
if (this.#completed.length === 0) return [];
|
|
123
|
+
return this.#completed.splice(0, this.#completed.length);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Flush held-back stream-end fragments as ordered events. Partial tool-call
|
|
128
|
+
* sections/envelopes are dropped by the delegated scanners; unterminated
|
|
129
|
+
* thinking blocks are emitted as thinking, matching the previous MiniMax parser
|
|
130
|
+
* behavior.
|
|
131
|
+
*/
|
|
132
|
+
flushEvents(): StreamMarkupHealingEvent[] {
|
|
133
|
+
const tail = this.#toolScanner ? this.#healThinking(this.#toolScanner.flush()) : [];
|
|
134
|
+
tail.push(...this.#thinkingScanner.flush());
|
|
135
|
+
return this.#convertScannerEvents(tail);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** Flush held-back text only. Reconstructed calls are retained for {@link drainCompleted}. */
|
|
139
|
+
flushPending(): string {
|
|
140
|
+
let clean = "";
|
|
141
|
+
for (const event of this.flushEvents()) {
|
|
142
|
+
if (event.type === "text") {
|
|
143
|
+
clean += event.text;
|
|
144
|
+
} else if (event.type === "toolCall") {
|
|
145
|
+
this.#completed.push(event.call);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return clean;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** True once any configured tool-call section/envelope has fully closed. */
|
|
152
|
+
get sectionClosed(): boolean {
|
|
153
|
+
return this.#sectionTerminated;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
#markSectionClosed(text: string): void {
|
|
157
|
+
if (this.#sectionTerminated || !this.#toolScanner) return;
|
|
158
|
+
if (this.#pattern === "kimi") {
|
|
159
|
+
this.#sectionTerminated = text.includes(KIMI_SECTION_END);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
this.#sectionTerminated =
|
|
163
|
+
text.includes(DSML_TOOL_CALLS_CLOSE_FULLWIDTH) || text.includes(DSML_TOOL_CALLS_CLOSE_ASCII);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Re-scan the tool scanner's visible text through the always-on thinking
|
|
168
|
+
* healer: `text` events are healed for leaked reasoning idioms, while the tool
|
|
169
|
+
* scanner's own thinking / tool-call events pass through in stream order.
|
|
170
|
+
*/
|
|
171
|
+
#healThinking(toolEvents: readonly InbandScanEvent[]): InbandScanEvent[] {
|
|
172
|
+
const out: InbandScanEvent[] = [];
|
|
173
|
+
for (const event of toolEvents) {
|
|
174
|
+
if (event.type === "text") out.push(...this.#thinkingScanner.feed(event.text));
|
|
175
|
+
else out.push(event);
|
|
176
|
+
}
|
|
177
|
+
return out;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
#convertScannerEvents(events: readonly InbandScanEvent[]): StreamMarkupHealingEvent[] {
|
|
181
|
+
const out: StreamMarkupHealingEvent[] = [];
|
|
182
|
+
for (const event of events) {
|
|
183
|
+
switch (event.type) {
|
|
184
|
+
case "text":
|
|
185
|
+
out.push({ type: "text", text: event.text });
|
|
186
|
+
break;
|
|
187
|
+
case "thinkingDelta":
|
|
188
|
+
if (event.delta.length > 0) out.push({ type: "thinking", thinking: event.delta });
|
|
189
|
+
break;
|
|
190
|
+
case "toolEnd":
|
|
191
|
+
out.push({
|
|
192
|
+
type: "toolCall",
|
|
193
|
+
call: {
|
|
194
|
+
id: generateHealedToolCallId(),
|
|
195
|
+
name: event.name,
|
|
196
|
+
arguments: JSON.stringify(event.arguments),
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
break;
|
|
200
|
+
case "thinkingStart":
|
|
201
|
+
case "thinkingEnd":
|
|
202
|
+
case "toolStart":
|
|
203
|
+
case "toolArgDelta":
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return out;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function generateHealedToolCallId(): string {
|
|
212
|
+
return `call_${crypto.randomUUID().replace(/-/g, "").slice(0, 24)}`;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** Cheap model/provider gate for Kimi-K2 chat-template token leaks. */
|
|
216
|
+
export function modelMayLeakKimiToolCalls(provider: string, modelId: string): boolean {
|
|
217
|
+
if (provider === "kimi-code" || provider === "moonshot") return true;
|
|
218
|
+
return /kimi[-/_.]?k2/i.test(modelId);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/** Cheap model/provider gate for DeepSeek DSML envelope leaks. */
|
|
222
|
+
export function modelMayLeakDsmlToolCalls(provider: string, modelId: string): boolean {
|
|
223
|
+
if (!isDeepseekModelIdOrName(modelId)) return false;
|
|
224
|
+
return (
|
|
225
|
+
provider === "ollama" ||
|
|
226
|
+
provider === "ollama-cloud" ||
|
|
227
|
+
provider === "nvidia" ||
|
|
228
|
+
provider === "deepseek" ||
|
|
229
|
+
provider === "fireworks" ||
|
|
230
|
+
provider === "nanogpt" ||
|
|
231
|
+
provider === "opencode-go" ||
|
|
232
|
+
provider === "openrouter"
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Pick the leaked-markup healer for an OpenAI-compatible / Ollama visible-text
|
|
238
|
+
* stream. Kimi chat-template tokens and DeepSeek DSML envelopes need their
|
|
239
|
+
* dedicated tool-call grammars; every other model uses `"thinking"`. All three
|
|
240
|
+
* patterns run the generic {@link ThinkingInbandScanner}, so leaked reasoning
|
|
241
|
+
* idioms (e.g. a Gemini ` ```thinking ` fence on OpenRouter) are always healed.
|
|
242
|
+
*/
|
|
243
|
+
export function getStreamMarkupHealingPattern(provider: string, modelId: string): StreamMarkupHealingPattern {
|
|
244
|
+
if (modelMayLeakKimiToolCalls(provider, modelId)) return "kimi";
|
|
245
|
+
if (modelMayLeakDsmlToolCalls(provider, modelId)) return "dsml";
|
|
246
|
+
return "thinking";
|
|
247
|
+
}
|