Skip to content

feat(chat): improve chat interface and streaming reliability#212

Merged
larryro merged 4 commits into
mainfrom
feat/chat-improvements
Jan 14, 2026
Merged

feat(chat): improve chat interface and streaming reliability#212
larryro merged 4 commits into
mainfrom
feat/chat-improvements

Conversation

@larryro

@larryro larryro commented Jan 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Replace custom optimistic message handling with the official Convex Agent SDK's optimisticallySendMessage utility
  • Remove manual message deduplication logic that was prone to timing issues
  • Simplify ChatInterface by removing ~100 lines of custom optimistic update code

Test plan

  • Send a message and verify it appears immediately in the UI
  • Confirm the message is properly deduplicated when the server confirms receipt
  • Test message streaming works correctly
  • Verify the thinking animation appears while waiting for AI response

🤖 Generated with Claude Code

Summary by CodeRabbit

Bug Fixes

  • Improved message sending reliability and eliminated duplicate message issues in the chat interface.

Refactor

  • Streamlined message processing and internal state management architecture.
  • Simplified message appearance and sending flow during user interactions.
  • Consolidated message handling logic across chat components.
  • Enhanced coordination between client and server message processing.

✏️ Tip: You can customize this high-level summary in your review settings.

- Refactor chat interface component
- Enhance chat with agent hook
- Simplify chat layout

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jan 14, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The pull request removes the client-side optimistic messaging flow and manual deduplication logic from the chat interface. In chat-interface.tsx, it eliminates the optimistic message creation, deduplication helpers, and draft message rendering. In use-chat-with-agent.ts, it introduces an optimistic update handler using Convex's optimisticallySendMessage for immediate UI feedback. In layout.tsx, it removes the OptimisticMessage type and related state from the chat context. The net result replaces custom optimistic handling with Convex's built-in optimistic update mechanism.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs



📜 Recent review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between ec84ceb and 469af7f.

📒 Files selected for processing (3)
  • services/platform/app/(app)/dashboard/[id]/chat/components/chat-interface.tsx
  • services/platform/app/(app)/dashboard/[id]/chat/hooks/use-chat-with-agent.ts
  • services/platform/app/(app)/dashboard/[id]/chat/layout.tsx
💤 Files with no reviewable changes (1)
  • services/platform/app/(app)/dashboard/[id]/chat/layout.tsx
🧰 Additional context used
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
Repo: talecorp/poc2 PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-10-03T11:34:20.628Z
Learning: Applies to convex/**/*.{ts,js} : Always use the new Convex function syntax (query/mutation/action with args/returns/handler)
📚 Learning: 2026-01-05T01:37:45.458Z
Learnt from: larryro
Repo: tale-project/tale PR: 76
File: services/platform/convex/lib/create_web_agent.ts:22-22
Timestamp: 2026-01-05T01:37:45.458Z
Learning: In agent factory files (services/platform/convex/lib/create_*_agent.ts), explicit `ToolName[]` type annotations for convexToolNames arrays are preferred over implicit typing for consistency across agent factories and clear type documentation.

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/chat/hooks/use-chat-with-agent.ts
📚 Learning: 2025-11-30T03:53:00.316Z
Learnt from: CR
Repo: tale-project/poc2 PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-11-30T03:53:00.316Z
Learning: Applies to convex/**/*.ts : Use the `api` object from `convex/_generated/api.ts` to call public functions registered with `query`, `mutation`, or `action`

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/chat/hooks/use-chat-with-agent.ts
📚 Learning: 2025-10-03T11:34:20.628Z
Learnt from: CR
Repo: talecorp/poc2 PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-10-03T11:34:20.628Z
Learning: Applies to convex/**/*.{ts,js} : Use ctx.runQuery to call queries, ctx.runMutation for mutations, and ctx.runAction for actions

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/chat/hooks/use-chat-with-agent.ts
📚 Learning: 2025-11-30T03:53:00.316Z
Learnt from: CR
Repo: tale-project/poc2 PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-11-30T03:53:00.316Z
Learning: Applies to convex/**/*.ts : Try to use as few calls from actions to queries and mutations as possible to avoid race conditions, since queries and mutations are transactions

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/chat/hooks/use-chat-with-agent.ts
📚 Learning: 2025-10-03T11:34:20.628Z
Learnt from: CR
Repo: talecorp/poc2 PR: 0
File: .cursor/rules/convex_rules.mdc:0-0
Timestamp: 2025-10-03T11:34:20.628Z
Learning: Applies to convex/**/*.{ts,js} : Always use the new Convex function syntax (query/mutation/action with args/returns/handler)

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/chat/hooks/use-chat-with-agent.ts
📚 Learning: 2025-12-30T06:21:13.183Z
Learnt from: larryro
Repo: tale-project/tale PR: 37
File: services/platform/convex/model/documents/validators.ts:89-102
Timestamp: 2025-12-30T06:21:13.183Z
Learning: Do not flag a missing trailing newline for TypeScript files in code reviews. POSIX text files should end with a trailing newline and Prettier (or your formatter) will enforce this. Treat the trailing newline as a non-issue in reviews for all TS files.

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/chat/hooks/use-chat-with-agent.ts
📚 Learning: 2025-12-20T13:38:13.773Z
Learnt from: larryro
Repo: tale-project/tale PR: 30
File: services/platform/convex/model/chat_agent/chat_with_agent.ts:130-144
Timestamp: 2025-12-20T13:38:13.773Z
Learning: In services/platform/convex/model/chat_agent/chat_with_agent.ts, image fileIds are intentionally displayed as `*(fileId: ${attachment.fileId})*` in the markdown because the AI needs to reference them from thread history for re-analysis using the image tool. This is a business/developer tool, not consumer-facing, so technical metadata visibility is acceptable.

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/chat/components/chat-interface.tsx
📚 Learning: 2025-12-26T02:23:20.245Z
Learnt from: larryro
Repo: tale-project/tale PR: 35
File: services/platform/app/(app)/dashboard/[id]/chat/components/integration-approval-card.tsx:58-90
Timestamp: 2025-12-26T02:23:20.245Z
Learning: In services/platform/app/(app)/dashboard/[id]/chat/components/integration-approval-card.tsx, prefer reading the approving user from the authenticated session context rather than passing a userId from the frontend. The hardcoded 'user' string can be acceptable only as a temporary placeholder during the initial implementation until a user profile feature is added; plan to replace with proper user identity via session context or user service once backend supports it.

Applied to files:

  • services/platform/app/(app)/dashboard/[id]/chat/components/chat-interface.tsx
🧬 Code graph analysis (1)
services/platform/app/(app)/dashboard/[id]/chat/components/chat-interface.tsx (1)
services/platform/app/(app)/dashboard/[id]/chat/layout.tsx (1)
  • useChatLayout (32-38)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build Docker Image
🔇 Additional comments (7)
services/platform/app/(app)/dashboard/[id]/chat/components/chat-interface.tsx (6)

295-295: Simplified context consumption aligns with optimistic update migration.

Correctly removed optimisticMessage and setOptimisticMessage from the destructured context, as optimistic updates are now handled within useChatWithAgent.


326-374: LGTM!

The threadMessages memo correctly handles the Issue #184 edge case for orphaned assistant messages while delegating primary deduplication to the SDK. The conversion from UIMessage to ChatMessage format is clean.


684-688: Simplified rendering condition removes draft message complexity.

The condition (threadId || threadMessages?.length > 0) correctly handles showing the chat area when either a thread exists or messages are present. This aligns with the removal of manual optimistic message rendering.


776-786: Comprehensive thinking indicator conditions.

The three-part condition correctly handles all states where a thinking indicator should appear: waiting for stream, stream started but no text, and active tool execution. The inline comments clearly document the reasoning.


500-507: LGTM!

The effect correctly clears isPending state only when the streaming message appears, ensuring the transition from "waiting" to "streaming" state is handled properly.


632-656: Clean simplification of message sending logic.

The removal of manual optimistic message creation is correct—the hook now handles optimistic updates internally. The attachment mapping is properly structured, and error handling correctly invokes clearChatState() which clears the isPending state via setIsPending(false), ensuring the loading indicator stops on error.

services/platform/app/(app)/dashboard/[id]/chat/hooks/use-chat-with-agent.ts (1)

15-24: Clean integration with Convex Agent SDK's optimistic updates.

The hook correctly chains withOptimisticUpdate and adapts the local message argument to the SDK-expected prompt field using the callback pattern documented in @convex-dev/agent v0.3.2. The implementation is correct.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

larryro and others added 3 commits January 14, 2026 17:52
When network is slow, streaming status may be missed causing the
Thinking animation to persist after message completion. Now also
checks for completed assistant messages to clear the pending state.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The previous fix incorrectly cleared isPending when any completed
assistant message existed. Now tracks the assistant message count
when sending to only clear isPending when a NEW response arrives.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@larryro larryro merged commit ad25153 into main Jan 14, 2026
2 checks passed
@larryro larryro deleted the feat/chat-improvements branch January 14, 2026 11:15
yannickmonney pushed a commit that referenced this pull request Apr 8, 2026
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
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