Skip to content

feat(ui): SessionView, one conversation view for the chat and for agent sessions - #381

Merged
giraffesyo merged 1 commit into
canaryfrom
feat/ui-session-view
Oct 19, 2026
Merged

giraffesyo merged 1 commit into
canaryfrom
feat/ui-session-view

Conversation

@giraffesyo

@giraffesyo giraffesyo commented Oct 19, 2026 •

Copy link
Copy Markdown
Member

Summary

First step toward one conversation view for a chat and for an agent session. Today the chat's ChatThread wires the transcript and composer one way, and a host showing agent sessions wires the same pieces another way: a different layout, its own loading and error handling, no Escape to stop, and agent replies without the actions a chat reply has.

SessionView is the transcript with the composer at the foot of the scrolling column, banners above, files dropped on it going to the composer, and loading and error states. The host binds its own data and callbacks:

  • messages, streaming and queued messages, onSend;
  • turn (running, onStop) for a turn the chat provider doesn't run;
  • optional onEdit, onRegenerate, onRetry, onNavigateBranch, which turn those on. Without them they don't show.

ChatThread is now SessionView bound to the chat provider. Nothing about the chat changes on screen: a host's 15 docs screenshots of its chat pages are pixel-identical before and after.

Same behavior wherever the view is used

  • Escape stops the running turn, whichever turn it is. It moved from the keyboard shortcut hook into SessionView, so a host turn gets it too. The Stop button's tooltip always promised it.
  • Agent replies get the actions row. A reply that is only a parts timeline (no flat content) had no actions. It now has copy (of the text it said), regenerate and branches where the host supports them, and time, model and tokens.

An agent reply now ends with copy, regenerate, branches, time and model

The same at phone width

Composer

  • ComposerControls, ModelSelector and AllocationSelector take model and allocation as a BoundSetting (value, onChange, disabled). A session that owns its own model and allocation shows and changes those without moving the chat's selection. A bound allocation never auto-selects.
  • ChatInput takes tools={false} for a composer the chat's tools don't apply to.
  • ChatMessageList's queueDelivery can be a function, for a host whose queued messages reach the model at different times (some at the agent's next step, some after the reply).

Testing

  • make check passes: 528 tests in src/ai, including new ones for SessionView (Escape for a host turn and for the provider, Escape left to an open dialog, edit through onEdit, no editing without it, error and loading), the agent reply's actions, a bound model pick, tools={false}, and per-message queue delivery.
  • A host's chat docs screenshots (15) are identical before and after. Its agent session screenshots differ only where intended: the model picker is disabled on a session that can't take a change.

Checklist

  • make check passes
  • A new or changed shared message is in every language in problem/messages/ (none changed)
  • No code, rule or param was renamed (they are API contract)

@giraffesyo
giraffesyo merged commit a507d89 into canary Oct 19, 2026
9 checks passed
@giraffesyo
giraffesyo deleted the feat/ui-session-view branch October 19, 2026 13:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant