Skip to content

Conversation

@taofeeq-deru
Copy link
Contributor

@taofeeq-deru taofeeq-deru commented Dec 30, 2025

Description

  • Add resumeGenerate method for resuming agent via generate
  • Add runId and suspendPayload to fullOuput of agent stream
  • Fix suspendedToolRunId: null sometimes breaking agent.stream

Related Issue(s)

#11485

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

    • Resume suspended agent executions via a new generate-based resume API.
    • Agent output now exposes runId and suspendPayload for clearer result context.
  • Bug Fixes

    • suspendedToolRunId now defaults to an empty string to avoid null/undefined issues.
  • Tests

    • Added tests covering generate-based suspend/resume flows across tools and workflows.

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

@vercel
Copy link

vercel bot commented Dec 30, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
assistant-ui Ready Ready Preview, Comment Dec 31, 2025 9:35am
mastra-docs Ready Ready Preview, Comment Dec 31, 2025 9:35am
mastra-docs-1.x Ready Ready Preview, Comment Dec 31, 2025 9:35am

@changeset-bot
Copy link

changeset-bot bot commented Dec 30, 2025

🦋 Changeset detected

Latest commit: 89a6b90

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

This PR includes changesets to release 17 packages
Name Type
@mastra/core Patch
@mastra/mcp-docs-server Patch
@mastra/client-js Patch
@mastra/react Patch
@mastra/dane Patch
@mastra/longmemeval Patch
@mastra/playground-ui Patch
@mastra/server Patch
@mastra/deployer Patch
@mastra/deployer-cloud Patch
@mastra/express Patch
@mastra/hono Patch
mastra Patch
@mastra/deployer-cloudflare Patch
@mastra/deployer-netlify Patch
@mastra/deployer-vercel Patch
create-mastra 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 Dec 30, 2025

Walkthrough

Adds a public resumeGenerate() method to resume suspended generate executions, surfaces runId and suspendPayload on stream full outputs, and changes suspendedToolRunId default to an empty string; tests exercise generate-based suspend/resume across tools and workflows. (≤50 words)

Changes

Cohort / File(s) Summary
Changeset entry
.changeset/silent-ends-lick.md
Adds a patch-level changeset documenting the new resumeGenerate API, FullOutput additions (runId, suspendPayload), and the suspendedToolRunId default change.
Tests
packages/core/src/agent/__tests__/tool-approval.test.ts
Adds multiple tests covering suspend → resume via generate for single tools, auto-resume tools, and workflows (v1/v2), asserting suspendPayload, suspended state, and final results after resume.
Agent implementation
packages/core/src/agent/agent.ts
Adds resumeGenerate() implementation (loads snapshot, validates model, calls internal execute with methodType: 'generate', maps errors) and changes suspendedToolRunId ?? runId to `suspendedToolRunId
Stream output types
packages/core/src/stream/base/output.ts
Extends PromiseResults<OUTPUT> and DelayedPromises<OUTPUT> with suspendPayload; MastraModelOutput.getFullOutput() now includes runId and suspendPayload in the returned full output.
Tool builder defaults
packages/core/src/tools/tool-builder/builder.ts
When a tool's input schema is a Zod object, sets suspendedToolRunId default to "" (empty string) while keeping the field optional.
E2E snapshot
e2e-tests/create-mastra/create-mastra.test.ts
Reorders properties in an inline snapshot for a tool input schema (JSON key order change only).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs

  • #10871 — Modifies agent suspend/resume behavior and touches agent workflow resume logic (overlaps with resumeGenerate and runId changes).
  • #10444 — Adjusts tool suspend/resume schema/validation (related to suspendedToolRunId default and suspendPayload handling).
  • #10998 — Touches agent suspension/resume behavior and tool builder changes (related to resume paths and builder defaults).

Suggested reviewers

  • abhiaiyer91
  • NikAiyer

Pre-merge checks and finishing touches

❌ 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%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ 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 'add resumeGenerate to agent' clearly and concisely describes the main feature addition in the PR, which is adding a resumeGenerate method to the Agent class.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5b4d851 and 89a6b90.

📒 Files selected for processing (1)
  • e2e-tests/create-mastra/create-mastra.test.ts
✅ Files skipped from review due to trivial changes (1)
  • e2e-tests/create-mastra/create-mastra.test.ts
⏰ 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). (8)
  • GitHub Check: Validate build outputs
  • GitHub Check: test (express)
  • GitHub Check: test (hono)
  • GitHub Check: test
  • GitHub Check: test
  • GitHub Check: test
  • GitHub Check: test
  • GitHub Check: Analyze (javascript-typescript)

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.

@github-actions
Copy link
Contributor

github-actions bot commented Dec 30, 2025

🚨 Redirect Validation Failed

The redirect validation found issues in vercel.json (duplicate sources or broken destination links).

Action Required: Review and fix the redirect configuration.

📋 View workflow logs for details

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

Caution

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

⚠️ Outside diff range comments (1)
packages/core/src/stream/base/output.ts (1)

824-851: Ensure suspendPayload is resolved in tripwire flows to avoid getFullOutput() errors

The new getFullOutput() field:

runId: this.runId,
suspendPayload: await this.suspendPayload,

assumes the suspendPayload promise is always resolved or rejected in all successful agent runs. For:

  • Normal completes: finish case already resolves suspendPayload as undefined.
  • Suspended completes: tool-call-suspended / tool-call-approval resolve suspendPayload with the payload.

However, in the tripwire path, resolvePromises does not touch suspendPayload, so it stays pending and is then rejected in the transformer flush’s “reject unresolved promises” loop. With the new await this.suspendPayload, this will cause getFullOutput() to throw for tripwire runs, even though other fields (text, tripwire, etc.) are valid.

To keep the new public surface safe, suspendPayload should be explicitly resolved to undefined in the tripwire case as well, matching the non‑suspended finish behavior.

Proposed fix: resolve suspendPayload in the tripwire case
            case 'tripwire':
              // Handle tripwire chunks from processors
              self.#tripwire = {
                reason: chunk.payload?.reason || 'Content blocked',
                retry: chunk.payload?.retry,
                metadata: chunk.payload?.metadata,
                processorId: chunk.payload?.processorId,
              };
              self.#finishReason = 'other';
              // Mark stream as finished for EventEmitter
              self.#streamFinished = true;

              // Resolve all delayed promises before terminating
              self.resolvePromises({
                text: self.#bufferedText.join(''),
                finishReason: 'other',
                object: undefined,
                usage: self.#usageCount,
                warnings: self.#warnings,
                providerMetadata: undefined,
                response: {},
                request: {},
                reasoning: [],
                reasoningText: undefined,
                sources: [],
                files: [],
                toolCalls: [],
                toolResults: [],
                steps: self.#bufferedSteps,
                totalUsage: self.#usageCount,
                content: [],
+               suspendPayload: undefined,
              });

This keeps suspendPayload consistently defined (or undefined) in all non‑error terminal states while preserving existing semantics for suspended runs.

Also applies to: 1118-1142

🧹 Nitpick comments (2)
packages/core/src/agent/__tests__/tool-approval.test.ts (1)

406-471: New generate-based suspend/resume tests look correct and comprehensive

The added tests for:

  • Tool suspend/resume via generate + resumeGenerate,
  • Tool suspend/resume via generate with autoResumeSuspendedTools,
  • Workflow suspend/resume via generate + resumeGenerate,
  • Workflow suspend/resume via generate with autoResumeSuspendedTools,

all correctly validate:

  • finishReason === 'suspended' and empty toolResults on the initial suspended call,
  • the shape and content of output.suspendPayload,
  • successful resume behavior and final tool/workflow outputs,
  • resumeOutput.suspendPayload being undefined after completion.

This gives solid coverage of the new resumeGenerate API and the extended fullOutput surface across both tools and workflows. Any duplication in tool/workflow setup is acceptable here for test readability; refactoring to helpers can be deferred.

Also applies to: 575-667, 778-877, 992-1093

packages/core/src/agent/agent.ts (1)

2060-2073: Workflow runId selection and resumeGenerate implementation are consistent; consider deduping with generate()

  • The change to const runIdToUse = suspendedToolRunId || runId; is consistent with the input schema default of '' and ensures:

    • New workflow invocations (no suspended run) use the agent run’s runId.
    • Resumes with a real suspendedToolRunId continue to target the original workflow run.
  • The new resumeGenerate():

    • Merges defaults with overrides in the same way as generate().
    • Enforces the same v1-model guard (AGENT_GENERATE_V1_MODEL_NOT_SUPPORTED).
    • Correctly loads the agentic-loop snapshot by runId and passes resumeContext into #execute with methodType: 'generate'.
    • Returns getFullOutput() and propagates finish-time errors exactly as generate() does.

Functionally this all looks sound. The generate and resumeGenerate bodies are now largely duplicated; if this evolves further, it may be worth extracting a small shared helper to construct and run the inner execution options to keep behavior in lockstep.

Also applies to: 3253-3338

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 46ce908 and fb552f5.

📒 Files selected for processing (5)
  • .changeset/silent-ends-lick.md
  • packages/core/src/agent/__tests__/tool-approval.test.ts
  • packages/core/src/agent/agent.ts
  • packages/core/src/stream/base/output.ts
  • packages/core/src/tools/tool-builder/builder.ts
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Run pnpm typecheck to validate TypeScript types across all packages

Files:

  • packages/core/src/tools/tool-builder/builder.ts
  • packages/core/src/agent/agent.ts
  • packages/core/src/agent/__tests__/tool-approval.test.ts
  • packages/core/src/stream/base/output.ts
**/*.{ts,tsx,js,jsx,json,md}

📄 CodeRabbit inference engine (CLAUDE.md)

Run pnpm prettier:format to format code and pnpm format to run linting with auto-fix across all packages

Files:

  • packages/core/src/tools/tool-builder/builder.ts
  • packages/core/src/agent/agent.ts
  • packages/core/src/agent/__tests__/tool-approval.test.ts
  • packages/core/src/stream/base/output.ts
packages/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

packages/**/*.{ts,tsx}: All packages must use TypeScript with strict type checking enabled
Use telemetry decorators for observability across components

Files:

  • packages/core/src/tools/tool-builder/builder.ts
  • packages/core/src/agent/agent.ts
  • packages/core/src/agent/__tests__/tool-approval.test.ts
  • packages/core/src/stream/base/output.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{test,spec}.{ts,tsx}: Use Vitest for testing framework in test files
Co-locate test files with source code using naming patterns like *.test.ts or *.spec.ts

Files:

  • packages/core/src/agent/__tests__/tool-approval.test.ts
.changeset/*.md

⚙️ CodeRabbit configuration file

.changeset/*.md: Changeset files are really important for keeping track of changes in the project. They'll be used to generate release notes and inform users about updates.

Review the changeset file according to these guidelines:

  • The target audience are developers
  • Write short, direct sentences that anyone can understand. Avoid commit messages, technical jargon, and acronyms. Use action-oriented verbs (Added, Fixed, Improved, Deprecated, Removed)
  • Avoid generic phrases like "Update code", "Miscellaneous improvements", or "Bug fixes"
  • Highlight outcomes! What does change for the end user? Do not focus on internal implementation details
  • Add context like links to issues or PRs when relevant
  • If the change is a breaking change or is adding a new feature, ensure that a code example is provided. This code example should show the public API usage (the before and after). Do not show code examples of internal implementation details.
  • Keep the formatting easy-to-read and scannable. If necessary, use bullet points or multiple paragraphs (Use bold text as the heading for these sections, do not use markdown headings).
  • For larger, more substantial changes, also answer the "Why" behind the changes
  • Each changeset file contains a YAML frontmatter at the top. It will be one or more package names followed by a colon and the type of change (patch, minor, major). Do not modify this frontmatter. Check that the description inside the changeset file only applies to the packages listed in the frontmatter. Do not allow descriptions that mention changes to packages not listed in the frontmatter. In these cases, the user must create a separate changeset file for those packages.

Files:

  • .changeset/silent-ends-lick.md
🧠 Learnings (7)
📓 Common learnings
Learnt from: taofeeq-deru
Repo: mastra-ai/mastra PR: 11486
File: packages/core/src/loop/workflows/agentic-execution/llm-execution-step.ts:643-678
Timestamp: 2025-12-30T15:02:58.132Z
Learning: In `packages/core/src/loop/workflows/agentic-execution/llm-execution-step.ts`, the system guarantees that `metadata.suspendedTools` and `metadata.pendingToolApprovals` never contain resumed tools, so no filtering is needed when using metadata directly.
📚 Learning: 2025-12-30T15:02:58.132Z
Learnt from: taofeeq-deru
Repo: mastra-ai/mastra PR: 11486
File: packages/core/src/loop/workflows/agentic-execution/llm-execution-step.ts:643-678
Timestamp: 2025-12-30T15:02:58.132Z
Learning: In `packages/core/src/loop/workflows/agentic-execution/llm-execution-step.ts`, the system guarantees that `metadata.suspendedTools` and `metadata.pendingToolApprovals` never contain resumed tools, so no filtering is needed when using metadata directly.

Applied to files:

  • packages/core/src/tools/tool-builder/builder.ts
  • packages/core/src/agent/agent.ts
  • packages/core/src/agent/__tests__/tool-approval.test.ts
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/test/**/*.test.ts : Include test cases for multiple occurrences of the transformation pattern, aliased imports, type imports, and mixed imports to verify the codemod works consistently

Applied to files:

  • packages/core/src/agent/__tests__/tool-approval.test.ts
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/test/__fixtures__/**/*.ts : Create test fixtures by copying examples DIRECTLY from migration guides in `docs/src/content/en/guides/migrations/upgrade-to-v1/` without hallucinating or inventing changes

Applied to files:

  • packages/core/src/agent/__tests__/tool-approval.test.ts
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/test/__fixtures__/**/*.ts : In output fixtures, ensure all NEGATIVE test cases remain EXACTLY IDENTICAL to their input fixture counterparts to verify the codemod only transforms intended patterns

Applied to files:

  • packages/core/src/agent/__tests__/tool-approval.test.ts
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/test/__fixtures__/**/*.ts : In input fixtures, include both POSITIVE test cases (patterns that should transform) and NEGATIVE test cases (unrelated code with similar names/patterns that should NOT transform)

Applied to files:

  • packages/core/src/agent/__tests__/tool-approval.test.ts
📚 Learning: 2025-11-24T16:42:04.244Z
Learnt from: CR
Repo: mastra-ai/mastra PR: 0
File: packages/codemod/AGENTS.md:0-0
Timestamp: 2025-11-24T16:42:04.244Z
Learning: Applies to packages/codemod/src/test/**/*.test.ts : Do NOT use `UPDATE_SNAPSHOT` to force tests to pass; instead fix the codemod implementation when tests fail

Applied to files:

  • packages/core/src/agent/__tests__/tool-approval.test.ts
🧬 Code graph analysis (2)
packages/core/src/agent/agent.ts (3)
packages/core/src/agent/agent.types.ts (2)
  • AgentExecutionOptions (34-135)
  • InnerAgentExecutionOptions (137-149)
packages/core/src/agent/utils.ts (1)
  • isSupportedLanguageModel (10-14)
packages/core/src/error/index.ts (1)
  • MastraError (142-142)
packages/core/src/agent/__tests__/tool-approval.test.ts (2)
packages/core/src/tools/tool.ts (1)
  • createTool (365-388)
examples/agent/src/mastra/workflows/other.ts (1)
  • findUserWorkflow (127-140)
⏰ 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). (7)
  • GitHub Check: test
  • GitHub Check: test
  • GitHub Check: Prebuild
  • GitHub Check: test
  • GitHub Check: test (hono)
  • GitHub Check: test (express)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
packages/core/src/tools/tool-builder/builder.ts (1)

67-73: suspendedToolRunId default aligns with resume semantics

Setting suspendedToolRunId to optional().default('') is consistent with downstream usage (suspendedToolRunId || runId) and avoids null/undefined issues in resume flows. No changes needed here.

@taofeeq-deru taofeeq-deru deleted the agent-resume-generate branch December 31, 2025 10:09
astout55555 pushed a commit to astout55555/mastra that referenced this pull request Jan 6, 2026
## Description

<!-- Provide a brief description of the changes in this PR -->

- [x] Add `resumeGenerate` method for resuming agent via generate
- [x] Add `runId` and `suspendPayload` to fullOuput of agent stream
- [x] Fix `suspendedToolRunId: null` sometimes breaking `agent.stream`

## Related Issue(s)

<!-- Link to the issue(s) this PR addresses, using hashtag notation:
mastra-ai#123 -->
mastra-ai#11485 

## Type of Change

- [x] Bug fix (non-breaking change that fixes an issue)
- [x] 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
- [x] Test update

## Checklist

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


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Resume suspended agent executions via a new generate-based resume API.
* Agent output now exposes runId and suspendPayload for clearer result
context.

* **Bug Fixes**
* suspendedToolRunId now defaults to an empty string to avoid
null/undefined issues.

* **Tests**
* Added tests covering generate-based suspend/resume flows across tools
and workflows.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Abhi Aiyer <abhiaiyer91@gmail.com>
@coderabbitai coderabbitai bot mentioned this pull request Jan 8, 2026
9 tasks
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.

4 participants