@bitkyc08/opencodex 2.75.0 → 2.76.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/README.md +6 -1
- package/bin/ocx.mjs +12 -1
- package/gui/dist/assets/App-CddorHdA.js +51 -0
- package/gui/dist/assets/App-DMudtISW.css +1 -0
- package/gui/dist/assets/{Tray-CGAD2AGk.js → Tray-DjNwwrWS.js} +1 -1
- package/gui/dist/assets/index-Btze1I3T.css +1 -0
- package/gui/dist/assets/index-CvnY7E6i.js +86 -0
- package/gui/dist/assets/quota-summary-B_AWpHfP.js +1 -0
- package/gui/dist/index.html +2 -2
- package/gui/dist/provider-icons/opengateway.svg +12 -0
- package/package.json +1 -1
- package/src/adapters/anthropic/account-metadata.ts +17 -0
- package/src/adapters/anthropic/client-identity.ts +69 -0
- package/src/adapters/anthropic/passthrough.ts +23 -4
- package/src/adapters/anthropic.ts +18 -1
- package/src/adapters/command-code-project-context.ts +7 -11
- package/src/adapters/devin/cloud-direct/tool-schema.ts +12 -48
- package/src/adapters/kiro-retry.ts +23 -8
- package/src/adapters/openai-chat/messages.ts +1 -1
- package/src/adapters/registry.ts +8 -1
- package/src/adapters/zed.ts +377 -0
- package/src/bridge/sse.ts +4 -2
- package/src/chatgpt/app-server-shim/app-server-rewrite.ts +45 -0
- package/src/chatgpt/app-server-shim/bundle-trust.ts +77 -0
- package/src/chatgpt/app-server-shim/filter.ts +157 -0
- package/src/chatgpt/app-server-shim/gate-rewrite.ts +99 -0
- package/src/chatgpt/app-server-shim/launcher.ts +91 -0
- package/src/claude/desktop-3p-startup.ts +62 -0
- package/src/claude/desktop-3p.ts +5 -0
- package/src/claude/first-party-settings.ts +14 -0
- package/src/claude/intercept/cli-catalog.ts +150 -0
- package/src/claude/intercept/cli-picker.ts +82 -0
- package/src/claude/intercept/listener.ts +21 -6
- package/src/claude/intercept/picker-bootstrap.ts +23 -5
- package/src/claude/intercept/picker-models.ts +57 -13
- package/src/claude/intercept/runtime.ts +30 -2
- package/src/claude/intercept/settings.ts +3 -0
- package/src/cli/agent.ts +172 -0
- package/src/cli/alias.ts +2 -1
- package/src/cli/capabilities-command.ts +3 -2
- package/src/cli/capabilities.ts +87 -0
- package/src/cli/chatgpt-command.ts +140 -0
- package/src/cli/combo.ts +144 -19
- package/src/cli/config-command.ts +3 -1
- package/src/cli/dispatch.ts +10 -1
- package/src/cli/help.ts +1 -0
- package/src/cli/index.ts +5 -24
- package/src/cli/init.ts +16 -2
- package/src/cli/integrations.ts +13 -0
- package/src/cli/internal-command.ts +12 -5
- package/src/cli/observe.ts +6 -1
- package/src/cli/registry.ts +6 -0
- package/src/cli/route-policy.ts +3 -1
- package/src/cli/runtime-api.ts +5 -2
- package/src/cli/status-oauth.ts +5 -0
- package/src/cli/status.ts +8 -1
- package/src/cli/stop-approval.ts +55 -16
- package/src/cli/stop-report.ts +5 -0
- package/src/clients/lazycodex.ts +48 -0
- package/src/clients/omo-role-models.ts +111 -0
- package/src/codex/account-credit-use.ts +99 -0
- package/src/codex/account-lifecycle.ts +2 -0
- package/src/codex/agent-role-models.ts +171 -0
- package/src/codex/auth-api/account-list.ts +10 -3
- package/src/codex/auth-api/routes.ts +34 -0
- package/src/codex/auth-context.ts +52 -11
- package/src/codex/catalog/discovered-natives.ts +11 -1
- package/src/codex/catalog/gather-capture.ts +6 -1
- package/src/codex/catalog/model-hints.ts +9 -1
- package/src/codex/catalog/provider-models.ts +60 -0
- package/src/codex/catalog/routed-gather.ts +30 -5
- package/src/codex/convergence-types.ts +2 -1
- package/src/codex/main-account-external-usage.ts +62 -0
- package/src/codex/main-account-hard-lock.ts +24 -13
- package/src/codex/native-profile-processes.ts +53 -16
- package/src/codex/prompt-layers/toml-edit.ts +1 -1
- package/src/codex/quota-types.ts +3 -7
- package/src/codex/quota.ts +19 -4
- package/src/codex/role-auto-assign.ts +159 -0
- package/src/codex/role-sizing-limits.ts +2 -0
- package/src/codex/role-sizing.ts +216 -0
- package/src/codex/routing/selection.ts +36 -0
- package/src/codex/routing/thread-affinity.ts +2 -0
- package/src/codex/routing.ts +4 -4
- package/src/codex/subagent-model-fallback.ts +82 -26
- package/src/codex/subagent-selectable-models.ts +32 -0
- package/src/combos/index.ts +18 -0
- package/src/combos/jev-decision-contract.ts +20 -0
- package/src/combos/jev-dispatch.ts +18 -0
- package/src/combos/jev-model-backend.ts +127 -0
- package/src/combos/jev.ts +249 -33
- package/src/combos/types.ts +125 -2
- package/src/config/diagnostics.ts +18 -0
- package/src/config/macos-system-proxy.ts +72 -15
- package/src/config/owner-registry.ts +13 -4
- package/src/config/process-state.ts +17 -8
- package/src/config/proxy-env.ts +35 -5
- package/src/config/schema/config-schema.ts +30 -1
- package/src/config/schema/leaf-validators.ts +4 -0
- package/src/config/serving-runtimes.ts +95 -1
- package/src/generated/compatibility-version.json +336 -156
- package/src/lib/errors.ts +7 -7
- package/src/lib/jsonc.ts +13 -0
- package/src/lib/local-chat-completion.ts +144 -0
- package/src/lib/provider-outbound.ts +87 -1
- package/src/lib/provider-runtime-fetch.ts +23 -0
- package/src/lib/provider-tls-profile.ts +221 -0
- package/src/lib/request-execution-budget.ts +16 -6
- package/src/lib/spend-reservation-ledger.ts +54 -20
- package/src/lib/sse-decoder.ts +20 -17
- package/src/lib/synced-state-location.ts +96 -0
- package/src/lib/winsw.ts +14 -5
- package/src/oauth/anthropic-account-refusal.ts +53 -4
- package/src/oauth/anthropic-model-quota.ts +83 -0
- package/src/oauth/anthropic-rate-limit-policy.ts +37 -0
- package/src/oauth/anthropic-routing.ts +112 -58
- package/src/oauth/health.ts +39 -3
- package/src/oauth/index.ts +14 -0
- package/src/oauth/kiro-account-load.ts +10 -0
- package/src/oauth/zed.ts +134 -0
- package/src/providers/model-discovery.ts +19 -8
- package/src/providers/model-rename-fields.ts +1 -0
- package/src/providers/provider-id-rewrite.ts +9 -2
- package/src/providers/quota/account-cache.ts +29 -7
- package/src/providers/quota/anthropic-cooldown-recovery.ts +18 -0
- package/src/providers/quota/anthropic-family-headers.ts +25 -0
- package/src/providers/quota/vendor-probes-oauth.ts +5 -1
- package/src/providers/quota-types.ts +4 -0
- package/src/providers/registry/entries-core.ts +18 -0
- package/src/providers/registry/entries-extended.ts +55 -0
- package/src/providers/registry/types.ts +3 -0
- package/src/providers/xai-fast-model.ts +12 -4
- package/src/providers/zed.ts +598 -0
- package/src/responses/state/snapshot-select.ts +22 -9
- package/src/responses/state.ts +2 -3
- package/src/router.ts +9 -0
- package/src/server/anthropic-rate-limit-headers.ts +7 -0
- package/src/server/auth-cors.ts +7 -0
- package/src/server/chat-completions.ts +9 -4
- package/src/server/claude-messages.ts +59 -21
- package/src/server/index/claude-intercept-lifecycle.ts +71 -25
- package/src/server/index/optional-listeners.ts +4 -0
- package/src/server/index/spend-ledger-lifecycle.ts +4 -0
- package/src/server/management/agent-settings-routes.ts +74 -37
- package/src/server/management/claude-desktop-picker-routes.ts +7 -0
- package/src/server/management/claude-intercept-routes.ts +35 -0
- package/src/server/management/codex-agent-role-routes.ts +122 -0
- package/src/server/management/codex-role-auto-assign.ts +208 -0
- package/src/server/management/combo-routes.ts +62 -5
- package/src/server/management/config-routes.ts +35 -3
- package/src/server/management/context.ts +4 -1
- package/src/server/management/decision-discovery.ts +74 -0
- package/src/server/management/decision-model-validation.ts +80 -0
- package/src/server/management/decision-routes.ts +160 -0
- package/src/server/management/native-integration-routes.ts +16 -0
- package/src/server/management/provider-routes.ts +30 -34
- package/src/server/management/route-registry.ts +12 -0
- package/src/server/management/sibling-guard.ts +1 -0
- package/src/server/management/zed-provider-probe.ts +38 -0
- package/src/server/management-api.ts +12 -1
- package/src/server/messages-native-oauth.ts +7 -2
- package/src/server/messages-native.ts +7 -3
- package/src/server/relay.ts +3 -1
- package/src/server/request-log.ts +2 -0
- package/src/server/responses/adapter-continuation.ts +3 -3
- package/src/server/responses/adapter-dispatch.ts +18 -3
- package/src/server/responses/compact.ts +14 -1
- package/src/server/responses/core-auth.ts +2 -0
- package/src/server/responses/core-combo.ts +67 -11
- package/src/server/responses/core-normalize.ts +21 -1
- package/src/server/responses/core-options.ts +11 -1
- package/src/server/responses/core.ts +5 -3
- package/src/server/responses/fetch-helpers.ts +6 -3
- package/src/server/responses/jev-model-invoke.ts +190 -0
- package/src/server/responses/passthrough-delivery.ts +16 -0
- package/src/server/responses/policy-fallback.ts +55 -3
- package/src/server/responses/policy-request-scope.ts +80 -0
- package/src/server/responses/request-prepare.ts +70 -18
- package/src/server/responses/request-transport.ts +54 -23
- package/src/server/responses/run-turn-execution.ts +1 -0
- package/src/server/responses/sidecar-execution.ts +9 -3
- package/src/server/responses-hosted-image-display.ts +225 -0
- package/src/service/managing-cli.ts +34 -4
- package/src/service/systemd-env.ts +75 -0
- package/src/service/windows-guarded-manager.ts +60 -19
- package/src/service/windows-scheduler.ts +22 -3
- package/src/service/windows-taskxml.ts +32 -10
- package/src/service-manager-probe.ts +72 -19
- package/src/types/config.ts +31 -1
- package/src/types/provider.ts +2 -0
- package/src/types/request.ts +2 -0
- package/src/update/index.ts +39 -6
- package/src/update/job.ts +63 -63
- package/src/update/npm-cache-preflight.d.mts +33 -1
- package/src/update/npm-cache-preflight.mjs +131 -18
- package/src/update/ownership-transaction.ts +19 -1
- package/src/update/restart-ownership.ts +80 -6
- package/src/update/transactional-install.d.mts +2 -0
- package/src/update/transactional-install.mjs +6 -1
- package/src/usage/jev-stats.ts +28 -1
- package/src/usage/log.ts +1 -1
- package/src/vision/anthropic-describe.ts +5 -3
- package/src/vision/index.ts +1 -0
- package/src/vision/plan.ts +2 -1
- package/src/vision/routed-describe.ts +29 -121
- package/src/web-search/alpha-search.ts +3 -3
- package/src/web-search/anthropic-executor.ts +6 -4
- package/src/web-search/index.ts +1 -1
- package/src/web-search/loop.ts +3 -3
- package/src/web-search/passthrough-bridge.ts +2 -1
- package/src/web-search/run-turn-loop.ts +1 -1
- package/src/web-search/sidecar-providers.ts +2 -1
- package/gui/dist/assets/App-ia4U0ufY.css +0 -1
- package/gui/dist/assets/App-xm0zGNOe.js +0 -51
- package/gui/dist/assets/index-DBT3Q31Y.css +0 -1
- package/gui/dist/assets/index-D_RGAT6Q.js +0 -86
- package/gui/dist/assets/quota-summary-CUFq48t-.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as e,n as t,x as n}from"./index-CvnY7E6i.js";var r=t(),i=e=>({viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`,...e}),a=e=>(0,r.jsxs)(`svg`,{...i(e),children:[(0,r.jsx)(`rect`,{x:`3`,y:`3`,width:`7`,height:`7`,rx:`1.5`}),(0,r.jsx)(`rect`,{x:`14`,y:`3`,width:`7`,height:`7`,rx:`1.5`}),(0,r.jsx)(`rect`,{x:`3`,y:`14`,width:`7`,height:`7`,rx:`1.5`}),(0,r.jsx)(`rect`,{x:`14`,y:`14`,width:`7`,height:`7`,rx:`1.5`})]}),o=e=>(0,r.jsxs)(`svg`,{...i(e),children:[(0,r.jsx)(`rect`,{x:`3`,y:`4`,width:`18`,height:`7`,rx:`2`}),(0,r.jsx)(`rect`,{x:`3`,y:`13`,width:`18`,height:`7`,rx:`2`}),(0,r.jsx)(`path`,{d:`M7 7.5h.01M7 16.5h.01`})]}),s=e=>(0,r.jsxs)(`svg`,{...i(e),children:[(0,r.jsx)(`path`,{d:`M12 2 4 6v6l8 4 8-4V6l-8-4Z`}),(0,r.jsx)(`path`,{d:`m4 6 8 4 8-4M12 10v8`})]}),c=e=>(0,r.jsxs)(`svg`,{...i(e),children:[(0,r.jsx)(`rect`,{x:`4`,y:`8`,width:`16`,height:`11`,rx:`3`}),(0,r.jsx)(`path`,{d:`M12 8V4M8 2h8`}),(0,r.jsx)(`circle`,{cx:`9`,cy:`13`,r:`1`}),(0,r.jsx)(`circle`,{cx:`15`,cy:`13`,r:`1`})]}),l=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01`})}),u=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M4 6h16M4 12h16M4 18h16`})}),d=e=>(0,r.jsxs)(`svg`,{...i(e),children:[(0,r.jsx)(`rect`,{x:`3`,y:`4`,width:`18`,height:`16`,rx:`2`}),(0,r.jsx)(`path`,{d:`M9 4v16`})]}),f=e=>(0,r.jsxs)(`svg`,{...i(e),children:[(0,r.jsx)(`path`,{d:`m4 17 6-5-6-5`}),(0,r.jsx)(`path`,{d:`M12 19h8`})]}),p=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M22 12h-4l-3 9L9 3l-3 9H2`})}),m=e=>(0,r.jsxs)(`svg`,{...i(e),children:[(0,r.jsx)(`path`,{d:`M22 12H2`}),(0,r.jsx)(`path`,{d:`M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11Z`}),(0,r.jsx)(`path`,{d:`M6 16h.01M10 16h.01`})]}),h=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`m20 6-11 11-5-5`})}),g=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M18 6 6 18M6 6l12 12`})}),ee=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M12 5v14M5 12h14`})}),_=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M21 12a9 9 0 0 1-9 9 9.8 9.8 0 0 1-6.7-2.7L3 16M3 21v-5h5M3 12a9 9 0 0 1 9-9 9.8 9.8 0 0 1 6.7 2.7L21 8M21 3v5h-5`})}),te=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M8 5v14M16 5v14`})}),ne=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`m7 4 13 8-13 8Z`})}),re=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6`})}),ie=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`m3 3 18 18M10.6 10.6a2 2 0 0 0 2.8 2.8M9.9 4.2A10.8 10.8 0 0 1 12 4c5 0 9 4 10 8a12.7 12.7 0 0 1-2 4.1M6.6 6.6A12.4 12.4 0 0 0 2 12c1 4 5 8 10 8 1.5 0 2.9-.4 4.1-1`})}),ae=e=>(0,r.jsxs)(`svg`,{...i(e),children:[(0,r.jsx)(`path`,{d:`M12 20h9`}),(0,r.jsx)(`path`,{d:`M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4Z`})]}),oe=e=>(0,r.jsxs)(`svg`,{...i(e),children:[(0,r.jsx)(`path`,{d:`M10.3 3.7 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.7a2 2 0 0 0-3.4 0Z`}),(0,r.jsx)(`path`,{d:`M12 9v4M12 17h.01`})]}),se=e=>(0,r.jsxs)(`svg`,{...i(e),children:[(0,r.jsx)(`circle`,{cx:`12`,cy:`12`,r:`10`}),(0,r.jsx)(`path`,{d:`M12 16v-4M12 8h.01`})]}),ce=e=>(0,r.jsxs)(`svg`,{...i(e),children:[(0,r.jsx)(`circle`,{cx:`11`,cy:`11`,r:`7`}),(0,r.jsx)(`path`,{d:`m21 21-4.3-4.3`})]}),le=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M12 19V5M5 12l7-7 7 7`})}),ue=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M12 5v14M19 12l-7 7-7-7`})}),de=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3`})}),fe=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`m9 18 6-6-6-6`})}),pe=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M9 19c-5 1.5-5-2.5-7-3m14 6v-3.9a3.4 3.4 0 0 0-.9-2.6c3-.3 6.2-1.5 6.2-6.7A5.2 5.2 0 0 0 20 4.8 4.9 4.9 0 0 0 19.9 1S18.7.6 16 2.5a13.4 13.4 0 0 0-7 0C6.3.6 5.1 1 5.1 1A4.9 4.9 0 0 0 5 4.8a5.2 5.2 0 0 0-1.4 3.7c0 5.1 3.1 6.4 6.1 6.7a3.4 3.4 0 0 0-.9 2.5V22`})}),me=e=>(0,r.jsxs)(`svg`,{...i(e),children:[(0,r.jsx)(`path`,{d:`M18.4 5.6a9 9 0 1 1-12.8 0`}),(0,r.jsx)(`path`,{d:`M12 2v10`})]}),he=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M15 3h6v6M10 14 21 3M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6`})}),ge=e=>(0,r.jsxs)(`svg`,{...i(e),children:[(0,r.jsx)(`circle`,{cx:`7.5`,cy:`15.5`,r:`4.5`}),(0,r.jsx)(`path`,{d:`m10.7 12.3 9.6-9.6M16 7l3 3M14 9l2 2`})]}),_e=e=>(0,r.jsx)(`svg`,{viewBox:`0 0 32 32`,fill:`none`,stroke:`currentColor`,strokeWidth:2.484,strokeLinecap:`round`,...e,children:(0,r.jsx)(`path`,{d:`M22.356 19.797H17.17M9.662 12.29l1.979 3.576a.511.511 0 0 1-.005.504l-1.974 3.409M30.758 16c0 8.15-6.607 14.758-14.758 14.758-8.15 0-14.758-6.607-14.758-14.758C1.242 7.85 7.85 1.242 16 1.242c8.15 0 14.758 6.608 14.758 14.758Z`})}),ve=e=>(0,r.jsxs)(`svg`,{...i(e),children:[(0,r.jsx)(`rect`,{x:`4`,y:`11`,width:`16`,height:`10`,rx:`2`}),(0,r.jsx)(`path`,{d:`M8 11V7a4 4 0 0 1 8 0v4`})]}),ye=e=>(0,r.jsxs)(`svg`,{...i(e),children:[(0,r.jsx)(`path`,{d:`M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z`}),(0,r.jsx)(`path`,{d:`M13 5v2`}),(0,r.jsx)(`path`,{d:`M13 17v2`}),(0,r.jsx)(`path`,{d:`M13 11v2`})]}),be=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M9 17H7A5 5 0 0 1 7 7h2M15 7h2a5 5 0 0 1 0 10h-2M8 12h8`})}),xe=e=>(0,r.jsxs)(`svg`,{...i(e),children:[(0,r.jsx)(`circle`,{cx:`12`,cy:`12`,r:`4`}),(0,r.jsx)(`path`,{d:`M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4`})]}),Se=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M21 12.8A9 9 0 1 1 11.2 3 7 7 0 0 0 21 12.8Z`})}),Ce=e=>(0,r.jsxs)(`svg`,{...i(e),children:[(0,r.jsx)(`rect`,{x:`2`,y:`3`,width:`20`,height:`14`,rx:`2`}),(0,r.jsx)(`path`,{d:`M8 21h8M12 17v4`})]}),we=e=>(0,r.jsxs)(`svg`,{...i(e),children:[(0,r.jsx)(`circle`,{cx:`12`,cy:`12`,r:`9`}),(0,r.jsx)(`path`,{d:`M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18`})]}),Te=e=>(0,r.jsxs)(`svg`,{...i(e),children:[(0,r.jsx)(`path`,{d:`m18 14 4 4-4 4`}),(0,r.jsx)(`path`,{d:`m18 2 4 4-4 4`}),(0,r.jsx)(`path`,{d:`M2 18h1.973a4 4 0 0 0 3.3-1.7l5.454-8.6a4 4 0 0 1 3.3-1.7H22`}),(0,r.jsx)(`path`,{d:`M2 6h1.972a4 4 0 0 1 3.6 2.2`}),(0,r.jsx)(`path`,{d:`M22 18h-6.041a4 4 0 0 1-3.3-1.8l-.359-.45`})]}),Ee=e=>(0,r.jsxs)(`svg`,{...i(e),children:[(0,r.jsx)(`circle`,{cx:`9`,cy:`6`,r:`1`,fill:`currentColor`,stroke:`none`}),(0,r.jsx)(`circle`,{cx:`15`,cy:`6`,r:`1`,fill:`currentColor`,stroke:`none`}),(0,r.jsx)(`circle`,{cx:`9`,cy:`12`,r:`1`,fill:`currentColor`,stroke:`none`}),(0,r.jsx)(`circle`,{cx:`15`,cy:`12`,r:`1`,fill:`currentColor`,stroke:`none`}),(0,r.jsx)(`circle`,{cx:`9`,cy:`18`,r:`1`,fill:`currentColor`,stroke:`none`}),(0,r.jsx)(`circle`,{cx:`15`,cy:`18`,r:`1`,fill:`currentColor`,stroke:`none`})]}),v=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`m12 2 3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z`})}),De=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M4 5h16l-6 7v5l-4 2v-7L4 5z`})}),Oe=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M12 3v18M3 12h18M5.6 5.6l12.8 12.8M5.6 18.4 18.4 5.6M8.5 3.7l7 16.6M3.7 8.5l16.6 7M3.7 15.5l16.6-7M8.5 20.3l7-16.6`})}),y={anthropic:`claude-color.svg`,"anthropic-apikey":`claude-color.svg`,"claude-cli":`claude-color.svg`,"azure-openai":`openai.svg`,chatgpt:`openai.svg`,"cloudflare-ai-gateway":`cloudflare-ai-gateway-color.svg`,"cloudflare-workers-ai":`cloudflare-ai-gateway-color.svg`,cline:`cline-color.svg`,"cline-pass":`cline-color.svg`,"command-code":`commandcode-color.svg`,commandcode:`commandcode-color.svg`,cursor:`cursor-color.svg`,deepseek:`deepseek-color.svg`,devin:`devin.svg`,firepass:`firepass-color.svg`,fireworks:`fireworks-color.svg`,github:`github-copilot-color.svg`,"github-copilot":`copilot-color.svg`,"gitlab-duo":`gitlab-duo-color.svg`,google:`gemini-color.svg`,"google-antigravity":`antigravity-color.svg`,"google-vertex":`gemini-color.svg`,groq:`groq-color.svg`,huggingface:`huggingface-color.svg`,kimi:`kimi-color.svg`,"kimi-code":`kimi-color.svg`,"kimi-responses":`kimi-color.svg`,kiro:`kiro-color.svg`,"lm-studio":`lm-studio-color.svg`,"meta-model":`meta.svg`,"meta-muse":`meta.svg`,mistral:`mistral-color.svg`,minimax:`minimax.svg`,"minimax-cn":`minimax.svg`,moonshot:`moonshot-color.svg`,nvidia:`nvidia-color.svg`,ollama:`ollama-color.svg`,"ollama-cloud":`ollama-color.svg`,openai:`openai.svg`,"openai-apikey":`openai.svg`,"opencode-free":`opencode.svg`,"opencode-go":`opencode.svg`,"opencode-zen":`opencode.svg`,openrouter:`openrouter-color.svg`,opengateway:`opengateway.svg`,opper:`opper.svg`,qianfan:`qianfan-color.svg`,qoder:`qoder.svg`,"qoder-cn":`qoder.svg`,alibaba:`alibaba-color.svg`,"alibaba-token-plan":`alibaba-color.svg`,"alibaba-token-plan-intl":`alibaba-color.svg`,baseten:`baseten.svg`,bizrouter:`bizrouter.svg`,cerebras:`cerebras.svg`,crusoe:`crusoe.svg`,deepinfra:`deepinfra.svg`,digitalocean:`digitalocean.svg`,featherless:`featherless.svg`,hyperbolic:`hyperbolic.svg`,kilo:`kilo.svg`,nanogpt:`nanogpt.svg`,nebius:`nebius.svg`,neuralwatt:`neuralwatt.svg`,nous:`nous.svg`,novita:`novita.svg`,orcarouter:`orcarouter.svg`,"orcarouter-oauth":`orcarouter.svg`,packycode:`packycode.svg`,tokenlab:`tokenlab.svg`,parallel:`parallel.svg`,sambanova:`sambanova.svg`,scaleway:`scaleway.svg`,stepfun:`stepfun-color.svg`,siliconflow:`siliconflow.svg`,synthetic:`synthetic.svg`,together:`together.svg`,umans:`umans.svg`,venice:`venice.svg`,vultr:`vultr.svg`,litellm:`litellm.svg`,zenmux:`zenmux.svg`,zai:`zai.svg`,"zhipu-bigmodel":`zai.svg`,"zhipu-bigmodel-coding":`zai.svg`,"qwen-cloud":`qwen-portal-color.svg`,"vercel-ai-gateway":`vercel-ai-gateway-color.svg`,vllm:`vllm-color.svg`,xai:`grok.svg`,"mimo-free":`xiaomi-color.svg`,mimo:`xiaomi-color.svg`,xiaomi:`xiaomi-color.svg`,"xiaomi-mimo":`xiaomi-color.svg`},b={anthropic:`Anthropic Claude`,"anthropic-apikey":`Anthropic Claude`,chatgpt:`ChatGPT`,openai:`OpenAI (Codex login)`,"openai-apikey":`OpenAI API`,"azure-openai":`Azure OpenAI`,"cloudflare-ai-gateway":`Cloudflare AI Gateway`,"cloudflare-workers-ai":`Cloudflare Workers AI`,cline:`Cline`,"cline-pass":`ClinePass`,nvidia:`NVIDIA NIM`,ollama:`Ollama`,"ollama-cloud":`Ollama Cloud`,xai:`xAI Grok`,"mimo-free":`MiMo Free`,xiaomi:`Xiaomi`,cursor:`Cursor`,deepseek:`DeepSeek`,zed:`Zed`,devin:`Devin`,github:`GitHub`,"github-copilot":`GitHub Copilot`,"gitlab-duo":`GitLab Duo`,openrouter:`OpenRouter`,opengateway:`OpenGateway`,opper:`Opper`,"opencode-go":`OpenCode Go`,"opencode-free":`OpenCode Free`,"opencode-zen":`OpenCode Zen`,orcarouter:`OrcaRouter - API`,"orcarouter-oauth":`OrcaRouter - Auth`,packycode:`PackyCode`,tokenlab:`TokenLab`,mistral:`Mistral`,groq:`Groq`,"meta-model":`Meta Model API`,"meta-muse":`Muse Code`,alibaba:`Alibaba Coding Plan`,"alibaba-token-plan":`Alibaba Token Plan`,"alibaba-token-plan-intl":`Alibaba Token Plan (Intl)`,kimi:`Kimi`,"kimi-code":`Kimi`,"kimi-responses":`Kimi`,moonshot:`Moonshot`,google:`Google`,"google-vertex":`Google Vertex`,"lm-studio":`LM Studio`,huggingface:`Hugging Face`,"qwen-cloud":`Qwen Cloud`,siliconflow:`SiliconFlow`,stepfun:`StepFun`,"tencent-coding-plan":`Tencent Cloud Coding Plan`,codebuddy:`CodeBuddy`,"codebuddy-cn":`CodeBuddy CN`,qoder:`Qoder`,"qoder-cn":`Qoder CN`,"vercel-ai-gateway":`Vercel AI Gateway`,vllm:`vLLM`,litellm:`LiteLLM`},x={"command-code":`provider.name.commandCodeAuth`,commandcode:`provider.name.commandCodeApi`,orcarouter:`provider.name.orcaRouterApi`,"orcarouter-oauth":`provider.name.orcaRouterAuth`,volcengine:`provider.name.volcengine`,"volcengine-coding-plan":`provider.name.volcengineCodingPlan`,"volcengine-agent-plan":`provider.name.volcengineAgentPlan`},ke=new Set([...Object.keys(b),...Object.keys(x)]);function Ae(e){let t=e.toLowerCase();return Object.hasOwn(y,t)?y[t]:void 0}function je(e,t){let n=Ae(e);return n?`/provider-icons/${n}`:void 0}var Me=new Set([`cerebras.svg`,`deepinfra.svg`,`neuralwatt.svg`,`nous.svg`,`novita.svg`,`packycode.svg`,`tokenlab.svg`,`opper.svg`,`opengateway.svg`,`siliconflow.svg`,`synthetic.svg`,`zenmux.svg`,`grok.svg`,`kimi-color.svg`,`ollama-color.svg`,`opencode.svg`,`vercel-ai-gateway-color.svg`]),Ne=new Set([`baseten.svg`,`kilo.svg`,`sambanova.svg`,`venice.svg`,`zai.svg`]),Pe=new Set([`bizrouter.svg`,`featherless.svg`,`hyperbolic.svg`,`nebius.svg`,`parallel.svg`,`umans.svg`]);function Fe(e){if(!e)return`image`;let t=e.split(`/`).pop()??``;return Me.has(t)?`mask`:Ne.has(t)?`plate`:Pe.has(t)?`dark-plate`:`image`}function S(e,t){let n=e.toLowerCase(),r=Object.hasOwn(x,n)?x[n]:void 0;return r?t(r):(Object.hasOwn(b,n)?b[n]:void 0)||(e===n&&/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(e)?e.split(`-`).map(e=>e&&e[0].toUpperCase()+e.slice(1)).join(` `):e)}function Ie(e){return ke.has(e.toLowerCase())}function Le(e){return e===`command-code`?`commandcode-auth`:e===`commandcode`?`commandcode-api`:e}function Re(e,t){let n=e.indexOf(`/`);if(n<=0)return e;let r=e.slice(0,n),i=e.slice(n+1);if(r===`command-code`||r===`commandcode`){let e=i.match(/^([a-z0-9]+)-([a-z0-9]+(?:-[a-z0-9]+)+)$/i);return e&&i.startsWith(`${e[1]}-${e[1]}-`)&&(i=i.slice(e[1].length+1)),`${r===`command-code`?`commandcode-auth`:`commandcode-api`}/${i}`}return e}var ze={ko:[{v:0x2386f26fc10000,s:`경`},{v:0xe8d4a51000,s:`조`},{v:1e8,s:`억`},{v:1e4,s:`만`}],zh:[{v:0x2386f26fc10000,s:`京`},{v:0xe8d4a51000,s:`兆`},{v:1e8,s:`亿`},{v:1e4,s:`万`}],"zh-TW":[{v:0x2386f26fc10000,s:`京`},{v:0xe8d4a51000,s:`兆`},{v:1e8,s:`億`},{v:1e4,s:`萬`}]};function C(e){return e.replace(/\.0+$/,``).replace(/(\.\d*?)0+$/,`$1`)}function Be(e,t){let n=ze[t];if(n){for(let t of n)if(e>=t.v)return`${C((e/t.v).toFixed(1))}${t.s}`;return String(e)}return e<1e4?String(e):e<1e6?`${C((e/1e3).toFixed(1))}K`:e<1e9?`${C((e/1e6).toFixed(1))}M`:e<0xe8d4a51000?`${C((e/1e9).toFixed(1))}B`:`${C((e/0xe8d4a51000).toFixed(1))}T`}var Ve=new Set([`claude-cli`]),He=`anthropic-apikey`;function w(e){return Ve.has((e.adapter??``).trim())}var T=`https://chatgpt.com/backend-api/codex`,Ue=`openai`;function E(e){try{let t=new URL(e.trim());if(t.username||t.password||t.search||t.hash)return;let n=t.pathname.replace(/\/+$/,``);return`${t.origin}${n}`}catch{return}}var We=new URL(T).protocol;function D(e,...t){return`${We}//${e}/${t.join(`/`)}`}var Ge={"cline-pass":{adapter:`openai-chat`,baseUrl:D(`api.cline.bot`,`api`,`v1`)},"mimo-free":{adapter:`mimo-free`,baseUrl:D(`api.xiaomimimo.com`,`api`,`free-ai`,`openai`,`chat`)}};function Ke(e,t){let n=Ge[e];return!n||t.adapter!==n.adapter||E(t.baseUrl)!==E(n.baseUrl)}function O(e){try{let t=new URL(e).hostname.replace(/^\[|\]$/g,``).toLowerCase();return t===`localhost`||t===`127.0.0.1`||t===`::1`}catch{return!1}}function k(e){return e.keyOptional===!0||w(e)||e.authMode===`oauth`||e.authMode===`forward`||e.authMode===`local`||O(e.baseUrl)||e.hasApiKey===!0}function A(e){return e.adapter===`openai-responses`&&e.authMode===`forward`&&E(e.baseUrl)===T}function j(e,t){return e===Ue&&A(t)}function M(e){return w(e)?!1:e.freeTier===!0||e.keyOptional===!0||e.authMode===`local`||O(e.baseUrl)}function N(e,t){return j(e,t)?`accounts`:M(t)?`free`:`paid`}function qe(e,t){let n=[...e],r=(e,t)=>e.name.localeCompare(t.name,void 0,{sensitivity:`base`}),i=e=>e.tier??N(e.name,e);switch(t){case`az`:return n.sort(r);case`za`:return n.sort((e,t)=>r(t,e));case`free-paid`:return n.sort((e,t)=>(i(e)===`free`?0:1)-(i(t)===`free`?0:1)||r(e,t));case`paid-free`:return n.sort((e,t)=>(i(e)===`free`)-+(i(t)===`free`)||r(e,t));case`accounts-first`:return n.sort((e,t)=>{let n=e=>{let t=i(e);return t===`accounts`?0:t===`free`?1:2};return n(e)-n(t)||r(e,t)});default:return n}}function Je(e){let t=[],n=[],r=[];for(let[i,a]of Object.entries(e)){if(a.disabled){r.push({name:i,...a});continue}k(a)?t.push({name:i,...a,tier:N(i,a)}):n.push({name:i,...a})}return{ready:t,needsSetup:n,disabled:r}}function Ye(e,t){let n=new Set(Object.entries(t).filter(([,e])=>e).map(([e])=>e));if(n.size===0)return e;let r=e=>e.map(e=>n.has(e.name)?{...e,activeNeedsReauth:!0}:e);return{ready:r(e.ready),needsSetup:r(e.needsSetup),disabled:e.disabled}}function P(e){return e.disabled?`disabled`:`activeNeedsReauth`in e&&e.activeNeedsReauth?`needs-setup`:k(e)?`ready`:`needs-setup`}function Xe(e){let t=e.openai,n=e.chatgpt;if(!t||!n||!j(`openai`,t)||!A(n))return e;let r={...e};return delete r.chatgpt,r}function F(e){return e.authMode===`local`||O(e.baseUrl)}var Ze=[`ollama`,`vllm`,`lm-studio`,`lmstudio`,`litellm`,`localai`];function Qe(e){let t=(e.authMode??``).toLowerCase();if(t===`oauth`||t===`forward`)return`login`;if(F(e))return`local`;let n=`${e.name??``} ${e.adapter} ${e.baseUrl}`.toLowerCase();return Ze.some(e=>n.includes(e))?`selfHosted`:`cloud`}function I(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e;if(typeof n.updatedAt!=`number`||!Number.isFinite(n.updatedAt))return null;let r=n.observed===!0;return!r&&t-n.updatedAt>=18e5||!(`quota`in n)||n.label!==void 0&&typeof n.label!=`string`||n.source!==void 0&&typeof n.source!=`string`?null:{...typeof n.label==`string`?{label:n.label}:{},...typeof n.source==`string`?{source:n.source}:{},updatedAt:n.updatedAt,quota:n.quota,...r?{observed:!0}:{},...n.aggregation===void 0?{}:{aggregation:n.aggregation}}}function $e(e,t=Date.now()){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n={};for(let[r,i]of Object.entries(e)){let e=I(i,t);r.trim()&&e&&(n[r]=e)}return n}function et(e,t=Date.now()){if(!Array.isArray(e))return{};let n={};for(let r of e){if(!r||typeof r!=`object`||Array.isArray(r))continue;let e=r.provider,i=I(r,t);typeof e==`string`&&e.trim()&&i&&(n[e]=i)}return n}function tt(e){return e?.observed===!0&&typeof e.updatedAt==`number`?e.updatedAt:void 0}var L=e=>typeof e==`number`&&Number.isFinite(e)?e:void 0,nt=e=>{let t=L(e);if(t===void 0)return;let n=t>1e10?t:t*1e3;return Number.isFinite(new Date(n).getTime())?t:void 0};function R(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e,r=Array.isArray(n.customWindows)?n.customWindows.flatMap(e=>{if(!e||typeof e!=`object`)return[];let t=e;return typeof t.label!=`string`||L(t.percent)===void 0?[]:[{label:t.label,percent:t.percent,...L(t.resetAt)===void 0?{}:{resetAt:t.resetAt}}]}):[],i=n.creditsUsd&&typeof n.creditsUsd==`object`&&!Array.isArray(n.creditsUsd)?n.creditsUsd:null,a=L(i?.used),o=L(i?.limit),s=L(i?.remaining),c=L(i?.percent),l=nt(i?.expiresAt),u=a!==void 0&&o!==void 0&&s!==void 0&&c!==void 0?{used:a,limit:o,remaining:s,percent:c,...l===void 0?{}:{expiresAt:l},...typeof i?.unlimited==`boolean`?{unlimited:i.unlimited}:{}}:void 0,d={...L(n.fiveHourPercent)===void 0?{}:{fiveHourPercent:n.fiveHourPercent},...L(n.fiveHourResetAt)===void 0?{}:{fiveHourResetAt:n.fiveHourResetAt},...L(n.weeklyPercent)===void 0?{}:{weeklyPercent:n.weeklyPercent},...L(n.weeklyResetAt)===void 0?{}:{weeklyResetAt:n.weeklyResetAt},...L(n.monthlyPercent)===void 0?{}:{monthlyPercent:n.monthlyPercent},...L(n.monthlyResetAt)===void 0?{}:{monthlyResetAt:n.monthlyResetAt},...r.length>0?{customWindows:r}:{},...u?{creditsUsd:u}:{},updatedAt:L(n.updatedAt)??t??Date.now()};return d.fiveHourPercent!==void 0||d.weeklyPercent!==void 0||d.monthlyPercent!==void 0||(d.customWindows?.length??0)>0||d.creditsUsd!==void 0?d:null}function z(e){return R(e?.quota,e?.updatedAt)}function rt(e){if(!e)return;if(e.aggregation===void 0)return e;let t=V(e)?.currentAccount?.quota??null;return{...e,aggregation:void 0,quota:t,updatedAt:t?.updatedAt}}function B(e){if(!e||typeof e!=`object`||Array.isArray(e))return;let t=e,n=L(t.usedPercent);if(n!==void 0)return{usedPercent:n,...typeof t.incomplete==`boolean`?{incomplete:t.incomplete}:{},...L(t.excludedAccounts)===void 0?{}:{excludedAccounts:t.excludedAccounts},...L(t.nextRecoveryAt)===void 0?{}:{nextRecoveryAt:t.nextRecoveryAt},...L(t.nextRecoveryPercent)===void 0?{}:{nextRecoveryPercent:t.nextRecoveryPercent}}}function V(e){let t=e?.aggregation;if(!t||typeof t!=`object`||Array.isArray(t))return null;let n=t;if(n.kind!==`capacity-weighted-v1`||n.scope!==`routable-known`)return null;let r=L(n.excludedAccounts),i=L(n.unknownPlanAccounts);if(r===void 0||i===void 0||typeof n.incomplete!=`boolean`)return null;let a=n.currentAccount&&typeof n.currentAccount==`object`&&!Array.isArray(n.currentAccount)?n.currentAccount:null,o=Array.isArray(n.customWindows)?n.customWindows.flatMap(e=>{if(!e||typeof e!=`object`||Array.isArray(e))return[];let t=e,n=B(t);return typeof t.label==`string`&&n?[{label:t.label,...n}]:[]}):[],s=B(n.fiveHour),c=B(n.weekly),l=B(n.monthly),u=!!s||!!c||!!l||o.length>0;return{presentation:n.presentation===`aggregate`||n.presentation===`effective-account-fallback`||n.presentation===`coverage-only`?n.presentation:u?`aggregate`:`coverage-only`,incomplete:n.incomplete,excludedAccounts:r,unknownPlanAccounts:i,partialWindowAccounts:L(n.partialWindowAccounts)??0,...s?{fiveHour:s}:{},...c?{weekly:c}:{},...l?{monthly:l}:{},...o.length>0?{customWindows:o}:{},...a?{currentAccount:{...typeof a.plan==`string`||a.plan===null?{plan:a.plan}:{},quota:R(a.quota)}}:{}}}function it(e){if(!e?.trim())return``;let[t,n]=e.split(`:`,2);return n?`${t} · ${n.replace(/-/g,` `)}`:e}function at(e,t){let n=P(e);return n===`disabled`?t(`prov.disabledBadge`):n===`ready`?t(`pws.status.ready`):`activeNeedsReauth`in e&&e.activeNeedsReauth?t(`pws.status.needsAttention`):t(`pws.status.needsSetup`)}function ot(e,t){if(w(e))return t(`modal.badge.subscriptionCli`);switch(e.authMode){case`oauth`:return t(`modal.badge.oauth`);case`forward`:return t(`pws.auth.chatgptPassthrough`);case`local`:return t(`modal.badge.local`);case`key`:return t(`modal.badge.apiKey`);default:return e.authMode??(e.keyOptional?t(`pws.auth.noKey`):t(`modal.badge.apiKey`))}}function st(e){let t=P(e);return t===`disabled`?`providers-workspace-rail-status providers-workspace-rail-status--inactive`:t===`ready`?`providers-workspace-rail-status providers-workspace-rail-status--active`:`providers-workspace-rail-status providers-workspace-rail-status--warning`}function H({name:e,adapter:t,baseUrl:i,cls:a}){let o=n(),s=je(e,{adapter:t,baseUrl:i}),c=Fe(s),l=c===`plate`?`${a} provider-icon--plate`:c===`dark-plate`?`${a} provider-icon--plate-dark`:a;return(0,r.jsx)(`span`,{className:l,children:s&&c===`mask`?(0,r.jsx)(`span`,{className:`provider-icon-mask`,style:{maskImage:`url(${s})`,WebkitMaskImage:`url(${s})`},"aria-hidden":`true`}):s?(0,r.jsx)(`img`,{src:s,alt:``,"aria-hidden":`true`}):(0,r.jsx)(ct,{name:e,label:S(e,o)})})}function ct({name:e,label:t}){let n=[...e].reduce((e,t)=>e+t.charCodeAt(0),0)%360,i=(t.trim()[0]??e[0]??`?`).toUpperCase();return(0,r.jsx)(`span`,{className:`provider-icon-fallback`,style:{background:`hsl(${n} 55% 90%)`,color:`hsl(${n} 65% 32%)`},"aria-hidden":`true`,children:i})}function lt({item:e,selected:t,tabbable:i,modelCount:a,isDefault:o,showConfigId:s,onClick:c,onFocus:l}){let u=n(),d=M(e),f=F(e),p=at(e,u),m=S(e.name,u),h=s?`${m} (${e.name})`:m,g=`${o?u(`pws.rail.suffixDefault`):``}${f?u(`pws.rail.suffixLocal`):d?u(`pws.rail.suffixFree`):``}`,ee=a!==void 0&&a>0?a===1?u(`pws.modelCountOne`):u(`pws.modelCount`,{count:a}):``,_=[s?e.name:``,ee].filter(Boolean).join(` · `);return(0,r.jsxs)(`button`,{type:`button`,className:`providers-workspace-rail-row${t?` providers-workspace-rail-row--selected`:``}`,onClick:c,role:`option`,"aria-selected":t,tabIndex:i?0:-1,"aria-label":u(`pws.rail.selectAria`,{name:h,status:p,suffix:g}),title:h,onFocus:l,children:[(0,r.jsx)(H,{name:e.name,adapter:e.adapter,baseUrl:e.baseUrl,cls:`providers-workspace-rail-icon`}),(0,r.jsxs)(`span`,{className:`providers-workspace-rail-copy`,children:[(0,r.jsxs)(`span`,{className:`providers-workspace-rail-primary`,children:[(0,r.jsx)(`span`,{className:`providers-workspace-rail-name-label`,title:m,children:m}),f?(0,r.jsx)(`span`,{className:`pwi-rail-badge pwi-rail-badge--local`,title:u(`pws.localTitle`),children:u(`modal.badge.local`)}):d?(0,r.jsx)(`span`,{className:`pwi-rail-badge pwi-rail-badge--free`,title:u(`pws.freeTitle`),children:u(`modal.badge.free`)}):null]}),(0,r.jsx)(`span`,{className:`providers-workspace-rail-secondary`,title:_||void 0,children:_||`\xA0`})]}),(0,r.jsxs)(`span`,{className:`providers-workspace-rail-trail`,children:[o&&(0,r.jsx)(`span`,{className:`pwi-default-star`,title:u(`prov.defaultBadge`),"aria-label":u(`prov.defaultBadge`),children:(0,r.jsx)(v,{width:17,height:17,"aria-hidden":`true`})}),(0,r.jsx)(`span`,{className:st(e),title:p,"aria-hidden":`true`})]})]})}var ut=1e10;function dt(e){return e<ut?e*1e3:e}function ft(e,t){let n=e=>typeof e==`number`&&Number.isFinite(e);if(!n(e.shortPercent)||e.shortPercent<100)return!1;let r=e.shortResetAt;if(!n(r)||r<=0){let r=e.shortObservedAt;if(!n(r))return!1;let i=t-r;return i>=0&&i<=3e5}return dt(r)>t}function pt(e){return{fiveHourAvailable:e?.shortWindowSeconds===18e3&&typeof e.shortResetAt==`number`,weeklyAvailable:typeof e?.weeklyResetAt==`number`}}function U(e){let t=e?.trim().toLowerCase();return t===`go`||t===`free`}function W(e,t){if(!e)return null;let n=e.shortPercent===void 0&&e.shortResetAt===void 0?e:{...e,fiveHourPercent:e.fiveHourPercent??e.shortPercent,fiveHourResetAt:e.fiveHourResetAt??e.shortResetAt};return U(t)?{...n.monthlyPercent===void 0?{}:{monthlyPercent:n.monthlyPercent},...n.monthlyResetAt===void 0?{}:{monthlyResetAt:n.monthlyResetAt},...n.creditsUsd===void 0?{}:{creditsUsd:n.creditsUsd},...n.resetCredits===void 0?{}:{resetCredits:n.resetCredits},updatedAt:n.updatedAt}:n}function mt(e,t,n=Date.now()){if(!e)return null;let r=e=>typeof e==`number`&&Number.isFinite(e),i=r(e.fiveHourPercent)?e.fiveHourPercent:r(e.shortPercent)?e.shortPercent:void 0,a=(U(t)?[e.monthlyPercent]:[e.weeklyPercent,e.monthlyPercent]).filter(r);if(a.length===0)return ft({...r(i)?{shortPercent:i}:{},...r(e.fiveHourResetAt??e.shortResetAt)?{shortResetAt:e.fiveHourResetAt??e.shortResetAt}:{},...r(e.shortObservedAt)?{shortObservedAt:e.shortObservedAt}:{}},n)?100:null;let o=r(i)?[...a,i]:a;return o.length?Math.max(...o):null}function ht(e){let t=new URLSearchParams({hours:String(e.chartHours),bucketMinutes:String(e.bucketMinutes),metric:e.tokenMetric,aggregation:e.aggregation,grouping:e.chartGrouping});e.models?.length&&t.set(`models`,e.models.join(`,`));for(let n of e.hiddenProviders)t.append(`hiddenProvider`,n);return t}function G(e){return Array.isArray(e)&&e.length<=100&&e.every(e=>typeof e==`string`)?JSON.stringify([...new Set(e)].sort()):void 0}function gt(e,t){let n=new Set(t.hiddenProviders),r=e.availableModels.filter(e=>!n.has(e.slice(0,e.indexOf(`/`))));if(t.models?.length===0)return{...e,series:[],availableModels:r};let i=t.models===null?null:new Set(t.models),a=i!==null||n.size>0,o=e.appliedFilters,s=!!o&&G(o.hiddenProviders)===G(t.hiddenProviders)&&(t.models===null?o.models===null:G(o.models)===G(t.models)),c=e.series.filter(e=>e.id===`other`&&e.provider===``?!a||s:!n.has(e.provider)&&(i===null||i.has(`${e.provider}/${e.model}`)||i.has(e.model)));return{...e,series:c,availableModels:r,truncated:e.truncated||(a||o!==void 0)&&!s}}var _t={6:15,24:60,72:180,168:360};function vt(e){return _t[e]}function K(e){if(e<1e3)return String(Math.round(e));let t=[[0xe8d4a51000,`T`],[1e9,`B`],[1e6,`M`],[1e3,`K`]];for(let n=0;n<t.length;n+=1){let[r,i]=t[n];if(e>=r){let a=Math.round(e/r);if(a>=1e3&&n>0){let[r,i]=t[n-1];return`${Math.round(e/r)}${i}`}return`${a}${i}`}}return String(Math.round(e))}function yt(e,t){let n=new Map;for(let r of e){let e=r.includes(`/`)?r.slice(0,r.indexOf(`/`)):r,i=n.get(e)??{provider:e,models:[],total:0},a=t.get(r)??0;i.models.push({id:r,total:a}),i.total+=a,n.set(e,i)}return Array.from(n.values()).map(e=>({...e,models:e.models.toSorted((e,t)=>t.total-e.total||e.id.localeCompare(t.id))})).toSorted((e,t)=>t.total-e.total||e.provider.localeCompare(t.provider))}function bt(e,t,n,r){let i=new Set(t),a=new Set((e??t).filter(e=>i.has(e)));for(let e of n)r?a.add(e):a.delete(e);return t.length>0&&t.every(e=>a.has(e))?null:t.filter(e=>a.has(e))}function xt(e,t=[]){let n={...e};if(typeof n.menuBarTemplate==`string`&&n.menuBarTemplate.trim()===``&&(n.menuBarTemplate=null),n.models!==void 0&&t.length>0){let e=n.models??[],r=new Set(e);e.length===t.length&&t.every(e=>r.has(e))&&(n.models=null)}return n}function St(e,t,n,r,i=8){let a=Math.max(0,t-i*2),o=Math.max(0,n-i*2),s=Math.max(r,1),c=Math.max(e.length-1,1);return e.map((e,t)=>`${i+a*t/c},${i+o*(1-Math.max(0,e)/s)}`).join(` `)}function Ct(e,t,n,r,i=8){let a=e[0]?.points.length??0;if(a===0)return[];let o=Math.max(0,t-i*2),s=Math.max(0,n-i*2),c=Math.max(r,1),l=Math.min(3,o/Math.max(a*8,1)),u=Math.max(0,o/a-l),d=[];for(let t=0;t<a;t+=1){let n=0;for(let r=0;r<e.length;r+=1){let f=s*Math.max(0,e[r]?.points[t]??0)/c;f>0&&d.push({x:i+o/a*t+l/2,y:i+s-n-f,width:u,height:f,seriesIndex:r,bucketIndex:t}),n+=f}}return d}var q=[`#0A84FF`,`#FF9F0A`,`#30D158`,`#BF5AF2`,`#FF453A`,`#64D2FF`],wt=640,Tt=160,J=28;function Et(e,t){return Math.max(...t===`stackedBar`?Array.from({length:e.buckets},(t,n)=>e.series.reduce((e,t)=>e+(t.points[n]??0),0)):e.series.flatMap(e=>e.points),0)}function Dt(e,t){let n=new Intl.DateTimeFormat(t,{month:`short`,day:`numeric`}),r=Math.max(1,Math.floor((e.buckets-1)/3));return[0,1,2,3].map(t=>{let i=Math.min(e.buckets-1,t*r);return n.format(new Date((e.start+i*e.bucketSeconds)*1e3))})}function Ot({timeline:e,chartStyle:t,hours:n,loading:i,error:a,onRetry:o,locale:s,t:c}){if(i)return(0,r.jsx)(`div`,{className:`usage-companion-chart-skeleton`,"aria-busy":`true`,"aria-label":c(`usage.companion.loading`)});if(a)return(0,r.jsxs)(`div`,{className:`usage-companion-chart-state`,role:`alert`,children:[(0,r.jsx)(`span`,{children:c(`usage.companion.timelineUnavailable`)}),(0,r.jsx)(`button`,{type:`button`,className:`btn btn-ghost btn-sm`,onClick:o,children:c(`common.retry`)})]});if(!e||e.series.length===0)return(0,r.jsx)(`div`,{className:`usage-companion-chart-state`,children:c(`usage.companion.empty`,{hours:e?.buckets?Math.round(e.buckets*e.bucketSeconds/3600):n})});let l=Et(e,t),u=Dt(e,s),d=J,f=u.map((e,t)=>(0,r.jsx)(`text`,{x:J+584*t/3,y:156,textAnchor:t===0?`start`:t===3?`end`:`middle`,className:`usage-companion-axis-label`,children:e},`${e}-${t}`)),p=t===`line`?e.series.map((e,t)=>(0,r.jsx)(`polyline`,{points:St(e.points,584,104,l,0),transform:`translate(${J},${J})`,fill:`none`,stroke:q[t%q.length],strokeWidth:`2`,strokeLinejoin:`round`,strokeLinecap:`round`},e.id)):Ct(e.series,584,104,l,0).map(e=>(0,r.jsx)(`rect`,{x:J+e.x,y:J+e.y,width:e.width,height:e.height,fill:q[e.seriesIndex%q.length],rx:`1`},`${e.bucketIndex}-${e.seriesIndex}`));return(0,r.jsxs)(`div`,{className:`usage-companion-chart`,children:[(0,r.jsxs)(`svg`,{viewBox:`0 0 ${wt} ${Tt}`,role:`img`,"aria-label":c(`usage.companion.chartLabel`),children:[(0,r.jsx)(`line`,{x1:J,y1:d,x2:J,y2:132,className:`usage-companion-axis`}),(0,r.jsx)(`line`,{x1:J,y1:132,x2:612,y2:132,className:`usage-companion-axis`}),(0,r.jsx)(`text`,{x:24,y:32,textAnchor:`end`,className:`usage-companion-axis-label`,children:K(l)}),p,f]}),(0,r.jsx)(`div`,{className:`usage-companion-legend`,children:e.series.map((e,t)=>(0,r.jsxs)(`span`,{className:`usage-companion-legend-item`,children:[(0,r.jsx)(`span`,{className:`usage-companion-swatch`,style:{background:q[t%q.length]},"aria-hidden":`true`}),(0,r.jsx)(`span`,{children:e.id})]},e.id))}),e.truncated&&(0,r.jsx)(`p`,{className:`muted text-caption`,children:c(`usage.companion.olderRecordsSkipped`)})]})}var Y=e=>typeof e==`number`&&Number.isFinite(e)&&e>=0,X=e=>typeof e==`object`&&e&&!Array.isArray(e)?e:{};function kt(e){return Object.entries(X(X(e).providers)).flatMap(([e,t])=>{let n=X(t);return n.disabled===!0?[]:e===`openai`?[{name:e,path:`/api/codex-auth/accounts`,switchKind:`codex`}]:n.authMode===`oauth`?[{name:e,path:`/api/oauth/accounts?${new URLSearchParams({provider:e,quota:`1`})}`,switchKind:`oauth`}]:n.hasApiKey===!0&&n.authMode!==`forward`?[{name:e,path:`/api/providers/keys?${new URLSearchParams({name:e,quota:`1`})}`,switchKind:`apiKey`}]:[{name:e,path:null,switchKind:null}]})}function At(e,t,n){return t===`codex`?{path:`/api/codex-auth/active`,body:{accountId:n}}:t===`oauth`?{path:`/api/oauth/accounts/active`,body:{provider:e,accountId:n}}:{path:`/api/providers/keys/active`,body:{name:e,id:n}}}function jt(e,t){return t?{switchState:`active`}:X(e.mainAccountHardLock).state===`blocked`?{switchState:`blocked`,blockedReason:`mainHardLock`}:e.paused===!0?{switchState:`blocked`,blockedReason:`paused`}:X(e.health).reason===`validation_pending`?{switchState:`blocked`,blockedReason:`validationPending`}:{switchState:`available`}}function Mt(e,t){let n=[`go`,`free`].includes((t??``).trim().toLowerCase()),r=e.fiveHourPercent??e.shortPercent;return(n?[e.monthlyPercent,r]:[e.weeklyPercent,e.monthlyPercent,r]).some(e=>typeof e==`number`&&Number.isFinite(e)&&e>=100)}function Nt(e){let t=X(e),n=t.accounts??t.keys;if(!Array.isArray(n))throw Error(`Invalid account roster`);return n.map(e=>{let n=X(e);if(typeof n.id!=`string`)throw Error(`Invalid account identifier`);let r=typeof n.email==`string`?Pt(n.email):void 0,i=[n.alias,n.label,r,n.logLabel,n.id].find(e=>typeof e==`string`&&e.length),a=n.quotaUnavailable===!0||n.quotaMode===`unsupported`||!n.quota?null:X(n.quota),o=typeof n.plan==`string`?n.plan:void 0,s=t.activeAccountId??t.activeId??t.activeCodexAccountId,c=typeof s==`string`?s===n.id:n.active===!0;return{id:n.id,label:i,email:r,plan:o,unavailable:n.quotaUnavailable===!0,active:c,...jt(n,c),exhausted:a!==null&&Mt(X(n.quota),o),status:typeof X(n.health).status==`string`?X(n.health).status:void 0,quotaFailure:typeof n.quotaFailure==`string`?n.quotaFailure:void 0,quota:W(a,o)}})}function Z(e){if(!Y(e)||e===0)return null;let t=e<0xe8d4a51000?e*1e3:e;return Number.isFinite(new Date(t).getTime())?t:null}function Pt(e){let[t,n]=e.split(`@`);if(!n)return`•••`;let r=n.includes(`.`)?n.slice(n.lastIndexOf(`.`)):``;return`${t?.slice(0,1)||`•`}•••@${n.slice(0,1)}•••${r}`}function Ft(e,t,n=Date.now()){let r=Z(e);if(r===null||r<=n)return{text:`—`};let i=Math.ceil((r-n)/6e4),a=(e,n)=>new Intl.NumberFormat(t,{style:`unit`,unit:n,unitDisplay:`narrow`}).format(e);return{text:i<60?a(i,`minute`):i<1440?`${a(Math.floor(i/60),`hour`)} ${a(i%60,`minute`)}`:i<10080?`${a(Math.floor(i/1440),`day`)} ${a(Math.floor(i%1440/60),`hour`)}`:new Intl.DateTimeFormat(t,{month:`short`,day:`numeric`}).format(r),exact:new Date(r).toLocaleString(t)}}function It(e){if(!e)return[];let t=[{id:`quota.fiveHourLimit`,key:`quota.fiveHourLimit`,percent:e.fiveHourPercent??e.shortPercent,reset:e.fiveHourResetAt??e.shortResetAt},{id:`quota.weeklyLimit`,key:`quota.weeklyLimit`,percent:e.weeklyPercent,reset:e.weeklyResetAt},{id:`quota.monthlyLimit`,key:`quota.monthlyLimit`,percent:e.monthlyPercent,reset:e.monthlyResetAt},...Array.isArray(e.customWindows)?e.customWindows.filter(e=>e&&typeof e.label==`string`).map(e=>({id:e.label,label:e.label,percent:e.percent,reset:e.resetAt})):[]].filter(e=>Y(e.percent)||Z(e.reset)!==null),n=new Map;return t.map(e=>{let t=n.get(e.id)??0;return n.set(e.id,t+1),t===0?e:{...e,id:`${e.id}#${t}`}})}function Lt(e,t){let n=new Set(t.hiddenProviders),r=t.models===null?null:new Set(t.models),i=e.models.filter(e=>!n.has(e.provider)&&(r===null||r.has(`${e.provider}/${e.model}`)||r.has(e.model)));if(t.models===null&&t.hiddenProviders.length===0)return{...e,models:i};if(t.models?.length!==0&&e.models.some(e=>!e.provider||!e.model||e.provider===`other`&&e.model===`other`))return{...e,models:i.filter(e=>e.provider!==`other`||e.model!==`other`),summary:{},usageIncomplete:!0};let a={};for(let e of[`requests`,`totalTokens`,`inputTokens`,`outputTokens`,`cachedInputTokens`,`cacheReadInputTokens`,`estimatedCostUsd`,`measuredRequests`,`pricedRequests`])i.length&&i.every(t=>Y(t[e]))&&(a[e]=i.reduce((t,n)=>t+n[e],0));return{...e,models:i,summary:a}}function Rt(e){let t={...e};if((e.requests??0)>0&&(e.measuredRequests===0||e.coverageRatio===0))for(let e of[`totalTokens`,`inputTokens`,`outputTokens`,`cachedInputTokens`,`cacheReadInputTokens`])delete t[e];return(e.requests??0)>0&&e.pricedRequests===0&&delete t.estimatedCostUsd,t}async function zt(t,n){let r=e(2e4),i=()=>r.controller.abort();n.aborted&&i(),n.addEventListener(`abort`,i,{once:!0});try{let e=await fetch(t,{signal:r.signal,cache:`no-store`});if(!e.ok)throw Error(String(e.status));let n=await e.json();if(r.signal.aborted)throw Error(`Tray request cancelled`);return n}finally{r.clear(),n.removeEventListener(`abort`,i)}}function Bt(e){let t=X(e);if(t.error||!t.summary||typeof t.summary!=`object`||Array.isArray(t.summary)||!Array.isArray(t.models))throw Error(`Invalid usage`);return t}var Q=e=>typeof e==`number`&&Number.isFinite(e);function $(e){return Q(e)?e>=90?`critical`:e>=70?`warn`:`normal`:`normal`}function Vt(e){return Q(e)?`${Math.floor(e)}%`:`-`}var Ht=[`quota.weeklyLimit`,`quota.monthlyLimit`,`quota.fiveHourLimit`];function Ut(e){let t=It(e).map(e=>{let t=Q(e.percent)?e.percent:void 0,n=Z(e.reset);return{id:e.id,...`key`in e&&e.key?{labelKey:e.key}:{},...`label`in e&&typeof e.label==`string`?{label:e.label}:{},...t===void 0?{}:{percent:t},...n===null?{}:{resetAt:n},severity:$(t)}}),n=e.creditsUsd;if(n&&n.unlimited!==!0&&Q(n.percent)){let e=Z(n.expiresAt);t.push({id:`quotaSummary.credits`,labelKey:`quotaSummary.credits`,percent:n.percent,...e===null?{}:{resetAt:e},severity:$(n.percent)})}return t}function Wt(e){let t=e.filter(e=>e.percent!==void 0),n=new Map(t.map(e=>[e.id,e]));for(let e of Ht){let t=n.get(e);if(t)return t}return t[0]}function Gt(e,t){let n=[];for(let[r,i]of Object.entries(e)){let e=z(i);if(!e)continue;let a=Ut(e),o=Wt(a);o&&n.push({provider:r,label:i.label?.trim()||t(r),headline:o,windows:a,...Q(i.updatedAt)?{updatedAt:i.updatedAt}:{},observed:i.observed===!0,severity:o.severity})}return n}export{p as $,rt as A,ee as At,Xe as B,re as Bt,W as C,u as Ct,ot as D,te as Dt,lt as E,d as Et,F,Te as Ft,qe as G,M as H,Qe as I,v as It,Be as J,He as K,Ye as L,xe as Lt,$e as M,_ as Mt,et as N,ce as Nt,z as O,ae as Ot,tt as P,o as Pt,Le as Q,P as R,f as Rt,mt as S,ve as St,H as T,Se as Tt,Ke as U,j as V,g as Vt,N as W,S as X,Re as Y,Ie as Z,gt as _,m as _t,zt as a,h as at,yt as b,be as bt,Rt as c,_e as ct,kt as d,ie as dt,oe as et,It as f,De as ft,xt as g,Ee as gt,vt as h,a as ht,At as i,s as it,it as j,me as jt,V as k,ne as kt,Nt as l,de as lt,Ot as m,we as mt,Vt as n,le as nt,Lt as o,fe as ot,Ft as p,pe as pt,w as q,$ as r,c as rt,Y as s,Oe as st,Gt as t,ue as tt,Bt as u,he as ut,ht as v,se as vt,pt as w,Ce as wt,bt as x,l as xt,K as y,ge as yt,Je as z,ye as zt};
|
package/gui/dist/index.html
CHANGED
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
document.documentElement.lang = langMap[locale];
|
|
36
36
|
})();
|
|
37
37
|
</script>
|
|
38
|
-
<script type="module" crossorigin src="/assets/index-
|
|
39
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
38
|
+
<script type="module" crossorigin src="/assets/index-CvnY7E6i.js"></script>
|
|
39
|
+
<link rel="stylesheet" crossorigin href="/assets/index-Btze1I3T.css">
|
|
40
40
|
</head>
|
|
41
41
|
<body>
|
|
42
42
|
<div id="root"></div>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1140 650" width="1140" height="650" fill="none" role="img" aria-label="OpenGateway">
|
|
2
|
+
<title>OpenGateway</title>
|
|
3
|
+
<g id="logo" stroke="currentColor" fill="currentColor">
|
|
4
|
+
<rect id="node-in" x="36" y="36" width="420" height="578" rx="89" fill="none" stroke-width="72"/>
|
|
5
|
+
<rect id="bar-in" x="72" y="272" width="277" height="106" stroke="none"/>
|
|
6
|
+
<path id="node-out" d="M684 213 L684 125 A89 89 0 0 1 773 36 L1015 36 A89 89 0 0 1 1104 125 L1104 525 A89 89 0 0 1 1015 614 L773 614 A89 89 0 0 1 684 525 L684 436" fill="none" stroke-width="72" stroke-linecap="butt"/>
|
|
7
|
+
<g id="arrow">
|
|
8
|
+
<rect id="arrow-shaft" x="420" y="272" width="394" height="106" stroke="none"/>
|
|
9
|
+
<path id="arrow-head" d="M833 220 L970 325 L833 430 Z" stroke-width="38" stroke-linejoin="round"/>
|
|
10
|
+
</g>
|
|
11
|
+
</g>
|
|
12
|
+
</svg>
|
package/package.json
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Serving-account alignment for observed JSON-string Claude metadata. No body-wide matching. */
|
|
2
|
+
const PROVIDER_UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
3
|
+
const MAX_USER_ID_BYTES = 4096;
|
|
4
|
+
type Rec = Record<string, unknown>;
|
|
5
|
+
const isRec = (value: unknown): value is Rec => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
6
|
+
|
|
7
|
+
/** Unknown formats stay untouched; the argument is the provider UUID, never the local pool id. */
|
|
8
|
+
export function bindAnthropicAccountMetadata(body: Rec, providerAccountUuid: string | undefined): Rec {
|
|
9
|
+
if (!providerAccountUuid || !PROVIDER_UUID.test(providerAccountUuid) || !isRec(body.metadata)) return body;
|
|
10
|
+
const userId = body.metadata.user_id;
|
|
11
|
+
if (typeof userId !== "string" || Buffer.byteLength(userId) > MAX_USER_ID_BYTES) return body;
|
|
12
|
+
let identity: unknown;
|
|
13
|
+
try { identity = JSON.parse(userId); } catch { return body; }
|
|
14
|
+
if (!isRec(identity) || typeof identity.account_uuid !== "string" || !PROVIDER_UUID.test(identity.account_uuid)
|
|
15
|
+
|| identity.account_uuid === providerAccountUuid) return body;
|
|
16
|
+
return { ...body, metadata: { ...body.metadata, user_id: JSON.stringify({ ...identity, account_uuid: providerAccountUuid }) } };
|
|
17
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/** Request-local compatibility data. Client headers never grant authorization or credential authority. */
|
|
2
|
+
import { classifyInterceptClient } from "../../claude/intercept/client-class";
|
|
3
|
+
|
|
4
|
+
const MAX_IDENTITY_BYTES = 4096;
|
|
5
|
+
const MAX_VALUE_BYTES = 512;
|
|
6
|
+
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
7
|
+
const SDK_TOKEN = /^[A-Za-z0-9._+-]{1,128}$/;
|
|
8
|
+
const NAMES = [
|
|
9
|
+
"User-Agent", "X-App", "X-Claude-Code-Session-Id", "x-client-request-id",
|
|
10
|
+
"X-Stainless-Lang", "X-Stainless-Runtime", "X-Stainless-Runtime-Version",
|
|
11
|
+
"X-Stainless-Package-Version", "X-Stainless-OS", "X-Stainless-Arch",
|
|
12
|
+
"X-Stainless-Retry-Count", "X-Stainless-Timeout",
|
|
13
|
+
] as const;
|
|
14
|
+
const REQUIRED = ["User-Agent", "X-App", "X-Claude-Code-Session-Id", "X-Stainless-Lang", "X-Stainless-Runtime"] as const;
|
|
15
|
+
declare const identityBrand: unique symbol;
|
|
16
|
+
/** Opaque in-memory handle: serializing it cannot publish caller headers. */
|
|
17
|
+
export interface AnthropicClientIdentity { readonly [identityBrand]: true }
|
|
18
|
+
const bundles = new WeakMap<AnthropicClientIdentity, Readonly<Record<string, string>>>();
|
|
19
|
+
|
|
20
|
+
function valid(name: typeof NAMES[number], value: string): boolean {
|
|
21
|
+
if (!value || Buffer.byteLength(value) > MAX_VALUE_BYTES || /[^\x20-\x7e]/.test(value)) return false;
|
|
22
|
+
if (name === "User-Agent") return classifyInterceptClient(value) === "cli";
|
|
23
|
+
if (name === "X-App") return value === "cli";
|
|
24
|
+
if (name === "X-Claude-Code-Session-Id" || name === "x-client-request-id") return UUID.test(value);
|
|
25
|
+
if (name === "X-Stainless-Lang") return value === "js";
|
|
26
|
+
if (name === "X-Stainless-Runtime") return value === "node";
|
|
27
|
+
if (name === "X-Stainless-Retry-Count" || name === "X-Stainless-Timeout") return /^\d{1,6}$/.test(value);
|
|
28
|
+
return SDK_TOKEN.test(value);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Select only a coherent observed CLI bundle; a UA alone does not select this compatibility lane. */
|
|
32
|
+
export function captureAnthropicClientIdentity(headers: Headers): AnthropicClientIdentity | undefined {
|
|
33
|
+
const connection = headers.get("connection") ?? "";
|
|
34
|
+
if (Buffer.byteLength(connection) > MAX_VALUE_BYTES) return undefined;
|
|
35
|
+
const hopNames = new Set(connection.toLowerCase().split(",").map(name => name.trim()));
|
|
36
|
+
const selected: Record<string, string> = {};
|
|
37
|
+
let bytes = 0;
|
|
38
|
+
for (const name of NAMES) {
|
|
39
|
+
const value = headers.get(name);
|
|
40
|
+
if (value === null) continue;
|
|
41
|
+
// Headers joins duplicate occurrences. Every scalar validator rejects joined values;
|
|
42
|
+
// the anchored CLI UA parser also rejects a second appended user agent.
|
|
43
|
+
if (hopNames.has(name.toLowerCase()) || !valid(name, value)) {
|
|
44
|
+
if ((REQUIRED as readonly string[]).includes(name)) return undefined;
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
bytes += Buffer.byteLength(name) + Buffer.byteLength(value);
|
|
48
|
+
if (bytes > MAX_IDENTITY_BYTES) return undefined;
|
|
49
|
+
selected[name] = value;
|
|
50
|
+
}
|
|
51
|
+
if (REQUIRED.some(name => selected[name] === undefined)) return undefined;
|
|
52
|
+
const handle = Object.freeze({}) as AnthropicClientIdentity;
|
|
53
|
+
bundles.set(handle, Object.freeze(selected));
|
|
54
|
+
return handle;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Called only after the builder verifies a first-party destination. Unknown/forged handles do nothing. */
|
|
58
|
+
export function applyAnthropicClientIdentity(headers: Record<string, string>, identity: AnthropicClientIdentity | undefined, operatorHeaders?: Readonly<Record<string, string>>): void {
|
|
59
|
+
const values = identity && bundles.get(identity);
|
|
60
|
+
if (!values) return;
|
|
61
|
+
const configured = new Set(Object.keys(operatorHeaders ?? {}).map(name => name.toLowerCase()));
|
|
62
|
+
for (const [name, value] of Object.entries(values)) {
|
|
63
|
+
if (configured.has(name.toLowerCase())) continue;
|
|
64
|
+
for (const existing of Object.keys(headers)) {
|
|
65
|
+
if (existing.toLowerCase() === name.toLowerCase()) delete headers[existing];
|
|
66
|
+
}
|
|
67
|
+
headers[name] = value;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Authority: only the provider's own credential is ever placed on the request — a configured
|
|
10
10
|
* key, or (PF-10) the access token of the OAuth account the lane resolved, which is sent only to
|
|
11
|
-
* `api.anthropic.com`.
|
|
12
|
-
*
|
|
11
|
+
* `api.anthropic.com`. Caller betas are reduced to `beta-allowlist.ts`; a bounded opaque
|
|
12
|
+
* CLI identity handle carries only observed compatibility headers for first-party destinations. The
|
|
13
13
|
* caller-forward passthrough in `src/server/claude-messages.ts` is the only place a caller's
|
|
14
14
|
* Anthropic credential may travel, and it does not come through here.
|
|
15
15
|
*
|
|
@@ -27,6 +27,8 @@ import {
|
|
|
27
27
|
applyAnthropicOAuthAuth,
|
|
28
28
|
resolveAnthropicMessagesUrl,
|
|
29
29
|
} from "../anthropic";
|
|
30
|
+
import { applyAnthropicClientIdentity, type AnthropicClientIdentity } from "./client-identity";
|
|
31
|
+
import { bindAnthropicAccountMetadata } from "./account-metadata";
|
|
30
32
|
import { allowlistAnthropicBetas } from "./beta-allowlist";
|
|
31
33
|
|
|
32
34
|
/**
|
|
@@ -75,6 +77,10 @@ export interface AnthropicMessagesPassthroughRequest {
|
|
|
75
77
|
export interface AnthropicMessagesPassthroughOptions {
|
|
76
78
|
/** The caller's `anthropic-beta` header, handed over by the ingress. */
|
|
77
79
|
callerAnthropicBeta?: string | null;
|
|
80
|
+
/** Provider UUID captured with the serving OAuth credential; never a local account slot id. */
|
|
81
|
+
providerAccountUuid?: string;
|
|
82
|
+
/** Internal request-local handle; never part of the serialized Messages body. */
|
|
83
|
+
clientIdentity?: AnthropicClientIdentity;
|
|
78
84
|
}
|
|
79
85
|
|
|
80
86
|
/** The allowlisted copy of `body` with `model` set to the wire model. Shallow: nothing is cloned. */
|
|
@@ -201,12 +207,25 @@ export function buildAnthropicMessagesPassthroughRequest(
|
|
|
201
207
|
: "anthropic provider requires a non-empty apiKey (authMode: key)");
|
|
202
208
|
}
|
|
203
209
|
const url = resolveAnthropicMessagesUrl(provider);
|
|
204
|
-
const
|
|
210
|
+
const native = anthropicMessagesNativeWireBody(provider, modelId, body);
|
|
211
|
+
const { strippedOpaqueState, oauthToolNames } = native;
|
|
212
|
+
const wireBody = oauth ? bindAnthropicAccountMetadata(native.wireBody, options.providerAccountUuid) : native.wireBody;
|
|
205
213
|
const headers = anthropicBaseRequestHeaders(wireBody.stream === true);
|
|
206
214
|
if (oauth) applyAnthropicOAuthAuth(headers, provider.apiKey);
|
|
207
215
|
else applyAnthropicKeyAuth(headers, provider);
|
|
208
216
|
// Operator-configured provider headers apply exactly as the adapter applies them.
|
|
209
|
-
if (provider.headers)
|
|
217
|
+
if (provider.headers) {
|
|
218
|
+
const configured = new Set(Object.keys(provider.headers).map(name => name.toLowerCase()));
|
|
219
|
+
for (const name of Object.keys(headers)) if (configured.has(name.toLowerCase())) delete headers[name];
|
|
220
|
+
Object.assign(headers, provider.headers);
|
|
221
|
+
}
|
|
222
|
+
if (oauth) {
|
|
223
|
+
const wireHeaders = new Headers(headers);
|
|
224
|
+
if (wireHeaders.get("authorization") !== `Bearer ${provider.apiKey}` || wireHeaders.has("x-api-key")) {
|
|
225
|
+
throw new Error("native OAuth serving credential was overridden by provider headers");
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (domain?.firstPartyAnthropic) applyAnthropicClientIdentity(headers, options.clientIdentity, provider.headers);
|
|
210
229
|
const betas = allowlistAnthropicBetas(options.callerAnthropicBeta, domain?.firstPartyAnthropic ? "first-party" : "compatible");
|
|
211
230
|
mergeAnthropicBetaHeader(headers, betas.betas);
|
|
212
231
|
return {
|
|
@@ -1050,7 +1050,24 @@ export function createAnthropicAdapter(provider: OcxProviderConfig, cacheRetenti
|
|
|
1050
1050
|
// always exceeds the budget within a model-safe ceiling, reserving room for visible output.
|
|
1051
1051
|
const maxOut = parsed.options.maxOutputTokens ?? omittedMaxTokens;
|
|
1052
1052
|
const wantBudget = reasoningBudget(effectiveReasoning);
|
|
1053
|
-
|
|
1053
|
+
// Clamp to what the TARGET can emit, not to a flat 32k. REASONING_MAX_TOKENS_CEILING
|
|
1054
|
+
// dates from Claude 4.x models that really stopped near 32k; Opus 4.6 and Sonnet 4.6
|
|
1055
|
+
// document 128K and Haiku 4.5 64K, so the flat ceiling cut an explicit caller
|
|
1056
|
+
// `max_tokens` to a quarter of what the model supports — the adaptive branch above
|
|
1057
|
+
// honours the caller's figure, and this one did not.
|
|
1058
|
+
//
|
|
1059
|
+
// `configuredMaxOut` only ever RAISES this ceiling. It is two different things at once:
|
|
1060
|
+
// a capability statement on the canonical Anthropic entries (documented Messages maxima)
|
|
1061
|
+
// and a plain fallback budget for omitted requests anywhere else. Letting it lower the
|
|
1062
|
+
// ceiling would read an operator's cheap `defaultMaxOutputTokens: 8192` as "this model
|
|
1063
|
+
// cannot emit more" and clamp an explicit 128000 request to 8192 — below what this path
|
|
1064
|
+
// sent before and with the thinking budget squeezed to 4096. Taking the larger of the two
|
|
1065
|
+
// keeps the historical ceiling as a floor, so a low fallback budget cannot regress a
|
|
1066
|
+
// caller who asked for more.
|
|
1067
|
+
const statedCeiling = typeof configuredMaxOut === "number" && configuredMaxOut > 0
|
|
1068
|
+
? Math.max(configuredMaxOut, REASONING_MAX_TOKENS_CEILING)
|
|
1069
|
+
: REASONING_MAX_TOKENS_CEILING;
|
|
1070
|
+
const maxTokens = Math.min(statedCeiling, Math.max(maxOut, wantBudget + OUTPUT_HEADROOM));
|
|
1054
1071
|
const budget = Math.max(MIN_THINKING_BUDGET, Math.min(wantBudget, maxTokens - OUTPUT_FLOOR));
|
|
1055
1072
|
body.max_tokens = maxTokens;
|
|
1056
1073
|
body.thinking = { type: "enabled", budget_tokens: budget };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { constants } from "node:fs";
|
|
2
2
|
import { lstat, open, opendir, realpath, stat } from "node:fs/promises";
|
|
3
|
-
import {
|
|
3
|
+
import { join, sep } from "node:path";
|
|
4
4
|
|
|
5
5
|
export type CommandCodeProjectContext = {
|
|
6
6
|
memory: string;
|
|
@@ -140,14 +140,11 @@ async function canonicalPath(candidate: string, deadline: number, scope: ScanSco
|
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
export function isContainedCanonicalPath(cwdCanonical: string, fileCanonical: string): boolean {
|
|
149
|
-
const rel = relative(normalizePathIdentity(cwdCanonical), normalizePathIdentity(fileCanonical));
|
|
150
|
-
return rel === "" || (rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel));
|
|
143
|
+
/** Exact canonical prefixes preserve case-sensitive Windows directory identities. */
|
|
144
|
+
export function isContainedCanonicalPath(cwdCanonical: string, fileCanonical: string, separator = sep): boolean {
|
|
145
|
+
if (fileCanonical === cwdCanonical) return true;
|
|
146
|
+
const prefix = cwdCanonical.endsWith(separator) ? cwdCanonical : `${cwdCanonical}${separator}`;
|
|
147
|
+
return fileCanonical.startsWith(prefix);
|
|
151
148
|
}
|
|
152
149
|
|
|
153
150
|
async function confinedCanonicalPath(
|
|
@@ -199,8 +196,7 @@ async function openedFileIsConfined(
|
|
|
199
196
|
const resolved = await withinDeadline(() => realpath(path), deadline, scope);
|
|
200
197
|
// The input path was canonical before open. A changed intermediate symlink changes this
|
|
201
198
|
// result even though O_NOFOLLOW protects only the final component on macOS and Linux.
|
|
202
|
-
if (!isContainedCanonicalPath(cwdCanonical, resolved)
|
|
203
|
-
|| normalizePathIdentity(resolved) !== normalizePathIdentity(path)) return false;
|
|
199
|
+
if (!isContainedCanonicalPath(cwdCanonical, resolved) || resolved !== path) return false;
|
|
204
200
|
const resolvedInfo = await withinDeadline(() => lstat(resolved), deadline, scope);
|
|
205
201
|
return resolvedInfo.isFile() && opened.dev === resolvedInfo.dev && opened.ino === resolvedInfo.ino;
|
|
206
202
|
}
|
|
@@ -32,10 +32,9 @@ type Schema = Record<string, unknown>;
|
|
|
32
32
|
const isSchema = (value: unknown): value is Schema => !!value && typeof value === 'object' && !Array.isArray(value);
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* outer keyword, and kept beside the split under allOf when one does.
|
|
35
|
+
* Replace a type array with an equivalent type-only union. Constraints remain on
|
|
36
|
+
* the surrounding node so nested schemas are represented exactly once rather
|
|
37
|
+
* than copied into every branch.
|
|
39
38
|
*/
|
|
40
39
|
function splitTypeArray(node: Schema, types: unknown[]): Schema {
|
|
41
40
|
const annotations: Schema = {};
|
|
@@ -49,51 +48,16 @@ function splitTypeArray(node: Schema, types: unknown[]): Schema {
|
|
|
49
48
|
const allowsNull = concrete.length < types.length
|
|
50
49
|
&& (!Array.isArray(rest.enum) || rest.enum.includes(null))
|
|
51
50
|
&& (!Object.hasOwn(rest, 'const') || rest.const === null);
|
|
51
|
+
const branches = concrete.map((type) => ({ type }));
|
|
52
|
+
if (allowsNull || branches.length === 0) branches.push({ type: 'null' });
|
|
53
|
+
const typeConstraint: Schema = branches.length === 1 ? branches[0]! : { anyOf: branches };
|
|
52
54
|
const existing = Array.isArray(node.anyOf) ? node.anyOf : undefined;
|
|
53
|
-
|
|
54
|
-
//
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
// Folding merges each branch into the outer keywords, which is only exact when
|
|
62
|
-
// they never disagree: `{maxLength: 5, anyOf: [{maxLength: 50}]}` folded would
|
|
63
|
-
// loosen the outer limit. On a disagreement keep both constraints under allOf,
|
|
64
|
-
// which this backend accepts (live: gemini-3-8-flash-medium).
|
|
65
|
-
if (existing?.some((branch) => isSchema(branch) && (
|
|
66
|
-
Object.keys(branch).some((key) => key !== 'type' && key in rest && JSON.stringify(branch[key]) !== JSON.stringify(rest[key]))
|
|
67
|
-
// Keep an existing null branch's own constraints; folding it to {type:"null"}
|
|
68
|
-
// would admit values that its enum, const, or nested schema rejects.
|
|
69
|
-
|| (allowsNull && branch.type === 'null' && Object.keys(branch).some((key) => key !== 'type'))
|
|
70
|
-
|| (allowsNull && branch.type === undefined && ['enum', 'const', 'not', 'allOf', 'oneOf'].some((key) => key in branch))
|
|
71
|
-
))) {
|
|
72
|
-
return { ...annotations, allOf: [splitTypeArray({ ...rest, type: types }, types), { anyOf: existing }] };
|
|
73
|
-
}
|
|
74
|
-
const branches: unknown[] = [];
|
|
75
|
-
let nullReachable = allowsNull && !existing;
|
|
76
|
-
if (!existing) {
|
|
77
|
-
for (const type of concrete) branches.push({ ...rest, type });
|
|
78
|
-
} else {
|
|
79
|
-
for (const branch of existing) {
|
|
80
|
-
if (!isSchema(branch)) continue;
|
|
81
|
-
if (branch.type === undefined) {
|
|
82
|
-
for (const type of concrete) branches.push({ ...rest, ...branch, type });
|
|
83
|
-
if (allowsNull) nullReachable = true;
|
|
84
|
-
} else if (branch.type === 'null') {
|
|
85
|
-
if (allowsNull) nullReachable = true;
|
|
86
|
-
} else if (concrete.includes(branch.type)) {
|
|
87
|
-
branches.push({ ...rest, ...branch });
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
if (nullReachable) branches.push({ type: 'null' });
|
|
92
|
-
// The two unions are disjoint. Keep both constraints rather than drop the type union,
|
|
93
|
-
// which would let the anyOf branches admit types the node never allowed.
|
|
94
|
-
if (branches.length === 0) return { ...annotations, allOf: [splitTypeArray({ ...rest, type: types }, types), { anyOf: existing }] };
|
|
95
|
-
if (branches.length === 1 && isSchema(branches[0])) return { ...annotations, ...branches[0] };
|
|
96
|
-
return { ...annotations, anyOf: branches };
|
|
55
|
+
if (!existing) return { ...annotations, ...rest, ...typeConstraint };
|
|
56
|
+
// Keep existing applicators and constraints at their original JSON Pointer
|
|
57
|
+
// locations. Appending only the type constraint also preserves allOf indices,
|
|
58
|
+
// resource scopes, and the sibling annotations read by unevaluated* keywords.
|
|
59
|
+
const allOf = Array.isArray(rest.allOf) ? rest.allOf : [];
|
|
60
|
+
return { ...annotations, ...rest, anyOf: existing, allOf: [...allOf, typeConstraint] };
|
|
97
61
|
}
|
|
98
62
|
|
|
99
63
|
function rewrite(node: unknown): unknown {
|
|
@@ -165,6 +165,8 @@ async function fetchWithResetRecovery(
|
|
|
165
165
|
notePhysicalSend: (reset: boolean) => void,
|
|
166
166
|
): Promise<Response> {
|
|
167
167
|
let lastError: unknown;
|
|
168
|
+
let destination = url;
|
|
169
|
+
let destinationRebased = false;
|
|
168
170
|
for (let attempt = 0; attempt < RESET_ATTEMPTS; attempt++) {
|
|
169
171
|
if (ctx.abortSignal?.aborted) throw abortError(ctx.abortSignal);
|
|
170
172
|
const executor = (ctx.executor ?? globalThis.fetch) as typeof globalThis.fetch & {
|
|
@@ -177,18 +179,22 @@ async function fetchWithResetRecovery(
|
|
|
177
179
|
// Every physical send is admitted, not just the adapter entry. Kiro nests a throttle loop
|
|
178
180
|
// over this ladder and can run the ladder twice per throttle round, so counting one entry
|
|
179
181
|
// as one send hid up to eighteen upstream requests from the per-request cap (#4546).
|
|
180
|
-
const decision = ctx.sendBudget?.reserveDispatch({
|
|
182
|
+
const decision = ctx.sendBudget?.reserveDispatch({
|
|
183
|
+
sendClass: "transient", targetKey: destination, rebasedTarget: destinationRebased,
|
|
184
|
+
});
|
|
185
|
+
destinationRebased = false;
|
|
181
186
|
if (decision && (!decision.allowed || !decision.permit.use())) {
|
|
182
|
-
throw new SendBudgetExhaustedError(
|
|
187
|
+
throw new SendBudgetExhaustedError(destination);
|
|
183
188
|
}
|
|
184
189
|
// Reported after admission and before dispatch, so a refused send is never counted and an
|
|
185
190
|
// admitted one is counted exactly once whichever way the fetch below settles.
|
|
186
191
|
notePhysicalSend(attempt > 0);
|
|
192
|
+
const requestUrl = request.url;
|
|
187
193
|
try {
|
|
188
194
|
const headers = new Headers(request.headers);
|
|
189
195
|
const recovered = attempt > 0;
|
|
190
196
|
if (recovered) headers.set("connection", "close");
|
|
191
|
-
return await sendTrackingRequestSlot(slot, () => fetchWithAttemptDeadline(
|
|
197
|
+
return await sendTrackingRequestSlot(slot, () => fetchWithAttemptDeadline(destination, {
|
|
192
198
|
method: request.method,
|
|
193
199
|
headers,
|
|
194
200
|
body: request.body,
|
|
@@ -208,6 +214,12 @@ async function fetchWithResetRecovery(
|
|
|
208
214
|
} catch (error) {
|
|
209
215
|
if (ctx.abortSignal?.aborted || !isConnectionResetError(error) || attempt === RESET_ATTEMPTS - 1) throw error;
|
|
210
216
|
lastError = error;
|
|
217
|
+
if (request.url !== requestUrl) {
|
|
218
|
+
destination = request.url;
|
|
219
|
+
// The rebuild retargeted this request; that move is authorized work, not a
|
|
220
|
+
// failover transition, so the endpoint fallback still owns the budget's one hop.
|
|
221
|
+
destinationRebased = true;
|
|
222
|
+
}
|
|
211
223
|
await sleepWithAbort(retryBackoffDelayMs(attempt, {
|
|
212
224
|
baseDelayMs: RESET_RETRY_BASE_MS,
|
|
213
225
|
maxDelayMs: RESET_RETRY_MAX_MS,
|
|
@@ -283,13 +295,15 @@ async function fetchKiroAttempt(
|
|
|
283
295
|
notePhysicalSend: (reset: boolean) => void,
|
|
284
296
|
): Promise<Response> {
|
|
285
297
|
const plannedUrl = request.url;
|
|
286
|
-
const legacy = legacyUrl(plannedUrl);
|
|
287
298
|
let response: Response;
|
|
288
299
|
try {
|
|
289
300
|
response = await fetchWithResetRecovery(request, plannedUrl, ctx, timeoutMs, notePhysicalSend);
|
|
290
301
|
} catch (error) {
|
|
291
|
-
|
|
292
|
-
|
|
302
|
+
// The legacy host must mirror the CURRENT destination: a reset rebuild retargets the
|
|
303
|
+
// request, and falling back to the original region would send its new credentials there.
|
|
304
|
+
const currentLegacy = legacyUrl(request.url);
|
|
305
|
+
if (!currentLegacy || !endpointConnectFailure(error)) throw error;
|
|
306
|
+
return fetchWithResetRecovery(request, currentLegacy, ctx, timeoutMs, notePhysicalSend);
|
|
293
307
|
}
|
|
294
308
|
|
|
295
309
|
if (!response.ok && (response.status === 502 || response.status === 503 || response.status === 504)) {
|
|
@@ -300,12 +314,13 @@ async function fetchKiroAttempt(
|
|
|
300
314
|
return fetchWithResetRecovery(request, alternate, ctx, timeoutMs, notePhysicalSend);
|
|
301
315
|
}
|
|
302
316
|
}
|
|
303
|
-
|
|
317
|
+
const currentLegacy = legacyUrl(request.url);
|
|
318
|
+
if (currentLegacy && !response.ok) {
|
|
304
319
|
const inspected = await inspectEndpointHttpFailure(response, ctx.abortSignal);
|
|
305
320
|
response = inspected.response;
|
|
306
321
|
if (inspected.fallback) {
|
|
307
322
|
cancelResponseBodyBestEffort(response);
|
|
308
|
-
response = await fetchWithResetRecovery(request,
|
|
323
|
+
response = await fetchWithResetRecovery(request, currentLegacy, ctx, timeoutMs, notePhysicalSend);
|
|
309
324
|
}
|
|
310
325
|
}
|
|
311
326
|
return response;
|
|
@@ -144,7 +144,7 @@ export function messagesToChatFormat(parsed: OcxParsedRequest, provider: OcxProv
|
|
|
144
144
|
const nativeOpenAI = isNativeOpenAIChatTarget(provider);
|
|
145
145
|
// Qwen3.8-27B's pinned chat template rejects non-leading system and every developer role;
|
|
146
146
|
// a later user is rendered in place. Keep this exception specific to that template family.
|
|
147
|
-
const qwen38LeadingSystemTemplate = !nativeOpenAI && /^(?:Qwen\/)?Qwen3\.8-27B$/i.test(parsed.modelId);
|
|
147
|
+
const qwen38LeadingSystemTemplate = !nativeOpenAI && /^(?:Qwen\/)?(?:Qwen3\.8-27B|qwen3-8-27b(?:-(?:fp8|lora))?)$/i.test(parsed.modelId);
|
|
148
148
|
// Which role a developer message carries, and why the unrecorded state folds, is stated once
|
|
149
149
|
// in ./developer-role.ts and read from there by the native passthrough as well. Either way the
|
|
150
150
|
// message keeps the slot it arrived in — only the role changes, never the position.
|
package/src/adapters/registry.ts
CHANGED
|
@@ -15,6 +15,7 @@ import { createMimoFreeAdapter } from "./mimo-free";
|
|
|
15
15
|
import { createOpenAIChatAdapter } from "./openai-chat";
|
|
16
16
|
import { createOllamaNativeAdapter } from "./ollama-native";
|
|
17
17
|
import { createResponsesPassthroughAdapter } from "./openai-responses";
|
|
18
|
+
import { createZedAdapter } from "./zed";
|
|
18
19
|
import type { OcxProviderConfig } from "../types";
|
|
19
20
|
import { createAdapterTierMetadata } from "../providers/fastwire";
|
|
20
21
|
import { withInputMediaGuard } from "./input-media-guard";
|
|
@@ -45,7 +46,8 @@ export type AdapterWire =
|
|
|
45
46
|
| "google"
|
|
46
47
|
| "kiro"
|
|
47
48
|
| "cursor"
|
|
48
|
-
| "devin"
|
|
49
|
+
| "devin"
|
|
50
|
+
| "zed";
|
|
49
51
|
|
|
50
52
|
export type AdapterMutationContract =
|
|
51
53
|
| "codex-owned"
|
|
@@ -132,6 +134,11 @@ export const ADAPTER_REGISTRY = {
|
|
|
132
134
|
mutation: "codex-owned",
|
|
133
135
|
create: (provider: OcxProviderConfig, context: AdapterFactoryContext) => createDevinAdapter(provider, context),
|
|
134
136
|
},
|
|
137
|
+
zed: {
|
|
138
|
+
wire: "zed",
|
|
139
|
+
mutation: "codex-owned",
|
|
140
|
+
create: (provider: OcxProviderConfig, _context: AdapterFactoryContext) => createZedAdapter(provider),
|
|
141
|
+
},
|
|
135
142
|
"mimo-free": {
|
|
136
143
|
contractParent: "openai-chat",
|
|
137
144
|
create: (provider: OcxProviderConfig, _context: AdapterFactoryContext) => createMimoFreeAdapter(provider),
|