@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
154 lines (146 loc) • 4.46 kB
text/typescript
/**
* @module ArtifactUtils
* @description Utilities for working with artifacts in the A2A protocol
*
* Artifacts are used to represent various types of content (text, files, data)
* that can be attached to tasks and messages in the A2A protocol.
*/
import type { Artifact } from '../types/a2a-protocol';
import { A2AError } from '../errors';
/**
* Error codes specific to artifact operations
*
* These error codes are used to identify specific issues that can occur
* when working with artifacts, such as serialization failures or invalid types.
*/
export enum ArtifactErrorCode {
/** Error code when artifact serialization fails (-32050) */
SerializationFailed = -32050,
/** Error code when artifact deserialization fails (-32051) */
DeserializationFailed = -32051,
/** Error code when artifact content is missing (-32052) */
MissingContent = -32052,
/** Error code when artifact type is invalid (-32053) */
InvalidType = -32053
}
/**
* Serializes an artifact to a JSON string
*
* This function converts an Artifact object to a JSON string representation
* that can be stored or transmitted. It handles error cases by throwing
* appropriate A2AError instances.
*
* @param artifact - Artifact object to serialize
* @returns JSON string representation of the artifact
* @throws {A2AError} If serialization fails
*
* @example
* ```typescript
* const artifact: Artifact = {
* id: 'artifact-123',
* type: 'text',
* content: 'This is a text artifact',
* metadata: { created: new Date().toISOString() }
* };
*
* try {
* const serialized = serializeArtifact(artifact);
* console.log('Serialized artifact:', serialized);
* } catch (error) {
* console.error('Failed to serialize:', error);
* }
* ```
*/
export function serializeArtifact(artifact: Artifact): string {
try {
return JSON.stringify(artifact);
} catch (err) {
throw new A2AError(
'Failed to serialize artifact',
ArtifactErrorCode.SerializationFailed,
{ cause: err }
);
}
}
/**
* Deserializes an artifact from a JSON string
*
* This function converts a JSON string representation back into an Artifact object.
* It handles error cases by throwing appropriate A2AError instances.
*
* @param data - JSON encoded artifact data
* @returns Deserialized Artifact object
* @throws {A2AError} If deserialization fails
*
* @example
* ```typescript
* try {
* const artifactJson = '{"id":"artifact-123","type":"text","content":"This is a text artifact"}';
* const artifact = deserializeArtifact(artifactJson);
* console.log('Artifact type:', artifact.type);
* console.log('Artifact content:', artifact.content);
* } catch (error) {
* console.error('Failed to deserialize:', error);
* }
* ```
*/
export function deserializeArtifact(data: string): Artifact {
try {
return JSON.parse(data) as Artifact;
} catch (err) {
throw new A2AError(
'Failed to deserialize artifact',
ArtifactErrorCode.DeserializationFailed,
{ cause: err }
);
}
}
/**
* Validates an artifact's structure and content
*
* This function checks that an artifact has the required fields and that
* the type is one of the supported values ('text', 'file', or 'data').
* It throws an appropriate error if validation fails.
*
* @param artifact - Artifact object to validate
* @returns True if the artifact is valid
* @throws {A2AError} If validation fails, with specific error codes
*
* @example
* ```typescript
* try {
* // Valid artifact
* const valid = validateArtifact({
* id: 'artifact-123',
* type: 'file',
* content: 'base64-encoded-content',
* metadata: { filename: 'document.pdf', mimeType: 'application/pdf' }
* });
* console.log('Artifact is valid:', valid);
*
* // This would throw an error
* validateArtifact({
* id: 'invalid-artifact',
* type: 'unsupported-type', // Invalid type
* content: 'some-content'
* });
* } catch (error) {
* console.error('Validation failed:', error);
* }
* ```
*/
export function validateArtifact(artifact: Artifact): boolean {
if (!artifact.content) {
throw new A2AError(
'Missing content for artifact',
ArtifactErrorCode.MissingContent
);
}
if (!['text', 'file', 'data'].includes(artifact.type)) {
throw new A2AError(
'Invalid artifact type',
ArtifactErrorCode.InvalidType
);
}
return true;
}