Skip to content

Chat UI

The Chat page (/chat) is the primary way to interact with Snippbot. A single conversation can host one or many agents, runs in a resizable layout that you can split into side-by-side panes, and supports execution modes that range from read-only planning to fully autonomous action.

This page is a reference for the desktop / browser surface. For a task-oriented walkthrough, see the Chat with Agents guide.

The Chat page is built from a stack of independent surfaces. Each pane is self-contained — in split-pane mode every pane gets its own copy.

SurfacePurpose
Header barConversation title + history dropdown, agent selector, model picker, Self-Talk toggle, view-mode controls
Tab barEach pane has its own row of tabs with agent avatars and a ”+” new-chat dropdown
Pane roster toolbarMode pill, turn-cap pill, roster avatar strip, inline ”+” add-agent trigger
Chat surfaceStreamed messages, queued message bubble, attachments rail, ContextWindow banners
ComposerAuto-resizing input with @ / @! typeahead, image paste, voice input, slash commands
Bottom toolbarAttach, image mode, stop, download, publish, convert to project, generate keypoints
Right side panelCompact view shows keypoints sidebar; Split view shows tabbed Tools Activity / Self-Talk

The header sits at the top of the page. It collapses into a thin strip when Focus Mode is active.

  • Conversation title — Click to open the history dropdown of the current agent’s conversations.
  • Chat Guide (book icon) — Opens an in-app walkthrough modeled on this page.
  • Agent selector — Switches the primary agent. Switching resumes that agent’s most recent chat-sourced conversation, or auto-creates a fresh one.
  • New Chat — Starts a fresh conversation with the selected agent.
  • Self-Talk — Pulsing brain icon. Visible only when the room is in Jarvis (human-led) mode (the active-thinker slot is assigned to a Jarvis-default agent). Toggle with Cmd/Ctrl + Shift + K.
  • Workspace history — Folder icon (in PaneActionButtons). Lists every workspace this conversation has produced and any chat-attached files.
  • Continue on another device — Transfer icon (also in PaneActionButtons). Opens the Transfer modal.
  • View mode toggle — Switches between Compact and Split.
  • Focus Mode — Collapses the header. Click again to restore.
  • Streaming indicator — A “Streaming” pulse appears while a response is generating.
  • Delete — Trash icon. Permanently deletes the conversation after a confirmation dialog. Disabled while streaming.

Each chat pane shows its own ChatTabBar. Tabs render the primary agent’s avatar as a circular badge to the left of the title, with a graceful fallback to a colored initial when the avatar fails to load.

  • Click the + at the end of the tab row to open a new conversation. The dropdown lets you pick which agent the new tab starts with.
  • Clicking + in the right tab bar (when split-pane mode is active) opens a new conversation in that pane.
  • Tabs persist across reloads via local storage. If a tab points to a deleted conversation, it auto-closes on next activation.

The strip above each pane is the PaneRosterToolbar. Layout, left to right:

  1. Mode pill — Current interaction mode. Click to open the dropdown.
  2. Cap pill — Maximum agent replies per user message. Click to pick Default, 10, 20, 40, 60, or No limit.
  3. Roster avatar strip — The primary agent always renders first with a cyan ring + glow and cannot be removed. Other roster members follow. Hovering any avatar opens the Agent Hover Popover.
  4. Inline + trigger — At the end of the strip. Opens the Add Agent dropdown.
  5. Right-side children — In normal layout this is the per-pane ViewModeToggle.

The + dropdown lists every agent available to Snippbot (gateway-folder-backed; e.g. Donna, Elon, Carl, and any custom agents you’ve created), minus the primary and anyone already in the room. If you have only the primary, the dropdown shows a Create agent → shortcut that opens the Awakening flow.

Hover any roster (or message bubble) avatar to open the AgentHoverPopover. It shows:

  • Avatar, name, @handle
  • Owner badge for the primary, Lead badge for the routing lead
  • Short bio + expertise tags
  • Inline preferred model dropdown (per-agent override)
  • Edit agent button (navigates to /agents/:id/edit)
  • Promote to lead (when applicable)
  • Remove from room (non-primary only)

The mode pill in the pane roster toolbar controls how the room schedules turns. Default for new conversations is On-demand.

ModeWho speaks per user turnLead routes?Agents can invite?Ship status
SoloOnly the agent(s) you @!-mention. No mention → lead.NoNoShipped
On-demand@!-mention wins; otherwise the lead replies directly or calls route_to(...) to hand off.YesNoShipped (default)
CollaborativeEveryone in the room by default, or the mentioned speaker; any speaker may invite_agent(...).Yes (entry)YesShipped
FreeformAny roster member can speak; each speaker may invite.Yes (entry)YesComing in v1.1
StructuredArchitect → Executor → Reviewer (subsumes the current team-orchestration loop).N/ANoComing in v1.2

The two future modes appear in the dropdown with a soon chip and are disabled.

The cap pill bounds how many agent replies a single user message can produce. Default defers to the mode’s built-in cap; the larger presets and No limit apply only when you want a longer back-and-forth in Collaborative / Freeform rooms. Solo and On-demand effectively ignore caps above their natural ceilings.

The composer supports a unified @-typeahead:

  • @ opens a combined picker showing roster members first, then other available agents, then files.
  • @! filters to agents only.
  • Selecting an agent inserts a chip backed by @!handle in the underlying message text.
  • If you address an agent that isn’t in the room, an inline “Add @handle to the room?” confirm appears on send.

The lead can also hand off mid-turn by calling the built-in route_to(agent_id, reason) tool. In Collaborative mode, speakers can call invite_agent(agent_id, reason) to enqueue additional teammates.

The lead is the agent the room routes to when no specific @!-mention applies. The primary defaults to lead. You can promote any non-primary roster member to lead from the Agent Hover Popover. Removing the current lead pauses the room until a new lead is picked.

Routing decisions are recorded in the message metadata and render under the new speaker’s bubble as a collapsed Lead → @reviewer — "<reason>" chip.

The dropdown next to the composer (the ExecutionModeSelector) controls how much autonomy the agent has when calling tools. The mode is persisted per agent — switching agents loads their saved default, and changes inside a conversation persist to the backend.

ModeBehaviorBadge
PlanRead-only. The agent reasons but cannot run mutating tools. The PlanModeBanner shows above the input.Safe
AutoFull access. Agents read and write freely without asking.Default
ApproveEach write pauses on an inline approval card. Approve / Reject / Approve all set the policy for that turn.Interactive

The card surface (the ApprovalDialog) appears inline in the chat stream and lists the tool name, arguments, and a preview of the change.

When the room has more than one effective agent, an ActiveThinkerSelector appears next to the composer. It picks the single agent whose autonomous Jarvis cycles run in this room.

  • Pick (none) to disable cycles.
  • Pick a Classic-default agent (chat mode bot) and you’ll see a Classic chip on the pill — cycles won’t fire until that agent’s default flips to Jarvis.
  • The slot resurfaces automatically as soon as a second agent joins the roster.

The slot replaces the legacy per-conversation chat_mode storage.

The ViewModeToggle in the header (single-pane) or the per-pane toolbar (split-pane) chooses how the chat surface lays out.

Single chat column. A right sidebar shows extracted keypoints (when present) and ambient panels. Default when you first open the page.

The chat stays on the left and a tabbed right panel hosts:

  • Tools Activity — live timeline of tool calls and results, with agent → tool attribution and color grouping
  • Self-Talk — the active thinker’s autonomous reasoning stream (auto-opens when you trigger Self-Talk)

Click any inline tool-placeholder chip in the chat to scroll the timeline to that message.

Open a second tab in the tab bar and the layout switches to two independent chat conversations side by side. Drag the divider to adjust the ratio. Each pane has:

  • Its own ChatTabBar
  • Its own PaneRosterToolbar with mode, cap, roster
  • Its own PaneActionButtons (workspace history, transfer)
  • Its own bottom toolbar
  • Its own Self-Talk state — toggling Self-Talk in one pane does not affect the other

Split-pane mode hides the top-level view-mode toggle and bottom toolbar; each pane renders its own.

Collapses the header to a thin bar so the chat takes the full screen. Click the focus button again to restore. The bottom toolbar and keypoints sidebar hide while focus mode is on; the per-pane toolbars stay visible.

Type in the input and press Enter to send, or Shift + Enter for a newline. Responses stream token-by-token over SSE.

  • Paperclip — Bottom toolbar; opens the system file picker.
  • Drag-and-drop — Drop onto the chat area; the FileDropZone previews each chip.
  • Browse Assets — Modal that selects from previously uploaded community assets / marketplace bundles.

Supported types:

  • Text / code: .txt, .py, .js, .ts, .json, .yaml, .toml, .md
  • Documents: .pdf (text is extracted server-side)
  • Images: .png, .jpg, .gif, .webp (for vision-capable models)

Paste screenshots or images straight from the clipboard. Each pasted image is renamed screenshot-{ISO_TIMESTAMP}.{ext} and added to the attachments rail.

When images are attached, an ImageModeSelector appears in the bottom toolbar. It picks how the model should treat attached images. Claude-native runtimes default to a free “Use Read tool” option; everything else defaults to OCR. Sidecar providers (e.g. gemini:gemini-2.5-flash) can be picked deliberately.

Type @ followed by a filename to insert a file reference. The dropdown searches chat-attached files first and auto-escalates to all project files if there are no matches in chat scope. You can also toggle scope manually.

Type @! followed by a handle to direct your message to a specific agent. Roster members are sorted first with an “in room” badge. Picking an agent inserts a chip; the underlying text serializes as @!handle.

Hover any of your past messages to edit or retry:

  • Edit deletes subsequent messages on both client and backend, then resends with the new text.
  • Retry truncates and re-runs the same content.

You can submit a follow-up while the agent is still streaming. The new message appears as a QueuedMessageBubble and auto-sends as soon as the current response (and any in-flight tool activity) finishes. You can edit or discard it before it fires.

The auto-submit logic is implemented in useQueuedMessageAutoSubmit — it waits on both isStreaming and a non-idle toolActivity.state before firing, so it won’t race a multi-agent turn that’s mid-tool-call.

The mic in the TTSControls records a message. A :::transcribing::: placeholder shows while STT processes audio.

When the agent calls tools, the UI reflects the work as it happens.

While a tool runs, the ToolCallingIndicator shows an animated row with the current tool name and a rotating status message (“Thinking…”, “Generating…”, “Running bash”).

Each completed tool result renders inline below the message that triggered it as a CompactToolGroup entry. Success / failure icons, expandable output (max ~400px, downloadable as .txt), and a copy button on hover.

In Split view each message shows a single ToolPlaceholderChip summarizing tool count + successes + failures. Click to open the full timeline in the side panel (and auto-scroll to the matching message).

Tool rows render the speaking agent’s handle when known: @architect → web_search. The row’s left border picks up the agent’s roster color so scanning a long timeline tells you who did what at a glance.

If a tool needs an OAuth scope it does not have (e.g. a new Google Drive scope), an inline OAuthReauthBanner appears. Click to grant.

When the agent runs a marketplace search, suggested assets render below the tool group with one-click install via the MarketplaceSuggestions component.

Self-Talk surfaces an agent’s autonomous reasoning stream — the same loop the scheduler uses for Jarvis cycles.

  • Think indicator — Pulsing pill above the composer. Click to open the Self-Talk panel.
  • Self-Talk button — Brain icon in the header. Visible only in Jarvis-mode rooms (isRoomJarvis === true).
  • Keyboard shortcutCmd/Ctrl + Shift + K. If the side panel is collapsed, the shortcut auto-opens it.
  • Per-pane state in split-pane — Each pane tracks its own Self-Talk toggle.
  • Thought bubbles — Autonomous thoughts surface in the chat stream with a pink “Thought” badge and a left-border accent.
  • Feedback — Thumbs up / down on each thought helps the agent learn.

When you ask the agent to do a complex multi-step task in Jarvis mode with agentic on, the chat can route to a sub-agent team that runs an Architect → Executor → Reviewer loop.

  • Phase indicator — A color-coded progress bar in the chat stream tracks the current phase: Architect (planning) → Executor (building) → Reviewer (validating) → Iteration (refining).
  • Workspace file tree — When the team produces files, an inline WorkspaceFileTree appears. Click any file to preview with syntax highlighting in a side panel.
  • Workspace history — The folder icon in the header lists every workspace this conversation has produced. Open a workspace in the standalone viewer or jump straight to a file.
  • Apply to Project — The ApplyToProjectDialog copies generated workspace files into a real project directory. The dialog flags new files vs. overwrites and lets you select which to apply.

See the Use Sub-Agents guide for the conceptual model.

  • TTS controls — Sit above the composer. Toggle auto-read so every new assistant message plays automatically, or play individual messages on demand from the speaker icon on each bubble.
  • Per-agent voice — Configure under Settings → Voice. Each agent can have its own provider and voice; the chat uses the active speaker’s overrides via VoiceOverrideContext.
  • Playback — Stop or cancel at any time. A status indicator shows when audio is being generated or spoken.

See the Voice Chat guide for setup.

Click the conversation title to open the ChatHistoryDropdown. It lists this agent’s recent conversations and the current one. Loading a conversation atomically updates the active pane’s tab.

After your first user message, the auto-generated Chat with {agent} - {date} title is replaced with the first 60 characters of your message. The auto-refine only fires once per conversation.

When the conversation outgrows the model’s context window, older messages are summarized. The ContextWindowBanner shows how many messages were condensed; dismiss it to hide. A second banner appears as you approach the limit (PR4 pre-compaction warning), and a transient “compacting…” indicator shows during an overflow retry.

The transfer icon (in PaneActionButtons) opens the TransferModal. Depending on your Settings → Chat configuration it generates a transfer code or QR for resuming on a paired phone or another device. Pending approvals are handled by a separate SessionApprovalModal polled from the security log.

  • /chat?conversationId=<id> — jump directly into a conversation
  • /chat?agent=<agentId> — pre-select an agent

Both work from external links and bookmarks. If the conversation no longer exists, the page recovers gracefully.

A floating chevron button appears when you scroll up. Click to jump back to the latest message.

The ChatBottomToolbar sits below the composer in single-pane mode (split-pane renders one per pane).

  • Attach files — Paperclip. Opens the file picker; attached files preview right next to the icon with quick-remove and clear-all.
  • Image mode selector — Appears when image attachments are present.
  • Stop — Visible only while the agent is streaming. Cancels the in-flight generation.
  • Download — Saves the conversation as a markdown file, with multi-agent attribution per message.
  • Publish to Marketplace — Opens the Publish Wizard to share this conversation as a Singularity Marketplace asset.
  • Convert to Project — Opens the Generate Project modal to turn the conversation into a planning project.
  • Generate Keypoints — Extracts features, components, pages, and requirements via the site’s default internal model. Re-run as the chat evolves.

Each agent has a preferred_model that the conversation inherits. Override it inline from the Agent Hover Popover. When the agent has no preferred model, the conversation falls back to the site-wide default_internal_model from Settings → Providers.

Available providers (via the ModelSelector): Anthropic, OpenAI, OpenRouter, Gemini, DeepSeek, xAI Grok, Groq, Mistral, plus the bundled Claude CLI runtimes (claude-native, claude-sub).

KeyAction
EnterSend the current message
Shift + EnterInsert a newline without sending
/Open the slash-command menu
@Open the unified Agents + Files typeahead
@!Open the agents-only typeahead
EscClose the active dropdown / overlay
Cmd / Ctrl + Shift + KToggle the Self-Talk panel (opens the side pane if needed)
Cmd / Ctrl + VPaste images from clipboard (when the composer is focused)

A keyboard-hints popover next to the TTS controls lists the full set.