feat(chat): unify QuickChat backend path and consolidate render toggle

Backend
- chat.ts now routes both regular chat and QuickChat through
  createResolvedAgentSession instead of branching to createFnAgent for
  the no-runtime-hint case. This removes the divergent path where
  pi-ai's cleanupSessionResources(sessionId) could tear down resources
  the next generation depends on.
- sendMessage's finally only disposes the agent if it still owns the
  activeGenerations slot. A newer generation that has pre-empted us
  cleans up its own agent in its own finally — disposing here would
  yank the underlying CLI process out from under it.
- __setCreateFnAgent test helper now mirrors its mock into the
  createResolvedAgentSession slot so existing test setups still work
  after the unification.

Frontend
- Extract createChatStreamHandlers (RAF coalescing, accumulators,
  tool-call dedup, fallback handling) — useChat and useQuickChat were
  duplicating ~85 LOC each. Both now compose the shared factory.
- Move shared chat types into chatTypes.ts. The hooks re-export them
  for backward compatibility with existing consumers.
- Removed per-message Markdown/plain-text eye toggles. A single
  thread-level toggle in the chat header now flips every assistant
  bubble (including the streaming one) between rendered Markdown and
  plain text.
- Model-only chats hide the per-message agent identity row entirely;
  the model name is already in the thread header.

Tests
- Updated ChatView tests to reflect the new render-toggle contract
  (single header toggle drives all bubbles) and the model-only avatar
  suppression.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-05-05 11:04:48 -07:00
parent a77932205c
commit b4a2e7a486
9 changed files with 491 additions and 373 deletions

View File

@@ -0,0 +1,9 @@
---
"@runfusion/fusion": patch
---
Fix Quick Chat backend divergence and consolidate the chat render-mode toggle.
- Backend: Quick Chat and regular chat now go through a single agent-creation path (`createResolvedAgentSession`), eliminating the `createFnAgent` branch where pi-ai's `cleanupSessionResources(sessionId)` could tear down resources still in use by a newer generation. The `sendMessage` `finally` only disposes the agent if it still owns the `activeGenerations` slot, so a pre-empted generation no longer rips state out from under its successor.
- Frontend: extracted the SSE streaming-handler factory shared between `useChat` and `useQuickChat` (RAF coalescing, accumulators, tool-call dedup, fallback handling) into `createChatStreamHandlers`. Both hooks now compose it instead of duplicating ~85 LOC each.
- UX: removed per-message Markdown/plain-text eye toggles. A single thread-level toggle now lives in the chat header and flips every assistant bubble (including the streaming one) between rendered Markdown and plain text. Model-only chats also drop their per-message agent-identity row — the model is shown once in the thread header.