@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,41 @@
|
|
|
1
|
+
/** Ownership captured before a physical send, independent of subsequent cooldown observations. */
|
|
2
|
+
import type { OAuthAccessSnapshot } from "./index";
|
|
3
|
+
import { credentialGeneration, getAccountSet, type AuthStore } from "./store";
|
|
4
|
+
import { isAnthropicInstanceId, type AnthropicInstanceId } from "../providers/anthropic-instance-id";
|
|
5
|
+
import { anthropicCooldownRecoveryFor } from "../providers/quota/anthropic-cooldown-recovery";
|
|
6
|
+
import { captureProviderAccountQuotaEpoch } from "../providers/quota/account-cache";
|
|
7
|
+
|
|
8
|
+
export type AnthropicPhysicalSendOwnership = Readonly<{
|
|
9
|
+
provider: AnthropicInstanceId;
|
|
10
|
+
accountId: string;
|
|
11
|
+
accessToken: string;
|
|
12
|
+
generation: string;
|
|
13
|
+
accountIncarnation: number;
|
|
14
|
+
loginId?: string;
|
|
15
|
+
addedAt?: number;
|
|
16
|
+
quotaEpoch: number;
|
|
17
|
+
}>;
|
|
18
|
+
|
|
19
|
+
/** Namespace API: config/target admission remains with the config-aware physical caller. */
|
|
20
|
+
export function captureAnthropicPhysicalSendOwnership(snapshot: OAuthAccessSnapshot): AnthropicPhysicalSendOwnership | null {
|
|
21
|
+
if (!isAnthropicInstanceId(snapshot.provider)) return null;
|
|
22
|
+
const row = getAccountSet(snapshot.provider)?.accounts.find(account => account.id === snapshot.accountId);
|
|
23
|
+
if (!row || row.paused || row.needsReauth || row.credential.access !== snapshot.accessToken
|
|
24
|
+
|| credentialGeneration(row.credential) !== snapshot.generation) return null;
|
|
25
|
+
return Object.freeze({
|
|
26
|
+
provider: snapshot.provider, accountId: snapshot.accountId,
|
|
27
|
+
accessToken: snapshot.accessToken, generation: snapshot.generation,
|
|
28
|
+
accountIncarnation: anthropicCooldownRecoveryFor(snapshot.provider).reserveAnthropicAccountIncarnation(snapshot.accountId),
|
|
29
|
+
loginId: row.loginId, addedAt: row.addedAt,
|
|
30
|
+
quotaEpoch: captureProviderAccountQuotaEpoch(snapshot.provider),
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Pure ownership read: never adopt or reserve the replacement account's current incarnation. */
|
|
35
|
+
export function anthropicPhysicalSendOwnershipIsCurrent(owner: AnthropicPhysicalSendOwnership, store?: AuthStore): boolean {
|
|
36
|
+
const row = (store ? store[owner.provider] : getAccountSet(owner.provider))?.accounts.find(account => account.id === owner.accountId);
|
|
37
|
+
return !!row && row.loginId === owner.loginId && row.addedAt === owner.addedAt
|
|
38
|
+
&& row.credential.access === owner.accessToken && credentialGeneration(row.credential) === owner.generation
|
|
39
|
+
&& anthropicCooldownRecoveryFor(owner.provider).anthropicAccountIncarnation(owner.accountId) === owner.accountIncarnation
|
|
40
|
+
&& captureProviderAccountQuotaEpoch(owner.provider) === owner.quotaEpoch;
|
|
41
|
+
}
|
package/src/oauth/anthropic.ts
CHANGED
|
@@ -4,6 +4,8 @@ import { bindAnthropicIdentity, resolveAnthropicAccountIdentity } from "./anthro
|
|
|
4
4
|
import { generatePKCE } from "./pkce";
|
|
5
5
|
import type { LocalTokenImportMode, OAuthController, OAuthCredentials } from "./types";
|
|
6
6
|
import { outboundProxyConfigured, startupOutboundProxyConfigured } from "../lib/proxy-env";
|
|
7
|
+
import type { AnthropicInstanceId } from "../providers/anthropic-instance-id";
|
|
8
|
+
import { AnthropicLocalCliImportError } from "./store-anthropic-instance";
|
|
7
9
|
|
|
8
10
|
const CLIENT_ID = atob("OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl");
|
|
9
11
|
const AUTHORIZE_URL = "https://claude.ai/oauth/authorize";
|
|
@@ -178,9 +180,10 @@ export class AnthropicOAuthFlow extends OAuthCallbackFlow {
|
|
|
178
180
|
|
|
179
181
|
export async function loginAnthropic(
|
|
180
182
|
ctrl: OAuthController,
|
|
181
|
-
opts?: { importLocal?: LocalTokenImportMode },
|
|
183
|
+
opts?: { importLocal?: LocalTokenImportMode; instance?: AnthropicInstanceId },
|
|
182
184
|
): Promise<OAuthCredentials> {
|
|
183
185
|
const importLocal = opts?.importLocal ?? "off";
|
|
186
|
+
if (opts?.instance === "anthropic2" && importLocal !== "off") throw new AnthropicLocalCliImportError();
|
|
184
187
|
if (importLocal !== "off") {
|
|
185
188
|
const { detectClaudeCodeToken } = await import("./local-token-detect");
|
|
186
189
|
const local = detectClaudeCodeToken();
|
package/src/oauth/chatgpt.ts
CHANGED
|
@@ -1,6 +1,106 @@
|
|
|
1
1
|
import { OAuthCallbackFlow } from "./callback-server";
|
|
2
2
|
import type { OAuthController, OAuthCredentials } from "./types";
|
|
3
3
|
import { generatePKCE } from "./pkce";
|
|
4
|
+
import { classifyChatgptRefreshFailure } from "../codex/chatgpt-refresh-failure";
|
|
5
|
+
import { readBoundedResponseBytes } from "../lib/bounded-body";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Per-fetch deadline for ChatGPT auth endpoint calls. The deviceauth grant got the
|
|
9
|
+
* same bound in #3898 after one stuck TCP connection held the login slot for the
|
|
10
|
+
* whole grant; a hung refresh would pin the refresh intent lock indefinitely.
|
|
11
|
+
*/
|
|
12
|
+
export const CHATGPT_FETCH_TIMEOUT_MS = 30_000;
|
|
13
|
+
|
|
14
|
+
/** Non-HTTP failures retain no caller reason, upstream error, or cause. */
|
|
15
|
+
export class ChatGptTokenRequestError extends Error {
|
|
16
|
+
readonly terminal = false;
|
|
17
|
+
|
|
18
|
+
constructor(kind: "abort" | "timeout" | "transport") {
|
|
19
|
+
super(kind === "abort" ? "ChatGPT token request cancelled"
|
|
20
|
+
: kind === "timeout" ? "ChatGPT token request timed out" : "ChatGPT token request failed");
|
|
21
|
+
this.name = kind === "abort" ? "AbortError" : kind === "timeout" ? "TimeoutError" : "ChatGptTokenRequestError";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const CHATGPT_ERROR_BODY_MAX_BYTES = 16 * 1024;
|
|
26
|
+
const CHATGPT_SUCCESS_BODY_MAX_BYTES = 64 * 1024;
|
|
27
|
+
|
|
28
|
+
/** One deadline covers headers and body; every settled call detaches its caller. */
|
|
29
|
+
async function chatGptTokenRequest(
|
|
30
|
+
body: URLSearchParams,
|
|
31
|
+
label: "ChatGPT refresh" | "ChatGPT token exchange",
|
|
32
|
+
options: { signal?: AbortSignal; timeoutMs?: number },
|
|
33
|
+
): Promise<OAuthCredentials> {
|
|
34
|
+
const controller = new AbortController();
|
|
35
|
+
const onAbort = () => controller.abort(new ChatGptTokenRequestError("abort"));
|
|
36
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
37
|
+
if (options.signal?.aborted) onAbort();
|
|
38
|
+
const timer = setTimeout(() => controller.abort(new ChatGptTokenRequestError("timeout")),
|
|
39
|
+
options.timeoutMs ?? CHATGPT_FETCH_TIMEOUT_MS);
|
|
40
|
+
let endpointError: ChatGptTokenError | undefined;
|
|
41
|
+
try {
|
|
42
|
+
controller.signal.throwIfAborted();
|
|
43
|
+
const response = await fetch(TOKEN_URL, {
|
|
44
|
+
method: "POST",
|
|
45
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
46
|
+
body: body.toString(),
|
|
47
|
+
signal: controller.signal,
|
|
48
|
+
});
|
|
49
|
+
const result = await readBoundedResponseBytes(response, {
|
|
50
|
+
signal: controller.signal,
|
|
51
|
+
maxBytes: response.ok ? CHATGPT_SUCCESS_BODY_MAX_BYTES : CHATGPT_ERROR_BODY_MAX_BYTES,
|
|
52
|
+
});
|
|
53
|
+
controller.signal.throwIfAborted();
|
|
54
|
+
const text = new TextDecoder().decode(result.bytes);
|
|
55
|
+
if (!response.ok) {
|
|
56
|
+
endpointError = chatGptTokenError(response.status, result.oversized ? "" : text, label);
|
|
57
|
+
throw endpointError;
|
|
58
|
+
}
|
|
59
|
+
if (result.oversized) throw new ChatGptTokenRequestError("transport");
|
|
60
|
+
return credsFromToken(JSON.parse(text) as Record<string, unknown>);
|
|
61
|
+
} catch (error) {
|
|
62
|
+
if (controller.signal.aborted) throw controller.signal.reason;
|
|
63
|
+
if (endpointError && error === endpointError) throw endpointError;
|
|
64
|
+
throw new ChatGptTokenRequestError("transport");
|
|
65
|
+
} finally {
|
|
66
|
+
clearTimeout(timer);
|
|
67
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Token-endpoint failure carrying the HTTP status, the allowlisted OAuth error code,
|
|
73
|
+
* and a terminal verdict requiring an explicit grant-refusal code. The shared
|
|
74
|
+
* Codex classifier supplies the code vocabulary; free text is never grant evidence.
|
|
75
|
+
*/
|
|
76
|
+
export class ChatGptTokenError extends Error {
|
|
77
|
+
constructor(
|
|
78
|
+
public readonly httpStatus: number,
|
|
79
|
+
public readonly oauthError: string | undefined,
|
|
80
|
+
public readonly terminal: boolean,
|
|
81
|
+
message: string,
|
|
82
|
+
) {
|
|
83
|
+
super(message);
|
|
84
|
+
this.name = "ChatGptTokenError";
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function chatGptTokenError(status: number, body: string, label: string): ChatGptTokenError {
|
|
89
|
+
const failure = classifyChatgptRefreshFailure(status, body);
|
|
90
|
+
// Reclassify the allowlisted code alone to reuse the shared terminal vocabulary
|
|
91
|
+
// without its description-only compatibility rule for other Codex callers.
|
|
92
|
+
const terminal = failure.reason !== "unknown" && failure.code !== undefined
|
|
93
|
+
&& classifyChatgptRefreshFailure(status, JSON.stringify({ error: failure.code })).reason !== "unknown";
|
|
94
|
+
// The message carries the status and the allowlisted OAuth code only — never the
|
|
95
|
+
// free-text `error_description`, which can echo OAuth material into log surfaces
|
|
96
|
+
// (the same closed vocabulary the pool's noteChatgptRefreshFailure logs with).
|
|
97
|
+
return new ChatGptTokenError(
|
|
98
|
+
status,
|
|
99
|
+
failure.code,
|
|
100
|
+
terminal,
|
|
101
|
+
`${label} failed: ${status} code=${failure.code ?? "none"}`,
|
|
102
|
+
);
|
|
103
|
+
}
|
|
4
104
|
|
|
5
105
|
const CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
|
|
6
106
|
const AUTH_URL = "https://auth.openai.com/oauth/authorize";
|
|
@@ -202,34 +302,16 @@ export class ChatGPTOAuthFlow extends OAuthCallbackFlow {
|
|
|
202
302
|
|
|
203
303
|
async exchangeToken(code: string, _state: string, redirectUri: string): Promise<OAuthCredentials> {
|
|
204
304
|
if (!this.#verifier) throw new Error("ChatGPT PKCE verifier not initialized");
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
redirect_uri: redirectUri,
|
|
213
|
-
code_verifier: this.#verifier,
|
|
214
|
-
}).toString(),
|
|
215
|
-
});
|
|
216
|
-
if (!resp.ok) {
|
|
217
|
-
const errDesc = await safeErrorDescription(resp);
|
|
218
|
-
throw new Error(`ChatGPT token exchange failed: ${resp.status} ${errDesc}`);
|
|
219
|
-
}
|
|
220
|
-
return credsFromToken((await resp.json()) as Record<string, unknown>);
|
|
305
|
+
return chatGptTokenRequest(new URLSearchParams({
|
|
306
|
+
grant_type: "authorization_code",
|
|
307
|
+
client_id: CLIENT_ID,
|
|
308
|
+
code,
|
|
309
|
+
redirect_uri: redirectUri,
|
|
310
|
+
code_verifier: this.#verifier,
|
|
311
|
+
}), "ChatGPT token exchange", { signal: this.ctrl.signal });
|
|
221
312
|
}
|
|
222
313
|
}
|
|
223
314
|
|
|
224
|
-
function safeErrorDescription(resp: Response): Promise<string> {
|
|
225
|
-
return resp.text().catch(() => "").then(text => {
|
|
226
|
-
try {
|
|
227
|
-
const parsed = JSON.parse(text) as { error?: string; error_description?: string };
|
|
228
|
-
return [parsed.error, parsed.error_description].filter(Boolean).join(": ") || `HTTP ${resp.status}`;
|
|
229
|
-
} catch { return `HTTP ${resp.status}`; }
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
|
|
233
315
|
/**
|
|
234
316
|
* How the user proves identity. `browser` runs the localhost:1455 callback flow;
|
|
235
317
|
* `device` runs the deviceauth grant, which needs no local browser or listener
|
|
@@ -255,21 +337,11 @@ export async function loginChatGPT(
|
|
|
255
337
|
// Codex-rs uses JSON for refresh — intentional divergence; both accepted by auth.openai.com.
|
|
256
338
|
export async function refreshChatGPTToken(
|
|
257
339
|
refreshToken: string,
|
|
258
|
-
options: { signal?: AbortSignal } = {},
|
|
340
|
+
options: { signal?: AbortSignal; timeoutMs?: number } = {},
|
|
259
341
|
): Promise<OAuthCredentials> {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
client_id: CLIENT_ID,
|
|
266
|
-
refresh_token: refreshToken,
|
|
267
|
-
}).toString(),
|
|
268
|
-
signal: options.signal,
|
|
269
|
-
});
|
|
270
|
-
if (!resp.ok) {
|
|
271
|
-
const errDesc = await safeErrorDescription(resp);
|
|
272
|
-
throw new Error(`ChatGPT refresh failed: ${resp.status} ${errDesc}`);
|
|
273
|
-
}
|
|
274
|
-
return credsFromToken((await resp.json()) as Record<string, unknown>);
|
|
342
|
+
return chatGptTokenRequest(new URLSearchParams({
|
|
343
|
+
grant_type: "refresh_token",
|
|
344
|
+
client_id: CLIENT_ID,
|
|
345
|
+
refresh_token: refreshToken,
|
|
346
|
+
}), "ChatGPT refresh", options);
|
|
275
347
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isBuiltinAnthropicInstanceRow } from "../providers/anthropic-instance";
|
|
1
2
|
/**
|
|
2
3
|
* Generic OAuth multi-account 429 failover (#2568).
|
|
3
4
|
*
|
|
@@ -157,7 +158,8 @@ export function kiroAutoSelection(
|
|
|
157
158
|
|
|
158
159
|
/** True when this provider participates in generic rotation at all. */
|
|
159
160
|
export function isGenericFailoverProvider(providerName: string, provider: OcxProviderConfig): boolean {
|
|
160
|
-
return provider.authMode === "oauth" && !EXCLUDED_PROVIDERS.has(providerName)
|
|
161
|
+
return provider.authMode === "oauth" && !EXCLUDED_PROVIDERS.has(providerName)
|
|
162
|
+
&& !isBuiltinAnthropicInstanceRow(providerName, provider);
|
|
161
163
|
}
|
|
162
164
|
|
|
163
165
|
/**
|
package/src/oauth/health.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { isAnthropicInstanceId } from "../providers/anthropic-instance-id";
|
|
1
2
|
import type { MainAccountHardLockStatus } from "../codex/main-account-hard-lock";
|
|
2
3
|
import type { MainAccountExternalUsageWarning } from "../codex/main-account-external-usage";
|
|
3
4
|
import { getCodexAccountHealthSnapshot, type CodexCooldownSource } from "../codex/routing";
|
|
4
|
-
import {
|
|
5
|
+
import { anthropicRoutingFor } from "./anthropic-routing";
|
|
5
6
|
import { isAccountNeedsReauth } from "../codex/account-runtime-state";
|
|
6
7
|
import { getCodexAccountCredential, listCodexAccountIds, readCodexAccountRecord } from "../codex/account-store";
|
|
7
8
|
import { MAIN_CODEX_ACCOUNT_ID } from "../codex/main-account";
|
|
@@ -10,7 +11,7 @@ import { LOCAL_MANAGEMENT_READ_PATHS } from "../lib/local-management-capability"
|
|
|
10
11
|
import { maskAccountId } from "../lib/privacy";
|
|
11
12
|
import { findLiveProxy } from "../server/proxy-liveness";
|
|
12
13
|
import { fetchBoundLocalManagementRead } from "../server/local-management-read-client";
|
|
13
|
-
import { loadAuthStore, peekAuthStore, peekOAuthRefreshIntent, readOAuthRefreshIntent } from "./store";
|
|
14
|
+
import { accountNeedsReauthForStatus, loadAuthStore, peekAuthStore, peekOAuthRefreshIntent, readOAuthRefreshIntent } from "./store";
|
|
14
15
|
import type { ProviderAccount } from "./types";
|
|
15
16
|
|
|
16
17
|
export type OAuthAccountHealth =
|
|
@@ -207,12 +208,13 @@ export function projectStoredOAuthAccountHealth(
|
|
|
207
208
|
now = Date.now(),
|
|
208
209
|
opts: { observeOnly?: boolean } = {},
|
|
209
210
|
): OAuthAccountHealth {
|
|
210
|
-
const anthropicSnap = provider
|
|
211
|
-
? getAnthropicAccountHealthSnapshot(account.id, now)
|
|
211
|
+
const anthropicSnap = isAnthropicInstanceId(provider)
|
|
212
|
+
? anthropicRoutingFor(provider).getAnthropicAccountHealthSnapshot(account.id, now)
|
|
212
213
|
: null;
|
|
214
|
+
const needsReauth = accountNeedsReauthForStatus(provider, account, now);
|
|
213
215
|
return projectOAuthAccountHealth({
|
|
214
|
-
needsReauth
|
|
215
|
-
reauthReason:
|
|
216
|
+
needsReauth,
|
|
217
|
+
reauthReason: needsReauth
|
|
216
218
|
? (account.needsReauthReason ?? "refresh_failed")
|
|
217
219
|
: undefined,
|
|
218
220
|
cooldownUntilMs: anthropicSnap?.cooldownUntil,
|