// Gateway protocol types — JSON-RPC-like messages over WebSocket. // ── Client → Server ──────────────────────────────────────────── export interface GatewayRequest { id: number; method: string; params?: Record; } // ── Server → Client ──────────────────────────────────────────── export interface GatewayResponse { id: number; result: unknown; } export interface GatewayError { id: number; error: { code: ErrorCode; message: string; }; } export interface GatewayEvent { id: number; event: EventType; data: unknown; } // ── Attachment data for gateway protocol messages ─────────────── /** Attachment data sent in agent.send params or emitted as events. */ export interface GatewayAttachment { /** MIME type (e.g. "image/jpeg", "audio/ogg") */ mimeType: string; /** Base64-encoded data */ data?: string; /** URL to the resource */ url?: string; /** Filename hint */ filename?: string; } // ── Event types emitted during agent.send ────────────────────── export type EventType = | 'content' | 'tool_start' | 'tool_end' | 'attachment' | 'done' | 'error'; export interface ContentEventData { text: string; } export interface ToolStartEventData { tool: string; args: unknown; } export interface ToolEndEventData { tool: string; result: { success: boolean; output: string; error?: string; }; } export interface AttachmentEventData { mimeType: string; data?: string; url?: string; filename?: string; } export interface DoneEventData { content: string; } export interface ErrorEventData { code: ErrorCode; message: string; } // ── Error codes ──────────────────────────────────────────────── export enum ErrorCode { ParseError = -1, InvalidRequest = -2, MethodNotFound = -3, AuthRequired = -4, AuthFailed = -5, SessionNotFound = 1, ToolNotFound = 2, AgentBusy = 3, RequestCancelled = 4, InternalError = 5, } // ── Outbound message (union of all server → client types) ────── export type OutboundMessage = GatewayResponse | GatewayError | GatewayEvent; // ── Validation helpers ───────────────────────────────────────── export function isValidRequest(msg: unknown): msg is GatewayRequest { if (typeof msg !== 'object' || msg === null) {return false;} const obj = msg as Record; return ( typeof obj.id === 'number' && typeof obj.method === 'string' && (obj.params === undefined || (typeof obj.params === 'object' && obj.params !== null)) ); } export function parseMessage(raw: string): GatewayRequest | null { try { const parsed = JSON.parse(raw); if (isValidRequest(parsed)) {return parsed;} return null; } catch { return null; } } export function makeResponse(id: number, result: unknown): GatewayResponse { return { id, result }; } export function makeError(id: number, code: ErrorCode, message: string): GatewayError { return { id, error: { code, message } }; } export function makeEvent(id: number, event: EventType, data: unknown): GatewayEvent { return { id, event, data }; }