{message.role === "user" && (
@@ -544,7 +550,7 @@ import { VList } from "virtua";
Imports needed: `VList` from `virtua`, `ChatAgentBadge` from `./ChatAgentBadge`, `ChatMarkdownMessage` from `./ChatMarkdownMessage`, `Button` from `@/components/ui/button`, `Pencil, RotateCcw, ChevronDown` from `lucide-react`, `Agent` from `@paperclipai/shared`, `useState, useRef, useEffect, useCallback` from `react`, `cn` from `../lib/utils`.
- **B. Update `ChatInput.tsx`** — Add Stop button, slash command popover, @mention popover:
+ **B. Update `ChatInput.tsx`** -- Add Stop button, slash command popover, @mention popover:
New props interface:
```typescript
@@ -603,9 +609,9 @@ import { VList } from "virtua";
- Render same `
` + `` pattern
- On item select: replace input with `@{agentName} `, close popover
- The popover trigger is the textarea container itself (invisible trigger — use `` on the textarea wrapper div).
+ The popover trigger is the textarea container itself (invisible trigger -- use `` on the textarea wrapper div).
- **C. Update `ChatPanel.tsx`** — Wire everything together:
+ **C. Update `ChatPanel.tsx`** -- Wire everything together:
1. Import `AgentSelector` from `./AgentSelector`.
2. Import `useStreamMessage, useEditMessage` from `../hooks/useChatMessages`.
@@ -650,7 +656,7 @@ import { VList } from "virtua";
try {
const conversation = await createConversation.mutateAsync(undefined);
setActiveConversationId(conversation.id);
- // Can't stream yet — conversation just created, need to wait for state update
+ // Can't stream yet -- conversation just created, need to wait for state update
// Queue the send for after state settles
setTimeout(() => stream.send(content, resolveAgentId(intent, agents, conversation.agentId)), 50);
} catch { /* ignore */ }
@@ -704,7 +710,7 @@ import { VList } from "virtua";
}, [editMessage, stream, activeConversation]);
```
- 16. Add `AgentSelector` to the panel header. Modify the inner layout — add a header bar above the message area:
+ 16. Add `AgentSelector` to the panel header. Modify the inner layout -- add a header bar above the message area:
```tsx
{/* Message area */}
@@ -778,9 +784,9 @@ import { VList } from "virtua";
-- `pnpm --filter @paperclipai/ui build` — TypeScript compiles
-- `pnpm --filter @paperclipai/ui test run` — all UI tests pass
-- `pnpm test run` — full suite green
+- `pnpm --filter @paperclipai/ui build` -- TypeScript compiles
+- `pnpm --filter @paperclipai/ui test run` -- all UI tests pass
+- `pnpm test run` -- full suite green
- ChatMessageList uses VList from virtua
- ChatInput shows Stop button during streaming
- ChatPanel has AgentSelector in header
diff --git a/.planning/phases/22-agent-streaming/22-04-PLAN.md b/.planning/phases/22-agent-streaming/22-04-PLAN.md
index 45c5de6f..ea769450 100644
--- a/.planning/phases/22-agent-streaming/22-04-PLAN.md
+++ b/.planning/phases/22-agent-streaming/22-04-PLAN.md
@@ -10,9 +10,14 @@ requirements: [CHAT-01, CHAT-08, CHAT-10, CHAT-11, CHAT-12, INPUT-05, INPUT-06,
must_haves:
truths:
- - "Full streaming chat flow works end-to-end"
- - "All three themes render agent colors correctly"
- - "All six success criteria from ROADMAP are met"
+ - "pnpm test run exits 0 with all chat-routes, chat-stream-routes, parseMessageIntent, ChatAgentBadge, and ChatInput.slash-mention tests passing"
+ - "pnpm --filter @paperclipai/ui build and pnpm --filter @paperclipai/server build both exit 0"
+ - "User sends a message and sees echo-stream tokens appear word-by-word in a streaming assistant bubble (CHAT-01 transport-level, echo-stream placeholder)"
+ - "Stop button (red square) appears during streaming and cancels the stream on click"
+ - "Agent selector dropdown in chat header shows agents with colored avatars and persists selection across page reload"
+ - "Agent badge with colored circle and name appears above each assistant message"
+ - "Slash command popover appears when typing / prefix, @mention popover appears when typing @ prefix"
+ - "Agent colors are visually distinguishable across all three themes (Catppuccin Mocha, Tokyo Night, Catppuccin Latte)"
artifacts: []
key_links: []
---
@@ -41,12 +46,15 @@ Output: Verified, working Phase 22.
Task 1: Full test suite verification and build check
-
+
+ (run-only verification task -- no source changes expected; reads test files for diagnostics if failures occur)
+
server/src/__tests__/chat-stream-routes.test.ts,
server/src/__tests__/chat-routes.test.ts,
ui/src/lib/parseMessageIntent.test.ts,
- ui/src/components/ChatAgentBadge.test.tsx
+ ui/src/components/ChatAgentBadge.test.tsx,
+ ui/src/components/ChatInput.slash-mention.test.tsx
Run the full test suite and verify all tests pass:
@@ -70,42 +78,34 @@ Output: Verified, working Phase 22.
pnpm test run && pnpm --filter @paperclipai/ui build && pnpm --filter @paperclipai/server build
-
- - pnpm test run exits 0
- - pnpm --filter @paperclipai/ui build exits 0
- - pnpm --filter @paperclipai/server build exits 0
-
All tests pass and both UI and server build cleanly
Task 2: Visual and functional verification of streaming chat
-
+
+ (checkpoint -- no files modified; visual/functional verification only)
+
- Present the verification checklist to the user. The user will manually test the streaming chat experience across all features built in Phase 22:
+ Present the verification checklist to the user. Complete Phase 22 agent streaming has been built:
+ SSE echo-stream endpoint, virtualized message list with agent badges, edit/retry actions,
+ Stop button, AgentSelector, slash command and @mention popovers.
+ The user will manually test:
1. Start the dev server: `pnpm dev`
2. Open the chat panel (MessageSquare icon in sidebar)
- 3. Create a new conversation and send a message — verify tokens stream in word-by-word
+ 3. Create a new conversation and send a message -- verify tokens stream in word-by-word (echo-stream: you will see your own message echoed back, this is the Phase 22 placeholder; real LLM responses come in Phase 23)
4. While streaming: verify the Stop button (red square) appears; click it to cancel
- 5. Hover over an assistant message — verify Retry button (rotate icon) appears; click it
- 6. Hover over a user message — verify Edit button (pencil icon) appears; click to enter edit mode, modify text, click Regenerate
- 7. Open the Agent Selector dropdown in the header — verify agents appear with colored avatars
- 8. Select a different agent — verify it persists (reload page, re-open conversation)
- 9. Type `/ask-pm ` — verify slash command popover appears with matching commands
- 10. Type `@` followed by an agent name — verify mention popover appears
- 11. Switch between all three themes (Catppuccin Mocha, Tokyo Night, Catppuccin Latte) — verify agent badge colors are distinguishable
+ 5. Hover over an assistant message -- verify Retry button (rotate icon) appears; click it
+ 6. Hover over a user message -- verify Edit button (pencil icon) appears; click to enter edit mode, modify text, click Regenerate
+ 7. Open the Agent Selector dropdown in the header -- verify agents appear with colored avatars
+ 8. Select a different agent -- verify it persists (reload page, re-open conversation)
+ 9. Type `/ask-pm ` -- verify slash command popover appears with matching commands
+ 10. Type `@` followed by an agent name -- verify mention popover appears
+ 11. Switch between all three themes (Catppuccin Mocha, Tokyo Night, Catppuccin Latte) -- verify agent badge colors are distinguishable
12. (Optional) If you have a conversation with many messages, scroll rapidly to check smoothness
User types "approved" or describes issues to fix
-
- - User confirms streaming tokens appear as they are generated
- - User confirms Stop button cancels in-progress stream
- - User confirms agent badge shows on assistant messages with colored avatar
- - User confirms agent selector changes the conversation's agent
- - User confirms slash command and @mention popovers appear
- - User confirms agent colors are distinguishable across all three themes
-
User has approved the complete Phase 22 streaming chat experience