From 6747e22757ab6ab9790df7398f95fb36baa1fa2b Mon Sep 17 00:00:00 2001 From: diegosouzapw Date: Mon, 27 Apr 2026 07:39:12 -0300 Subject: [PATCH] =?UTF-8?q?fix(codex,db):=20resolve=206=20issues=20?= =?UTF-8?q?=E2=80=94=20Codex=20502,=20store=20default,=20migration=20guard?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: - fix(codex): rename getWreqWebsocket() → getCodexWebSocketTransport() Fixes the ReferenceError causing 502 on all Codex requests (#1652, #1653) - fix(codex): default store to false instead of true Codex OAuth backend rejects store=true with 'Store must be set to false' (#1635) - fix(db): add post-migration startup guards for combos.sort_order (#1657) and batches/files tables (#1648) — handles heuristic seeding edge case - fix(db): renumber duplicate migration 032_create_reasoning_cache → 033 Closes #1635, #1648, #1652, #1653, #1657 Also closed as user-config: #1649 (Claude 429), #1659 (thought_signature) --- CHANGELOG.md | 26 +++++ open-sse/executors/codex.ts | 17 ++-- src/lib/db/core.ts | 95 +++++++++++++++++++ ...che.sql => 033_create_reasoning_cache.sql} | 0 4 files changed, 130 insertions(+), 8 deletions(-) rename src/lib/db/migrations/{032_create_reasoning_cache.sql => 033_create_reasoning_cache.sql} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index d89796bbac..fde5903bf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,32 @@ --- +## [3.7.2] — 2026-04-27 + +### ✨ New Features + +- **feat(authz):** introduce centralized proxy-based authz pipeline and lifecycle policy (#1632) +- **feat(logs):** configure call log pipeline artifacts (#1650) +- **feat(network):** add guarded remote image fetch utility +- **feat(codex):** enable native Codex websocket responses on beta-gated models (#1658) + +### 🐛 Bug Fixes + +- **fix(chatgpt-web):** bound tls-client native deadlocks so requests never hang forever (#1664) +- **fix(codex):** default gpt-5.5 to HTTP transport instead of WebSocket (#1660) +- **fix(codex):** [urgent] fix gpt-5.5 websocket transport and model labels (#1656) +- **fix(grokweb):** update Request and Response Specifications (#1655) +- **fix(blackbox-web):** set isPremium flag to true to enable premium model access (#1661) +- **fix(core):** avoid OpenAI stream options for Anthropic-compatible providers (#1654) +- **fix(electron):** resolve MCP server start failure on Windows (#1662) +- **fix(electron):** make Windows smoke test non-blocking (continue-on-error), pre-create userData dir for Windows + stream logs in CI, and add --no-sandbox and sandbox env for CI smoke tests +- **fix(codex):** fix `getWreqWebsocket` ReferenceError causing 502 on all Codex requests (#1652, #1653) +- **fix(codex):** default `store` to `false` — Codex OAuth backend rejects `store=true` (#1635) +- **fix(db):** add post-migration guards for missing `batches` table and `combos.sort_order` column on DB upgrades (#1648, #1657) +- **fix(db):** renumber duplicate migration `032` to prevent collision + +--- + ## [3.7.1] — 2026-04-26 ### ✨ New Features diff --git a/open-sse/executors/codex.ts b/open-sse/executors/codex.ts index f934a392cc..241b25afc4 100644 --- a/open-sse/executors/codex.ts +++ b/open-sse/executors/codex.ts @@ -526,7 +526,7 @@ export function isCodexResponsesWebSocketRequired(_model: string, credentials: u credentials && typeof credentials === "object" ? (credentials as { providerSpecificData?: Record }).providerSpecificData : null; - return !!(providerSpecificData?.codexTransport === "websocket" && getWreqWebsocket()); + return !!(providerSpecificData?.codexTransport === "websocket" && getCodexWebSocketTransport()); } function toStatusCode(value: unknown): number | null { @@ -1004,20 +1004,21 @@ export class CodexExecutor extends BaseExecutor { } } - // Store: The Codex API defaults store to false when not specified. - // Proxy clients (e.g. OpenClaw) rely on response chaining via previous_response_id, - // which requires store=true so that response items are persisted. - // If the client explicitly sets store, respect it. Otherwise default to true. + // Store: The Codex OAuth backend rejects store=true with + // "Store must be set to false". Default to false unless the provider + // explicitly opts in (e.g. API-key accounts that support persistence). + // Ref: sub2api openai_codex_transform.go line 75-80 const explicitStoreSetting = credentials?.providerSpecificData && typeof credentials.providerSpecificData === "object" && !Array.isArray(credentials.providerSpecificData) ? credentials.providerSpecificData.openaiStoreEnabled : undefined; - if (explicitStoreSetting === false) { - body.store = false; - } else if (body.store === undefined) { + if (explicitStoreSetting === true) { body.store = true; + } else { + // backend rejects store=true ("Store must be set to false"), so default to false. + body.store = false; } // Codex Responses only supports function tools with non-empty names. diff --git a/src/lib/db/core.ts b/src/lib/db/core.ts index 96eaf8b209..4a0deee28d 100644 --- a/src/lib/db/core.ts +++ b/src/lib/db/core.ts @@ -1250,6 +1250,101 @@ export function getDbInstance(): SqliteDatabase { ); } runMigrations(db, { isNewDb }); + + // ── Post-migration safety guards ────────────────────────────────────────── + // The heuristic seeding above can mark migration versions as "applied" based + // on column detection, causing the migration runner to skip newer migrations + // whose tables/columns don't have heuristic detectors yet. + // These guards ensure critical schema elements exist regardless of migration + // state, fixing upgrade failures reported in #1648 and #1657. + + // Guard: combos.sort_order (migration 020) + if (hasTable(db, "combos") && !hasColumn(db, "combos", "sort_order")) { + try { + db.exec(` + ALTER TABLE combos ADD COLUMN sort_order INTEGER NOT NULL DEFAULT 0; + WITH ordered_combos AS ( + SELECT id, ROW_NUMBER() OVER ( + ORDER BY created_at ASC, updated_at ASC, name COLLATE NOCASE ASC + ) AS next_sort_order + FROM combos + ) + UPDATE combos SET sort_order = ( + SELECT next_sort_order FROM ordered_combos + WHERE ordered_combos.id = combos.id + ); + `); + console.log("[DB] Post-migration guard: added missing combos.sort_order column (#1657)"); + } catch (e: unknown) { + const msg = e instanceof Error ? e.message : String(e); + if (!msg.includes("duplicate column")) { + console.warn("[DB] Post-migration guard: combos.sort_order failed:", msg); + } + } + } + + // Guard: batches table (migration 028) + if (!hasTable(db, "batches")) { + try { + db.exec(` + CREATE TABLE IF NOT EXISTS files ( + id TEXT PRIMARY KEY, + bytes INTEGER NOT NULL, + created_at INTEGER NOT NULL, + filename TEXT NOT NULL, + purpose TEXT NOT NULL, + content BLOB, + mime_type TEXT, + api_key_id TEXT, + deleted_at INTEGER, + status TEXT DEFAULT 'validating', + expires_at INTEGER + ); + CREATE INDEX IF NOT EXISTS idx_files_api_key ON files(api_key_id); + + CREATE TABLE IF NOT EXISTS batches ( + id TEXT PRIMARY KEY, + endpoint TEXT NOT NULL, + completion_window TEXT NOT NULL, + status TEXT NOT NULL, + input_file_id TEXT NOT NULL, + output_file_id TEXT, + error_file_id TEXT, + created_at INTEGER NOT NULL, + in_progress_at INTEGER, + expires_at INTEGER, + finalizing_at INTEGER, + completed_at INTEGER, + failed_at INTEGER, + expired_at INTEGER, + cancelling_at INTEGER, + cancelled_at INTEGER, + request_counts_total INTEGER DEFAULT 0, + request_counts_completed INTEGER DEFAULT 0, + request_counts_failed INTEGER DEFAULT 0, + metadata TEXT, + api_key_id TEXT, + errors TEXT, + model TEXT, + usage TEXT, + output_expires_after_seconds INTEGER, + output_expires_after_anchor TEXT, + FOREIGN KEY(input_file_id) REFERENCES files(id), + FOREIGN KEY(output_file_id) REFERENCES files(id), + FOREIGN KEY(error_file_id) REFERENCES files(id) + ); + CREATE INDEX IF NOT EXISTS idx_batches_api_key ON batches(api_key_id); + CREATE INDEX IF NOT EXISTS idx_batches_status ON batches(status); + `); + console.log("[DB] Post-migration guard: created missing batches/files tables (#1648)"); + } catch (e: unknown) { + const msg = e instanceof Error ? e.message : String(e); + if (!msg.includes("already exists")) { + console.warn("[DB] Post-migration guard: batches/files creation failed:", msg); + } + } + } + offloadLegacyCallLogDetails(db); // Auto-migrate from db.json if exists diff --git a/src/lib/db/migrations/032_create_reasoning_cache.sql b/src/lib/db/migrations/033_create_reasoning_cache.sql similarity index 100% rename from src/lib/db/migrations/032_create_reasoning_cache.sql rename to src/lib/db/migrations/033_create_reasoning_cache.sql