Skip to content

Add userId field to UIMessage type#213

Merged
sethconvex merged 1 commit intomainfrom
seth/userid-in-uimessage-188
Jan 21, 2026
Merged

Add userId field to UIMessage type#213
sethconvex merged 1 commit intomainfrom
seth/userid-in-uimessage-188

Conversation

@sethconvex
Copy link
Contributor

@sethconvex sethconvex commented Jan 16, 2026

Problem

The UIMessage type did not include a userId field, making it impossible to identify which user a message belongs to in the UI layer. This information was available in the underlying MessageDoc but was not propagated to UIMessage.

Solution

Add userId field to the UIMessage type and propagate it during message creation:

// src/UIMessages.ts - UIMessage type
export type UIMessage<...> = {
  id: string;
  key: string;
  order: number;
  stepOrder: number;
  status: UIStatus;
  agentName?: string;
  userId?: string;  // NEW
  text: string;
  _creationTime: number;
};

Propagate in each message type creator:

// System messages
function createSystemUIMessage(...) {
  return {
    ...
    userId: message.userId,  // NEW
    ...
  };
}

// User messages  
function createUserUIMessage(...) {
  return {
    ...
    userId: message.userId,  // NEW
    ...
  };
}

// Assistant messages (uses first message's userId)
function createAssistantUIMessage(...) {
  const common = {
    ...
    userId: firstMessage.userId,  // NEW
  };
  ...
}

Fixes #188

Test plan

  • Test: preserves userId in user messages
  • Test: preserves userId in system messages
  • Test: preserves userId in assistant messages
  • Test: preserves userId from first message in grouped assistant messages
  • Test: handles undefined userId gracefully

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Messages now include an optional userId so system, user, and assistant messages preserve and carry a message-level user identifier across flows.
  • Tests

    • Added tests to verify userId preservation across roles and grouped assistant messages, including edge cases where userId is undefined.

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

@coderabbitai
Copy link

coderabbitai bot commented Jan 16, 2026

📝 Walkthrough

Walkthrough

Added an optional userId field to UIMessage and updated message conversion functions so userId is preserved when constructing UI messages from source messages, plus tests verifying preservation across roles and grouped assistant messages.

Changes

Cohort / File(s) Summary
UIMessage type & creators
src/UIMessages.ts
Added optional userId?: string to UIMessage. Updated fromUIMessages to set userId: uiMessage.userId ?? meta.userId. Updated createSystemUIMessage, createUserUIMessage, and createAssistantUIMessage to include userId in returned UIMessage/common fields (assistant uses first message's userId).
Tests: userId preservation
src/toUIMessages.test.ts
Added tests under "userId preservation" covering user, system, assistant messages (including grouped assistant messages) and cases with undefined userId to ensure correct preservation and fallback behavior.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 I hopped through threads both near and far,

tagging voices like a tiny star.
Now every message wears its name,
no more mystery, no more game.
Hooray — each user leaves their mark! 🥕✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a userId field to the UIMessage type, which is the primary focus of this PR.
Linked Issues check ✅ Passed All coding requirements from issue #188 are met: userId added to UIMessage type, propagated in createUserUIMessage/createSystemUIMessage/createAssistantUIMessage, with comprehensive tests covering all message types and edge cases.
Out of Scope Changes check ✅ Passed All changes are directly related to the linked issue #188; modifications to UIMessages.ts and test additions align with the stated objective of preserving userId during MessageDoc to UIMessage conversion.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings


📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cdce325 and ab6a8b0.

📒 Files selected for processing (2)
  • src/UIMessages.ts
  • src/toUIMessages.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/UIMessages.ts
  • src/toUIMessages.test.ts

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


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 16, 2026

Open in StackBlitz

npm i https://pkg.pr.new/get-convex/agent/@convex-dev/agent@213

commit: ab6a8b0

@sethconvex sethconvex force-pushed the seth/userid-in-uimessage-188 branch from 9ec4fec to cdce325 Compare January 16, 2026 15:28
@sethconvex sethconvex marked this pull request as ready for review January 16, 2026 15:40
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/UIMessages.ts (1)

70-85: Prevent meta.userId from being overwritten by undefined.

Because the creators now always set userId (even as undefined), spreading uiMessage after meta can wipe a provided meta.userId. This can drop identity when round‑tripping UI messages that lack a userId. Consider coalescing explicitly.

🔧 Proposed fix
-      ...omit(uiMessage, ["parts", "role", "key", "text"]),
+      ...omit(uiMessage, ["parts", "role", "key", "text", "userId"]),
+      userId: uiMessage.userId ?? meta.userId,
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 74cbf01 and cdce325.

📒 Files selected for processing (2)
  • src/UIMessages.ts
  • src/toUIMessages.test.ts
🧰 Additional context used
🧬 Code graph analysis (1)
src/toUIMessages.test.ts (2)
src/UIMessages.ts (1)
  • toUIMessages (161-184)
src/react/index.ts (1)
  • toUIMessages (3-3)
🔇 Additional comments (5)
src/toUIMessages.test.ts (1)

732-857: Good coverage for userId propagation scenarios.

The new tests validate user/system/assistant and grouped assistant behaviors, plus undefined userId handling.

src/UIMessages.ts (4)

35-46: UIMessage surface update looks right.

Adding userId?: string aligns with the new preservation flow.


282-295: System UI message now preserves userId.

Looks good and consistent with the updated UIMessage shape.


343-355: User UI message now preserves userId.

Propagation is straightforward and matches the requirement.


369-377: Assistant UI message userId propagation looks correct.

Using the first message in the group aligns with the grouping contract and tests.

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

When converting MessageDoc to UIMessage via toUIMessages(), the userId
field was being lost. This made it difficult to identify which user sent
each message in multi-user thread conversations.

Changes:
- Add userId?: string to UIMessage type definition
- Include userId in createSystemUIMessage()
- Include userId in createUserUIMessage()
- Include userId in createAssistantUIMessage() (from first message)
- Add tests for userId preservation across all message types

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@sethconvex sethconvex force-pushed the seth/userid-in-uimessage-188 branch from cdce325 to ab6a8b0 Compare January 16, 2026 16:15
Copilot AI added a commit to zboyles/agent that referenced this pull request Jan 16, 2026
zboyles added a commit to zboyles/agent that referenced this pull request Jan 16, 2026
@zboyles zboyles mentioned this pull request Jan 16, 2026
Copy link
Member

@ianmacartney ianmacartney left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works - I figured any metadata returned on MessageDoc would show up, but it's a good point that when it's reduced to a UIMessage some fields get "promoted" to not be per-message but for the whole collection, and userId is something that seems fine to special-case. Doesn't seem like we'll be leaking extra data out, since that data was already present by default

@sethconvex sethconvex merged commit 23171b0 into main Jan 21, 2026
3 checks passed
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.

Support userId in UIMessage for multi-user thread conversations

2 participants