feat(12-03): add decompose mode support to ClaudeAgentManager
- Import decomposeOutputSchema and decomposeOutputJsonSchema from schema.ts - Update getJsonSchemaForMode() to handle 'decompose' mode - Add handleDecomposeOutput() method following pattern of handleBreakdownOutput() - Update handleAgentCompletion() switch to call handleDecomposeOutput for decompose mode - Handle decompose_complete/questions/unrecoverable_error statuses
This commit is contained in:
@@ -33,6 +33,8 @@ import {
|
|||||||
discussOutputJsonSchema,
|
discussOutputJsonSchema,
|
||||||
breakdownOutputSchema,
|
breakdownOutputSchema,
|
||||||
breakdownOutputJsonSchema,
|
breakdownOutputJsonSchema,
|
||||||
|
decomposeOutputSchema,
|
||||||
|
decomposeOutputJsonSchema,
|
||||||
} from './schema.js';
|
} from './schema.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,6 +85,8 @@ export class ClaudeAgentManager implements AgentManager {
|
|||||||
return discussOutputJsonSchema;
|
return discussOutputJsonSchema;
|
||||||
case 'breakdown':
|
case 'breakdown':
|
||||||
return breakdownOutputJsonSchema;
|
return breakdownOutputJsonSchema;
|
||||||
|
case 'decompose':
|
||||||
|
return decomposeOutputJsonSchema;
|
||||||
case 'execute':
|
case 'execute':
|
||||||
default:
|
default:
|
||||||
return agentOutputJsonSchema;
|
return agentOutputJsonSchema;
|
||||||
@@ -194,6 +198,9 @@ export class ClaudeAgentManager implements AgentManager {
|
|||||||
case 'breakdown':
|
case 'breakdown':
|
||||||
await this.handleBreakdownOutput(agent, rawOutput);
|
await this.handleBreakdownOutput(agent, rawOutput);
|
||||||
break;
|
break;
|
||||||
|
case 'decompose':
|
||||||
|
await this.handleDecomposeOutput(agent, rawOutput);
|
||||||
|
break;
|
||||||
case 'execute':
|
case 'execute':
|
||||||
default:
|
default:
|
||||||
await this.handleExecuteOutput(agent, rawOutput, cliResult.session_id);
|
await this.handleExecuteOutput(agent, rawOutput, cliResult.session_id);
|
||||||
@@ -473,6 +480,95 @@ export class ClaudeAgentManager implements AgentManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle output for decompose mode.
|
||||||
|
* Outputs tasks array when phase decomposition is complete.
|
||||||
|
*/
|
||||||
|
private async handleDecomposeOutput(
|
||||||
|
agent: { id: string; name: string; taskId: string | null },
|
||||||
|
rawOutput: unknown
|
||||||
|
): Promise<void> {
|
||||||
|
const decomposeOutput = decomposeOutputSchema.parse(rawOutput);
|
||||||
|
const active = this.activeAgents.get(agent.id);
|
||||||
|
|
||||||
|
switch (decomposeOutput.status) {
|
||||||
|
case 'decompose_complete': {
|
||||||
|
if (active) {
|
||||||
|
active.result = {
|
||||||
|
success: true,
|
||||||
|
message: `Decompose complete with ${decomposeOutput.tasks.length} tasks`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
await this.repository.updateStatus(agent.id, 'idle');
|
||||||
|
|
||||||
|
if (this.eventBus) {
|
||||||
|
const event: AgentStoppedEvent = {
|
||||||
|
type: 'agent:stopped',
|
||||||
|
timestamp: new Date(),
|
||||||
|
payload: {
|
||||||
|
agentId: agent.id,
|
||||||
|
name: agent.name,
|
||||||
|
taskId: agent.taskId ?? '',
|
||||||
|
reason: 'decompose_complete',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
this.eventBus.emit(event);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'questions': {
|
||||||
|
if (active) {
|
||||||
|
active.pendingQuestions = {
|
||||||
|
questions: decomposeOutput.questions,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
await this.repository.updateStatus(agent.id, 'waiting_for_input');
|
||||||
|
|
||||||
|
if (this.eventBus) {
|
||||||
|
const event: AgentWaitingEvent = {
|
||||||
|
type: 'agent:waiting',
|
||||||
|
timestamp: new Date(),
|
||||||
|
payload: {
|
||||||
|
agentId: agent.id,
|
||||||
|
name: agent.name,
|
||||||
|
taskId: agent.taskId ?? '',
|
||||||
|
sessionId: '',
|
||||||
|
questions: decomposeOutput.questions,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
this.eventBus.emit(event);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'unrecoverable_error': {
|
||||||
|
if (active) {
|
||||||
|
active.result = {
|
||||||
|
success: false,
|
||||||
|
message: decomposeOutput.error,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
await this.repository.updateStatus(agent.id, 'crashed');
|
||||||
|
|
||||||
|
if (this.eventBus) {
|
||||||
|
const event: AgentCrashedEvent = {
|
||||||
|
type: 'agent:crashed',
|
||||||
|
timestamp: new Date(),
|
||||||
|
payload: {
|
||||||
|
agentId: agent.id,
|
||||||
|
name: agent.name,
|
||||||
|
taskId: agent.taskId ?? '',
|
||||||
|
error: decomposeOutput.error,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
this.eventBus.emit(event);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle agent errors - actual crashes (not waiting for input).
|
* Handle agent errors - actual crashes (not waiting for input).
|
||||||
* With structured output via --json-schema, question status is handled in
|
* With structured output via --json-schema, question status is handled in
|
||||||
|
|||||||
Reference in New Issue
Block a user