@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
116 lines (109 loc) • 3.62 kB
text/typescript
/**
* @module MessageUtils
* @description Utilities for working with messages in the A2A protocol
*
* This module provides utility functions for validating and processing message parts
* in the A2A protocol. Messages are composed of one or more parts, each with a specific
* type (text, file, data, or heartbeat) and content.
*/
import type { MessagePart } from '../types/a2a-protocol';
import { A2AError } from '../errors';
/**
* Error codes specific to message operations
*
* These error codes are used to identify specific issues that can occur
* when working with messages, such as invalid parts, missing content,
* or unsupported message types.
*/
export enum MessageErrorCode {
/** Error code when message parts are invalid or empty (-32060) */
InvalidParts = -32060,
/** Error code when message content is missing (-32061) */
MissingContent = -32061,
/** Error code when message type is invalid (-32062) */
InvalidType = -32062
}
/**
* Validates message parts for compliance with the A2A protocol
*
* This function checks that message parts are present, have content, and use
* supported types. It throws appropriate errors if validation fails, which can
* be caught and handled by the caller.
*
* @param parts - Message parts to validate
* @throws {A2AError} If validation fails, with specific error codes
*
* @example
* ```typescript
* try {
* // Valid message parts
* validateMessageParts([
* { type: 'text', content: 'Hello, world!' },
* { type: 'file', content: 'base64-encoded-content', name: 'document.pdf', mimeType: 'application/pdf' }
* ]);
* console.log('Message parts are valid');
*
* // This would throw an error
* validateMessageParts([
* { type: 'unknown', content: 'some content' } // Invalid type
* ]);
* } catch (error) {
* console.error('Validation failed:', error);
* }
* ```
*/
export function validateMessageParts(parts: MessagePart[]): void {
if (!parts || parts.length === 0) {
throw new A2AError(
'Message must contain at least one part',
MessageErrorCode.InvalidParts
);
}
for (const part of parts) {
if (!part.content) {
throw new A2AError(
'Message part missing content',
MessageErrorCode.MissingContent
);
}
if (!['text', 'file', 'data', 'heartbeat'].includes(part.type)) {
throw new A2AError(
`Invalid message part type: ${part.type}`,
MessageErrorCode.InvalidType
);
}
}
}
/**
* Extracts and combines text content from message parts
*
* This function filters message parts to include only those with type 'text',
* extracts their content, and combines them with double newlines between each part.
* It's useful for getting a plain text representation of a message that might
* include multiple types of content.
*
* @param parts - Message parts to process
* @returns Combined text content from all text parts, separated by double newlines
*
* @example
* ```typescript
* const messageParts = [
* { type: 'text', content: 'Hello, world!' },
* { type: 'file', content: 'base64-encoded-content', name: 'image.png', mimeType: 'image/png' },
* { type: 'text', content: 'This is a second text part.' }
* ];
*
* const textContent = extractTextContent(messageParts);
* console.log(textContent);
* // Output:
* // Hello, world!
* //
* // This is a second text part.
* ```
*/
export function extractTextContent(parts: MessagePart[]): string {
return parts
.filter(part => part.type === 'text')
.map(part => part.content as string)
.join('\n\n');
}