Skip to content

fix: validate UI/response messages and keep streaming response messag…#1016

Merged
omeraplak merged 5 commits intomainfrom
fix/stream-persist
Feb 4, 2026
Merged

fix: validate UI/response messages and keep streaming response messag…#1016
omeraplak merged 5 commits intomainfrom
fix/stream-persist

Conversation

@omeraplak
Copy link
Member

@omeraplak omeraplak commented Feb 4, 2026

…e IDs consistent across streams

PR Checklist

Please check if your PR fulfills the following requirements:

Bugs / Features

What is the current behavior?

What is the new behavior?

fixes (issue)

Notes for reviewers


Summary by cubic

Ensures streaming responses use a stable message ID across UI streams and validates UI messages to prevent malformed data. Also prevents duplicate message insert errors in Postgres and Supabase. Resolves #1010.

  • Bug Fixes
    • Pre-create an assistant message and persist it, then forward its ID to UI streams for consistent streaming updates.
    • Validate incoming and prepared UI messages before use.
    • Postgres/Supabase: upsert messages by (conversation_id, message_id) to avoid duplicate insert failures.
    • Added test to verify ID forwarding to UI streams.

Written for commit 12235df. Summary will update on new commits.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed inconsistent streaming response message IDs across UI streams.
    • Prevented duplicate message insert failures by switching to upsert semantics in Postgres and Supabase integrations.
    • Added validation for incoming UI/response messages to surface invalid input.
  • Tests

    • Added test coverage verifying streaming message persistence and propagation of saved message IDs.
  • Chores

    • Added a changeset for a patch release.

@changeset-bot
Copy link

changeset-bot bot commented Feb 4, 2026

🦋 Changeset detected

Latest commit: 12235df

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@voltagent/postgres Patch
@voltagent/supabase Patch
@voltagent/core Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 4, 2026

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Adds pre-created streaming UI message IDs in the core agent and validates incoming UI messages; updates Postgres and Supabase memory adapters to upsert messages by (conversation_id, message_id); and adds tests asserting placeholder message persistence and ID forwarding to UI streams.

Changes

Cohort / File(s) Summary
Release Configuration
.changeset/wild-aliens-kneel.md
Adds a patch changeset declaring fixes for @voltagent/core, @voltagent/postgres, and @voltagent/supabase.
Core agent: runtime & tests
packages/core/src/agent/agent.ts, packages/core/src/agent/agent.spec.ts, packages/core/src/agent/agent-semantic-search.spec.ts
Introduces STREAM_RESPONSE_MESSAGE_ID_KEY, ensureStreamingResponseMessageId(), applyResponseMessageId(); integrates validateUIMessages and validateIncomingUIMessages; wires stable streaming response message IDs into UI streams; updates tests and AI mock to validate and assert pre-created message persistence and ID forwarding.
Postgres memory adapter
packages/postgres/src/memory-adapter.ts
Replaces plain inserts with upserts using ON CONFLICT (conversation_id, message_id) DO UPDATE; consolidates message_id generation per operation to avoid duplicate-insert failures.
Supabase memory adapter
packages/supabase/src/memory-adapter.ts
Switches single and batch inserts to upserts on (conversation_id, message_id), removes explicit created_at insertion, and consolidates message_id generation per message.

Sequence Diagram(s)

sequenceDiagram
    actor Client
    participant Agent as Core Agent
    participant Memory as Memory Adapter
    participant DB as Database
    participant UI as UI Stream

    Client->>Agent: generateText / streamText(input)
    Agent->>Agent: validateIncomingUIMessages(input)
    Agent->>Agent: ensureStreamingResponseMessageId()
    Agent->>Memory: saveMessage(placeholder streaming message)
    Memory->>DB: upsert (conversation_id, message_id)
    DB-->>Memory: persisted
    Memory-->>Agent: return messageId
    Agent->>UI: streamText with applied messageId
    UI-->>Client: streamed response messages (with stable message_id)
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 I dug a little placeholder hole,

A message-id to keep the stream whole,
Upserts snug duplicates away,
Validation keeps the hops in play,
Now responses hop with an ID on their way.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is truncated but clearly refers to the main changes: validating UI/response messages and maintaining consistent streaming response message IDs across streams, which aligns with the primary objectives.
Description check ✅ Passed The description includes the checklist with most items checked, identifies issue #1010, includes a cubic-generated summary, and explains the key changes. However, the 'Tests for the changes have been added' checkbox is unchecked despite a test being added.
Linked Issues check ✅ Passed The PR addresses issue #1010 by pre-creating and persisting assistant messages with stable IDs, validating UI messages, and upserting messages to prevent duplicates, fully meeting the feature request requirements.
Out of Scope Changes check ✅ Passed All changes are directly related to the stated objectives: message persistence, ID forwarding, UI message validation, and upsert logic for database operations. No unrelated or extraneous changes detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/stream-persist

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.

@joggrbot

This comment has been minimized.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 6 files

Copy link
Contributor

@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: 1

🤖 Fix all issues with AI agents
In `@packages/core/src/agent/agent.ts`:
- Line 1467: ensureStreamingResponseMessageId currently returns null when
memory/user/conversation is missing, causing unstable UI stream IDs; change it
to always generate and return a stable responseMessageId and cache it in the
in-memory buffer, but only persist to the conversation/memory store when those
are present. Update the implementation in ensureStreamingResponseMessageId (and
the similar logic in the block referenced at lines ~3289-3318) to: 1) generate a
deterministic/new UUID for the streaming response when none exists, 2) store it
in the provided buffer/session cache so subsequent calls return the same ID, and
3) conditionally call the persistence path (saving to conversation or memory)
only if user/conversation/memory are available.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Feb 4, 2026

Deploying voltagent with  Cloudflare Pages  Cloudflare Pages

Latest commit: a9584b6
Status: ✅  Deploy successful!
Preview URL: https://0506b713.voltagent.pages.dev
Branch Preview URL: https://fix-stream-persist.voltagent.pages.dev

View logs

@omeraplak omeraplak merged commit 238f87f into main Feb 4, 2026
20 of 23 checks passed
@omeraplak omeraplak deleted the fix/stream-persist branch February 4, 2026 02:00
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.

[FEAT] Generate records in the voltagent_memory_messages table in advance before generating the chat history in streaming generation mode

1 participant