fix(api): migrate deprecated Codex [features].codex_hooks to [features].hooks (#4342)

Codex renamed the `codex_hooks` feature flag to `hooks`; recent Codex CLI
versions ignore the old key and warn. When OmniRoute rewrites an existing
config.toml (configure/reset Codex provider) it now renames
[features].codex_hooks -> [features].hooks, preserving the value and never
clobbering an already-present `hooks`, then drops the deprecated key. The
migration is a no-op when the flag is absent and runs on both the POST and
DELETE config paths.

Reported-by: Bian-Sh (https://github.com/decolua/9router/issues/1327)

Co-authored-by: Bian-Sh <24520547+Bian-Sh@users.noreply.github.com>
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-06-20 10:54:42 -03:00
committed by GitHub
parent 55eb1b5a14
commit d6ce094a60
4 changed files with 70 additions and 0 deletions

View File

@@ -15,6 +15,7 @@ import { cliModelConfigSchema } from "@/shared/validation/schemas";
import { isValidationFailure, validateBody } from "@/shared/validation/helpers";
import { getApiKeyById } from "@/lib/localDb";
import { normalizeCodexBaseUrl } from "@/shared/utils/codexBaseUrl";
import { migrateCodexFeatureFlags } from "@/shared/utils/codexConfig";
const getCodexConfigPath = () => getCliConfigPaths("codex").config;
const getCodexAuthPath = () => getCliConfigPaths("codex").auth;
@@ -252,6 +253,9 @@ export async function POST(request: Request) {
/* No existing config */
}
// Carry the user's intent forward off the deprecated Codex feature flag (#1327).
migrateCodexFeatureFlags(parsed);
// Update only OmniRoute related fields (api_key goes to auth.json, not config.toml)
parsed._root.model = model;
@@ -351,6 +355,9 @@ export async function DELETE(request: Request) {
throw error;
}
// Carry the user's intent forward off the deprecated Codex feature flag (#1327).
migrateCodexFeatureFlags(parsed);
// Remove OmniRoute related root fields
delete parsed._root.openai_base_url;

View File

@@ -0,0 +1,30 @@
/**
* Helpers for generating/maintaining the Codex CLI `config.toml`.
*/
interface ParsedCodexToml {
_root: Record<string, unknown>;
_sections: Record<string, Record<string, unknown>>;
}
/**
* Migrate the deprecated Codex `[features].codex_hooks` flag to `[features].hooks`.
*
* Codex renamed the feature flag; recent Codex CLI versions ignore the old key and
* print a deprecation notice. When OmniRoute rewrites an existing `config.toml` it
* should carry the user's intent forward by renaming the key (preserving its value)
* and dropping the deprecated one. A no-op when `[features]` or `codex_hooks` is
* absent, and it never clobbers an already-present `hooks` value. (#1327)
*
* Operates in place on the route's parsed-TOML shape (`{ _root, _sections }`).
*/
export function migrateCodexFeatureFlags(parsed: ParsedCodexToml): ParsedCodexToml {
const features = parsed?._sections?.features;
if (!features || typeof features !== "object") return parsed;
if (!Object.prototype.hasOwnProperty.call(features, "codex_hooks")) return parsed;
if (!Object.prototype.hasOwnProperty.call(features, "hooks")) {
features.hooks = features.codex_hooks;
}
delete features.codex_hooks;
return parsed;
}