@bitkyc08/opencodex 2.80.0 → 2.82.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 +3 -3
- package/bin/ocx.mjs +166 -73
- package/gui/dist/assets/App-Ds_qL7o8.js +54 -0
- package/gui/dist/assets/Tray-BqHF5Trd.js +1 -0
- package/gui/dist/assets/{index-Brk6F3fn.css → index-BAbcj51J.css} +1 -1
- package/gui/dist/assets/index-D3FBCNiP.js +94 -0
- package/gui/dist/assets/quota-summary-DTBC8n7-.js +1 -0
- package/gui/dist/index.html +2 -2
- package/gui/dist/provider-icons/claude-green.svg +1 -0
- package/package.json +3 -2
- package/src/adapters/anthropic-model-contract.ts +8 -2
- package/src/adapters/anthropic.ts +8 -3
- package/src/adapters/codebuddy/mcp-server.ts +2 -25
- package/src/adapters/codebuddy/tool-bridge.ts +1 -7
- package/src/adapters/coding-agent/mcp-server.ts +33 -0
- package/src/adapters/coding-agent/protocol.ts +122 -17
- package/src/adapters/coding-agent/tool-catalog.ts +75 -0
- package/src/adapters/coding-agent/turn.ts +101 -44
- package/src/adapters/cursor/catalog.ts +8 -0
- package/src/adapters/cursor/effort-map.ts +2 -0
- package/src/adapters/devin/live-models.ts +2 -0
- package/src/adapters/kiro-retry.ts +9 -4
- package/src/adapters/openai-chat/messages.ts +7 -6
- package/src/adapters/openai-responses/compaction-search-history.ts +109 -0
- package/src/adapters/openai-responses/passthrough.ts +9 -4
- package/src/adapters/openai-responses/tool-output-recovery.ts +20 -0
- package/src/adapters/physical-send.ts +8 -5
- package/src/adapters/qoder/adapter.ts +41 -6
- package/src/adapters/qoder/scaffold-guard.ts +2 -3
- package/src/adapters/zed.ts +16 -1
- package/src/claude/agents-inject.ts +14 -3
- package/src/claude/context-windows.ts +19 -17
- package/src/claude/desktop-3p.ts +88 -12
- package/src/claude/desktop-profile.ts +2 -1
- package/src/claude/gateway-cache.ts +18 -1
- package/src/claude/inbound-cache-stabilize.ts +4 -9
- package/src/claude/inbound.ts +78 -3
- package/src/claude/intercept/cli-catalog.ts +3 -0
- package/src/claude/intercept/model-bindings.ts +1 -0
- package/src/claude/intercept/picker-ca-persistence.ts +7 -6
- package/src/claude/intercept/picker-listener.ts +71 -4
- package/src/claude/intercept/picker-models.ts +14 -6
- package/src/claude/intercept/settings.ts +3 -0
- package/src/claude/long-context.ts +66 -0
- package/src/claude/model-info.ts +19 -16
- package/src/claude/outbound.ts +94 -9
- package/src/claude/subagent-model.ts +40 -11
- package/src/cli/account-anthropic-threshold.ts +14 -5
- package/src/cli/account-api.ts +3 -1
- package/src/cli/account-extended.ts +13 -9
- package/src/cli/account-policy-dto.ts +1 -1
- package/src/cli/account-policy.ts +13 -4
- package/src/cli/account.ts +3 -3
- package/src/cli/agent.ts +9 -5
- package/src/cli/aside-profile-recovery.ts +33 -0
- package/src/cli/capabilities-accounts.ts +2 -2
- package/src/cli/capabilities-agents-routing.ts +24 -0
- package/src/cli/capabilities-base.ts +5 -5
- package/src/cli/capabilities-integrations.ts +18 -2
- package/src/cli/cli-path-diagnostics.ts +132 -0
- package/src/cli/codex-shim-autorestore.ts +3 -0
- package/src/cli/desktop-runtime-guidance.ts +65 -0
- package/src/cli/dispatch.ts +15 -1
- package/src/cli/doctor.ts +16 -3
- package/src/cli/help.ts +4 -1
- package/src/cli/index.ts +25 -14
- package/src/cli/integration-aside-sync.ts +2 -1
- package/src/cli/integration-plan-dto.ts +1 -0
- package/src/cli/integration-preview.ts +8 -1
- package/src/cli/integrations.ts +48 -6
- package/src/cli/message-args.ts +34 -0
- package/src/cli/message-command.ts +43 -0
- package/src/cli/message-runtime.ts +6 -0
- package/src/cli/observe.ts +3 -1
- package/src/cli/provider.ts +29 -6
- package/src/cli/registry.ts +24 -2
- package/src/cli/resolve.ts +25 -2
- package/src/cli/root.ts +4 -2
- package/src/cli/status.ts +64 -12
- package/src/cli/update-restart-child.ts +4 -2
- package/src/cli/update-restart-home.ts +28 -10
- package/src/cli/update-restart-service-record.ts +116 -0
- package/src/cli/update-restart-supervision.ts +96 -0
- package/src/cli/update-restart.ts +59 -13
- package/src/cli/v2.ts +27 -20
- package/src/cli/version-skew-notice.ts +77 -0
- package/src/clients/config-export/commandcode.ts +131 -0
- package/src/clients/config-export/contracts.ts +12 -0
- package/src/clients/config-export.ts +64 -1
- package/src/clients/lazycodex.ts +1 -1
- package/src/clients/omo-role-models.ts +32 -7
- package/src/codex/auth-api/account-list.ts +11 -3
- package/src/codex/auth-api/account-selection.ts +107 -0
- package/src/codex/auth-api/main-account-probe.ts +25 -8
- package/src/codex/auth-api/pool-mode-gate.ts +33 -9
- package/src/codex/auth-api/pool-quota-probe.ts +15 -1
- package/src/codex/auth-api/routes.ts +11 -49
- package/src/codex/auth-context.ts +20 -1
- package/src/codex/autostart-health.ts +12 -3
- package/src/codex/catalog/auto-review.ts +13 -6
- package/src/codex/catalog/build-entries.ts +33 -7
- package/src/codex/catalog/bundled.ts +155 -26
- package/src/codex/catalog/combo-member.ts +3 -2
- package/src/codex/catalog/control-plane.ts +45 -0
- package/src/codex/catalog/effort.ts +37 -6
- package/src/codex/catalog/gather-capture.ts +10 -3
- package/src/codex/catalog/model-hints.ts +15 -8
- package/src/codex/catalog/model-visibility.ts +3 -1
- package/src/codex/catalog/operator-tiers.ts +38 -0
- package/src/codex/catalog/parsing.ts +2 -1
- package/src/codex/catalog/provider-models.ts +58 -44
- package/src/codex/catalog/retained-sync.ts +7 -5
- package/src/codex/catalog/routed-gather.ts +15 -1
- package/src/codex/catalog-auto-refresh-sources.ts +3 -4
- package/src/codex/catalog-auto-refresh.ts +19 -0
- package/src/codex/catalog.ts +1 -1
- package/src/codex/codex-home-owner.ts +3 -0
- package/src/codex/config-write-lock.ts +333 -0
- package/src/codex/control-plane-models.ts +6 -0
- package/src/codex/convergence.ts +2 -1
- package/src/codex/features.ts +257 -200
- package/src/codex/inject/config-write-section.ts +34 -0
- package/src/codex/inject/multi-agent-v2.ts +14 -6
- package/src/codex/inject/remove.ts +36 -11
- package/src/codex/inject/restore.ts +85 -20
- package/src/codex/inject-coordination.ts +15 -6
- package/src/codex/inject.ts +62 -20
- package/src/codex/journal.ts +62 -17
- package/src/codex/main-account-cache.ts +43 -0
- package/src/codex/paths.ts +2 -0
- package/src/codex/prepared-home.ts +18 -0
- package/src/codex/prompt-journal.ts +25 -12
- package/src/codex/prompt-layers.ts +49 -26
- package/src/codex/prompt-lock-claim.ts +134 -0
- package/src/codex/prompt-lock-evidence.ts +26 -0
- package/src/codex/prompt-lock-io.ts +16 -0
- package/src/codex/prompt-lock-owner.ts +130 -0
- package/src/codex/prompt-lock.ts +84 -53
- package/src/codex/routing/failure-window.ts +146 -0
- package/src/codex/routing/selection.ts +4 -1
- package/src/codex/routing.ts +13 -17
- package/src/codex/runtime.ts +106 -18
- package/src/codex/shim.ts +45 -19
- package/src/combos/jev-decision-contract.ts +25 -2
- package/src/combos/jev-service-exchange.ts +281 -0
- package/src/combos/jev.ts +34 -219
- package/src/combos/types.ts +1 -1
- package/src/config/atomic-write.ts +1 -1
- package/src/config/codex-ws-reuse-setting.ts +10 -0
- package/src/config/diagnostics.ts +27 -16
- package/src/config/live-reconcile.ts +17 -0
- package/src/config/load-degrade.ts +42 -0
- package/src/config/rebase-provenance.ts +11 -0
- package/src/config/schema/anthropic-account-pool.ts +143 -0
- package/src/config/schema/config-schema.ts +11 -1
- package/src/config/schema/leaf-validators.ts +4 -0
- package/src/config.ts +2 -0
- package/src/generated/compatibility-version.json +566 -298
- package/src/generated/model-metadata.ts +7 -6
- package/src/grok/inject.ts +50 -4
- package/src/grok/sync.ts +2 -1
- package/src/images/loop.ts +30 -11
- package/src/integrations/aside-profiles.ts +10 -3
- package/src/integrations/catalog-refresh.ts +19 -3
- package/src/integrations/mutation-plan.ts +7 -0
- package/src/integrations/registry.ts +8 -0
- package/src/integrations/state.ts +9 -2
- package/src/integrations/writer.ts +17 -5
- package/src/lib/bun-path-runtime.d.mts +32 -0
- package/src/lib/bun-path-runtime.mjs +95 -0
- package/src/lib/bun-runtime-preflight.ts +140 -0
- package/src/lib/desktop-cli-handoff.d.mts +20 -0
- package/src/lib/desktop-cli-handoff.mjs +92 -0
- package/src/lib/desktop-cli-record.d.mts +29 -0
- package/src/lib/desktop-cli-record.mjs +102 -0
- package/src/lib/lab-live-route-production.ts +9 -1
- package/src/lib/request-execution-budget.ts +244 -58
- package/src/lib/spend-pool-alias-validation.ts +79 -0
- package/src/lib/spend-pool-continuity.ts +34 -0
- package/src/lib/spend-reservation-ledger.ts +412 -50
- package/src/lib/state-store-registrations.ts +20 -3
- package/src/lib/synced-state-location.ts +46 -6
- package/src/lib/test-home-guard.ts +87 -1
- package/src/lib/translator-budget.ts +17 -4
- package/src/lib/upstream-retry.ts +17 -5
- package/src/lib/windows-atomic-replace.ts +38 -16
- package/src/lib/windows-elevation.ts +6 -0
- package/src/lib/windows-secret-acl.ts +92 -25
- package/src/lib/winsw.ts +2 -3
- package/src/lib/workflow-budget.ts +53 -11
- package/src/messaging/budget.ts +45 -0
- package/src/messaging/discovery.ts +57 -0
- package/src/messaging/envelope.ts +49 -0
- package/src/messaging/input.ts +37 -0
- package/src/messaging/rpc.ts +196 -0
- package/src/messaging/send.ts +58 -0
- package/src/messaging/socket.ts +72 -0
- package/src/messaging/types.ts +29 -0
- package/src/oauth/anthropic-account-refusal.ts +90 -18
- package/src/oauth/anthropic-account-threshold.ts +8 -2
- package/src/oauth/anthropic-continuity.ts +15 -1
- package/src/oauth/anthropic-model-quota.ts +120 -48
- package/src/oauth/anthropic-model-routes.ts +11 -3
- package/src/oauth/anthropic-oauth-definitions.ts +98 -0
- package/src/oauth/anthropic-pool-config.ts +30 -0
- package/src/oauth/anthropic-rate-limit-policy.ts +64 -9
- package/src/oauth/anthropic-routing.ts +1202 -866
- package/src/oauth/anthropic-send-ownership.ts +41 -0
- package/src/oauth/anthropic.ts +4 -1
- package/src/oauth/chatgpt.ts +113 -41
- package/src/oauth/generic-account-failover.ts +3 -1
- package/src/oauth/health.ts +8 -6
- package/src/oauth/index.ts +96 -175
- package/src/oauth/kiro.ts +22 -9
- package/src/oauth/login-cli.ts +2 -0
- package/src/oauth/model-discovery-auth.ts +43 -0
- package/src/oauth/pool-kernel.ts +11 -5
- package/src/oauth/pool-settings-capability.ts +5 -3
- package/src/oauth/store-anthropic-instance.ts +87 -0
- package/src/oauth/store.ts +68 -10
- package/src/oauth/token-guardian.ts +2 -0
- package/src/oauth/types.ts +2 -0
- package/src/protocols/plan-snapshot.ts +5 -0
- package/src/protocols/settings.ts +20 -5
- package/src/providers/anthropic-instance-id.ts +47 -0
- package/src/providers/anthropic-instance.ts +48 -0
- package/src/providers/anthropic-reset-grant-ledger.ts +11 -1
- package/src/providers/azure-model-metadata.ts +115 -0
- package/src/providers/derive.ts +23 -0
- package/src/providers/kiro-models.ts +3 -0
- package/src/providers/label.ts +1 -1
- package/src/providers/model-rename-fields.ts +2 -0
- package/src/providers/quota/account-cache.ts +37 -11
- package/src/providers/quota/anthropic-account-quota.ts +93 -0
- package/src/providers/quota/anthropic-cooldown-recovery.ts +222 -111
- package/src/providers/quota/report-cache.ts +24 -1
- package/src/providers/quota/vendor-probes-key.ts +127 -17
- package/src/providers/quota/vendor-probes-oauth.ts +46 -14
- package/src/providers/quota.ts +23 -33
- package/src/providers/registry/entries-core.ts +35 -30
- package/src/providers/registry/model-ids.ts +1 -0
- package/src/providers/registry/model-seeds.ts +7 -4
- package/src/providers/registry/types.ts +3 -0
- package/src/providers/registry.ts +3 -3
- package/src/responses/reasoning-envelope.ts +29 -1
- package/src/responses/reasoning-replay-cache.ts +17 -1
- package/src/responses/spill-store.ts +20 -3
- package/src/responses/state/metrics.ts +95 -0
- package/src/responses/state/snapshot-codec.ts +6 -0
- package/src/responses/state/spill-failure.ts +12 -0
- package/src/responses/state/spill-queue.ts +13 -5
- package/src/responses/state/unforced-store-false.ts +55 -0
- package/src/responses/state.ts +68 -76
- package/src/responses/task-input.ts +17 -0
- package/src/router.ts +28 -4
- package/src/routing/compatibility/assemble.ts +1 -1
- package/src/routing/quota.ts +7 -3
- package/src/server/auth-cors.ts +5 -0
- package/src/server/background-lifecycle.ts +27 -0
- package/src/server/chat-completions.ts +7 -1
- package/src/server/chat-native.ts +64 -28
- package/src/server/claude-messages.ts +59 -8
- package/src/server/gui-static.ts +38 -4
- package/src/server/inbound-body-admission.ts +1 -0
- package/src/server/index/claude-intercept-lifecycle.ts +3 -1
- package/src/server/index/serve-options.ts +10 -2
- package/src/server/index/spend-ledger-lifecycle.ts +12 -5
- package/src/server/index/startup-warnings.ts +19 -0
- package/src/server/index.ts +5 -2
- package/src/server/inference/context.ts +1 -1
- package/src/server/lifecycle.ts +1 -1
- package/src/server/management/agent-settings-routes.ts +123 -38
- package/src/server/management/anthropic-account-threshold.ts +12 -9
- package/src/server/management/anthropic-pool-settings.ts +72 -0
- package/src/server/management/anthropic-reset-grant-routes.ts +98 -39
- package/src/server/management/codex-agent-role-routes.ts +4 -2
- package/src/server/management/codex-prompt-routes.ts +1 -0
- package/src/server/management/codex-role-auto-assign.ts +13 -2
- package/src/server/management/config-routes.ts +85 -14
- package/src/server/management/context.ts +2 -2
- package/src/server/management/decision-routes.ts +2 -1
- package/src/server/management/integration-routes.ts +25 -2
- package/src/server/management/oauth-account-routes.ts +79 -98
- package/src/server/management/provider-instance-ownership.ts +44 -0
- package/src/server/management/provider-routes.ts +21 -28
- package/src/server/management/route-registry.ts +3 -1
- package/src/server/management/routing-profile-routes.ts +4 -4
- package/src/server/management/shared.ts +3 -3
- package/src/server/management/system-restart.ts +44 -14
- package/src/server/management/system-routes.ts +24 -2
- package/src/server/management/vision-sidecar-options.ts +9 -6
- package/src/server/management/web-search-sidecar-options.ts +51 -2
- package/src/server/management-auth.ts +6 -0
- package/src/server/messages-native-eligibility.ts +3 -2
- package/src/server/messages-native-oauth.ts +91 -45
- package/src/server/messages-native-selector.ts +39 -0
- package/src/server/messages-native.ts +133 -38
- package/src/server/messages-response-headers.ts +14 -0
- package/src/server/request-log-conversation.ts +48 -5
- package/src/server/request-log.ts +36 -2
- package/src/server/responses/adapter-continuation.ts +31 -19
- package/src/server/responses/adapter-dispatch.ts +75 -24
- package/src/server/responses/antigravity-validation-refusal.ts +20 -6
- package/src/server/responses/codex-ws-exchange.ts +17 -2
- package/src/server/responses/codex-ws-pool.ts +100 -13
- package/src/server/responses/codex-ws-wire.ts +9 -0
- package/src/server/responses/combo-requested-effort.ts +3 -1
- package/src/server/responses/compact.ts +25 -8
- package/src/server/responses/compaction-recovery.ts +1 -1
- package/src/server/responses/core-codex-account.ts +22 -1
- package/src/server/responses/core-combo-native.ts +24 -4
- package/src/server/responses/core-combo.ts +38 -25
- package/src/server/responses/core-lifetime.ts +3 -36
- package/src/server/responses/core-normalize.ts +1 -0
- package/src/server/responses/core-options.ts +8 -1
- package/src/server/responses/core-replay.ts +78 -0
- package/src/server/responses/core.ts +3 -3
- package/src/server/responses/fetch-helpers.ts +26 -3
- package/src/server/responses/passthrough-delivery.ts +30 -4
- package/src/server/responses/passthrough-dispatch.ts +39 -9
- package/src/server/responses/request-prepare.ts +41 -5
- package/src/server/responses/request-send-budget.ts +150 -50
- package/src/server/responses/request-spend.ts +325 -33
- package/src/server/responses/request-transport.ts +132 -52
- package/src/server/responses/response-effects.ts +1 -0
- package/src/server/responses/run-turn-execution.ts +13 -3
- package/src/server/responses/sidecar-execution.ts +113 -22
- package/src/server/responses/sidecar-send-budget.ts +58 -0
- package/src/server/responses/ws-upstream.ts +19 -6
- package/src/server/responses-undeclared-tool-guard.ts +5 -1
- package/src/server/startup-health-cache.ts +2 -1
- package/src/server/workflow-refusal.ts +33 -0
- package/src/service/cli.ts +20 -4
- package/src/service/desktop-command-guard.ts +32 -0
- package/src/service/desktop-startup.ts +66 -40
- package/src/service/desktop-supervision.d.mts +26 -0
- package/src/service/desktop-supervision.mjs +140 -0
- package/src/service/managing-cli.ts +1 -0
- package/src/service/orchestration.ts +46 -20
- package/src/service/ownership-mutation-lease.d.mts +1 -1
- package/src/service/ownership-mutation-lease.mjs +5 -7
- package/src/service/repair.ts +25 -9
- package/src/service/state.ts +4 -3
- package/src/service/systemd.ts +17 -8
- package/src/service/windows-ops.ts +61 -22
- package/src/sidecar/anthropic-binding.ts +79 -0
- package/src/sidecar/auth.ts +76 -2
- package/src/storage/policy-job.ts +5 -1
- package/src/storage/policy-worker.ts +3 -1
- package/src/storage/policy.ts +9 -0
- package/src/types/anthropic-account-pool.ts +33 -0
- package/src/types/config.ts +33 -28
- package/src/types/provider.ts +5 -0
- package/src/types/request.ts +5 -0
- package/src/types/tools.ts +7 -0
- package/src/types/wire.ts +1 -0
- package/src/types.ts +4 -0
- package/src/update/index.ts +57 -9
- package/src/update/restart-ownership.ts +10 -3
- package/src/update/runtime-ownership.d.mts +6 -0
- package/src/update/runtime-ownership.mjs +23 -7
- package/src/usage/cost.ts +3 -2
- package/src/usage/expected-prices.ts +66 -14
- package/src/vision/anthropic-describe.ts +16 -3
- package/src/vision/index.ts +3 -0
- package/src/vision/plan.ts +19 -6
- package/src/web-search/alpha-search.ts +7 -1
- package/src/web-search/anthropic-executor.ts +16 -4
- package/src/web-search/index.ts +7 -3
- package/src/web-search/loop.ts +32 -7
- package/src/web-search/passthrough-bridge.ts +4 -1
- package/src/web-search/sidecar-providers.ts +4 -3
- package/gui/dist/assets/App-MbDVfUeC.js +0 -54
- package/gui/dist/assets/Tray-CzkxK82A.js +0 -1
- package/gui/dist/assets/index-UJt6npXk.js +0 -94
- package/gui/dist/assets/quota-summary-DU3sD6Z-.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{S as e,n as t,v as n}from"./index-D3FBCNiP.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:`M4 6h16M4 12h16M4 18h16`})}),u=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`})]}),d=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`})]}),f=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M22 12h-4l-3 9L9 3l-3 9H2`})}),p=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`})]}),m=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`m20 6-11 11-5-5`})}),h=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M18 6 6 18M6 6l12 12`})}),g=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:`M5 12h14`})}),v=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`})}),ee=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M8 5v14M16 5v14`})}),te=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`m7 4 13 8-13 8Z`})}),ne=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6`})}),re=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`})}),ie=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`})]}),ae=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`})]}),oe=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`})]}),se=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`})]}),ce=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M12 19V5M5 12l7-7 7 7`})}),le=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`M12 5v14M19 12l-7 7-7-7`})}),ue=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`})}),de=e=>(0,r.jsx)(`svg`,{...i(e),children:(0,r.jsx)(`path`,{d:`m9 18 6-6-6-6`})}),fe=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`})}),pe=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`})]}),me=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`})}),he=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`})]}),ge=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`})}),_e=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`})]}),ve=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`})]}),ye=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`})}),be=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`})]}),xe=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`})}),Se=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`})]}),Ce=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`})]}),we=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`})]}),Te=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`})}),Ee=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`,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`,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`},De=new Set([...Object.keys(x),...Object.keys(S)]);function Oe(e){let t=e.toLowerCase();return Object.hasOwn(b,t)?b[t]:void 0}function ke(e,t){let n=Oe(e);return n?`/provider-icons/${n}`:void 0}var Ae=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`]),je=new Set([`baseten.svg`,`kilo.svg`,`sambanova.svg`,`venice.svg`,`zai.svg`]),Me=new Set([`bizrouter.svg`,`featherless.svg`,`hyperbolic.svg`,`nebius.svg`,`parallel.svg`,`umans.svg`]);function Ne(e){if(!e)return`image`;let t=e.split(`/`).pop()??``;return Ae.has(t)?`mask`:je.has(t)?`plate`:Me.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 Pe(e){return De.has(e.toLowerCase())}function Fe(e){return e===`command-code`?`commandcode-auth`:e===`commandcode`?`commandcode-api`:e}function Ie(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 Le={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 Re(e,t){let n=Le[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 ze=new Set([`claude-cli`]),Be=`anthropic-apikey`;function T(e){return ze.has((e.adapter??``).trim())}var E=`https://chatgpt.com/backend-api/codex`,Ve=`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 He=new URL(E).protocol;function O(e,...t){return`${He}//${e}/${t.join(`/`)}`}var Ue={"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 We(e,t){let n=Ue[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===Ve&&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 Ge(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 Ke(e){let t=[],n=[],r=[];for(let[i,a]of Object.entries(e)){if(a.disabled){r.push({name:i,...a});continue}A(a)?t.push({name:i,...a,tier:P(i,a)}):n.push({name:i,...a})}return{ready:t,needsSetup:n,disabled:r}}function qe(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 Je(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 Ye=[`ollama`,`vllm`,`lm-studio`,`lmstudio`,`litellm`,`localai`];function Xe(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 Ye.some(e=>n.includes(e))?`selfHosted`:`cloud`}function L(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 Ze(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=L(i,t);r.trim()&&e&&(n[r]=e)}return n}function Qe(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=L(r,t);typeof e==`string`&&e.trim()&&i&&(n[e]=i)}return n}function $e(e){return e?.observed===!0&&typeof e.updatedAt==`number`?e.updatedAt:void 0}var R=e=>typeof e==`number`&&Number.isFinite(e)?e:void 0,et=e=>{let t=R(e);if(t===void 0)return;let n=t>1e10?t:t*1e3;return Number.isFinite(new Date(n).getTime())?t:void 0};function z(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`||R(t.percent)===void 0?[]:[{label:t.label,percent:t.percent,...R(t.resetAt)===void 0?{}:{resetAt:t.resetAt}}]}):[],i=n.creditsUsd&&typeof n.creditsUsd==`object`&&!Array.isArray(n.creditsUsd)?n.creditsUsd:null,a=R(i?.used),o=R(i?.limit),s=R(i?.remaining),c=R(i?.percent),l=et(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={...R(n.fiveHourPercent)===void 0?{}:{fiveHourPercent:n.fiveHourPercent},...R(n.fiveHourResetAt)===void 0?{}:{fiveHourResetAt:n.fiveHourResetAt},...R(n.weeklyPercent)===void 0?{}:{weeklyPercent:n.weeklyPercent},...R(n.weeklyResetAt)===void 0?{}:{weeklyResetAt:n.weeklyResetAt},...R(n.monthlyPercent)===void 0?{}:{monthlyPercent:n.monthlyPercent},...R(n.monthlyResetAt)===void 0?{}:{monthlyResetAt:n.monthlyResetAt},...r.length>0?{customWindows:r}:{},...u?{creditsUsd:u}:{},updatedAt:R(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 B(e){return z(e?.quota,e?.updatedAt)}function tt(e){if(!e)return;if(e.aggregation===void 0)return e;let t=H(e)?.currentAccount?.quota??null;return{...e,aggregation:void 0,quota:t,updatedAt:t?.updatedAt}}function V(e){if(!e||typeof e!=`object`||Array.isArray(e))return;let t=e,n=R(t.usedPercent);if(n!==void 0)return{usedPercent:n,...typeof t.incomplete==`boolean`?{incomplete:t.incomplete}:{},...R(t.excludedAccounts)===void 0?{}:{excludedAccounts:t.excludedAccounts},...R(t.nextRecoveryAt)===void 0?{}:{nextRecoveryAt:t.nextRecoveryAt},...R(t.nextRecoveryPercent)===void 0?{}:{nextRecoveryPercent:t.nextRecoveryPercent}}}function H(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=R(n.excludedAccounts),i=R(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=V(t);return typeof t.label==`string`&&n?[{label:t.label,...n}]:[]}):[],s=V(n.fiveHour),c=V(n.weekly),l=V(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:R(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:z(a.quota)}}:{}}}function nt(e){if(!e?.trim())return``;let[t,n]=e.split(`:`,2);return n?`${t} · ${n.replace(/-/g,` `)}`:e}function rt(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 it(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 at(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 U({name:t,adapter:n,baseUrl:i,cls:a}){let o=e(),s=ke(t,{adapter:n,baseUrl:i}),c=Ne(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)(ot,{name:t,label:C(t,o)})})}function ot({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 st({item:t,selected:n,tabbable:i,modelCount:a,isDefault:o,showConfigId:s,onClick:c,onFocus:l}){let u=e(),d=N(t),f=I(t),p=rt(t,u),m=C(t.name,u),h=s?`${m} (${t.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?t.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)(U,{name:t.name,adapter:t.adapter,baseUrl:t.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:at(t),title:p,"aria-hidden":`true`})]})]})}var ct=1e10;function lt(e){return e<ct?e*1e3:e}function ut(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 lt(r)>t}function dt(e){return{fiveHourAvailable:e?.shortWindowSeconds===18e3&&typeof e.shortResetAt==`number`,weeklyAvailable:typeof e?.weeklyResetAt==`number`}}function ft(e){let t=e?.trim().toLowerCase();return t===`go`||t===`free`}function pt(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 ft(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=(ft(t)?[e.monthlyPercent]:[e.weeklyPercent,e.monthlyPercent]).filter(r);if(a.length===0)return ut({...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 W(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&&W(o.hiddenProviders)===W(t.hiddenProviders)&&(t.models===null?o.models===null:W(o.models)===W(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 G(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 K=[`#0A84FF`,`#FF9F0A`,`#30D158`,`#BF5AF2`,`#FF453A`,`#64D2FF`],wt=640,Tt=160,q=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=q,f=u.map((e,t)=>(0,r.jsx)(`text`,{x:q+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(${q},${q})`,fill:`none`,stroke:K[t%K.length],strokeWidth:`2`,strokeLinejoin:`round`,strokeLinecap:`round`},e.id)):Ct(e.series,584,104,l,0).map(e=>(0,r.jsx)(`rect`,{x:q+e.x,y:q+e.y,width:e.width,height:e.height,fill:K[e.seriesIndex%K.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:q,y1:d,x2:q,y2:132,className:`usage-companion-axis`}),(0,r.jsx)(`line`,{x1:q,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:G(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:K[t%K.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 J=e=>typeof e==`number`&&Number.isFinite(e)&&e>=0,Y=e=>typeof e==`object`&&e&&!Array.isArray(e)?e:{};function kt(e){return Object.entries(Y(Y(e).providers)).flatMap(([e,t])=>{let n=Y(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`}:Y(e.mainAccountHardLock).state===`blocked`?{switchState:`blocked`,blockedReason:`mainHardLock`}:e.paused===!0?{switchState:`blocked`,blockedReason:`paused`}:Y(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=Y(e),n=t.accounts??t.keys;if(!Array.isArray(n))throw Error(`Invalid account roster`);return n.map(e=>{let n=Y(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:Y(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(Y(n.quota),o),status:typeof Y(n.health).status==`string`?Y(n.health).status:void 0,quotaFailure:typeof n.quotaFailure==`string`?n.quotaFailure:void 0,quota:pt(a,o)}})}function X(e){if(!J(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=X(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 Z(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=>J(e.percent)||X(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 It(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=>J(t[e]))&&(a[e]=i.reduce((t,n)=>t+n[e],0));return{...e,models:i,summary:a}}function Lt(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 Rt(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 zt(e){let t=Y(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 Bt(e){return Q(e)?`${Math.floor(e)}%`:`-`}var Vt=[`quota.weeklyLimit`,`quota.monthlyLimit`,`quota.fiveHourLimit`];function Ht(e){let t=Z(e).map(e=>{let t=Q(e.percent)?e.percent:void 0,n=X(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=X(n.expiresAt);t.push({id:`quotaSummary.credits`,labelKey:`quotaSummary.credits`,percent:n.percent,...e===null?{}:{resetAt:e},severity:$(n.percent)})}return t}function Ut(e){let t=e.filter(e=>e.percent!==void 0),n=new Map(t.map(e=>[e.id,e]));for(let e of Vt){let t=n.get(e);if(t)return t}return t[0]}function Wt(e,t){let n=[];for(let[r,i]of Object.entries(e)){let e=B(i);if(!e)continue;let a=Ht(e),o=Ut(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{f as $,tt as A,pe as At,Je as B,h as Bt,pt as C,Se as Ct,it as D,ie as Dt,st as E,ee as Et,I as F,y as Ft,Ge as G,N as H,Xe as I,be as It,Re as J,Be as K,qe as L,d as Lt,Ze as M,se as Mt,Qe as N,o as Nt,B as O,te as Ot,$e as P,we as Pt,Fe as Q,F as R,ve as Rt,mt as S,_ as St,U as T,u as Tt,We as U,M as V,P as W,C as X,Ie as Y,Pe as Z,gt as _,oe as _t,Rt as a,m as at,yt as b,_e as bt,Lt as c,ue as ct,kt as d,Ee as dt,ae as et,Z as f,fe as ft,xt as g,p as gt,vt as h,Te as ht,At as i,s as it,nt as j,v as jt,H as k,g as kt,Nt as l,me as lt,Ot as m,a as mt,Bt as n,ce as nt,It as o,de as ot,Ft as p,Ce as pt,T as q,$ as r,c as rt,J as s,ge as st,Wt as t,le as tt,zt as u,re as ut,ht as v,he as vt,dt as w,xe as wt,bt as x,l as xt,G as y,ye as yt,Ke as z,ne as zt};
|
package/gui/dist/index.html
CHANGED
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
document.documentElement.lang = langMap[locale];
|
|
37
37
|
})();
|
|
38
38
|
</script>
|
|
39
|
-
<script type="module" crossorigin src="/assets/index-
|
|
40
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
39
|
+
<script type="module" crossorigin src="/assets/index-D3FBCNiP.js"></script>
|
|
40
|
+
<link rel="stylesheet" crossorigin href="/assets/index-BAbcj51J.css">
|
|
41
41
|
</head>
|
|
42
42
|
<body>
|
|
43
43
|
<div id="root"></div>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg style="flex:none;line-height:1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Claude Pool 2</title><style>@media(prefers-color-scheme:dark){path{fill:#4ecb9d}}</style><path d="M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z" fill="#0a7d5c" fill-rule="nonzero"></path></svg>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bitkyc08/opencodex",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.82.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",
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"trustedDependencies": [
|
|
42
42
|
"bun"
|
|
43
43
|
],
|
|
44
|
+
"testRunnerBun": "1.4.0",
|
|
44
45
|
"scripts": {
|
|
45
46
|
"dev": "bun run src/cli/index.ts start",
|
|
46
47
|
"dev:proxy": "bun run src/cli/index.ts start",
|
|
@@ -82,7 +83,7 @@
|
|
|
82
83
|
"@bufbuild/protobuf": "^2.14.0",
|
|
83
84
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
84
85
|
"@napi-rs/keyring": "1.3.0",
|
|
85
|
-
"bun": "1.4.
|
|
86
|
+
"bun": "1.4.2",
|
|
86
87
|
"zod": "4.4.3"
|
|
87
88
|
},
|
|
88
89
|
"devDependencies": {
|
|
@@ -11,11 +11,13 @@
|
|
|
11
11
|
* while older families (Haiku 4.5, Sonnet 4.x, Opus <= 4.6) 400 on `adaptive` — so both wire
|
|
12
12
|
* shapes must stay. Verified against api.anthropic.com: sonnet-5, fable-5, opus-4-7 and opus-4-8
|
|
13
13
|
* require adaptive; haiku-4-5 and sonnet-4-5 reject it; opus-4-6/sonnet-4-6 accept both.
|
|
14
|
+
* Haiku 5.5 requires adaptive (platform.claude.com Haiku 5.5 migration guide, 2026-10-08).
|
|
14
15
|
*/
|
|
15
16
|
const ADAPTIVE_THINKING_FAMILY_MINIMUMS: Record<string, readonly [major: number, minor: number]> = {
|
|
16
17
|
sonnet: [5, 0],
|
|
17
18
|
opus: [4, 7],
|
|
18
19
|
fable: [0, 0],
|
|
20
|
+
haiku: [5, 5],
|
|
19
21
|
};
|
|
20
22
|
|
|
21
23
|
/**
|
|
@@ -88,11 +90,13 @@ export function usesBetweenToolsFloor(modelId: string): boolean {
|
|
|
88
90
|
* need no disable at all. Seeded with the family where the defect reproduces
|
|
89
91
|
* (#545); widen only with vendor evidence, since a wrong entry here turns a
|
|
90
92
|
* silent truncation into a 400. Sonnet 5.5 dropped `disabled` again, so the
|
|
91
|
-
* Sonnet range ends there and `usesBetweenToolsFloor` takes over.
|
|
93
|
+
* Sonnet range ends there and `usesBetweenToolsFloor` takes over. Haiku 5.5+ accepts disable
|
|
94
|
+
* at high effort or below; send no effort with it (Haiku 5.5 migration guide, 2026-10-08).
|
|
92
95
|
*/
|
|
93
96
|
export function supportsExplicitThinkingDisable(modelId: string): boolean {
|
|
94
97
|
const parsed = claudeFamilyVersion(modelId);
|
|
95
|
-
return parsed?.family === "sonnet" && atLeast(parsed, [5, 0]) && !atLeast(parsed, [5, 5])
|
|
98
|
+
return (parsed?.family === "sonnet" && atLeast(parsed, [5, 0]) && !atLeast(parsed, [5, 5]))
|
|
99
|
+
|| (parsed?.family === "haiku" && atLeast(parsed, [5, 5]));
|
|
96
100
|
}
|
|
97
101
|
|
|
98
102
|
/**
|
|
@@ -111,6 +115,7 @@ export function rejectsForcedToolChoice(modelId: string): boolean {
|
|
|
111
115
|
* Families that 400 on any non-default `temperature`, `top_p` or `top_k` ("temperature is deprecated
|
|
112
116
|
* for this model."), with or without thinking. Live 2026-09-29: Opus 4.7, 4.8, 5 and 5.5,
|
|
113
117
|
* Sonnet 5 and 5.5, Fable 5 and 5.1 reject them; Opus 4.6, Sonnet 4.6 and Haiku 4.5 accept them.
|
|
118
|
+
* Haiku 5.5 rejects them too (Haiku 5.5 migration guide, read 2026-10-08).
|
|
114
119
|
* `temperature: 1` (the default) is accepted everywhere, but the adapter drops the field rather than
|
|
115
120
|
* guess which value a caller meant as default.
|
|
116
121
|
*/
|
|
@@ -118,6 +123,7 @@ const SAMPLING_REJECTION_FAMILY_MINIMUMS: Record<string, readonly [major: number
|
|
|
118
123
|
sonnet: [5, 0],
|
|
119
124
|
opus: [4, 7],
|
|
120
125
|
fable: [0, 0],
|
|
126
|
+
haiku: [5, 5],
|
|
121
127
|
};
|
|
122
128
|
|
|
123
129
|
export function rejectsSamplingParameters(modelId: string): boolean {
|
|
@@ -624,9 +624,14 @@ function usageFromAnthropic(usage: unknown): OcxUsage | undefined {
|
|
|
624
624
|
// canonical inclusive convention (types.ts OcxUsage / devlog 070).
|
|
625
625
|
const inputTokens = input + read + write;
|
|
626
626
|
if (!Number.isFinite(inputTokens)) return undefined;
|
|
627
|
+
// Thinking is a reported subset of output, not extra billable output or an
|
|
628
|
+
// estimate from visible summaries. Invalid optional detail leaves totals intact.
|
|
629
|
+
const thinking = isAnthropicRecord(usage.output_tokens_details) ? usage.output_tokens_details.thinking_tokens : undefined;
|
|
630
|
+
const reasoningOutputTokens = typeof thinking === "number" && Number.isFinite(thinking) && thinking >= 0 && thinking <= output ? thinking : undefined;
|
|
627
631
|
return {
|
|
628
632
|
inputTokens,
|
|
629
633
|
outputTokens: output,
|
|
634
|
+
...(reasoningOutputTokens !== undefined ? { reasoningOutputTokens } : {}),
|
|
630
635
|
...(hasCache ? {
|
|
631
636
|
cachedInputTokens: read,
|
|
632
637
|
cacheReadInputTokens: read,
|
|
@@ -1011,7 +1016,7 @@ export function createAnthropicAdapter(provider: OcxProviderConfig, cacheRetenti
|
|
|
1011
1016
|
// "none" is not the same as absent. Omitting `thinking` lets a default-on model think
|
|
1012
1017
|
// anyway, and thinking shares the caller's `max_tokens` — which truncates a small-budget
|
|
1013
1018
|
// request before it can emit its stop sequence (#545). Say "disabled" out loud where the
|
|
1014
|
-
|
|
1019
|
+
// model both defaults to thinking and accepts being told not to.
|
|
1015
1020
|
const effectiveReasoning = parsed.options.reasoning ?? defaultReasoningEffort(provider, parsed.modelId);
|
|
1016
1021
|
if (effectiveReasoning === "none" && supportsExplicitThinkingDisable(parsed.modelId)) {
|
|
1017
1022
|
body.thinking = { type: "disabled" };
|
|
@@ -1078,7 +1083,7 @@ export function createAnthropicAdapter(provider: OcxProviderConfig, cacheRetenti
|
|
|
1078
1083
|
}
|
|
1079
1084
|
|
|
1080
1085
|
if (rejectsSamplingParameters(parsed.modelId)) {
|
|
1081
|
-
// Opus 4.7+, Sonnet 5+ and Fable 400 on
|
|
1086
|
+
// Opus 4.7+, Sonnet 5+, Haiku 5.5+ and Fable 400 on non-default sampling, with or without
|
|
1082
1087
|
// thinking (anthropic-model-contract.ts).
|
|
1083
1088
|
delete body.temperature;
|
|
1084
1089
|
delete body.top_p;
|
|
@@ -1362,7 +1367,7 @@ export function createAnthropicAdapter(provider: OcxProviderConfig, cacheRetenti
|
|
|
1362
1367
|
}
|
|
1363
1368
|
case "message_stop": {
|
|
1364
1369
|
yield* emitDone();
|
|
1365
|
-
|
|
1370
|
+
return;
|
|
1366
1371
|
}
|
|
1367
1372
|
case "ping": {
|
|
1368
1373
|
// A data-only `{"type":"ping"}` record carries no SSE `event:` line, so the
|
|
@@ -8,12 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { open } from "node:fs/promises";
|
|
11
|
-
import {
|
|
12
|
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
13
|
-
import {
|
|
14
|
-
CallToolRequestSchema,
|
|
15
|
-
ListToolsRequestSchema,
|
|
16
|
-
} from "@modelcontextprotocol/sdk/types.js";
|
|
11
|
+
import { serveCodingAgentMcpTools } from "../coding-agent/mcp-server";
|
|
17
12
|
import { CODEBUDDY_TOOL_LIMITS } from "./tool-bridge";
|
|
18
13
|
|
|
19
14
|
interface ToolDefinition {
|
|
@@ -156,25 +151,7 @@ async function loadTools(path: string): Promise<ToolDefinition[]> {
|
|
|
156
151
|
|
|
157
152
|
export async function runCodeBuddyMcpServer(catalogPath: string): Promise<void> {
|
|
158
153
|
if (!catalogPath) throw new Error("missing tool catalog");
|
|
159
|
-
|
|
160
|
-
// the parent terminates its CLI, including after a captured message_stop.
|
|
161
|
-
const exitOnStdinClose = (): void => process.exit(0);
|
|
162
|
-
process.stdin.on("end", exitOnStdinClose);
|
|
163
|
-
process.stdin.on("close", exitOnStdinClose);
|
|
164
|
-
|
|
165
|
-
const tools = await loadTools(catalogPath);
|
|
166
|
-
const advertisedNames = new Set(tools.map(tool => tool.name));
|
|
167
|
-
const server = new Server(
|
|
168
|
-
{ name: "opencodex-codebuddy-capture", version: "1.0.0" },
|
|
169
|
-
{ capabilities: { tools: {} } },
|
|
170
|
-
);
|
|
171
|
-
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools }));
|
|
172
|
-
server.setRequestHandler(CallToolRequestSchema, async request => {
|
|
173
|
-
if (!advertisedNames.has(request.params.name)) throw new Error("unknown isolated tool");
|
|
174
|
-
// The external Codex client retains approval and execution ownership.
|
|
175
|
-
return await new Promise<never>(() => {});
|
|
176
|
-
});
|
|
177
|
-
await server.connect(new StdioServerTransport());
|
|
154
|
+
await serveCodingAgentMcpTools(await loadTools(catalogPath), "opencodex-codebuddy-capture");
|
|
178
155
|
}
|
|
179
156
|
|
|
180
157
|
if (import.meta.main) await runCodeBuddyMcpServer(process.argv[2] ?? "");
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import {
|
|
3
3
|
namespacedToolName,
|
|
4
|
+
requiresToolCall,
|
|
4
5
|
toolChoiceToolPredicate,
|
|
5
6
|
type OcxParsedRequest,
|
|
6
7
|
type OcxTool,
|
|
@@ -475,13 +476,6 @@ function codeBuddyToolAliases(wireNames: readonly string[]): Map<string, string>
|
|
|
475
476
|
return aliases;
|
|
476
477
|
}
|
|
477
478
|
|
|
478
|
-
function requiresToolCall(choice: OcxToolChoice | undefined): boolean {
|
|
479
|
-
return choice === "required"
|
|
480
|
-
|| (typeof choice === "object" && choice !== null && (
|
|
481
|
-
"name" in choice || ("mode" in choice && choice.mode === "required")
|
|
482
|
-
));
|
|
483
|
-
}
|
|
484
|
-
|
|
485
479
|
function validateToolNamePart(value: unknown): value is string {
|
|
486
480
|
return typeof value === "string"
|
|
487
481
|
&& value.length > 0
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
5
|
+
|
|
6
|
+
export interface CodingAgentMcpTool {
|
|
7
|
+
name: string;
|
|
8
|
+
description: string;
|
|
9
|
+
inputSchema: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** Advertise client tools without executing them: only Codex/client may execute a call. */
|
|
13
|
+
export async function serveCodingAgentMcpTools(tools: CodingAgentMcpTool[], serverName: string): Promise<void> {
|
|
14
|
+
const exitOnStdinClose = (): void => process.exit(0);
|
|
15
|
+
process.stdin.on("end", exitOnStdinClose);
|
|
16
|
+
process.stdin.on("close", exitOnStdinClose);
|
|
17
|
+
|
|
18
|
+
const names = new Set(tools.map(tool => tool.name));
|
|
19
|
+
const server = new Server({ name: serverName, version: "1.0.0" }, { capabilities: { tools: {} } });
|
|
20
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools }));
|
|
21
|
+
server.setRequestHandler(CallToolRequestSchema, async request => {
|
|
22
|
+
if (!names.has(request.params.name)) throw new Error("unknown isolated tool");
|
|
23
|
+
return new Promise<never>(() => {});
|
|
24
|
+
});
|
|
25
|
+
await server.connect(new StdioServerTransport());
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export async function runCodingAgentMcpServer(catalogPath: string): Promise<void> {
|
|
29
|
+
const tools = JSON.parse(await readFile(catalogPath, "utf8")) as CodingAgentMcpTool[];
|
|
30
|
+
await serveCodingAgentMcpTools(tools, "opencodex-coding-agent-tools");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (import.meta.main) await runCodingAgentMcpServer(process.argv[2] ?? "");
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { namespacedToolName, type AdapterEvent, type OcxMessage, type OcxParsedRequest, type OcxUsage } from "../../types";
|
|
2
2
|
import type { TranslatorBudget } from "../../lib/translator-budget";
|
|
3
|
+
import { isValidCodingAgentToolNamePart } from "./tool-catalog";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Shared stream-json protocol for official coding-agent CLIs (CodeBuddy Code and Qoder CLI).
|
|
@@ -227,6 +228,8 @@ export interface StreamParseState {
|
|
|
227
228
|
sawTerminalResult: boolean;
|
|
228
229
|
/** A `message_stop` stream event arrived: the assistant message is complete. */
|
|
229
230
|
sawMessageStop?: boolean;
|
|
231
|
+
/** The final complete assistant block explicitly ends a tool-use response. */
|
|
232
|
+
sawAssistantToolUseStop?: boolean;
|
|
230
233
|
/**
|
|
231
234
|
* Open tool_use blocks keyed by content-block index. CodeBuddy parallel tool calls arrive
|
|
232
235
|
* as several tool_use blocks on ONE shared content-block index — intermediate blocks never
|
|
@@ -240,8 +243,10 @@ export interface StreamParseState {
|
|
|
240
243
|
openToolBlocks?: Map<number, OpenToolBlock>;
|
|
241
244
|
/** Shared request budget for tool identity and buffered argument fragments. */
|
|
242
245
|
translatorBudget?: TranslatorBudget;
|
|
243
|
-
/** A capture bridge may impose a tighter ceiling
|
|
246
|
+
/** A capture bridge may impose a tighter ceiling on distinct calls and retained blocks. */
|
|
244
247
|
maxToolBlockStarts?: number;
|
|
248
|
+
/** Qoder's isolated CLI names, validated at partial block start before retaining anything. */
|
|
249
|
+
toolBridgeNames?: ReadonlyMap<string, string>;
|
|
245
250
|
/** Set before an over-limit block can be allocated or emitted. */
|
|
246
251
|
toolCallLimitExceeded?: boolean;
|
|
247
252
|
/** Synthetic decreasing keys for tool_use start frames that omit the block index. */
|
|
@@ -252,12 +257,16 @@ export interface StreamParseState {
|
|
|
252
257
|
completedToolCalls?: number;
|
|
253
258
|
/** CodeBuddy's capture-only bridge requires complete JSON and matching block indices. */
|
|
254
259
|
strictToolBlockCapture?: boolean;
|
|
255
|
-
/**
|
|
260
|
+
/** Retained bridge IDs; Qoder counts distinct admissions here, independently of open blocks. */
|
|
256
261
|
partialToolCallIds?: Set<string>;
|
|
257
262
|
/** One budget lease per ID retained by complete-assistant deduplication, released at turn cleanup. */
|
|
258
263
|
partialToolCallBudgetIds?: string[];
|
|
259
264
|
/** A complete assistant tool block had no matching partial capture. */
|
|
260
265
|
uncapturedToolUse?: boolean;
|
|
266
|
+
/** Consume complete assistant tool_use blocks when the CLI does not stream partial tool events. */
|
|
267
|
+
completeAssistantToolUse?: boolean;
|
|
268
|
+
/** Shared complete/partial snapshots retained for exact-repeat suppression and conflicting-ID rejection. */
|
|
269
|
+
emittedToolCalls?: Map<string, { name: string; argumentsJson: string; budgetCallIds: string[] }>;
|
|
261
270
|
/** Highest-seen usage snapshot from `message_delta`/assistant frames before a terminal result. */
|
|
262
271
|
partialUsage?: OcxUsage;
|
|
263
272
|
}
|
|
@@ -283,6 +292,7 @@ export function mapStreamMessageToEvents(message: StreamMessage, state: StreamPa
|
|
|
283
292
|
// Fallback path: a complete assistant message. Surface text and thinking independently
|
|
284
293
|
// only when the partial delta stream did not already carry them (§十二).
|
|
285
294
|
const messageRecord = asRecord(message.message);
|
|
295
|
+
if (messageRecord?.stop_reason === "tool_use") state.sawAssistantToolUseStop = true;
|
|
286
296
|
const content = messageRecord?.content;
|
|
287
297
|
if (Array.isArray(content)) {
|
|
288
298
|
for (const block of content) {
|
|
@@ -297,7 +307,45 @@ export function mapStreamMessageToEvents(message: StreamMessage, state: StreamPa
|
|
|
297
307
|
if (thinking) events.push({ type: "thinking_delta", thinking });
|
|
298
308
|
} else if (blockType === "tool_use") {
|
|
299
309
|
const id = asString(part.id);
|
|
300
|
-
if (
|
|
310
|
+
if (state.completeAssistantToolUse) {
|
|
311
|
+
const name = asString(part.name);
|
|
312
|
+
const input = asRecord(part.input);
|
|
313
|
+
if (!id || !name || !input) throw new CodingAgentProtocolError("Coding-agent CLI returned a tool call without structured identity and input.");
|
|
314
|
+
const argumentsJson = JSON.stringify(input);
|
|
315
|
+
if (isEmittedToolCallRepeat(state, id, name, argumentsJson)) continue;
|
|
316
|
+
const distinctIds = state.partialToolCallIds ??= new Set<string>();
|
|
317
|
+
const limit = Math.min(MAX_TOOL_BLOCK_STARTS, state.maxToolBlockStarts ?? MAX_TOOL_BLOCK_STARTS);
|
|
318
|
+
if (!distinctIds.has(id) && distinctIds.size >= limit) {
|
|
319
|
+
state.toolCallLimitExceeded = true;
|
|
320
|
+
return events;
|
|
321
|
+
}
|
|
322
|
+
const budget = state.translatorBudget;
|
|
323
|
+
const budgetCallIds: string[] = [];
|
|
324
|
+
if (budget) {
|
|
325
|
+
try {
|
|
326
|
+
// Match partial capture: ID has its own call limit; name and args share one.
|
|
327
|
+
for (const bytes of [Buffer.byteLength(id), Buffer.byteLength(name) + Buffer.byteLength(argumentsJson)]) {
|
|
328
|
+
const leaseId = `coding-agent-complete:${++nextBudgetCallOrdinal}`;
|
|
329
|
+
budget.openCall(leaseId);
|
|
330
|
+
budgetCallIds.push(leaseId);
|
|
331
|
+
budget.chargeRetained(bytes, { kind: "tool_args", callId: leaseId });
|
|
332
|
+
}
|
|
333
|
+
} catch (error) {
|
|
334
|
+
for (const leaseId of budgetCallIds) budget.closeCall(leaseId);
|
|
335
|
+
throw error;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
// Retain snapshot bytes until turn cleanup: dedup still owns name/input after emit.
|
|
339
|
+
(state.emittedToolCalls ??= new Map()).set(id, { name, argumentsJson, budgetCallIds });
|
|
340
|
+
distinctIds.add(id); // The ledger's lease already owns this ID.
|
|
341
|
+
state.toolBlockStarts = (state.toolBlockStarts ?? 0) + 1;
|
|
342
|
+
events.push(
|
|
343
|
+
{ type: "tool_call_start", id, name },
|
|
344
|
+
{ type: "tool_call_delta", arguments: argumentsJson },
|
|
345
|
+
{ type: "tool_call_end" },
|
|
346
|
+
);
|
|
347
|
+
state.completedToolCalls = (state.completedToolCalls ?? 0) + 1;
|
|
348
|
+
} else if (!id || !state.partialToolCallIds?.has(id)) state.uncapturedToolUse = true;
|
|
301
349
|
}
|
|
302
350
|
}
|
|
303
351
|
}
|
|
@@ -399,6 +447,16 @@ function resolveToolBlockKey(state: StreamParseState, event: StreamMessage): num
|
|
|
399
447
|
return state.strictToolBlockCapture && block.indexed ? undefined : key;
|
|
400
448
|
}
|
|
401
449
|
|
|
450
|
+
/** One emitted identity regardless of whether it arrived complete or in partial blocks. */
|
|
451
|
+
function isEmittedToolCallRepeat(state: StreamParseState, id: string, name: string, argumentsJson: string): boolean {
|
|
452
|
+
const previous = state.emittedToolCalls?.get(id);
|
|
453
|
+
if (!previous) return false;
|
|
454
|
+
if (previous.name !== name || previous.argumentsJson !== argumentsJson) {
|
|
455
|
+
throw new CodingAgentProtocolError("Coding-agent CLI reused a completed tool call ID with conflicting name or input.");
|
|
456
|
+
}
|
|
457
|
+
return true;
|
|
458
|
+
}
|
|
459
|
+
|
|
402
460
|
/**
|
|
403
461
|
* Emit a closed block atomically — start, the buffered fragments in arrival order, end —
|
|
404
462
|
* so the strictly sequential downstream bridge never sees two calls open at once.
|
|
@@ -406,24 +464,41 @@ function resolveToolBlockKey(state: StreamParseState, event: StreamMessage): num
|
|
|
406
464
|
function closeToolBlock(state: StreamParseState, key: number, events: AdapterEvent[], implicit = false): void {
|
|
407
465
|
const block = state.openToolBlocks?.get(key);
|
|
408
466
|
if (!block || !state.openToolBlocks) return;
|
|
409
|
-
|
|
467
|
+
let argumentsJson: string | undefined;
|
|
468
|
+
if (state.completeAssistantToolUse || (state.strictToolBlockCapture && (implicit || block.argParts.length > 0))) {
|
|
410
469
|
// A second start on this index is an implicit stop only when the previous call's
|
|
411
470
|
// arguments are already complete. Otherwise a later delta could be assigned to the
|
|
412
471
|
// wrong call and still produce a superficially successful tool-use turn. An explicit
|
|
413
472
|
// stop with no deltas retains the CLI's existing empty-arguments representation.
|
|
414
|
-
const
|
|
473
|
+
const rawArgumentsJson = block.argParts.join("");
|
|
415
474
|
let parsedArguments: unknown;
|
|
416
475
|
try {
|
|
417
|
-
parsedArguments = JSON.parse(
|
|
476
|
+
parsedArguments = JSON.parse(!implicit && block.argParts.length === 0 ? "{}" : rawArgumentsJson);
|
|
418
477
|
} catch {
|
|
419
478
|
throw new CodingAgentProtocolError("Coding-agent CLI ended a tool call with incomplete JSON arguments.");
|
|
420
479
|
}
|
|
421
480
|
if (!asRecord(parsedArguments)) {
|
|
422
481
|
throw new CodingAgentProtocolError("Coding-agent CLI ended a tool call with non-object JSON arguments.");
|
|
423
482
|
}
|
|
483
|
+
if (state.completeAssistantToolUse) {
|
|
484
|
+
argumentsJson = JSON.stringify(parsedArguments);
|
|
485
|
+
if (isEmittedToolCallRepeat(state, block.id, block.name, argumentsJson)) {
|
|
486
|
+
state.openToolBlocks.delete(key);
|
|
487
|
+
if (block.budgetCallId) state.translatorBudget?.closeCall(block.budgetCallId);
|
|
488
|
+
state.toolBlockStarts = (state.toolBlockStarts ?? 1) - 1;
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
// Canonical serialization can expand numeric literals; admit the retained snapshot too.
|
|
492
|
+
const extraBytes = Buffer.byteLength(argumentsJson) - Buffer.byteLength(rawArgumentsJson);
|
|
493
|
+
if (extraBytes > 0) state.translatorBudget?.chargeRetained(extraBytes, { kind: "tool_args", callId: block.budgetCallId });
|
|
494
|
+
}
|
|
424
495
|
}
|
|
425
496
|
state.openToolBlocks.delete(key);
|
|
426
|
-
if (
|
|
497
|
+
if (argumentsJson !== undefined) {
|
|
498
|
+
(state.emittedToolCalls ??= new Map()).set(block.id, {
|
|
499
|
+
name: block.name, argumentsJson, budgetCallIds: block.budgetCallId ? [block.budgetCallId] : [],
|
|
500
|
+
});
|
|
501
|
+
} else if (block.budgetCallId) state.translatorBudget?.closeCall(block.budgetCallId);
|
|
427
502
|
events.push({ type: "tool_call_start", id: block.id, name: block.name });
|
|
428
503
|
for (const part of block.argParts) events.push({ type: "tool_call_delta", arguments: part });
|
|
429
504
|
events.push({ type: "tool_call_end" });
|
|
@@ -438,6 +513,10 @@ export function releaseOpenToolBlocks(state: StreamParseState): void {
|
|
|
438
513
|
state.openToolBlocks?.clear();
|
|
439
514
|
for (const leaseId of state.partialToolCallBudgetIds ?? []) state.translatorBudget?.closeCall(leaseId);
|
|
440
515
|
state.partialToolCallBudgetIds = undefined;
|
|
516
|
+
for (const call of state.emittedToolCalls?.values() ?? []) {
|
|
517
|
+
for (const leaseId of call.budgetCallIds) state.translatorBudget?.closeCall(leaseId);
|
|
518
|
+
}
|
|
519
|
+
state.emittedToolCalls?.clear();
|
|
441
520
|
}
|
|
442
521
|
|
|
443
522
|
/** Map a raw Anthropic SSE event (carried inside a `stream_event` frame) to AdapterEvents. */
|
|
@@ -497,8 +576,17 @@ function mapRawStreamEvent(event: StreamMessage, state: StreamParseState): Adapt
|
|
|
497
576
|
const id = asString(block?.id) ?? "";
|
|
498
577
|
const name = asString(block?.name) ?? "tool";
|
|
499
578
|
if (id) {
|
|
579
|
+
if (state.completeAssistantToolUse && (!isValidCodingAgentToolNamePart(block?.name)
|
|
580
|
+
|| (state.toolBridgeNames && !state.toolBridgeNames.has(name)))) {
|
|
581
|
+
throw new CodingAgentProtocolError("Coding-agent CLI started a tool block with an invalid or undeclared name.");
|
|
582
|
+
}
|
|
583
|
+
const previous = state.emittedToolCalls?.get(id);
|
|
584
|
+
if (previous && previous.name !== name) {
|
|
585
|
+
throw new CodingAgentProtocolError("Coding-agent CLI reused a completed tool call ID with conflicting name or input.");
|
|
586
|
+
}
|
|
587
|
+
const distinctIds = state.completeAssistantToolUse ? (state.partialToolCallIds ??= new Set<string>()) : undefined;
|
|
500
588
|
const limit = Math.min(MAX_TOOL_BLOCK_STARTS, state.maxToolBlockStarts ?? MAX_TOOL_BLOCK_STARTS);
|
|
501
|
-
if ((state.toolBlockStarts ?? 0) >= limit) {
|
|
589
|
+
if (distinctIds ? !distinctIds.has(id) && distinctIds.size >= limit : (state.toolBlockStarts ?? 0) >= limit) {
|
|
502
590
|
state.toolCallLimitExceeded = true;
|
|
503
591
|
return events;
|
|
504
592
|
}
|
|
@@ -511,6 +599,11 @@ function mapRawStreamEvent(event: StreamMessage, state: StreamParseState): Adapt
|
|
|
511
599
|
// block only after the capture path verifies its arguments form a complete object.
|
|
512
600
|
closeToolBlock(state, key, events, true);
|
|
513
601
|
}
|
|
602
|
+
// Repeats reserve no distinct ID, but each unfinished block retains its own lease.
|
|
603
|
+
if ((state.openToolBlocks?.size ?? 0) >= limit) {
|
|
604
|
+
state.toolCallLimitExceeded = true;
|
|
605
|
+
return events;
|
|
606
|
+
}
|
|
514
607
|
const budget = state.translatorBudget;
|
|
515
608
|
const budgetCallId = budget ? `coding-agent:${++nextBudgetCallOrdinal}` : undefined;
|
|
516
609
|
if (budget && budgetCallId) {
|
|
@@ -625,7 +718,7 @@ function imagePart(imageUrl: string): WireContentPart | undefined {
|
|
|
625
718
|
return undefined;
|
|
626
719
|
}
|
|
627
720
|
|
|
628
|
-
function formatMessageForHistory(message: OcxMessage): string {
|
|
721
|
+
function formatMessageForHistory(message: OcxMessage, vendorNameByWire?: ReadonlyMap<string, string>): string {
|
|
629
722
|
if (message.role === "user") {
|
|
630
723
|
const text = typeof message.content === "string"
|
|
631
724
|
? message.content
|
|
@@ -640,8 +733,11 @@ function formatMessageForHistory(message: OcxMessage): string {
|
|
|
640
733
|
} else if (part.type === "thinking" && part.thinking.trim()) {
|
|
641
734
|
parts.push(`[Thinking: ${part.thinking.trim()}]`);
|
|
642
735
|
} else if (part.type === "toolCall") {
|
|
736
|
+
// Without a vendor map the history keeps the bare request name, byte-for-byte as before.
|
|
737
|
+
const wireName = vendorNameByWire ? namespacedToolName(part.namespace, part.name) : part.name;
|
|
738
|
+
const name = vendorNameByWire?.get(wireName) ?? wireName;
|
|
643
739
|
const args = JSON.stringify(part.arguments ?? {});
|
|
644
|
-
parts.push(`[Tool call: ${
|
|
740
|
+
parts.push(`[Tool call: ${name} (call_id: ${part.id}) with args: ${args}]`);
|
|
645
741
|
}
|
|
646
742
|
}
|
|
647
743
|
return `ASSISTANT:\n${parts.join("\n") || "(empty response)"}`;
|
|
@@ -663,7 +759,10 @@ function formatMessageForHistory(message: OcxMessage): string {
|
|
|
663
759
|
* accepts `type: "user"` frames. Writing undocumented `type: "assistant"` frames is rejected.
|
|
664
760
|
* Non-user messages are therefore projected into valid user frames.
|
|
665
761
|
*/
|
|
666
|
-
export function buildInputLines(
|
|
762
|
+
export function buildInputLines(
|
|
763
|
+
message: OcxMessage,
|
|
764
|
+
options: { vendorNameByWire?: ReadonlyMap<string, string> } = {},
|
|
765
|
+
): string[] {
|
|
667
766
|
if (message.role === "developer") return [];
|
|
668
767
|
|
|
669
768
|
const content: WireContentPart[] = [];
|
|
@@ -684,7 +783,7 @@ export function buildInputLines(message: OcxMessage): string[] {
|
|
|
684
783
|
}
|
|
685
784
|
}
|
|
686
785
|
} else {
|
|
687
|
-
const formatted = formatMessageForHistory(message);
|
|
786
|
+
const formatted = formatMessageForHistory(message, options.vendorNameByWire);
|
|
688
787
|
if (formatted) content.push(textPart(formatted));
|
|
689
788
|
}
|
|
690
789
|
|
|
@@ -718,14 +817,17 @@ export function buildSystemPrompt(parsed: OcxParsedRequest): string | undefined
|
|
|
718
817
|
* prior conversation turns are structured as bounded context text with tool results as text,
|
|
719
818
|
* clearly demarcated from the current user request. Codex retains tool control; vendor tools are never invoked.
|
|
720
819
|
*/
|
|
721
|
-
export function buildConversationInput(
|
|
820
|
+
export function buildConversationInput(
|
|
821
|
+
parsed: OcxParsedRequest,
|
|
822
|
+
options: { maxHistoryChars?: number; vendorNameByWire?: ReadonlyMap<string, string> } = {},
|
|
823
|
+
): string[] {
|
|
722
824
|
const nonDev = parsed.context.messages.filter(m => m.role !== "developer");
|
|
723
825
|
if (nonDev.length === 0) {
|
|
724
826
|
return [JSON.stringify({ type: "user", message: { role: "user", content: [{ type: "text", text: "" }] } })];
|
|
725
827
|
}
|
|
726
828
|
|
|
727
829
|
if (nonDev.length === 1 && nonDev[0]!.role === "user") {
|
|
728
|
-
return buildInputLines(nonDev[0]
|
|
830
|
+
return buildInputLines(nonDev[0]!, { vendorNameByWire: options.vendorNameByWire });
|
|
729
831
|
}
|
|
730
832
|
|
|
731
833
|
// Multi-turn conversation or history with tool results:
|
|
@@ -796,13 +898,16 @@ export function buildConversationInput(parsed: OcxParsedRequest, options: { maxH
|
|
|
796
898
|
const status = currentMessage.isError ? " (error)" : "";
|
|
797
899
|
currentRequestText = `TOOL RESULT (call_id: ${currentMessage.toolCallId})${status}:\n${text}\n\nPlease proceed based on the above tool result.`;
|
|
798
900
|
} else {
|
|
799
|
-
currentRequestText = formatMessageForHistory(currentMessage);
|
|
901
|
+
currentRequestText = formatMessageForHistory(currentMessage, options.vendorNameByWire);
|
|
800
902
|
}
|
|
801
903
|
|
|
802
904
|
const imageBlocks: WireContentPart[] = [...historyImageBlocks, ...currentImageBlocks];
|
|
803
905
|
|
|
804
906
|
const maxHistoryChars = options.maxHistoryChars ?? MAX_PROJECTED_HISTORY_CHARS;
|
|
805
|
-
let historyText = historyMessages
|
|
907
|
+
let historyText = historyMessages
|
|
908
|
+
.map(msg => formatMessageForHistory(msg, options.vendorNameByWire))
|
|
909
|
+
.filter(Boolean)
|
|
910
|
+
.join("\n\n");
|
|
806
911
|
if (historyText.length > maxHistoryChars) {
|
|
807
912
|
historyText = `[Earlier conversation history truncated for length...]\n\n` +
|
|
808
913
|
historyText.slice(historyText.length - maxHistoryChars);
|