UNPKG

agentic-qe

Version:

Agentic Quality Engineering Fleet System - AI-driven quality management platform

397 lines 10.7 kB
"use strict"; /** * Task - Represents a unit of work to be executed by agents * * @remarks * The Task class encapsulates all information needed to execute a unit of work * in the AQE Fleet, including data, requirements, status tracking, and results. * * Tasks are automatically assigned to capable agents by the FleetManager and * provide event-based progress tracking. * * @example * ```typescript * // Create a test generation task * const task = new Task( * 'test-generation', * 'Generate unit tests for UserService', * { * filePath: './src/services/UserService.ts', * framework: 'jest', * coverageTarget: 95 * }, * { * capabilities: ['ai-test-generation'], * agentTypes: ['test-generator'] * }, * TaskPriority.HIGH * ); * * // Monitor task progress * task.on('status:changed', (data) => { * console.log(`Task ${data.taskId} status: ${data.newStatus}`); * }); * * await fleet.submitTask(task); * const result = await task.waitForCompletion(); * ``` * * @public */ Object.defineProperty(exports, "__esModule", { value: true }); exports.Task = exports.TaskPriority = exports.TaskStatus = void 0; const uuid_1 = require("uuid"); const events_1 = require("events"); /** * Current execution status of a task * * @public */ var TaskStatus; (function (TaskStatus) { /** Task has been created but not submitted */ TaskStatus["CREATED"] = "created"; /** Task is queued waiting for an available agent */ TaskStatus["QUEUED"] = "queued"; /** Task has been assigned to an agent */ TaskStatus["ASSIGNED"] = "assigned"; /** Task is currently being executed */ TaskStatus["RUNNING"] = "running"; /** Task completed successfully */ TaskStatus["COMPLETED"] = "completed"; /** Task execution failed */ TaskStatus["FAILED"] = "failed"; /** Task was cancelled before completion */ TaskStatus["CANCELLED"] = "cancelled"; })(TaskStatus || (exports.TaskStatus = TaskStatus = {})); /** * Priority level for task execution * * @public */ var TaskPriority; (function (TaskPriority) { /** Low priority task */ TaskPriority[TaskPriority["LOW"] = 0] = "LOW"; /** Medium priority task (default) */ TaskPriority[TaskPriority["MEDIUM"] = 1] = "MEDIUM"; /** High priority task */ TaskPriority[TaskPriority["HIGH"] = 2] = "HIGH"; /** Critical priority task (executed first) */ TaskPriority[TaskPriority["CRITICAL"] = 3] = "CRITICAL"; })(TaskPriority || (exports.TaskPriority = TaskPriority = {})); class Task extends events_1.EventEmitter { constructor(type, name, data = {}, requirements = {}, priority = TaskPriority.MEDIUM) { super(); this.result = null; this.error = null; this.id = (0, uuid_1.v4)(); this.type = type; this.name = name; this.data = data; this.requirements = requirements; this.status = TaskStatus.CREATED; this.priority = priority; this.metadata = { createdAt: new Date(), retryCount: 0, maxRetries: 3 }; } /** * Get task ID * * @returns Unique identifier for this task * @public */ getId() { return this.id; } /** * Get task type * * @returns The type of task (e.g., 'test-generation', 'coverage-analysis') * @public */ getType() { return this.type; } /** * Get task name * * @returns Human-readable name for this task * @public */ getName() { return this.name; } /** * Get task data * * @returns The data payload for task execution * @public */ getData() { return this.data; } /** * Get task requirements */ getRequirements() { return this.requirements; } /** * Get task status */ getStatus() { return this.status; } /** * Set task status and update metadata * * @param status - The new status for the task * @fires status:changed * @public */ setStatus(status) { const previousStatus = this.status; this.status = status; // Update metadata based on status switch (status) { case TaskStatus.RUNNING: this.metadata.startedAt = new Date(); break; case TaskStatus.COMPLETED: case TaskStatus.FAILED: case TaskStatus.CANCELLED: this.metadata.completedAt = new Date(); break; } this.emit('status:changed', { taskId: this.id, previousStatus, newStatus: status, timestamp: new Date() }); } /** * Get task priority */ getPriority() { return this.priority; } /** * Set task priority */ setPriority(priority) { this.priority = priority; this.emit('priority:changed', { taskId: this.id, priority, timestamp: new Date() }); } /** * Get task result */ getResult() { return this.result; } /** * Set task result */ setResult(result) { this.result = result; this.emit('result:set', { taskId: this.id, result, timestamp: new Date() }); } /** * Get task error */ getError() { return this.error; } /** * Set task error */ setError(error) { this.error = error; this.emit('error:set', { taskId: this.id, error, timestamp: new Date() }); } /** * Get task metadata */ getMetadata() { return this.metadata; } /** * Assign agent to task */ assignAgent(agentId) { this.metadata.assignedAgent = agentId; this.setStatus(TaskStatus.ASSIGNED); this.emit('agent:assigned', { taskId: this.id, agentId, timestamp: new Date() }); } /** * Check if task can be retried */ canRetry() { return this.metadata.retryCount < this.metadata.maxRetries; } /** * Increment retry count */ incrementRetry() { this.metadata.retryCount++; this.emit('retry:attempted', { taskId: this.id, retryCount: this.metadata.retryCount, timestamp: new Date() }); } /** * Set maximum retries */ setMaxRetries(maxRetries) { this.metadata.maxRetries = maxRetries; } /** * Set timeout for task execution */ setTimeout(timeout) { this.metadata.timeout = timeout; } /** * Check if task has timed out */ hasTimedOut() { if (!this.metadata.timeout || !this.metadata.startedAt) { return false; } const elapsed = Date.now() - this.metadata.startedAt.getTime(); return elapsed > this.metadata.timeout; } /** * Get task execution duration */ getExecutionDuration() { if (!this.metadata.startedAt) { return null; } const endTime = this.metadata.completedAt || new Date(); return endTime.getTime() - this.metadata.startedAt.getTime(); } /** * Check if task is complete (either completed or failed) */ isComplete() { return this.status === TaskStatus.COMPLETED || this.status === TaskStatus.FAILED || this.status === TaskStatus.CANCELLED; } /** * Wait for task completion * * @remarks * Returns a promise that resolves when the task completes successfully * or rejects if the task fails or is cancelled. * * @returns A promise that resolves to the task result * @throws {Error} If the task fails or is cancelled * * @example * ```typescript * const task = new Task('test-generation', 'Generate tests', data); * await fleet.submitTask(task); * const result = await task.waitForCompletion(); * console.log('Tests generated:', result); * ``` * * @public */ async waitForCompletion() { return new Promise((resolve, reject) => { if (this.isComplete()) { if (this.status === TaskStatus.COMPLETED) { resolve(this.result); } else { reject(this.error || new Error(`Task ${this.id} was ${this.status}`)); } return; } const onStatusChange = (data) => { if (data.taskId === this.id && this.isComplete()) { this.removeListener('status:changed', onStatusChange); if (this.status === TaskStatus.COMPLETED) { resolve(this.result); } else { reject(this.error || new Error(`Task ${this.id} was ${this.status}`)); } } }; this.on('status:changed', onStatusChange); }); } /** * Cancel the task */ cancel() { if (!this.isComplete()) { this.setStatus(TaskStatus.CANCELLED); this.emit('task:cancelled', { taskId: this.id, timestamp: new Date() }); } } /** * Convert task to JSON representation */ toJSON() { return { id: this.id, type: this.type, name: this.name, data: this.data, requirements: this.requirements, status: this.status, priority: this.priority, result: this.result, error: this.error?.message, metadata: this.metadata }; } /** * Create task from JSON representation */ static fromJSON(json) { const task = new Task(json.type, json.name, json.data, json.requirements, json.priority); task.status = json.status; task.result = json.result; if (json.error) { task.error = new Error(json.error); } task.metadata = { ...json.metadata, createdAt: new Date(json.metadata.createdAt), startedAt: json.metadata.startedAt ? new Date(json.metadata.startedAt) : undefined, completedAt: json.metadata.completedAt ? new Date(json.metadata.completedAt) : undefined }; return task; } } exports.Task = Task; //# sourceMappingURL=Task.js.map