feat(06-02): enhance conflict bounce-back with agent messaging
Adds MessageRepository to DefaultCoordinationManager for conflict notification: - Creates info message to agent when merge conflict occurs - Message includes conflicting file list and resolution instructions - System-generated messages use senderType='user' with null senderId - Refactors conflict description into cleaner array.join format
This commit is contained in:
@@ -18,6 +18,7 @@ import type {
|
||||
import type { WorktreeManager } from '../git/types.js';
|
||||
import type { TaskRepository } from '../db/repositories/task-repository.js';
|
||||
import type { AgentRepository } from '../db/repositories/agent-repository.js';
|
||||
import type { MessageRepository } from '../db/repositories/message-repository.js';
|
||||
import type { CoordinationManager, MergeQueueItem, MergeResult } from './types.js';
|
||||
|
||||
// =============================================================================
|
||||
@@ -55,6 +56,7 @@ export class DefaultCoordinationManager implements CoordinationManager {
|
||||
private worktreeManager?: WorktreeManager,
|
||||
private taskRepository?: TaskRepository,
|
||||
private agentRepository?: AgentRepository,
|
||||
private messageRepository?: MessageRepository,
|
||||
private eventBus?: EventBus
|
||||
) {}
|
||||
|
||||
@@ -257,24 +259,45 @@ export class DefaultCoordinationManager implements CoordinationManager {
|
||||
|
||||
/**
|
||||
* Handle a merge conflict.
|
||||
* Creates a conflict-resolution task and assigns back to the agent.
|
||||
* Creates a conflict-resolution task and notifies the agent via message.
|
||||
*/
|
||||
async handleConflict(taskId: string, conflicts: string[]): Promise<void> {
|
||||
if (!this.taskRepository) {
|
||||
throw new Error('TaskRepository not configured');
|
||||
}
|
||||
|
||||
if (!this.agentRepository) {
|
||||
throw new Error('AgentRepository not configured');
|
||||
}
|
||||
|
||||
// Get original task for context
|
||||
const originalTask = await this.taskRepository.findById(taskId);
|
||||
if (!originalTask) {
|
||||
throw new Error(`Original task not found: ${taskId}`);
|
||||
}
|
||||
|
||||
// Get agent that was working on the task
|
||||
const agent = await this.agentRepository.findByTaskId(taskId);
|
||||
if (!agent) {
|
||||
throw new Error(`No agent found for task: ${taskId}`);
|
||||
}
|
||||
|
||||
// Build conflict description
|
||||
const conflictDescription = [
|
||||
'Merge conflicts detected. Resolve conflicts in the following files:',
|
||||
'',
|
||||
...conflicts.map((f) => `- ${f}`),
|
||||
'',
|
||||
`Original task: ${originalTask.name}`,
|
||||
'',
|
||||
'Instructions: Resolve merge conflicts in the listed files, then mark task complete.',
|
||||
].join('\n');
|
||||
|
||||
// Create new conflict-resolution task
|
||||
const conflictTask = await this.taskRepository.create({
|
||||
planId: originalTask.planId,
|
||||
name: `Resolve conflicts: ${originalTask.name}`,
|
||||
description: `Merge conflicts detected. Resolve conflicts in the following files:\n\n${conflicts.map((f) => `- ${f}`).join('\n')}\n\nOriginal task: ${originalTask.name}\n\nInstructions: Resolve merge conflicts in the listed files, then mark task complete.`,
|
||||
description: conflictDescription,
|
||||
type: 'auto',
|
||||
priority: 'high', // Conflicts should be resolved quickly
|
||||
status: 'pending',
|
||||
@@ -284,6 +307,30 @@ export class DefaultCoordinationManager implements CoordinationManager {
|
||||
// Update original task status to blocked
|
||||
await this.taskRepository.update(taskId, { status: 'blocked' });
|
||||
|
||||
// Create message to agent if messageRepository is configured
|
||||
if (this.messageRepository) {
|
||||
const messageContent = [
|
||||
`Merge conflict detected for task: ${originalTask.name}`,
|
||||
'',
|
||||
'Conflicting files:',
|
||||
...conflicts.map((f) => `- ${f}`),
|
||||
'',
|
||||
`A new task has been created to resolve these conflicts: ${conflictTask.name}`,
|
||||
'',
|
||||
'Please resolve the merge conflicts in the listed files and mark the resolution task as complete.',
|
||||
].join('\n');
|
||||
|
||||
await this.messageRepository.create({
|
||||
senderType: 'user', // System-generated messages appear as from user
|
||||
senderId: null,
|
||||
recipientType: 'agent',
|
||||
recipientId: agent.id,
|
||||
type: 'info',
|
||||
content: messageContent,
|
||||
requiresResponse: false,
|
||||
});
|
||||
}
|
||||
|
||||
// Emit TaskQueuedEvent for the new conflict-resolution task
|
||||
const event: TaskQueuedEvent = {
|
||||
type: 'task:queued',
|
||||
|
||||
Reference in New Issue
Block a user