/** * Agent/chat wire payload types embedded in the tray sync protocol * (`tray-sync-protocol.ts`) — the leader↔follower data-channel format * partially mirrored by the iOS follower * (`packages/ios-app/SliccTrayKit/Models/SyncProtocol.swift`). * * Types only — platform-agnostic by construction (no DOM, no Node, no * imports). The behavior that produces/consumes these shapes stays in * `@slicc/webapp` (`core/attachments.ts`, `core/agent-types.ts`, * `scoops/chat-types.ts`, `scoops/lick-manager.ts`), which re-exports them * so webapp-internal importers keep their layer-local import sites. */ export type MessageAttachmentKind = 'image' | 'text' | 'file'; export interface MessageAttachment { id: string; name: string; mimeType: string; size: number; kind: MessageAttachmentKind; /** Base64 payload for LLM-supported image attachments. */ data?: string; /** UTF-8 content for text-like file attachments. */ text?: string; /** * VFS path (e.g. `/tmp/attachment-…`) when the file was persisted to the * virtual filesystem because it was too large to inline. The agent can * `read_file`/`bash cat` this path to access the full content. */ path?: string; /** Human-readable reason when the payload could not be included. */ error?: string; } export interface ChatMessageUsage { input: number; output: number; cacheRead: number; cacheWrite: number; cost: { input: number; output: number; cacheRead: number; cacheWrite: number; total: number; }; } /** * One progress tick for a unit of work inside a tool call (a `sleep 30`, a * download, a loop). Emitted by the webapp's bash progress overlay * (`packages/webapp/src/shell/progress/`) as a `progress` partial tool result * and forwarded to the chat UI as a `tool_progress` agent event. Mirrors what * just-bash upstream would carry (vercel-labs/just-bash#319) so it can collapse * onto that protocol later. */ export interface ToolProgressEvent { /** Stable id per running unit (command invocation or loop). */ id: string; /** Human label: "sleep 30", "curl …/big.tar.gz", "for (3 of 12)". */ label: string; /** 0..1 when determinate; undefined => indeterminate spinner. */ fraction?: number; /** Best-effort remaining ms; undefined when unknown. */ etaMs?: number; /** Optional unit counters, e.g. bytes or iterations. */ done?: number; total?: number; unit?: 'bytes' | 'iterations' | 'ms'; phase: 'start' | 'update' | 'end'; } export type AgentEvent = { type: 'message_start'; messageId: string; } | { type: 'content_delta'; messageId: string; text: string; } | { type: 'content_done'; messageId: string; model?: string; usage?: ChatMessageUsage; } | { type: 'tool_use_start'; messageId: string; toolName: string; toolInput: unknown; /** * Provider tool-call id. Optional only for back-compat with followers * built before it existed; without it the UI must fall back to matching * results by tool NAME, which mispairs concurrent same-named calls * (the agent loop runs a message's tool calls with `Promise.all`). */ toolCallId?: string; } | { type: 'tool_result'; messageId: string; toolName: string; result: string; isError?: boolean; /** Provider tool-call id; see `tool_use_start`. */ toolCallId?: string; } | { type: 'tool_ui'; messageId: string; toolName: string; requestId: string; html: string; } | { type: 'tool_ui_done'; messageId: string; requestId: string; } | { type: 'tool_progress'; messageId: string; toolName: string; progress: ToolProgressEvent; /** Provider tool-call id; see `tool_use_start`. */ toolCallId?: string; } | { type: 'turn_end'; messageId: string; } | { type: 'error'; error: string; } | { type: 'screenshot'; base64: string; url?: string; } | { type: 'terminal_output'; text: string; }; export type MessageRole = 'user' | 'assistant'; /** * Result state of an actionable lick card (currently scoop sudo-requests): * `pending` (awaiting a decision — the default), `confirmed` (allowed), or * `dismissed` (denied). Drives the `` `state` attribute. */ export type LickState = 'pending' | 'confirmed' | 'dismissed'; export interface ChatMessage { id: string; role: MessageRole; content: string; timestamp: number; attachments?: MessageAttachment[]; toolCalls?: ToolCall[]; isStreaming?: boolean; /** Assistant model id, retained for cost attribution when the session freezes. */ model?: string; /** Final assistant usage, present only after the provider reports the completed turn. */ usage?: ChatMessageUsage; /** Source of the message: 'cone' for main agent, scoop name for sub-agents, 'lick' for async events */ source?: 'cone' | 'lick' | string; /** For licks: the channel type (webhook, cron, etc.) */ channel?: string; /** Render-time collation: how many consecutive same-channel licks this row stands for. */ lickCount?: number; /** Render-time collation: the individual lick bodies folded into this row. */ lickParts?: string[]; /** * For actionable licks (sudo-request): the orchestrator-minted lick id used * to locate this card when its decision settles, so the state can flip live. */ lickId?: string; /** Result state for an actionable lick: pending / confirmed / dismissed. */ lickState?: LickState; /** True when the message is queued (submitted while the agent is still processing). */ queued?: boolean; /** * Cone-error marker — set by the chat controller's `error` AgentEvent * handler. The view renders this assistant message as a `slicc-error-card` * with a retry affordance instead of a plain assistant bubble. */ error?: boolean; } export interface ToolCall { id: string; name: string; input: unknown; result?: string; isError?: boolean; /** Transient screenshot data URL — not persisted to session store. */ _screenshotDataUrl?: string; /** Transient tool-UI request id used by `handleToolUI` to thread the * approval/result roundtrip back to the offscreen agent. Not * persisted. */ _toolUIRequestId?: string; } /** * Which agentic-discovery artifact a `discovery` lick advertises: * - `ai-catalog` — an ARD `/.well-known/ai-catalog.json` manifest (advertised * via a `rel="ai-catalog"` Link header or found by the well-known probe). * - `llms-txt` — a root `/llms.txt` digest found by the well-known probe. */ export type DiscoveryKind = 'ai-catalog' | 'llms-txt'; export interface LickEvent { type: 'webhook' | 'cron' | 'sprinkle' | 'fswatch' | 'session-reload' | 'navigate' | 'upgrade' | 'cherry' | 'workflow' | 'bash' | 'sudo-request' | 'preview' | 'discovery'; webhookId?: string; webhookName?: string; cronId?: string; cronName?: string; sprinkleName?: string; /** For fswatch events */ fswatchId?: string; fswatchName?: string; changes?: Array<{ type: string; path: string; }>; /** For navigate events: the URL whose response advertised a SLICC handoff `Link` rel. */ navigateUrl?: string; /** For upgrade events: the previously-seen and current bundled SLICC versions. */ upgradeFromVersion?: string; upgradeToVersion?: string; /** For cherry events: the host-page event name, owning follower runtime, and host origin. */ cherryName?: string; cherryRuntimeId?: string; cherryOrigin?: string; /** For preview events: the bridge connection metadata. */ previewConnId?: string; previewOrigin?: string; previewToken?: string; previewUserAgent?: string; previewConnectedAt?: string; previewLifecycle?: 'connected' | 'disconnected'; /** * For `discovery` events: an agentic-resource-discovery artifact advertised * by a page/origin. `discoveryOrigin` is the origin it was found on, * `discoveryKind` is which artifact, and `discoveryUrl` is the absolute URL * of the manifest (`ai-catalog.json`) or digest (`llms.txt`). */ discoveryOrigin?: string; discoveryKind?: DiscoveryKind; discoveryUrl?: string; /** * Provenance for discovery events. Only real main-frame navigation observers * set this; replayed/archive-derived event text has no valid source and is * rejected before lick creation. */ discoverySource?: 'live-navigation'; /** * Stable identifier for an actionable lick — one that the cone resolves via * the generic `lick_confirm` / `lick_dismiss` tools. Set by the * orchestrator's actionable-lick registry (see `ConeRequestRegistry`) and * carried through to the UI chip + formatter. For `sudo-request` events the * remaining `sudo*` fields mirror `SudoRequest` so the cone (or the user * reading the chip) can see what is being escalated. The actionable * agent-facing message is still delivered by * `Orchestrator.deliverSudoRequestToCone` — this lick is a UI-chip * notification only (see `defaultLickEventHandler` for the non-routing * branch). */ lickId?: string; sudoKind?: string; sudoDetail?: string; sudoScoopName?: string; sudoSuggestedPattern?: string; targetScoop?: string; /** * Set ONLY by the leader when it re-emits a lick forwarded from a * follower. `originFollowerId` is the follower's bootstrapId (reserved * for future per-follower response routing); `originLabel` is a * human-readable source ("extension follower", "iOS follower", …) * to be surfaced to the agent by `formatLickEventForCone`. */ originFollowerId?: string; originLabel?: string; /** Workflow completion (SP2): set by WorkflowRunManager on cone-origin runs. */ workflowRunId?: string; workflowName?: string; /** * Completion of a `bash` tool run that outlived its `background_after` budget * and was detached. Fired at the scoop (or cone) that started it — see * `targetScoop` — so an unattended scoop still learns the outcome of a command * nobody was left waiting on. */ bashJobId?: string; bashCommand?: string; bashExitCode?: number; /** * Kernel pid the detached run held. Absent when the context has no process * manager (tests, floats without a kernel host). Reported so the recipient can * correlate the completion with what it saw in `ps` while the job was live. */ bashJobPid?: number; /** Durable output file: a workflow run's result JSON, or a bash job's output. */ resultPath?: string; preview?: string; timestamp: string; headers?: Record; body: unknown; } //# sourceMappingURL=agent-wire-types.d.ts.map