sync latest local runtime changes

This commit is contained in:
cc-dan
2026-03-18 11:05:01 +00:00
parent e40f841649
commit c2427807e9
4 changed files with 135 additions and 26 deletions

View File

@@ -349,11 +349,19 @@ async function main() {
assert(codexConfigMsg.config.supportsSearch === false, 'Codex config should expose unsupported search capability');
assert(codexConfigMsg.config.enableSearch === false, 'Codex config should ignore unsupported search toggle');
ws.send(JSON.stringify({ type: 'new_session', agent: 'codex', cwd: '/tmp/codex-space', mode: 'plan' }));
const codexSession = await nextMessage(messages, ws, (msg) => msg.type === 'session_info' && msg.agent === 'codex' && msg.cwd === '/tmp/codex-space');
const codexInitCwd = path.join(tempRoot, 'codex-space');
mkdirp(codexInitCwd);
ws.send(JSON.stringify({ type: 'new_session', agent: 'codex', cwd: codexInitCwd, mode: 'plan' }));
const codexSession = await nextMessage(messages, ws, (msg) => msg.type === 'session_info' && msg.agent === 'codex' && msg.cwd === codexInitCwd);
assert(codexSession.mode === 'plan', 'Codex new_session should follow requested mode');
assert(codexSession.model === 'gpt-5.4', 'Codex new_session should inject default model gpt-5.4');
ws.send(JSON.stringify({ type: 'message', text: '/init', sessionId: codexSession.sessionId, mode: 'plan', agent: 'codex' }));
const codexInitStart = await nextMessage(messages, ws, (msg) => msg.type === 'system_message' && /AGENTS\.md/.test(msg.message || ''));
assert(/AGENTS\.md/.test(codexInitStart.message || ''), 'Codex /init should announce AGENTS.md generation');
await nextMessage(messages, ws, (msg) => msg.type === 'done' && msg.sessionId === codexSession.sessionId);
assert(fs.existsSync(path.join(codexInitCwd, 'AGENTS.md')), 'Codex /init should generate AGENTS.md in the workspace');
ws.send(JSON.stringify({ type: 'message', text: '/model gpt-5.3-codex', sessionId: codexSession.sessionId, mode: 'plan', agent: 'codex' }));
const codexModelChanged = await nextMessage(messages, ws, (msg) => msg.type === 'model_changed' && msg.model === 'gpt-5.3-codex');
assert(codexModelChanged.model === 'gpt-5.3-codex', 'Codex /model should accept arbitrary Codex model names');
@@ -393,14 +401,14 @@ async function main() {
.find((line) => line.includes(`"event":"process_spawn"`) && line.includes(firstMessageSession.sessionId.slice(0, 8)));
assert(spawnLine && !spawnLine.includes('--search') && spawnLine.includes('--image'), 'Codex exec should attach images and not append unsupported --search flag');
const allSpawnsForSession = processLog
.trim()
.split('\n')
.filter((line) => line.includes(`"event":"process_spawn"`) && line.includes(firstMessageSession.sessionId.slice(0, 8)));
const lastSpawn = allSpawnsForSession[allSpawnsForSession.length - 1] || '';
assert(lastSpawn.includes('resume') && lastSpawn.includes(threadIdBeforeMode), 'Codex mode switch should keep resume thread id');
assert(lastSpawn.includes('-s read-only'), 'Codex plan mode should set sandbox read-only');
assert(lastSpawn.includes('-s read-only resume'), 'Codex resume in plan mode must place -s before resume subcommand');
const allSpawnsForSession = processLog
.trim()
.split('\n')
.filter((line) => line.includes(`"event":"process_spawn"`) && line.includes(firstMessageSession.sessionId.slice(0, 8)));
const lastSpawn = allSpawnsForSession[allSpawnsForSession.length - 1] || '';
assert(lastSpawn.includes('resume') && lastSpawn.includes(threadIdBeforeMode), 'Codex mode switch should keep resume thread id');
assert(lastSpawn.includes('-s read-only'), 'Codex plan mode should set sandbox read-only');
assert(lastSpawn.includes('-s read-only resume'), 'Codex resume in plan mode must place -s before resume subcommand');
const runtimeToml = fs.readFileSync(path.join(configDir, 'codex-runtime-home', 'config.toml'), 'utf8');
assert(runtimeToml.includes('preferred_auth_method = "apikey"'), 'Codex custom profile should write isolated runtime auth mode');
@@ -423,10 +431,16 @@ async function main() {
assert(/Codex \/compact/.test(autoCompactStart.message || ''), 'Codex auto /compact should announce auto compact start');
const autoCompactDone = await nextMessage(messages, ws, (msg) => msg.type === 'system_message' && /已执行 Codex \/compact/.test(msg.message || ''));
assert(/已执行 Codex \/compact/.test(autoCompactDone.message || ''), 'Codex auto /compact should finish compact step');
const autoCompactResume = await nextMessage(messages, ws, (msg) => msg.type === 'system_message' && /按 Codex 压缩计划继续执行/.test(msg.message || ''));
assert(/继续执行/.test(autoCompactResume.message || ''), 'Codex auto /compact should announce retry');
const autoCompactRetryText = await nextMessage(messages, ws, (msg) => msg.type === 'text_delta' && /trigger codex context limit/.test(msg.text || ''), 8000);
assert(/trigger codex context limit/.test(autoCompactRetryText.text || ''), 'Codex auto /compact should replay the failed prompt after compact');
const autoCompactResume = await nextMessage(messages, ws, (msg) => msg.type === 'system_message' && /按 Codex 压缩计划继续执行/.test(msg.message || ''));
assert(/继续执行/.test(autoCompactResume.message || ''), 'Codex auto /compact should announce retry');
// Some Codex builds won't echo the original prompt text as a text delta on retry; accept either.
const autoCompactRetry = await nextMessage(messages, ws, (msg) => (
(msg.type === 'text_delta' && /trigger codex context limit/.test(msg.text || '')) ||
(msg.type === 'done' && msg.sessionId === autoCompactSession.sessionId)
), 20000);
if (autoCompactRetry.type === 'text_delta') {
assert(/trigger codex context limit/.test(autoCompactRetry.text || ''), 'Codex auto /compact should replay the failed prompt after compact');
}
const claudeAttachment = await uploadAttachment(port, token, {
filename: 'claude-test.png',