Add Codex multi-agent timeline support (#588)

* checkpoint codex multiagent UI state

* fix codex multiagent event scoping

* fix: stabilize codex subagent timeline

* chore: remove codex subagent nesting prompt

* test(web): stabilize tool result rendering tests

* fix: collapse codex agent trace rows by default

* fix(web): keep chat scrolled to bottom

* fix(web): backfill agent-run-heavy message loads

* fix(codex): fail stuck subagent spawns

* fix(codex): preserve wrapped child event scope

* fix(codex): surface agent tool completions
This commit is contained in:
SmallSpider
2026-05-07 10:46:16 +08:00
committed by GitHub
parent 0006d04f9e
commit 841b7cc035
31 changed files with 5745 additions and 152 deletions
+28 -7
View File
@@ -1,9 +1,16 @@
import { describe, expect, it } from 'vitest';
import { buildThreadStartParams, buildTurnStartParams } from './appServerConfig';
import {
buildThreadStartParams,
buildTurnStartParams,
codexCollaborationSpawnAgentInstructions
} from './appServerConfig';
import { codexSystemPrompt } from './systemPrompt';
describe('appServerConfig', () => {
const mcpServers = { hapi: { command: 'node', args: ['mcp'] } };
const withCollaborationInstructions = (developerInstructions: string): string => {
return `${developerInstructions}\n\n${codexCollaborationSpawnAgentInstructions}`;
};
it('applies CLI overrides when permission mode is default', () => {
const params = buildThreadStartParams({
@@ -122,7 +129,7 @@ describe('appServerConfig', () => {
settings: {
model: 'o3',
reasoning_effort: 'high',
developer_instructions: codexSystemPrompt
developer_instructions: withCollaborationInstructions(codexSystemPrompt)
}
});
expect(params.model).toBeUndefined();
@@ -146,7 +153,7 @@ describe('appServerConfig', () => {
settings: {
model: 'o3',
reasoning_effort: 'high',
developer_instructions: codexSystemPrompt
developer_instructions: withCollaborationInstructions(codexSystemPrompt)
}
});
expect(params.model).toBeUndefined();
@@ -165,11 +172,25 @@ describe('appServerConfig', () => {
mode: 'plan',
settings: {
model: 'o3',
developer_instructions: `${codexSystemPrompt}\n\nOnly respond in Chinese.`
developer_instructions: withCollaborationInstructions(`${codexSystemPrompt}\n\nOnly respond in Chinese.`)
}
});
});
it('injects spawn_agent argument rules into collaboration mode instructions', () => {
const params = buildTurnStartParams({
threadId: 'thread-1',
message: 'hello',
cwd: '/workspace/project',
mode: { permissionMode: 'default', model: 'o3', collaborationMode: 'default' }
});
const instructions = params.collaborationMode?.settings.developer_instructions;
expect(instructions).toContain('If you call spawn_agent with fork_context: true');
expect(instructions).toContain('do not set agent_type, model, or reasoning_effort');
expect(instructions).toContain('omit fork_context or set fork_context: false');
});
it('rejects collaboration mode payloads without a resolved model', () => {
expect(() => buildTurnStartParams({
threadId: 'thread-1',
@@ -194,7 +215,7 @@ describe('appServerConfig', () => {
mode: 'default',
settings: {
model: 'o3',
developer_instructions: codexSystemPrompt
developer_instructions: withCollaborationInstructions(codexSystemPrompt)
}
});
});
@@ -214,7 +235,7 @@ describe('appServerConfig', () => {
mode: 'default',
settings: {
model: 'o3',
developer_instructions: codexSystemPrompt
developer_instructions: withCollaborationInstructions(codexSystemPrompt)
}
});
});
@@ -233,7 +254,7 @@ describe('appServerConfig', () => {
mode: 'default',
settings: {
model: 'gpt-5',
developer_instructions: codexSystemPrompt
developer_instructions: withCollaborationInstructions(codexSystemPrompt)
}
});
expect(params.model).toBeUndefined();