Skip to content

feat(web): chats are mail threads with one agent; sidebar sections workbenches and chats (CL-8432) - #868

Merged
TheGreatAxios merged 2 commits into
mainfrom
cl-8432-chats-threads
Sep 18, 2026
Merged

TheGreatAxios merged 2 commits into
mainfrom
cl-8432-chats-threads

Conversation

@TheGreatAxios

Copy link
Copy Markdown
Contributor

What

Chats are ephemeral, ChatGPT-style threads in the bench tenant with exactly one agent, built on stock surfaces only. No backend changes.

  • apps/web/src/chat/threads-api.ts — the one seam:
    • agents: the stock GET /workflows/runs listing (it already carries address and definitionName; myra-deploy-source displays as "Myra")
    • chats: GET /mailbox/me/inbox/threads, grouped by thread root, agent inferred from the run_… address among a thread's participants
    • transcript: GET .../threads/:rootUid plus GET /me/inbox for the frame bodies
    • send and reply: POST /api/tenants/:t/workflows/:runId/mail
    • live updates: GET /me/inbox/events
    • every response parsed with arktype at the boundary
  • Sidebar — two labeled sections, never mixed: Workbenches (# glyph, the bench's child tenants from the stock tenant listing) above Chats (agent initials circle, newest first, collapsed past five with a See all toggle). Nothing in the sidebar path calls a deleted chat route.
  • Chat page — /chats/new composes a first message with an agent select (default Myra) or by @tagging an agent; /chats/:id is the transcript plus a reply box. / hops onto the newest chat, or the composer when there are none.
  • Every backend call goes through TanStack Query: useQuery with keys from one factory, useMutation with invalidation, SSE invalidating the cache rather than fetching in an effect.

Known gap

The person's own turns are held in localStorage, not in the mailbox: @corbits/mailbox writes rows for addressed principals only, and a run address is not a mailbox, so a trigger leaves no durable copy the sender can read back. The agent's replies are durable; the person's own turns follow the device until the hub gives a sender a copy of their own outbound mail.

Tests

Tests pinning the deleted listing shapes were deleted rather than adapted (sidebar-rows, workbench-list, fetch-dedupe), per the standing ruling.

@linear-code

linear-code Bot commented Sep 18, 2026

Copy link
Copy Markdown

CL-8432

…rkbenches and chats (CL-8432)

Chats now ride the stock surfaces only: a person triggers an agent's
deployment run over POST /workflows/:runId/mail, and the agent's reply
lands in their own @corbits/mailbox inbox, threaded by In-Reply-To.

- apps/web/src/chat/threads-api.ts is the one seam: agents from the
  stock run listing, chats from GET /me/inbox/threads, transcripts from
  a thread read plus inbox frames, sends through the run-trigger route,
  live updates from the inbox SSE stream. Every response is parsed with
  arktype.
- The sidebar shows two labeled sections: Workbenches (the bench's child
  tenants, from the stock tenant listing) above Chats (one agent each,
  newest first, collapsed past five). Nothing in the sidebar path calls
  a deleted chat route any more.
- /chats/new composes a first message to an agent picked in a select or
  by @tagging one; /chats/:id is that chat. / hops onto the newest chat.
- Tests covering the deleted listing shapes are removed rather than
  adapted.
Every backend call on the chat surfaces is now a useQuery with a stable
key from one factory, or a useMutation that invalidates that key's scope.
The inbox SSE subscription is the only remaining effect: it writes into
the query cache by invalidating, never by fetching.
@TheGreatAxios
TheGreatAxios merged commit 27b9cd1 into main Sep 18, 2026
1 check passed
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