feat(M1): Codex Reliability Fix

This commit is contained in:
2026-05-19 19:54:27 -05:00
parent 5b78889b09
commit bcddb42608
4 changed files with 52 additions and 23 deletions
+6 -2
View File
@@ -118,8 +118,10 @@ export async function main(
} }
const config = resolveConfig(); const config = resolveConfig();
const parsedTimeout =
typeof args.timeout === "string" ? Number(args.timeout) : undefined;
const timeoutMs = const timeoutMs =
typeof args.timeout === "string" ? Number(args.timeout) : config.timeout; Number.isFinite(parsedTimeout) ? parsedTimeout : config.timeout;
try { try {
const result = await executePrompt(client, prompt, { const result = await executePrompt(client, prompt, {
@@ -178,8 +180,10 @@ export async function main(
return 1; return 1;
} }
const parsedTimeout =
typeof args.timeout === "string" ? Number(args.timeout) : undefined;
const timeoutMs = const timeoutMs =
typeof args.timeout === "string" ? Number(args.timeout) : config.timeout; Number.isFinite(parsedTimeout) ? parsedTimeout : config.timeout;
try { try {
const result = await executePrompt(client, prompt, { const result = await executePrompt(client, prompt, {
+1 -2
View File
@@ -1,3 +1,4 @@
import { CLIENT_NAMES } from "./constants.js";
import type { ClientName } from "./types.js"; import type { ClientName } from "./types.js";
export interface DispatchConfig { export interface DispatchConfig {
@@ -5,8 +6,6 @@ export interface DispatchConfig {
client?: ClientName; client?: ClientName;
} }
const CLIENT_NAMES: ClientName[] = ["codex", "claude", "opencode"];
export function resolveClient( export function resolveClient(
prompt: string, prompt: string,
config?: DispatchConfig config?: DispatchConfig
-19
View File
@@ -27,25 +27,6 @@ export interface DebugInfo {
noisySuccess: boolean; noisySuccess: boolean;
} }
export interface DispatchConfigFile {
paths?: Partial<Record<ClientName, string>>;
defaultClient?: ClientName;
timeout?: number;
}
export interface DispatchEnv {
AI_CLI_DEFAULT_CLIENT?: string;
AI_CLI_TIMEOUT?: string;
AI_CLI_CODEX_PATH?: string;
AI_CLI_CLAUDE_PATH?: string;
AI_CLI_OPENCODE_PATH?: string;
}
export interface ToolConfig {
clients: ClientName[];
defaultClient?: ClientName;
}
export class ClientNotFoundError extends Error { export class ClientNotFoundError extends Error {
constructor(client: string) { constructor(client: string) {
super(`Client "${client}" not found or not installed.`); super(`Client "${client}" not found or not installed.`);
+45
View File
@@ -452,6 +452,51 @@ describe("main", () => {
} }
}); });
it("run ignores non-numeric --timeout and falls back to config timeout", async () => {
const out = captureOutput();
try {
let receivedTimeout: number | undefined;
const code = await main(
["node", "cli.ts", "run", "--client", "codex", "--prompt", "hello", "--timeout", "not-a-number"],
{
detectClients: () => mockClients,
executePrompt: async (_client, _prompt, options?) => {
receivedTimeout = options?.timeoutMs;
return mockResult;
},
resolveConfig: () => ({ paths: {}, timeout: 600_000 }),
}
);
assert.strictEqual(code, 0);
assert.strictEqual(receivedTimeout, 600_000);
} finally {
out.restore();
}
});
it("dispatch ignores non-numeric --timeout and falls back to config timeout", async () => {
const out = captureOutput();
try {
let receivedTimeout: number | undefined;
const code = await main(
["node", "cli.ts", "dispatch", "do something", "--timeout", "bad"],
{
detectClients: () => mockClients,
executePrompt: async (_client, _prompt, options?) => {
receivedTimeout = options?.timeoutMs;
return mockResult;
},
resolveClient: () => "codex",
resolveConfig: () => ({ paths: {}, timeout: 600_000 }),
}
);
assert.strictEqual(code, 0);
assert.strictEqual(receivedTimeout, 600_000);
} finally {
out.restore();
}
});
it("dispatch prints debug diagnostic JSON to stderr with --debug", async () => { it("dispatch prints debug diagnostic JSON to stderr with --debug", async () => {
const out = captureOutput(); const out = captureOutput();
const stderrChunks: string[] = []; const stderrChunks: string[] = [];