Skip to content

feat(chat,langgraph): message actions + streaming-stability fixes#177

Merged
blove merged 3 commits into
mainfrom
claude/chat-actions-and-merge-fix
May 2, 2026
Merged

feat(chat,langgraph): message actions + streaming-stability fixes#177
blove merged 3 commits into
mainfrom
claude/chat-actions-and-merge-fix

Conversation

@blove
Copy link
Copy Markdown
Contributor

@blove blove commented May 2, 2026

Why

Three things converged this round:

  1. Live-smoke against a real LangGraph backend revealed a subtle bug: the optimistic human message rendered as an assistant bubble (looked like a duplicate of the user's prompt prefixed above the actual response). Root cause: `buildSubmitPayload` only set `role: 'human'` but `toMessage` reads from `_getType` || raw['type'], so it fell through to the 'ai' default.
  2. Intermediate values events were dropping partial AI (and sometimes the optimistic human) from the messages array because we were replacing on values-event sync. LangGraph state.messages lags behind messages-tuple events during streaming.
  3. We were missing the message-action row that copilotkit ships under each assistant message (regenerate / copy / thumbs up / thumbs down). Audited copilotkit and ported the pattern.

chat (0.0.10 → 0.0.11)

  • New primitive: `ChatMessageActionsComponent` — regenerate / copy / thumbs up / thumbs down, hidden by default, fades in via `:host-context()` on hover or on the current message, always visible on mobile, suppressed during streaming. Copy uses navigator clipboard with a 2000ms ✓ feedback. Wired into the default chat composition.
  • New outputs on ``: `regenerate`, `rate`, `messageCopy`. The default regenerate handler calls `agent.reload()`.
  • Caret: switched from step-end blink to copilotkit's smooth pulse (2s cubic-bezier) with inline alignment tweaks.

langgraph (0.0.6 → 0.0.9)

  • buildSubmitPayload: optimistic human messages now carry both `type: 'human'` and `role: 'human'`. Fixes the "user question shown as assistant" bug.
  • values-event sync: always merge state messages into existing rather than replace. Prevents the partial AI / optimistic human from being torn down mid-stream by an intermediate values snapshot.

Verified

  • `nx test chat` — green
  • `nx test langgraph` — 100 tests green
  • `nx build chat` / `nx build langgraph` — clean
  • Live MutationObserver against real LLM backend: single-turn stream produces exactly 2 `CHAT-MESSAGE` additions and 0 removals (was: 3 adds + 1 remove + 1 add). Action controls render correctly post-stream.

🤖 Generated with Claude Code

…tability

Combined patch addressing live-smoke findings + a copilotkit chat-UI audit.

## chat (0.0.10 → 0.0.11)

- New primitive: ChatMessageActionsComponent (regenerate / copy / thumbs
  up / thumbs down) auto-rendered under each assistant message in the
  default chat composition. Mirrors copilotkit's AssistantMessage
  controls: hidden by default, fades in via :host-context() on hover or
  on the current message, always visible on mobile, suppressed during
  streaming. Copy uses the navigator clipboard API with a 2000ms checkmark
  feedback fallback to execCommand. Thumb buttons toggle between
  active/inactive on click. New outputs on chat: `regenerate`, `rate`,
  `messageCopy`. `regenerate` calls `agent.reload()`.
- Caret animation: switched from harsh step-end blink to copilotkit's
  smooth pulse (2s cubic-bezier(0.4, 0, 0.6, 1)) with marginTop and
  vertical-align tweaks so the caret sits inline with the last text line.
- Public API exports the new component.

## langgraph (0.0.6 → 0.0.9)

- buildSubmitPayload: optimistic human messages now carry both `type:
  'human'` (what toMessage reads) and `role: 'human'` (what the server
  expects). Without `type`, toMessage fell through to the 'ai' default
  and the user's question rendered as an assistant message — the
  duplicate-bubble bug we observed in live testing.
- values-event sync: ALWAYS merge state messages into existing instead of
  replacing. LangGraph emits intermediate values events during streaming
  whose state.messages can lag behind what we've already received via
  messages-tuple. Replacing dropped the partial AI (and even the
  optimistic human) and tore down their DOM mid-stream.

Verified against the local LangGraph LLM backend with MutationObserver
instrumentation: a single-turn streaming response now produces exactly
two CHAT-MESSAGE additions and zero removals, with action controls
appearing only after the stream finishes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 2, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cacheplane Ready Ready Preview, Comment May 2, 2026 3:35pm

Request Review

@blove blove merged commit b9981f3 into main May 2, 2026
14 checks passed
@blove blove deleted the claude/chat-actions-and-merge-fix branch May 7, 2026 16:30
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