@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
package/src/types/config.ts
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import type { OcxProviderConfig } from "./provider";
|
|
2
2
|
import type { CodexAccount } from "./accounts";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
match: string;
|
|
7
|
-
accounts: string[];
|
|
8
|
-
fallback?: boolean;
|
|
9
|
-
}
|
|
3
|
+
import type { AnthropicAccountPoolConfig, OcxAccountPoolRotationStrategy } from "./anthropic-account-pool";
|
|
4
|
+
import type { AnthropicInstanceId } from "../providers/anthropic-instance-id";
|
|
5
|
+
export type { AnthropicAccountPoolConfig, AnthropicModelRoute, OcxAccountPoolRotationStrategy, OcxAccountPoolQuotaWindow } from "./anthropic-account-pool";
|
|
10
6
|
|
|
11
7
|
/** Public inference API exposure. Responses and Chat Completions are always served. */
|
|
12
8
|
export interface OcxApiSurfacesConfig {
|
|
@@ -178,6 +174,15 @@ export interface OcxClaudeCodeConfig {
|
|
|
178
174
|
autoContext?: boolean;
|
|
179
175
|
/** Compact-window tokens for auto-context. Default 829_800 (AUTO_COMPACT_WINDOW_DEFAULT). */
|
|
180
176
|
autoCompactWindow?: number;
|
|
177
|
+
/**
|
|
178
|
+
* Context accounting on Claude surfaces (devlog/_plan/261009_claude_1m_default/030). Absent
|
|
179
|
+
* (the default) = "1m": long-window models are offered at 1M wherever opencodex picks the
|
|
180
|
+
* default (launch env slots, Desktop pickers, Desktop 3P prefer1m, generated subagents).
|
|
181
|
+
* "200k" is the opt-in: nothing is marked [1m] automatically and no compact window is injected;
|
|
182
|
+
* a selector the user marks [1m] keeps it, and discovery and Desktop 3P keep offering 1M as a
|
|
183
|
+
* choice. The only stored value; "1m" deletes the key.
|
|
184
|
+
*/
|
|
185
|
+
contextAccounting?: "200k";
|
|
181
186
|
/**
|
|
182
187
|
* Local CONNECT proxy + TLS listener that intercepts Claude Code's own `api.anthropic.com`
|
|
183
188
|
* traffic without any `ANTHROPIC_BASE_URL` rewrite (src/claude/intercept). Claude Code reaches
|
|
@@ -222,9 +227,9 @@ export interface OcxClaudeCodeConfig {
|
|
|
222
227
|
/** Optional roster-style model forced on subagents at the next routed Claude Code launch. */
|
|
223
228
|
subagentModelForce?: string;
|
|
224
229
|
/** Claude-originated web-search override. Unset fields inherit the global sidecar settings. */
|
|
225
|
-
webSearchSidecar?: { backend?: "openai" | "anthropic" | "xai" | "gemini" | "exa"; model?: string };
|
|
230
|
+
webSearchSidecar?: { backend?: "openai" | "anthropic" | "xai" | "gemini" | "exa"; model?: string; anthropicInstance?: AnthropicInstanceId };
|
|
226
231
|
/** Claude-originated vision override. Unset fields inherit the global sidecar settings. */
|
|
227
|
-
visionSidecar?: { backend?: "openai" | "anthropic" | "routed"; model?: string };
|
|
232
|
+
visionSidecar?: { backend?: "openai" | "anthropic" | "routed"; model?: string; anthropicInstance?: AnthropicInstanceId };
|
|
228
233
|
/** Persisted Claude Desktop four-family routing profile. */
|
|
229
234
|
desktopProfile?: OcxClaudeDesktopProfile;
|
|
230
235
|
/**
|
|
@@ -1052,6 +1057,8 @@ export interface OcxConfig {
|
|
|
1052
1057
|
* upgrade against a number nobody chose.
|
|
1053
1058
|
*/
|
|
1054
1059
|
spend?: OcxSpendConfig;
|
|
1060
|
+
/** Historical salted pool aliases; h(pool,P) cannot map to Q != P for any configured provider P. */
|
|
1061
|
+
spendPoolAliases?: Record<string, string>;
|
|
1055
1062
|
/** Opt-in per-account activation of newly reset Codex quota windows. */
|
|
1056
1063
|
codexQuotaAutoRefresh?: Record<string, {
|
|
1057
1064
|
fiveHour?: boolean;
|
|
@@ -1176,6 +1183,18 @@ export interface OcxConfig {
|
|
|
1176
1183
|
accountPoolStickyLimit?: number;
|
|
1177
1184
|
/** Consecutive non-2xx upstream responses before switching future new threads. Default 3. 0 = disabled. */
|
|
1178
1185
|
upstreamFailoverThreshold?: number;
|
|
1186
|
+
/**
|
|
1187
|
+
* Sliding 60s transient-failure ratio for Codex pool placement. Default on.
|
|
1188
|
+
* Set false to steer new threads from the consecutive counter only.
|
|
1189
|
+
*/
|
|
1190
|
+
codexFailureWindow?: boolean;
|
|
1191
|
+
/**
|
|
1192
|
+
* What a manual pin does while its failure window is degraded.
|
|
1193
|
+
* `hold` keeps using it and logs a warning. `detour-new-threads` places only new threads elsewhere.
|
|
1194
|
+
*/
|
|
1195
|
+
codexPinnedTransientPolicy?: "hold" | "detour-new-threads";
|
|
1196
|
+
/** Opt-in: retain one Codex WebSocket per account and thread across turns. Default off. */
|
|
1197
|
+
codexWsReuseAcrossTurns?: boolean;
|
|
1179
1198
|
/**
|
|
1180
1199
|
* Opt-in provider-origin circuit threshold for proven pre-connection reachability failures.
|
|
1181
1200
|
* Default 0 (disabled); range 0..20. The circuit never counts timeouts or HTTP responses.
|
|
@@ -1216,21 +1235,7 @@ export interface OcxConfig {
|
|
|
1216
1235
|
* upstream has just rate-limited only ever runs after a refusal, so stranding it while a
|
|
1217
1236
|
* second logged-in account sits idle is a defect rather than a configuration choice.
|
|
1218
1237
|
*/
|
|
1219
|
-
anthropicAccountPool?:
|
|
1220
|
-
enabled?: boolean;
|
|
1221
|
-
/** Preserve native Claude Messages while the pool is enabled. Default true; false selects legacy translation. */
|
|
1222
|
-
nativeMessages?: boolean;
|
|
1223
|
-
/** Usage % threshold for new-session auto-pick. Default 80. 0 = disabled (affinity/active only). */
|
|
1224
|
-
autoSwitchThreshold?: number;
|
|
1225
|
-
/** New-session rotation strategy. Default quota (today's behaviour). */
|
|
1226
|
-
strategy?: OcxAccountPoolRotationStrategy;
|
|
1227
|
-
/** Successful new-session binds retained on one round-robin selection. Default 1; range 1..100. */
|
|
1228
|
-
stickyLimit?: number;
|
|
1229
|
-
/** Usage window for quota-based scoring. Default "five-hour" (today's behaviour). */
|
|
1230
|
-
quotaWindow?: OcxAccountPoolQuotaWindow;
|
|
1231
|
-
/** Ordered model allowlists; inactive while the pool is disabled. Stored account IDs only. */
|
|
1232
|
-
routes?: AnthropicModelRoute[];
|
|
1233
|
-
};
|
|
1238
|
+
anthropicAccountPool?: AnthropicAccountPoolConfig;
|
|
1234
1239
|
/**
|
|
1235
1240
|
* Generic OAuth multi-account PROACTIVE account preference (#2568, #695).
|
|
1236
1241
|
*
|
|
@@ -1262,10 +1267,6 @@ export interface OcxConfig {
|
|
|
1262
1267
|
corsAllowOrigins?: string[];
|
|
1263
1268
|
}
|
|
1264
1269
|
|
|
1265
|
-
export type OcxAccountPoolRotationStrategy = "quota" | "round-robin" | "fill-first";
|
|
1266
|
-
|
|
1267
|
-
export type OcxAccountPoolQuotaWindow = "five-hour" | "weekly" | "max-utilization";
|
|
1268
|
-
|
|
1269
1270
|
export type OcxComboStrategy = "failover" | "round-robin" | "random" | "least-used" | "reset-window" | "jev";
|
|
1270
1271
|
export type OcxComboDefaultEffort = "low" | "medium" | "high" | "xhigh" | "max" | "ultra";
|
|
1271
1272
|
export type OcxComboDefaultEffortMode = "fallback" | "force";
|
|
@@ -1526,6 +1527,8 @@ export interface OcxSearchConfig {
|
|
|
1526
1527
|
}
|
|
1527
1528
|
|
|
1528
1529
|
export interface OcxVisionSidecarConfig {
|
|
1530
|
+
/** Explicit Anthropic account pool; unset inherits the request's instance. */
|
|
1531
|
+
anthropicInstance?: AnthropicInstanceId;
|
|
1529
1532
|
/** Master switch. Default: enabled when the selected backend has a usable credential. */
|
|
1530
1533
|
enabled?: boolean;
|
|
1531
1534
|
/**
|
|
@@ -1545,6 +1548,8 @@ export interface OcxVisionSidecarConfig {
|
|
|
1545
1548
|
}
|
|
1546
1549
|
|
|
1547
1550
|
export interface OcxWebSearchSidecarConfig {
|
|
1551
|
+
/** Explicit Anthropic account pool; unset inherits the request's instance. */
|
|
1552
|
+
anthropicInstance?: AnthropicInstanceId;
|
|
1548
1553
|
/** Master switch. Default: enabled when a forward (ChatGPT) provider exists and the caller is logged in. */
|
|
1549
1554
|
enabled?: boolean;
|
|
1550
1555
|
/**
|
package/src/types/provider.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { UpstreamHttpVersion, ReasoningSummaryDelivery, CodexAccountMode } from "./wire";
|
|
2
|
+
import type { AnthropicAccountPoolConfig } from "./anthropic-account-pool";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Per-provider proactive-refresh policy. The guardian only ever touches a provider whose EFFECTIVE
|
|
@@ -274,6 +275,10 @@ export interface ModelCapabilities {
|
|
|
274
275
|
}
|
|
275
276
|
|
|
276
277
|
export interface OcxProviderConfig {
|
|
278
|
+
/** Explicit builtin Pool 2 provenance; endpoints never imply ownership. */
|
|
279
|
+
anthropicOAuthInstance?: "anthropic2";
|
|
280
|
+
/** Independent Anthropic pool settings; valid only on providers.anthropic2. */
|
|
281
|
+
anthropicAccountPool?: AnthropicAccountPoolConfig;
|
|
277
282
|
/** Optional browser-compatible outbound TLS profile; disabled by default. */
|
|
278
283
|
tlsProfile?: "antigravity-browser";
|
|
279
284
|
/** Optional short provider namespace used only at request/catalog presentation time. */
|
package/src/types/request.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { KiroOAuthMetadata } from "../oauth/types";
|
|
2
|
+
import type { NativeReasoningOwner } from "../responses/reasoning-replay-cache";
|
|
2
3
|
import type { OcxTool, OcxToolChoice } from "./tools";
|
|
3
4
|
import type { TierDecision, TierObservationContext } from "./provider";
|
|
4
5
|
|
|
@@ -57,6 +58,10 @@ export interface OcxParsedRequest {
|
|
|
57
58
|
stream: boolean;
|
|
58
59
|
options: OcxRequestOptions;
|
|
59
60
|
_rawBody?: unknown;
|
|
61
|
+
/** Claude replay tags, retained only until each route binding verifies them. */
|
|
62
|
+
_nativeReasoningReplay?: ReadonlyMap<string, string>;
|
|
63
|
+
_nativeReasoningBoundOwner?: NativeReasoningOwner;
|
|
64
|
+
_nativeReasoningMint?: { owner?: NativeReasoningOwner };
|
|
60
65
|
/**
|
|
61
66
|
* Boundary between replayed history and this turn's newly appended input. Usually the
|
|
62
67
|
* items the proxy restored from local previous_response_id state; also set when the
|
package/src/types/tools.ts
CHANGED
|
@@ -399,6 +399,13 @@ export function isAllowedToolChoice(value: OcxToolChoice | undefined): value is
|
|
|
399
399
|
return typeof value === "object" && value !== null && "allowedTools" in value;
|
|
400
400
|
}
|
|
401
401
|
|
|
402
|
+
export function requiresToolCall(choice: OcxToolChoice | undefined): boolean {
|
|
403
|
+
return choice === "required"
|
|
404
|
+
|| (typeof choice === "object" && choice !== null && (
|
|
405
|
+
"name" in choice || ("mode" in choice && choice.mode === "required")
|
|
406
|
+
));
|
|
407
|
+
}
|
|
408
|
+
|
|
402
409
|
/** Compile the request's tool-choice policy into a reusable advertisement/restoration predicate. */
|
|
403
410
|
export function toolChoiceToolPredicate(
|
|
404
411
|
choice: OcxToolChoice | undefined,
|
package/src/types/wire.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -16,6 +16,7 @@ export {
|
|
|
16
16
|
resolveToolChoiceWireName,
|
|
17
17
|
modelInList,
|
|
18
18
|
isAllowedToolChoice,
|
|
19
|
+
requiresToolCall,
|
|
19
20
|
toolChoiceToolPredicate,
|
|
20
21
|
declaresCodeModeExec,
|
|
21
22
|
toolRestrictsCallers,
|
|
@@ -23,6 +24,9 @@ export {
|
|
|
23
24
|
} from "./types/tools";
|
|
24
25
|
|
|
25
26
|
export type { UpstreamHttpVersion, ReasoningSummaryDelivery, CodexAccountMode } from "./types/wire";
|
|
27
|
+
export type { AnthropicInstanceId } from "./providers/anthropic-instance-id";
|
|
28
|
+
export { ANTHROPIC_INSTANCE_IDS, ANTHROPIC_PRIMARY_INSTANCE, ANTHROPIC_POOL2_INSTANCE, isAnthropicInstanceId } from "./providers/anthropic-instance-id";
|
|
29
|
+
export type { AnthropicAccountPoolConfig, AnthropicModelRoute } from "./types/anthropic-account-pool";
|
|
26
30
|
export {
|
|
27
31
|
UPSTREAM_HTTP_VERSION_VALUES,
|
|
28
32
|
REASONING_SUMMARY_DELIVERY_VALUES,
|
package/src/update/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { spawn, spawnSync } from "node:child_process";
|
|
2
|
+
import { createSupervisionLatch, inspectDesktopSupervision } from "../service/desktop-supervision.mjs";
|
|
2
3
|
import { manualUpdateFailureGuidance } from "./update-failure-guidance.mjs";
|
|
3
4
|
import { STOP_HISTORY_INCOMPLETE_EXIT_CODE } from "./stop-contract.mjs";
|
|
4
5
|
import { proxyIdentityAt } from "../server/proxy-liveness";
|
|
@@ -484,14 +485,17 @@ export async function runUpdate(): Promise<void> {
|
|
|
484
485
|
} catch { /* best-effort */ }
|
|
485
486
|
// What this update may do to the runtime. A desktop takeover vetoes both the stop and the
|
|
486
487
|
// service refresh below; see `planUpdateRuntimeHandling` for why each half is wrong.
|
|
488
|
+
const supervisionLatch = createSupervisionLatch();
|
|
489
|
+
const observeSupervision = () => supervisionLatch.observe(inspectDesktopSupervision());
|
|
487
490
|
const initialOwnership = await resolvedRuntimeOwnership();
|
|
488
491
|
const runtimePlan = planUpdateRuntimeHandling({
|
|
489
492
|
...initialOwnership,
|
|
490
493
|
serviceInstalled: serviceWasInstalled,
|
|
494
|
+
supervision: observeSupervision(),
|
|
491
495
|
});
|
|
492
496
|
if (runtimePlan.notice) console.log(runtimePlan.notice);
|
|
493
497
|
if (!runtimePlan.mayReplacePackage) {
|
|
494
|
-
console.error("⚠️ Update stopped before tray handoff, runtime stop, or package replacement because runtime
|
|
498
|
+
console.error("⚠️ Update stopped before tray handoff, runtime stop, or package replacement because runtime authority does not permit it.");
|
|
495
499
|
return 1;
|
|
496
500
|
}
|
|
497
501
|
let trayWasInstalled = false;
|
|
@@ -548,6 +552,15 @@ export async function runUpdate(): Promise<void> {
|
|
|
548
552
|
&& before?.consentGeneration === after?.consentGeneration;
|
|
549
553
|
};
|
|
550
554
|
const startProxyDirectly = async (): Promise<boolean> => {
|
|
555
|
+
const ownership = await resolvedRuntimeOwnership();
|
|
556
|
+
const supervision = observeSupervision();
|
|
557
|
+
const plan = planUpdateRuntimeHandling({ ...ownership, serviceInstalled: false, supervision });
|
|
558
|
+
if (!plan.mayStopRuntime) {
|
|
559
|
+
console.warn(supervision
|
|
560
|
+
? "OpenCodex Desktop supervises the proxy; no CLI runtime was restored."
|
|
561
|
+
: plan.notice);
|
|
562
|
+
return false;
|
|
563
|
+
}
|
|
551
564
|
if (!postUpdateLauncherUsable || !existsSync(postUpdateLauncher)) return false;
|
|
552
565
|
// An ordinary owner: a stray sibling marker would otherwise mark it before any probe.
|
|
553
566
|
const env = mutation.controlEnvironment(withoutSiblingMarker(process.env));
|
|
@@ -574,7 +587,7 @@ export async function runUpdate(): Promise<void> {
|
|
|
574
587
|
const planRecovery = async () => {
|
|
575
588
|
const current = await resolvedRuntimeOwnership();
|
|
576
589
|
return planStoppedRuntimeRecovery({
|
|
577
|
-
stopAttempted, ...current, sameOwner: sameOwner(current),
|
|
590
|
+
stopAttempted, ...current, sameOwner: sameOwner(current), supervision: observeSupervision(),
|
|
578
591
|
liveness: currentPackageRuntimeLiveness(), serviceInstalled: serviceWasInstalled,
|
|
579
592
|
launcherUsable: postUpdateLauncherUsable && existsSync(postUpdateLauncher), hadRuntimeState,
|
|
580
593
|
});
|
|
@@ -588,10 +601,17 @@ export async function runUpdate(): Promise<void> {
|
|
|
588
601
|
mutation.release();
|
|
589
602
|
recovery = await planRecovery();
|
|
590
603
|
}
|
|
591
|
-
if (recovery.
|
|
604
|
+
if (recovery.reason === "desktop-supervised") {
|
|
605
|
+
console.log("OpenCodex Desktop supervises the proxy; no CLI runtime was restored.");
|
|
606
|
+
} else if (recovery.action === "manual") {
|
|
592
607
|
console.warn(`⚠️ ${reason}; runtime recovery requires manual review (${recovery.reason}).`);
|
|
593
608
|
} else if (recovery.action === "service") {
|
|
594
609
|
const { serviceReinstallArgs, isServiceViable } = await import("../service");
|
|
610
|
+
recovery = await planRecovery();
|
|
611
|
+
if (recovery.action !== "service") {
|
|
612
|
+
console.warn("Runtime authority changed before service recovery; no CLI runtime was restored.");
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
595
615
|
const service = spawnSync(process.execPath, [postUpdateLauncher, ...serviceReinstallArgs()], {
|
|
596
616
|
stdio: updateChildStdio(), windowsHide: true,
|
|
597
617
|
env: mutation.controlEnvironment({ ...process.env, OCX_BAKE_PORT: String(capturedListen.port) }),
|
|
@@ -602,7 +622,7 @@ export async function runUpdate(): Promise<void> {
|
|
|
602
622
|
mutation.reacquire();
|
|
603
623
|
const nowOwned = await resolvedRuntimeOwnership();
|
|
604
624
|
const fallback = planStoppedRuntimeRecovery({
|
|
605
|
-
stopAttempted, ...nowOwned, sameOwner: sameOwner(nowOwned),
|
|
625
|
+
stopAttempted, ...nowOwned, sameOwner: sameOwner(nowOwned), supervision: observeSupervision(),
|
|
606
626
|
liveness: currentPackageRuntimeLiveness(), serviceInstalled: false,
|
|
607
627
|
launcherUsable: postUpdateLauncherUsable && existsSync(postUpdateLauncher), hadRuntimeState,
|
|
608
628
|
});
|
|
@@ -632,6 +652,15 @@ export async function runUpdate(): Promise<void> {
|
|
|
632
652
|
// Full `ocx stop` semantics (drain, service stop, restore).
|
|
633
653
|
|
|
634
654
|
if (runtimePlan.mayStopRuntime && (serviceWasInstalled || readPid() || readRuntimePort() || pendingTeardownOutstanding())) {
|
|
655
|
+
const preStopPlan = planUpdateRuntimeHandling({
|
|
656
|
+
...(await resolvedRuntimeOwnership()),
|
|
657
|
+
serviceInstalled: serviceWasInstalled,
|
|
658
|
+
supervision: supervisionLatch.observe(inspectDesktopSupervision({ targetPid: runtimeTrusted ? livePid : undefined })),
|
|
659
|
+
});
|
|
660
|
+
if (!preStopPlan.mayStopRuntime) {
|
|
661
|
+
console.error(preStopPlan.notice);
|
|
662
|
+
return 1;
|
|
663
|
+
}
|
|
635
664
|
stopAttempted = true;
|
|
636
665
|
console.log("⏹ Stopping the running proxy before updating...");
|
|
637
666
|
const stopStdio = updateChildStdio();
|
|
@@ -701,13 +730,14 @@ export async function runUpdate(): Promise<void> {
|
|
|
701
730
|
stderr?: string | Buffer | null;
|
|
702
731
|
} | null = null;
|
|
703
732
|
let replacementRefusal: string | null = null;
|
|
704
|
-
//
|
|
705
|
-
//
|
|
706
|
-
//
|
|
733
|
+
// Re-read durable ownership and live supervision before package replacement.
|
|
734
|
+
// Desktop supervision and foreign/unknown ownership veto replacement.
|
|
735
|
+
// Plain unknown supervision preserves the existing ownership/liveness decision.
|
|
707
736
|
const replacementOwnership = await resolvedRuntimeOwnership();
|
|
708
737
|
const replacementPlan = planUpdateRuntimeHandling({
|
|
709
738
|
...replacementOwnership,
|
|
710
739
|
serviceInstalled: serviceWasInstalled,
|
|
740
|
+
supervision: observeSupervision(),
|
|
711
741
|
});
|
|
712
742
|
const replacementLiveness = currentPackageRuntimeLiveness();
|
|
713
743
|
if (replacementOwnership.subjectToken !== initialOwnership.subjectToken
|
|
@@ -786,9 +816,11 @@ export async function runUpdate(): Promise<void> {
|
|
|
786
816
|
const postInstallPlan = planUpdateRuntimeHandling({
|
|
787
817
|
...(await resolvedRuntimeOwnership()),
|
|
788
818
|
serviceInstalled: serviceWasInstalled,
|
|
819
|
+
supervision: observeSupervision(),
|
|
789
820
|
});
|
|
790
821
|
if (r.status === 0) {
|
|
791
822
|
console.log(`\n✅ Updated${latest ? ` to v${latest}` : ""}.`);
|
|
823
|
+
if (!postInstallPlan.mayStopRuntime) console.warn("Runtime authority does not permit CLI recovery; no service was refreshed or proxy started.");
|
|
792
824
|
// Re-enter through the verified active package launcher. This keeps the Codex
|
|
793
825
|
// shim, tray, service and proxy recovery paths on the same package/group that
|
|
794
826
|
// pnpm selected, including when the update changed the global link target.
|
|
@@ -819,6 +851,16 @@ export async function runUpdate(): Promise<void> {
|
|
|
819
851
|
// (spawn the fresh cli.ts so updated code writes the baked paths) so a
|
|
820
852
|
// launchd/schtasks/systemd user isn't left with the background proxy down.
|
|
821
853
|
if (postInstallPlan.mayRestoreService) {
|
|
854
|
+
const mayRefresh = async () => {
|
|
855
|
+
const ownership = await resolvedRuntimeOwnership();
|
|
856
|
+
const supervision = observeSupervision();
|
|
857
|
+
const plan = planUpdateRuntimeHandling({ ...ownership, serviceInstalled: true, supervision });
|
|
858
|
+
if (!plan.mayRestoreService) console.warn(supervision
|
|
859
|
+
? "OpenCodex Desktop supervises the proxy; CLI recovery was skipped. Use the app's updater (tray → Check for Updates)."
|
|
860
|
+
: plan.notice);
|
|
861
|
+
return plan.mayRestoreService;
|
|
862
|
+
};
|
|
863
|
+
if (!await mayRefresh()) return;
|
|
822
864
|
console.log("🔁 Refreshing the background service with the updated files...");
|
|
823
865
|
const { serviceReinstallArgs } = await import("../service");
|
|
824
866
|
const { reclaimListenPort } = await import("../server/port-reclaim");
|
|
@@ -840,6 +882,7 @@ export async function runUpdate(): Promise<void> {
|
|
|
840
882
|
const prevBake = process.env.OCX_BAKE_PORT;
|
|
841
883
|
process.env.OCX_BAKE_PORT = String(capturedListen.port);
|
|
842
884
|
try {
|
|
885
|
+
if (!await mayRefresh()) return;
|
|
843
886
|
const svcStdio = updateChildStdio();
|
|
844
887
|
const svc = spawnSync(process.execPath, [postUpdateLauncher, ...serviceReinstallArgs()], {
|
|
845
888
|
env: mutation.controlEnvironment(),
|
|
@@ -889,12 +932,17 @@ export async function runUpdate(): Promise<void> {
|
|
|
889
932
|
console.warn(` Run 'ocx service repair', then 'ocx start --port ${capturedListen.port}'.`);
|
|
890
933
|
return 1;
|
|
891
934
|
}
|
|
935
|
+
const fallbackOwnership = await resolvedRuntimeOwnership();
|
|
936
|
+
const supervision = observeSupervision();
|
|
892
937
|
const nowOwned = planUpdateRuntimeHandling({
|
|
893
|
-
...
|
|
938
|
+
...fallbackOwnership,
|
|
894
939
|
serviceInstalled: true,
|
|
940
|
+
supervision,
|
|
895
941
|
});
|
|
896
942
|
if (!nowOwned.mayStopRuntime) {
|
|
897
|
-
console.warn(
|
|
943
|
+
console.warn(supervision
|
|
944
|
+
? "OpenCodex Desktop supervises the proxy; CLI recovery was skipped. Use the app's updater (tray → Check for Updates)."
|
|
945
|
+
: nowOwned.notice ?? "⚠️ The background runtime is owned elsewhere; not starting a second proxy.");
|
|
898
946
|
return;
|
|
899
947
|
}
|
|
900
948
|
console.warn(
|
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
OWNERSHIP_MUTATION_LEASE_TOKEN_ENV,
|
|
7
7
|
} from "../service/ownership-mutation-lease.mjs";
|
|
8
8
|
import { planUpdateRuntimeHandling } from "./runtime-ownership.mjs";
|
|
9
|
+
import { createSupervisionLatch, inspectDesktopSupervision } from "../service/desktop-supervision.mjs";
|
|
10
|
+
type SupervisionInspector = typeof inspectDesktopSupervision;
|
|
9
11
|
|
|
10
12
|
export type { ServiceOwnershipResolution };
|
|
11
13
|
|
|
@@ -24,6 +26,8 @@ export type { ServiceOwnershipResolution };
|
|
|
24
26
|
*/
|
|
25
27
|
export function updateRestartVeto(
|
|
26
28
|
resolve: () => ServiceOwnershipResolution = resolveServiceOwnership,
|
|
29
|
+
inspect: SupervisionInspector = inspectDesktopSupervision,
|
|
30
|
+
latch = createSupervisionLatch(),
|
|
27
31
|
): string | null {
|
|
28
32
|
const owner = resolve();
|
|
29
33
|
const plan = planUpdateRuntimeHandling({
|
|
@@ -31,6 +35,7 @@ export function updateRestartVeto(
|
|
|
31
35
|
ownershipUnknown: owner.kind === "unknown",
|
|
32
36
|
// The restart decision does not refresh the service; only the stop veto is read here.
|
|
33
37
|
serviceInstalled: false,
|
|
38
|
+
supervision: latch.observe(inspect()),
|
|
34
39
|
});
|
|
35
40
|
if (plan.mayStopRuntime) return null;
|
|
36
41
|
return plan.notice ?? "The background runtime is owned elsewhere; it was left running.";
|
|
@@ -78,7 +83,9 @@ const REACQUIRE_WAIT_MS = 10_000;
|
|
|
78
83
|
export async function runUpdateRestartWithOwnershipLease<T>(
|
|
79
84
|
resolve: (() => ServiceOwnershipResolution) | undefined,
|
|
80
85
|
restart: (lease: UpdateRestartLeaseControl) => Promise<T>,
|
|
86
|
+
inspect: SupervisionInspector = inspectDesktopSupervision,
|
|
81
87
|
): Promise<{ readonly kind: "veto"; readonly notice: string } | { readonly kind: "ran"; readonly value: T }> {
|
|
88
|
+
const latch = createSupervisionLatch();
|
|
82
89
|
let lease = acquireOwnershipMutationLease(serviceStatePaths());
|
|
83
90
|
const previous = process.env[OWNERSHIP_MUTATION_LEASE_TOKEN_ENV];
|
|
84
91
|
process.env[OWNERSHIP_MUTATION_LEASE_TOKEN_ENV] = lease.token;
|
|
@@ -107,11 +114,11 @@ export async function runUpdateRestartWithOwnershipLease<T>(
|
|
|
107
114
|
heldNow = true;
|
|
108
115
|
process.env[OWNERSHIP_MUTATION_LEASE_TOKEN_ENV] = lease.token;
|
|
109
116
|
}
|
|
110
|
-
const veto = updateRestartVeto(resolve);
|
|
117
|
+
const veto = updateRestartVeto(resolve, inspect, latch);
|
|
111
118
|
return veto ? { notice: veto, failed: false } : null;
|
|
112
119
|
};
|
|
113
120
|
try {
|
|
114
|
-
const veto = updateRestartVeto(resolve);
|
|
121
|
+
const veto = updateRestartVeto(resolve, inspect, latch);
|
|
115
122
|
return veto
|
|
116
123
|
? { kind: "veto", notice: veto }
|
|
117
124
|
: {
|
|
@@ -119,7 +126,7 @@ export async function runUpdateRestartWithOwnershipLease<T>(
|
|
|
119
126
|
value: await restart({
|
|
120
127
|
releaseForServiceManager: release,
|
|
121
128
|
reacquireForDirectStart,
|
|
122
|
-
vetoAgain: () => updateRestartVeto(resolve),
|
|
129
|
+
vetoAgain: () => updateRestartVeto(resolve, inspect, latch),
|
|
123
130
|
}),
|
|
124
131
|
};
|
|
125
132
|
} finally {
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import type { SupervisionEvidence } from "../service/desktop-supervision.mjs";
|
|
2
|
+
|
|
1
3
|
export declare function planUpdateRuntimeHandling(input: {
|
|
2
4
|
ownership: { owner: string; installId: string; consentGeneration: number } | null;
|
|
3
5
|
ownershipUnknown?: boolean;
|
|
6
|
+
/** Fresh evidence or the operation's supervision latch verdict. */
|
|
7
|
+
supervision?: SupervisionEvidence | boolean;
|
|
4
8
|
serviceInstalled: boolean;
|
|
5
9
|
}): {
|
|
6
10
|
mayReplacePackage: boolean;
|
|
@@ -13,6 +17,8 @@ export declare function planStoppedRuntimeRecovery(input: {
|
|
|
13
17
|
stopAttempted: boolean;
|
|
14
18
|
ownership: { owner: string; installId: string; consentGeneration: number } | null;
|
|
15
19
|
ownershipUnknown?: boolean;
|
|
20
|
+
/** Fresh evidence or the operation's supervision latch verdict. */
|
|
21
|
+
supervision?: SupervisionEvidence | boolean;
|
|
16
22
|
sameOwner: boolean;
|
|
17
23
|
liveness: "live" | "dead" | "unknown";
|
|
18
24
|
serviceInstalled: boolean;
|
|
@@ -7,6 +7,11 @@
|
|
|
7
7
|
* situation separately is how a fix ships on one side only.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
function desktopSupervisionBlocked(supervision) {
|
|
11
|
+
return supervision === true || supervision?.kind === "desktop"
|
|
12
|
+
|| (supervision?.kind === "unknown" && supervision.desktopSeen);
|
|
13
|
+
}
|
|
14
|
+
|
|
10
15
|
/**
|
|
11
16
|
* Decide how an update treats a runtime it may not own.
|
|
12
17
|
*
|
|
@@ -21,11 +26,11 @@
|
|
|
21
26
|
* The service registration itself is untouched in every case. It is kept by decision, not by
|
|
22
27
|
* accident, so a user who later runs `ocx service install` gets their npm service back.
|
|
23
28
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
+
* Durable ownership and live supervision are separate. Desktop supervision denies package
|
|
30
|
+
* replacement, stop and restoration even without a claim. A latch retains that veto through
|
|
31
|
+
* inconclusive probes until a positive none. Plain unknown supervision alone keeps existing
|
|
32
|
+
* behavior; unknown durable ownership still vetoes. Explicit service install recovers a stale
|
|
33
|
+
* durable claim after Desktop has quit.
|
|
29
34
|
*
|
|
30
35
|
* The three returned flags are separate authorities, not commands. In particular, leaving
|
|
31
36
|
* a runtime running is not permission to replace the package it may be executing from.
|
|
@@ -34,10 +39,19 @@
|
|
|
34
39
|
* carries installation identity, it therefore blocks package replacement as well as stop and
|
|
35
40
|
* restoration; the notice tells a stale-marker user how to take ownership back explicitly.
|
|
36
41
|
*
|
|
37
|
-
* @param {{ ownership: { owner: string, installId: string, consentGeneration: number } | null, ownershipUnknown?: boolean, serviceInstalled: boolean }} input
|
|
42
|
+
* @param {{ ownership: { owner: string, installId: string, consentGeneration: number } | null, ownershipUnknown?: boolean, serviceInstalled: boolean, supervision?: boolean | ReturnType<typeof import('../service/desktop-supervision.mjs').inspectDesktopSupervision> }} input
|
|
38
43
|
* @returns {{ mayReplacePackage: boolean, mayStopRuntime: boolean, mayRestoreService: boolean, notice: string | null }}
|
|
39
44
|
*/
|
|
40
|
-
export function planUpdateRuntimeHandling({ ownership, ownershipUnknown = false, serviceInstalled }) {
|
|
45
|
+
export function planUpdateRuntimeHandling({ ownership, ownershipUnknown = false, serviceInstalled, supervision }) {
|
|
46
|
+
if (desktopSupervisionBlocked(supervision)) {
|
|
47
|
+
return {
|
|
48
|
+
mayReplacePackage: false,
|
|
49
|
+
mayStopRuntime: false,
|
|
50
|
+
mayRestoreService: false,
|
|
51
|
+
notice: "OpenCodex Desktop runs this proxy from its own bundle; use the app's updater (tray → Check for Updates). "
|
|
52
|
+
+ "This npm/Bun install was left unchanged; quit OpenCodex first to update it.",
|
|
53
|
+
};
|
|
54
|
+
}
|
|
41
55
|
// Unreadable, malformed or contradictory is not "nobody owns it". Reading it that way is
|
|
42
56
|
// how a permissions error reactivates the npm launcher over a consented takeover.
|
|
43
57
|
if (ownershipUnknown) {
|
|
@@ -77,6 +91,7 @@ export function planUpdateRuntimeHandling({ ownership, ownershipUnknown = false,
|
|
|
77
91
|
/** Decide recovery after this updater already stopped the prior CLI-owned runtime. */
|
|
78
92
|
export function planStoppedRuntimeRecovery({
|
|
79
93
|
stopAttempted,
|
|
94
|
+
supervision,
|
|
80
95
|
ownership,
|
|
81
96
|
ownershipUnknown = false,
|
|
82
97
|
sameOwner,
|
|
@@ -86,6 +101,7 @@ export function planStoppedRuntimeRecovery({
|
|
|
86
101
|
hadRuntimeState,
|
|
87
102
|
}) {
|
|
88
103
|
if (!stopAttempted) return { action: "none", reason: "not-stopped" };
|
|
104
|
+
if (desktopSupervisionBlocked(supervision)) return { action: "none", reason: "desktop-supervised" };
|
|
89
105
|
if (ownershipUnknown) return { action: "manual", reason: "ownership-unknown" };
|
|
90
106
|
if (!sameOwner || (ownership && ownership.owner !== "cli")) {
|
|
91
107
|
return { action: "none", reason: "ownership-transferred" };
|
package/src/usage/cost.ts
CHANGED
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
cursorFastPriceSupported,
|
|
31
31
|
findContextTier,
|
|
32
32
|
isLongContext,
|
|
33
|
+
pricingFamilyProvider,
|
|
33
34
|
type Cost4,
|
|
34
35
|
type ExpectedPriceOverlay,
|
|
35
36
|
type ExpectedPriceStatus,
|
|
@@ -262,7 +263,7 @@ function resolveMatchedPriceExact(
|
|
|
262
263
|
if (userOverlay) return userOverlay;
|
|
263
264
|
if (!cursorFastPriceSupported(provider, modelId)) return null;
|
|
264
265
|
const verifiedOverride = overlays === EXPECTED_PRICE_OVERLAYS
|
|
265
|
-
? findVerifiedPriceOverride(provider, modelId)
|
|
266
|
+
? findVerifiedPriceOverride(pricingFamilyProvider(provider), modelId)
|
|
266
267
|
: undefined;
|
|
267
268
|
if (verifiedOverride && verifiedOverride.status !== "unverified" && validCost4(verifiedOverride.cost4) && hasNonZeroCost(verifiedOverride.cost4)) {
|
|
268
269
|
return {
|
|
@@ -291,7 +292,7 @@ function resolveMatchedPriceExact(
|
|
|
291
292
|
...cursorFastPriceProvenance(provider, modelId),
|
|
292
293
|
};
|
|
293
294
|
}
|
|
294
|
-
const overlay = findExpectedPriceOverlay(provider, modelId, overlays);
|
|
295
|
+
const overlay = findExpectedPriceOverlay(overlays === EXPECTED_PRICE_OVERLAYS ? pricingFamilyProvider(provider) : provider, modelId, overlays);
|
|
295
296
|
if (!overlay || !validCost4(overlay.cost4) || !hasNonZeroCost(overlay.cost4)) {
|
|
296
297
|
if (options.allowModelLevelFallback === false) return null;
|
|
297
298
|
const fallback = resolveModelLevelPrice(provider, modelId);
|