/** * PhotonBridge - Unified UI Communication Layer * * Provides a standardized API for custom UIs to communicate with Photon servers. * Compatible with OpenAI Apps SDK patterns and MCP Apps (SEP-1865) proposal. * * Usage in custom UI (iframe): * window.photon.onProgress((data) => updateProgressBar(data.value)); * window.photon.onElicitation(async (ask) => showMyDialog(ask)); * * @see https://developers.openai.com/apps-sdk/build/chatgpt-ui/ * @see https://blog.modelcontextprotocol.io/posts/2025-11-21-mcp-apps/ */ export interface ProgressEvent { emit: 'progress'; value: number; message?: string; } export interface StatusEvent { emit: 'status'; message: string; } export interface StreamEvent { emit: 'stream'; data: any; } export type EmitEvent = ProgressEvent | StatusEvent | StreamEvent; export interface AskTextEvent { ask: 'text' | 'password'; message: string; default?: string; placeholder?: string; } export interface AskConfirmEvent { ask: 'confirm'; message: string; default?: boolean; } export interface AskSelectEvent { ask: 'select'; message: string; options: Array; default?: string; } export interface AskNumberEvent { ask: 'number'; message: string; min?: number; max?: number; step?: number; default?: number; } export type AskEvent = AskTextEvent | AskConfirmEvent | AskSelectEvent | AskNumberEvent; export interface PhotonContext { theme: 'light' | 'dark'; locale: string; photon: string; method: string; } /** * PhotonBridge API - injected as window.photon in custom UI iframes */ export interface PhotonBridge { /** Arguments supplied when the tool was invoked */ toolInput: Record; /** Structured content returned by the tool (available after completion) */ toolOutput: any; /** Snapshot of UI state persisted between renders */ widgetState: any; /** Synchronously store state snapshot after UI interactions */ setWidgetState(state: any): void; /** Subscribe to progress updates (0-1 value with optional message) */ onProgress(callback: (event: ProgressEvent) => void): () => void; /** Subscribe to status messages (spinner/indeterminate progress) */ onStatus(callback: (event: StatusEvent) => void): () => void; /** Subscribe to stream data chunks */ onStream(callback: (event: StreamEvent) => void): () => void; /** Subscribe to any emit event */ onEmit(callback: (event: EmitEvent) => void): () => void; /** * Handle elicitation requests from the server * Return a promise that resolves with the user's response */ onElicitation(handler: (ask: AskEvent) => Promise): () => void; /** Subscribe to result (tool completion) */ onResult(callback: (result: any) => void): () => void; /** Subscribe to errors */ onError(callback: (error: { message: string; code?: string; }) => void): () => void; /** Invoke another tool on the same photon */ callTool(toolName: string, args: Record, options?: { instance?: string; }): Promise; /** Alias for callTool - invoke another tool on the same photon */ invoke(toolName: string, args: Record, options?: { instance?: string; }): Promise; /** Send a follow-up message (for conversational UIs) */ sendFollowUpMessage(message: string): Promise; /** Current theme */ theme: 'light' | 'dark'; /** User locale */ locale: string; /** Current photon name */ photon: string; /** Current method being executed */ method: string; /** Check if running inside ChatGPT (has window.openai) */ isChatGPT: boolean; /** Universal motion API for animations and transitions */ motion: { /** Apply an enter animation to an element */ enter(el: any, effect?: string): void; /** Apply an exit animation, returns Promise that resolves after element is removed */ exit(el: any, effect?: string): Promise; /** Add stagger animation to a container's children */ stagger(container: any): void; /** Apply a depth/perspective preset to an element */ depth(el: any, preset?: string): void; }; } export type HostToUIMessage = { type: 'photon:init'; context: PhotonContext; toolInput: Record; /** Pre-computed theme CSS variables; iframe applies them so dark/light matches host. */ themeTokens?: Record; } | { type: 'photon:emit'; event: EmitEvent; } | { type: 'photon:ask'; id: string; event: AskEvent; } | { type: 'photon:result'; data: any; } | { type: 'photon:error'; error: { message: string; code?: string; }; } | { type: 'photon:context'; context: Partial; /** Pre-computed theme CSS variables when the theme changes mid-session. */ themeTokens?: Record; }; export type UIToHostMessage = { type: 'photon:ready'; } | { type: 'photon:ask-response'; id: string; value: any; } | { type: 'photon:set-state'; state: any; } | { type: 'photon:follow-up'; message: string; }; /** * Create the PhotonBridge instance for use in custom UI iframes. * This is injected as window.photon by the PhotonBridgeLoader script. */ export declare function createPhotonBridge(): PhotonBridge; /** * Generate the script that should be injected into custom UI HTML. * This creates window.photon with the full bridge API. */ export declare function generateBridgeLoaderScript(): string; //# sourceMappingURL=photon-bridge.d.ts.map