@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
181 lines • 5.73 kB
JavaScript
;
/**
* @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.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.createRequestContext = createRequestContext;
exports.getCurrentContext = getCurrentContext;
exports.runInContext = runInContext;
exports.attachRelatedTask = attachRelatedTask;
exports.getMessageText = getMessageText;
const async_hooks_1 = require("async_hooks");
/** Storage for the current request context, accessible across async boundaries */
const contextStorage = new async_hooks_1.AsyncLocalStorage();
/**
* 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?' }]
* }
* );
* ```
*/
function createRequestContext(task, agentId, message, configuration, metadata) {
return {
task,
agentId,
requestId: crypto.randomUUID(),
contextId: task.contextId || crypto.randomUUID(),
timestamp: Date.now(),
message,
configuration,
relatedTasks: [],
metadata
};
}
/**
* 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}`);
* }
* ```
*/
function getCurrentContext() {
return contextStorage.getStore();
}
/**
* 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';
* });
* ```
*/
function runInContext(context, fn) {
return contextStorage.run(context, fn);
}
/**
* 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);
* });
* ```
*/
function attachRelatedTask(task) {
const context = getCurrentContext();
if (!context) {
throw new Error('Cannot attach task outside of request context');
}
context.relatedTasks.push(task);
}
/**
* 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}`);
* });
* ```
*/
function getMessageText(delimiter = '\n') {
const context = getCurrentContext();
if (!context || !context.message) {
return '';
}
return context.message.parts
.filter(part => part.type === 'text')
.map(part => part.content)
.join(delimiter);
}
//# sourceMappingURL=request-context.js.map