/** * Shared, product-agnostic types for the floating AssistantWidget. * * The widget itself (fe-libs, Layer 1) knows nothing about how prompts are * fulfilled — each host product injects an `AssistantTransport` that performs * the actual backend work (e.g. VibeControls wraps its sandbox `api-calls` * agent). This keeps the UI reusable across every product shell while the * backend wiring lives in the product layer that is allowed to depend on it. */ export type AssistantWidgetRole = 'user' | 'assistant'; export interface AssistantWidgetMessage { id: string; role: AssistantWidgetRole; /** Rendered as plain text / lightweight markdown. */ content: string; /** Marks an assistant message that is still streaming. */ pending?: boolean; /** Marks an assistant message that ended in an error. */ error?: boolean; } export interface AssistantSendArgs { /** The user's prompt text. */ prompt: string; /** * Files the user attached via the upload button, if any. The widget stays * parsing-free (Layer 1): it only carries the raw `File`s through. The host * transport is responsible for extracting text/rows (JSON/CSV natively, * Excel/PDF via its own deps) and folding a capped preview into the prompt it * sends to the agent. Omitted/empty when the host disables `enableAttachments`. */ attachments?: File[]; /** * Called repeatedly with the latest partial assistant text while the turn * streams. The widget renders this live so users see progress. */ onProgress: (partialText: string) => void; /** Aborts the in-flight turn when the user closes/cancels. */ signal: AbortSignal; } /** * Backend adapter the host product supplies. A single transport instance is * reused across turns so it can keep a warm session/sandbox between sends. */ /** * One downloadable build artifact produced by an artifact-mode turn (e.g. the * scaffolded plugin/node and its zip). Only transports whose backend writes to * a session output dir surface these; everyone else omits the methods below and * no download UI renders. */ export interface AssistantArtifact { /** File or directory name, shown to the user. */ name: string; /** Path relative to the session output dir — the download key. */ path: string; /** 'file' or 'directory' (directories download as a .tar.gz). */ type: string; /** Size in bytes, for display. */ size: number; } /** One past conversation, for the history list. */ export interface AssistantSessionSummary { id: string; title: string; /** epoch ms — used only for ordering/labelling. */ updatedAt?: number; /** True for the conversation currently on screen. */ active?: boolean; } export interface AssistantTransport { sendPrompt: (args: AssistantSendArgs) => Promise<{ text: string; }>; /** Warm the runtime ahead of the first prompt. 'probe' must not create a sandbox. */ prewarm?: (level?: 'probe' | 'full') => void; /** Stop keep-warm work (widget closed / hidden). */ suspend?: () => void; /** All conversations for this user/sandbox, newest first. */ listSessions?: () => Promise; /** Start an empty conversation and make it active. */ newSession?: () => Promise; /** * Delete one conversation by id. * * Replaces a blanket "clear chat", which could only ever remove whichever chat * happened to be open — ambiguous, and useless for tidying up an old one. A * delete control on each history row says exactly what it will remove. */ deleteSession?: (sessionId: string) => Promise; /** Switch to a past conversation; returns its messages. */ selectSession?: (sessionId: string) => Promise; /** * Optional: restore the conversation from the backend when the widget opens. * * The widget holds messages in component state, so without this a reload (or * any remount) wipes the visible chat. Transports whose backend already owns * the transcript — e.g. the sandbox agent, which keeps a durable session — * implement this to rehydrate from that source of truth, which also keeps the * UI honest: what the user sees is what the agent actually remembers. * * Return an empty array when there is nothing to restore. Transports that are * stateless simply omit this and keep the previous ephemeral behaviour. */ loadHistory?: () => Promise; /** Downloadable artifacts for the active conversation, newest build first. */ listArtifacts?: () => Promise; /** Fetch one artifact and trigger a browser save. */ downloadArtifact?: (artifact: AssistantArtifact) => Promise; } //# sourceMappingURL=types.d.ts.map