feat: Auto-resume idle agents for inter-agent conversations
When an agent asks a question via `cw ask` targeting an idle agent, the conversation router now auto-resumes the idle agent's session so it can answer. Previously, questions to idle agents sat unanswered forever because target resolution only matched running agents. Changes: - Add `resumeForConversation()` to AgentManager interface and implement on MultiProviderAgentManager (mirrors resumeForCommit pattern) - Relax createConversation target resolution: prefer running, fall back to idle (was running-only) - Trigger auto-resume after conversation creation for idle targets - Add concurrency lock (conversationResumeLocks Set) to prevent double-resume race conditions
This commit is contained in:
@@ -471,6 +471,42 @@ export class MockAgentManager implements AgentManager {
|
||||
record.info.updatedAt = now;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resume an idle agent to answer an inter-agent conversation.
|
||||
* Mock implementation: marks agent as running and schedules immediate completion.
|
||||
*/
|
||||
async resumeForConversation(
|
||||
agentId: string,
|
||||
conversationId: string,
|
||||
question: string,
|
||||
fromAgentId: string,
|
||||
): Promise<boolean> {
|
||||
const record = this.agents.get(agentId);
|
||||
if (!record || record.info.status !== 'idle' || !record.info.sessionId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
record.info.status = 'running';
|
||||
record.info.updatedAt = new Date();
|
||||
|
||||
if (this.eventBus) {
|
||||
const event: AgentResumedEvent = {
|
||||
type: 'agent:resumed',
|
||||
timestamp: new Date(),
|
||||
payload: {
|
||||
agentId,
|
||||
name: record.info.name,
|
||||
taskId: record.info.taskId,
|
||||
sessionId: record.info.sessionId,
|
||||
},
|
||||
};
|
||||
this.eventBus.emit(event);
|
||||
}
|
||||
|
||||
this.scheduleCompletion(agentId, { status: 'done', delay: 0, result: 'Answered conversation' });
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all agents and pending timers.
|
||||
* Useful for test cleanup.
|
||||
|
||||
@@ -237,4 +237,24 @@ export interface AgentManager {
|
||||
* @param agentId - Agent to dismiss
|
||||
*/
|
||||
dismiss(agentId: string): Promise<void>;
|
||||
|
||||
/**
|
||||
* Resume an idle agent to answer an inter-agent conversation.
|
||||
*
|
||||
* When Agent A asks Agent B a question via `cw ask` and Agent B is idle,
|
||||
* this resumes B's session with a prompt to answer via `cw answer` and
|
||||
* drain any remaining pending conversations via `cw listen`.
|
||||
*
|
||||
* @param agentId - The idle agent to resume
|
||||
* @param conversationId - The conversation that triggered the resume
|
||||
* @param question - The question being asked
|
||||
* @param fromAgentId - The agent asking the question
|
||||
* @returns true if resume was initiated, false if not possible
|
||||
*/
|
||||
resumeForConversation(
|
||||
agentId: string,
|
||||
conversationId: string,
|
||||
question: string,
|
||||
fromAgentId: string,
|
||||
): Promise<boolean>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user