@bitkyc08/opencodex 2.91.0 → 2.92.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/bin/ocx.mjs +37 -3
- package/gui/dist/assets/{App-nZ34cR5G.js → App-sUf_8afJ.js} +18 -18
- package/gui/dist/assets/{Tray-BuLy7hL1.js → Tray-BSsxznDm.js} +1 -1
- package/gui/dist/assets/index-BlFE_VB_.js +94 -0
- package/gui/dist/assets/quota-summary-BRlbXgw0.js +1 -0
- package/gui/dist/index.html +1 -1
- package/gui/dist/provider-icons/workbuddy-color.svg +29 -0
- package/package.json +4 -3
- package/src/adapters/google-vertex-endpoint.ts +9 -1
- package/src/adapters/google-vertex-key-project.ts +223 -0
- package/src/adapters/google.ts +13 -3
- package/src/adapters/openai-chat/tool-name-registry.ts +3 -1
- package/src/adapters/openai-chat.ts +2 -2
- package/src/adapters/openai-responses/request-strips.ts +60 -0
- package/src/adapters/registry.ts +5 -0
- package/src/adapters/workbuddy-schema.ts +61 -0
- package/src/adapters/workbuddy.ts +68 -0
- package/src/bridge/response-json.ts +1 -1
- package/src/bridge/sse.ts +1 -1
- package/src/chat/outbound.ts +11 -4
- package/src/cli/capabilities-agents-routing.ts +3 -3
- package/src/cli/codex-cli-update.ts +8 -0
- package/src/cli/combo-result.ts +6 -0
- package/src/cli/combo-stats.ts +3 -0
- package/src/cli/combo.ts +66 -42
- package/src/cli/launcher-context.ts +49 -2
- package/src/cli/link.ts +45 -32
- package/src/cli/provider.ts +2 -1
- package/src/cli/usage-compare.ts +68 -12
- package/src/client/link-ingress.ts +1 -1
- package/src/client/link-readiness.ts +97 -0
- package/src/client/link-relay-transport.ts +79 -11
- package/src/client/link-relay.ts +74 -15
- package/src/client/link-tunnel.ts +45 -18
- package/src/client/machine-listener.ts +20 -2
- package/src/client/runtime.ts +20 -2
- package/src/codex/account-store.ts +17 -3
- package/src/codex/app-server-restart-service.ts +6 -5
- package/src/codex/catalog/effort.ts +9 -2
- package/src/codex/catalog/gather-capture.ts +4 -2
- package/src/codex/catalog/provider-models.ts +14 -8
- package/src/codex/chatgpt-refresh-failure.ts +6 -2
- package/src/codex/cli-install-provenance.ts +418 -0
- package/src/codex/cli-installation-targets.ts +5 -1
- package/src/codex/cli-update-plan.ts +43 -16
- package/src/codex/desktop-app/picker-freshness.ts +10 -8
- package/src/codex/desktop-compatibility/usage-activation.ts +2 -1
- package/src/codex/desktop-compatibility/usage-controller.ts +7 -1
- package/src/codex/pool-refresh-backoff.ts +3 -1
- package/src/codex/user-identity.ts +35 -6
- package/src/codex/windows-current-sid.ts +162 -0
- package/src/combos/jev-quota-activation.ts +5 -1
- package/src/combos/jev-quota-route.ts +1 -1
- package/src/combos/jev-quota.ts +9 -1
- package/src/combos/jev-session-pin-config.ts +51 -0
- package/src/combos/jev.ts +6 -0
- package/src/combos/types.ts +19 -0
- package/src/config/provider-validation.ts +7 -0
- package/src/config/schema/leaf-validators.ts +1 -0
- package/src/generated/compatibility-version.json +194 -122
- package/src/lib/decision-quota-sink.ts +10 -0
- package/src/lib/translator-budget.ts +4 -4
- package/src/lib/upstream-retry.ts +4 -1
- package/src/link/diagnostics.ts +193 -0
- package/src/link/relay-auth.ts +6 -0
- package/src/link/status-projection.ts +39 -0
- package/src/link/supervisor.ts +45 -12
- package/src/link/tunnel-history.ts +109 -0
- package/src/link/tunnel-state.ts +80 -17
- package/src/messaging/remote-files.ts +24 -1
- package/src/oauth/generic-account-failover.ts +91 -7
- package/src/oauth/index.ts +15 -0
- package/src/oauth/model-discovery-auth.ts +5 -0
- package/src/oauth/store.ts +4 -1
- package/src/oauth/token-guardian.ts +7 -0
- package/src/oauth/types.ts +9 -0
- package/src/oauth/workbuddy.ts +139 -0
- package/src/providers/antigravity-quota-identity.ts +37 -0
- package/src/providers/base-url-choices.ts +8 -5
- package/src/providers/derive.ts +23 -3
- package/src/providers/model-discovery.ts +2 -0
- package/src/providers/model-rename-fields.ts +1 -0
- package/src/providers/quota/account-cache.ts +3 -2
- package/src/providers/quota/antigravity.ts +25 -14
- package/src/providers/quota/report-cache.ts +13 -4
- package/src/providers/quota/vendor-probes-key.ts +60 -0
- package/src/providers/quota/workbuddy.ts +83 -0
- package/src/providers/quota-decision-antigravity.ts +64 -0
- package/src/providers/quota-decision-publication.ts +11 -0
- package/src/providers/quota-decision-snapshot.ts +21 -4
- package/src/providers/quota-types.ts +2 -0
- package/src/providers/quota.ts +3 -1
- package/src/providers/registry/entries-core.ts +9 -0
- package/src/providers/registry/entries-extended.ts +20 -7
- package/src/providers/registry/model-ids.ts +3 -0
- package/src/providers/registry/model-seeds.ts +27 -28
- package/src/providers/registry/types.ts +19 -1
- package/src/providers/resolved-model-policy.ts +4 -4
- package/src/providers/routed-config.ts +15 -0
- package/src/providers/stale-model-roster-migration.ts +83 -15
- package/src/providers/workbuddy-credit-balance.ts +81 -0
- package/src/providers/workbuddy-models.ts +37 -0
- package/src/providers/workbuddy.ts +60 -0
- package/src/responses/reasoning-replay-cache.ts +18 -14
- package/src/router.ts +2 -0
- package/src/routing/analytics.ts +2 -3
- package/src/routing/fallback-policy.ts +3 -3
- package/src/server/auth-cors.ts +1 -0
- package/src/server/chat-completions.ts +14 -1
- package/src/server/chat-native-reasoning.ts +10 -3
- package/src/server/chat-native.ts +13 -2
- package/src/server/claude-messages.ts +3 -0
- package/src/server/index/link-relay-sessions.ts +9 -5
- package/src/server/index/optional-listeners.ts +4 -0
- package/src/server/local-management-read-client.ts +3 -1
- package/src/server/management/combo-routes.ts +10 -4
- package/src/server/management/link-routes.ts +5 -2
- package/src/server/management/provider-routes.ts +1 -1
- package/src/server/port-reclaim.ts +51 -9
- package/src/server/request-log-conversation.ts +49 -0
- package/src/server/request-log.ts +2 -0
- package/src/server/responses/anthropic-thinking-recovery.ts +1 -0
- package/src/server/responses/compact.ts +10 -2
- package/src/server/responses/core-combo.ts +53 -31
- package/src/server/responses/core-lifetime.ts +2 -2
- package/src/server/responses/core-normalize.ts +6 -3
- package/src/server/responses/core-opaque-recovery.ts +1 -0
- package/src/server/responses/core-options.ts +5 -0
- package/src/server/responses/core-replay.ts +2 -1
- package/src/server/responses/jev-combo-choice.ts +39 -0
- package/src/server/responses/jev-session-pin.ts +203 -0
- package/src/server/responses/passthrough-delivery.ts +4 -0
- package/src/server/responses/request-prepare.ts +10 -5
- package/src/server/responses/request-transport.ts +25 -6
- package/src/server/responses/run-turn-execution.ts +2 -4
- package/src/server/responses/sidecar-execution.ts +2 -4
- package/src/server/responses-phase-inference.ts +267 -0
- package/src/server/sse-payload-rewrite.ts +14 -1
- package/src/service/definition.ts +20 -8
- package/src/types/config.ts +6 -0
- package/src/types/provider.ts +9 -1
- package/src/types/request.ts +1 -0
- package/src/types/wire.ts +1 -0
- package/src/update/codex-cli-update-launch-policy.d.mts +9 -0
- package/src/update/codex-cli-update-launch-policy.mjs +30 -0
- package/src/usage/jev-stats.ts +54 -14
- package/gui/dist/assets/index-DGXS51sp.js +0 -94
- package/gui/dist/assets/quota-summary-DO1Sx5TM.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{n as e,w as t,y as n}from"./index-BlFE_VB_.js";var r=e(),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`})}),_=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M12 5v14M5 12h14`})}),v=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M5 12h14`})}),ee=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`})]}),y=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`})}),b={anthropic:`claude-color.svg`,anthropic2:`claude-green.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`,"dsh-account":`deepseek-color.svg`,"workbuddy-ai":`workbuddy-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`},x={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`,"dsh-account":`DeepSeek Account (DSH)`,"workbuddy-ai":`WorkBuddy AI`,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`},S={anthropic2:`provider.name.anthropic2`,"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`},Oe=new Set([...Object.keys(x),...Object.keys(S)]);function ke(e){let t=e.toLowerCase();return Object.hasOwn(b,t)?b[t]:void 0}function Ae(e,t){let n=ke(e);return n?`/provider-icons/${n}`:void 0}var je=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`]),Me=new Set([`baseten.svg`,`kilo.svg`,`sambanova.svg`,`venice.svg`,`zai.svg`]),Ne=new Set([`bizrouter.svg`,`featherless.svg`,`hyperbolic.svg`,`nebius.svg`,`parallel.svg`,`umans.svg`]);function Pe(e){if(!e)return`image`;let t=e.split(`/`).pop()??``;return je.has(t)?`mask`:Me.has(t)?`plate`:Ne.has(t)?`dark-plate`:`image`}function C(e,t){let n=e.toLowerCase(),r=Object.hasOwn(S,n)?S[n]:void 0;return r?t(r):(Object.hasOwn(x,n)?x[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 Fe(e){return Oe.has(e.toLowerCase())}function Ie(e){return e===`command-code`?`commandcode-auth`:e===`commandcode`?`commandcode-api`:e}function Le(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 Re={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 w(e){return e.replace(/\.0+$/,``).replace(/(\.\d*?)0+$/,`$1`)}function ze(e,t){let n=Re[t];if(n){for(let t of n)if(e>=t.v)return`${w((e/t.v).toFixed(1))}${t.s}`;return String(e)}return e<1e4?String(e):e<1e6?`${w((e/1e3).toFixed(1))}K`:e<1e9?`${w((e/1e6).toFixed(1))}M`:e<0xe8d4a51000?`${w((e/1e9).toFixed(1))}B`:`${w((e/0xe8d4a51000).toFixed(1))}T`}var Be=new Set([`claude-cli`]),Ve=`anthropic-apikey`;function T(e){return Be.has((e.adapter??``).trim())}var E=`https://chatgpt.com/backend-api/codex`,He=`openai`;function D(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 Ue=new URL(E).protocol;function O(e,...t){return`${Ue}//${e}/${t.join(`/`)}`}var We={"cline-pass":{adapter:`openai-chat`,baseUrl:O(`api.cline.bot`,`api`,`v1`)},"mimo-free":{adapter:`mimo-free`,baseUrl:O(`api.xiaomimimo.com`,`api`,`free-ai`,`openai`,`chat`)}};function Ge(e,t){let n=We[e];return!n||t.adapter!==n.adapter||D(t.baseUrl)!==D(n.baseUrl)}function k(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 A(e){return e.keyOptional===!0||T(e)||e.authMode===`oauth`||e.authMode===`forward`||e.authMode===`local`||k(e.baseUrl)||e.hasApiKey===!0}function j(e){return e.adapter===`openai-responses`&&e.authMode===`forward`&&D(e.baseUrl)===E}function M(e,t){return e===He&&j(t)}function N(e){return T(e)?!1:e.freeTier===!0||e.keyOptional===!0||e.authMode===`local`||k(e.baseUrl)}function P(e,t){return M(e,t)?`accounts`:N(t)?`free`:`paid`}function Ke(e,t){let n=[...e],r=(e,t)=>e.name.localeCompare(t.name,void 0,{sensitivity:`base`}),i=e=>e.tier??P(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 qe(e){let t=[],n=[],r=[];for(let[i,a]of Object.entries(e))a.disabled?r.push({name:i,...a}):A(a)?t.push({name:i,...a,tier:P(i,a)}):n.push({name:i,...a});return{ready:t,needsSetup:n,disabled:r}}function Je(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 F(e){return e.disabled?`disabled`:`activeNeedsReauth`in e&&e.activeNeedsReauth?`needs-setup`:A(e)?`ready`:`needs-setup`}function Ye(e){let t=e.openai,n=e.chatgpt;if(!t||!n||!M(`openai`,t)||!j(n))return e;let r={...e};return delete r.chatgpt,r}function I(e){return e.authMode===`local`||k(e.baseUrl)}var Xe=[`ollama`,`vllm`,`lm-studio`,`lmstudio`,`litellm`,`localai`];function Ze(e){let t=(e.authMode??``).toLowerCase();if(t===`oauth`||t===`forward`)return`login`;if(I(e))return`local`;let n=`${e.name??``} ${e.adapter} ${e.baseUrl}`.toLowerCase();return Xe.some(e=>n.includes(e))?`selfHosted`:`cloud`}var L=[`plan_base`,`plan_bonus`,`addon`,`benefit`,`other`];function R(e){return typeof e==`object`&&e&&!Array.isArray(e)?e:{}}function z(e){if(typeof e!=`number`&&!(typeof e==`string`&&/^\d+(?:\.\d+)?$/.test(e)))return;let t=Number(e);return Number.isFinite(t)&&t>=0&&t<=2**53-1?t:void 0}function B(e){let t=R(e),n=z(t.total),r=z(t.used),i=z(t.remaining),a=z(t.frozen);if(n!==void 0&&r!==void 0&&i!==void 0&&a!==void 0)return{total:n,used:r,remaining:i,frozen:a}}function Qe(e){let t=R(e),n=B(e);if(!n||!Array.isArray(t.groups)||t.groups.length>L.length)return;let r=[],i=new Set;for(let e of t.groups){let t=R(e),n=B(t),a=L.find(e=>e===t.kind);if(!n||!a||i.has(a))return;i.add(a),r.push({kind:a,...n})}let a=R(t.expiring),o=z(a.amount),s=typeof a.at==`number`&&a.at>0&&Number.isFinite(new Date(a.at).getTime())?a.at:void 0;return{...n,groups:r,...o!==void 0&&o>0&&s!==void 0?{expiring:{amount:o,at:s}}:{}}}function V(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=V(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=V(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 H=e=>typeof e==`number`&&Number.isFinite(e)?e:void 0,nt=e=>{let t=H(e);if(t===void 0)return;let n=t>1e10?t:t*1e3;return Number.isFinite(new Date(n).getTime())?t:void 0};function U(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`||H(t.percent)===void 0?[]:[{label:t.label,percent:t.percent,...H(t.resetAt)===void 0?{}:{resetAt:t.resetAt},...typeof t.modelId==`string`&&t.modelId.length<=128?{modelId:t.modelId}:{}}]}):[],i=n.creditsUsd&&typeof n.creditsUsd==`object`&&!Array.isArray(n.creditsUsd)?n.creditsUsd:null,a=H(i?.used),o=H(i?.limit),s=H(i?.remaining),c=H(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=Qe(n.workbuddyCredits),f={...d?{workbuddyCredits:d}:{},...H(n.fiveHourPercent)===void 0?{}:{fiveHourPercent:n.fiveHourPercent},...H(n.fiveHourResetAt)===void 0?{}:{fiveHourResetAt:n.fiveHourResetAt},...H(n.weeklyPercent)===void 0?{}:{weeklyPercent:n.weeklyPercent},...H(n.weeklyResetAt)===void 0?{}:{weeklyResetAt:n.weeklyResetAt},...H(n.monthlyPercent)===void 0?{}:{monthlyPercent:n.monthlyPercent},...H(n.monthlyResetAt)===void 0?{}:{monthlyResetAt:n.monthlyResetAt},...r.length>0?{customWindows:r}:{},...u?{creditsUsd:u}:{},updatedAt:H(n.updatedAt)??t??Date.now()};return f.fiveHourPercent!==void 0||f.weeklyPercent!==void 0||f.monthlyPercent!==void 0||(f.customWindows?.length??0)>0||f.creditsUsd!==void 0||f.workbuddyCredits!==void 0?f:null}function W(e){return U(e?.quota,e?.updatedAt)}function rt(e){if(!e)return;if(e.aggregation===void 0)return e;let t=it(e)?.currentAccount?.quota??null;return{...e,aggregation:void 0,quota:t,updatedAt:t?.updatedAt}}function G(e){if(!e||typeof e!=`object`||Array.isArray(e))return;let t=e,n=H(t.usedPercent);if(n!==void 0)return{usedPercent:n,...typeof t.incomplete==`boolean`?{incomplete:t.incomplete}:{},...H(t.excludedAccounts)===void 0?{}:{excludedAccounts:t.excludedAccounts},...H(t.nextRecoveryAt)===void 0?{}:{nextRecoveryAt:t.nextRecoveryAt},...H(t.nextRecoveryPercent)===void 0?{}:{nextRecoveryPercent:t.nextRecoveryPercent}}}function it(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=H(n.excludedAccounts),i=H(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=G(t);return typeof t.label==`string`&&n?[{label:t.label,...n}]:[]}):[],s=G(n.fiveHour),c=G(n.weekly),l=G(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:H(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:U(a.quota)}}:{}}}function at(e){if(!e?.trim())return``;let[t,n]=e.split(`:`,2);return n?`${t} · ${n.replace(/-/g,` `)}`:e}function ot(e,t){let n=F(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 st(e,t){if(T(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 ct(e){let t=F(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 lt({name:e,adapter:n,baseUrl:i,cls:a}){let o=t(),s=Ae(e,{adapter:n,baseUrl:i}),c=Pe(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)(ut,{name:e,label:C(e,o)})})}function ut({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 dt({item:e,selected:n,tabbable:i,modelCount:a,isDefault:o,showConfigId:s,onClick:c,onFocus:l}){let u=t(),d=N(e),f=I(e),p=ot(e,u),m=C(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`):``}`,_=a!==void 0&&a>0?a===1?u(`pws.modelCountOne`):u(`pws.modelCount`,{count:a}):``,v=[s?e.name:``,_].filter(Boolean).join(` · `);return(0,r.jsxs)(`button`,{type:`button`,className:`providers-workspace-rail-row${n?` providers-workspace-rail-row--selected`:``}`,onClick:c,role:`option`,"aria-selected":n,tabIndex:i?0:-1,"aria-label":u(`pws.rail.selectAria`,{name:h,status:p,suffix:g}),title:h,onFocus:l,children:[(0,r.jsx)(lt,{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:v||void 0,children:v||`\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)(y,{width:17,height:17,"aria-hidden":`true`})}),(0,r.jsx)(`span`,{className:ct(e),title:p,"aria-hidden":`true`})]})]})}var ft=1e10;function pt(e){return e<ft?e*1e3:e}function mt(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 pt(r)>t}function ht(e){return{fiveHourAvailable:e?.shortWindowSeconds===18e3&&typeof e.shortResetAt==`number`,weeklyAvailable:typeof e?.weeklyResetAt==`number`}}function gt(e){let t=e?.trim().toLowerCase();return t===`go`||t===`free`}function _t(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 gt(t)?{...n.monthlyPercent===void 0?{}:{monthlyPercent:n.monthlyPercent},...n.monthlyResetAt===void 0?{}:{monthlyResetAt:n.monthlyResetAt},...n.workbuddyCredits===void 0?{}:{workbuddyCredits:n.workbuddyCredits},...n.creditsUsd===void 0?{}:{creditsUsd:n.creditsUsd},...n.resetCredits===void 0?{}:{resetCredits:n.resetCredits},updatedAt:n.updatedAt}:n}function vt(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=(gt(t)?[e.monthlyPercent]:[e.weeklyPercent,e.monthlyPercent]).filter(r);if(a.length===0)return mt({...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 yt(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 K(e){return Array.isArray(e)&&e.length<=100&&e.every(e=>typeof e==`string`)?JSON.stringify([...new Set(e)].sort()):void 0}function bt(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&&K(o.hiddenProviders)===K(t.hiddenProviders)&&(t.models===null?o.models===null:K(o.models)===K(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 xt={6:15,24:60,72:180,168:360};function St(e){return xt[e]}function Ct(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 wt(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 Tt(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 Et(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 Dt(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 Ot(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`],kt=640,At=160,J=28;function jt(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 Mt(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 Nt({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=jt(e,t),u=Mt(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:Dt(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)):Ot(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 ${kt} ${At}`,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:Ct(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 Pt(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 Ft(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 It(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 Lt(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 Rt(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`?zt(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,...It(n,c),exhausted:a!==null&&Lt(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:_t(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 zt(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 Bt(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 Vt(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,modelId:e.modelId,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 Ht(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 Ut(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 Wt(e,t){let r=n(2e4),i=()=>r.controller.abort();t.aborted&&i(),t.addEventListener(`abort`,i,{once:!0});try{let t=await fetch(e,{signal:r.signal,cache:`no-store`});if(!t.ok)throw Error(String(t.status));let n=await t.json();if(r.signal.aborted)throw Error(`Tray request cancelled`);return n}finally{r.clear(),t.removeEventListener(`abort`,i)}}function Gt(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 Kt(e){return Q(e)?`${Math.floor(e)}%`:`-`}var qt=[`quota.weeklyLimit`,`quota.monthlyLimit`,`quota.fiveHourLimit`];function Jt(e){let t=Vt(e).map(e=>{let t=Q(e.percent)?e.percent:void 0,n=Z(e.reset),r=`modelId`in e?e.modelId:void 0;return{id:e.id,...r===void 0?{}:{modelId:r},...`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:r===void 0?$(t):`normal`}}),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 Yt(e){let t=e.filter(e=>e.modelId===void 0&&e.percent!==void 0),n=new Map(t.map(e=>[e.id,e]));for(let e of qt){let t=n.get(e);if(t)return t}return t[0]}function Xt(e,t){let n=[];for(let[r,i]of Object.entries(e)){let e=W(i);if(!e)continue;let a=Jt(e),o=Yt(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,_ as At,Ye as B,re as Bt,_t as C,v as Ct,st as D,te as Dt,dt as E,d as Et,I as F,Te as Ft,Ke as G,N as H,Ze as I,y as It,ze as J,Ve as K,Je as L,xe as Lt,$e as M,ee as Mt,et as N,ce as Nt,W as O,ae as Ot,tt as P,o as Pt,Ie as Q,F as R,f as Rt,vt as S,u as St,lt as T,Se as Tt,Ge as U,M as V,g as Vt,P as W,C as X,Le as Y,Fe as Z,bt as _,se as _t,Wt as a,h as at,wt as b,l as bt,Ut as c,de as ct,Pt as d,De as dt,oe as et,Vt as f,pe as ft,Et as g,m as gt,St as h,Ee as ht,Ft as i,s as it,at as j,me as jt,it as k,ne as kt,Rt as l,he as lt,Nt as m,a as mt,Kt as n,le as nt,Ht as o,fe as ot,Bt as p,we as pt,T as q,$ as r,c as rt,Y as s,_e as st,Xt as t,ue as tt,Gt as u,ie as ut,yt as v,ge as vt,ht as w,Ce as wt,Tt as x,ve as xt,Ct as y,be as yt,qe as z,ye as zt};
|
package/gui/dist/index.html
CHANGED
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
document.documentElement.lang = langMap[locale];
|
|
37
37
|
})();
|
|
38
38
|
</script>
|
|
39
|
-
<script type="module" crossorigin src="/assets/index-
|
|
39
|
+
<script type="module" crossorigin src="/assets/index-BlFE_VB_.js"></script>
|
|
40
40
|
<link rel="stylesheet" crossorigin href="/assets/index-DPeB9HpV.css">
|
|
41
41
|
</head>
|
|
42
42
|
<body>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<g clip-path="url(#clip0_542_3370)">
|
|
3
|
+
<rect width="40" height="40" rx="20" fill="url(#paint0_linear_542_3370)"/>
|
|
4
|
+
<g filter="url(#filter0_f_542_3370)">
|
|
5
|
+
<circle cx="31.3411" cy="43.6183" r="12.8704" fill="#FFE355" fill-opacity="0.49" style="fill:#FFE355;fill:color(display-p3 1.0000 0.8891 0.3348);fill-opacity:0.49;"/>
|
|
6
|
+
</g>
|
|
7
|
+
<path d="M28.5931 3.12762C28.9853 2.77585 29.0091 2.76226 29.2968 2.74499C29.7628 2.71096 30.1894 2.93488 30.916 3.59634C32.6132 5.13875 34.9769 8.30904 36.4462 11.0168L37.0138 12.0682L37.8156 12.4668C38.5896 12.8579 39.8593 13.6593 40.3898 14.0895C40.6297 14.2878 40.6638 14.2925 40.9133 14.1954C42.0388 13.7572 43.6506 14.3382 45.0727 15.7024C46.3529 16.9294 47.5794 19.026 48.0491 20.7757C48.1177 21.0574 48.2087 21.6628 48.2419 22.1134C48.349 23.6964 47.8414 24.9608 46.8637 25.5331C46.664 25.6484 46.6505 25.6795 46.6561 26.1774C46.7011 28.5481 46.0621 30.9144 44.7785 33.2221C43.3293 35.8133 40.7489 38.4945 37.2566 41.0199C35.3813 42.3846 30.9445 44.9701 28.9382 45.8778C24.1324 48.0414 20.2794 48.8709 16.9329 48.4609C14.9368 48.219 12.6769 47.44 11.34 46.5355C10.9885 46.2925 10.9325 46.2774 10.6637 46.3543C9.2327 46.7651 7.35867 45.9207 5.76659 44.1535C5.13165 43.4471 4.1065 41.7127 3.77404 40.7843C3.0054 38.6118 3.15852 36.6506 4.18236 35.4799C4.44671 35.1785 4.45511 35.1658 4.39735 34.6589C4.30195 33.8289 4.25837 32.6008 4.30192 31.808L4.33666 31.0674L3.22502 29.101C1.5033 26.0375 0.409325 23.4645 -0.012563 21.4992C-0.235219 20.4218 -0.221193 19.9436 0.0522186 19.5899C0.21871 19.3763 0.764928 19.1545 1.42322 19.0329C3.08041 18.742 6.69466 19.0056 10.7155 19.7155L11.1329 19.788L12.0511 18.976C13.5747 17.6264 14.587 16.8696 16.4531 15.706C18.3981 14.4891 20.5929 13.4877 23.0648 12.695L23.8577 12.4414L24.2939 11.2964C25.8547 7.17615 27.4533 4.13844 28.5931 3.12762ZM15.5182 24.243C13.7542 25.2615 12.8718 25.7706 12.2236 26.3413C9.59893 28.6526 8.61811 32.3134 9.73545 35.6274C10.0114 36.4457 10.5201 37.3283 11.5386 39.0923C12.5571 40.8564 13.0671 41.7383 13.6378 42.3864C15.9491 45.0112 19.6103 45.9929 22.9243 44.8755C23.7426 44.5995 24.6249 44.0899 26.3888 43.0714L36.5375 37.2121C38.3016 36.1936 39.184 35.6845 39.8321 35.1137C42.4568 32.8024 43.4373 29.1409 42.3198 25.8269C42.0438 25.0086 41.5342 24.1264 40.5158 22.3624C39.4973 20.5983 38.9882 19.7159 38.4175 19.0678C36.1062 16.4432 32.4454 15.4622 29.1314 16.5796C28.3131 16.8556 27.431 17.3651 25.6669 18.3836L15.5182 24.243Z" fill="url(#paint1_linear_542_3370)"/>
|
|
8
|
+
<rect x="16.4961" y="31.3344" width="4.00904" height="8.32646" rx="2.00452" transform="rotate(-30 16.4961 31.3344)" fill="white" style="fill:white;fill-opacity:1;"/>
|
|
9
|
+
<rect x="27.3125" y="25.0894" width="4.00904" height="8.32646" rx="2.00452" transform="rotate(-30 27.3125 25.0894)" fill="white" style="fill:white;fill-opacity:1;"/>
|
|
10
|
+
</g>
|
|
11
|
+
<defs>
|
|
12
|
+
<filter id="filter0_f_542_3370" x="7.47033" y="19.7475" width="47.742" height="47.7416" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
|
13
|
+
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
|
14
|
+
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
|
15
|
+
<feGaussianBlur stdDeviation="5.50019" result="effect1_foregroundBlur_542_3370"/>
|
|
16
|
+
</filter>
|
|
17
|
+
<linearGradient id="paint0_linear_542_3370" x1="20" y1="0" x2="20" y2="40" gradientUnits="userSpaceOnUse">
|
|
18
|
+
<stop stop-color="#0EC8A9" style="stop-color:#0EC8A9;stop-color:color(display-p3 0.0565 0.7837 0.6625);stop-opacity:1;"/>
|
|
19
|
+
<stop offset="1" stop-color="#01C886" style="stop-color:#01C886;stop-color:color(display-p3 0.0021 0.7858 0.5246);stop-opacity:1;"/>
|
|
20
|
+
</linearGradient>
|
|
21
|
+
<linearGradient id="paint1_linear_542_3370" x1="14.6642" y1="11.0783" x2="33.3762" y2="43.4885" gradientUnits="userSpaceOnUse">
|
|
22
|
+
<stop stop-color="white" stop-opacity="0.8" style="stop-color:white;stop-opacity:0.8;"/>
|
|
23
|
+
<stop offset="0.437689" stop-color="white" style="stop-color:white;stop-opacity:1;"/>
|
|
24
|
+
</linearGradient>
|
|
25
|
+
<clipPath id="clip0_542_3370">
|
|
26
|
+
<rect width="40" height="40" rx="20" fill="white" style="fill:white;fill-opacity:1;"/>
|
|
27
|
+
</clipPath>
|
|
28
|
+
</defs>
|
|
29
|
+
</svg>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bitkyc08/opencodex",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.92.0",
|
|
4
4
|
"description": "Universal provider proxy for OpenAI Codex & Claude Code — use any LLM with Codex CLI/App/SDK and Claude Code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./bin/package-main.mjs",
|
|
@@ -82,8 +82,8 @@
|
|
|
82
82
|
"@bufbuild/protobuf": "^2.14.0",
|
|
83
83
|
"@modelcontextprotocol/sdk": "^1.32.1",
|
|
84
84
|
"@napi-rs/keyring": "1.3.0",
|
|
85
|
-
"bun": "1.4.
|
|
86
|
-
"zod": "4.
|
|
85
|
+
"bun": "1.4.4",
|
|
86
|
+
"zod": "4.6.6"
|
|
87
87
|
},
|
|
88
88
|
"devDependencies": {
|
|
89
89
|
"@types/bun": "1.4.0",
|
|
@@ -94,6 +94,7 @@
|
|
|
94
94
|
},
|
|
95
95
|
"overrides": {
|
|
96
96
|
"@hono/node-server": "2.1.0",
|
|
97
|
+
"body-parser": "2.4.0",
|
|
97
98
|
"fast-uri": "^3.1.7",
|
|
98
99
|
"hono": "4.13.8",
|
|
99
100
|
"ip-address": "^10.4.0",
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { googleVertexLocationConfigError } from "../providers/google-vertex-location";
|
|
2
|
+
import { VERTEX_PROJECT_AUTO } from "./google-vertex-key-project";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Vertex endpoint selection, shared by inference and replay identity.
|
|
5
6
|
*
|
|
6
7
|
* API keys follow explicit provider configuration only: `provider.project` selects the project
|
|
7
8
|
* endpoint (location defaults to `global`), otherwise the projectless express endpoint is used.
|
|
9
|
+
* `provider.project: "auto"` resolves the project of each key it sends (see
|
|
10
|
+
* google-vertex-key-project.ts), so one key pool may span several projects.
|
|
8
11
|
* Ambient GOOGLE_CLOUD_PROJECT / GCLOUD_PROJECT / GOOGLE_CLOUD_LOCATION belong to ADC, so an
|
|
9
12
|
* unrelated gcloud default in the shell cannot move an express-mode key onto another project.
|
|
10
13
|
*/
|
|
@@ -20,11 +23,16 @@ export function selectVertexEndpoint(
|
|
|
20
23
|
env: NodeJS.ProcessEnv = process.env,
|
|
21
24
|
): VertexEndpointSelection {
|
|
22
25
|
// A blank or whitespace-only project is unset: it must not select a /projects/%20/ endpoint.
|
|
23
|
-
const
|
|
26
|
+
const rawProject = provider.project?.trim() || undefined;
|
|
27
|
+
const configuredProject = rawProject?.toLowerCase() === VERTEX_PROJECT_AUTO ? VERTEX_PROJECT_AUTO : rawProject;
|
|
24
28
|
if (hasApiKey) {
|
|
25
29
|
if (!configuredProject) return { kind: "express" };
|
|
26
30
|
return { kind: "project", project: configuredProject, location: provider.location || "global" };
|
|
27
31
|
}
|
|
32
|
+
// "auto" names a per-key lookup, never a project id; ADC has no key to resolve it from.
|
|
33
|
+
if (configuredProject === VERTEX_PROJECT_AUTO) {
|
|
34
|
+
throw new Error('Vertex AI project "auto" requires an API key; set provider.project to a project id for ADC.');
|
|
35
|
+
}
|
|
28
36
|
const project = configuredProject || env.GOOGLE_CLOUD_PROJECT || env.GCLOUD_PROJECT;
|
|
29
37
|
if (!project) throw new Error("Vertex AI requires a project id (provider.project or GOOGLE_CLOUD_PROJECT/GCLOUD_PROJECT).");
|
|
30
38
|
const location = provider.location || env.GOOGLE_CLOUD_LOCATION;
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { readBoundedResponseBody } from "../lib/bounded-body";
|
|
2
|
+
import { markEgressTransparentExecutor, providerEgressSendInit } from "../lib/provider-egress";
|
|
3
|
+
import { configuredOutboundFetch } from "../lib/proxy-env";
|
|
4
|
+
import { withUpstreamHttpVersion } from "../lib/upstream-http-version";
|
|
5
|
+
import type { OcxProviderConfig } from "../types";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Per-key project discovery for Vertex express-mode API keys (`provider.project: "auto"`).
|
|
9
|
+
*
|
|
10
|
+
* An express-mode key belongs to one Google Cloud project, and Google's projectless endpoint
|
|
11
|
+
* echoes `projects/<number>/locations/<region>/...` in its 404 body for a nonexistent model
|
|
12
|
+
* (observed 2026-10-18 across five express-mode keys on `aiplatform.googleapis.com`). That is an
|
|
13
|
+
* undocumented upstream error shape rather than a stable discovery API, so `"auto"` is strictly
|
|
14
|
+
* opt-in and any non-404, truncated, oversized, invalid-UTF-8 or non-matching body falls back to
|
|
15
|
+
* the projectless express endpoint without caching.
|
|
16
|
+
*/
|
|
17
|
+
export const VERTEX_PROJECT_AUTO = "auto";
|
|
18
|
+
|
|
19
|
+
const PROBE_URL = "https://aiplatform.googleapis.com/v1/publishers/google/models/ocx-project-probe:countTokens";
|
|
20
|
+
const PROBE_TIMEOUT_MS = 10_000;
|
|
21
|
+
/** Google's 404 JSON for a missing publisher model is ~320 bytes; 4 KiB bounds untrusted bodies. */
|
|
22
|
+
export const VERTEX_PROBE_MAX_BYTES = 4096;
|
|
23
|
+
const PROJECT_NUMBER = /\bprojects\/(\d{1,20})\/locations\//;
|
|
24
|
+
/** Pool sizes are small; the cap only bounds a pathological rotation of distinct keys. */
|
|
25
|
+
const CACHE_LIMIT = 64;
|
|
26
|
+
|
|
27
|
+
/** Keyed by a SHA-256 digest so the cache never retains raw key material. Insertion-order LRU. */
|
|
28
|
+
const resolved = new Map<string, string>();
|
|
29
|
+
|
|
30
|
+
interface ProbeWaiter {
|
|
31
|
+
signal?: AbortSignal;
|
|
32
|
+
resolve: (project: string | undefined) => void;
|
|
33
|
+
reject: (reason: unknown) => void;
|
|
34
|
+
onAbort?: () => void;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interface InflightProbe {
|
|
38
|
+
controller: AbortController;
|
|
39
|
+
waiters: Set<ProbeWaiter>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const inflight = new Map<string, InflightProbe>();
|
|
43
|
+
|
|
44
|
+
/** Computes the non-reversible SHA-256 cache key for an API key. */
|
|
45
|
+
function cacheKey(apiKey: string): string {
|
|
46
|
+
return new Bun.CryptoHasher("sha256").update(apiKey).digest("base64url");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Records a resolved project number in the bounded insertion-order LRU cache. */
|
|
50
|
+
function remember(key: string, project: string): void {
|
|
51
|
+
resolved.delete(key);
|
|
52
|
+
resolved.set(key, project);
|
|
53
|
+
while (resolved.size > CACHE_LIMIT) resolved.delete(resolved.keys().next().value!);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Extracts the project number from Google's projectless NOT_FOUND body; exported for tests. */
|
|
57
|
+
export function parseVertexProbeProjectNumber(body: string): string | undefined {
|
|
58
|
+
return PROJECT_NUMBER.exec(body)?.[1];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface VertexKeyProjectOptions {
|
|
62
|
+
fetch?: typeof fetch;
|
|
63
|
+
signal?: AbortSignal;
|
|
64
|
+
provider?: OcxProviderConfig;
|
|
65
|
+
providerName?: string;
|
|
66
|
+
/** Test seam for the bounded-body and request deadline. */
|
|
67
|
+
timeoutMs?: number;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const defaultOutboundFetch = markEgressTransparentExecutor(
|
|
71
|
+
((input: Parameters<typeof fetch>[0], init?: RequestInit) => configuredOutboundFetch(input, init)) as typeof fetch,
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
/** Builds the side-effect-free outbound transport honoring provider egress and HTTP version. */
|
|
75
|
+
function selectProbeFetch(options: VertexKeyProjectOptions): typeof fetch {
|
|
76
|
+
if (options.fetch) return options.fetch;
|
|
77
|
+
const provider = options.provider;
|
|
78
|
+
const customFetch = (provider as (OcxProviderConfig & { fetch?: typeof fetch }) | undefined)?.fetch;
|
|
79
|
+
if (!provider) return customFetch ?? globalThis.fetch;
|
|
80
|
+
const base = customFetch ?? defaultOutboundFetch;
|
|
81
|
+
const providerName = options.providerName ?? "google-vertex";
|
|
82
|
+
return ((input: Parameters<typeof fetch>[0], init?: RequestInit) => {
|
|
83
|
+
const egressInit = providerEgressSendInit({ providerName, provider }, base, input);
|
|
84
|
+
const versioned = withUpstreamHttpVersion(input, init, provider);
|
|
85
|
+
return base(input, { ...versioned, ...egressInit });
|
|
86
|
+
}) as typeof fetch;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Sends one bounded countTokens probe to Google and extracts the project number from a 404 body. */
|
|
90
|
+
async function probe(
|
|
91
|
+
apiKey: string,
|
|
92
|
+
fetchImpl: typeof fetch,
|
|
93
|
+
signal: AbortSignal,
|
|
94
|
+
timeoutMs: number,
|
|
95
|
+
): Promise<string | undefined> {
|
|
96
|
+
const probeSignal = AbortSignal.any([signal, AbortSignal.timeout(timeoutMs)]);
|
|
97
|
+
try {
|
|
98
|
+
const res = await fetchImpl(PROBE_URL, {
|
|
99
|
+
method: "POST",
|
|
100
|
+
redirect: "manual",
|
|
101
|
+
headers: { "content-type": "application/json", "x-goog-api-key": apiKey },
|
|
102
|
+
body: JSON.stringify({ contents: [{ role: "user", parts: [{ text: "x" }] }] }),
|
|
103
|
+
signal: probeSignal,
|
|
104
|
+
});
|
|
105
|
+
// Only Google's model NOT_FOUND names the key's project; 401/403/429 and redirects do not.
|
|
106
|
+
if (res.status !== 404) {
|
|
107
|
+
void res.body?.cancel().catch(() => {});
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
const body = await readBoundedResponseBody(res, {
|
|
111
|
+
maxBytes: VERTEX_PROBE_MAX_BYTES,
|
|
112
|
+
totalTimeoutMs: timeoutMs,
|
|
113
|
+
inactivityTimeoutMs: timeoutMs,
|
|
114
|
+
firstByteTimeoutMs: timeoutMs,
|
|
115
|
+
signal: probeSignal,
|
|
116
|
+
reportUtf8Validity: true,
|
|
117
|
+
});
|
|
118
|
+
if (body.truncated || body.oversized || body.timedOut || !body.displaySafe || body.utf8Valid === false) {
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
return parseVertexProbeProjectNumber(body.text);
|
|
122
|
+
} catch {
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** Detaches the abort listener registered for a coalesced probe waiter. */
|
|
128
|
+
function cleanupWaiter(waiter: ProbeWaiter): void {
|
|
129
|
+
if (waiter.signal && waiter.onAbort) {
|
|
130
|
+
waiter.signal.removeEventListener("abort", waiter.onAbort);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** Starts a shared in-flight probe and fans the result out to all active waiters. */
|
|
135
|
+
function startInflight(
|
|
136
|
+
key: string,
|
|
137
|
+
apiKey: string,
|
|
138
|
+
fetchImpl: typeof fetch,
|
|
139
|
+
timeoutMs: number,
|
|
140
|
+
): InflightProbe {
|
|
141
|
+
const controller = new AbortController();
|
|
142
|
+
const waiters = new Set<ProbeWaiter>();
|
|
143
|
+
const entry: InflightProbe = { controller, waiters };
|
|
144
|
+
inflight.set(key, entry);
|
|
145
|
+
|
|
146
|
+
void (async () => {
|
|
147
|
+
let project: string | undefined;
|
|
148
|
+
try {
|
|
149
|
+
project = await probe(apiKey, fetchImpl, controller.signal, timeoutMs);
|
|
150
|
+
} finally {
|
|
151
|
+
if (inflight.get(key) === entry) inflight.delete(key);
|
|
152
|
+
}
|
|
153
|
+
if (project && !controller.signal.aborted) remember(key, project);
|
|
154
|
+
for (const waiter of Array.from(waiters)) {
|
|
155
|
+
cleanupWaiter(waiter);
|
|
156
|
+
if (waiter.signal?.aborted) waiter.reject(waiter.signal.reason);
|
|
157
|
+
else waiter.resolve(project);
|
|
158
|
+
}
|
|
159
|
+
})();
|
|
160
|
+
|
|
161
|
+
return entry;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Resolves the project number that owns `apiKey`, or undefined when Google does not reveal it.
|
|
166
|
+
* Successful lookups are cached per key; failures are not, so a transient error retries next time.
|
|
167
|
+
* Concurrent callers for the same uncached key share one probe; an aborted caller detaches
|
|
168
|
+
* immediately without cancelling the shared probe unless every waiter has aborted.
|
|
169
|
+
*/
|
|
170
|
+
export async function resolveVertexApiKeyProject(
|
|
171
|
+
apiKey: string,
|
|
172
|
+
options: VertexKeyProjectOptions | typeof fetch = {},
|
|
173
|
+
): Promise<string | undefined> {
|
|
174
|
+
const opts: VertexKeyProjectOptions = typeof options === "function" ? { fetch: options } : options;
|
|
175
|
+
const signal = opts.signal;
|
|
176
|
+
signal?.throwIfAborted();
|
|
177
|
+
|
|
178
|
+
const key = cacheKey(apiKey);
|
|
179
|
+
const cached = resolved.get(key);
|
|
180
|
+
if (cached) {
|
|
181
|
+
remember(key, cached);
|
|
182
|
+
return cached;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Synchronous egress validation (for example an opaque custom fetch combined with an explicit
|
|
186
|
+
// provider.proxy) must reject the caller rather than being swallowed into an express fallback.
|
|
187
|
+
const fetchImpl = selectProbeFetch(opts);
|
|
188
|
+
const timeoutMs = opts.timeoutMs ?? PROBE_TIMEOUT_MS;
|
|
189
|
+
const entry = inflight.get(key) ?? startInflight(key, apiKey, fetchImpl, timeoutMs);
|
|
190
|
+
|
|
191
|
+
return new Promise<string | undefined>((resolve, reject) => {
|
|
192
|
+
if (signal?.aborted) {
|
|
193
|
+
if (entry.waiters.size === 0) {
|
|
194
|
+
if (inflight.get(key) === entry) inflight.delete(key);
|
|
195
|
+
entry.controller.abort(signal.reason);
|
|
196
|
+
}
|
|
197
|
+
reject(signal.reason);
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const waiter: ProbeWaiter = { signal, resolve, reject };
|
|
201
|
+
if (signal) {
|
|
202
|
+
const onAbort = () => {
|
|
203
|
+
signal.removeEventListener("abort", onAbort);
|
|
204
|
+
entry.waiters.delete(waiter);
|
|
205
|
+
reject(signal.reason);
|
|
206
|
+
if (entry.waiters.size === 0) {
|
|
207
|
+
if (inflight.get(key) === entry) inflight.delete(key);
|
|
208
|
+
entry.controller.abort(signal.reason);
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
waiter.onAbort = onAbort;
|
|
212
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
213
|
+
}
|
|
214
|
+
entry.waiters.add(waiter);
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/** Clears the resolved project cache and aborts any in-flight probes for tests. */
|
|
219
|
+
export function __resetVertexApiKeyProjectCache(): void {
|
|
220
|
+
resolved.clear();
|
|
221
|
+
for (const entry of inflight.values()) entry.controller.abort();
|
|
222
|
+
inflight.clear();
|
|
223
|
+
}
|
package/src/adapters/google.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { openCodeZenGeminiEndpoint } from "../types/opencode-zen";
|
|
2
|
-
import type { AdapterFetchContext, AdapterRequest, ProviderAdapter } from "./base";
|
|
2
|
+
import type { AdapterFetchContext, AdapterRequest, IncomingMeta, ProviderAdapter } from "./base";
|
|
3
3
|
import { debugDroppedFrame, debugProviderDiagnosticLazy } from "../lib/debug";
|
|
4
4
|
import { createToolCallIdAllocator } from "./tool-call-id";
|
|
5
5
|
import { openCodeGoGeminiEndpoint } from "../types/opencode-go";
|
|
@@ -37,6 +37,7 @@ import {
|
|
|
37
37
|
} from "./google-antigravity-replay";
|
|
38
38
|
import { canonicalAntigravityUsageModel, resolveAntigravityEffortWireModel } from "../providers/antigravity-models";
|
|
39
39
|
import { selectVertexEndpoint, vertexInferenceUrl, vertexReplayModelKey } from "./google-vertex-endpoint";
|
|
40
|
+
import { resolveVertexApiKeyProject, VERTEX_PROJECT_AUTO } from "./google-vertex-key-project";
|
|
40
41
|
import { forgetThoughtSignatureForReplay, lookupReplayThoughtSignature } from "../responses/thought-signature-replay";
|
|
41
42
|
import {
|
|
42
43
|
isTranslatorBudgetExceededError,
|
|
@@ -992,7 +993,7 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte
|
|
|
992
993
|
: {}),
|
|
993
994
|
|
|
994
995
|
/** Compile an admitted request into the selected Gemini endpoint, body and authentication. */
|
|
995
|
-
async buildRequest(parsed: OcxParsedRequest) {
|
|
996
|
+
async buildRequest(parsed: OcxParsedRequest, incoming?: IncomingMeta) {
|
|
996
997
|
// Structured-output admission runs FIRST, before messagesToGeminiFormat writes
|
|
997
998
|
// lastInjectedCallIds/lastReasoningReplayScope: a refused request must not leave
|
|
998
999
|
// adapter-scoped replay state pointing at call ids that never went out. These
|
|
@@ -1225,7 +1226,16 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte
|
|
|
1225
1226
|
reportToolSchemaLoss(compiled.toolSchemaLossReport);
|
|
1226
1227
|
restoreGoogleToolName = compiled.restoreToolName;
|
|
1227
1228
|
const apiKey = resolveVertexApiKey(provider.apiKey);
|
|
1228
|
-
|
|
1229
|
+
let vertexEndpoint = selectVertexEndpoint(provider, Boolean(apiKey));
|
|
1230
|
+
if (apiKey && vertexEndpoint.kind === "project" && vertexEndpoint.project === VERTEX_PROJECT_AUTO) {
|
|
1231
|
+
// Unresolved keys use express for this request so Google's status drives key failover.
|
|
1232
|
+
const project = await resolveVertexApiKeyProject(apiKey, {
|
|
1233
|
+
signal: incoming?.abortSignal,
|
|
1234
|
+
provider,
|
|
1235
|
+
providerName: incoming?.providerName,
|
|
1236
|
+
});
|
|
1237
|
+
vertexEndpoint = project ? { ...vertexEndpoint, project } : { kind: "express" };
|
|
1238
|
+
}
|
|
1229
1239
|
const url = vertexInferenceUrl(vertexEndpoint, parsed.modelId, method, streamParam);
|
|
1230
1240
|
vertexReplayModel = vertexReplayModelKey(vertexEndpoint, parsed.modelId);
|
|
1231
1241
|
vertexReplaySession = vertexReplaySessionId(parsed);
|
|
@@ -63,6 +63,7 @@ export function openAIChatToolNameIdentities(parsed: OcxParsedRequest): ToolIden
|
|
|
63
63
|
*/
|
|
64
64
|
export function createOpenAIChatToolNameRegistry(
|
|
65
65
|
tools: readonly ToolIdentity[] | undefined,
|
|
66
|
+
strictNames = false,
|
|
66
67
|
): OpenAIChatToolNameRegistry {
|
|
67
68
|
const identities = new Map<string, ToolIdentity>();
|
|
68
69
|
for (const tool of tools ?? []) identities.set(identityKey(tool), tool);
|
|
@@ -85,6 +86,7 @@ export function createOpenAIChatToolNameRegistry(
|
|
|
85
86
|
for (const [key, tool] of sortedIdentities) {
|
|
86
87
|
const wireName = namespacedToolName(tool.namespace, tool.name);
|
|
87
88
|
const candidate = (tool.namespace !== undefined && wireName.length > MAX_CHAT_TOOL_NAME_LENGTH)
|
|
89
|
+
|| (strictNames && !/^[A-Za-z0-9_-]+$/.test(wireName))
|
|
88
90
|
|| RESERVED_ALIAS_PATTERN.test(wireName)
|
|
89
91
|
|| wireOwners.get(wireName) === null
|
|
90
92
|
? boundedAlias(tool, wireName)
|
|
@@ -157,7 +159,7 @@ export function withOpenAIChatToolNames<T>(
|
|
|
157
159
|
let registry = createOpenAIChatToolNameRegistry(undefined);
|
|
158
160
|
return build({
|
|
159
161
|
messages(parsed, baseUrl, messages): unknown {
|
|
160
|
-
registry = createOpenAIChatToolNameRegistry(openAIChatToolNameIdentities(parsed));
|
|
162
|
+
registry = createOpenAIChatToolNameRegistry(openAIChatToolNameIdentities(parsed), baseUrl === "https://www.workbuddy.ai/v2");
|
|
161
163
|
return frameAgentRouterMessages(baseUrl, aliasOpenAIChatMessageToolNames(messages, registry));
|
|
162
164
|
},
|
|
163
165
|
registry: () => registry,
|
|
@@ -614,9 +614,9 @@ export function createOpenAIChatAdapter(provider: OcxProviderConfig): ProviderAd
|
|
|
614
614
|
}
|
|
615
615
|
bufferBytes = nextBufferBytes;
|
|
616
616
|
|
|
617
|
-
const lines = buffer.split("\n");
|
|
617
|
+
const lines = decoded.includes("\n") ? buffer.split("\n") : [buffer];
|
|
618
618
|
buffer = lines.pop() ?? "";
|
|
619
|
-
const residualBytes = budgetEncoder.encode(buffer).byteLength;
|
|
619
|
+
const residualBytes = lines.length ? budgetEncoder.encode(buffer).byteLength : bufferBytes;
|
|
620
620
|
const residualReservation = budget.reserveTransient(residualBytes, { kind: "live_transient" });
|
|
621
621
|
residualReservation.commitRetained();
|
|
622
622
|
budget.releaseRetained(bufferBytes, { kind: "live_transient" });
|
|
@@ -24,6 +24,66 @@ export function stripProviderInputItemMetadata(body: unknown): unknown {
|
|
|
24
24
|
input ??= [...body.input];
|
|
25
25
|
input[index] = next;
|
|
26
26
|
}
|
|
27
|
+
return repairUrlCitationAnnotations(input ? { ...body, input } : body);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function isUrlCitationIndex(value: unknown): value is number {
|
|
31
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Coerce a replayed citation index to a non-negative safe integer, falling back to 0. */
|
|
35
|
+
function repairUrlCitationIndex(value: unknown): number {
|
|
36
|
+
if (isUrlCitationIndex(value)) return value;
|
|
37
|
+
if (typeof value === "string" && /^\d+$/.test(value)) {
|
|
38
|
+
const index = Number(value);
|
|
39
|
+
if (isUrlCitationIndex(index)) return index;
|
|
40
|
+
}
|
|
41
|
+
return 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* OpenAI Responses requires `title` (string) and integer `start_index`/`end_index` on every
|
|
46
|
+
* `url_citation` annotation of a replayed `output_text` part. History written by an older bridge
|
|
47
|
+
* (title omitted when the search source had none) or a lossy client otherwise fails every later
|
|
48
|
+
* request carrying it, most visibly remote compaction, with a deterministic HTTP 400
|
|
49
|
+
* (`Missing required parameter: input[N].content[M].annotations[K].title`).
|
|
50
|
+
* Repair only those fields on `url_citation` annotations of assistant message content; other
|
|
51
|
+
* annotation types, unknown keys and every other item are untouched. Copy on write: an already
|
|
52
|
+
* valid body is returned by reference.
|
|
53
|
+
*/
|
|
54
|
+
export function repairUrlCitationAnnotations(body: unknown): unknown {
|
|
55
|
+
if (!isPlainObject(body) || !Array.isArray(body.input)) return body;
|
|
56
|
+
let input: unknown[] | undefined;
|
|
57
|
+
for (let itemIndex = 0; itemIndex < body.input.length; itemIndex += 1) {
|
|
58
|
+
const item = body.input[itemIndex];
|
|
59
|
+
if (!isPlainObject(item) || !Array.isArray(item.content)) continue;
|
|
60
|
+
let content: unknown[] | undefined;
|
|
61
|
+
for (let partIndex = 0; partIndex < item.content.length; partIndex += 1) {
|
|
62
|
+
const part = item.content[partIndex];
|
|
63
|
+
if (!isPlainObject(part) || part.type !== "output_text" || !Array.isArray(part.annotations)) continue;
|
|
64
|
+
let annotations: unknown[] | undefined;
|
|
65
|
+
for (let annIndex = 0; annIndex < part.annotations.length; annIndex += 1) {
|
|
66
|
+
const ann = part.annotations[annIndex];
|
|
67
|
+
if (!isPlainObject(ann) || ann.type !== "url_citation") continue;
|
|
68
|
+
const titleOk = typeof ann.title === "string";
|
|
69
|
+
const startOk = isUrlCitationIndex(ann.start_index);
|
|
70
|
+
const endOk = isUrlCitationIndex(ann.end_index);
|
|
71
|
+
if (titleOk && startOk && endOk) continue;
|
|
72
|
+
const next: Record<string, unknown> = { ...ann };
|
|
73
|
+
if (!titleOk) next.title = typeof ann.url === "string" ? ann.url : "";
|
|
74
|
+
if (!startOk) next.start_index = repairUrlCitationIndex(ann.start_index);
|
|
75
|
+
if (!endOk) next.end_index = repairUrlCitationIndex(ann.end_index);
|
|
76
|
+
annotations ??= [...part.annotations];
|
|
77
|
+
annotations[annIndex] = next;
|
|
78
|
+
}
|
|
79
|
+
if (!annotations) continue;
|
|
80
|
+
content ??= [...item.content];
|
|
81
|
+
content[partIndex] = { ...part, annotations };
|
|
82
|
+
}
|
|
83
|
+
if (!content) continue;
|
|
84
|
+
input ??= [...body.input];
|
|
85
|
+
input[itemIndex] = { ...item, content };
|
|
86
|
+
}
|
|
27
87
|
return input ? { ...body, input } : body;
|
|
28
88
|
}
|
|
29
89
|
|
package/src/adapters/registry.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createAnthropicAdapter } from "./anthropic";
|
|
2
|
+
import { createWorkBuddyAdapter } from "./workbuddy";
|
|
2
3
|
import { createDshAccountAdapter } from "./dsh-account";
|
|
3
4
|
import { createAzureAdapter } from "./azure";
|
|
4
5
|
import type { ProviderAdapter } from "./base";
|
|
@@ -74,6 +75,10 @@ type InheritedAdapterDefinition = {
|
|
|
74
75
|
type AdapterDefinition = DirectAdapterDefinition | InheritedAdapterDefinition;
|
|
75
76
|
|
|
76
77
|
export const ADAPTER_REGISTRY = {
|
|
78
|
+
"workbuddy-ai": {
|
|
79
|
+
contractParent: "openai-chat",
|
|
80
|
+
create: (provider: OcxProviderConfig) => withUniqueToolCallIds(createWorkBuddyAdapter(provider)),
|
|
81
|
+
},
|
|
77
82
|
codebuddy: {
|
|
78
83
|
wire: "codebuddy",
|
|
79
84
|
mutation: "codex-owned",
|