Skip to content

2.2 chat

wiki[bot] edited this page Aug 8, 2026 · 3 revisions

2.2. The Chat Experience

The Chat area is the reason 3F exists: a complete, streaming, multi-modal conversation UI that shows its work. Component root: src/components/chat/.

Layout

┌─ conversation-header ─ model, session, conversation controls (rename/delete/pin) ─┐
│                                                               │
│  exchange-list                    ┌─ right-panel ────────────┐│
│   ├ chat-exchange (user)          │  session metadata,       ││
│   ├ chat-exchange (assistant)     │  attachments, tools,     ││
│   │   └ exchange-content          │  playlist                ││
│   │       ├ reasoning-area        └──────────────────────────┘│
│   │       └ assistant-response (structured)                   │
│   └ pending-indicator (streaming state)                       │
├─ prompt-action-bar ─ input, images, submit, cancel, think ────┤
└─ toolbar · floating-player · floating-playlist (media) ────────┘

Exchanges

An exchange is one user request + the assistant's full response cycle, keyed by requestId and persisted per session/conversation (HarnessConversation.content). The exchange-list renders the history; each chat-exchange shows:

  • the user prompt with its attached images;
  • the assistant-response, rendered from the harness's structured schemas — comparisons, describe/OCR blocks, summaries, articles, product/news cards, image/video galleries render as UI elements, not raw prose; foreign-language articles/videos appear in an international coverage aside so they augment rather than displace primary-language content.

Reasoning areas

Models with thinking support stream their chain-of-thought as a distinct phase. The reasoning-area renders it collapsed-but-inspectable inside the exchange — you can watch the model think without letting it dominate the answer. use-chat-think wires the think parameter so thinking is a per-conversation choice.

Conversation controls

The conversation header manages the thread's lifecycle directly:

  • Rename — inline title editing (ConversationTitleEditor).
  • Delete — remove the conversation and its uploaded objects.
  • Pin / Unpin — toggle a conversation between temporary and persistent (ConversationHeaderActions), so important threads survive session cleanup while throwaway ones stay ephemeral.

Streaming UX

  • Tokens land on the Socket.IO room as text/stream payloads (see 1.4) and append live; pending-indicator reflects the harness phase rather than a spinner-of-doom.
  • use-frozen-read-snapshot + use-read-tracker freeze the reading viewport while content grows, and release it precisely — no scroll fights mid-stream.
  • Cancel posts /api/v1/harness/cancel and waits for cancel_result — in-flight generation actually stops (see 1.2).

Input

The prompt action bar handles multimodal input: text plus one or more images (validated before upload), numCtx awareness (use-chat-context-size shows how much of the window the current thread consumes — the feature many proprietary chats hide), model picker fed by the live catalogue, and submit/cancel that maps 1:1 to the harness lifecycle.

SysCtl, DLQ, PProc interplay

Chat is not isolated: model + preprocessing + provider overrides configured in SysCtl apply to the next request; failed jobs surface in DLQ where they can be repaired and re-instated; PProc previews exactly which image variants the server will compute from your uploads.

Debuggability

components/debug and the debug store mirror the raw socket/API traffic. Every exchange can be traced client-side from submission through room events to the persisted record — the dashboard treats observability as a user feature.

Clone this wiki locally