UNPKG

@dexwox-labs/a2a-core

Version:

Core types, validation and telemetry for Google's Agent-to-Agent (A2A) protocol - shared foundation for client and server implementations

177 lines 5.88 kB
"use strict"; /** * @module TaskUtils * @description Utilities for working with tasks in the A2A protocol * * This module provides utility functions for validating and managing tasks * in the A2A protocol. Tasks are the primary unit of work in the protocol and * follow a specific state machine with defined transitions. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.TaskErrorCode = void 0; exports.validateTransition = validateTransition; exports.validateTask = validateTask; exports.createTransition = createTransition; const errors_1 = require("../errors"); /** * Error codes specific to task operations * * These error codes are used to identify specific issues that can occur * when working with tasks, such as invalid state transitions or missing * required properties. */ var TaskErrorCode; (function (TaskErrorCode) { /** Error code when a task state transition is invalid (-32070) */ TaskErrorCode[TaskErrorCode["InvalidTransition"] = -32070] = "InvalidTransition"; /** Error code when a task is missing a required ID (-32071) */ TaskErrorCode[TaskErrorCode["MissingTaskId"] = -32071] = "MissingTaskId"; /** Error code when a task state is invalid (-32072) */ TaskErrorCode[TaskErrorCode["InvalidState"] = -32072] = "InvalidState"; })(TaskErrorCode || (exports.TaskErrorCode = TaskErrorCode = {})); /** * Map of valid task state transitions * * This constant defines the valid state transitions for tasks in the A2A protocol. * Each key represents a current state, and the array value contains all valid * next states. Empty arrays indicate terminal states with no valid transitions. * * The state machine follows these rules: * - submitted → working, failed, canceled * - working → input_required, completed, failed, canceled * - input_required → working, failed, canceled * - completed → (terminal state, no transitions) * - failed → (terminal state, no transitions) * - canceled → (terminal state, no transitions) * * @internal */ const VALID_TRANSITIONS = { submitted: ['working', 'failed', 'canceled'], working: ['input_required', 'completed', 'failed', 'canceled'], input_required: ['working', 'failed', 'canceled'], completed: [], failed: [], canceled: [] }; /** * Validates that a task state transition is allowed * * This function checks if a proposed state transition follows the rules of the * task state machine. It throws an error if the transition is not allowed. * * @param current - Current task state * @param next - Proposed next state * @throws {A2AError} If the transition is invalid * * @example * ```typescript * try { * // Valid transition * validateTransition('submitted', 'working'); * console.log('Transition is valid'); * * // Invalid transition * validateTransition('completed', 'working'); * } catch (error) { * console.error('Invalid transition:', error.message); * // Output: Invalid transition: Invalid transition from completed to working * } * ``` */ function validateTransition(current, next) { if (!VALID_TRANSITIONS[current].includes(next)) { throw new errors_1.A2AError(`Invalid transition from ${current} to ${next}`, TaskErrorCode.InvalidTransition); } } /** * Validates that a task has all required properties and a valid state * * This function checks that a task has a valid ID and state. It throws * appropriate errors if validation fails, which can be caught and handled * by the caller. * * @param task - Task object to validate * @throws {A2AError} If validation fails, with specific error codes * * @example * ```typescript * try { * // Valid task * validateTask({ * id: 'task-123', * name: 'Example Task', * status: 'working', * createdAt: new Date().toISOString(), * updatedAt: new Date().toISOString() * }); * console.log('Task is valid'); * * // This would throw an error * validateTask({ * name: 'Invalid Task', // Missing ID * status: 'working', * createdAt: new Date().toISOString(), * updatedAt: new Date().toISOString() * }); * } catch (error) { * console.error('Validation failed:', error.message); * } * ``` */ function validateTask(task) { if (!task.id) { throw new errors_1.A2AError('Task missing required id', TaskErrorCode.MissingTaskId); } if (!Object.keys(VALID_TRANSITIONS).includes(task.status)) { throw new errors_1.A2AError(`Invalid task state: ${task.status}`, TaskErrorCode.InvalidState); } } /** * Creates a new task transition record * * This function creates a transition record that documents a change in task state. * Transition records include the starting state, ending state, timestamp, and an * optional reason for the transition. * * @param from - Starting task state * @param to - Ending task state * @param reason - Optional reason for the transition * @returns A new transition object with timestamp * * @example * ```typescript * // Create a transition record when a task is completed * const transition = createTransition('working', 'completed'); * console.log(transition); * // Output: { * // from: 'working', * // to: 'completed', * // timestamp: '2023-05-26T12:34:56.789Z' * // } * * // Create a transition record with a reason * const failedTransition = createTransition( * 'working', * 'failed', * 'API request timeout' * ); * console.log(failedTransition); * // Output: { * // from: 'working', * // to: 'failed', * // timestamp: '2023-05-26T12:35:12.345Z', * // reason: 'API request timeout' * // } * ``` */ function createTransition(from, to, reason) { validateTransition(from, to); return { from, to, timestamp: new Date().toISOString(), reason }; } //# sourceMappingURL=task.js.map