-
-
Notifications
You must be signed in to change notification settings - Fork 0
2.2 chat
The Chat area is the reason 3F exists: a complete, streaming, multi-modal conversation UI that shows its work. Component root: src/components/chat/.
┌─ 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) ────────┘
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.
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.
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.
- Tokens land on the Socket.IO room as
text/streampayloads (see 1.4) and append live;pending-indicatorreflects the harness phase rather than a spinner-of-doom. -
use-frozen-read-snapshot+use-read-trackerfreeze the reading viewport while content grows, and release it precisely — no scroll fights mid-stream. -
Cancel posts
/api/v1/harness/canceland waits forcancel_result— in-flight generation actually stops (see 1.2).
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.
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.
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.