Skip to content

fix: persist modelId in assistant message content.metadata#12969

Merged
abhiaiyer91 merged 8 commits into
mastra-ai:mainfrom
catdalfonso:feature/persist-model-id-in-message-metadata
Mar 9, 2026
Merged

fix: persist modelId in assistant message content.metadata#12969
abhiaiyer91 merged 8 commits into
mastra-ai:mainfrom
catdalfonso:feature/persist-model-id-in-message-metadata

Conversation

@catdalfonso

@catdalfonso catdalfonso commented Feb 11, 2026

Copy link
Copy Markdown
Contributor

Description

Currently, llm-execution-step.ts captures modelId in runState.state.responseMetadata during streaming but never propagates it to MastraDBMessage.content.metadata before messages are saved. This means downstream consumers (storage adapters, processors) that read content.metadata.modelId receive undefined.

Inject responseMetadata.modelId into content.metadata of all assistant response messages after they are added to the MessageList and before output processors run.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Code refactoring
  • Performance improvement
  • Test update

Checklist

  • I have made corresponding changes to the documentation (if applicable)
  • I have added tests that prove my fix is effective or that my feature works

Summary by CodeRabbit

  • New Features

    • Assistant messages now include a modelId in their metadata so stored and streamed responses indicate which model produced them.
  • Tests

    • Added a test ensuring modelId is persisted on streamed assistant messages (v2 flow).
  • Chores

    • Added a patch release entry documenting the metadata persistence change.

@vercel

vercel Bot commented Feb 11, 2026

Copy link
Copy Markdown

@catdalfonso is attempting to deploy a commit to the Mastra Team on Vercel.

A member of the Team first needs to authorize it.

@changeset-bot

changeset-bot Bot commented Feb 11, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 937c211

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

This PR includes changesets to release 21 packages
Name Type
@mastra/core Patch
mastracode Patch
@mastra/mcp-docs-server Patch
@internal/playground Patch
@mastra/client-js Patch
@mastra/opencode Patch
@mastra/longmemeval Patch
mastra Patch
@mastra/deployer-cloud Patch
@mastra/deployer-vercel Patch
@mastra/playground-ui Patch
@mastra/react Patch
@mastra/server Patch
@mastra/deployer Patch
create-mastra Patch
@mastra/express Patch
@mastra/fastify Patch
@mastra/hono Patch
@mastra/koa Patch
@mastra/deployer-cloudflare Patch
@mastra/deployer-netlify 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

coderabbitai Bot commented Feb 11, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Persist the LLM response model identifier by adding content.metadata.modelId to assistant messages during response assembly; includes implementation changes to propagate modelId, a v2-only streaming test that verifies persistence to MockMemory, and a changeset documenting the patch.

Changes

Cohort / File(s) Summary
Changeset Documentation
.changeset/olive-bees-film.md
Adds a patch release entry for @mastra/core documenting that content.metadata.modelId is now persisted on assistant messages.
Core Implementation
packages/core/src/loop/workflows/agentic-execution/llm-execution-step.ts
Introduces buildResponseModelMetadata(runState) and spreads its result into message.content.metadata across streaming, reasoning, file/source, and tool-invocation message construction paths so assistant messages carry modelId when present.
Test Coverage
packages/core/src/agent/__tests__/memory-metadata.test.ts
Adds a v2-only test (via skipIf) that streams an assistant response into MockMemory, recalls assistant messages for a thread, and asserts each assistant message content.metadata.modelId equals 'mock-model-id'.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 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: fixing persistence of modelId in assistant message metadata. It is concise (58 chars, just over the 50-char suggestion), uses imperative mood ('fix'), and clearly conveys the purpose.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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/loop/workflows/agentic-execution/llm-execution-step.ts`:
- Around line 1012-1022: The code currently stamps responseModelId from
runState.state.responseMetadata onto every assistant message returned by
messageList.get.response.db(), which wrongly overwrites prior iterations'
modelIds; change the loop that iterates over messageList.get.response.db() (and
the code that sets msg.content.metadata) to only update messages whose messageId
matches the current step's response messages (use the current iteration's
message IDs kept on the run state or the subset returned by messageList for this
step) so only assistant messages produced in the current LLM execution (not
earlier ones) receive the responseModelId.
🧹 Nitpick comments (1)
.changeset/olive-bees-film.md (1)

5-5: Remove internal implementation detail from changeset description.

The phrase "from response-metadata stream chunks" exposes an internal implementation detail. Per the changeset guidelines, focus on the outcome for downstream consumers rather than how the data is sourced internally.

Consider simplifying to something like:

Fixed modelId not being persisted in assistant message content.metadata. Downstream consumers (storage adapters, processors) can now read which model generated each assistant message via content.metadata.modelId.

As per coding guidelines, changeset descriptions should "Highlight outcomes! What does change for the end user? Do not focus on internal implementation details" and use action-oriented verbs like "Fixed" for bug fixes.

Comment thread packages/core/src/loop/workflows/agentic-execution/llm-execution-step.ts Outdated
Currently llm-execution-step.ts captures modelId in
runState.state.responseMetadata during streaming but never propagates it
to MastraDBMessage.content.metadata before messages are saved. This
means downstream consumers (storage adapters, processors) that read
content.metadata.modelId receive undefined.

Inject responseMetadata.modelId into content.metadata of all assistant
response messages after they are added to the MessageList and before
output processors run.

Co-authored-by: Cursor <cursoragent@cursor.com>
@catdalfonso catdalfonso force-pushed the feature/persist-model-id-in-message-metadata branch from 484a657 to 1957c4a Compare February 11, 2026 21:33
if (responseModelId) {
for (const msg of messageList.get.response.db()) {
if (msg.id === messageId && msg.role === 'assistant') {
msg.content.metadata = { ...msg.content.metadata, modelId: responseModelId };

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

hmm I'm not sure this is the right way to do it, I think we should add it when we add messages to message list during streaming. The problem here is om "seals" messages now, breaking up the same agents response message into smaller chunks (each with unique ids) so that background buffering/retrieval of parts of messages works properly

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good call, I moved this around to better support OM.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.changeset/olive-bees-film.md:
- Line 5: Rewrite the changeset entry for the addition of modelId so it uses
short, direct, outcome-focused sentences aimed at developers: state what changed
(assistant messages now include a modelId in content.metadata), what users or
downstream systems will see (messages carry the model identifier so storage
adapters and processors can determine the model that generated a message), and
avoid internal implementation details (omit mentions of streaming internals,
sealed/split observational memory handling). Locate the text referencing
modelId, assistant message, and content.metadata in the current changeset and
replace it with 2–3 concise sentences that emphasize the observable behavior and
impact.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6d3c2e8 and fe7a04a.

📒 Files selected for processing (2)
  • .changeset/olive-bees-film.md
  • packages/core/src/loop/workflows/agentic-execution/llm-execution-step.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/core/src/loop/workflows/agentic-execution/llm-execution-step.ts

Comment thread .changeset/olive-bees-film.md Outdated
@abhiaiyer91 abhiaiyer91 merged commit 31b6067 into mastra-ai:main Mar 9, 2026
36 of 43 checks passed
graysonhicks pushed a commit that referenced this pull request Mar 10, 2026
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Tyler Barnes <tylerdbarnes@gmail.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.

3 participants