/** * March Agent SDK - Surface Structural Streamer * Port of Python march_agent/structural/surface.py * * Surface structural streamer for embedded interactive components. */ import { StructuralStreamer, generateShortId } from './base.js' /** * Manages embedded surface lifecycle (similar to Artifact). * * Surfaces are embedded interactive components (iframes, embeds). * Surface data is persisted to database as artifacts with surface type. * * @example * ```typescript * const surface = new Surface() * s.streamBy(surface).generating("Loading calendar...") * s.streamBy(surface).done({ url: "https://cal.com/embed", type: "iframe" }) * ``` */ export class Surface extends StructuralStreamer { protected _generateId(): string { return `surface-${generateShortId()}` } getEventTypePrefix(): string { return 'surface' } /** * Signal surface is loading. * * @param message - Status message (e.g., "Loading calendar...") * @param progress - Progress value 0.0-1.0 * @returns this for method chaining */ generating(message?: string, progress?: number): this { const data: Record = {} if (message !== undefined) { data.message = message } if (progress !== undefined) { data.progress = progress } return this._sendEvent('generating', data) } /** * Signal surface is ready and persist to database. * * @param options - Surface completion options * @param options.url - URL to surface * @param options.type - Surface type (default: iframe) * @param options.title - Display title * @param options.description - Optional description * @param options.metadata - Additional metadata * @returns this for method chaining */ done(options: { url: string type?: string title?: string description?: string metadata?: Record }): this { const data: Record = { url: options.url, type: options.type ?? 'iframe', } if (options.title) { data.title = options.title } if (options.description) { data.description = options.description } if (options.metadata) { data.metadata = options.metadata } return this._sendEvent('done', data) } /** * Signal surface loading failed. * * @param message - Error message * @returns this for method chaining */ error(message: string): this { return this._sendEvent('error', { message }) } }