@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,92 @@
|
|
|
1
|
+
import * as AIError from "../../error";
|
|
2
|
+
|
|
3
|
+
const DEVICE_FLOW_CANCEL_MESSAGE = "Login cancelled";
|
|
4
|
+
const DEVICE_FLOW_TIMEOUT_MESSAGE = "Device flow timed out";
|
|
5
|
+
const DEVICE_FLOW_SLOW_DOWN_TIMEOUT_MESSAGE =
|
|
6
|
+
"Device flow timed out after one or more slow_down responses. This is often caused by clock drift in WSL or VM environments. Please sync or restart the VM clock and try again.";
|
|
7
|
+
const MINIMUM_DEVICE_FLOW_INTERVAL_MS = 1000;
|
|
8
|
+
const DEFAULT_DEVICE_FLOW_INTERVAL_SECONDS = 5;
|
|
9
|
+
const SLOW_DOWN_INTERVAL_INCREMENT_MS = 5000;
|
|
10
|
+
|
|
11
|
+
/** Result returned by one OAuth device-code polling attempt. */
|
|
12
|
+
export type OAuthDeviceCodePollResult<T> =
|
|
13
|
+
| { status: "complete"; value: T }
|
|
14
|
+
| { status: "pending" }
|
|
15
|
+
| { status: "slow_down" }
|
|
16
|
+
| { status: "failed"; message: string };
|
|
17
|
+
|
|
18
|
+
/** Options for polling an RFC 8628-style OAuth device-code flow. */
|
|
19
|
+
export interface OAuthDeviceCodeFlowOptions<T> {
|
|
20
|
+
/** Poll the provider once and classify the response. */
|
|
21
|
+
poll(): OAuthDeviceCodePollResult<T> | Promise<OAuthDeviceCodePollResult<T>>;
|
|
22
|
+
/** Provider-requested polling cadence; defaults to RFC 8628's five seconds. */
|
|
23
|
+
intervalSeconds?: number;
|
|
24
|
+
/** Provider-issued expiry window for the device code. */
|
|
25
|
+
expiresInSeconds?: number;
|
|
26
|
+
/** Cancels the flow with the legacy "Login cancelled" error. */
|
|
27
|
+
signal?: AbortSignal;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function abortableDeviceFlowSleep(ms: number, signal: AbortSignal | undefined): Promise<void> {
|
|
31
|
+
if (!signal) {
|
|
32
|
+
await Bun.sleep(ms);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (signal.aborted) {
|
|
36
|
+
throw new AIError.LoginCancelledError(DEVICE_FLOW_CANCEL_MESSAGE);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const { promise, resolve, reject } = Promise.withResolvers<void>();
|
|
40
|
+
let timer: Timer | undefined;
|
|
41
|
+
const onAbort = () => {
|
|
42
|
+
clearTimeout(timer);
|
|
43
|
+
reject(new AIError.LoginCancelledError(DEVICE_FLOW_CANCEL_MESSAGE));
|
|
44
|
+
};
|
|
45
|
+
timer = setTimeout(() => {
|
|
46
|
+
signal.removeEventListener("abort", onAbort);
|
|
47
|
+
resolve();
|
|
48
|
+
}, ms);
|
|
49
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
50
|
+
await promise;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Poll an OAuth device-code flow until completion, provider failure, timeout, or cancellation. */
|
|
54
|
+
export async function pollOAuthDeviceCodeFlow<T>(options: OAuthDeviceCodeFlowOptions<T>): Promise<T> {
|
|
55
|
+
const deadline =
|
|
56
|
+
typeof options.expiresInSeconds === "number"
|
|
57
|
+
? Date.now() + options.expiresInSeconds * 1000
|
|
58
|
+
: Number.POSITIVE_INFINITY;
|
|
59
|
+
let intervalMs = Math.max(
|
|
60
|
+
MINIMUM_DEVICE_FLOW_INTERVAL_MS,
|
|
61
|
+
Math.floor((options.intervalSeconds ?? DEFAULT_DEVICE_FLOW_INTERVAL_SECONDS) * 1000),
|
|
62
|
+
);
|
|
63
|
+
let slowDownResponses = 0;
|
|
64
|
+
|
|
65
|
+
while (Date.now() < deadline) {
|
|
66
|
+
if (options.signal?.aborted) {
|
|
67
|
+
throw new AIError.LoginCancelledError(DEVICE_FLOW_CANCEL_MESSAGE);
|
|
68
|
+
}
|
|
69
|
+
const result = await options.poll();
|
|
70
|
+
if (result.status === "complete") {
|
|
71
|
+
return result.value;
|
|
72
|
+
}
|
|
73
|
+
if (result.status === "failed") {
|
|
74
|
+
throw new AIError.OAuthError(result.message, { kind: "polling" });
|
|
75
|
+
}
|
|
76
|
+
if (result.status === "slow_down") {
|
|
77
|
+
slowDownResponses += 1;
|
|
78
|
+
intervalMs = Math.max(MINIMUM_DEVICE_FLOW_INTERVAL_MS, intervalMs + SLOW_DOWN_INTERVAL_INCREMENT_MS);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const remainingMs = deadline - Date.now();
|
|
82
|
+
if (remainingMs <= 0) {
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
await abortableDeviceFlowSleep(Math.min(intervalMs, remainingMs), options.signal);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
throw new AIError.OAuthError(
|
|
89
|
+
slowDownResponses > 0 ? DEVICE_FLOW_SLOW_DOWN_TIMEOUT_MESSAGE : DEVICE_FLOW_TIMEOUT_MESSAGE,
|
|
90
|
+
{ kind: "timeout" },
|
|
91
|
+
);
|
|
92
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import * as AIError from "../../error";
|
|
2
|
+
import { OAuthCallbackFlow } from "./callback-server";
|
|
3
|
+
import { generatePKCE } from "./pkce";
|
|
4
|
+
import type { OAuthController, OAuthCredentials } from "./types";
|
|
5
|
+
|
|
6
|
+
type FetchFunction = NonNullable<OAuthController["fetch"]>;
|
|
7
|
+
|
|
8
|
+
const DEVIN_WEBAPP_URL = "https://app.devin.ai";
|
|
9
|
+
const DEVIN_API_URL = "https://api.devin.ai";
|
|
10
|
+
const CALLBACK_PORT = 59653;
|
|
11
|
+
const CALLBACK_PATH = "/callback";
|
|
12
|
+
const TOKEN_PATH = "/auth/cli/token";
|
|
13
|
+
const FALLBACK_EXPIRES_MS = 365 * 24 * 60 * 60 * 1000;
|
|
14
|
+
|
|
15
|
+
interface DevinPKCEParams {
|
|
16
|
+
verifier: string;
|
|
17
|
+
challenge: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function loginDevin(ctrl: OAuthController): Promise<OAuthCredentials> {
|
|
21
|
+
const flow = new DevinOAuthFlow(ctrl);
|
|
22
|
+
return flow.login();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
class DevinOAuthFlow extends OAuthCallbackFlow {
|
|
26
|
+
#pkce?: DevinPKCEParams;
|
|
27
|
+
|
|
28
|
+
constructor(ctrl: OAuthController) {
|
|
29
|
+
super(ctrl, {
|
|
30
|
+
preferredPort: CALLBACK_PORT,
|
|
31
|
+
callbackPath: CALLBACK_PATH,
|
|
32
|
+
callbackHostname: "127.0.0.1",
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
override generateState(): string {
|
|
37
|
+
return crypto.randomUUID();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async generateAuthUrl(state: string, redirectUri: string): Promise<{ url: string; instructions?: string }> {
|
|
41
|
+
this.#pkce = await generatePKCE();
|
|
42
|
+
const params = new URLSearchParams({
|
|
43
|
+
redirect_uri: redirectUri,
|
|
44
|
+
state,
|
|
45
|
+
prompt: "select_account",
|
|
46
|
+
code_challenge: this.#pkce.challenge,
|
|
47
|
+
code_challenge_method: "S256",
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
url: `${DEVIN_WEBAPP_URL}/auth/cli/continue?${params.toString()}`,
|
|
52
|
+
instructions: "Sign in to Devin in your browser.",
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async exchangeToken(code: string): Promise<OAuthCredentials> {
|
|
57
|
+
if (!this.#pkce) {
|
|
58
|
+
throw new AIError.OAuthError("Devin PKCE verifier was not initialized", {
|
|
59
|
+
kind: "configuration",
|
|
60
|
+
provider: "devin",
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
const token = await exchangeDevinCliToken(code, this.#pkce.verifier, this.ctrl.fetch);
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
access: token,
|
|
67
|
+
refresh: token,
|
|
68
|
+
expires: getTokenExpiry(token),
|
|
69
|
+
apiEndpoint: DEVIN_API_URL,
|
|
70
|
+
enterpriseUrl: DEVIN_WEBAPP_URL,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export async function exchangeDevinCliToken(
|
|
76
|
+
authorizationCode: string,
|
|
77
|
+
codeVerifier: string,
|
|
78
|
+
fetchImpl: FetchFunction = fetch,
|
|
79
|
+
): Promise<string> {
|
|
80
|
+
const response = await fetchImpl(`${DEVIN_API_URL}${TOKEN_PATH}`, {
|
|
81
|
+
method: "POST",
|
|
82
|
+
headers: {
|
|
83
|
+
Accept: "application/json",
|
|
84
|
+
"Content-Type": "application/json",
|
|
85
|
+
},
|
|
86
|
+
body: JSON.stringify({
|
|
87
|
+
code: authorizationCode,
|
|
88
|
+
code_verifier: codeVerifier,
|
|
89
|
+
}),
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
if (!response.ok) {
|
|
93
|
+
const error = await response.text();
|
|
94
|
+
throw new AIError.OAuthError(`Devin CLI token exchange failed: ${response.status} ${error}`.trim(), {
|
|
95
|
+
kind: "token-exchange",
|
|
96
|
+
provider: "devin",
|
|
97
|
+
status: response.status,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const data = (await response.json()) as { token?: unknown };
|
|
102
|
+
if (typeof data.token !== "string" || data.token.length === 0) {
|
|
103
|
+
throw new AIError.OAuthError("Devin CLI token exchange returned an empty token", {
|
|
104
|
+
kind: "validation",
|
|
105
|
+
provider: "devin",
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return data.token;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function getTokenExpiry(token: string): number {
|
|
112
|
+
try {
|
|
113
|
+
const [, payload] = token.split(".");
|
|
114
|
+
if (payload) {
|
|
115
|
+
const decoded = JSON.parse(Buffer.from(payload, "base64url").toString("utf8")) as { exp?: unknown };
|
|
116
|
+
if (typeof decoded.exp === "number" && Number.isFinite(decoded.exp)) {
|
|
117
|
+
return decoded.exp * 1000 - 5 * 60 * 1000;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
} catch {
|
|
121
|
+
// Ignore malformed non-JWT tokens and use a conservative long-lived fallback.
|
|
122
|
+
}
|
|
123
|
+
return Date.now() + FALLBACK_EXPIRES_MS;
|
|
124
|
+
}
|
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Copilot OAuth flow (opencode OAuth app)
|
|
3
|
+
*/
|
|
4
|
+
import { scheduler } from "node:timers/promises";
|
|
5
|
+
import { getBundledModels } from "@linxiraos/pi-catalog/models";
|
|
6
|
+
import {
|
|
7
|
+
COPILOT_API_HEADERS,
|
|
8
|
+
getGitHubCopilotBaseUrl,
|
|
9
|
+
isPublicGitHubHost,
|
|
10
|
+
normalizeDomain,
|
|
11
|
+
normalizeGitHubCopilotApiEndpoint,
|
|
12
|
+
normalizeGitHubCopilotEnterpriseDomain,
|
|
13
|
+
OPENCODE_HEADERS,
|
|
14
|
+
} from "@linxiraos/pi-catalog/wire/github-copilot";
|
|
15
|
+
import * as AIError from "../../error";
|
|
16
|
+
import type { FetchImpl } from "../../types";
|
|
17
|
+
import type { OAuthCredentials } from "./types";
|
|
18
|
+
|
|
19
|
+
const CLIENT_ID = "Ov23li8tweQw6odWQebz";
|
|
20
|
+
|
|
21
|
+
const INITIAL_POLL_INTERVAL_MULTIPLIER = 1.2;
|
|
22
|
+
const SLOW_DOWN_POLL_INTERVAL_MULTIPLIER = 1.4;
|
|
23
|
+
|
|
24
|
+
type GitHubCopilotLoginOptions = {
|
|
25
|
+
onAuth: (url: string, instructions?: string) => void;
|
|
26
|
+
onPrompt: (prompt: { message: string; placeholder?: string; allowEmpty?: boolean }) => Promise<string>;
|
|
27
|
+
onProgress?: (message: string) => void;
|
|
28
|
+
signal?: AbortSignal;
|
|
29
|
+
pollIntervalFloorMs?: number;
|
|
30
|
+
pollIntervalScaleMs?: number;
|
|
31
|
+
fetch?: FetchImpl;
|
|
32
|
+
};
|
|
33
|
+
type DeviceCodeResponse = {
|
|
34
|
+
device_code: string;
|
|
35
|
+
user_code: string;
|
|
36
|
+
verification_uri: string;
|
|
37
|
+
interval: number;
|
|
38
|
+
expires_in: number;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
type DeviceTokenSuccessResponse = {
|
|
42
|
+
access_token: string;
|
|
43
|
+
token_type?: string;
|
|
44
|
+
scope?: string;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
type DeviceTokenErrorResponse = {
|
|
48
|
+
error: string;
|
|
49
|
+
error_description?: string;
|
|
50
|
+
interval?: number;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
function getUrls(domain: string): {
|
|
54
|
+
deviceCodeUrl: string;
|
|
55
|
+
accessTokenUrl: string;
|
|
56
|
+
} {
|
|
57
|
+
return {
|
|
58
|
+
deviceCodeUrl: `https://${domain}/login/device/code`,
|
|
59
|
+
accessTokenUrl: `https://${domain}/login/oauth/access_token`,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function fetchJson(url: string, init: RequestInit, fetchImpl: FetchImpl): Promise<unknown> {
|
|
64
|
+
const response = await fetchImpl(url, init);
|
|
65
|
+
if (!response.ok) {
|
|
66
|
+
const text = await response.text();
|
|
67
|
+
throw new AIError.ProviderHttpError(`${response.status} ${response.statusText}: ${text}`, response.status);
|
|
68
|
+
}
|
|
69
|
+
return response.json();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function startDeviceFlow(domain: string, fetchImpl: FetchImpl): Promise<DeviceCodeResponse> {
|
|
73
|
+
const urls = getUrls(domain);
|
|
74
|
+
const data = await fetchJson(
|
|
75
|
+
urls.deviceCodeUrl,
|
|
76
|
+
{
|
|
77
|
+
method: "POST",
|
|
78
|
+
headers: {
|
|
79
|
+
Accept: "application/json",
|
|
80
|
+
"Content-Type": "application/json",
|
|
81
|
+
...OPENCODE_HEADERS,
|
|
82
|
+
},
|
|
83
|
+
body: JSON.stringify({
|
|
84
|
+
client_id: CLIENT_ID,
|
|
85
|
+
scope: "read:user",
|
|
86
|
+
}),
|
|
87
|
+
},
|
|
88
|
+
fetchImpl,
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
if (!data || typeof data !== "object") {
|
|
92
|
+
throw new AIError.OAuthError("Invalid device code response", { kind: "validation", provider: "github-copilot" });
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const deviceCode = (data as Record<string, unknown>).device_code;
|
|
96
|
+
const userCode = (data as Record<string, unknown>).user_code;
|
|
97
|
+
const verificationUri = (data as Record<string, unknown>).verification_uri;
|
|
98
|
+
const interval = (data as Record<string, unknown>).interval;
|
|
99
|
+
const expiresIn = (data as Record<string, unknown>).expires_in;
|
|
100
|
+
|
|
101
|
+
if (
|
|
102
|
+
typeof deviceCode !== "string" ||
|
|
103
|
+
typeof userCode !== "string" ||
|
|
104
|
+
typeof verificationUri !== "string" ||
|
|
105
|
+
typeof interval !== "number" ||
|
|
106
|
+
typeof expiresIn !== "number"
|
|
107
|
+
) {
|
|
108
|
+
throw new AIError.OAuthError("Invalid device code response fields", {
|
|
109
|
+
kind: "validation",
|
|
110
|
+
provider: "github-copilot",
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
device_code: deviceCode,
|
|
116
|
+
user_code: userCode,
|
|
117
|
+
verification_uri: verificationUri,
|
|
118
|
+
interval,
|
|
119
|
+
expires_in: expiresIn,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async function pollForGitHubAccessToken(
|
|
124
|
+
domain: string,
|
|
125
|
+
deviceCode: string,
|
|
126
|
+
intervalSeconds: number,
|
|
127
|
+
expiresIn: number,
|
|
128
|
+
signal: AbortSignal | undefined,
|
|
129
|
+
fetchImpl: FetchImpl,
|
|
130
|
+
pollIntervalFloorMs = 1000,
|
|
131
|
+
pollIntervalScaleMs = 1000,
|
|
132
|
+
) {
|
|
133
|
+
const urls = getUrls(domain);
|
|
134
|
+
const deadline = Date.now() + expiresIn * 1000;
|
|
135
|
+
let intervalMs = Math.max(pollIntervalFloorMs, Math.floor(intervalSeconds * pollIntervalScaleMs));
|
|
136
|
+
let intervalMultiplier = INITIAL_POLL_INTERVAL_MULTIPLIER;
|
|
137
|
+
let slowDownResponses = 0;
|
|
138
|
+
|
|
139
|
+
while (Date.now() < deadline) {
|
|
140
|
+
if (signal?.aborted) {
|
|
141
|
+
throw new AIError.LoginCancelledError();
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const remainingMs = deadline - Date.now();
|
|
145
|
+
const waitMs = Math.min(Math.ceil(intervalMs * intervalMultiplier), remainingMs);
|
|
146
|
+
try {
|
|
147
|
+
await scheduler.wait(waitMs, { signal });
|
|
148
|
+
} catch {
|
|
149
|
+
throw new AIError.LoginCancelledError();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const raw = await fetchJson(
|
|
153
|
+
urls.accessTokenUrl,
|
|
154
|
+
{
|
|
155
|
+
method: "POST",
|
|
156
|
+
headers: {
|
|
157
|
+
Accept: "application/json",
|
|
158
|
+
"Content-Type": "application/json",
|
|
159
|
+
...OPENCODE_HEADERS,
|
|
160
|
+
},
|
|
161
|
+
body: JSON.stringify({
|
|
162
|
+
client_id: CLIENT_ID,
|
|
163
|
+
device_code: deviceCode,
|
|
164
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
165
|
+
}),
|
|
166
|
+
},
|
|
167
|
+
fetchImpl,
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
if (raw && typeof raw === "object" && typeof (raw as DeviceTokenSuccessResponse).access_token === "string") {
|
|
171
|
+
return (raw as DeviceTokenSuccessResponse).access_token;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (raw && typeof raw === "object" && typeof (raw as DeviceTokenErrorResponse).error === "string") {
|
|
175
|
+
const { error, error_description: description, interval } = raw as DeviceTokenErrorResponse;
|
|
176
|
+
if (error === "authorization_pending") {
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (error === "slow_down") {
|
|
181
|
+
slowDownResponses += 1;
|
|
182
|
+
intervalMs =
|
|
183
|
+
typeof interval === "number" && interval > 0
|
|
184
|
+
? Math.max(pollIntervalFloorMs, interval * pollIntervalScaleMs)
|
|
185
|
+
: Math.max(pollIntervalFloorMs, intervalMs + 5 * pollIntervalScaleMs);
|
|
186
|
+
intervalMultiplier = SLOW_DOWN_POLL_INTERVAL_MULTIPLIER;
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const descriptionSuffix = description ? `: ${description}` : "";
|
|
191
|
+
throw new AIError.OAuthError(`Device flow failed: ${error}${descriptionSuffix}`, {
|
|
192
|
+
kind: "polling",
|
|
193
|
+
provider: "github-copilot",
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (slowDownResponses > 0) {
|
|
199
|
+
throw new AIError.OAuthError(
|
|
200
|
+
"Device flow timed out after one or more slow_down responses. This is often caused by clock drift in WSL or VM environments. Please sync or restart the VM clock and try again.",
|
|
201
|
+
{ kind: "timeout", provider: "github-copilot" },
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
throw new AIError.OAuthError("Device flow timed out", { kind: "timeout", provider: "github-copilot" });
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/** Far-future expiry (10 years). GitHub OAuth tokens are long-lived; no JWT exchange needed. */
|
|
209
|
+
const FAR_FUTURE_MS = Date.now() + 10 * 365.25 * 24 * 60 * 60 * 1000;
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Refresh GitHub Copilot token.
|
|
213
|
+
* With the opencode OAuth flow, the GitHub token is used directly — no JWT exchange needed.
|
|
214
|
+
*/
|
|
215
|
+
export function refreshGitHubCopilotToken(
|
|
216
|
+
refreshToken: string,
|
|
217
|
+
enterpriseDomain?: string,
|
|
218
|
+
apiEndpoint?: string,
|
|
219
|
+
): OAuthCredentials {
|
|
220
|
+
return {
|
|
221
|
+
refresh: refreshToken,
|
|
222
|
+
access: refreshToken,
|
|
223
|
+
expires: FAR_FUTURE_MS,
|
|
224
|
+
enterpriseUrl: enterpriseDomain,
|
|
225
|
+
apiEndpoint,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
async function discoverGitHubCopilotApiEndpoint(token: string, fetchImpl: FetchImpl): Promise<string | undefined> {
|
|
230
|
+
try {
|
|
231
|
+
const data = await fetchJson(
|
|
232
|
+
"https://api.github.com/copilot_internal/user",
|
|
233
|
+
{
|
|
234
|
+
headers: {
|
|
235
|
+
Accept: "application/json",
|
|
236
|
+
Authorization: `token ${token}`,
|
|
237
|
+
...OPENCODE_HEADERS,
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
fetchImpl,
|
|
241
|
+
);
|
|
242
|
+
if (!data || typeof data !== "object") return undefined;
|
|
243
|
+
const endpoints = (data as { endpoints?: { api?: unknown } }).endpoints;
|
|
244
|
+
return typeof endpoints?.api === "string" ? normalizeGitHubCopilotApiEndpoint(endpoints.api) : undefined;
|
|
245
|
+
} catch {
|
|
246
|
+
return undefined;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Enable a model for the user's GitHub Copilot account.
|
|
252
|
+
* This is required for some models (like Claude, Grok) before they can be used.
|
|
253
|
+
*/
|
|
254
|
+
async function enableGitHubCopilotModel(
|
|
255
|
+
token: string,
|
|
256
|
+
modelId: string,
|
|
257
|
+
fetchImpl: FetchImpl,
|
|
258
|
+
enterpriseDomain: string | undefined,
|
|
259
|
+
apiEndpoint: string | undefined,
|
|
260
|
+
): Promise<boolean> {
|
|
261
|
+
const baseUrl = apiEndpoint ?? getGitHubCopilotBaseUrl(enterpriseDomain);
|
|
262
|
+
const url = `${baseUrl}/models/${modelId}/policy`;
|
|
263
|
+
|
|
264
|
+
try {
|
|
265
|
+
const response = await fetchImpl(url, {
|
|
266
|
+
method: "POST",
|
|
267
|
+
headers: {
|
|
268
|
+
"Content-Type": "application/json",
|
|
269
|
+
Authorization: `Bearer ${token}`,
|
|
270
|
+
...COPILOT_API_HEADERS,
|
|
271
|
+
"openai-intent": "chat-policy",
|
|
272
|
+
"x-interaction-type": "chat-policy",
|
|
273
|
+
},
|
|
274
|
+
body: JSON.stringify({ state: "enabled" }),
|
|
275
|
+
});
|
|
276
|
+
return response.ok;
|
|
277
|
+
} catch {
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Enable all known GitHub Copilot models that may require policy acceptance.
|
|
284
|
+
* Called after successful login to ensure all models are available.
|
|
285
|
+
*/
|
|
286
|
+
async function enableAllGitHubCopilotModels(
|
|
287
|
+
token: string,
|
|
288
|
+
enterpriseDomain: string | undefined,
|
|
289
|
+
apiEndpoint: string | undefined,
|
|
290
|
+
fetchImpl: FetchImpl,
|
|
291
|
+
onProgress?: (model: string, success: boolean) => void,
|
|
292
|
+
): Promise<void> {
|
|
293
|
+
// Synthesized catalog variants (Copilot long-context `-1m` entries) share
|
|
294
|
+
// the upstream model id; enable each wire id exactly once.
|
|
295
|
+
const wireModelIds = [...new Set(getBundledModels("github-copilot").map(model => model.requestModelId ?? model.id))];
|
|
296
|
+
const BATCH_SIZE = 5;
|
|
297
|
+
for (let i = 0; i < wireModelIds.length; i += BATCH_SIZE) {
|
|
298
|
+
const batch = wireModelIds.slice(i, i + BATCH_SIZE);
|
|
299
|
+
await Promise.all(
|
|
300
|
+
batch.map(async modelId => {
|
|
301
|
+
const success = await enableGitHubCopilotModel(token, modelId, fetchImpl, enterpriseDomain, apiEndpoint);
|
|
302
|
+
onProgress?.(modelId, success);
|
|
303
|
+
}),
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Login with GitHub Copilot OAuth (device code flow)
|
|
310
|
+
*
|
|
311
|
+
* @param options.onAuth - Callback with URL and optional instructions (user code)
|
|
312
|
+
* @param options.onPrompt - Callback to prompt user for input
|
|
313
|
+
* @param options.onProgress - Optional progress callback
|
|
314
|
+
* @param options.signal - Optional AbortSignal for cancellation
|
|
315
|
+
*/
|
|
316
|
+
export async function loginGitHubCopilot(options: GitHubCopilotLoginOptions): Promise<OAuthCredentials> {
|
|
317
|
+
const fetchImpl = options.fetch ?? fetch;
|
|
318
|
+
const input = await options.onPrompt({
|
|
319
|
+
message: "GitHub Enterprise URL/domain (blank for github.com)",
|
|
320
|
+
placeholder: "company.ghe.com",
|
|
321
|
+
allowEmpty: true,
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
if (options.signal?.aborted) {
|
|
325
|
+
throw new AIError.LoginCancelledError();
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const trimmed = input.trim();
|
|
329
|
+
const normalizedDomain = normalizeDomain(input);
|
|
330
|
+
if (trimmed && !normalizedDomain) {
|
|
331
|
+
throw new AIError.OAuthError("Invalid GitHub Enterprise URL/domain", {
|
|
332
|
+
kind: "validation",
|
|
333
|
+
provider: "github-copilot",
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
const enterpriseDomain = normalizeGitHubCopilotEnterpriseDomain(normalizedDomain ?? undefined);
|
|
337
|
+
const domain =
|
|
338
|
+
normalizedDomain && isPublicGitHubHost(normalizedDomain) ? "github.com" : (normalizedDomain ?? "github.com");
|
|
339
|
+
|
|
340
|
+
const device = await startDeviceFlow(domain, fetchImpl);
|
|
341
|
+
options.onAuth(device.verification_uri, `Enter code: ${device.user_code}`);
|
|
342
|
+
|
|
343
|
+
const githubAccessToken = await pollForGitHubAccessToken(
|
|
344
|
+
domain,
|
|
345
|
+
device.device_code,
|
|
346
|
+
device.interval,
|
|
347
|
+
device.expires_in,
|
|
348
|
+
options.signal,
|
|
349
|
+
fetchImpl,
|
|
350
|
+
options.pollIntervalFloorMs,
|
|
351
|
+
options.pollIntervalScaleMs,
|
|
352
|
+
);
|
|
353
|
+
|
|
354
|
+
const apiEndpoint = await discoverGitHubCopilotApiEndpoint(githubAccessToken, fetchImpl);
|
|
355
|
+
|
|
356
|
+
// With opencode OAuth, the GitHub token is used directly for all API requests
|
|
357
|
+
const credentials: OAuthCredentials = {
|
|
358
|
+
refresh: githubAccessToken,
|
|
359
|
+
access: githubAccessToken,
|
|
360
|
+
expires: FAR_FUTURE_MS,
|
|
361
|
+
enterpriseUrl: enterpriseDomain ?? undefined,
|
|
362
|
+
apiEndpoint,
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
// Enable all models after successful login
|
|
366
|
+
options.onProgress?.("Enabling models...");
|
|
367
|
+
await enableAllGitHubCopilotModels(githubAccessToken, enterpriseDomain ?? undefined, apiEndpoint, fetchImpl);
|
|
368
|
+
return credentials;
|
|
369
|
+
}
|