doc/plans/2026-03-11-agent-chat-ui-and-issue-backed-conversations.md
PAP-475 asks two related questions:
This is not only a component-library decision. In Paperclip today:
tasks + comments only, with no separate chat system.taskKey, and today taskKey falls back to issueId.That means the cheapest useful path is not "add a second messaging product inside Paperclip." It is "add a better conversational UI on top of issue and run primitives we already have."
The durable object in Paperclip is the issue, not a chat thread.
IssueDetail already combines comments, linked runs, live runs, and activity into one timeline.CommentThread already renders markdown comments and supports reply/reassignment flows.LiveRunWidget already renders streaming assistant/tool/system output for active runs.Session continuity is already task-shaped.
heartbeat.ts derives taskKey from taskKey, then taskId, then issueId.agent_task_sessions stores session state per company + agent + adapter + task key.sessionKeyStrategy=issue|fixed|run, and issue already matches the Paperclip mental model well.That means "chat with the CEO about this issue" naturally maps to one durable session per issue today without inventing a second session system.
Billing is already issue-aware.
cost_events can attach to issueId, projectId, goalId, and billingCode.If chat leaves the issue model, Paperclip would need a second billing story. That is avoidable.
assistant-uiUse assistant-ui as the chat presentation layer.
Why it fits Paperclip:
Why not make "the Vercel one" the primary choice:
useChat over /api/chat" framing. Its transport layer is flexible and can support custom protocols.So the clean split is:
assistant-ui for UI primitivesCreate a new top-level chat/thread model unrelated to issues.
Pros:
Cons:
Verdict: not recommended for V1.
Treat chat as a UI mode over an issue. The issue remains the durable record.
Pros:
Cons:
Verdict: best V1 foundation.
Back every conversation with an issue, but allow a conversation-flavored issue mode that is hidden from default execution boards unless promoted.
Pros:
Cons:
Verdict: likely the right product shape after a basic issue-backed MVP.
For the first implementation, chat should be issue-backed.
More specifically:
This keeps Paperclip honest about what it is:
For onboarding, weekly reviews, and "chat with the CEO", use a conversation issue rather than a global chat tab.
Suggested shape:
This solves several concerns at once:
Use one durable conversation session per issue.
That already matches current behavior:
taskKeytaskKey already falls back to issueIdThis means "resume the CEO conversation later" works by reopening the same issue and waking the same agent on the same issue.
Do not add multi-thread-per-issue chat in the first pass.
If Paperclip later needs several parallel threads on one issue, then add an explicit conversation identity and derive:
taskKey = issue:<issueId>:conversation:<conversationId>sessionKey = paperclip:conversation:<conversationId>Until that requirement becomes real, one issue == one durable conversation is the simpler and better rule.
Chat should not invent a separate billing pipeline.
All chat cost should continue to roll up through the issue:
cost_events.issueIdbillingCode when presentIf a conversation is important enough to exist, it is important enough to have a durable issue-backed audit and cost trail.
This is another reason ephemeral freeform chat should not be the default.
assistant-ui as the rendering/composer layer.POST /api/issues/{id}/comments/issues/{id}/live-runs and /issues/{id}/active-run data feeds drive streaming.Paperclip already has most of the backend pieces:
The missing piece is mostly the presentation and the mapping layer, not a new backend domain.
Do not launch this as "chat with every agent."
Start narrower:
Reasons:
If direct chat with other agents becomes useful later, the same issue-backed pattern can expand cleanly.
assistant-uiThis is the highest-leverage step because it tests whether the UX is actually useful before product model expansion.
The smallest implementation could be a label or issue metadata flag. If it becomes important enough, then promote it to a first-class issue subtype later.
Only if we later see a real need:
This should be demand-driven, not designed up front.
If the question is "what should we use?", the answer is:
assistant-ui for the chat UIIf the question is "how should we think about chat in Paperclip?", the answer is:
The most defensible first build is:
assistant-ui primitives over existing comments and live run eventsdoc/SPEC-implementation.mdui/src/pages/IssueDetail.tsx, ui/src/components/CommentThread.tsx, ui/src/components/LiveRunWidget.tsxserver/src/services/heartbeat.ts, packages/db/src/schema/agent_task_sessions.tspackages/adapters/openclaw-gateway/README.md