Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion apps/server/src/provider/codexLaunchArgs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import * as NodeAssert from "node:assert/strict";

import { describe, it } from "vite-plus/test";

import { codexAppServerArgs, codexExecLaunchArgs } from "./codexLaunchArgs.ts";
import {
codexAppServerArgs,
codexExecLaunchArgs,
codexMcpListLaunchArgs,
} from "./codexLaunchArgs.ts";

describe("codexAppServerArgs", () => {
it("preserves escaped TOML quotes in config values", () => {
Expand All @@ -27,3 +31,32 @@ describe("codexExecLaunchArgs", () => {
]);
});
});

describe("codex exec and mcp list launch args", () => {
const launchArgs =
"--strict-config --oss --local-provider ollama --profile local -p=work --listen off --enable foo";

it("keeps the local model provider flags for codex exec", () => {
NodeAssert.deepStrictEqual(codexExecLaunchArgs(launchArgs), [
"--strict-config",
"--oss",
"--local-provider",
"ollama",
"--profile",
"local",
"-p=work",
"--enable",
"foo",
]);
});

it("keeps the selected profile and drops exec-only flags for codex mcp list", () => {
NodeAssert.deepStrictEqual(codexMcpListLaunchArgs(launchArgs), [
"--profile",
"local",
"-p=work",
"--enable",
"foo",
]);
});
});
45 changes: 36 additions & 9 deletions apps/server/src/provider/codexLaunchArgs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,53 @@ export const codexAppServerArgs = (launchArgs?: string) => [
...codexLaunchArgv(launchArgs),
];

export const codexExecLaunchArgs = (launchArgs?: string) => {
interface LaunchArgFilter {
readonly switches: ReadonlySet<string>;
readonly valueFlags: ReadonlySet<string>;
readonly inlinePrefixes: ReadonlyArray<string>;
}

const SHARED_VALUE_FLAGS = ["--config", "-c", "--enable", "--disable"];
const SHARED_INLINE_PREFIXES = ["--config=", "-c=", "--enable=", "--disable="];

const MCP_LIST_FILTER: LaunchArgFilter = {
switches: new Set(),
valueFlags: new Set([...SHARED_VALUE_FLAGS, "--profile", "-p"]),
inlinePrefixes: [...SHARED_INLINE_PREFIXES, "--profile=", "-p="],
};

const EXEC_FILTER: LaunchArgFilter = {
switches: new Set(["--strict-config", "--oss"]),
valueFlags: new Set([...SHARED_VALUE_FLAGS, "--local-provider", "--profile", "-p"]),
inlinePrefixes: [...SHARED_INLINE_PREFIXES, "--local-provider=", "--profile=", "-p="],
};

const filterLaunchArgs = (launchArgs: string | undefined, allowed: LaunchArgFilter) => {
const args = codexLaunchArgv(launchArgs);
const execArgs: Array<string> = [];
const kept: Array<string> = [];

for (let index = 0; index < args.length; index++) {
const arg = args[index];
if (arg === undefined) continue;

if (arg === "--strict-config" || arg.startsWith("--config=") || arg.startsWith("-c=")) {
execArgs.push(arg);
} else if (arg === "--config" || arg === "-c" || arg === "--enable" || arg === "--disable") {
if (allowed.switches.has(arg)) {
kept.push(arg);
} else if (allowed.valueFlags.has(arg)) {
const value = args[index + 1];
if (value !== undefined && !value.startsWith("-")) {
execArgs.push(arg, value);
kept.push(arg, value);
index++;
}
} else if (arg.startsWith("--enable=") || arg.startsWith("--disable=")) {
execArgs.push(arg);
} else if (allowed.inlinePrefixes.some((prefix) => arg.startsWith(prefix))) {
kept.push(arg);
}
}

return execArgs;
return kept;
};

export const codexExecLaunchArgs = (launchArgs?: string) =>
filterLaunchArgs(launchArgs, EXEC_FILTER);

export const codexMcpListLaunchArgs = (launchArgs?: string) =>
filterLaunchArgs(launchArgs, MCP_LIST_FILTER);
4 changes: 2 additions & 2 deletions apps/server/src/textGeneration/CodexTextGeneration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -429,8 +429,8 @@ it.layer(layerCodexTextGenerationTest)("CodexTextGeneration", (it) => {
subject: "Add important change",
body: "",
}),
launchArgs: "--strict-config --listen off",
requireArg: "--strict-config",
launchArgs: "--strict-config --oss --local-provider ollama --listen off",
requireArg: "--strict-config --oss --local-provider ollama",
forbidArg: "--listen",
},
(textGeneration) =>
Expand Down
12 changes: 7 additions & 5 deletions apps/server/src/textGeneration/CodexTextGeneration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ import { resolveSpawnCommand } from "@t3tools/shared/shell";
import { resolveAttachmentPath } from "../attachmentStore.ts";
import * as ServerConfig from "../config.ts";
import { expandHomePath } from "@t3tools/provider-core/server/pathExpansion";
import { codexExecLaunchArgs, resolveCodexLaunchArgs } from "../provider/codexLaunchArgs.ts";
import {
codexExecLaunchArgs,
codexMcpListLaunchArgs,
resolveCodexLaunchArgs,
} from "../provider/codexLaunchArgs.ts";
import * as TextGenerationOperations from "@t3tools/provider-core/server/textGenerationOperations";
import {
normalizeCliError,
Expand Down Expand Up @@ -287,19 +291,17 @@ export const makeCodexTextGeneration = Effect.fn("makeCodexTextGeneration")(func
}
: {}),
};
const execLaunchArgs = codexExecLaunchArgs(launchArgs);
const mcpServersOff = yield* listEnabledMcpServers({
binary,
cwd,
env,
// `codex mcp` rejects --strict-config; the overrides still apply.
launchArgs: execLaunchArgs.filter((arg) => arg !== "--strict-config"),
launchArgs: codexMcpListLaunchArgs(launchArgs),
Comment thread
maria-rcks marked this conversation as resolved.
Resolved
}).pipe(Effect.map(codexMcpServersOff));
const spawnCommand = yield* resolveSpawnCommand(
binary,
[
"exec",
...execLaunchArgs,
...codexExecLaunchArgs(launchArgs),
// A user's MCP server could act on the text-generation prompt.
...CODEX_NO_PLUGIN_ARGS,
...(mcpServersOff ? ["--config", mcpServersOff] : []),
Expand Down
Loading