@iislee/opencodex 2.31.0 → 2.35.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 +99 -70
- package/gui/dist/assets/index-Be1sDpWw.css +1 -0
- package/gui/dist/assets/index-D4OKgUV4.js +114 -0
- package/gui/dist/index.html +2 -2
- package/package.json +3 -1
- package/src/adapters/anthropic.ts +104 -15
- package/src/adapters/base.ts +29 -1
- package/src/adapters/command-code.ts +42 -6
- package/src/adapters/cursor/call-id.ts +44 -0
- package/src/adapters/cursor/catalog.ts +541 -0
- package/src/adapters/cursor/checkpoint-store.ts +15 -10
- package/src/adapters/cursor/cursor-errors.ts +15 -0
- package/src/adapters/cursor/discovery.ts +69 -18
- package/src/adapters/cursor/effort-map.ts +79 -1
- package/src/adapters/cursor/envelope-echo.ts +290 -0
- package/src/adapters/cursor/live-models.ts +7 -2
- package/src/adapters/cursor/live-transport.ts +14 -0
- package/src/adapters/cursor/message-mapper.ts +4 -1
- package/src/adapters/cursor/native-exec-desktop.ts +23 -0
- package/src/adapters/cursor/native-exec-fs.ts +2 -2
- package/src/adapters/cursor/native-exec-network.ts +1 -1
- package/src/adapters/cursor/native-exec-shell.ts +5 -2
- package/src/adapters/cursor/native-exec.ts +20 -0
- package/src/adapters/cursor/protobuf-request.ts +68 -14
- package/src/adapters/cursor/request-builder.ts +40 -10
- package/src/adapters/cursor/tool-definitions.ts +14 -4
- package/src/adapters/cursor/tool-result-normalize.ts +28 -5
- package/src/adapters/cursor/types.ts +20 -0
- package/src/adapters/cursor.ts +209 -38
- package/src/adapters/exec-tool-result-normalize.ts +99 -0
- package/src/adapters/google-antigravity-replay.ts +173 -25
- package/src/adapters/google-antigravity-wire.ts +5 -0
- package/src/adapters/google-errors.ts +44 -12
- package/src/adapters/google.ts +136 -24
- package/src/adapters/image.ts +1 -1
- package/src/adapters/kiro-constants.ts +27 -0
- package/src/adapters/kiro-tools.ts +55 -16
- package/src/adapters/kiro.ts +182 -23
- package/src/adapters/openai-chat.ts +300 -242
- package/src/adapters/openai-responses.ts +353 -27
- package/src/adapters/run-turn-queue.ts +36 -1
- package/src/adapters/tool-catalog-nudge.ts +4 -3
- package/src/adapters/xai-tool-schema.ts +436 -0
- package/src/adapters/xai-web-search.ts +17 -16
- package/src/bridge.ts +90 -37
- package/src/chat/inbound.ts +14 -1
- package/src/chat/outbound.ts +15 -7
- package/src/claude/agents-inject.ts +8 -1
- package/src/claude/context-windows.ts +16 -9
- package/src/claude/outbound.ts +24 -11
- package/src/cli/access.ts +46 -3
- package/src/cli/account-api.ts +116 -19
- package/src/cli/account-extended.ts +262 -29
- package/src/cli/account-main.ts +12 -12
- package/src/cli/account.ts +69 -15
- package/src/cli/agent.ts +8 -1
- package/src/cli/alias.ts +66 -0
- package/src/cli/capabilities-command.ts +94 -0
- package/src/cli/capabilities.ts +496 -0
- package/src/cli/claude-desktop.ts +31 -11
- package/src/cli/claude.ts +26 -1
- package/src/cli/dispatch.ts +256 -28
- package/src/cli/doctor.ts +126 -14
- package/src/cli/help.ts +17 -6
- package/src/cli/index.ts +39 -9
- package/src/cli/init.ts +1 -0
- package/src/cli/inspect.ts +230 -0
- package/src/cli/models-runtime.ts +95 -0
- package/src/cli/models.ts +26 -10
- package/src/cli/observe.ts +31 -8
- package/src/cli/provider-runtime.ts +16 -2
- package/src/cli/provider.ts +2 -1
- package/src/cli/registry.ts +49 -10
- package/src/cli/runtime-api.ts +51 -7
- package/src/cli/status.ts +41 -1
- package/src/cli/storage.ts +234 -0
- package/src/cli/system-command.ts +16 -0
- package/src/cli/system-restart-client.ts +1 -1
- package/src/cli/usage-report.ts +184 -0
- package/src/cli/v2.ts +34 -10
- package/src/cli/version-skew.ts +46 -0
- package/src/clients/config-export.ts +85 -3
- package/src/clients/effective-status.ts +30 -2
- package/src/clients/probes/cline.ts +81 -0
- package/src/codex/account-label.ts +21 -0
- package/src/codex/account-pause.ts +2 -1
- package/src/codex/account-priority.ts +3 -2
- package/src/codex/app-server-processes.ts +83 -7
- package/src/codex/auth-api.ts +50 -10
- package/src/codex/auth-context.ts +21 -18
- package/src/codex/autostart-health.ts +16 -0
- package/src/codex/catalog/aggregation.ts +18 -0
- package/src/codex/catalog/effort.ts +18 -3
- package/src/codex/catalog/metadata.ts +27 -1
- package/src/codex/catalog/native-models.ts +5 -2
- package/src/codex/catalog/parsing.ts +72 -27
- package/src/codex/catalog/provider-fetch.ts +187 -31
- package/src/codex/catalog/sync.ts +131 -5
- package/src/codex/catalog.ts +1 -1
- package/src/codex/codex-write-lock.ts +3 -1
- package/src/codex/convergence-types.ts +1 -1
- package/src/codex/convergence.ts +27 -2
- package/src/codex/desired-state.ts +2 -2
- package/src/codex/desktop-app-restart.ts +355 -0
- package/src/codex/history-job.ts +32 -3
- package/src/codex/history-manifest.ts +112 -0
- package/src/codex/history-migration-guardian.ts +5 -5
- package/src/codex/history-provider.ts +825 -247
- package/src/codex/history-worker.ts +8 -5
- package/src/codex/inject-coordination.ts +83 -0
- package/src/codex/inject.ts +63 -22
- package/src/codex/injected-marker.ts +1 -1
- package/src/codex/internal/history-writer.ts +4 -3
- package/src/codex/log-guard/inspect.ts +22 -4
- package/src/codex/model-entitlements.ts +9 -2
- package/src/codex/native-profile-startup.ts +157 -27
- package/src/codex/native-residue.ts +26 -33
- package/src/codex/prompt-layers.ts +371 -25
- package/src/codex/prompt-text-probe.ts +238 -0
- package/src/codex/quota.ts +91 -10
- package/src/codex/routing.ts +9 -0
- package/src/codex/shim.ts +56 -3
- package/src/codex/subagent-model-fallback.ts +104 -25
- package/src/codex/transition-state.ts +116 -8
- package/src/combos/failover.ts +27 -0
- package/src/combos/types.ts +10 -0
- package/src/compatibility/index.ts +26 -0
- package/src/compatibility/manifest.ts +253 -0
- package/src/compatibility/openai-responses.ts +121 -0
- package/src/config/atomic-write.ts +219 -0
- package/src/config/paths.ts +40 -0
- package/src/config/process-state.ts +309 -0
- package/src/config/provider-validation.ts +177 -0
- package/src/config/rebase-provenance.ts +68 -0
- package/src/config.ts +206 -824
- package/src/generated/compatibility-version.json +373 -213
- package/src/images/loop.ts +5 -4
- package/src/images/plan.ts +5 -4
- package/src/integrations/ownership-policy.ts +160 -0
- package/src/integrations/ownership.ts +46 -2
- package/src/integrations/registry.ts +7 -0
- package/src/integrations/state.ts +79 -7
- package/src/integrations/writer.ts +26 -2
- package/src/lab/conformance/fixtures/protocol-v1-cases.json +1 -1
- package/src/lab/fabric/producer-child.ts +1 -1
- package/src/lib/admin-secrets.ts +24 -0
- package/src/lib/bounded-body.ts +14 -2
- package/src/lib/config-ownership.ts +20 -0
- package/src/lib/errors.ts +36 -3
- package/src/lib/package-tree-integrity.ts +101 -0
- package/src/lib/process-control.ts +2 -1
- package/src/lib/service-secrets.ts +15 -0
- package/src/lib/tool-argument-integers.ts +56 -5
- package/src/oauth/callback-server.ts +22 -2
- package/src/oauth/cline.ts +203 -0
- package/src/oauth/generic-account-failover.ts +231 -0
- package/src/oauth/health.ts +1 -1
- package/src/oauth/index.ts +65 -6
- package/src/oauth/key-providers.ts +10 -1
- package/src/oauth/kimi.ts +9 -1
- package/src/oauth/kiro.ts +45 -0
- package/src/oauth/local-token-detect.ts +2 -0
- package/src/oauth/open-browser-choice.ts +26 -0
- package/src/oauth/store.ts +14 -5
- package/src/oauth/types.ts +15 -0
- package/src/providers/auto-compact-budget.ts +65 -0
- package/src/providers/command-code-efforts.ts +38 -6
- package/src/providers/context-cap.ts +4 -3
- package/src/providers/default-aliases.ts +65 -0
- package/src/providers/derive.ts +28 -0
- package/src/providers/fastwire.ts +7 -1
- package/src/providers/label.ts +34 -1
- package/src/providers/model-presets.ts +119 -0
- package/src/providers/new-model-policy.ts +146 -0
- package/src/providers/provider-id-rewrite.ts +2 -1
- package/src/providers/quota.ts +65 -7
- package/src/providers/registry.ts +184 -69
- package/src/providers/slug-codec.ts +52 -0
- package/src/providers/xai-transport.ts +21 -0
- package/src/reasoning-effort.ts +19 -2
- package/src/responses/apply-patch-envelope.ts +63 -0
- package/src/responses/code-mode-helper-compat.ts +50 -0
- package/src/responses/custom-tool-compat.ts +157 -39
- package/src/responses/namespace-tool-compat.ts +84 -4
- package/src/responses/parser.ts +7 -2
- package/src/responses/reasoning-replay-cache.ts +81 -3
- package/src/responses/schema.ts +5 -1
- package/src/responses/state.ts +94 -4
- package/src/responses/thought-signature-replay.ts +17 -0
- package/src/responses/turn-termination.ts +107 -0
- package/src/router.ts +40 -2
- package/src/routing/analytics.ts +1 -0
- package/src/routing/quota.ts +10 -0
- package/src/server/auth-cors.ts +27 -7
- package/src/server/chat-completions.ts +24 -16
- package/src/server/chat-native-sse.ts +3 -3
- package/src/server/chat-native.ts +30 -11
- package/src/server/claude-messages.ts +1 -1
- package/src/server/index.ts +179 -32
- package/src/server/lifecycle.ts +52 -1
- package/src/server/local-management-read-client.ts +1 -1
- package/src/server/local-provider-reload-client.ts +1 -1
- package/src/server/management/agent-settings-routes.ts +45 -23
- package/src/server/management/codex-prompt-routes.ts +570 -0
- package/src/server/management/combo-routes.ts +2 -1
- package/src/server/management/config-routes.ts +59 -12
- package/src/server/management/context.ts +10 -1
- package/src/server/management/logs-usage-routes.ts +30 -24
- package/src/server/management/model-routes.ts +274 -4
- package/src/server/management/model-rows.ts +4 -0
- package/src/server/management/native-integration-routes.ts +2 -1
- package/src/server/management/oauth-account-routes.ts +10 -4
- package/src/server/management/provider-capability-config.ts +1 -1
- package/src/server/management/provider-routes.ts +81 -11
- package/src/server/management/route-registry.ts +332 -0
- package/src/server/management/routing-profile-routes.ts +2 -2
- package/src/server/management/system-restart.ts +1 -1
- package/src/server/management-api.ts +18 -16
- package/src/server/port-reclaim.ts +1 -1
- package/src/server/proxy-liveness.ts +29 -5
- package/src/server/relay-eager.ts +147 -20
- package/src/server/relay.ts +251 -19
- package/src/server/request-log-conversation.ts +51 -0
- package/src/server/request-log.ts +70 -16
- package/src/server/responses/codex-auth-error.ts +55 -0
- package/src/server/responses/collaboration.ts +37 -3
- package/src/server/responses/combo-stream-preflight.ts +178 -0
- package/src/server/responses/compact.ts +6 -21
- package/src/server/responses/core.ts +810 -208
- package/src/server/responses/empty-completion-guard.ts +63 -6
- package/src/server/responses/fetch-helpers.ts +17 -102
- package/src/server/responses/input-admission.ts +3 -1
- package/src/server/responses/passthrough-error.ts +33 -9
- package/src/server/responses/responses-field-backfill.ts +105 -13
- package/src/server/responses/ws-upstream.ts +75 -2
- package/src/server/responses-custom-tool-repair.ts +87 -6
- package/src/server/responses-terminal-repair.ts +25 -4
- package/src/server/responses-undeclared-tool-guard.ts +241 -18
- package/src/server/sse-frame-buffer.ts +31 -4
- package/src/server/ws-bridge.ts +14 -2
- package/src/service.ts +42 -4
- package/src/storage/policy-job.ts +14 -4
- package/src/storage/policy.ts +88 -23
- package/src/types/config.ts +66 -0
- package/src/types/provider.ts +69 -0
- package/src/types/request.ts +17 -4
- package/src/types/tools.ts +116 -11
- package/src/types.ts +3 -1
- package/src/update/index.ts +5 -4
- package/src/update/job.ts +3 -1
- package/src/update/transactional-install.mjs +8 -1
- package/src/usage/expected-prices.ts +43 -24
- package/src/usage/log.ts +63 -12
- package/src/usage/summary.ts +211 -8
- package/src/vision/describe.ts +18 -13
- package/src/web-search/exa-executor.ts +40 -9
- package/src/web-search/executor.ts +10 -3
- package/src/web-search/loop.ts +5 -4
- package/gui/dist/assets/index-BF38heuV.js +0 -104
- package/gui/dist/assets/index-DMiI18Kv.css +0 -1
package/src/service.ts
CHANGED
|
@@ -10,8 +10,8 @@ import { findLiveProxy, proxyIdentityAt, SERVICE_STOP_LIVENESS } from "./server/
|
|
|
10
10
|
import { chmodSync, existsSync, mkdirSync, mkdtempSync, readFileSync, rmdirSync, unlinkSync, writeFileSync } from "node:fs";
|
|
11
11
|
import { homedir, tmpdir } from "node:os";
|
|
12
12
|
import { dirname, join, posix, resolve, win32 } from "node:path";
|
|
13
|
-
import { expandUserPath, getConfigDir,
|
|
14
|
-
import {
|
|
13
|
+
import { expandUserPath, getConfigDir, loadConfig } from "./config";
|
|
14
|
+
import { readPid, removePid, removeRuntimePort, verifyPidIdentity } from "./config/process-state";
|
|
15
15
|
import { restoreNativeCodex, restoreNativeCodexAsync } from "./codex/inject";
|
|
16
16
|
import { stripGrokConfig } from "./grok/inject";
|
|
17
17
|
import { isWslRuntime, resolveCodexHomeDir, type CodexHomeDeps } from "./codex/home";
|
|
@@ -19,6 +19,7 @@ import { BUN_RUNTIME_PATH_ENV, BUN_RUNTIME_SOURCE_ENV, durableBunRuntime } from
|
|
|
19
19
|
import type { BunRuntimeSource } from "./lib/bun-runtime";
|
|
20
20
|
import { isProcessAlive, stopProxy } from "./lib/process-control";
|
|
21
21
|
import { serviceApiTokenFilePath } from "./lib/service-secrets";
|
|
22
|
+
import { tokenCollidesWithAdmin } from "./lib/admin-secrets";
|
|
22
23
|
import { PROXY_ENV_KEYS } from "./lib/proxy-env";
|
|
23
24
|
import { randomUUID } from "node:crypto";
|
|
24
25
|
import {
|
|
@@ -97,13 +98,17 @@ function defaultOpenCodexHome(): string {
|
|
|
97
98
|
return resolve(join(homedir(), ".opencodex"));
|
|
98
99
|
}
|
|
99
100
|
|
|
100
|
-
function
|
|
101
|
-
const paths = [
|
|
101
|
+
export function serviceStatePathsForOpenCodexHome(opencodexHome: string): string[] {
|
|
102
|
+
const paths = [join(opencodexHome, "service-state.json")];
|
|
102
103
|
const defaultPath = join(defaultOpenCodexHome(), "service-state.json");
|
|
103
104
|
if (normalizePathForCompare(defaultPath) !== normalizePathForCompare(paths[0])) paths.push(defaultPath);
|
|
104
105
|
return paths;
|
|
105
106
|
}
|
|
106
107
|
|
|
108
|
+
function serviceStatePaths(): string[] {
|
|
109
|
+
return serviceStatePathsForOpenCodexHome(currentOpenCodexHome());
|
|
110
|
+
}
|
|
111
|
+
|
|
107
112
|
function currentCodexHome(deps: CodexHomeDeps = {}): string {
|
|
108
113
|
// Service ownership must identify the same home as the runtime. In WSL an
|
|
109
114
|
// unset CODEX_HOME can resolve to the single Windows Desktop home rather than
|
|
@@ -362,8 +367,38 @@ export function serviceRetryCommand(
|
|
|
362
367
|
return diag.installed && !diag.conflict ? "ocx service repair" : "ocx service install";
|
|
363
368
|
}
|
|
364
369
|
|
|
370
|
+
/**
|
|
371
|
+
* Refuse a management (admin) token as the data-plane secret.
|
|
372
|
+
*
|
|
373
|
+
* The service exports the contents of the service token file as
|
|
374
|
+
* `OPENCODEX_API_AUTH_TOKEN` before starting the proxy. When that value is the admin
|
|
375
|
+
* token, the server treats the management credential as a data-plane admission secret
|
|
376
|
+
* and fails the ENTIRE management plane closed at boot, so every `/api/*` request
|
|
377
|
+
* returns 503 — even on a loopback install that never needed a data-plane secret.
|
|
378
|
+
* Exporting the admin token in the CLI cannot recover it, because the fence is decided
|
|
379
|
+
* server-side at startup (#2696).
|
|
380
|
+
*
|
|
381
|
+
* Nothing in this codebase puts an admin token in that env var; it arrives from the
|
|
382
|
+
* installing shell. This function is the chokepoint that should refuse it rather than
|
|
383
|
+
* writing a file that produces a broken service. Comparison is the same helper doctor
|
|
384
|
+
* uses: minted `ocx_admin_…` prefix, or byte-equal to configuredAdminToken (env or file).
|
|
385
|
+
*/
|
|
386
|
+
export function assertNotAdminToken(token: string, env: NodeJS.ProcessEnv = process.env): void {
|
|
387
|
+
if (!tokenCollidesWithAdmin(token, env)) return;
|
|
388
|
+
throw new Error(
|
|
389
|
+
"OPENCODEX_API_AUTH_TOKEN holds a management (admin) token. The service exports it "
|
|
390
|
+
+ "as the data-plane secret, which fences the whole management API closed and makes "
|
|
391
|
+
+ "every ocx management command fail with 503. Unset OPENCODEX_API_AUTH_TOKEN, or set "
|
|
392
|
+
+ "it to a distinct data-plane key, then rerun the install.",
|
|
393
|
+
);
|
|
394
|
+
}
|
|
395
|
+
|
|
365
396
|
export function assertServiceAuthEnvironment(): void {
|
|
366
397
|
const config = loadConfig();
|
|
398
|
+
// Check the collision before the loopback short-circuit: a loopback install writes
|
|
399
|
+
// the token file too, so returning early here is what let the broken state through.
|
|
400
|
+
const present = process.env.OPENCODEX_API_AUTH_TOKEN?.trim();
|
|
401
|
+
if (present) assertNotAdminToken(present);
|
|
367
402
|
if (isLoopbackHostname(config.hostname)) return;
|
|
368
403
|
if (process.env.OPENCODEX_API_AUTH_TOKEN?.trim()) return;
|
|
369
404
|
// Reached from `service repair` as well as `install`, so name a command that can
|
|
@@ -379,6 +414,9 @@ export function assertServiceAuthEnvironment(): void {
|
|
|
379
414
|
function writeServiceApiTokenFile(): string | null {
|
|
380
415
|
const token = process.env.OPENCODEX_API_AUTH_TOKEN?.trim();
|
|
381
416
|
if (!token) return null;
|
|
417
|
+
// Last line of defence: every install/repair path funnels through here, so a
|
|
418
|
+
// collision cannot reach disk regardless of which caller ran (#2696).
|
|
419
|
+
assertNotAdminToken(token);
|
|
382
420
|
const path = serviceApiTokenFilePath();
|
|
383
421
|
const dir = getConfigDir();
|
|
384
422
|
recordOwnedConfigPath(dir, path);
|
|
@@ -38,6 +38,7 @@ export interface PolicyJobOutcome {
|
|
|
38
38
|
freedBytes?: number;
|
|
39
39
|
removed?: number;
|
|
40
40
|
trashDir?: string;
|
|
41
|
+
metadataPersistenceError?: PolicyRunResult["metadataPersistenceError"];
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
export interface PolicyJobState {
|
|
@@ -238,6 +239,7 @@ export async function abortStorageCleanupPolicyJobAsync(): Promise<void> {
|
|
|
238
239
|
}
|
|
239
240
|
}
|
|
240
241
|
|
|
242
|
+
/** Project a run result into the bounded management-API job outcome. */
|
|
241
243
|
function outcomeFromResult(result: PolicyRunResult): PolicyJobOutcome {
|
|
242
244
|
return {
|
|
243
245
|
ok: result.ok,
|
|
@@ -248,18 +250,26 @@ function outcomeFromResult(result: PolicyRunResult): PolicyJobOutcome {
|
|
|
248
250
|
...(result.freedBytes !== undefined ? { freedBytes: result.freedBytes } : {}),
|
|
249
251
|
...(result.removed !== undefined ? { removed: result.removed } : {}),
|
|
250
252
|
...(result.trashDir ? { trashDir: result.trashDir } : {}),
|
|
253
|
+
...(result.metadataPersistenceError
|
|
254
|
+
? { metadataPersistenceError: result.metadataPersistenceError }
|
|
255
|
+
: {}),
|
|
251
256
|
};
|
|
252
257
|
}
|
|
253
258
|
|
|
259
|
+
/** Publish one completed evaluation without losing successful cleanup effects. */
|
|
254
260
|
function applyFinished(result: PolicyRunResult): void {
|
|
255
261
|
// Prefer the latest persisted policy over `result.policy`. The worker (or
|
|
256
262
|
// in-process run) already merged run metadata into disk; a concurrent PUT
|
|
257
263
|
// may also have landed after that write. Re-reading avoids applying a stale
|
|
258
264
|
// start-of-job snapshot when the run skipped without saving.
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
265
|
+
// A best-effort fallback policy may predate concurrent edits; keep the current
|
|
266
|
+
// live config untouched when the durable metadata write did not land.
|
|
267
|
+
if (!result.metadataPersistenceError) {
|
|
268
|
+
try {
|
|
269
|
+
livePolicyApply?.(readStorageCleanupPolicyFromConfig());
|
|
270
|
+
} catch {
|
|
271
|
+
livePolicyApply?.(result.policy);
|
|
272
|
+
}
|
|
263
273
|
}
|
|
264
274
|
state = {
|
|
265
275
|
status: "idle",
|
package/src/storage/policy.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* Privacy: logs never include host paths, digests of file contents, or secrets.
|
|
9
9
|
*/
|
|
10
10
|
import { resolveCodexHomeDir } from "../codex/home";
|
|
11
|
-
import { loadConfig, saveConfigPreservingClaudeCode } from "../config";
|
|
11
|
+
import { loadConfig, mutatePersistedConfig, saveConfigPreservingClaudeCode } from "../config";
|
|
12
12
|
import type { StorageCleanupPolicy } from "../types";
|
|
13
13
|
import {
|
|
14
14
|
computePreviewDigest,
|
|
@@ -38,6 +38,7 @@ export function setStorageCleanupPolicyLiveSink(
|
|
|
38
38
|
|
|
39
39
|
export type PolicySchedule = StorageCleanupPolicy["schedule"];
|
|
40
40
|
export type PolicyRunReason = "startup" | "schedule" | "manual";
|
|
41
|
+
export type PolicyMetadataPersistenceError = "missing" | "invalid" | "conflict" | "write_failed";
|
|
41
42
|
|
|
42
43
|
export type PolicySkipReason =
|
|
43
44
|
| "disabled"
|
|
@@ -54,6 +55,7 @@ export interface PolicyRunResult {
|
|
|
54
55
|
freedBytes?: number;
|
|
55
56
|
removed?: number;
|
|
56
57
|
trashDir?: string;
|
|
58
|
+
metadataPersistenceError?: PolicyMetadataPersistenceError;
|
|
57
59
|
policy: StorageCleanupPolicy;
|
|
58
60
|
}
|
|
59
61
|
|
|
@@ -399,6 +401,21 @@ export type PolicyRunMetadataPatch = {
|
|
|
399
401
|
lastRun?: StorageCleanupPolicy["lastRun"];
|
|
400
402
|
};
|
|
401
403
|
|
|
404
|
+
/** Apply only run-owned fields while preserving the supplied policy settings. */
|
|
405
|
+
function applyPolicyRunMetadata(
|
|
406
|
+
policy: StorageCleanupPolicy,
|
|
407
|
+
patch: PolicyRunMetadataPatch,
|
|
408
|
+
): StorageCleanupPolicy {
|
|
409
|
+
let next =
|
|
410
|
+
patch.nextRun === "defer_busy"
|
|
411
|
+
? deferBusy(policy, patch.now)
|
|
412
|
+
: advanceNextRun(policy, patch.now);
|
|
413
|
+
if (patch.lastRun) {
|
|
414
|
+
next = { ...next, lastRun: patch.lastRun };
|
|
415
|
+
}
|
|
416
|
+
return next;
|
|
417
|
+
}
|
|
418
|
+
|
|
402
419
|
/**
|
|
403
420
|
* Reload the latest persisted policy and write only run-owned metadata
|
|
404
421
|
* (`lastRun` / `nextRun`). Preserves concurrent edits to enabled, trigger,
|
|
@@ -410,17 +427,57 @@ export function commitPolicyRunMetadata(
|
|
|
410
427
|
patch: PolicyRunMetadataPatch,
|
|
411
428
|
): StorageCleanupPolicy {
|
|
412
429
|
const latest = normalizeStorageCleanupPolicy(load());
|
|
413
|
-
|
|
414
|
-
patch.nextRun === "defer_busy"
|
|
415
|
-
? deferBusy(latest, patch.now)
|
|
416
|
-
: advanceNextRun(latest, patch.now);
|
|
417
|
-
if (patch.lastRun) {
|
|
418
|
-
next = { ...next, lastRun: patch.lastRun };
|
|
419
|
-
}
|
|
430
|
+
const next = applyPolicyRunMetadata(latest, patch);
|
|
420
431
|
save(next);
|
|
421
432
|
return next;
|
|
422
433
|
}
|
|
423
434
|
|
|
435
|
+
type PolicyRunMetadataCommit = {
|
|
436
|
+
policy: StorageCleanupPolicy;
|
|
437
|
+
persistenceError?: PolicyMetadataPersistenceError;
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
/** Attach the durable metadata outcome without replacing cleanup status or metrics. */
|
|
441
|
+
function withMetadataCommit(
|
|
442
|
+
result: Omit<PolicyRunResult, "policy" | "metadataPersistenceError">,
|
|
443
|
+
committed: PolicyRunMetadataCommit,
|
|
444
|
+
): PolicyRunResult {
|
|
445
|
+
return {
|
|
446
|
+
...result,
|
|
447
|
+
policy: committed.policy,
|
|
448
|
+
...(committed.persistenceError ? { metadataPersistenceError: committed.persistenceError } : {}),
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/** Recompute run-owned metadata from the latest config inside the mutation lock. */
|
|
453
|
+
function commitPolicyRunMetadataToConfig(
|
|
454
|
+
patch: PolicyRunMetadataPatch,
|
|
455
|
+
fallbackPolicy: StorageCleanupPolicy,
|
|
456
|
+
): PolicyRunMetadataCommit {
|
|
457
|
+
const unavailable = (reason: PolicyMetadataPersistenceError): PolicyRunMetadataCommit => {
|
|
458
|
+
console.warn(`[storage-policy] metadata_persist_failed reason=${reason}`);
|
|
459
|
+
return {
|
|
460
|
+
policy: applyPolicyRunMetadata(fallbackPolicy, patch),
|
|
461
|
+
persistenceError: reason,
|
|
462
|
+
};
|
|
463
|
+
};
|
|
464
|
+
try {
|
|
465
|
+
const outcome = mutatePersistedConfig(config => {
|
|
466
|
+
const next = applyPolicyRunMetadata(
|
|
467
|
+
normalizeStorageCleanupPolicy(config.storageCleanupPolicy),
|
|
468
|
+
patch,
|
|
469
|
+
);
|
|
470
|
+
config.storageCleanupPolicy = next;
|
|
471
|
+
return { changed: true, value: next };
|
|
472
|
+
});
|
|
473
|
+
if (outcome.status === "unavailable") return unavailable(outcome.reason);
|
|
474
|
+
livePolicySink?.(outcome.value);
|
|
475
|
+
return { policy: outcome.value };
|
|
476
|
+
} catch {
|
|
477
|
+
return unavailable("write_failed");
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
424
481
|
function logPolicyEvent(message: string): void {
|
|
425
482
|
console.log(`[storage-policy] ${message}`);
|
|
426
483
|
}
|
|
@@ -434,8 +491,14 @@ export function runStorageCleanupPolicy(deps: PolicyRunDeps): PolicyRunResult {
|
|
|
434
491
|
const load = deps.loadPolicy ?? readStorageCleanupPolicyFromConfig;
|
|
435
492
|
const save = deps.savePolicy ?? writeStorageCleanupPolicyToConfig;
|
|
436
493
|
const execute = deps.execute ?? executeArchivedCleanup;
|
|
437
|
-
|
|
438
494
|
const policy = normalizeStorageCleanupPolicy(load());
|
|
495
|
+
// Injected stores retain the existing load/save contract. The production path
|
|
496
|
+
// recomputes metadata from the latest persisted policy inside the config lock.
|
|
497
|
+
const commitMetadata = deps.loadPolicy !== undefined || deps.savePolicy !== undefined
|
|
498
|
+
? (patch: PolicyRunMetadataPatch): PolicyRunMetadataCommit => ({
|
|
499
|
+
policy: commitPolicyRunMetadata(load, save, patch),
|
|
500
|
+
})
|
|
501
|
+
: (patch: PolicyRunMetadataPatch) => commitPolicyRunMetadataToConfig(patch, policy);
|
|
439
502
|
|
|
440
503
|
if (typeof deps.holdAfterLoadMs === "number" && Number.isFinite(deps.holdAfterLoadMs) && deps.holdAfterLoadMs > 0) {
|
|
441
504
|
Bun.sleepSync(Math.floor(deps.holdAfterLoadMs));
|
|
@@ -451,15 +514,15 @@ export function runStorageCleanupPolicy(deps: PolicyRunDeps): PolicyRunResult {
|
|
|
451
514
|
|
|
452
515
|
const selection = selectPolicyPreview(policy, deps.codexHome);
|
|
453
516
|
if (selection.archivedBytes <= policy.trigger.archivedBytesOver) {
|
|
454
|
-
const
|
|
517
|
+
const committed = commitMetadata({ now, nextRun: "advance" });
|
|
455
518
|
logPolicyEvent("skip under_threshold");
|
|
456
|
-
return { ok: true, skipped: "under_threshold",
|
|
519
|
+
return withMetadataCommit({ ok: true, skipped: "under_threshold" }, committed);
|
|
457
520
|
}
|
|
458
521
|
|
|
459
522
|
if (selection.count === 0) {
|
|
460
|
-
const
|
|
523
|
+
const committed = commitMetadata({ now, nextRun: "advance" });
|
|
461
524
|
logPolicyEvent("skip nothing_selected");
|
|
462
|
-
return { ok: true, skipped: "nothing_selected",
|
|
525
|
+
return withMetadataCommit({ ok: true, skipped: "nothing_selected" }, committed);
|
|
463
526
|
}
|
|
464
527
|
|
|
465
528
|
const result = execute({
|
|
@@ -473,25 +536,28 @@ export function runStorageCleanupPolicy(deps: PolicyRunDeps): PolicyRunResult {
|
|
|
473
536
|
});
|
|
474
537
|
|
|
475
538
|
if (!result.ok && result.error === "codex_busy") {
|
|
476
|
-
const
|
|
539
|
+
const committed = commitMetadata({ now, nextRun: "defer_busy" });
|
|
477
540
|
logPolicyEvent("defer codex_busy");
|
|
478
|
-
return {
|
|
541
|
+
return withMetadataCommit({
|
|
542
|
+
ok: false,
|
|
543
|
+
deferred: "codex_busy",
|
|
544
|
+
error: "codex_busy",
|
|
545
|
+
}, committed);
|
|
479
546
|
}
|
|
480
547
|
|
|
481
548
|
if (!result.ok) {
|
|
482
549
|
// Non-busy failure: still advance schedule so we do not tight-loop.
|
|
483
|
-
const
|
|
550
|
+
const committed = commitMetadata({ now, nextRun: "advance" });
|
|
484
551
|
logPolicyEvent(`fail ${result.error ?? "cleanup_failed"}`);
|
|
485
|
-
return {
|
|
552
|
+
return withMetadataCommit({
|
|
486
553
|
ok: false,
|
|
487
554
|
error: result.error,
|
|
488
555
|
mode: result.mode,
|
|
489
556
|
...(result.trashDir ? { trashDir: result.trashDir } : {}),
|
|
490
|
-
|
|
491
|
-
};
|
|
557
|
+
}, committed);
|
|
492
558
|
}
|
|
493
559
|
|
|
494
|
-
const
|
|
560
|
+
const committed = commitMetadata({
|
|
495
561
|
now,
|
|
496
562
|
nextRun: "advance",
|
|
497
563
|
lastRun: {
|
|
@@ -503,14 +569,13 @@ export function runStorageCleanupPolicy(deps: PolicyRunDeps): PolicyRunResult {
|
|
|
503
569
|
logPolicyEvent(
|
|
504
570
|
`ok mode=${result.mode} removed=${result.count} freedBytes=${result.bytes}`,
|
|
505
571
|
);
|
|
506
|
-
return {
|
|
572
|
+
return withMetadataCommit({
|
|
507
573
|
ok: true,
|
|
508
574
|
mode: result.mode,
|
|
509
575
|
freedBytes: result.bytes,
|
|
510
576
|
removed: result.count,
|
|
511
577
|
...(result.trashDir ? { trashDir: result.trashDir } : {}),
|
|
512
|
-
|
|
513
|
-
};
|
|
578
|
+
}, committed);
|
|
514
579
|
}
|
|
515
580
|
|
|
516
581
|
/** Startup / schedule tick entry — swallows unexpected errors. */
|
package/src/types/config.ts
CHANGED
|
@@ -239,14 +239,48 @@ export interface OcxClientIntegrationsConfig {
|
|
|
239
239
|
"claude-desktop"?: boolean;
|
|
240
240
|
}
|
|
241
241
|
|
|
242
|
+
export interface OcxConfigRebaseProvenance {
|
|
243
|
+
version: 1;
|
|
244
|
+
deletedTopLevelKeys: string[];
|
|
245
|
+
}
|
|
246
|
+
|
|
242
247
|
export interface OcxConfig {
|
|
243
248
|
port: number;
|
|
244
249
|
/** Opt in to one identical-turn retry when a Responses completion has no text or tool call. */
|
|
245
250
|
emptyCompletionRetry?: boolean;
|
|
251
|
+
/**
|
|
252
|
+
* Whether a login may open a browser on the machine running the proxy.
|
|
253
|
+
*
|
|
254
|
+
* Absent and `true` both mean "open", which is what every existing install
|
|
255
|
+
* already does. Only an explicit `false` declines — for an operator who wants
|
|
256
|
+
* to paste the authorization URL into a different browser profile, or who is
|
|
257
|
+
* driving the dashboard from a different machine than the proxy.
|
|
258
|
+
*
|
|
259
|
+
* Deliberately a boolean and not an "auto" mode: inferring headlessness from
|
|
260
|
+
* SSH_CONNECTION or a missing DISPLAY breaks a working login silently when
|
|
261
|
+
* the guess is wrong.
|
|
262
|
+
*/
|
|
263
|
+
oauthOpenBrowser?: boolean;
|
|
246
264
|
/** Maximum usage-log bytes read for one management snapshot. */
|
|
247
265
|
managementUsageMaxReadBytes?: number;
|
|
248
266
|
providers: Record<string, OcxProviderConfig>;
|
|
249
267
|
defaultProvider: string;
|
|
268
|
+
/** Persisted state for newly discovered provider models (#2464). Absent keeps legacy "on" behavior. */
|
|
269
|
+
modelDiscovery?: {
|
|
270
|
+
newModelPolicy?: "on" | "off";
|
|
271
|
+
knownModels?: Record<string, {
|
|
272
|
+
ids: string[];
|
|
273
|
+
removed: string[];
|
|
274
|
+
updatedAt: string;
|
|
275
|
+
/** Consecutive successful discoveries in which an active id was absent. */
|
|
276
|
+
missing?: Record<string, number>;
|
|
277
|
+
}>;
|
|
278
|
+
recentArrivals?: Record<string, Array<{ id: string; at: string }>>;
|
|
279
|
+
};
|
|
280
|
+
/** Enable the shipped model alias patterns for providers without an override. */
|
|
281
|
+
defaultModelAliases?: boolean;
|
|
282
|
+
/** Explicit top-level deletion intent used by stale whole-config rebases. */
|
|
283
|
+
configRebaseProvenance?: OcxConfigRebaseProvenance | Record<string, unknown>;
|
|
250
284
|
/** OpenAI provider-contract migration marker (v2 = single `openai` provider with account mode). */
|
|
251
285
|
openaiProviderTierVersion?: 1 | 2;
|
|
252
286
|
/** One-time migration marker for Antigravity's static-catalog defaults. */
|
|
@@ -470,6 +504,13 @@ export interface OcxConfig {
|
|
|
470
504
|
* those are unset — Bun's fetch honors them for all outbound calls; localhost is excluded.
|
|
471
505
|
*/
|
|
472
506
|
proxy?: string;
|
|
507
|
+
/**
|
|
508
|
+
* Hosts that bypass `proxy` for OpenCodex's own outbound provider calls, merged into
|
|
509
|
+
* NO_PROXY at startup. Accepts a comma-separated string (NO_PROXY syntax) or an array.
|
|
510
|
+
* Loopback is always excluded regardless of this setting, and an inherited NO_PROXY is
|
|
511
|
+
* preserved — this ADDS entries, it never replaces the environment.
|
|
512
|
+
*/
|
|
513
|
+
noProxy?: string | string[];
|
|
473
514
|
/**
|
|
474
515
|
* Upstream stall timeout (seconds). After this many seconds of no upstream data, emits
|
|
475
516
|
* response.incomplete. Default 300. Min 1.
|
|
@@ -541,6 +582,15 @@ export interface OcxConfig {
|
|
|
541
582
|
* selector map remains visible for compatibility with hand-written configurations.
|
|
542
583
|
*/
|
|
543
584
|
codexAccountPickerEnabled?: boolean;
|
|
585
|
+
/**
|
|
586
|
+
* Show the GPT-5.3-Codex-Spark weekly window on Codex quota surfaces. Default false.
|
|
587
|
+
*
|
|
588
|
+
* Spark is a single-model window that reads 0% for most operators, and on a multi-account
|
|
589
|
+
* pool it doubles the bar count for information almost nobody acts on. Hidden by default and
|
|
590
|
+
* revealed by an explicit `true`; a malformed value reads as hidden rather than rejecting the
|
|
591
|
+
* whole config.
|
|
592
|
+
*/
|
|
593
|
+
showCodexSparkQuota?: boolean;
|
|
544
594
|
/** Active pool account id for next session. undefined = main (passthrough as-is). */
|
|
545
595
|
activeCodexAccountId?: string;
|
|
546
596
|
/** Auto-switch threshold (0-100). Default 80. 0 = disabled. */
|
|
@@ -570,6 +620,22 @@ export interface OcxConfig {
|
|
|
570
620
|
/** Successful new-session binds retained on one round-robin selection. Default 1; range 1..100. */
|
|
571
621
|
stickyLimit?: number;
|
|
572
622
|
};
|
|
623
|
+
/**
|
|
624
|
+
* Generic OAuth multi-account 429 failover (#2568). Presence-driven by default.
|
|
625
|
+
*
|
|
626
|
+
* Rotates to another logged-in account of the SAME provider when one is rate-limited, for
|
|
627
|
+
* OAuth providers that have no pool of their own — xAI, Cursor, Kimi, GitHub Copilot,
|
|
628
|
+
* Antigravity, Nous. The Codex pool and the Anthropic pool own their own rotation and are
|
|
629
|
+
* excluded; this setting changes neither.
|
|
630
|
+
*
|
|
631
|
+
* With the key absent, rotation activates when a provider has 2 or more eligible stored
|
|
632
|
+
* accounts — the same consent rule API-key pools already apply to a 2+ key pool (#2568d). A
|
|
633
|
+
* single account is a strict no-op. Set `false` to keep strict single-account behaviour;
|
|
634
|
+
* `providers.<name>.oauthAccountFailover` overrides this per provider.
|
|
635
|
+
*/
|
|
636
|
+
oauthAccountFailover?: {
|
|
637
|
+
enabled?: boolean;
|
|
638
|
+
};
|
|
573
639
|
/** Virtual `combo/<id>` models spanning concrete provider/model targets (issue #133). */
|
|
574
640
|
combos?: Record<string, OcxComboConfig>;
|
|
575
641
|
/**
|
package/src/types/provider.ts
CHANGED
|
@@ -115,6 +115,15 @@ export interface TierObservationContext {
|
|
|
115
115
|
fastWire: FastWire | null;
|
|
116
116
|
demandDecision: "force-fast" | "force-default" | "inherit";
|
|
117
117
|
callerTier?: string;
|
|
118
|
+
/**
|
|
119
|
+
* Whether the destination's echoed `service_tier` is authoritative about Fast scheduling.
|
|
120
|
+
*
|
|
121
|
+
* The ChatGPT-internal Codex backend returns `service_tier: "default"` on turns that were in
|
|
122
|
+
* fact scheduled as priority, so treating its echo as a downgrade produced a false
|
|
123
|
+
* `response-declined` on every Fast request (#2558). Absent means "assume authoritative",
|
|
124
|
+
* preserving the behaviour for the public API where the echo does mean what it says.
|
|
125
|
+
*/
|
|
126
|
+
responseTierAuthoritative?: boolean;
|
|
118
127
|
}
|
|
119
128
|
|
|
120
129
|
export type TierDecision =
|
|
@@ -127,6 +136,12 @@ export type TierDecision =
|
|
|
127
136
|
* retries are allowed; OAuth/forward credentials and local runtimes are never replayed.
|
|
128
137
|
*/
|
|
129
138
|
export interface OcxProviderConfig {
|
|
139
|
+
/** Optional short provider namespace used only at request/catalog presentation time. */
|
|
140
|
+
alias?: string;
|
|
141
|
+
/** Native model id -> short, slash-free request alias. */
|
|
142
|
+
modelAliases?: Record<string, string>;
|
|
143
|
+
/** Override the global built-in model-alias switch for this provider. */
|
|
144
|
+
defaultAliases?: boolean;
|
|
130
145
|
adapter: string;
|
|
131
146
|
/**
|
|
132
147
|
* Codex tool calling mode for routed models.
|
|
@@ -266,6 +281,33 @@ export interface OcxProviderConfig {
|
|
|
266
281
|
* full set so the user can pick). See devlog issue_052_provider-model-allowlist.
|
|
267
282
|
*/
|
|
268
283
|
selectedModels?: string[];
|
|
284
|
+
/** Override for newly discovered models. Absent/"inherit" uses the install policy. */
|
|
285
|
+
newModelPolicy?: "on" | "off" | "inherit";
|
|
286
|
+
/**
|
|
287
|
+
* Model-preset marker for `selectedModels` (#2465). Absent means "all", exactly today's
|
|
288
|
+
* semantics — an existing provider is never narrowed by an upgrade.
|
|
289
|
+
*
|
|
290
|
+
* The preset is a SEED, not a lock: `selectedModels` holds concrete ids materialized from
|
|
291
|
+
* the shipped rules, so every existing consumer and older binaries keep working against a
|
|
292
|
+
* plain allowlist. Divergence is detected at the WRITE path rather than by diffing — any user
|
|
293
|
+
* edit while the mode is "preset" flips it to "custom", after which the proxy never
|
|
294
|
+
* re-materializes. That collapses upgrade reconciliation to a version compare.
|
|
295
|
+
*
|
|
296
|
+
* Deliberately distinct from `deriveProviderPresets`, which curates WHICH PROVIDERS to offer.
|
|
297
|
+
* This curates which MODELS a provider exposes; the code says "model preset" throughout.
|
|
298
|
+
*/
|
|
299
|
+
modelPreset?: {
|
|
300
|
+
mode: "preset" | "all" | "custom";
|
|
301
|
+
/** MODEL_PRESETS version materialized into `selectedModels`. */
|
|
302
|
+
appliedVersion?: number;
|
|
303
|
+
appliedAt?: string;
|
|
304
|
+
/**
|
|
305
|
+
* Set when materialization matched nothing and the provider fell back to "all". A preset
|
|
306
|
+
* must never write an empty allowlist, because empty means ALL and would silently
|
|
307
|
+
* un-curate; the fallback marker lets the next convergence retry.
|
|
308
|
+
*/
|
|
309
|
+
fallback?: "preset-empty";
|
|
310
|
+
};
|
|
269
311
|
/** Provider-wide fallback when context metadata is absent; otherwise caps the reported window. */
|
|
270
312
|
contextWindow?: number;
|
|
271
313
|
/** Per-model fallback when context metadata is absent; otherwise caps the reported window. */
|
|
@@ -274,6 +316,11 @@ export interface OcxProviderConfig {
|
|
|
274
316
|
modelInputModalities?: Record<string, string[]>;
|
|
275
317
|
/** Model-specific max input token limits. Values cap auto_compact_token_limit. */
|
|
276
318
|
modelMaxInputTokens?: Record<string, number>;
|
|
319
|
+
/**
|
|
320
|
+
* Per-model soft compaction budgets. Values may only lower the effective
|
|
321
|
+
* context/max-input envelope; they never raise hard admission limits.
|
|
322
|
+
*/
|
|
323
|
+
modelAutoCompactTokenLimits?: Record<string, number>;
|
|
277
324
|
/**
|
|
278
325
|
* Provider-wide fallback for chat-completions `max_tokens` when the caller omits
|
|
279
326
|
* Responses `max_output_tokens`. Adapters still let an explicit request win.
|
|
@@ -304,6 +351,16 @@ export interface OcxProviderConfig {
|
|
|
304
351
|
* providers whose registry entry declares authKind "local" (management API enforces).
|
|
305
352
|
*/
|
|
306
353
|
authMode?: "key" | "forward" | "oauth" | "local";
|
|
354
|
+
/**
|
|
355
|
+
* Per-provider override for generic OAuth multi-account 429 failover (#2568).
|
|
356
|
+
*
|
|
357
|
+
* Rotation is presence-driven by default — 2+ logged-in accounts activate it — so this exists
|
|
358
|
+
* for the operator who accepts rotation on one provider and refuses it on another. An explicit
|
|
359
|
+
* boolean here beats the global `oauthAccountFailover` and beats presence.
|
|
360
|
+
*/
|
|
361
|
+
oauthAccountFailover?: {
|
|
362
|
+
enabled?: boolean;
|
|
363
|
+
};
|
|
307
364
|
/** Allow an explicitly key/oauth provider to run without a credential (for keyless local proxies). */
|
|
308
365
|
keyOptional?: boolean;
|
|
309
366
|
/**
|
|
@@ -336,6 +393,18 @@ export interface OcxProviderConfig {
|
|
|
336
393
|
* Responses backend rejects Codex summary-delivery fields for that model.
|
|
337
394
|
*/
|
|
338
395
|
modelSupportsReasoningSummaries?: Record<string, boolean>;
|
|
396
|
+
/**
|
|
397
|
+
* Model-specific Codex Responses verbosity capability. Set false when the upstream ignores
|
|
398
|
+
* `text.verbosity`; the catalog hides the no-op picker and the Responses adapter strips stale
|
|
399
|
+
* or caller-supplied values while preserving other `text` fields.
|
|
400
|
+
*/
|
|
401
|
+
modelSupportsVerbosity?: Record<string, boolean>;
|
|
402
|
+
/**
|
|
403
|
+
* Provider-wide Codex Responses verbosity capability, applied to models the per-model map
|
|
404
|
+
* does not enumerate (a live-discovered id, for example). Materialized from the registry at
|
|
405
|
+
* seed/enrich time so the catalog hint pass never has to read PROVIDER_REGISTRY.
|
|
406
|
+
*/
|
|
407
|
+
supportsVerbosity?: boolean;
|
|
339
408
|
/**
|
|
340
409
|
* Per-model wire value for Responses `stream_options.reasoning_summary_delivery`.
|
|
341
410
|
* Presence also advertises reasoning-summary support for that routed model.
|
package/src/types/request.ts
CHANGED
|
@@ -30,6 +30,11 @@ export interface OcxReasoningReplayIdentity {
|
|
|
30
30
|
* the holder, so late tool-call cache writes see the active physical identity.
|
|
31
31
|
*/
|
|
32
32
|
export interface OcxReasoningReplayScopeRef {
|
|
33
|
+
/**
|
|
34
|
+
* Conversation namespace for replay state. Historically this was always the Codex parent-thread
|
|
35
|
+
* id; headerless Responses callers use a raw sanitized thread/Cursor/session fallback, never the
|
|
36
|
+
* hashed request-log conversation id.
|
|
37
|
+
*/
|
|
33
38
|
readonly clientThreadId: string;
|
|
34
39
|
current?: Readonly<OcxReasoningReplayIdentity>;
|
|
35
40
|
}
|
|
@@ -63,7 +68,9 @@ export interface OcxParsedRequest {
|
|
|
63
68
|
_cursorConversationId?: string;
|
|
64
69
|
/** Stable upstream client thread identity, used only to derive provider-scoped continuation ids. */
|
|
65
70
|
_clientThreadId?: string;
|
|
66
|
-
/**
|
|
71
|
+
/** Cursor-only thread owner; may be an opaque process-local Desktop session/thread identity. */
|
|
72
|
+
_cursorClientThreadId?: string;
|
|
73
|
+
/** Conversation/provider/account/model-bound namespace for reasoning replay state. */
|
|
67
74
|
_reasoningReplayScope?: OcxReasoningReplayScopeRef;
|
|
68
75
|
/**
|
|
69
76
|
* Set by bindRouteReasoningReplayScope after a proven serving-identity change, or by
|
|
@@ -81,7 +88,7 @@ export interface OcxParsedRequest {
|
|
|
81
88
|
*/
|
|
82
89
|
_cursorIsolateConversation?: boolean;
|
|
83
90
|
/** Account-scoped, non-secret Kiro request metadata selected with the OAuth access token. */
|
|
84
|
-
_kiroAuthContext?: Pick<KiroOAuthMetadata, "profileArn" | "apiRegion" | "ssoRegion">;
|
|
91
|
+
_kiroAuthContext?: Pick<KiroOAuthMetadata, "profileArn" | "apiRegion" | "ssoRegion" | "authType">;
|
|
85
92
|
/** Provider-private continuation metadata resolved from the Responses previous_response_id chain. */
|
|
86
93
|
_providerContinuation?: OcxProviderContinuationState;
|
|
87
94
|
/** Persisted continuation considered only after the final physical route is known. */
|
|
@@ -183,8 +190,14 @@ export interface OcxImageContent {
|
|
|
183
190
|
detail?: string;
|
|
184
191
|
}
|
|
185
192
|
|
|
186
|
-
|
|
187
|
-
|
|
193
|
+
export interface OcxVideoContent {
|
|
194
|
+
type: "video";
|
|
195
|
+
/** A base64 `data:` URL from an OpenAI-compatible `video_url` part. */
|
|
196
|
+
videoUrl: string;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/** A user/developer message content part: text or native media. */
|
|
200
|
+
export type OcxContentPart = OcxTextContent | OcxImageContent | OcxVideoContent;
|
|
188
201
|
|
|
189
202
|
export interface OcxThinkingContent {
|
|
190
203
|
type: "thinking";
|