From b2e7c2920fb6652147cb40b6caa9db9eabe0e46b Mon Sep 17 00:00:00 2001 From: Lukas May Date: Fri, 30 Jan 2026 20:32:43 +0100 Subject: [PATCH] feat(05-03): create DispatchManager port interface - QueuedTask type with priority and dependencies - DispatchResult type for dispatch operation outcomes - DispatchManager interface with queue/dispatch/complete/block methods - Follows hexagonal architecture pattern (same as EventBus, AgentManager) --- src/dispatch/index.ts | 9 ++++ src/dispatch/types.ts | 118 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 src/dispatch/index.ts create mode 100644 src/dispatch/types.ts diff --git a/src/dispatch/index.ts b/src/dispatch/index.ts new file mode 100644 index 0000000..28f9002 --- /dev/null +++ b/src/dispatch/index.ts @@ -0,0 +1,9 @@ +/** + * Dispatch Module - Public API + * + * Exports the DispatchManager port interface and related types. + * All modules should import from this index file. + */ + +// Port interface (what consumers depend on) +export type { DispatchManager, QueuedTask, DispatchResult } from './types.js'; diff --git a/src/dispatch/types.ts b/src/dispatch/types.ts new file mode 100644 index 0000000..137774f --- /dev/null +++ b/src/dispatch/types.ts @@ -0,0 +1,118 @@ +/** + * Dispatch Module Types + * + * Port interface for task dispatch management. + * DispatchManager is the PORT. Implementations are ADAPTERS. + * + * This follows the same hexagonal architecture pattern as EventBus and AgentManager: + * - Interface defines the contract (port) + * - Implementations can be swapped without changing consumers + * - Enables testing with in-memory/mock implementations + */ + +// ============================================================================= +// Dispatch Domain Types +// ============================================================================= + +/** + * Represents a task queued for dispatch. + * Tasks are dispatched when all dependencies complete. + */ +export interface QueuedTask { + /** Unique identifier for the task */ + taskId: string; + /** Task priority level */ + priority: 'low' | 'medium' | 'high'; + /** When the task was queued */ + queuedAt: Date; + /** Task IDs that must complete before this task can be dispatched */ + dependsOn: string[]; +} + +/** + * Result of a dispatch operation. + * Success means task was assigned to an agent; failure means dispatch couldn't happen. + */ +export interface DispatchResult { + /** Whether the task was successfully dispatched */ + success: boolean; + /** ID of the task that was dispatched */ + taskId: string; + /** ID of the agent assigned to the task (only present on success) */ + agentId?: string; + /** Reason why dispatch failed (only present on failure) */ + reason?: string; +} + +// ============================================================================= +// DispatchManager Port Interface +// ============================================================================= + +/** + * DispatchManager Port Interface + * + * Manages task dispatch queue with dependency ordering. + * + * Covers requirements: + * - TASK-04: Dependency-ordered dispatch + * - TASK-05: Work queue for available agents + */ +export interface DispatchManager { + /** + * Queue a task for dispatch. + * Task will be dispatched when all dependencies complete. + * + * @param taskId - ID of the task to queue + */ + queue(taskId: string): Promise; + + /** + * Get next dispatchable task. + * Returns task with all dependencies complete, highest priority first. + * Returns null if no tasks ready. + * + * @returns Next dispatchable task or null + */ + getNextDispatchable(): Promise; + + /** + * Dispatch next available task to an agent. + * Finds available agent, assigns task, spawns agent. + * Returns dispatch result. + * + * @returns Result of the dispatch operation + */ + dispatchNext(): Promise; + + /** + * Mark a task as complete. + * Triggers re-evaluation of dependent tasks. + * + * @param taskId - ID of the completed task + */ + completeTask(taskId: string): Promise; + + /** + * Mark a task as blocked. + * Task will not be dispatched until unblocked. + * + * @param taskId - ID of the task to block + * @param reason - Reason for blocking + */ + blockTask(taskId: string, reason: string): Promise; + + /** + * Get current queue state. + * Returns all queued tasks with their dispatch readiness. + * + * @returns Queue state with queued, ready, and blocked tasks + */ + getQueueState(): Promise<{ + /** All queued tasks */ + queued: QueuedTask[]; + /** Tasks ready for dispatch (all dependencies complete) */ + ready: QueuedTask[]; + /** Tasks that are blocked */ + blocked: Array<{ taskId: string; reason: string }>; + }>; +}