@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
|
@@ -19,17 +19,11 @@
|
|
|
19
19
|
* No token, account id or body content is logged or returned in an error message.
|
|
20
20
|
*/
|
|
21
21
|
import type { OAuthAccessSnapshot } from "../oauth";
|
|
22
|
-
import {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
resolveAnthropicDispatchAccountId,
|
|
28
|
-
resolveAnthropicAccountForSession,
|
|
29
|
-
getEligibleAnthropicAccounts,
|
|
30
|
-
isAnthropicAccountPoolEnabled,
|
|
31
|
-
} from "../oauth/anthropic-routing";
|
|
32
|
-
import { resolveAnthropicModelRoute, routeCandidates, type AnthropicRouteDecision } from "../oauth/anthropic-model-routes";
|
|
22
|
+
import { anthropicRoutingFor } from "../oauth/anthropic-routing";
|
|
23
|
+
import { resolveAnthropicModelRouteForInstance, routeCandidates, type AnthropicRouteDecision } from "../oauth/anthropic-model-routes";
|
|
24
|
+
import { configuredAnthropicInstance, type AnthropicInstanceId } from "../providers/anthropic-instance";
|
|
25
|
+
import { resolveAnthropicMessagesUrl } from "../adapters/anthropic";
|
|
26
|
+
import { routedProviderConfig } from "../router";
|
|
33
27
|
import {
|
|
34
28
|
captureOAuthAccountSelection,
|
|
35
29
|
commitOAuthAccountSelection,
|
|
@@ -40,7 +34,6 @@ import type { TranslatorBudget } from "../lib/translator-budget";
|
|
|
40
34
|
import type { OcxConfig } from "../types";
|
|
41
35
|
import { relaySseWithPayloadRewrite } from "./sse-payload-rewrite";
|
|
42
36
|
|
|
43
|
-
const PROVIDER = "anthropic";
|
|
44
37
|
const MAX_SELECTION_ATTEMPTS = 3;
|
|
45
38
|
|
|
46
39
|
type Selection = NonNullable<ReturnType<typeof captureOAuthAccountSelection>>;
|
|
@@ -52,6 +45,9 @@ function isRec(value: unknown): value is Rec {
|
|
|
52
45
|
|
|
53
46
|
/** The committed selection and the credential snapshot one native request is served with. */
|
|
54
47
|
export interface NativeOAuthBinding {
|
|
48
|
+
readonly instance: AnthropicInstanceId;
|
|
49
|
+
/** Config-authorized physical destination, captured before any credential await. */
|
|
50
|
+
readonly routeTarget: string;
|
|
55
51
|
readonly selection: Selection;
|
|
56
52
|
readonly snapshot: OAuthAccessSnapshot;
|
|
57
53
|
/** Anthropic account UUID from the same stored generation, distinct from snapshot.accountId. */
|
|
@@ -74,17 +70,43 @@ export class NativeOAuthSelectionChangedError extends Error {
|
|
|
74
70
|
/** Invalid operator route configuration remains a request refusal, not an auth failure. */
|
|
75
71
|
export class NativeOAuthModelRouteError extends Error {}
|
|
76
72
|
|
|
77
|
-
|
|
78
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Current configured ownership and target; a revoked B never resolves orphan credentials.
|
|
75
|
+
*
|
|
76
|
+
* Adapter, auth mode and destination are read from the routed provider, the same normalization the
|
|
77
|
+
* settled route used to compute its target. Routing canonicalizes the primary row's adapter and auth
|
|
78
|
+
* mode from the registry, so a raw-field comparison would refuse an existing Pool 1 row the route
|
|
79
|
+
* already accepted. B's own raw-row shape is still enforced through `configuredAnthropicInstance`.
|
|
80
|
+
*/
|
|
81
|
+
function nativeOAuthRouteTarget(instance: AnthropicInstanceId, config: OcxConfig): string {
|
|
82
|
+
const provider = config.providers[instance];
|
|
83
|
+
if (configuredAnthropicInstance(config, instance) !== instance || !provider || provider.disabled === true) {
|
|
84
|
+
throw new NativeOAuthSelectionChangedError();
|
|
85
|
+
}
|
|
86
|
+
let routed: ReturnType<typeof routedProviderConfig>;
|
|
87
|
+
try {
|
|
88
|
+
routed = routedProviderConfig(instance, provider);
|
|
89
|
+
} catch {
|
|
90
|
+
// A destination the router now refuses is a moved route, not a different failure class.
|
|
91
|
+
throw new NativeOAuthSelectionChangedError();
|
|
92
|
+
}
|
|
93
|
+
if (routed.authMode !== "oauth" || routed.adapter !== "anthropic") throw new NativeOAuthSelectionChangedError();
|
|
94
|
+
return resolveAnthropicMessagesUrl(routed);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function currentRoute(instance: AnthropicInstanceId, config: OcxConfig, model?: string): AnthropicRouteDecision | null {
|
|
98
|
+
const resolved = model ? resolveAnthropicModelRouteForInstance(instance, config, model) : { decision: null };
|
|
79
99
|
if (resolved.error) throw new NativeOAuthModelRouteError(`Invalid Anthropic model routes: ${resolved.error}`);
|
|
80
100
|
return resolved.decision ? { ...resolved.decision, accounts: [...resolved.decision.accounts] } : null;
|
|
81
101
|
}
|
|
82
102
|
|
|
83
|
-
function routeIsCurrent(config: OcxConfig, model: string | undefined, decision: AnthropicRouteDecision | null): boolean {
|
|
84
|
-
return JSON.stringify(currentRoute(config, model)) === JSON.stringify(decision);
|
|
103
|
+
function routeIsCurrent(instance: AnthropicInstanceId, config: OcxConfig, model: string | undefined, decision: AnthropicRouteDecision | null): boolean {
|
|
104
|
+
return JSON.stringify(currentRoute(instance, config, model)) === JSON.stringify(decision);
|
|
85
105
|
}
|
|
86
106
|
|
|
87
107
|
export interface NativeOAuthBindingOptions {
|
|
108
|
+
/** Settled route destination; retries may never authorize a replacement destination. */
|
|
109
|
+
routeTarget?: string;
|
|
88
110
|
sessionKey?: string | null;
|
|
89
111
|
model?: string;
|
|
90
112
|
/** An account proposed by the shared pre-output refusal recovery policy. */
|
|
@@ -94,51 +116,68 @@ export interface NativeOAuthBindingOptions {
|
|
|
94
116
|
expectedRecoveryRouteDecision?: AnthropicRouteDecision | null;
|
|
95
117
|
}
|
|
96
118
|
|
|
119
|
+
/** Compatibility entrypoint: the original instance only. */
|
|
120
|
+
export function resolveNativeOAuthBinding(config: OcxConfig, options: NativeOAuthBindingOptions = {}): Promise<NativeOAuthBinding> {
|
|
121
|
+
return resolveNativeOAuthBindingForInstance("anthropic", config, options);
|
|
122
|
+
}
|
|
123
|
+
|
|
97
124
|
/** Resolve the shared pool selector and commit its exact credential generation for dispatch. */
|
|
98
|
-
export async function
|
|
125
|
+
export async function resolveNativeOAuthBindingForInstance(
|
|
126
|
+
instance: AnthropicInstanceId,
|
|
99
127
|
config: OcxConfig,
|
|
100
128
|
options: NativeOAuthBindingOptions = {},
|
|
101
129
|
): Promise<NativeOAuthBinding> {
|
|
130
|
+
const routeTarget = options.routeTarget ?? nativeOAuthRouteTarget(instance, config);
|
|
131
|
+
const routing = anthropicRoutingFor(instance);
|
|
132
|
+
const assertOwner = () => {
|
|
133
|
+
if (nativeOAuthRouteTarget(instance, config) !== routeTarget) throw new NativeOAuthSelectionChangedError();
|
|
134
|
+
};
|
|
102
135
|
const sessionKey = options.sessionKey ?? null;
|
|
103
136
|
const model = options.model;
|
|
104
137
|
for (let attempt = 0; attempt < MAX_SELECTION_ATTEMPTS; attempt++) {
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
const proposed = resolveAnthropicAccountForSession(sessionKey, config, Date.now(), routeDecision, model);
|
|
112
|
-
// A lost selection commit discards a recovery proposal: a newer manual/policy choice wins.
|
|
138
|
+
assertOwner();
|
|
139
|
+
const routeDecision = currentRoute(instance, config, model);
|
|
140
|
+
const manualSelectionGeneration = routing.captureAnthropicManualSelectionGeneration();
|
|
141
|
+
const selection = captureOAuthAccountSelection(instance);
|
|
142
|
+
// A recovery candidate may replace a terminal active credential, including pool-off.
|
|
143
|
+
// A newer committed selection or route discards the proposal and uses normal admission.
|
|
113
144
|
const recoverySelectionMatches = !!options.expectedRecoverySelection
|
|
114
145
|
&& selection?.accountId === options.expectedRecoverySelection.accountId
|
|
115
146
|
&& selection?.revision === options.expectedRecoverySelection.revision;
|
|
116
147
|
const recoveryRouteMatches = options.expectedRecoveryRouteDecision === undefined
|
|
117
148
|
|| JSON.stringify(options.expectedRecoveryRouteDecision) === JSON.stringify(routeDecision);
|
|
118
|
-
const
|
|
119
|
-
? options.candidateAccountId :
|
|
149
|
+
const recoveryAccountId = attempt === 0 && options.candidateAccountId && recoverySelectionMatches && recoveryRouteMatches
|
|
150
|
+
? options.candidateAccountId : undefined;
|
|
151
|
+
const accountId = recoveryAccountId
|
|
152
|
+
?? await routing.resolveAnthropicDispatchAccountId(config, sessionKey, routeDecision, model);
|
|
153
|
+
assertOwner();
|
|
154
|
+
if (!routeIsCurrent(instance, config, model, routeDecision)) continue;
|
|
155
|
+
const proposed = routing.resolveAnthropicAccountForSession(sessionKey, config, Date.now(), routeDecision, model);
|
|
120
156
|
if (!selection) continue;
|
|
121
|
-
if (!routeCandidates(getEligibleAnthropicAccounts(Date.now(), model), routeDecision).includes(accountId)) {
|
|
157
|
+
if (!routeCandidates(routing.getEligibleAnthropicAccounts(Date.now(), model), routeDecision).includes(accountId)) {
|
|
122
158
|
throw new NativeOAuthSelectionChangedError();
|
|
123
159
|
}
|
|
124
|
-
const candidate = await getAnthropicPoolAccessSnapshot(accountId);
|
|
125
|
-
|
|
126
|
-
|
|
160
|
+
const candidate = await routing.getAnthropicPoolAccessSnapshot(accountId);
|
|
161
|
+
assertOwner();
|
|
162
|
+
if (candidate.provider !== instance) throw new NativeOAuthSelectionChangedError();
|
|
163
|
+
if (!routeIsCurrent(instance, config, model, routeDecision)) continue;
|
|
164
|
+
const committed = await commitOAuthAccountSelection(instance, candidate.accountId, {
|
|
127
165
|
expectedSelection: selection,
|
|
128
166
|
expectedCredentialGeneration: candidate.generation,
|
|
129
167
|
requireUsableAccount: true,
|
|
130
168
|
});
|
|
169
|
+
assertOwner();
|
|
131
170
|
if (committed) {
|
|
132
|
-
if (!routeIsCurrent(config, model, routeDecision)
|
|
133
|
-
|| manualSelectionGeneration !== captureAnthropicManualSelectionGeneration()) continue;
|
|
134
|
-
if (!commitAnthropicSelectionRouting(candidate.accountId, selection, committed, {
|
|
171
|
+
if (!routeIsCurrent(instance, config, model, routeDecision)
|
|
172
|
+
|| manualSelectionGeneration !== routing.captureAnthropicManualSelectionGeneration()) continue;
|
|
173
|
+
if (!routing.commitAnthropicSelectionRouting(candidate.accountId, selection, committed, {
|
|
135
174
|
config, sessionKey, model, routeDecision,
|
|
136
175
|
reason: accountId === proposed.accountId ? proposed.reason : undefined,
|
|
137
176
|
expectedCredentialGeneration: candidate.generation,
|
|
138
177
|
})) continue;
|
|
139
|
-
const row = getAccountCredentialWithStatus(
|
|
140
|
-
if (!row || credentialGeneration(row.credential) !== candidate.generation) continue;
|
|
141
|
-
const binding = { selection: committed, snapshot: candidate, providerAccountUuid: row.credential.accountId, routeDecision, sessionKey, model, config, manualSelectionGeneration };
|
|
178
|
+
const row = getAccountCredentialWithStatus(instance, candidate.accountId);
|
|
179
|
+
if (!row || row.credential.access !== candidate.accessToken || credentialGeneration(row.credential) !== candidate.generation) continue;
|
|
180
|
+
const binding: NativeOAuthBinding = { instance, routeTarget, selection: committed, snapshot: candidate, providerAccountUuid: row.credential.accountId, routeDecision, sessionKey, model, config, manualSelectionGeneration };
|
|
142
181
|
if (nativeOAuthBindingIsCurrent(binding)) return binding;
|
|
143
182
|
}
|
|
144
183
|
}
|
|
@@ -150,12 +189,18 @@ export async function resolveNativeOAuthBinding(
|
|
|
150
189
|
* selection, plus the same usable credential generation. Checked before every physical send.
|
|
151
190
|
*/
|
|
152
191
|
export function nativeOAuthBindingIsCurrent(binding: NativeOAuthBinding): boolean {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
192
|
+
const { instance } = binding;
|
|
193
|
+
const routing = anthropicRoutingFor(instance);
|
|
194
|
+
try {
|
|
195
|
+
if (nativeOAuthRouteTarget(instance, binding.config) !== binding.routeTarget) return false;
|
|
196
|
+
} catch { return false; }
|
|
197
|
+
if (binding.snapshot.provider !== instance) return false;
|
|
198
|
+
if (binding.manualSelectionGeneration !== routing.captureAnthropicManualSelectionGeneration()
|
|
199
|
+
|| !routeIsCurrent(instance, binding.config, binding.model, binding.routeDecision)) return false;
|
|
200
|
+
const selected = captureOAuthAccountSelection(instance);
|
|
201
|
+
const row = getAccountCredentialWithStatus(instance, binding.snapshot.accountId);
|
|
202
|
+
const sessionRoute = routing.isAnthropicAccountPoolEnabled(binding.config) && binding.sessionKey
|
|
203
|
+
? routing.resolveAnthropicAccountForSession(binding.sessionKey, binding.config, Date.now(), binding.routeDecision, binding.model) : null;
|
|
159
204
|
// Another conversation may move the automatic active pointer without revoking this
|
|
160
205
|
// session's affinity. Manual selection clears affinity and precedes it in the selector.
|
|
161
206
|
const selectionCurrent = sessionRoute?.reason === "affinity"
|
|
@@ -163,8 +208,9 @@ export function nativeOAuthBindingIsCurrent(binding: NativeOAuthBinding): boolea
|
|
|
163
208
|
|| (selected?.accountId === binding.selection.accountId && selected?.revision === binding.selection.revision);
|
|
164
209
|
return selectionCurrent
|
|
165
210
|
&& !!row && !row.paused && !row.needsReauth && row.credential.expires > Date.now()
|
|
166
|
-
&& !getAnthropicAccountHealthSnapshot(binding.snapshot.accountId)
|
|
167
|
-
&& routeCandidates(getEligibleAnthropicAccounts(Date.now(), binding.model), binding.routeDecision).includes(binding.snapshot.accountId)
|
|
211
|
+
&& !routing.getAnthropicAccountHealthSnapshot(binding.snapshot.accountId)
|
|
212
|
+
&& routeCandidates(routing.getEligibleAnthropicAccounts(Date.now(), binding.model), binding.routeDecision).includes(binding.snapshot.accountId)
|
|
213
|
+
&& row.credential.access === binding.snapshot.accessToken
|
|
168
214
|
&& credentialGeneration(row.credential) === binding.snapshot.generation
|
|
169
215
|
&& row.credential.accountId === binding.providerAccountUuid;
|
|
170
216
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** Pure caller-forward exclusion shared by Messages ingress and protocol preview. */
|
|
2
|
+
import { resolveInboundModel } from "../claude/inbound-model-options";
|
|
3
|
+
import { routeConcreteModel } from "../router";
|
|
4
|
+
import { configuredAnthropicInstance } from "../providers/anthropic-instance";
|
|
5
|
+
import { hasOwnProvider } from "../config/provider-name";
|
|
6
|
+
import type { OcxConfig } from "../types";
|
|
7
|
+
|
|
8
|
+
export function messagesSelectorTargetsSecondaryInstance(
|
|
9
|
+
config: OcxConfig,
|
|
10
|
+
model: string,
|
|
11
|
+
cc: OcxConfig["claudeCode"] = config.claudeCode,
|
|
12
|
+
): boolean {
|
|
13
|
+
const selector = resolveInboundModel(model, cc);
|
|
14
|
+
const slash = selector.indexOf("/");
|
|
15
|
+
if (slash <= 0) return false;
|
|
16
|
+
const qualifier = selector.slice(0, slash);
|
|
17
|
+
// An orphan or unmarked B selector must also never forward a caller's credential.
|
|
18
|
+
if (qualifier === "anthropic2") return true;
|
|
19
|
+
// Provider keys are case-sensitive and outrank aliases, including when disabled.
|
|
20
|
+
if (hasOwnProvider(config.providers, qualifier)) return false;
|
|
21
|
+
try {
|
|
22
|
+
// Concrete resolution handles configured provider aliases without picking a combo/account.
|
|
23
|
+
return routeConcreteModel(config, selector).providerName === "anthropic2";
|
|
24
|
+
} catch {
|
|
25
|
+
return config.providers.anthropic2?.alias?.trim().toLowerCase() === qualifier.toLowerCase();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** A missing B row must not fall through the router's generic default-provider path. */
|
|
30
|
+
export function messagesSecondaryInstanceUnavailable(
|
|
31
|
+
config: OcxConfig,
|
|
32
|
+
model: string,
|
|
33
|
+
cc: OcxConfig["claudeCode"] = config.claudeCode,
|
|
34
|
+
): boolean {
|
|
35
|
+
if (!messagesSelectorTargetsSecondaryInstance(config, model, cc)) return false;
|
|
36
|
+
const provider = config.providers.anthropic2;
|
|
37
|
+
return !provider || provider.disabled === true
|
|
38
|
+
|| provider.authMode === "oauth" && configuredAnthropicInstance(config, "anthropic2") !== "anthropic2";
|
|
39
|
+
}
|