/** * Agent Chat Bridge (browser) * * Sends structured messages to the agent chat from UI interactions. * Messages are sent via postMessage to the parent window (or self if top-level). * Builder frames are special: code requests go to Builder, but content prompts * stay inside the embedded app so its own AgentSidebar can receive them. */ import type { ReasoningEffort } from "../shared/reasoning-effort.js"; export type AgentChatRequestMode = "act" | "plan"; export interface AgentChatMessage { /** The visible prompt message sent to the chat */ message: string; /** Hidden context appended to the message (not shown in chat UI) */ context?: string; /** true = auto-submit, false = prefill only, omit = use project setting */ submit?: boolean; /** Optional project slug for structured context */ projectSlug?: string; /** Optional preset name for downstream consumers */ preset?: string; /** Optional reference image paths */ referenceImagePaths?: string[]; /** Optional uploaded reference images */ uploadedReferenceImages?: string[]; /** Optional image data URLs to include in the submitted chat message */ images?: string[]; /** Stable tab identifier — auto-generated if omitted */ tabId?: string; /** * Message routing type: * - "content" (default): stays in the embedded app agent for content/data operations * - "code": routes to the code editing frame (Agent Native Desktop or Builder.io) * * When type is "code" and no frame is connected, a dialog is shown. * `requiresCode: true` is treated as `type: "code"` for backward compatibility. */ type?: "content" | "code"; /** @deprecated Use `type: "code"` instead. If true, treated as `type: "code"`. */ requiresCode?: boolean; /** Model preference for this sub-agent (e.g. "claude-haiku-4-5"). Uses default if omitted */ model?: string; /** Engine preference paired with model for cross-provider switches. */ engine?: string; /** Reasoning effort preference paired with model. */ effort?: ReasoningEffort; /** * Execution mode for this submitted turn. When omitted, sendToAgentChat * snapshots the current AgentPanel mode from localStorage when available. */ mode?: AgentChatRequestMode; /** @deprecated Use `mode` instead. */ requestMode?: AgentChatRequestMode; /** Scoped system prompt additions for this sub-agent */ instructions?: string; /** * Message delivery target. Auto-submitted MCP App messages normally relay to * the host chat; use "local" when a control explicitly targets this app's * own AgentSidebar. */ chatTarget?: "auto" | "local"; /** * Whether to open the agent sidebar if it's currently hidden. * Defaults to true — submitting a chat should make the response visible. * Pass `false` for background/silent sends that shouldn't pop the UI open. */ openSidebar?: boolean; /** * When true, opens a new chat tab before sending the message. * Use for creation requests (create tool, dashboard, etc.) that deserve * their own isolated thread rather than cluttering an existing conversation. */ newTab?: boolean; /** * When true with newTab, creates the tab in the background without * focusing it or opening the sidebar. The message runs silently. */ background?: boolean; /** * Stable id used to deduplicate a submit and correlate it with * {@link AGENT_CHAT_SUBMIT_RESULT_EVENT}. Auto-generated if omitted. */ submitMessageId?: string; } export interface AgentChatContextItem { /** Stable key used to replace an existing context nugget. */ key: string; /** Short label shown in the composer context chip. */ title: string; /** Hidden context included with the next submitted prompt. */ context: string; } export interface AgentChatContextSetOptions extends AgentChatContextItem { /** * Whether to open the agent sidebar if it's currently hidden. * Defaults to true so the user can see the staged context. */ openSidebar?: boolean; /** * Whether to move keyboard focus into the composer when staging the item. * Defaults to true. Pass `false` for context that mirrors ambient UI state * (e.g. a canvas element selection) so staging never steals focus from an * unrelated editor — such as an inline text editor in a design canvas. */ focus?: boolean; } /** @deprecated Use `AgentChatContextSetOptions` instead. */ export type AgentChatContextMessage = AgentChatContextSetOptions; export interface AgentChatContextState { items: AgentChatContextItem[]; updatedAt: number; } export interface AgentChatOpenThreadRequest { threadId: string; newThread?: boolean; /** * Open only while this thread is still active (or no thread is active). * This lets transient surfaces restore their own chat without stealing a * thread the user selected in the meantime. */ onlyIfActiveThreadId?: string; openRequestId?: string; } export interface AgentChatOpenTaskRequest { threadId: string; parentThreadId?: string; description?: string; name?: string; openRequestId?: string; } export type BufferedAgentChatOpenRequest = { id: string; eventType: "agent-chat:open-thread" | "agent-task-open"; detail: AgentChatOpenThreadRequest | AgentChatOpenTaskRequest; }; export interface AgentComposerReference { label: string; icon?: string; source?: string; refType: string; refId?: string | null; refPath?: string | null; /** Stable composer slot this reference occupies. Slot references replace older values. */ slotKey?: string; /** Short label shown before the selected value in the composer chip. */ slotLabel?: string; /** Additional app-defined data used by the client for filtering and grouping. */ metadata?: Record; /** Slots to remove when this reference is inserted or removed. */ clearsSlots?: string[]; /** Additional references to insert before this one. */ relatedReferences?: AgentComposerReference[]; } export interface AgentComposerReferenceInsertOptions { /** * Whether to open the agent sidebar before inserting the reference. * Defaults to false so contextual auto-tags can stay quiet. */ openSidebar?: boolean; } export interface AgentComposerReferenceInsertPayload extends AgentComposerReference { insertMessageId: string; } export interface AgentChatContextMutationOptions { /** * Whether to open the agent sidebar if it's currently hidden. * Defaults to true for set/add and false for remove/clear. */ openSidebar?: boolean; } export interface AgentChatContextRemoveOptions extends AgentChatContextMutationOptions { /** Stable key of the staged context nugget to remove. */ key: string; } export declare const AGENT_CHAT_CONTEXT_CHANGED_EVENT = "agentNative.chatContextChanged"; export declare const AGENT_CHAT_SET_CONTEXT_MESSAGE_TYPE = "agentNative.setChatContext"; export declare const AGENT_CHAT_REMOVE_CONTEXT_MESSAGE_TYPE = "agentNative.removeChatContext"; export declare const AGENT_CHAT_CLEAR_CONTEXT_MESSAGE_TYPE = "agentNative.clearChatContext"; export declare const AGENT_CHAT_INSERT_REFERENCE_MESSAGE_TYPE = "agentNative.insertComposerReference"; export declare const AGENT_CHAT_INSERT_REFERENCE_EVENT = "agentNative:insert-composer-reference"; /** * Fired once a submitted turn's fate is known: `delivered: true` once the * receiving AssistantChat has actually committed the turn (added it to the * visible thread, independent of whether the agent's response later * succeeds), or `delivered: false` when it was rejected before ever * appearing — e.g. no LLM/agent engine configured. Callers that must know * whether their submit truly landed (rather than fire-and-forget) should use * {@link sendToAgentChatAndConfirm} instead of listening for this directly. */ export declare const AGENT_CHAT_SUBMIT_RESULT_EVENT = "agentNative.chatSubmitResult"; export interface AgentChatSubmitResult { submitMessageId: string; delivered: boolean; reason?: string; } /** Report a submit's definitive outcome so `sendToAgentChatAndConfirm` (or any * other correlated listener) can resolve. No-ops without a submitMessageId or * a window (SSR). */ export declare function reportAgentChatSubmitResult(submitMessageId: string | undefined, delivered: boolean, reason?: string): void; /** Generate a unique tab ID */ export declare function generateTabId(): string; /** * Permanently tombstone a submit for this page lifetime and remove its * cold-start replay. A confirmation timeout must be terminal: callers may * retry while preserving their own state, so the original submit cannot be * allowed to appear later when a lazy panel or thread ref finally mounts. */ export declare function cancelAgentChatSubmit(id: string | undefined): void; /** Whether a confirmed-submit timeout has made this delivery terminal. */ export declare function isAgentChatSubmitCancelled(id: string | undefined): boolean; /** Unclaimed self-submit payloads, for the panel to replay once it mounts. */ export declare function drainBufferedAgentChatSubmits(): Array>; /** Claim a submit; false if already handled. Idless submits always pass. */ export declare function claimAgentChatSubmit(id: string | undefined): boolean; /** Unclaimed open-thread/task requests, for the panel to replay once it mounts. */ export declare function drainBufferedAgentChatOpenRequests(): BufferedAgentChatOpenRequest[]; /** Claim an open-thread/task request; false if already handled. Idless events pass. */ export declare function claimAgentChatOpenRequest(id: unknown): boolean; /** Test-only: reset the self-submit buffer and claim set. */ export declare function _resetAgentChatSubmitBufferForTests(): void; export declare function normalizeAgentChatContextItem(item: unknown): AgentChatContextItem | null; export declare function normalizeAgentChatContextItems(items: unknown): AgentChatContextItem[]; export declare function publishAgentChatContextItems(items: readonly AgentChatContextItem[], options?: { persist?: boolean; updatedAt?: number; }): AgentChatContextState; export declare function getAgentChatContextState(): AgentChatContextState; export declare function listAgentChatContext(): AgentChatContextItem[]; export declare function subscribeAgentChatContext(listener: () => void): () => void; export declare function refreshAgentChatContext(): Promise; export declare function formatAgentChatContextItemsForPrompt(items: readonly AgentChatContextItem[]): string; export declare function appendAgentChatContextToMessage(message: string, context: string): string; export declare function normalizeAgentComposerReference(value: unknown): AgentComposerReference | null; export declare function requestAgentChatThreadOpen(detail: AgentChatOpenThreadRequest): void; export declare function requestAgentTaskOpen(detail: AgentChatOpenTaskRequest): void; /** A normalized `agentNative.submitChat` payload — decode via {@link parseSubmitChatMessage}. */ export interface ParsedSubmitChat { /** Visible prompt text (non-empty). */ message: string; context?: string; /** Submit (true) or prefill only (false); defaults to true. */ submit: boolean; openSidebar?: boolean; model?: string; /** Raw effort hint; the receiver validates it against the model. */ effort?: unknown; newTab?: boolean; background?: boolean; tabId?: string; images?: string[]; /** Mode as sent; the receiver falls back to its exec mode when undefined. */ requestMode?: AgentChatRequestMode; /** Id used to dedup the live post against a cold-start replay. */ submitMessageId?: string; } /** Decode a `message` event into a submit payload, or null if it isn't one / has no text. */ export declare function parseSubmitChatMessage(event: MessageEvent): ParsedSubmitChat | null; /** * Send a message to the agent chat via postMessage. * Returns the stable tabId for tracking this chat run. */ export declare function sendToAgentChat(opts: AgentChatMessage): string; export interface SendToAgentChatAndConfirmResult { tabId: string; /** True once the message actually became a visible turn in the chat. */ delivered: boolean; /** Set when `delivered` is false: "missing-engine", "timeout", etc. */ reason?: string; } /** * Like {@link sendToAgentChat}, but resolves once the submit's fate is known * instead of firing and forgetting. Use this whenever the caller must decide * whether to keep/restore its own state on failure (e.g. a draw/annotate * overlay that should not discard the user's work unless the message actually * reached the chat) — see the `AGENT_CHAT_SUBMIT_RESULT_EVENT` contract. * This acknowledgement is intentionally limited to submitted, non-code * messages with `chatTarget: "local"`; parent-frame and MCP host chats use * different delivery protocols and return `unsupported-target` here. * * Resolves `delivered: false` if the receiving chat explicitly rejects the * submit (e.g. no LLM/agent engine configured) OR if no result arrives within * `timeoutMs` — a silently-stuck submit (panel never mounts, thread never * gets a ref, message type not handled by this build) must fail the same way * an explicit rejection does, since the caller cannot otherwise tell the * difference between "still in flight" and "dropped." */ export declare function sendToAgentChatAndConfirm(opts: Omit, options?: { timeoutMs?: number; }): Promise; /** * Add or replace a keyed context nugget in the active agent chat composer. * The context is not submitted until the user sends the prompt. */ export declare function setAgentChatContextItem(opts: AgentChatContextSetOptions): void; /** @deprecated Use `setAgentChatContextItem` instead. */ export declare const setContextToAgentChat: typeof setAgentChatContextItem; /** @deprecated Use `setAgentChatContextItem` instead. */ export declare const addContextToAgentChat: typeof setAgentChatContextItem; export declare function insertAgentComposerReference(ref: AgentComposerReference, options?: AgentComposerReferenceInsertOptions): void; export declare function removeAgentChatContextItem(keyOrOpts: string | AgentChatContextRemoveOptions): void; export declare function clearAgentChatContext(opts?: AgentChatContextMutationOptions): void; export declare function _resetAgentChatContextForTests(): void; //# sourceMappingURL=agent-chat.d.ts.map