UNPKG

@dexwox-labs/a2a-server

Version:

TypeScript server implementation for Google's Agent-to-Agent (A2A) protocol - includes Express/WebSocket handlers, request validation and queue management

156 lines (141 loc) 5.33 kB
/** * @module AgentExecutor * @description Interfaces and implementations for executing agent tasks * * This module provides the interfaces and implementations for executing tasks * on behalf of agents in the A2A protocol. It handles task lifecycle management, * status updates, and event publishing. */ import { EventQueue } from './event-queue'; import { RequestContext } from './request-context'; /** * Interface for executing agent tasks * * This interface defines the contract for executing tasks on behalf of agents. * Implementations are responsible for handling task execution, cancellation, * and lifecycle management. * * @example * ```typescript * class CustomAgentExecutor implements AgentExecutor { * async execute(context: RequestContext, eventQueue: EventQueue): Promise<void> { * // Custom execution logic * console.log(`Executing task ${context.task.id}`); * * // Publish events * eventQueue.publish({ * type: 'task.updated', * payload: { taskId: context.task.id, status: 'working' } * }); * } * * async cancel(context: RequestContext, eventQueue: EventQueue): Promise<void> { * // Custom cancellation logic * console.log(`Canceling task ${context.task.id}`); * } * } * ``` */ export interface AgentExecutor { /** * Execute a task with the given context * @param context Request context including task details * @param eventQueue Event queue for publishing task events */ execute(context: RequestContext, eventQueue: EventQueue): Promise<void>; /** * Cancel an ongoing task execution * @param context Request context including task details * @param eventQueue Event queue for publishing cancellation events */ cancel(context: RequestContext, eventQueue: EventQueue): Promise<void>; } import { TaskManager } from '../tasks/task-manager'; import { TaskEventManager } from './task-event-manager'; import { Task, InvalidTaskStateError, TaskNotFoundError, TaskAlreadyCompletedError, TaskCanceledError, TaskFailedError } from '@dexwox-labs/a2a-core'; /** * Default implementation of the AgentExecutor interface * * This class provides a basic implementation of the AgentExecutor interface * that manages task lifecycle, publishes events, and handles errors. It uses * a TaskManager for task persistence and a TaskEventManager for event publishing. * * @example * ```typescript * // Create dependencies * const taskStore = new InMemoryTaskStore(); * const taskManager = new TaskManager(taskStore); * const taskEventManager = new TaskEventManager(); * * // Create the executor * const executor = new DefaultAgentExecutor(taskManager, taskEventManager); * * // Execute a task * await executor.execute( * createRequestContext(task, 'agent-123'), * new EventQueue() * ); * ``` */ export class DefaultAgentExecutor implements AgentExecutor { /** * Creates a new DefaultAgentExecutor * * @param taskManager - The task manager for task persistence * @param taskEventManager - The task event manager for event publishing */ constructor( private taskManager: TaskManager, private taskEventManager: TaskEventManager ) {} /** * Executes a task on behalf of an agent * * This method handles the execution of a task, including updating its status, * publishing events, and handling errors. It transitions the task from its * current state to 'working' and then to 'completed' if successful. * * @param context - The request context containing task and agent information * @param eventQueue - The event queue for publishing events * @returns Promise that resolves when execution is complete * @throws Various task-related errors if execution fails */ async execute(context: RequestContext, eventQueue: EventQueue): Promise<void> { const task = await this.taskManager.getTask(context.task.id); // Update task status to working const workingTask = await this.taskManager.updateTaskStatus(task.id, 'working'); // Publish task update event this.taskEventManager.taskUpdated(workingTask, task.status); try { // TODO: Implement actual agent execution logic // For now we'll simulate successful completion await new Promise(resolve => setTimeout(resolve, 1000)); const completedTask = await this.taskManager.updateTaskStatus(task.id, 'completed'); this.taskEventManager.taskCompleted(completedTask); } catch (error) { const failedTask = await this.taskManager.updateTaskStatus(task.id, 'failed'); const normalizedError = error instanceof Error ? error : new Error(error instanceof Object ? JSON.stringify(error) : String(error)); this.taskEventManager.taskFailed(failedTask, normalizedError); throw normalizedError; } } async cancel(context: RequestContext, eventQueue: EventQueue): Promise<void> { const task = await this.taskManager.getTask(context.task.id); if (['completed', 'failed', 'canceled'].includes(task.status)) { throw new InvalidTaskStateError( `Task ${task.id} is already in terminal state: ${task.status}` ); } await this.taskManager.cancelTask(task.id); this.taskEventManager.taskCanceled(task); } }