fix(ai): preserve UI message IDs in model conversion - #1066
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughUI-to-model conversion now preserves stable UI message IDs across generated user, assistant, tool, approval, and fallback messages. Unit tests and a provider-free end-to-end route verify the behavior and validation responses. ChangesMessage ID preservation
Estimated code review effort: 3 (Moderate) | ~20 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration. 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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
testing/e2e/tests/chat.spec.ts (1)
56-58: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDocument the provider-free aimock exception in the spec header.
This test does not call a provider HTTP endpoint. Add a header comment that states this condition and explains why aimock is intentionally not configured. Based on learnings: provider-free E2E specs must document the aimock policy exception in the spec header.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@testing/e2e/tests/chat.spec.ts` around lines 56 - 58, Document the provider-free aimock policy exception in the header of the chat E2E spec, near the test identified by preserves UI message IDs at the server conversion boundary. State that the test does not call a provider HTTP endpoint and therefore intentionally does not configure aimock.Source: Learnings
packages/ai/tests/message-converters.test.ts (1)
350-404: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winCover the empty assistant fallback ID path.
This test does not exercise the
messageList.length === 0path. Add a test with an assistantUIMessagethat has no emit-worthy parts. Assert that the fallback assistantModelMessageretainsuiMessage.id.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/ai/tests/message-converters.test.ts` around lines 350 - 404, The existing test only verifies IDs on generated messages when parts produce output; add a separate test for an assistant UIMessage with no emit-worthy parts. Call uiMessageToModelMessages and assert it returns the fallback assistant ModelMessage with uiMessage.id preserved.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@testing/e2e/src/routes/api.message-ids.ts`:
- Around line 13-18: Update the POST handler to validate the parsed request body
with the existing or appropriate Zod schema before calling
convertMessagesToModelMessages. Catch JSON parsing and schema-validation
failures, returning a 400 Response for either invalid JSON or invalid
message/message-part data; only perform conversion after successful validation.
---
Nitpick comments:
In `@packages/ai/tests/message-converters.test.ts`:
- Around line 350-404: The existing test only verifies IDs on generated messages
when parts produce output; add a separate test for an assistant UIMessage with
no emit-worthy parts. Call uiMessageToModelMessages and assert it returns the
fallback assistant ModelMessage with uiMessage.id preserved.
In `@testing/e2e/tests/chat.spec.ts`:
- Around line 56-58: Document the provider-free aimock policy exception in the
header of the chat E2E spec, near the test identified by preserves UI message
IDs at the server conversion boundary. State that the test does not call a
provider HTTP endpoint and therefore intentionally does not configure aimock.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 94a97e80-caa5-4bf2-ab2d-fb7af1490b83
📒 Files selected for processing (7)
.changeset/fix-ui-message-id-roundtrip.mdpackages/ai/src/activities/chat/messages.tspackages/ai/tests/message-converters.test.tspackages/ai/tests/messages.test.tstesting/e2e/src/routeTree.gen.tstesting/e2e/src/routes/api.message-ids.tstesting/e2e/tests/chat.spec.ts
|
Addressed the review feedback in d9db7e1:\n\n- validate the provider-free message conversion request with Zod and return 400 for malformed JSON or invalid message parts\n- cover the empty assistant fallback ID path\n- document why this provider-free E2E intentionally does not configure aimock\n\nValidation: focused converter tests (64 passed), focused Playwright tests (3 passed), affected type checks, lint, build/publint, Sherif, Knip, docs, Kiira, and dangling declaration scan. |
Summary
UIMessage.idon everyModelMessageemitted by UI-to-model conversion, including assistant segments and derived tool results.@tanstack/ai.Fixes #1063
Test plan
pnpm --filter @tanstack/ai test:lib --run— 80 files, 1451 tests passed.pnpm --filter @tanstack/ai test:types— passed.pnpm --filter @tanstack/ai test:oxlint— passed with existing warnings only.pnpm --filter @tanstack/ai test:build— passed.pnpm --filter @tanstack/ai-e2e test:e2e -- --grep "preserves UI message IDs"— passed.pnpm test:dts— passed.pnpm test:pr— all 73 Nx target groups reported success; the wrapper exits with the existing Windows NxEISDIR: illegal operation on a directory, lstat 'D:'cleanup error.chromium_headless_shell-1200binary, while request-only tests ran.Summary by CodeRabbit
Bug Fixes
Tests