fix(local-agents): support current Codex exec CLI (#95)

This commit is contained in:
Joseph Magly authored and GitHub committed 2026-07-15 19:09:34 -04:00
1 parent 4b81bf6436
commit 51f610f3a5
2 files changed
+16 -8

No files matched your search

+12 -2
View File
@@ -126,7 +126,17 @@ const SPECS: AgentSpec[] = [
versionArgs: ['--version'], versionArgs: ['--version'],
parseVersion: (o) => (o.match(/[\d]+\.[\d]+(\.[\d]+)?/) || ['?'])[0], parseVersion: (o) => (o.match(/[\d]+\.[\d]+(\.[\d]+)?/) || ['?'])[0],
authArtifacts: ['~/.codex/auth.json', '~/.config/codex/auth.json'], authArtifacts: ['~/.codex/auth.json', '~/.config/codex/auth.json'],
oneShot: (p, m) => ['exec', ...(m ? ['-m', m] : []), p], oneShot: (p, m) => [
'exec',
'--ephemeral',
'--skip-git-repo-check',
'--sandbox',
'read-only',
'--color',
'never',
...(m ? ['-m', m] : []),
p,
],
}, },
{ {
id: 'hermes', id: 'hermes',
@@ -322,7 +332,7 @@ export function localAgentChat(id: string, prompt: string, opts: { model?: strin
} else if (id === 'codex') { } else if (id === 'codex') {
workDir = mkdtempSync(join(tmpdir(), 't3mp3st-codexllm-')); workDir = mkdtempSync(join(tmpdir(), 't3mp3st-codexllm-'));
outFile = join(workDir, 'reply.txt'); outFile = join(workDir, 'reply.txt');
args = ['exec', '--skip-git-repo-check', '--color', 'never', '--sandbox', 'read-only', '--output-last-message', outFile, ...(model ? ['-m', model] : [])]; args = ['exec', '--ephemeral', '--skip-git-repo-check', '--color', 'never', '--sandbox', 'read-only', '--output-last-message', outFile, ...(model ? ['-m', model] : [])];
} else { // hermes — takes the prompt as an arg } else { // hermes — takes the prompt as an arg
args = ['-z', prompt, ...(hermesYoloEnabled() ? ['--yolo'] : []), ...(model ? ['-m', model] : [])]; args = ['-z', prompt, ...(hermesYoloEnabled() ? ['--yolo'] : []), ...(model ? ['-m', model] : [])];
viaStdin = false; viaStdin = false;
+4 -6
View File
@@ -6654,8 +6654,6 @@ function bringUpMissionFromPlan(
async function runCodexExecReadinessProbe(command: string): Promise<{ stdout: string; stderr: string }> { async function runCodexExecReadinessProbe(command: string): Promise<{ stdout: string; stderr: string }> {
const marker = 'T3MP3ST_CODEX_READY'; const marker = 'T3MP3ST_CODEX_READY';
const args = [ const args = [
'--ask-for-approval',
'never',
'exec', 'exec',
'-c', '-c',
'model_reasoning_effort="low"', 'model_reasoning_effort="low"',
@@ -6681,7 +6679,7 @@ async function runCodexExecReadinessProbe(command: string): Promise<{ stdout: st
const timer = setTimeout(() => { const timer = setTimeout(() => {
child.kill('SIGTERM'); child.kill('SIGTERM');
reject(new Error('Codex exec readiness probe timed out')); reject(new Error('Codex exec readiness probe timed out'));
}, 30000); }, 60000);
// Bounded accumulation so a runaway/verbose child can't grow these strings without limit // Bounded accumulation so a runaway/verbose child can't grow these strings without limit
// before the 30s timer fires (matches the local-agent caps). A normal probe emits a tiny // before the 30s timer fires (matches the local-agent caps). A normal probe emits a tiny
@@ -6733,7 +6731,7 @@ app.get('/api/codex/status', async (_req: Request, res: Response): Promise<void>
tokenHandling: 'no token is accepted by or returned from T3MP3ST', tokenHandling: 'no token is accepted by or returned from T3MP3ST',
command, command,
version: stdout.trim(), version: stdout.trim(),
executionMode: 'codex exec --ephemeral --sandbox read-only --ask-for-approval never', executionMode: 'codex exec --ephemeral --sandbox read-only',
execProbe: 'POST /api/codex/probe', // exec self-test moved off GET (B-04) execProbe: 'POST /api/codex/probe', // exec self-test moved off GET (B-04)
}); });
} catch (error: any) { } catch (error: any) {
@@ -6753,7 +6751,7 @@ app.post('/api/codex/probe', async (_req: Request, res: Response): Promise<void>
provider: 'codex', provider: 'codex',
command, command,
version: stdout.trim(), version: stdout.trim(),
executionMode: 'codex exec --ephemeral --sandbox read-only --ask-for-approval never', executionMode: 'codex exec --ephemeral --sandbox read-only',
}; };
try { try {
const probe = await runCodexExecReadinessProbe(command); const probe = await runCodexExecReadinessProbe(command);
@@ -7472,7 +7470,7 @@ type ConnectedLocalAgent = {
}; };
const connectedLocalAgents = new Map<string, ConnectedLocalAgent>(); const connectedLocalAgents = new Map<string, ConnectedLocalAgent>();
const LOCAL_AGENT_HEALTH_TTL_MS = 30_000; const LOCAL_AGENT_HEALTH_TTL_MS = 30_000;
const LOCAL_AGENT_HEALTH_TIMEOUT_MS = 15_000; const LOCAL_AGENT_HEALTH_TIMEOUT_MS = 45_000;
async function refreshConnectedLocalAgentHealth(force = false): Promise<void> { async function refreshConnectedLocalAgentHealth(force = false): Promise<void> {
const now = Date.now(); const now = Date.now();