feat(08.1-02): update MockAgentManager to schema-aligned scenarios

- Change MockAgentScenario from outcome-based to status-based discriminated union
- Align with agent output schema: done/question/unrecoverable_error
- Update completeAgent() to handle new status types
- Update resume() to use new scenario format
This commit is contained in:
Lukas May
2026-01-31 15:28:38 +01:00
parent ee0d6eae33
commit ead4614383

View File

@@ -26,23 +26,28 @@ import type {
/**
* Scenario configuration for mock agent behavior.
* Uses discriminated union on status to match agent output schema.
*/
export interface MockAgentScenario {
/** How agent completes: 'success' | 'crash' | 'waiting_for_input' */
outcome: 'success' | 'crash' | 'waiting_for_input';
/** Delay before completion (ms). Default 0 for synchronous tests. */
delay?: number;
/** Result message for success/crash */
message?: string;
/** Files modified (for success) */
filesModified?: string[];
/** Question to surface (for waiting_for_input) */
question?: string;
/** Options for question (for waiting_for_input) */
options?: Array<{ label: string; description?: string }>;
/** Whether multiple options can be selected (for waiting_for_input) */
multiSelect?: boolean;
}
export type MockAgentScenario =
| {
status: 'done';
result?: string;
filesModified?: string[];
delay?: number;
}
| {
status: 'question';
question: string;
options?: Array<{ label: string; description?: string }>;
multiSelect?: boolean;
delay?: number;
}
| {
status: 'unrecoverable_error';
error: string;
attempted?: string;
delay?: number;
};
/**
* Internal agent record with scenario and timer tracking.
@@ -59,10 +64,10 @@ interface MockAgentRecord {
* Default scenario: immediate success with generic message.
*/
const DEFAULT_SCENARIO: MockAgentScenario = {
outcome: 'success',
delay: 0,
message: 'Task completed successfully',
status: 'done',
result: 'Task completed successfully',
filesModified: [],
delay: 0,
};
/**
@@ -178,7 +183,7 @@ export class MockAgentManager implements AgentManager {
}
/**
* Complete agent based on scenario outcome.
* Complete agent based on scenario status.
*/
private completeAgent(agentId: string, scenario: MockAgentScenario): void {
const record = this.agents.get(agentId);
@@ -186,11 +191,11 @@ export class MockAgentManager implements AgentManager {
const { info } = record;
switch (scenario.outcome) {
case 'success':
switch (scenario.status) {
case 'done':
record.result = {
success: true,
message: scenario.message ?? 'Task completed successfully',
message: scenario.result ?? 'Task completed successfully',
filesModified: scenario.filesModified,
};
record.info.status = 'idle';
@@ -211,10 +216,10 @@ export class MockAgentManager implements AgentManager {
}
break;
case 'crash':
case 'unrecoverable_error':
record.result = {
success: false,
message: scenario.message ?? 'Agent crashed',
message: scenario.error,
};
record.info.status = 'crashed';
record.info.updatedAt = new Date();
@@ -227,18 +232,18 @@ export class MockAgentManager implements AgentManager {
agentId,
name: info.name,
taskId: info.taskId,
error: scenario.message ?? 'Agent crashed',
error: scenario.error,
},
};
this.eventBus.emit(event);
}
break;
case 'waiting_for_input':
case 'question':
record.info.status = 'waiting_for_input';
record.info.updatedAt = new Date();
record.pendingQuestion = {
question: scenario.question ?? 'User input required',
question: scenario.question,
options: scenario.options,
multiSelect: scenario.multiSelect,
};
@@ -252,7 +257,7 @@ export class MockAgentManager implements AgentManager {
name: info.name,
taskId: info.taskId,
sessionId: info.sessionId ?? '',
question: scenario.question ?? 'User input required',
question: scenario.question,
options: scenario.options,
multiSelect: scenario.multiSelect,
},
@@ -369,11 +374,14 @@ export class MockAgentManager implements AgentManager {
// Re-run scenario (after resume, typically completes successfully)
// For testing, we use a new scenario that defaults to success
// Extract filesModified from original scenario if it was a 'done' type
const originalFilesModified =
record.scenario.status === 'done' ? record.scenario.filesModified : undefined;
const resumeScenario: MockAgentScenario = {
outcome: 'success',
status: 'done',
delay: record.scenario.delay ?? 0,
message: 'Resumed and completed successfully',
filesModified: record.scenario.filesModified,
result: 'Resumed and completed successfully',
filesModified: originalFilesModified,
};
this.scheduleCompletion(agentId, resumeScenario);