@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
263 lines • 8.47 kB
TypeScript
/**
* @module RequestContext
* @description Context management for A2A protocol requests
*
* This module provides utilities for creating, accessing, and managing request
* contexts in the A2A protocol server. It uses AsyncLocalStorage to maintain
* context across asynchronous operations.
*/
import { type TaskState, type Artifact, type TaskTransition, MessageSendConfiguration, type MessagePart } from '@dexwox-labs/a2a-core';
/**
* Represents a message in the A2A protocol
*
* This interface defines the structure of messages exchanged between agents
* in the A2A protocol. Messages consist of one or more parts and can be
* associated with a task and context.
*/
export interface Message {
/** The parts that make up the message (text, file, data, etc.) */
parts: MessagePart[];
/** Optional ID of the task associated with this message */
taskId?: string;
/** Optional ID of the context this message belongs to */
contextId?: string;
}
/**
* Represents a task in the A2A protocol
*
* This interface defines the structure of tasks in the A2A protocol.
* Tasks represent units of work that agents can perform, and they
* have a lifecycle represented by their status.
*/
export interface Task {
/** Unique identifier for the task */
id: string;
/** Human-readable name of the task */
name: string;
/** Current state of the task (submitted, working, completed, etc.) */
status: TaskState;
/** Optional ID of the agent assigned to this task */
agentId?: string;
/** Optional message parts associated with this task */
parts?: MessagePart[];
/** Optional expected number of parts for this task */
expectedParts?: number;
/** Optional artifacts produced by or associated with this task */
artifacts?: Artifact[];
/** Optional history of state transitions for this task */
transitions?: TaskTransition[];
/** ISO timestamp when the task was created */
createdAt: string;
/** ISO timestamp when the task was last updated */
updatedAt: string;
/** Optional error information if the task failed */
error?: {
/** Error code */
code: number;
/** Error message */
message: string;
/** Optional additional error data */
data?: Record<string, any>;
};
/** Optional additional metadata for the task */
metadata?: Record<string, unknown>;
/** Optional ID of the context this task belongs to */
contextId?: string;
}
/**
* Context for an A2A protocol request
*
* The RequestContext provides all the information needed to process a request
* in the A2A protocol. It includes the task being processed, the agent handling
* the request, and various metadata about the request.
*
* @example
* ```typescript
* // Create a request context
* const context = createRequestContext(
* task,
* 'weather-agent',
* { parts: [{ type: 'text', content: 'What is the weather?' }] }
* );
*
* // Run a function with this context
* runInContext(context, async () => {
* // Inside this function, getCurrentContext() will return the context
* const currentContext = getCurrentContext();
* console.log(`Processing task: ${currentContext.task.id}`);
*
* // Process the request
* await processRequest();
* });
* ```
*/
export interface RequestContext {
/**
* The task being processed
*/
task: Task;
/**
* The agent ID handling this request
*/
agentId: string;
/**
* Unique request ID
*/
requestId: string;
/**
* Context ID for grouping related requests
*/
contextId: string;
/**
* Timestamp when request was received
*/
timestamp: number;
/**
* Original message (for message requests)
*/
message?: Message;
/**
* Message configuration
*/
configuration?: MessageSendConfiguration;
/**
* Related tasks in this context
*/
relatedTasks: Task[];
/**
* Additional context data
*/
metadata?: Record<string, any>;
}
/**
* Creates a new request context
*
* This function creates a new RequestContext object with the provided task,
* agent ID, and optional message, configuration, and metadata. It generates
* a unique request ID and uses the task's context ID if available, or generates
* a new one if not.
*
* @param task - The task being processed
* @param agentId - The ID of the agent handling the request
* @param message - Optional message associated with the request
* @param configuration - Optional message configuration
* @param metadata - Optional additional metadata
* @returns A new RequestContext object
*
* @example
* ```typescript
* const context = createRequestContext(
* {
* id: 'task-123',
* name: 'Weather Request',
* status: 'submitted',
* createdAt: new Date().toISOString(),
* updatedAt: new Date().toISOString()
* },
* 'weather-agent',
* {
* parts: [{ type: 'text', content: 'What is the weather in New York?' }]
* }
* );
* ```
*/
export declare function createRequestContext(task: Task, agentId: string, message?: Message, configuration?: MessageSendConfiguration, metadata?: Record<string, any>): RequestContext;
/**
* Gets the current request context
*
* This function retrieves the RequestContext from the AsyncLocalStorage
* for the current asynchronous execution context. It returns undefined
* if called outside of a context established by runInContext.
*
* @returns The current RequestContext, or undefined if not in a context
*
* @example
* ```typescript
* // Inside a function that's run with runInContext
* function processRequest() {
* const context = getCurrentContext();
* if (!context) {
* throw new Error('Not in a request context');
* }
* console.log(`Processing task: ${context.task.id}`);
* }
* ```
*/
export declare function getCurrentContext(): RequestContext | undefined;
/**
* Runs a function within a request context
*
* This function establishes a RequestContext for the duration of the provided
* function's execution, including any asynchronous operations. The context
* can be accessed using getCurrentContext() from anywhere within the function
* or its asynchronous continuations.
*
* @param context - The RequestContext to establish
* @param fn - The function to run within the context
* @returns The result of the function
*
* @example
* ```typescript
* // Run a function with a request context
* const result = runInContext(context, async () => {
* // Access the context from anywhere in this function
* const currentContext = getCurrentContext();
*
* // Even in nested async functions
* await someAsyncOperation();
*
* return 'result';
* });
* ```
*/
export declare function runInContext<T>(context: RequestContext, fn: () => T): T;
/**
* Attaches a related task to the current request context
*
* This function adds a task to the relatedTasks array of the current
* RequestContext. It throws an error if called outside of a context
* established by runInContext.
*
* @param task - The task to attach to the current context
* @throws Error if called outside of a request context
*
* @example
* ```typescript
* runInContext(context, () => {
* // Create a subtask
* const subtask = createTask({
* name: 'Subtask',
* status: 'submitted'
* });
*
* // Attach it to the current context
* attachRelatedTask(subtask);
* });
* ```
*/
export declare function attachRelatedTask(task: Task): void;
/**
* Gets the text content of the current request's message
*
* This function extracts and concatenates all text parts from the message
* in the current RequestContext. It returns an empty string if called
* outside of a context or if the context has no message.
*
* @param delimiter - The delimiter to use when joining text parts (default: '\n')
* @returns The concatenated text content of the message
*
* @example
* ```typescript
* runInContext(context, () => {
* // Get the text content of the message
* const text = getMessageText();
* console.log(`Message text: ${text}`);
*
* // Get the text content with a custom delimiter
* const textWithSpaces = getMessageText(' ');
* console.log(`Message text with spaces: ${textWithSpaces}`);
* });
* ```
*/
export declare function getMessageText(delimiter?: string): string;
//# sourceMappingURL=request-context.d.ts.map