From 7e6ce7d7246b57fc244432bcfd813616965072c1 Mon Sep 17 00:00:00 2001 From: t Date: Wed, 9 Sep 2026 02:40:43 +0900 Subject: [PATCH 1/7] fix(codex): keep Spark five-hour quota model-scoped Carried from #4018 (author cb8010d6) for maintainer-side CI and sequential integration. Closes #4017 Co-authored-by: cb8010d6 <53855466+cb8010d6@users.noreply.github.com> --- src/codex/auth-api.ts | 9 ++++--- src/codex/quota.ts | 23 ++++++++++------ src/types/config.ts | 2 +- tests/codex-integration/codex-routing.test.ts | 11 +++++--- .../codex-spark-visibility.test.ts | 27 ++++++++++++++----- 5 files changed, 50 insertions(+), 22 deletions(-) diff --git a/src/codex/auth-api.ts b/src/codex/auth-api.ts index 2e2a775867..1a1e66d88b 100644 --- a/src/codex/auth-api.ts +++ b/src/codex/auth-api.ts @@ -241,12 +241,15 @@ function codexAccountPersistenceConflict( } /** - * The exact label `parseUsageQuota` emits for the Codex Spark window (quota.ts). + * The exact labels `parseUsageQuota` emits for the Codex Spark windows (quota.ts). * Matching on the label rather than on "is a custom window" is load-bearing: the same array * carries Cursor's First-party models / API usage, Anthropic's Fable / Opus / Sonnet, * Antigravity's Gem / Cla, Kimi's subscription credits and a dozen dynamic provider meters. */ -const CODEX_SPARK_WINDOW_LABEL = "GPT-5.3-Codex-Spark Weekly"; +const CODEX_SPARK_WINDOW_LABELS = new Set([ + "GPT-5.3-Codex-Spark 5h", + "GPT-5.3-Codex-Spark Weekly", +]); /** * Drop the Spark window unless the operator asked for it (default hidden). @@ -264,7 +267,7 @@ export function withSparkVisibility window.label !== CODEX_SPARK_WINDOW_LABEL); + const kept = quota.customWindows.filter(window => !CODEX_SPARK_WINDOW_LABELS.has(window.label)); if (kept.length === quota.customWindows.length) return quota; // An empty list is dropped rather than serialized: an absent field and an empty array should // not be two different ways of saying "no custom windows" on the wire. diff --git a/src/codex/quota.ts b/src/codex/quota.ts index 0648e4a717..d125f09f93 100644 --- a/src/codex/quota.ts +++ b/src/codex/quota.ts @@ -795,6 +795,10 @@ export function parseUsageQuota(data: WhamUsageResponse): Omit !!window); + const sparkShort = sparkWindows.find(window => { + const percent = normalizeUsagePercent(window.used_percent); + return percent !== undefined && isExplicitShortWindow(window); + }); const sparkWeekly = sparkWindows.find(window => { const percent = normalizeUsagePercent(window.used_percent); const seconds = window.limit_window_seconds; @@ -803,16 +807,19 @@ export function parseUsageQuota(data: WhamUsageResponse): Omit= WEEKLY_WINDOW_MIN_SECONDS); }); - const sparkPercent = normalizeUsagePercent(sparkWeekly?.used_percent); - if (sparkPercent !== undefined) { - const sparkWindow: { label: string; percent: number; resetAt?: number } = { - label: "GPT-5.3-Codex-Spark Weekly", - percent: sparkPercent, - }; - const resetAt = normalizeResetAt(sparkWeekly?.reset_at); + const sparkCustomWindows: Array<{ label: string; percent: number; resetAt?: number }> = []; + for (const [label, window] of [ + ["GPT-5.3-Codex-Spark 5h", sparkShort], + ["GPT-5.3-Codex-Spark Weekly", sparkWeekly], + ] as const) { + const percent = normalizeUsagePercent(window?.used_percent); + if (percent === undefined) continue; + const sparkWindow: { label: string; percent: number; resetAt?: number } = { label, percent }; + const resetAt = normalizeResetAt(window?.reset_at); if (resetAt !== undefined) sparkWindow.resetAt = resetAt; - quota.customWindows = [sparkWindow]; + sparkCustomWindows.push(sparkWindow); } + if (sparkCustomWindows.length > 0) quota.customWindows = sparkCustomWindows; if (resetCredits !== undefined) quota.resetCredits = resetCredits; return hasKnownQuotaValue(quota) || resetCredits !== undefined ? quota : null; diff --git a/src/types/config.ts b/src/types/config.ts index 0b0a2b2b98..fc9a55a8fa 100644 --- a/src/types/config.ts +++ b/src/types/config.ts @@ -753,7 +753,7 @@ export interface OcxConfig { */ codexAccountPickerEnabled?: boolean; /** - * Show the GPT-5.3-Codex-Spark weekly window on Codex quota surfaces. Default false. + * Show the GPT-5.3-Codex-Spark 5-hour and weekly windows on Codex quota surfaces. Default false. * * Spark is a single-model window that reads 0% for most operators, and on a multi-account * pool it doubles the bar count for information almost nobody acts on. Hidden by default and diff --git a/tests/codex-integration/codex-routing.test.ts b/tests/codex-integration/codex-routing.test.ts index 11774ef474..85ecb3a3fd 100644 --- a/tests/codex-integration/codex-routing.test.ts +++ b/tests/codex-integration/codex-routing.test.ts @@ -1746,8 +1746,9 @@ describe("codex routing", () => { }); }); - test("WHAM preserves the 5h, weekly, and Spark weekly windows", () => { + test("WHAM keeps general and Spark windows separate", () => { expect(parseUsageQuota({ + plan_type: "pro", rate_limit: { primary_window: { used_percent: 11, reset_at: 1, limit_window_seconds: 5 * 60 * 60 }, secondary_window: { used_percent: 22, reset_at: 2, limit_window_seconds: 7 * 24 * 60 * 60 }, @@ -1756,7 +1757,8 @@ describe("codex routing", () => { limit_name: "GPT-5.3-Codex-Spark", metered_feature: "codex_bengalfox", rate_limit: { - primary_window: { used_percent: 33, reset_at: 3, limit_window_seconds: 7 * 24 * 60 * 60 }, + primary_window: { used_percent: 33, reset_at: 3, limit_window_seconds: 5 * 60 * 60 }, + secondary_window: { used_percent: 44, reset_at: 4, limit_window_seconds: 7 * 24 * 60 * 60 }, }, }], })).toEqual({ @@ -1765,7 +1767,10 @@ describe("codex routing", () => { shortWindowSeconds: 5 * 60 * 60, weeklyPercent: 22, weeklyResetAt: 2, - customWindows: [{ label: "GPT-5.3-Codex-Spark Weekly", percent: 33, resetAt: 3 }], + customWindows: [ + { label: "GPT-5.3-Codex-Spark 5h", percent: 33, resetAt: 3 }, + { label: "GPT-5.3-Codex-Spark Weekly", percent: 44, resetAt: 4 }, + ], }); }); diff --git a/tests/codex-integration/codex-spark-visibility.test.ts b/tests/codex-integration/codex-spark-visibility.test.ts index c5dfe1c8a7..f97073b142 100644 --- a/tests/codex-integration/codex-spark-visibility.test.ts +++ b/tests/codex-integration/codex-spark-visibility.test.ts @@ -9,6 +9,7 @@ import type { OcxConfig } from "../../src/types"; import { removeTreeWithRetry } from "../helpers/remove-tree"; const SPARK = "GPT-5.3-Codex-Spark Weekly"; +const SPARK_SHORT = "GPT-5.3-Codex-Spark 5h"; const originalHome = process.env.OPENCODEX_HOME; let home = ""; @@ -33,7 +34,7 @@ afterEach(() => { }); /** - * Codex Spark is a single-model weekly window. It reads 0% for most operators and, on a + * Codex Spark is a single-model quota with 5-hour and weekly windows. It reads 0% for most operators and, on a * multi-account pool, doubles the bar count on every card for information almost nobody acts * on — so it is hidden unless the operator asks for it. * @@ -46,7 +47,10 @@ describe("Codex Spark quota visibility", () => { saveConfig(baseConfig()); const stored = { weeklyPercent: 11, - customWindows: [{ label: SPARK, percent: 33, resetAt: 3 }], + customWindows: [ + { label: SPARK_SHORT, percent: 33, resetAt: 2 }, + { label: SPARK, percent: 34, resetAt: 3 }, + ], updatedAt: Date.now(), }; const projected = withSparkVisibility(stored); @@ -54,7 +58,7 @@ describe("Codex Spark quota visibility", () => { // saying the same thing on the wire. expect(projected.customWindows).toBeUndefined(); // The source object is untouched — routing and capacity still see the window. - expect(stored.customWindows).toHaveLength(1); + expect(stored.customWindows).toHaveLength(2); expect(projected.weeklyPercent).toBe(11); }); @@ -62,17 +66,26 @@ describe("Codex Spark quota visibility", () => { saveConfig(baseConfig(true)); loadConfig(); const projected = withSparkVisibility({ - customWindows: [{ label: SPARK, percent: 33, resetAt: 3 }], + customWindows: [ + { label: SPARK_SHORT, percent: 33, resetAt: 2 }, + { label: SPARK, percent: 34, resetAt: 3 }, + ], updatedAt: Date.now(), }); - expect(projected.customWindows).toEqual([{ label: SPARK, percent: 33, resetAt: 3 }]); + expect(projected.customWindows).toEqual([ + { label: SPARK_SHORT, percent: 33, resetAt: 2 }, + { label: SPARK, percent: 34, resetAt: 3 }, + ]); }); test("an explicit false hides it", () => { saveConfig(baseConfig(false)); loadConfig(); const projected = withSparkVisibility({ - customWindows: [{ label: SPARK, percent: 33 }], + customWindows: [ + { label: SPARK_SHORT, percent: 33 }, + { label: SPARK, percent: 34 }, + ], updatedAt: Date.now(), }); expect(projected.customWindows).toBeUndefined(); @@ -87,6 +100,7 @@ describe("Codex Spark quota visibility", () => { customWindows: [ { label: "First-party models", percent: 40 }, { label: "API usage", percent: 12 }, + { label: SPARK_SHORT, percent: 32 }, { label: SPARK, percent: 33 }, { label: "Fable", percent: 7 }, { label: "Total subscription credits", percent: 90 }, @@ -112,4 +126,3 @@ describe("Codex Spark quota visibility", () => { expect(withSparkVisibility(null)).toBeNull(); }); }); - From acf1de4a8bf6954d49d1c26cc3206bb71d6a4002 Mon Sep 17 00:00:00 2001 From: t Date: Wed, 9 Sep 2026 02:40:44 +0900 Subject: [PATCH 2/7] fix(codex): retain Spark quota on partial header updates Carried from #4008 (author cb8010d6) for maintainer-side CI and sequential integration. Closes #4007 Co-authored-by: cb8010d6 <53855466+cb8010d6@users.noreply.github.com> --- src/codex/quota.ts | 3 ++ .../codex-quota-parser-parity.test.ts | 45 ++++++++++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/codex/quota.ts b/src/codex/quota.ts index d125f09f93..351f5fb994 100644 --- a/src/codex/quota.ts +++ b/src/codex/quota.ts @@ -336,6 +336,9 @@ function mergeAccountQuota( } if (snapshotHasCustom(quota)) next.customWindows = quota.customWindows; + // Ordinary response headers omit model-specific windows reported by WHAM. + // Absence is a partial update; an explicit list (including []) still replaces it. + else if (existing?.customWindows !== undefined) next.customWindows = existing.customWindows; if (quota.resetCredits !== undefined) next.resetCredits = quota.resetCredits; else if (existing?.resetCredits !== undefined) next.resetCredits = existing.resetCredits; diff --git a/tests/codex-integration/codex-quota-parser-parity.test.ts b/tests/codex-integration/codex-quota-parser-parity.test.ts index 172168ada8..a698525648 100644 --- a/tests/codex-integration/codex-quota-parser-parity.test.ts +++ b/tests/codex-integration/codex-quota-parser-parity.test.ts @@ -1,12 +1,56 @@ import { describe, expect, it } from "bun:test"; import { clearAccountQuota, + applyAccountQuotaFromUpstreamHeaders, + getAccountQuota, parseUpstreamQuotaHeaders, parseUsageQuota, setAccountQuotaFromParsed, } from "../../src/codex/quota"; import { codexPoolQuotaEvidence } from "../../src/routing/quota"; +describe("Spark quota survives partial header updates", () => { + it("keeps the WHAM Spark window when an ordinary response updates standard quota", () => { + clearAccountQuota(); + const refreshed = parseUsageQuota({ + rate_limit: { primary_window: { used_percent: 20, limit_window_seconds: 604_800 } }, + additional_rate_limits: [{ + limit_name: "GPT-5.3-Codex-Spark", + rate_limit: { primary_window: { used_percent: 30, reset_at: 2_000_000_000, limit_window_seconds: 604_800 } }, + }], + }); + setAccountQuotaFromParsed("spark-partial", refreshed); + applyAccountQuotaFromUpstreamHeaders("spark-partial", new Headers({ + "x-codex-primary-used-percent": "21", + "x-codex-primary-window-minutes": "10080", + })); + expect(getAccountQuota("spark-partial")?.weeklyPercent).toBe(21); + expect(getAccountQuota("spark-partial")?.customWindows).toEqual(refreshed?.customWindows); + }); + + it("replaces custom windows when supplied, including an explicit empty list", () => { + clearAccountQuota(); + setAccountQuotaFromParsed("spark-replace", { + customWindows: [{ label: "GPT-5.3-Codex-Spark Weekly", percent: 30 }], + }); + const replacement = [{ label: "GPT-5.3-Codex-Spark Weekly", percent: 0, resetAt: 2_000_000_000 }]; + setAccountQuotaFromParsed("spark-replace", { customWindows: replacement }); + expect(getAccountQuota("spark-replace")?.customWindows).toEqual(replacement); + setAccountQuotaFromParsed("spark-replace", { weeklyPercent: 21, customWindows: [] }); + expect(getAccountQuota("spark-replace")?.customWindows).toEqual([]); + }); + + it("does not carry custom windows across an account cache clear", () => { + clearAccountQuota(); + setAccountQuotaFromParsed("spark-clear", { + customWindows: [{ label: "GPT-5.3-Codex-Spark Weekly", percent: 30 }], + }); + clearAccountQuota("spark-clear"); + setAccountQuotaFromParsed("spark-clear", { weeklyPercent: 21 }); + expect(getAccountQuota("spark-clear")?.customWindows).toBeUndefined(); + }); +}); + /** * The two quota parsers, pinned against each other. * @@ -109,4 +153,3 @@ describe("routing headroom accounts for the burst window", () => { expect(evidence.headroom).toBeLessThanOrEqual(0.05); }); }); - From 309f2b6d3e76434dd9d8657bad40cbf2920c79aa Mon Sep 17 00:00:00 2001 From: t Date: Wed, 9 Sep 2026 02:40:44 +0900 Subject: [PATCH 3/7] fix(codex): invalidate app-server observations at catalog boundaries Carried from #3981 (author yansigit) for maintainer-side CI and sequential integration. Co-authored-by: yansigit <44089734+yansigit@users.noreply.github.com> --- .../content/docs/guides/codex-app-models.md | 2 + src/codex/internal/catalog-writer.ts | 3 + src/codex/sync.ts | 5 ++ .../codex-models-cache-invalidate.test.ts | 62 ++++++++++++++++++- 4 files changed, 70 insertions(+), 2 deletions(-) diff --git a/docs-site/src/content/docs/guides/codex-app-models.md b/docs-site/src/content/docs/guides/codex-app-models.md index bcda44080b..6f9b756789 100644 --- a/docs-site/src/content/docs/guides/codex-app-models.md +++ b/docs-site/src/content/docs/guides/codex-app-models.md @@ -319,3 +319,5 @@ ocx sync opencodex rewrites `models_cache.json` with a deliberately stale cache wrapper whenever catalog visibility, priority, or metadata changes, so the next Codex model refresh reads the new catalog. + +After a catalog or model-cache write, OpenCodex invalidates its cached app-server observation so the next request checks process freshness again. A configuration sync also invalidates the observation when catalog contents are unchanged. This refresh does not restart Codex processes. diff --git a/src/codex/internal/catalog-writer.ts b/src/codex/internal/catalog-writer.ts index 370bbda95e..0d9bee79ef 100644 --- a/src/codex/internal/catalog-writer.ts +++ b/src/codex/internal/catalog-writer.ts @@ -16,6 +16,7 @@ import { forgetEphemeralSecretPath, hardenSecretPath, } from "../../lib/windows-secret-acl"; +import { resetCodexAppServerCatalogStateCache } from "../app-server-processes"; export interface PreparedCatalogFileWrite { readonly path: string; @@ -167,6 +168,7 @@ export function replaceActiveCodexCatalog( ): void { assertCatalogWritePermit(permit, owningCodexHome); atomicWriteFile(prepared.path, prepared.content, io); + resetCodexAppServerCatalogStateCache(); } /** Atomically publish the catalog-path-keyed immutable backup without clobbering. */ @@ -200,4 +202,5 @@ export function replaceCodexModelsCache( ): void { assertCatalogWritePermit(permit, owningCodexHome); atomicWriteFile(prepared.path, prepared.content, io); + resetCodexAppServerCatalogStateCache(); } diff --git a/src/codex/sync.ts b/src/codex/sync.ts index 4c10068b74..6d7008a01a 100644 --- a/src/codex/sync.ts +++ b/src/codex/sync.ts @@ -8,6 +8,7 @@ import { summarizeComboCatalogOmissions, type ComboCatalogOmission } from "./cat import { shouldSyncCodexOnStart } from "./desired-state"; import { admitCodexWrite, type CodexAdmission } from "./admission"; import type { CodexCatalogSyncOptions } from "./catalog/sync"; +import { resetCodexAppServerCatalogStateCache } from "./app-server-processes"; export interface CodexSyncResult { /** @@ -116,6 +117,10 @@ export async function syncModelsToCodex( message: admission.message, }; } + // Config injection is a relevant Codex write even when the catalog bytes are unchanged. + // Drop cached process evidence before async discovery so a process that appeared since the + // last read cannot make native-default guidance report active after this sync. + resetCodexAppServerCatalogStateCache(); const p = port ?? config.port ?? 10100; const externalProvider = (deps.currentExternalCodexModelProvider ?? currentExternalCodexModelProvider)(); diff --git a/tests/codex-integration/codex-models-cache-invalidate.test.ts b/tests/codex-integration/codex-models-cache-invalidate.test.ts index 3efb316511..b644740e40 100644 --- a/tests/codex-integration/codex-models-cache-invalidate.test.ts +++ b/tests/codex-integration/codex-models-cache-invalidate.test.ts @@ -5,9 +5,14 @@ import { join } from "node:path"; import { invalidateCodexModelsCache } from "../../src/codex/catalog"; import { invalidateCodexModelsCacheWithPermit } from "../../src/codex/catalog/sync"; import { withCatalogWriteSerialization } from "../../src/codex/catalog-write-serialization"; -import { afterCatalogWriteHandleAppServers } from "../../src/codex/app-server-processes"; +import { + collectCodexAppServerCatalogStateForRequest, + resetCodexAppServerCatalogStateCache, + afterCatalogWriteHandleAppServers, +} from "../../src/codex/app-server-processes"; import { refreshCodexModelCatalog } from "../../src/codex/refresh"; import { syncModelsToCodex } from "../../src/codex/sync"; +import { flushConfigDirHardening } from "../../src/config/paths"; import type { OcxConfig } from "../../src/types"; import { removeTreeWithRetry } from "../helpers/remove-tree"; @@ -32,7 +37,9 @@ describe("invalidateCodexModelsCache write gate (#476 / #518)", () => { process.env.OPENCODEX_HOME = opencodexHome; }); - afterEach(() => { + afterEach(async () => { + await flushConfigDirHardening(opencodexHome); + resetCodexAppServerCatalogStateCache(); if (previousCodexHome === undefined) delete process.env.CODEX_HOME; else process.env.CODEX_HOME = previousCodexHome; if (previousOpenCodexHome === undefined) delete process.env.OPENCODEX_HOME; @@ -298,4 +305,55 @@ describe("invalidateCodexModelsCache write gate (#476 / #518)", () => { expect(errors).toEqual([]); expect(logs).toEqual([]); }); + test("sync invalidates a cached not-running observation before a catalog write", async () => { + let snapshots: Array<{ pid: number; commandLine: string }> = []; + const io = { + platform: "win32" as const, + now: () => 3_000, + listSnapshotsAsync: async () => snapshots, + readStartMsBatchAsync: async (pids: readonly number[]) => new Map(pids.map(pid => [pid, 1_000])), + catalogMtimeMs: () => 2_000, + }; + resetCodexAppServerCatalogStateCache(); + expect((await collectCodexAppServerCatalogStateForRequest(io)).state).toBe("not_running"); + snapshots = [{ pid: 42, commandLine: "codex app-server" }]; + // Prove the real request cache is warm; injected synchronous IO bypasses it. + expect((await collectCodexAppServerCatalogStateForRequest(io)).state).toBe("not_running"); + + writeFileSync(join(codexHome, "opencodex-catalog.json"), JSON.stringify({ models: [{ slug: "gpt-5.5" }] })); + expect(invalidateCodexModelsCache({ allowWhenDesiredDisabled: true })).toBe(true); + + expect((await collectCodexAppServerCatalogStateForRequest(io)).state).toBe("stale"); + }); + + test("sync invalidates cached process state even when catalog refresh is a no-op", async () => { + let snapshots: Array<{ pid: number; commandLine: string }> = []; + const io = { + platform: "win32" as const, + now: () => 3_000, + listSnapshotsAsync: async () => snapshots, + readStartMsBatchAsync: async (pids: readonly number[]) => new Map(pids.map(pid => [pid, 1_000])), + catalogMtimeMs: () => 2_000, + }; + resetCodexAppServerCatalogStateCache(); + expect((await collectCodexAppServerCatalogStateForRequest(io)).state).toBe("not_running"); + snapshots = [{ pid: 42, commandLine: "codex app-server" }]; + // Prove the real request cache is warm; injected synchronous IO bypasses it. + expect((await collectCodexAppServerCatalogStateForRequest(io)).state).toBe("not_running"); + + await syncModelsToCodex(19107, emptyConfig, null, { + refreshCodexModelCatalog: async () => ({ + added: 0, + path: join(codexHome, "opencodex-catalog.json"), + catalogExists: false, + catalogWritten: false, + cacheSynced: false, + comboOmissions: [], + }), + injectCodexConfig: async () => ({ success: true, message: "injected" }), + currentExternalCodexModelProvider: () => null, + }); + + expect((await collectCodexAppServerCatalogStateForRequest(io)).state).toBe("stale"); + }); }); From f8dc526e447988fcb8bbae2e1d0af503c93d6e48 Mon Sep 17 00:00:00 2001 From: t Date: Wed, 9 Sep 2026 02:40:44 +0900 Subject: [PATCH 4/7] fix(web-search): stop inactivity timing after terminal events Carried from #3979 (author yansigit) for maintainer-side CI and sequential integration. Co-authored-by: yansigit <44089734+yansigit@users.noreply.github.com> --- src/web-search/progress-stream.ts | 4 ++++ tests/web-search/web-search-progress-stream.test.ts | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/web-search/progress-stream.ts b/src/web-search/progress-stream.ts index f51a55efc6..e3889eb5bc 100644 --- a/src/web-search/progress-stream.ts +++ b/src/web-search/progress-stream.ts @@ -303,6 +303,10 @@ export async function* parseStreamWithProgress( } if (event.type === "done" || event.type === "incomplete") { heldTerminal = event; + // Response-byte inactivity ends once the adapter has produced a terminal event. + // From here the separate post-terminal drain guard owns the bounded wait for + // iterator cleanup, so leaving the inactivity timer armed creates a false timeout. + clearInactivity(); continue; } await handoff.deliver(event); diff --git a/tests/web-search/web-search-progress-stream.test.ts b/tests/web-search/web-search-progress-stream.test.ts index ddb325b2fb..d36bb42594 100644 --- a/tests/web-search/web-search-progress-stream.test.ts +++ b/tests/web-search/web-search-progress-stream.test.ts @@ -215,10 +215,13 @@ describe("web-search streamed-body progress collector", () => { let returned = false; const parser: ParseStream = async function* () { yield { type: "done", usage: { inputTokens: 1, outputTokens: 2 } }; - await sleep(20); + await sleep(30); returned = true; }; - const iterator = parseStreamWithProgress(new Response(chunkStream([])), parser, { inactivityTimeoutMs: 100 }); + const iterator = parseStreamWithProgress(new Response(chunkStream([])), parser, { + inactivityTimeoutMs: 10, + postTerminalDrainTimeoutMs: 100, + }); const next = await iterator.next(); expect(returned).toBe(true); expect(next.value).toEqual({ type: "done", usage: { inputTokens: 1, outputTokens: 2 } }); From f5b4a8f580299c8efa37793cfac25a3d0752ebe9 Mon Sep 17 00:00:00 2001 From: t Date: Wed, 9 Sep 2026 02:40:44 +0900 Subject: [PATCH 5/7] fix(responses): strip Muse web_search fields on direct Meta Carried from #3964 (author ildunari) for maintainer-side CI and sequential integration. Co-authored-by: ildunari <95185577+ildunari@users.noreply.github.com> --- ...se-spark-meta-search-content-types-400.jpg | Bin 0 -> 61033 bytes src/adapters/openai-responses.ts | 14 +++--- .../muse-spark-web-search-compat.test.ts | 40 ++++++++++++++++-- 3 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 .github/pr-assets/muse-spark-meta-search-content-types-400.jpg diff --git a/.github/pr-assets/muse-spark-meta-search-content-types-400.jpg b/.github/pr-assets/muse-spark-meta-search-content-types-400.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d18dd98dab30eae3b04688f587440bd1942c35d5 GIT binary patch literal 61033 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 { return { @@ -219,7 +225,14 @@ describe("#2617/#3378 Muse Spark web_search compatibility", () => { } }); - test("direct Meta preserves its web_search fields at both tool positions", () => { + /** + * #3456 scoped the guard to OpenCode Zen/Go URLs on the assumption that + * `https://api.meta.ai/v1` accepted Codex's extra web_search fields. Direct + * Meta still 400s `tools[].search_content_types` on ordinary `web_search` + * (live 2026-09-07 against muse-spark-1.3-contributor). Same model-id set, + * same field drop, same preview preservation. + */ + test("direct Meta strips rejected web_search fields at both tool positions", () => { const body = buildForProvider(META_PROVIDER, "muse-spark-1.3-contributor", { tools: [webSearchTool()], input: [{ type: "additional_tools", tools: [webSearchTool()] }], @@ -228,8 +241,29 @@ describe("#2617/#3378 Muse Spark web_search compatibility", () => { const item = (body.input as Array>)[0]!; const nested = (item.tools as Array>)[0]!; for (const declaration of [tool, nested]) { - expect(declaration.search_content_types).toEqual(["text", "image"]); - expect(declaration.indexed_web_access).toBe(true); + expect(declaration.type).toBe("web_search"); + expect(declaration.search_context_size).toBe("medium"); + expect(Object.hasOwn(declaration, "search_content_types")).toBe(false); + expect(Object.hasOwn(declaration, "indexed_web_access")).toBe(false); } }); + + test("direct Meta keeps the field on web_search_preview", () => { + const body = buildForProvider(META_PROVIDER, "muse-spark-1.3-contributor", { + tools: [{ ...webSearchTool(), type: "web_search_preview" }], + }); + const tool = toolsOf(body)[0]!; + expect(tool.type).toBe("web_search_preview"); + expect(tool.search_content_types).toEqual(["text", "image"]); + expect(tool.indexed_web_access).toBe(true); + }); + + test("split Meta baseUrl and responsesPath derives the same strict destination", () => { + const body = buildForProvider(META_PATH_PROVIDER, "muse-spark-1.3-contributor", { + tools: [webSearchTool()], + }); + const tool = toolsOf(body)[0]!; + expect(Object.hasOwn(tool, "search_content_types")).toBe(false); + expect(Object.hasOwn(tool, "indexed_web_access")).toBe(false); + }); }); From 613a6102bf07835c7cbf6e07d47ae190fd8554cb Mon Sep 17 00:00:00 2001 From: t Date: Wed, 9 Sep 2026 02:40:44 +0900 Subject: [PATCH 6/7] fix: preserve combo capabilities and skip referenced archives Carried from #3863 (author x3M3x) for maintainer-side CI and sequential integration. Co-authored-by: x3M3x <98298256+x3M3x@users.noreply.github.com> --- .../3863-storage-skip-referenced.png | Bin 0 -> 158186 bytes gui/src/i18n/de.ts | 1 + gui/src/i18n/en.ts | 1 + gui/src/i18n/fr.ts | 1 + gui/src/i18n/ja.ts | 1 + gui/src/i18n/ko.ts | 1 + gui/src/i18n/ru.ts | 1 + gui/src/i18n/tr.ts | 1 + gui/src/i18n/zh-TW.ts | 1 + gui/src/i18n/zh.ts | 1 + gui/src/pages/Storage.tsx | 10 +- src/codex/catalog/provider-fetch.ts | 29 +++-- src/server/management/logs-usage-routes.ts | 1 + src/storage/cleanup.ts | 122 +++++++++++------- tests/codex-integration/codex-catalog.test.ts | 52 ++++++++ tests/storage/storage-cleanup.test.ts | 49 ++++++- 16 files changed, 208 insertions(+), 64 deletions(-) create mode 100644 .github/pr-assets/3863-storage-skip-referenced.png diff --git a/.github/pr-assets/3863-storage-skip-referenced.png b/.github/pr-assets/3863-storage-skip-referenced.png new file mode 100644 index 0000000000000000000000000000000000000000..0fcc6370a442c05bf3113143f72fb5b7f5ba225f GIT binary patch literal 158186 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 TJ>1vHB7XW6<9>pd_dT(OzTR`Qlv}Jm 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

FyaEdl+*Uv3N_jp{?XmpP_&8f|dDVZfgtr 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 = { "storage.cleanup.confirmPermanent": "Dauerhaft löschen", "storage.cleanup.doneQuarantine": "{count} Datei(en) in Quarantäne ({size}).", "storage.cleanup.donePermanent": "{count} Datei(en) dauerhaft gelöscht ({size}).", + "storage.cleanup.skippedReferenced": "{count} referenzierte Datei(en) übersprungen.", "storage.cleanup.previewFailed": "Vorschau fehlgeschlagen.", "storage.cleanup.cleanupFailed": "Bereinigung fehlgeschlagen.", "storage.cleanup.err.codex_busy": "Codex verwendet state.sqlite — beende Codex und versuche es erneut.", diff --git a/gui/src/i18n/en.ts b/gui/src/i18n/en.ts index 53d940d7e6..0cf7469f56 100644 --- a/gui/src/i18n/en.ts +++ b/gui/src/i18n/en.ts @@ -1010,6 +1010,7 @@ export const en = { "storage.cleanup.confirmPermanent": "Delete permanently", "storage.cleanup.doneQuarantine": "Quarantined {count} file(s) ({size}).", "storage.cleanup.donePermanent": "Permanently deleted {count} file(s) ({size}).", + "storage.cleanup.skippedReferenced": "Skipped {count} referenced file(s).", "storage.cleanup.previewFailed": "Preview failed.", "storage.cleanup.cleanupFailed": "Cleanup failed.", "storage.cleanup.err.codex_busy": "Codex is using state.sqlite — try again after quitting Codex.", diff --git a/gui/src/i18n/fr.ts b/gui/src/i18n/fr.ts index 7afb44ab2c..576c3b7f23 100644 --- a/gui/src/i18n/fr.ts +++ b/gui/src/i18n/fr.ts @@ -986,6 +986,7 @@ export const fr: Record = { "storage.cleanup.confirmPermanent": "Supprimer définitivement", "storage.cleanup.doneQuarantine": "{count} fichier(s) mis en quarantaine ({size}).", "storage.cleanup.donePermanent": "{count} fichier(s) supprimé(s) définitivement ({size}).", + "storage.cleanup.skippedReferenced": "{count} fichier(s) référencé(s) ignoré(s).", "storage.cleanup.previewFailed": "Échec de l’aperçu.", "storage.cleanup.cleanupFailed": "Échec du nettoyage.", "storage.cleanup.err.codex_busy": "Codex utilise state.sqlite — réessayez après avoir quitté Codex.", diff --git a/gui/src/i18n/ja.ts b/gui/src/i18n/ja.ts index 75095da332..1e01aea545 100644 --- a/gui/src/i18n/ja.ts +++ b/gui/src/i18n/ja.ts @@ -925,6 +925,7 @@ export const ja: Record = { "storage.cleanup.confirmPermanent": "完全に削除", "storage.cleanup.doneQuarantine": "{count} 件を隔離しました({size})。", "storage.cleanup.donePermanent": "{count} 件を完全削除しました({size})。", + "storage.cleanup.skippedReferenced": "参照されている {count} 件をスキップしました。", "storage.cleanup.previewFailed": "プレビューに失敗しました。", "storage.cleanup.cleanupFailed": "クリーンアップに失敗しました。", "storage.cleanup.err.codex_busy": "Codex が state.sqlite を使用中です — Codex を終了して再試行してください。", diff --git a/gui/src/i18n/ko.ts b/gui/src/i18n/ko.ts index 5ae812e9e8..f1d20bf65e 100644 --- a/gui/src/i18n/ko.ts +++ b/gui/src/i18n/ko.ts @@ -1816,6 +1816,7 @@ export const ko: Record = { "storage.cleanup.confirmPermanent": "영구 삭제", "storage.cleanup.doneQuarantine": "파일 {count}개를 격리했습니다({size}).", "storage.cleanup.donePermanent": "파일 {count}개를 영구 삭제했습니다({size}).", + "storage.cleanup.skippedReferenced": "참조된 파일 {count}개를 건너뛰었습니다.", "storage.cleanup.previewFailed": "미리보기에 실패했습니다.", "storage.cleanup.cleanupFailed": "정리에 실패했습니다.", "storage.cleanup.err.codex_busy": "Codex가 state.sqlite를 사용 중입니다 — Codex를 종료한 뒤 다시 시도하세요.", diff --git a/gui/src/i18n/ru.ts b/gui/src/i18n/ru.ts index 2900abb6f3..c583bccb99 100644 --- a/gui/src/i18n/ru.ts +++ b/gui/src/i18n/ru.ts @@ -980,6 +980,7 @@ export const ru: Record = { "storage.cleanup.confirmPermanent": "Удалить навсегда", "storage.cleanup.doneQuarantine": "В карантин: {count} файл(ов) ({size}).", "storage.cleanup.donePermanent": "Удалено навсегда: {count} файл(ов) ({size}).", + "storage.cleanup.skippedReferenced": "Пропущено файлов, на которые ссылается история: {count}.", "storage.cleanup.previewFailed": "Не удалось выполнить предпросмотр.", "storage.cleanup.cleanupFailed": "Не удалось выполнить очистку.", "storage.cleanup.err.codex_busy": "Codex использует state.sqlite — закройте Codex и повторите попытку.", diff --git a/gui/src/i18n/tr.ts b/gui/src/i18n/tr.ts index f551a97d43..ca39260677 100644 --- a/gui/src/i18n/tr.ts +++ b/gui/src/i18n/tr.ts @@ -999,6 +999,7 @@ export const tr: Record = { "storage.cleanup.confirmPermanent": "Kalıcı Olarak Sil", "storage.cleanup.doneQuarantine": "{count} dosya karantinaya alındı ({size}).", "storage.cleanup.donePermanent": "{count} dosya kalıcı olarak silindi ({size}).", + "storage.cleanup.skippedReferenced": "Başvurulan {count} dosya atlandı.", "storage.cleanup.previewFailed": "Önizleme başarısız oldu.", "storage.cleanup.cleanupFailed": "Temizleme başarısız oldu.", "storage.cleanup.err.codex_busy": "Codex state.sqlite dosyasını kullanıyor.", diff --git a/gui/src/i18n/zh-TW.ts b/gui/src/i18n/zh-TW.ts index ae0ee0517b..6462f6c4b5 100644 --- a/gui/src/i18n/zh-TW.ts +++ b/gui/src/i18n/zh-TW.ts @@ -788,6 +788,7 @@ export const zhTW: Record = { "storage.cleanup.confirmPermanent": "永久刪除", "storage.cleanup.doneQuarantine": "已隔離 {count} 個檔案({size})。", "storage.cleanup.donePermanent": "已永久刪除 {count} 個檔案({size})。", + "storage.cleanup.skippedReferenced": "已略過 {count} 個被參照的檔案。", "storage.cleanup.previewFailed": "預覽失敗。", "storage.cleanup.cleanupFailed": "清理失敗。", "storage.cleanup.err.codex_busy": "Codex 正在使用 state.sqlite — 請退出 Codex 後重試。", diff --git a/gui/src/i18n/zh.ts b/gui/src/i18n/zh.ts index ca92aaeafc..685227abc0 100644 --- a/gui/src/i18n/zh.ts +++ b/gui/src/i18n/zh.ts @@ -1797,6 +1797,7 @@ export const zh: Record = { "storage.cleanup.confirmPermanent": "永久删除", "storage.cleanup.doneQuarantine": "已隔离 {count} 个文件({size})。", "storage.cleanup.donePermanent": "已永久删除 {count} 个文件({size})。", + "storage.cleanup.skippedReferenced": "已跳过 {count} 个被引用的文件。", "storage.cleanup.previewFailed": "预览失败。", "storage.cleanup.cleanupFailed": "清理失败。", "storage.cleanup.err.codex_busy": "Codex 正在使用 state.sqlite — 请退出 Codex 后重试。", diff --git a/gui/src/pages/Storage.tsx b/gui/src/pages/Storage.tsx index fceb45fe04..751e609de1 100644 --- a/gui/src/pages/Storage.tsx +++ b/gui/src/pages/Storage.tsx @@ -29,6 +29,7 @@ interface CleanupResult { trashDir?: string; error?: string; message?: string; + skippedReferencedPaths?: string[]; } interface TrashEntry { @@ -222,11 +223,12 @@ function ArchivedCleanupPanel({ throw new Error(mapCleanupError(json.error, json.message, json.trashDir)); } closeConfirm(true); - setStatus( - permanent + const complete = permanent ? t("storage.cleanup.donePermanent", { count: String(json.count), size: formatBytes(json.bytes, locale) }) - : t("storage.cleanup.doneQuarantine", { count: String(json.count), size: formatBytes(json.bytes, locale) }), - ); + : t("storage.cleanup.doneQuarantine", { count: String(json.count), size: formatBytes(json.bytes, locale) }); + setStatus(json.skippedReferencedPaths?.length + ? `${complete} ${t("storage.cleanup.skippedReferenced", { count: String(json.skippedReferencedPaths.length) })}` + : complete); onDone(); } catch (e) { // Keep the dialog open (except stale_preview) so the failure is visible. diff --git a/src/codex/catalog/provider-fetch.ts b/src/codex/catalog/provider-fetch.ts index dab45af38e..1e361ad7bc 100644 --- a/src/codex/catalog/provider-fetch.ts +++ b/src/codex/catalog/provider-fetch.ts @@ -954,16 +954,21 @@ function comboMemberVendorMetadata(provider: string, modelId: string): ModelMeta */ function vendorMetadataComboFallback(target: { provider: string; model: string }): ComboCatalogMemberFallback | undefined { const metadataProvider = resolveMetadataProvider(target.provider); - const metadata = metadataProvider ? comboMemberVendorMetadata(metadataProvider, target.model) : undefined; + // Custom OpenAI-compatible routes commonly retain the canonical OpenAI model id + // while using a provider name that has no metadata alias. Reuse only its effort + // ladder below; context/modality rows remain provider-owned. + const metadata = metadataProvider + ? comboMemberVendorMetadata(metadataProvider, target.model) + : comboMemberVendorMetadata("openai", target.model); if (!metadata) return undefined; return { - ...(typeof metadata.contextWindow === "number" && metadata.contextWindow > 0 + ...(metadataProvider && typeof metadata.contextWindow === "number" && metadata.contextWindow > 0 ? { contextWindow: metadata.contextWindow } : {}), - ...(typeof metadata.maxTokens === "number" && metadata.maxTokens > 0 + ...(metadataProvider && typeof metadata.maxTokens === "number" && metadata.maxTokens > 0 ? { maxOutputTokens: metadata.maxTokens } : {}), - ...(Array.isArray(metadata.input) && metadata.input.length > 0 + ...(metadataProvider && Array.isArray(metadata.input) && metadata.input.length > 0 ? { inputModalities: [...metadata.input] } : {}), ...(metadata.reasoning === true ? { reasoningEfforts: [...ROUTED_COMBO_MEMBER_REASONING_EFFORTS] } : {}), @@ -1040,15 +1045,21 @@ export function resolveComboCatalogMember( && typeof existing.contextWindow === "number" && existing.contextWindow > 0 ) { - const capped = applyProviderContextCap(existing.contextWindow, contextCap); + // Live discovery can explicitly say text-only even when configured routing + // supplies a vision sidecar. Apply the same provider hints used for thin + // rows before deriving a combo from this complete row. + const hinted = prov && isModelVisionSidecarConsumer(prov, existing.id) + ? applyProviderConfigHints(target.provider, prov, existing, contextCap, metadataModelIdCaseFold) + : existing; + const capped = applyProviderContextCap(hinted.contextWindow, contextCap); if (capped === undefined || capped === existing.contextWindow) { - return withFallbackMetadata(existing); + return withFallbackMetadata(hinted); } - const maxInput = typeof existing.maxInputTokens === "number" && existing.maxInputTokens > 0 - ? Math.min(existing.maxInputTokens, capped) + const maxInput = typeof hinted.maxInputTokens === "number" && hinted.maxInputTokens > 0 + ? Math.min(hinted.maxInputTokens, capped) : Math.min(fallback?.maxInputTokens ?? capped, capped); return withFallbackMetadata({ - ...existing, + ...hinted, contextWindow: capped, maxInputTokens: maxInput, contextCap, diff --git a/src/server/management/logs-usage-routes.ts b/src/server/management/logs-usage-routes.ts index 0177e56776..a66ff4b79c 100644 --- a/src/server/management/logs-usage-routes.ts +++ b/src/server/management/logs-usage-routes.ts @@ -425,6 +425,7 @@ export async function handleLogsUsageRoutes(ctx: ManagementContext): Promise t.id); - const idSet = new Set(ids); - - // Paginated history keeps durable projections tied to the rollout — refuse cleanup. - if (threads.some(t => (t.history_mode ?? "").toLowerCase() === "paginated")) { - return true; - } - - // Spawn edges that cross the delete boundary keep history reachable. - if (tableExists(db, "thread_spawn_edges")) { - for (const chunk of chunkIds(ids, SQLITE_ID_CHUNK)) { +): { safe: ThreadSnapshot[]; skipped: ThreadSnapshot[] } { + let safe = threads.filter(t => (t.history_mode ?? "").toLowerCase() !== "paginated"); + const skipped = new Map(threads + .filter(t => (t.history_mode ?? "").toLowerCase() === "paginated") + .map(t => [t.id, t])); + + while (safe.length > 0) { + const idSet = new Set(safe.map(t => t.id)); + const unsafeIds = new Set(); + + // Spawn edges that cross the delete boundary keep history reachable. + if (tableExists(db, "thread_spawn_edges")) { + for (const chunk of chunkIds([...idSet], SQLITE_ID_CHUNK)) { const placeholders = chunk.map(() => "?").join(","); const edges = db.query<{ parent_thread_id: string; child_thread_id: string }, string[]>( `SELECT parent_thread_id, child_thread_id FROM thread_spawn_edges WHERE parent_thread_id IN (${placeholders}) OR child_thread_id IN (${placeholders})`, ).all(...chunk, ...chunk); for (const edge of edges) { - if (!idSet.has(edge.parent_thread_id) || !idSet.has(edge.child_thread_id)) { - return true; + if (!idSet.has(edge.parent_thread_id)) unsafeIds.add(edge.child_thread_id); + if (!idSet.has(edge.child_thread_id)) unsafeIds.add(edge.parent_thread_id); + } + } + } + + // Other threads that list one of ours as forked_from / parent (when columns exist). + for (const column of ["forked_from_id", "parent_thread_id", "source_thread_id"] as const) { + if (!columnExists(db, "threads", column)) continue; + for (const chunk of chunkIds([...idSet], SQLITE_ID_CHUNK * 2)) { + const placeholders = chunk.map(() => "?").join(","); + const rows = db.query<{ id: string; ref: string }, string[]>( + `SELECT id, ${column} AS ref FROM threads WHERE ${column} IN (${placeholders})`, + ).all(...chunk); + for (const row of rows) { + if (!idSet.has(row.id)) unsafeIds.add(row.ref); } } } - } - // Other threads that list one of ours as forked_from / parent (when columns exist). - for (const column of ["forked_from_id", "parent_thread_id", "source_thread_id"] as const) { - if (!columnExists(db, "threads", column)) continue; - for (const chunk of chunkIds(ids, SQLITE_ID_CHUNK * 2)) { - const placeholders = chunk.map(() => "?").join(","); - const rows = db.query<{ id: string }, string[]>( - `SELECT id FROM threads WHERE ${column} IN (${placeholders})`, - ).all(...chunk); - if (rows.some(r => !idSet.has(r.id))) return true; + if (unsafeIds.size === 0) break; + for (const thread of safe) { + if (unsafeIds.has(thread.id)) skipped.set(thread.id, thread); } + safe = safe.filter(thread => !unsafeIds.has(thread.id)); } - return false; + return { safe, skipped: [...skipped.values()] }; } function tableExists(db: Database, name: string): boolean { @@ -778,6 +786,7 @@ function deleteThreadsAndDependents(db: Database, threadIds: string[]): void { interface ReconcileOk { ok: true; threads: ThreadSnapshot[]; + skipped: ThreadSnapshot[]; } interface ReconcileErr { ok: false; @@ -1463,14 +1472,14 @@ function withWritableDb( } } -/** Load matching archived threads and refuse referenced history — no deletes yet. */ +/** Load matching archived threads and retain referenced history — no deletes yet. */ function loadThreadsForCleanup( stateDbPath: string, candidates: ArchivedCandidate[], codexHome: string, busyTimeoutMs: number, ): ReconcileOk | ReconcileErr { - if (!stateDbPath || !existsSync(stateDbPath)) return { ok: true, threads: [] }; + if (!stateDbPath || !existsSync(stateDbPath)) return { ok: true, threads: [], skipped: [] }; let db: Database | undefined; try { db = openDbWritable(stateDbPath, busyTimeoutMs); @@ -1478,10 +1487,8 @@ function loadThreadsForCleanup( if (threads.some(t => Number(t.is_pinned ?? 0) === 1)) { return { ok: false, error: "pinned_thread" }; } - if (findReferencedHistory(db, threads)) { - return { ok: false, error: "referenced_history" }; - } - return { ok: true, threads }; + const filtered = filterReferencedHistory(db, threads); + return { ok: true, threads: filtered.safe, skipped: filtered.skipped }; } catch (error) { return { ok: false, error: mapDbError(error) }; } finally { @@ -1504,7 +1511,7 @@ function reconcileDeletedThreads( stageDir: string, hooks?: ReconcileTestHooks, ): ReconcileOk | ReconcileErr { - if (!paths.state || !existsSync(paths.state)) return { ok: true, threads: [] }; + if (!paths.state || !existsSync(paths.state)) return { ok: true, threads: [], skipped: [] }; if (hooks?.beforeReconcileLock) hooks.beforeReconcileLock(); @@ -1546,7 +1553,7 @@ function reconcileDeletedThreads( stateDb.exec("ROLLBACK"); return { ok: false, error: "pinned_thread" }; } - if (findReferencedHistory(stateDb, threads)) { + if (filterReferencedHistory(stateDb, threads).safe.length !== threads.length) { stateDb.exec("ROLLBACK"); return { ok: false, error: "referenced_history" }; } @@ -1582,7 +1589,7 @@ function reconcileDeletedThreads( if (hooks?.afterSatelliteMutations) hooks.afterSatelliteMutations(); // Re-check under the same lock before committing state deletes. - if (findReferencedHistory(stateDb, threads)) { + if (filterReferencedHistory(stateDb, threads).safe.length !== threads.length) { stateDb.exec("ROLLBACK"); return failWithRestore("referenced_history"); } @@ -1590,7 +1597,7 @@ function reconcileDeletedThreads( if (hooks?.failBeforeStateCommit) throw new Error("test_fail_before_state_commit"); stateDb.exec("COMMIT"); // Keep satellite-backup.json for quarantine restore; permanent purge removes the stage. - return { ok: true, threads }; + return { ok: true, threads, skipped: [] }; } catch (error) { if (satelliteLocks) rollbackAllSatelliteLocks(satelliteLocks); throw error; @@ -1895,7 +1902,30 @@ export function executeArchivedCleanup(options: ExecuteCleanupOptions): CleanupR const normalized = normalizeArchivedRolloutPath(thread.rollout_path, codexHome); if (normalized) threadByRelPath.set(normalized, thread); } - const manifestEntries: CleanupManifestEntry[] = preview.candidates.map(candidate => { + const skippedReferencedPaths = loaded.skipped + .map(thread => normalizeArchivedRolloutPath(thread.rollout_path, codexHome)) + .filter((path): path is string => path !== null); + const matchedPaths = new Set([ + ...threadByRelPath.keys(), + ...skippedReferencedPaths, + ]); + const candidates = preview.candidates.filter(candidate => { + return !matchedPaths.has(candidate.relPath) || threadByRelPath.has(candidate.relPath); + }); + if (candidates.length === 0) { + removeStageIfEmpty(stageDir, []); + removeEmptyTrashRoot(codexHome); + return { + ok: true, + mode, + percent, + count: 0, + bytes: 0, + removedPaths: [], + ...(skippedReferencedPaths.length ? { skippedReferencedPaths } : {}), + }; + } + const manifestEntries: CleanupManifestEntry[] = candidates.map(candidate => { const thread = threadByRelPath.get(candidate.relPath); return { relPath: candidate.relPath, @@ -1936,7 +1966,7 @@ export function executeArchivedCleanup(options: ExecuteCleanupOptions): CleanupR return fail(mode, percent, "fs_failed"); } - const stageResult = stageCandidates(codexHome, preview.candidates, stageDir, { + const stageResult = stageCandidates(codexHome, candidates, stageDir, { blockDestBasenames: blockStageDest.size > 0 ? blockStageDest : undefined, }); if (!stageResult.ok) { @@ -1956,7 +1986,7 @@ export function executeArchivedCleanup(options: ExecuteCleanupOptions): CleanupR const deleted = reconcileDeletedThreads( paths, - preview.candidates, + candidates, codexHome, busyTimeoutMs, stageDir, @@ -1973,8 +2003,8 @@ export function executeArchivedCleanup(options: ExecuteCleanupOptions): CleanupR return fail(mode, percent, deleted.error, keepTrash ? { trashDir } : undefined); } - const removedPaths = preview.candidates.map(c => c.relPath); - const bytes = preview.candidates.reduce((sum, c) => sum + c.bytes, 0); + const removedPaths = candidates.map(c => c.relPath); + const bytes = candidates.reduce((sum, c) => sum + c.bytes, 0); if (mode === "quarantine") { return { @@ -1985,6 +2015,7 @@ export function executeArchivedCleanup(options: ExecuteCleanupOptions): CleanupR bytes, trashDir, removedPaths, + ...(skippedReferencedPaths.length ? { skippedReferencedPaths } : {}), }; } @@ -2038,6 +2069,7 @@ export function executeArchivedCleanup(options: ExecuteCleanupOptions): CleanupR count: removedPaths.length, bytes, removedPaths, + ...(skippedReferencedPaths.length ? { skippedReferencedPaths } : {}), }; } diff --git a/tests/codex-integration/codex-catalog.test.ts b/tests/codex-integration/codex-catalog.test.ts index bb3c8a880f..38f362c81b 100644 --- a/tests/codex-integration/codex-catalog.test.ts +++ b/tests/codex-integration/codex-catalog.test.ts @@ -1640,6 +1640,43 @@ describe("combo catalog capability intersection", () => { )).not.toHaveProperty("reasoningEfforts"); }); + test("resolveComboCatalogMember restores canonical OpenAI effort levels through generic routes", () => { + const providers = new Map([["azu-lab2", { + adapter: "openai-chat" as const, + baseUrl: "https://azu-lab2.example/v1", + }]]); + const member = resolveComboCatalogMember( + { provider: "azu-lab2", model: "gpt-5.6-terra" }, + new Map([["azu-lab2/gpt-5.6-terra", { + provider: "azu-lab2", + id: "gpt-5.6-terra", + contextWindow: 373_000, + inputModalities: ["text", "image"], + }]]), + providers, + ); + expect(member?.reasoningEfforts).toEqual(["low", "medium", "high", "xhigh", "max"]); + }); + + test("resolveComboCatalogMember applies sidecar hints to complete discovery rows", () => { + const providers = new Map([["sidecar", { + adapter: "openai-chat" as const, + baseUrl: "https://sidecar.example/v1", + modelInputModalities: { planner: ["text"] }, + }]]); + const member = resolveComboCatalogMember( + { provider: "sidecar", model: "planner" }, + new Map([["sidecar/planner", { + provider: "sidecar", + id: "planner", + contextWindow: 200_000, + inputModalities: ["text"], + }]]), + providers, + ); + expect(member?.inputModalities).toEqual(["text", "image"]); + }); + // Sniper for the OUTPUT-vs-INPUT mapping defect carried over from PR #3332. The test // above uses toMatchObject, which only inspects the keys it names, so without this a // regression that puts the OUTPUT ceiling into the INPUT slot passes green. @@ -7085,6 +7122,21 @@ describe("Codex reasoning-effort capability clamp", () => { }); }); +test("provider-configured cap applies to discovered window and does not get overwritten by discovery", () => { + const resolved = applyProviderConfigHints("prov", { + adapter: "openai-chat", + baseUrl: "https://prov.test/v1", + modelContextWindows: { "disco-model": 100_000 }, + }, { + provider: "prov", + id: "disco-model", + contextWindow: 200_000, + }, 150_000); + + expect(resolved.contextWindow).toBe(100_000); + expect(resolved.contextCap).toBe(150_000); +}); + describe("auto_review_model configuration (#1225)", () => { test("applyAutoReviewModelOverride sets auto_review_model_override across all entries", () => { const { applyAutoReviewModelOverride } = require("../../src/codex/catalog/sync"); diff --git a/tests/storage/storage-cleanup.test.ts b/tests/storage/storage-cleanup.test.ts index 31cbcd6d21..8e4564e0ef 100644 --- a/tests/storage/storage-cleanup.test.ts +++ b/tests/storage/storage-cleanup.test.ts @@ -586,23 +586,60 @@ describe("executeArchivedCleanup", () => { db.close(); }, { timeout: STORE_BUDGET_MS }); - test("rejects candidates still referenced by a live spawn edge", () => { + test("skips candidates still referenced by a live spawn edge", () => { home = buildHome({ withSpawnEdges: true }); // Edge told→tmid; deleting only oldest (told) leaves tmid outside the set. const result = runWithDigest(34, "quarantine", home); - expect(result.ok).toBe(false); - expect(result.error).toBe("referenced_history"); + expect(result.ok).toBe(true); + expect(result.count).toBe(0); + expect(result.skippedReferencedPaths).toEqual(["archived_sessions/rollout-old.jsonl"]); expect(existsSync(join(home, "archived_sessions", "rollout-old.jsonl"))).toBe(true); + // Stage dir should not remain when no candidates are selected. + expect(existsSync(join(home, ".trash"))).toBe(false); }); - test("rejects paginated history_mode threads", () => { + test("skips paginated history_mode threads", () => { home = buildHome(); const db = new Database(join(home, "state_5.sqlite")); db.exec(`UPDATE threads SET history_mode='paginated' WHERE id='told'`); db.close(); const result = runWithDigest(50, "quarantine", home); - expect(result.ok).toBe(false); - expect(result.error).toBe("referenced_history"); + expect(result.ok).toBe(true); + expect(result.count).toBe(0); + expect(result.skippedReferencedPaths).toEqual(["archived_sessions/rollout-old.jsonl"]); + // Ensure the trash root has been removed when nothing was staged. + expect(existsSync(join(home, ".trash"))).toBe(false); + }); + + test("deletes safe candidates while skipping referenced history", () => { + home = buildHome({ withSpawnEdges: true }); + const exactPaths = [ + "archived_sessions/rollout-old.jsonl", + "archived_sessions/rollout-new.jsonl", + ]; + const preview = previewExactArchivedCleanup( + listArchivedCandidates(home).filter(candidate => exactPaths.includes(candidate.relPath)), + home, + ); + const result = executeArchivedCleanup({ + percent: 0, + mode: "quarantine", + digest: preview.digest, + candidateRelPaths: [ + "archived_sessions/rollout-old.jsonl", + "archived_sessions/rollout-new.jsonl", + ], + codexHome: home, + }); + expect(result.ok).toBe(true); + expect(result.removedPaths).toEqual(["archived_sessions/rollout-new.jsonl"]); + expect(result.skippedReferencedPaths).toEqual(["archived_sessions/rollout-old.jsonl"]); + expect(existsSync(join(home, "archived_sessions", "rollout-old.jsonl"))).toBe(true); + expect(existsSync(join(home, "archived_sessions", "rollout-new.jsonl"))).toBe(false); + const db = new Database(join(home, "state_5.sqlite"), { readonly: true }); + expect(db.query("SELECT id FROM threads WHERE id='told'").get()).toBeTruthy(); + expect(db.query("SELECT id FROM threads WHERE id='tnew'").get()).toBeNull(); + db.close(); }); test("quarantine removes both plain and compressed physical files", () => { From 1e32dee6e4e8b9f9bea11dada2f8774a0f4aab73 Mon Sep 17 00:00:00 2001 From: t Date: Wed, 9 Sep 2026 02:40:45 +0900 Subject: [PATCH 7/7] fix(codex): recover ocx1-compacted threads for native replay Carried from #3920 (author cb8010d6) for maintainer-side CI and sequential integration. Closes #3916 Co-authored-by: cb8010d6 <53855466+cb8010d6@users.noreply.github.com> --- .../docs/fr/reference/cli/lifecycle.md | 4 + .../docs/ja/reference/cli/lifecycle.md | 4 + .../docs/ko/reference/cli/lifecycle.md | 4 + .../content/docs/reference/cli/lifecycle.md | 9 + .../docs/ru/reference/cli/lifecycle.md | 4 + .../docs/tr/reference/cli/lifecycle.md | 4 + .../docs/zh-cn/reference/cli/lifecycle.md | 4 + .../docs/zh-tw/reference/cli/lifecycle.md | 4 + scripts/test-layout/layout.json | 1 + src/cli/dispatch.ts | 2 + src/cli/help.ts | 2 + src/cli/index.ts | 25 +- src/cli/registry.ts | 4 +- src/codex/ocx-compaction-history.ts | 226 ++++++++++++++++++ src/responses/compaction.ts | 4 + .../management/native-integration-routes.ts | 3 +- tests/cli/cli-help.test.ts | 48 +++- tests/cli/cli-restore-back.test.ts | 1 + .../codex-composed-acceptance.test.ts | 6 +- .../history-ocx-compaction-recovery.test.ts | 108 +++++++++ tests/fixtures/test-layout-expected.json | 1 + 21 files changed, 459 insertions(+), 9 deletions(-) create mode 100644 src/codex/ocx-compaction-history.ts create mode 100644 tests/codex-integration/history-ocx-compaction-recovery.test.ts diff --git a/docs-site/src/content/docs/fr/reference/cli/lifecycle.md b/docs-site/src/content/docs/fr/reference/cli/lifecycle.md index 59652bbaef..d87aa4895a 100644 --- a/docs-site/src/content/docs/fr/reference/cli/lifecycle.md +++ b/docs-site/src/content/docs/fr/reference/cli/lifecycle.md @@ -53,6 +53,10 @@ Récupération explicite destinée aux anciennes versions de développement qui Il s'agit d'un réétiquetage large et destructif : chaque fil contenant un message utilisateur et actuellement marqué `opencodex` passe à `openai`, `exec` est normalisé en `cli` et l'indicateur d'événement est activé. L'historique légitime d'un fournisseur dédié est également concerné. Sauvegardez l'état et n'exécutez la commande que si vous souhaitez cette portée complète. +### `ocx recover-history --ocx-compaction --yes` + +Réparez l'historique d'une tâche compactée par un fournisseur routé avant de la reprendre avec Codex natif. La commande sélectionne exactement une tâche par UUID, enregistre d'abord une sauvegarde privée octet par octet, puis convertit uniquement l'état de compaction `ocx1:` propre à OpenCodeX en résumé ordinaire relisible par Codex natif. Le contenu chiffré natif et les autres tâches restent inchangés. Fermez la tâche sélectionnée avant d'exécuter la commande ; toute modification simultanée du rollout interrompt la récupération sans remplacer le fichier. + ### `ocx uninstall` · `ocx remove` Arrête le service et le proxy, supprime le service et le shim Codex, rétablit le fonctionnement natif de Codex, puis supprime la configuration locale d’opencodex uniquement si toutes les étapes de restauration ont réussi. `remove` est un alias de `uninstall`. Le nettoyage de la configuration exige les métadonnées de propriété créées par une installation récente ; les répertoires anciens ou partagés sont conservés. diff --git a/docs-site/src/content/docs/ja/reference/cli/lifecycle.md b/docs-site/src/content/docs/ja/reference/cli/lifecycle.md index b7952b5c28..9f8612a2c6 100644 --- a/docs-site/src/content/docs/ja/reference/cli/lifecycle.md +++ b/docs-site/src/content/docs/ja/reference/cli/lifecycle.md @@ -53,6 +53,10 @@ ocx eject back これは広範囲で破壊的な再ラベル付けです。ユーザーメッセージを持ち、現在 `opencodex` とタグ付けされているすべてのスレッドを `openai` に変更し、`exec` を `cli` に正規化してイベントマーカーを設定します。正当な専用プロバイダー履歴も対象です。状態をバックアップし、この全範囲を意図する場合にのみ実行してください。 +### `ocx recover-history --ocx-compaction --yes` + +ルーティングされたプロバイダーで圧縮されたタスクをネイティブ Codex で再開する前に、その履歴を修復します。このコマンドは UUID で 1 つのタスクだけを選択し、非公開のバイト単位バックアップを保存してから、OpenCodeX 所有の `ocx1:` 圧縮状態だけをネイティブ Codex が再生できる通常の要約に変換します。ネイティブの暗号化コンテンツと他のタスクは変更しません。実行前に対象タスクを閉じてください。処理中に rollout が変更された場合、ファイルを置き換えずに修復を中止します。 + ### `ocx uninstall`・`ocx remove` すべての復元手順が成功した場合にのみ、サービスとプロキシを停止し、サービスと Codex シムを削除し、ネイティブ Codex を復元してから、opencodex ローカル設定を削除します。 `remove` は `uninstall` の別名です。設定のクリーンアップには、新規インストールによって作成された所有権メタデータが必要です。従来のディレクトリまたは共有ディレクトリはそのまま残ります。 diff --git a/docs-site/src/content/docs/ko/reference/cli/lifecycle.md b/docs-site/src/content/docs/ko/reference/cli/lifecycle.md index 796a3d7a12..15a8bfee78 100644 --- a/docs-site/src/content/docs/ko/reference/cli/lifecycle.md +++ b/docs-site/src/content/docs/ko/reference/cli/lifecycle.md @@ -75,6 +75,10 @@ ocx eject back thread를 `openai`로 바꾸고, `exec`를 `cli`로 정규화하며 event marker를 설정합니다. 정상적인 dedicated-provider history도 포함됩니다. 상태를 백업하고 이 전체 범위를 의도한 경우에만 실행하세요. +### `ocx recover-history --ocx-compaction --yes` + +라우팅된 provider를 통해 압축된 작업을 native Codex에서 다시 열기 전에 해당 기록을 복구합니다. 이 명령은 UUID로 정확히 하나의 작업을 선택하고 비공개 바이트 단위 백업을 저장한 뒤, OpenCodeX가 소유한 `ocx1:` 압축 상태만 native Codex가 재생할 수 있는 일반 요약으로 변환합니다. native 암호화 콘텐츠와 다른 작업은 변경하지 않습니다. 실행 전에 선택한 작업을 닫으십시오. 처리 중 rollout이 변경되면 파일을 교체하지 않고 복구를 중단합니다. + ### `ocx uninstall` · `ocx remove` 서비스와 프록시를 중지하고, 서비스와 Codex shim을 제거한 뒤, 기본 Codex를 복원합니다. 그 다음 diff --git a/docs-site/src/content/docs/reference/cli/lifecycle.md b/docs-site/src/content/docs/reference/cli/lifecycle.md index 92253e41f8..13a5b17616 100644 --- a/docs-site/src/content/docs/reference/cli/lifecycle.md +++ b/docs-site/src/content/docs/reference/cli/lifecycle.md @@ -81,6 +81,15 @@ changed to `openai`, `exec` is normalized to `cli`, and the event marker is set. legitimate dedicated-provider history. Back up the state and run it only when that full scope is intended. +### `ocx recover-history --ocx-compaction --yes` + +Repair one thread that was compacted through a routed provider before resuming it through native +Codex. The command reads the exact thread selected by UUID, saves a private byte-for-byte backup, +then converts only OpenCodeX-owned `ocx1:` compaction state into a plain summary that native Codex +can replay. Native encrypted content and other threads are left unchanged. Close the selected +thread before running the command; a concurrent rollout change makes recovery stop without +replacing the file. + ### `ocx uninstall` · `ocx remove` Stop the service and proxy, remove the service and Codex shim, restore native Codex, then remove diff --git a/docs-site/src/content/docs/ru/reference/cli/lifecycle.md b/docs-site/src/content/docs/ru/reference/cli/lifecycle.md index f743f5f468..e72d956bcd 100644 --- a/docs-site/src/content/docs/ru/reference/cli/lifecycle.md +++ b/docs-site/src/content/docs/ru/reference/cli/lifecycle.md @@ -78,6 +78,10 @@ ocx eject back устанавливается. Корректная история выделенного провайдера тоже входит в охват. Сначала сделайте резервную копию и запускайте команду только если нужен весь этот охват. +### `ocx recover-history --ocx-compaction --yes` + +Исправьте историю одной задачи, сжатой через маршрутизируемого провайдера, перед её возобновлением в нативном Codex. Команда выбирает ровно одну задачу по UUID, сначала сохраняет приватную побайтовую резервную копию, а затем преобразует только принадлежащее OpenCodeX состояние сжатия `ocx1:` в обычную сводку, которую может воспроизвести нативный Codex. Нативное зашифрованное содержимое и другие задачи не изменяются. Перед запуском закройте выбранную задачу; если rollout изменится во время обработки, восстановление остановится без замены файла. + ### `ocx uninstall` · `ocx remove` Остановить службу и прокси, удалить службу и Codex shim, восстановить native Codex, а затем diff --git a/docs-site/src/content/docs/tr/reference/cli/lifecycle.md b/docs-site/src/content/docs/tr/reference/cli/lifecycle.md index 6a7a565139..0aa50bfebf 100644 --- a/docs-site/src/content/docs/tr/reference/cli/lifecycle.md +++ b/docs-site/src/content/docs/tr/reference/cli/lifecycle.md @@ -84,6 +84,10 @@ Bu, geniş kapsamlı ve yıkıcı bir yeniden etiketlemedir: kullanıcı iletisi olarak normalleştirilir ve event marker ayarlanır. Geçerli dedicated-provider geçmişi de kapsama dahildir. Durumu yedekleyin ve yalnızca bu kapsamın tamamını istiyorsanız çalıştırın. +### `ocx recover-history --ocx-compaction --yes` + +Yönlendirilmiş bir sağlayıcı üzerinden sıkıştırılmış bir görevi yerel Codex ile sürdürmeden önce geçmişini onarın. Komut UUID ile yalnızca bir görevi seçer, önce özel ve bayt bayt bir yedek kaydeder, ardından yalnızca OpenCodeX'e ait `ocx1:` sıkıştırma durumunu yerel Codex'in yeniden oynatabileceği düz bir özete dönüştürür. Yerel şifreli içerik ve diğer görevler değişmeden kalır. Komutu çalıştırmadan önce seçili görevi kapatın; işlem sırasında rollout değişirse kurtarma dosyayı değiştirmeden durur. + ### `ocx uninstall` · `ocx remove` Servisi ve proxy'yi durdurun, servisi ve Codex dolgusunu kaldırın, yerel Codex'i diff --git a/docs-site/src/content/docs/zh-cn/reference/cli/lifecycle.md b/docs-site/src/content/docs/zh-cn/reference/cli/lifecycle.md index 5977c734de..541485dbf4 100644 --- a/docs-site/src/content/docs/zh-cn/reference/cli/lifecycle.md +++ b/docs-site/src/content/docs/zh-cn/reference/cli/lifecycle.md @@ -53,6 +53,10 @@ ocx eject back 这是范围很广且具有破坏性的重标记:所有包含用户消息且当前标记为 `opencodex` 的线程都会改标为 `openai`,`exec` 会规范化为 `cli`,并设置事件标记。正常的专用提供方历史记录也在范围内。请先备份状态,并且仅在确实需要这一完整范围时执行。 +### `ocx recover-history --ocx-compaction --yes` + +在通过原生 Codex 恢复某个曾由路由提供方压缩的任务前,修复该任务的历史记录。此命令按 UUID 精确选择一个任务,先保存私有的逐字节备份,然后仅将 OpenCodeX 自有的 `ocx1:` 压缩状态转换为原生 Codex 可重放的普通摘要。原生加密内容和其他任务保持不变。运行前请关闭所选任务;如果 rollout 在处理期间发生变化,恢复会停止且不会替换原文件。 + ### `ocx uninstall` · `ocx remove` 停止服务和代理,移除服务和 Codex shim,恢复原生 Codex,然后仅在所有恢复步骤都成功时才删除 opencodex 本地配置。`remove` 是 `uninstall` 的别名。配置清理需要由全新安装创建的所有权元数据;旧版或共享目录会保留原样。 diff --git a/docs-site/src/content/docs/zh-tw/reference/cli/lifecycle.md b/docs-site/src/content/docs/zh-tw/reference/cli/lifecycle.md index 71d575e774..0eaf6c75f9 100644 --- a/docs-site/src/content/docs/zh-tw/reference/cli/lifecycle.md +++ b/docs-site/src/content/docs/zh-tw/reference/cli/lifecycle.md @@ -52,6 +52,10 @@ ocx eject back 這是範圍很廣且具破壞性的重新標記:所有含有使用者訊息且目前標記為 `opencodex` 的 thread 都會改標為 `openai`,`exec` 會正規化為 `cli`,並設定 event marker。正常的專用 provider 歷史也包含在內。請先備份狀態,而且只有在確實需要這個完整範圍時才執行。 +### `ocx recover-history --ocx-compaction --yes` + +在透過原生 Codex 恢復曾由路由提供方壓縮的工作前,修復該工作的歷史記錄。此命令依 UUID 精確選取一個工作,先儲存私有的逐位元組備份,然後只把 OpenCodeX 自有的 `ocx1:` 壓縮狀態轉換成原生 Codex 可重播的普通摘要。原生加密內容與其他工作不會變更。執行前請關閉所選工作;若 rollout 在處理期間發生變化,復原會停止且不會取代原始檔案。 + ### `ocx uninstall` · `ocx remove` 停止服務與代理、移除服務與 Codex shim、還原原生 Codex,然後僅在所有還原步驟成功時移除 opencodex 本機設定。`remove` 是 `uninstall` 的別名。設定清理需要由全新安裝建立的擁有權中繼資料;舊版或共享目錄會被原樣保留。 diff --git a/scripts/test-layout/layout.json b/scripts/test-layout/layout.json index 0ff7d4861c..d0eee3c739 100644 --- a/scripts/test-layout/layout.json +++ b/scripts/test-layout/layout.json @@ -689,6 +689,7 @@ "gui-static.test.ts": "gui", "health-scoring.test.ts": "server", "history-migration-guardian.test.ts": "codex-integration", + "history-ocx-compaction-recovery.test.ts": "codex-integration", "hyperbolic-provider.test.ts": "providers", "identity-neutralize.test.ts": "adapters", "init-backup-cleanup.test.ts": "service", diff --git a/src/cli/dispatch.ts b/src/cli/dispatch.ts index c884bb2e5d..e85de1c05f 100644 --- a/src/cli/dispatch.ts +++ b/src/cli/dispatch.ts @@ -25,6 +25,7 @@ import { afterCatalogWriteHandleAppServers } from "../codex/app-server-processes import { normalizeUpdateChannel, runGuiUpdateWorker } from "../update/job"; import { isJsonOption, takeFlag } from "./runtime-api"; import type { ClientConnectionState } from "../client/state"; +import { OCX_NATIVE_REPLAY_RECOVERY_NOTE } from "../responses/compaction"; export interface CliDispatchDeps { args: string[]; @@ -199,6 +200,7 @@ const commandRunners: Record = { } if (r.success) { console.log("Codex integration is OFF and plain `codex` now runs natively. Switch back with: ocx restore back"); + console.log(`Note: ${OCX_NATIVE_REPLAY_RECOVERY_NOTE}`); } else { console.error("Plain `codex` was not fully restored. Inspect $CODEX_HOME/config.toml before using native Codex."); } diff --git a/src/cli/help.ts b/src/cli/help.ts index 0cd6bec4dc..43916695b6 100644 --- a/src/cli/help.ts +++ b/src/cli/help.ts @@ -33,6 +33,8 @@ Usage: ocx restore back Re-point codex at the running proxy (undo restore) ocx recover-history --legacy-openai --yes Force all user-message opencodex rows to OpenAI (legacy recovery) + ocx recover-history --ocx-compaction --yes + Back up and make one ocx1-compacted thread replayable by native Codex ocx uninstall Remove service/shim/config and restore native Codex (alias: remove) ocx service [sub] Run as a background service (default: install/update/start) ocx codex-shim Auto-start proxy when \`codex\` launches (install|status|uninstall|remove) diff --git a/src/cli/index.ts b/src/cli/index.ts index 663514a120..309eea763a 100755 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -1442,8 +1442,31 @@ async function handleStatus() { } async function handleRecoverHistory() { + if (args[1] === "--ocx-compaction") { + const threadId = args[2]; + if (args.length !== 4 || !threadId || args[3] !== "--yes") { + console.error("Usage: ocx recover-history --ocx-compaction --yes"); + console.error("This rewrites one rollout after saving a private byte-for-byte backup. Close that Codex thread before retrying."); + process.exit(1); + } + console.error("WARNING: this converts OpenCodeX-owned ocx1 compaction state into a plain summary for native Codex replay."); + try { + const { recoverOcxCompactionHistory } = await import("../codex/ocx-compaction-history"); + const result = recoverOcxCompactionHistory({ threadId }); + if (result.replaced === 0) { + console.log(`Thread ${threadId} has no repairable ocx1 compaction history; no files changed.`); + return; + } + console.log(`Recovered ${result.replaced} ocx1 compaction item(s) in thread ${threadId}.`); + console.log(`Backup: ${result.backupPath}`); + return; + } catch (error) { + console.error(`Recovery failed: ${error instanceof Error ? error.message : String(error)}`); + process.exit(1); + } + } if (args[1] !== "--legacy-openai") { - console.error("Usage: ocx recover-history --legacy-openai --yes"); + console.error("Usage: ocx recover-history (--legacy-openai | --ocx-compaction ) --yes"); console.error("This force-relabels every user-message opencodex row to OpenAI, including legitimate dedicated-provider history. Back up first and use it only for pre-backup legacy recovery."); process.exit(1); } diff --git a/src/cli/registry.ts b/src/cli/registry.ts index 467a0f7971..73bbd68e31 100644 --- a/src/cli/registry.ts +++ b/src/cli/registry.ts @@ -36,8 +36,8 @@ export const CLI_COMMANDS: CliCommandEntry[] = [ }, { name: "recover-history", - usage: "ocx recover-history --legacy-openai --yes", - summary: "Force all user-message opencodex rows to OpenAI for legacy recovery.", + usage: "ocx recover-history (--legacy-openai | --ocx-compaction ) --yes", + summary: "Recover legacy provider metadata or one OpenCodeX-compacted thread for native replay.", }, { name: "uninstall", diff --git a/src/codex/ocx-compaction-history.ts b/src/codex/ocx-compaction-history.ts new file mode 100644 index 0000000000..7cab765c4f --- /dev/null +++ b/src/codex/ocx-compaction-history.ts @@ -0,0 +1,226 @@ +import { createHash } from "node:crypto"; +import { + chmodSync, + closeSync, + constants, + existsSync, + fsyncSync, + lstatSync, + mkdirSync, + openSync, + readFileSync, + realpathSync, + truncateSync, + unlinkSync, + writeFileSync, +} from "node:fs"; +import { basename, isAbsolute, join, relative, resolve } from "node:path"; + +import { Database } from "bun:sqlite"; + +import { getConfigDir } from "../config"; +import { hardenSecretPath } from "../lib/windows-secret-acl"; +import { renameAtomicFile } from "../lib/windows-atomic-replace"; +import { + decodeCompactionSummary, + isCompactionItemType, + SUMMARY_PREFIX, +} from "../responses/compaction"; +import { resolveCodexHomeDir } from "./home"; +import { resolveCodexStateDbPath } from "./paths"; + +export interface OcxCompactionRewriteResult { + content: string; + replaced: number; +} + +export interface OcxCompactionHistoryRecoveryResult { + rolloutPath: string; + backupPath: string | null; + replaced: number; +} + +export interface OcxCompactionHistoryRecoveryOptions { + threadId: string; + codexHome?: string; + stateDbPath?: string; + backupRoot?: string; + now?: () => Date; +} + +const THREAD_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; + +function digest(content: string | Buffer): string { + return createHash("sha256").update(content).digest("hex"); +} + +function pathInside(root: string, candidate: string): boolean { + const rel = relative(root, candidate); + return rel === "" || (!rel.startsWith("..") && !isAbsolute(rel)); +} + +function resolveOwnedRolloutPath(codexHome: string, rawPath: string): string { + const candidate = resolve(isAbsolute(rawPath) ? rawPath : join(codexHome, rawPath)); + const roots = [join(codexHome, "sessions"), join(codexHome, "archived_sessions")] + .filter(existsSync) + .map(root => realpathSync.native(root)); + const entry = lstatSync(candidate); + if (!entry.isFile() || entry.isSymbolicLink()) { + throw new Error("the referenced rollout is not a regular file"); + } + const canonical = realpathSync.native(candidate); + if (!roots.some(root => pathInside(root, canonical))) { + throw new Error("the referenced rollout is outside Codex session storage"); + } + return canonical; +} + +function writePrivateFile(path: string, content: string): void { + const fd = openSync(path, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL, 0o600); + try { + if (process.platform !== "win32") chmodSync(path, 0o600); + else hardenSecretPath(path, { required: true, timeoutMemoKey: path }); + writeFileSync(fd, content, "utf8"); + fsyncSync(fd); + } finally { + closeSync(fd); + } +} + +function safeRemovePrivateFile(path: string): void { + try { truncateSync(path, 0); } catch { /* best effort before unlink */ } + try { unlinkSync(path); } catch { /* caller reports the original failure */ } +} + +function isRecord(value: unknown): value is Record { + return value !== null && typeof value === "object" && !Array.isArray(value); +} + +function lowerCompactionItem(item: unknown): { item: unknown; changed: boolean } { + if (!isRecord(item) || !isCompactionItemType(item.type)) { + return { item, changed: false }; + } + if (typeof item.encrypted_content !== "string") { + return { item, changed: false }; + } + const summary = decodeCompactionSummary(item.encrypted_content); + if (summary === null) return { item, changed: false }; + return { + item: { + type: "message", + role: "user", + content: [{ type: "input_text", text: `${SUMMARY_PREFIX}\n${summary}` }], + }, + changed: true, + }; +} + +function rewriteJsonlLine(line: string): { line: string; replaced: number } { + let record: unknown; + try { + record = JSON.parse(line); + } catch { + return { line, replaced: 0 }; + } + if (!isRecord(record) || record.type !== "compacted" || !isRecord(record.payload)) { + return { line, replaced: 0 }; + } + const history = record.payload.replacement_history; + if (!Array.isArray(history)) return { line, replaced: 0 }; + + let replaced = 0; + const replacementHistory = history.map(item => { + const lowered = lowerCompactionItem(item); + if (lowered.changed) replaced += 1; + return lowered.item; + }); + if (replaced === 0) return { line, replaced: 0 }; + + return { + line: JSON.stringify({ + ...record, + payload: { ...record.payload, replacement_history: replacementHistory }, + }), + replaced, + }; +} + +/** + * Convert OpenCodeX-owned `ocx1:` compaction items into ordinary replayable user messages. + * + * Only the authoritative `compacted.payload.replacement_history` snapshot is changed. Earlier + * response-item events are historical output and are deliberately preserved byte-for-byte. + * Native opaque compactions are also untouched because OpenCodeX cannot decode them safely. + */ +export function rewriteOcxCompactionsForNativeReplay(content: string): OcxCompactionRewriteResult { + const parts = content.split(/(\r?\n)/); + let replaced = 0; + for (let index = 0; index < parts.length; index += 2) { + const line = parts[index]; + if (!line) continue; + const rewritten = rewriteJsonlLine(line); + if (rewritten.replaced === 0) continue; + parts[index] = rewritten.line; + replaced += rewritten.replaced; + } + return replaced === 0 + ? { content, replaced: 0 } + : { content: parts.join(""), replaced }; +} + +/** + * Repair one explicitly selected Codex rollout for direct native replay. + * + * The original bytes are copied to an owner-private backup before the rollout is atomically + * replaced. A last-moment digest check refuses a concurrent Codex append instead of losing it. + */ +export function recoverOcxCompactionHistory( + options: OcxCompactionHistoryRecoveryOptions, +): OcxCompactionHistoryRecoveryResult { + if (!THREAD_ID_RE.test(options.threadId)) throw new Error("thread id must be a UUID"); + const codexHome = realpathSync.native(options.codexHome ?? resolveCodexHomeDir()); + const stateDbPath = options.stateDbPath ?? resolveCodexStateDbPath({ codexHome }); + if (!existsSync(stateDbPath)) throw new Error("Codex state database was not found"); + + const db = new Database(stateDbPath, { readonly: true }); + let rawRolloutPath: string | undefined; + try { + db.exec("PRAGMA busy_timeout = 1000"); + rawRolloutPath = db.query<{ rollout_path: string }, [string]>( + "SELECT rollout_path FROM threads WHERE id = ? LIMIT 1", + ).get(options.threadId)?.rollout_path; + } finally { + db.close(); + } + if (!rawRolloutPath) throw new Error("thread was not found in the Codex state database"); + + const rolloutPath = resolveOwnedRolloutPath(codexHome, rawRolloutPath); + const originalBytes = readFileSync(rolloutPath); + const original = originalBytes.toString("utf8"); + if (!Buffer.from(original, "utf8").equals(originalBytes)) { + throw new Error("the rollout is not valid UTF-8 and cannot be repaired safely"); + } + const rewritten = rewriteOcxCompactionsForNativeReplay(original); + if (rewritten.replaced === 0) { + return { rolloutPath, backupPath: null, replaced: 0 }; + } + + const stamp = (options.now ?? (() => new Date()))().toISOString().replace(/[:.]/g, "-"); + const backupDir = resolve(options.backupRoot ?? join(getConfigDir(), "history-recovery-backups", options.threadId)); + mkdirSync(backupDir, { recursive: true, mode: 0o700 }); + const backupPath = join(backupDir, `${basename(rolloutPath)}.${stamp}.bak`); + writePrivateFile(backupPath, original); + + const tempPath = `${rolloutPath}.ocx-repair-${process.pid}-${crypto.randomUUID()}.tmp`; + try { + writePrivateFile(tempPath, rewritten.content); + if (digest(readFileSync(rolloutPath)) !== digest(originalBytes)) { + throw new Error("the rollout changed while it was being repaired; close Codex and retry"); + } + renameAtomicFile(tempPath, rolloutPath); + } catch (error) { + safeRemovePrivateFile(tempPath); + throw error; + } + return { rolloutPath, backupPath, replaced: rewritten.replaced }; +} diff --git a/src/responses/compaction.ts b/src/responses/compaction.ts index f3fba7a033..b067e7c858 100644 --- a/src/responses/compaction.ts +++ b/src/responses/compaction.ts @@ -17,6 +17,10 @@ export const OCX_COMPACTION_PREFIX = "ocx1:"; +export const OCX_NATIVE_REPLAY_RECOVERY_NOTE = + "Threads compacted through a routed provider can contain OpenCodeX-owned ocx1 state. " + + "Before resuming one through native Codex, run `ocx recover-history --ocx-compaction --yes`."; + /** Mirrors codex-rs core/templates/compact/prompt.md (the local-compaction instruction). */ export const COMPACT_PROMPT = `You are performing a CONTEXT CHECKPOINT COMPACTION. Create a handoff summary for another LLM that will resume the task. diff --git a/src/server/management/native-integration-routes.ts b/src/server/management/native-integration-routes.ts index e63001c980..56158bd162 100644 --- a/src/server/management/native-integration-routes.ts +++ b/src/server/management/native-integration-routes.ts @@ -366,13 +366,14 @@ async function handleCodexToggle(ctx: ManagementContext): Promise { } } const { restoreNativeCodexAsync } = await import("../../codex/inject"); + const { OCX_NATIVE_REPLAY_RECOVERY_NOTE } = await import("../../responses/compaction"); const restored = await restoreNativeCodexAsync({ revalidateDesiredState: true }); return jsonResponse({ ok: true, clientId: "codex", changed: durable && persisted.status === "committed", state: restored.success ? "absent" : "unsafe", desiredEnabled: enabled, message: restored.success - ? "Codex restored to its native path; the proxy is still serving other clients" + ? `Codex restored to its native path; the proxy is still serving other clients. ${OCX_NATIVE_REPLAY_RECOVERY_NOTE}` : `Codex intent saved, but restoring the native path did not complete: ${restored.message}`, ...(restored.success ? (durable ? {} : { reason: "not_durable" }) diff --git a/tests/cli/cli-help.test.ts b/tests/cli/cli-help.test.ts index d101b75bc8..1020439e49 100644 --- a/tests/cli/cli-help.test.ts +++ b/tests/cli/cli-help.test.ts @@ -1,6 +1,6 @@ import { describe, expect, setDefaultTimeout, test } from "bun:test"; import { spawnSync } from "node:child_process"; -import { chmodSync, existsSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs"; +import { chmodSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; @@ -288,8 +288,8 @@ describe("CLI subcommand help", () => { expectSpawnFinished(result, "ocx recover-history --help"); expect(result.status).toBe(0); - expect(result.stdout).toContain("Usage: ocx recover-history --legacy-openai --yes"); - expect(result.stdout).toContain("Force all user-message opencodex rows to OpenAI"); + expect(result.stdout).toContain("Usage: ocx recover-history (--legacy-openai | --ocx-compaction ) --yes"); + expect(result.stdout).toContain("Recover legacy provider metadata or one OpenCodeX-compacted thread"); expect(result.stdout).not.toContain("Recovered"); expect(result.stderr).toBe(""); expect(existsSync(statePath)).toBe(false); @@ -345,6 +345,48 @@ describe("CLI subcommand help", () => { } }); + test("recover-history repairs one explicitly selected ocx1-compacted thread", () => { + const codexHome = mkdtempSync(join(tmpdir(), "ocx-recover-compaction-")); + const opencodexHome = mkdtempSync(join(tmpdir(), "ocx-recover-compaction-state-")); + try { + writeFileSync(join(codexHome, "config.toml"), 'model = "gpt-5"\n', "utf8"); + const threadId = "01a018e6-242f-7801-81b8-ffc0a5c6d589"; + const rolloutDir = join(codexHome, "sessions", "2026", "09", "07"); + mkdirSync(rolloutDir, { recursive: true }); + const rollout = join(rolloutDir, `rollout-fixture-${threadId}.jsonl`); + const summary = `ocx1:${Buffer.from("portable summary", "utf8").toString("base64")}`; + writeFileSync(rollout, `${JSON.stringify({ + type: "compacted", + payload: { + replacement_history: [{ type: "compaction", id: "cmp_fixture", encrypted_content: summary }], + }, + })}\n`, "utf8"); + const statePath = join(codexHome, "state_5.sqlite"); + const db = new Database(statePath, { create: true }); + db.exec("CREATE TABLE threads (id TEXT PRIMARY KEY, rollout_path TEXT NOT NULL)"); + db.query("INSERT INTO threads (id, rollout_path) VALUES (?, ?)").run(threadId, rollout); + db.close(); + + const result = runCli( + ["recover-history", "--ocx-compaction", threadId, "--yes"], + { CODEX_HOME: codexHome, OPENCODEX_HOME: opencodexHome, CI: "1" }, + ); + + expectSpawnFinished(result, "ocx recover-history --ocx-compaction"); + expect(result.status).toBe(0); + expect(result.stdout).toContain("Recovered 1 ocx1 compaction item(s)"); + expect(readFileSync(rollout, "utf8")).toContain("portable summary"); + expect(readFileSync(rollout, "utf8")).not.toContain("ocx1:"); + const backupDir = join(opencodexHome, "history-recovery-backups", threadId); + const backups = readdirSync(backupDir); + expect(backups).toHaveLength(1); + expect(readFileSync(join(backupDir, backups[0]), "utf8")).toContain("ocx1:"); + } finally { + removeTreeWithRetry(opencodexHome); + removeTreeWithRetry(codexHome); + } + }); + test("start rejects unknown and partially numeric port arguments", () => { const cases = [ { args: ["start", "--port", "123abc"], expected: "Invalid port number" }, diff --git a/tests/cli/cli-restore-back.test.ts b/tests/cli/cli-restore-back.test.ts index 04051a4b10..a750ae8ee9 100644 --- a/tests/cli/cli-restore-back.test.ts +++ b/tests/cli/cli-restore-back.test.ts @@ -45,6 +45,7 @@ describe("ocx restore back", () => { expect(result.status).toBe(0); expect(JSON.parse(readFileSync(join(ocxHome, "config.json"), "utf8")).clientIntegrations.codex).toBe(false); expect(`${result.stdout}\n${result.stderr}`).toContain("Codex integration is OFF and plain `codex` now runs natively."); + expect(result.stdout).toContain("ocx recover-history --ocx-compaction --yes"); } finally { removeTreeWithRetry(codexHome); removeTreeWithRetry(ocxHome); diff --git a/tests/codex-integration/codex-composed-acceptance.test.ts b/tests/codex-integration/codex-composed-acceptance.test.ts index b333fa3c65..44730e5453 100644 --- a/tests/codex-integration/codex-composed-acceptance.test.ts +++ b/tests/codex-integration/codex-composed-acceptance.test.ts @@ -484,9 +484,11 @@ describe("WP13 composed toggle acceptance", () => { // The CLI's own output is the assertion message: a bare "expected 0, got 1" sent two // Windows CI rounds chasing a timeout that was never the cause. expect(`exit=${back.exitCode}\nstderr: ${back.stderr}\nstdout: ${back.stdout}`).toContain("exit=0"); - expect((await fx.request(server.runtime, "/api/native-integrations/codex", { + const disabledAgain = await fx.request(server.runtime, "/api/native-integrations/codex", { method: "PUT", body: JSON.stringify({ enabled: false }), - })).body).toMatchObject({ desiredEnabled: false }); + }); + expect(disabledAgain.body).toMatchObject({ desiredEnabled: false }); + expect(String(disabledAgain.body.message)).toContain("ocx recover-history --ocx-compaction --yes"); } finally { await fx.stop(server); } diff --git a/tests/codex-integration/history-ocx-compaction-recovery.test.ts b/tests/codex-integration/history-ocx-compaction-recovery.test.ts new file mode 100644 index 0000000000..325a83c93d --- /dev/null +++ b/tests/codex-integration/history-ocx-compaction-recovery.test.ts @@ -0,0 +1,108 @@ +import { describe, expect, test } from "bun:test"; +import { Database } from "bun:sqlite"; +import { mkdirSync, mkdtempSync, readFileSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; + +import { + recoverOcxCompactionHistory, + rewriteOcxCompactionsForNativeReplay, +} from "../../src/codex/ocx-compaction-history"; +import { encodeCompactionSummary, SUMMARY_PREFIX } from "../../src/responses/compaction"; +import { removeTreeWithRetry } from "../helpers/remove-tree"; + +describe("OpenCodeX compaction history recovery", () => { + test("lowers only proxy-owned compactions in compacted replacement history", () => { + const source = [ + JSON.stringify({ type: "session_meta", payload: { id: "thread-fixture" } }), + JSON.stringify({ + type: "compacted", + payload: { + replacement_history: [ + { type: "message", role: "user", content: [{ type: "input_text", text: "keep" }] }, + { + type: "compaction", + id: "cmp_fixture", + encrypted_content: encodeCompactionSummary("fixture summary"), + }, + { type: "compaction", id: "cmp_native", encrypted_content: "native-opaque" }, + ], + }, + }), + JSON.stringify({ + type: "response_item", + payload: { type: "compaction", encrypted_content: encodeCompactionSummary("historical output") }, + }), + "", + ].join("\n"); + + const result = rewriteOcxCompactionsForNativeReplay(source); + + expect(result.replaced).toBe(1); + const lines = result.content.trimEnd().split("\n").map(line => JSON.parse(line)); + expect(lines[1].payload.replacement_history).toEqual([ + { type: "message", role: "user", content: [{ type: "input_text", text: "keep" }] }, + { + type: "message", + role: "user", + content: [{ type: "input_text", text: `${SUMMARY_PREFIX}\nfixture summary` }], + }, + { type: "compaction", id: "cmp_native", encrypted_content: "native-opaque" }, + ]); + expect(lines[2].payload.encrypted_content).toStartWith("ocx1:"); + expect(result.content.endsWith("\n")).toBe(true); + }); + + test("is byte-stable when no repairable compaction exists", () => { + const source = `${JSON.stringify({ + type: "compacted", + payload: { replacement_history: [{ type: "compaction", encrypted_content: "native-opaque" }] }, + })}\nnot-json\n`; + + expect(rewriteOcxCompactionsForNativeReplay(source)).toEqual({ content: source, replaced: 0 }); + }); + + test("backs up and atomically repairs one database-selected rollout", () => { + const root = mkdtempSync(join(tmpdir(), "ocx-compaction-recovery-")); + try { + const codexHome = join(root, "codex"); + const rolloutDir = join(codexHome, "sessions", "2026", "09", "07"); + const backupRoot = join(root, "backups"); + mkdirSync(rolloutDir, { recursive: true }); + const threadId = "01a018e6-242f-7801-81b8-ffc0a5c6d589"; + const rolloutPath = join(rolloutDir, `rollout-fixture-${threadId}.jsonl`); + const original = `${JSON.stringify({ + type: "compacted", + payload: { + replacement_history: [{ + type: "compaction", + id: "cmp_fixture", + encrypted_content: encodeCompactionSummary("recover me"), + }], + }, + })}\n`; + writeFileSync(rolloutPath, original, "utf8"); + const stateDbPath = join(codexHome, "state_5.sqlite"); + const db = new Database(stateDbPath, { create: true }); + db.exec("CREATE TABLE threads (id TEXT PRIMARY KEY, rollout_path TEXT NOT NULL)"); + db.query("INSERT INTO threads (id, rollout_path) VALUES (?, ?)").run(threadId, rolloutPath); + db.close(); + + const result = recoverOcxCompactionHistory({ + threadId, + codexHome, + stateDbPath, + backupRoot, + now: () => new Date("2026-09-07T00:00:00.000Z"), + }); + + expect(result.replaced).toBe(1); + expect(result.backupPath).not.toBeNull(); + expect(readFileSync(result.backupPath!, "utf8")).toBe(original); + expect(readFileSync(rolloutPath, "utf8")).toContain(`${SUMMARY_PREFIX}\\nrecover me`); + expect(readFileSync(rolloutPath, "utf8")).not.toContain("ocx1:"); + } finally { + removeTreeWithRetry(root); + } + }); +}); diff --git a/tests/fixtures/test-layout-expected.json b/tests/fixtures/test-layout-expected.json index 98907bd26a..568fd6f6ee 100644 --- a/tests/fixtures/test-layout-expected.json +++ b/tests/fixtures/test-layout-expected.json @@ -524,6 +524,7 @@ "gui-static.test.ts": "gui", "health-scoring.test.ts": "server", "history-migration-guardian.test.ts": "codex-integration", + "history-ocx-compaction-recovery.test.ts": "codex-integration", "hyperbolic-provider.test.ts": "providers", "identity-neutralize.test.ts": "adapters", "init-backup-cleanup.test.ts": "service",