Skip to content

Develop#69

Merged
ssdeanx merged 2 commits intomainfrom
develop
Jan 5, 2026
Merged

Develop#69
ssdeanx merged 2 commits intomainfrom
develop

Conversation

@ssdeanx
Copy link
Owner

@ssdeanx ssdeanx commented Jan 5, 2026

Summary by Sourcery

Integrate an e2b-powered sandbox tool suite into the Mastra workflows and register a new marketing campaign workflow while updating related dependencies and cleaning up unused GitHub instruction files.

New Features:

  • Add a comprehensive set of e2b sandbox tools for code execution, filesystem operations, directory watching, and command running.
  • Register a new marketing campaign workflow in the Mastra workflow configuration.

Enhancements:

  • Upgrade multiple AI and UI-related dependencies to newer patch or minor versions for improved compatibility and maintenance.

Chores:

  • Remove obsolete GitHub instruction markdown files from the repository.

- Updated @ai-sdk/google-vertex from ^4.0.2 to ^4.0.3
- Updated @ai-sdk/react from ^3.0.6 to ^3.0.7
- Updated ai-sdk-provider-claude-code from ^3.0.1 to ^3.1.0
- Updated framer-motion from ^12.23.26 to ^12.24.0
- Updated motion from ^12.23.26 to ^12.24.0
- Updated react-resizable-panels from ^4.2.0 to ^4.2.1
- Updated @ai-sdk/anthropic from 3.0.2 to 3.0.3
- Added marketingCampaignWorkflow to mastra workflows
- Removed memory-agent and memory-bank instruction files
- Introduced new tools for e2b sandbox functionality:
  - createSandbox: Create a new e2b sandbox with custom metadata and environment variables.
  - runCode: Execute code within an e2b sandbox, supporting multiple languages.
  - readFile: Read a file from the e2b sandbox.
  - writeFile: Write a single file to the e2b sandbox.
  - writeFiles: Write multiple files to the e2b sandbox.
  - listFiles: List files and directories in a specified path within the e2b sandbox.
  - deleteFile: Delete a file or directory from the e2b sandbox.
  - createDirectory: Create a directory in the e2b sandbox.
  - getFileInfo: Retrieve detailed information about a file or directory in the e2b sandbox.
  - checkFileExists: Check if a file or directory exists in the e2b sandbox.
  - getFileSize: Get the size of a file or directory in the e2b sandbox.
  - watchDirectory: Monitor a directory for file system changes in the e2b sandbox.
  - runCommand: Execute a shell command in the e2b sandbox.

- Updated package.json and package-lock.json to include new dependencies:
  - Added "@e2b/code-interpreter": "^2.3.3".
Copilot AI review requested due to automatic review settings January 5, 2026 17:06
@continue
Copy link

continue bot commented Jan 5, 2026

All Green - Keep your PRs mergeable

Learn more

All Green is an AI agent that automatically:

✅ Addresses code review comments

✅ Fixes failing CI checks

✅ Resolves merge conflicts


Unsubscribe from All Green comments

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@sourcery-ai
Copy link

sourcery-ai bot commented Jan 5, 2026

Reviewer's Guide

Adds a new set of e2b code-interpreter-backed Mastra tools for sandboxed code execution and filesystem operations, wires a new marketing workflow into the Mastra entrypoint, updates several AI/animation/react-related dependencies, and removes obsolete GitHub memory instruction files.

Sequence diagram for watchDirectory e2b sandbox tool execution

sequenceDiagram
  actor Caller
  participant watchDirectoryTool
  participant Sandbox
  participant FilesAPI as FilesAPI
  participant WatchHandle

  Caller->>watchDirectoryTool: execute(inputData)
  activate watchDirectoryTool
  watchDirectoryTool->>Sandbox: connect(inputData.sandboxId)
  activate Sandbox
  Sandbox-->>watchDirectoryTool: sandbox
  deactivate Sandbox

  watchDirectoryTool->>FilesAPI: watchDir(inputData.path, onEvent, {recursive})
  activate FilesAPI
  FilesAPI-->>watchDirectoryTool: WatchHandle
  deactivate FilesAPI

  loop watchDuration
    FilesAPI-->>watchDirectoryTool: onEvent(event)
    watchDirectoryTool->>watchDirectoryTool: push event to events array
  end

  watchDirectoryTool->>WatchHandle: stop()
  activate WatchHandle
  WatchHandle-->>watchDirectoryTool: stopped
  deactivate WatchHandle

  watchDirectoryTool-->>Caller: {watchStarted, path, events}
  deactivate watchDirectoryTool
Loading

Class diagram for new e2b sandbox tools integration

classDiagram
  class MastraTool {
    +id string
    +description string
    +inputSchema ZodSchema
    +outputSchema ZodSchema
    +execute(input any) Promise~any~
  }

  class Sandbox {
    +string sandboxId
    +static create(options any) Promise~Sandbox~
    +static connect(sandboxId string) Promise~Sandbox~
    +runCode(code string, runCodeOpts any) Promise~Execution~
    +files FilesAPI
    +commands CommandsAPI
  }

  class FilesAPI {
    +read(path string) Promise~string~
    +write(path string, content any) Promise~void~
    +list(path string) Promise~FileInfo[]~
    +remove(path string) Promise~void~
    +makeDir(path string) Promise~void~
    +getInfo(path string) Promise~FileInfo~
    +watchDir(path string, onEvent FilesystemCallback, options any) Promise~WatchHandle~
  }

  class CommandsAPI {
    +run(command string, options any) Promise~CommandResult~
  }

  class FileInfo {
    +string name
    +FileType type
    +string path
    +number size
    +number mode
    +string permissions
    +string owner
    +string group
    +Date modifiedTime
    +string symlinkTarget
  }

  class WatchHandle {
    +stop() Promise~void~
  }

  class Execution {
    +toJSON() any
  }

  class CommandResult {
    +number exitCode
    +string stdout
    +string stderr
  }

  class createSandboxTool {
    +execute(sandboxOptions any) Promise~CreateSandboxOutput~
  }

  class runCodeTool {
    +execute(inputData any) Promise~RunCodeOutput~
  }

  class readFileTool {
    +execute(inputData any) Promise~ReadFileOutput~
  }

  class writeFileTool {
    +execute(inputData any) Promise~WriteFileOutput~
  }

  class writeFilesTool {
    +execute(inputData any) Promise~WriteFilesOutput~
  }

  class listFilesTool {
    +execute(inputData any) Promise~ListFilesOutput~
  }

  class deleteFileTool {
    +execute(inputData any) Promise~DeleteFileOutput~
  }

  class createDirectoryTool {
    +execute(inputData any) Promise~CreateDirectoryOutput~
  }

  class getFileInfoTool {
    +execute(inputData any) Promise~GetFileInfoOutput~
  }

  class checkFileExistsTool {
    +execute(inputData any) Promise~CheckFileExistsOutput~
  }

  class getFileSizeTool {
    +execute(inputData any) Promise~GetFileSizeOutput~
  }

  class watchDirectoryTool {
    +execute(inputData any) Promise~WatchDirectoryOutput~
  }

  class runCommandTool {
    +execute(inputData any) Promise~RunCommandOutput~
  }

  MastraTool <|-- createSandboxTool
  MastraTool <|-- runCodeTool
  MastraTool <|-- readFileTool
  MastraTool <|-- writeFileTool
  MastraTool <|-- writeFilesTool
  MastraTool <|-- listFilesTool
  MastraTool <|-- deleteFileTool
  MastraTool <|-- createDirectoryTool
  MastraTool <|-- getFileInfoTool
  MastraTool <|-- checkFileExistsTool
  MastraTool <|-- getFileSizeTool
  MastraTool <|-- watchDirectoryTool
  MastraTool <|-- runCommandTool

  createSandboxTool --> Sandbox : create()
  runCodeTool --> Sandbox : connect()
  readFileTool --> Sandbox : connect()
  writeFileTool --> Sandbox : connect()
  writeFilesTool --> Sandbox : connect()
  listFilesTool --> Sandbox : connect()
  deleteFileTool --> Sandbox : connect()
  createDirectoryTool --> Sandbox : connect()
  getFileInfoTool --> Sandbox : connect()
  checkFileExistsTool --> Sandbox : connect()
  getFileSizeTool --> Sandbox : connect()
  watchDirectoryTool --> Sandbox : connect()
  runCommandTool --> Sandbox : connect()

  Sandbox --> FilesAPI : files
  Sandbox --> CommandsAPI : commands
  FilesAPI --> FileInfo
  FilesAPI --> WatchHandle
  Sandbox --> Execution
  CommandsAPI --> CommandResult
Loading

File-Level Changes

Change Details Files
Introduce e2b sandbox tooling for code execution, filesystem management, and process control within Mastra.
  • Add @e2b/code-interpreter as a runtime dependency
  • Define Mastra tools to create/connect sandboxes and run code with configurable language and timeouts
  • Expose filesystem helpers for reading, writing, listing, deleting, and inspecting files/directories, including size and existence checks
  • Add directory watch support that streams filesystem events over a bounded time window
  • Provide a runCommand helper to execute shell commands with timeout and execution metadata
package.json
src/mastra/tools/e2b.ts
package-lock.json
Wire an additional marketing campaign workflow into the Mastra workflows registry.
  • Import marketingCampaignWorkflow from the workflows module into the Mastra index
  • Expose the new workflow through the Mastra configuration so it can be invoked like existing workflows
src/mastra/index.ts
Refresh selected frontend and AI SDK dependencies to newer patch/minor versions.
  • Bump several @ai-sdk/* packages, including google-vertex, react, and claude-code provider
  • Update motion/framer-motion and react-resizable-panels to newer versions for UI/animation fixes and improvements
package.json
package-lock.json
Remove unused GitHub memory agent instruction files from the repository.
  • Delete memory-agent and memory-bank instruction markdown files under .github
.github/-/memory-agent.instruction.md
.github/-/memory-bank.instructions.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@github-actions
Copy link

github-actions bot commented Jan 5, 2026

🤖 Hi @ssdeanx, I've received your request, and I'm working on it now! You can track my progress in the logs for more details.

@coderabbitai
Copy link

coderabbitai bot commented Jan 5, 2026

Caution

Review failed

The pull request is closed.

Summary by CodeRabbit

  • New Features

    • Integrated E2B code execution sandbox with tools for running code, managing files, and executing commands across multiple programming languages
    • Added marketing campaign workflow support
  • Chores

    • Updated dependencies across AI SDK, Framer Motion, and related packages
    • Added code interpreter dependency for enhanced execution capabilities

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

Walkthrough

This PR removes two documentation files related to memory management infrastructure, updates package dependencies including a new E2B code interpreter integration, registers a marketing campaign workflow in the Mastra instance, and introduces a comprehensive E2B sandbox toolset with 13 operations for sandbox lifecycle and filesystem management.

Changes

Cohort / File(s) Summary
Memory Documentation Removal
.github/-/memory-agent.instruction.md, .github/-/memory-bank.instructions.md
Deleted documentation files describing Memory Agent and Memory Bank structure, workflows, and task management conventions; no code logic affected.
Dependency Updates
package.json
Updated 6 dependencies to patch/minor versions (@ai-sdk/google-vertex, @ai-sdk/react, framer-motion, motion, react-resizable-panels, ai-sdk-provider-claude-code); added new @e2b/code-interpreter dependency (^2.3.3).
Workflow Registration
src/mastra/index.ts
Added import and registration of marketingCampaignWorkflow in Mastra workflows collection.
E2B Sandbox Toolset
src/mastra/tools/e2b.ts
New file introducing 13 tools for E2B sandbox interactions: createSandbox, runCode, readFile, writeFile, writeFiles, listFiles, deleteFile, createDirectory, getFileInfo, checkFileExists, getFileSize, watchDirectory, runCommand; each with Zod-validated input/output schemas, error handling, and structured return types.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • sourcery-ai

Poem

🐰 Hop hop, the sandbox tools are here!
With E2B magic, files run clear—
Workflows dance, deps take flight,
Memory banks fade into night,
New code paths blazing ever bright! ✨

✨ 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 develop

📜 Recent review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0ae75b1 and a497bf4.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (5)
  • .github/-/memory-agent.instruction.md
  • .github/-/memory-bank.instructions.md
  • package.json
  • src/mastra/index.ts
  • src/mastra/tools/e2b.ts

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.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @ssdeanx, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces significant enhancements to the AI agent system by integrating the E2B Code Interpreter, allowing agents to dynamically execute code and shell commands within isolated sandboxes. This change is accompanied by the removal of a static, documentation-based memory system, signaling a strategic pivot towards a more interactive and code-driven approach for agent intelligence and task management. Additionally, a new workflow has been added, and various project dependencies have been updated to ensure the system remains current.

Highlights

  • E2B Code Interpreter Integration: A comprehensive set of tools has been added to enable AI agents to interact with E2B sandboxes. This includes capabilities to create sandboxes, execute code (Python, TypeScript, JavaScript), run shell commands, and perform various file system operations like reading, writing, listing, and deleting files and directories.
  • Refactoring of Agent Memory Management: The previous static documentation-based memory and instruction files (memory-agent.instruction.md and memory-bank.instructions.md) have been removed. This suggests a shift from a documentation-centric approach to a more dynamic, code-driven model for managing AI agent intelligence and task context.
  • New Workflow Introduction: A new marketingCampaignWorkflow has been imported and registered within the Mastra system, indicating an expansion of the available AI agent functionalities.
  • Dependency Updates: Several project dependencies, including @ai-sdk/google-vertex, @ai-sdk/react, ai-sdk-provider-claude-code, framer-motion, motion, and react-resizable-panels, have been updated to their latest patch or minor versions.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@ssdeanx ssdeanx merged commit f9acb6a into main Jan 5, 2026
17 of 21 checks passed
Copy link

@sourcery-ai sourcery-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.

Hey - I've found 4 issues, and left some high level feedback:

  • The import import { marketingCampaignWorkflow } from './workflows' in src/mastra/index.ts looks incorrect and likely needs a more specific path (e.g. the actual workflow file) to avoid runtime import failures.
  • In src/mastra/tools/e2b.ts, schemas like z.enum(FileType) and z.enum(FilesystemEventType) are probably invalid because z.enum expects string literals; consider using z.nativeEnum(...) or explicit string unions that match the enum values.
  • The repeated error-wrapping (const errObj = ...; throw new Error(JSON.stringify(errObj));) across all tools in e2b.ts could be refactored into a small helper to reduce duplication and keep the tools’ execute functions more focused.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The import `import { marketingCampaignWorkflow } from './workflows'` in `src/mastra/index.ts` looks incorrect and likely needs a more specific path (e.g. the actual workflow file) to avoid runtime import failures.
- In `src/mastra/tools/e2b.ts`, schemas like `z.enum(FileType)` and `z.enum(FilesystemEventType)` are probably invalid because `z.enum` expects string literals; consider using `z.nativeEnum(...)` or explicit string unions that match the enum values.
- The repeated error-wrapping (`const errObj = ...; throw new Error(JSON.stringify(errObj));`) across all tools in `e2b.ts` could be refactored into a small helper to reduce duplication and keep the tools’ execute functions more focused.

## Individual Comments

### Comment 1
<location> `src/mastra/tools/e2b.ts:273` </location>
<code_context>
+  }),
+  outputSchema: z.object({
+      name: z.string().describe('The name of the file or directory'),
+      type: z.enum(FileType).optional().describe('Whether this is a file or directory'),
+      path: z.string().describe('The full path of the file or directory'),
+      size: z.number().describe('The size of the file or directory in bytes'),
</code_context>

<issue_to_address>
**issue (bug_risk):** Use `z.nativeEnum` (or string literals) instead of passing the enum type directly to `z.enum`.

`z.enum` requires an array of string literals, not the enum object. Here this should be `z.nativeEnum(FileType)` or `z.enum(['FILE', 'DIR', ...] as const)`, and the same adjustment is needed in `checkFileExists` and `getFileSize` where `z.enum(FileType)` is currently used.
</issue_to_address>

### Comment 2
<location> `src/mastra/tools/e2b.ts:280` </location>
<code_context>
+      permissions: z.string().describe('Human-readable permissions string'),
+      owner: z.string().describe('The owner of the file or directory'),
+      group: z.string().describe('The group of the file or directory'),
+      modifiedTime: z.date().optional().describe('The last modified time in ISO string format'),
+      symlinkTarget: z.string().optional().describe('The target path if this is a symlink, null otherwise'),
+    }),
</code_context>

<issue_to_address>
**issue (bug_risk):** `modifiedTime` is typed as `Date` but described as an ISO string, which is inconsistent with the likely runtime value.

The schema currently uses `z.date()` while the description implies an ISO string, and many APIs return timestamps as strings. If `info.modifiedTime` is a string, validation will fail; if it’s a `Date`, the description is inaccurate. Please either switch to `z.string()` for ISO timestamps or ensure the value is converted with `new Date(...)` before validation/return.
</issue_to_address>

### Comment 3
<location> `src/mastra/tools/e2b.ts:314-20` </location>
<code_context>
+    sandboxId: z.string().describe('The sandboxId for the sandbox to check file existence in'),
+    path: z.string().describe('The path to check for existence'),
+  }),
+  outputSchema: z
+    .object({
+      exists: z.boolean().describe('Whether the file or directory exists'),
+      path: z.string().describe('The path that was checked'),
+      type: z.enum(FileType).optional().describe('The type if the path exists'),
+    })
+    .or(
+      z.object({
+        error: z.string().describe('The error from a failed existence check'),
+      }),
+    ),
+  execute: async (inputData) => {
</code_context>

<issue_to_address>
**suggestion:** The union branch with `{ error: string }` is never returned because errors are rethrown, making the schema misleading.

In `getFileSize`, `checkFileExists`, and `watchDirectory`, the `outputSchema` is a union of a success object and `{ error: string }`, but the outer `try` block wraps failures into thrown exceptions instead. Since `{ error: string }` is never actually returned, please either return that shape on failure instead of throwing, or remove the error branch from the schema so it reflects the real behavior.
</issue_to_address>

### Comment 4
<location> `src/mastra/tools/e2b.ts:484` </location>
<code_context>
+    command: z.string().describe('The shell command to execute'),
+    workingDirectory: z.string().optional().describe('The working directory to run the command in'),
+    timeoutMs: z.number().default(30000).describe('Timeout for the command execution in milliseconds'),
+    captureOutput: z.boolean().default(true).describe('Whether to capture stdout and stderr output'),
+  }),
+  outputSchema: z.object({
</code_context>

<issue_to_address>
**suggestion:** `captureOutput` option is defined but never used in `runCommand` execution logic.

In `runCommand.execute`, `stdout` and `stderr` are always captured and returned, so `captureOutput` currently has no effect. Please either connect this flag to the underlying `sandbox.commands.run` behavior (if available) or remove it from the schema to avoid a misleading, no-op option.

Suggested implementation:

```typescript
  inputSchema: z.object({
    sandboxId: z.string().describe('The sandboxId for the sandbox to run the command in'),
    command: z.string().describe('The shell command to execute'),
    workingDirectory: z.string().optional().describe('The working directory to run the command in'),
    timeoutMs: z.number().default(30000).describe('Timeout for the command execution in milliseconds'),

```

1. Remove any `captureOutput` property from the `runCommand` `inputSchema` object if it appears elsewhere in this file (e.g., if the snippet you shared was truncated before the `captureOutput` line).
2. If `captureOutput` is currently destructured or referenced in `runCommand.execute` or in any type definitions derived from `inputSchema`, remove those references as well.
3. If there is public documentation or type exports describing `captureOutput` for `runCommand`, update them to reflect that this option is no longer available.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

}),
outputSchema: z.object({
name: z.string().describe('The name of the file or directory'),
type: z.enum(FileType).optional().describe('Whether this is a file or directory'),
Copy link

Choose a reason for hiding this comment

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

issue (bug_risk): Use z.nativeEnum (or string literals) instead of passing the enum type directly to z.enum.

z.enum requires an array of string literals, not the enum object. Here this should be z.nativeEnum(FileType) or z.enum(['FILE', 'DIR', ...] as const), and the same adjustment is needed in checkFileExists and getFileSize where z.enum(FileType) is currently used.

permissions: z.string().describe('Human-readable permissions string'),
owner: z.string().describe('The owner of the file or directory'),
group: z.string().describe('The group of the file or directory'),
modifiedTime: z.date().optional().describe('The last modified time in ISO string format'),
Copy link

Choose a reason for hiding this comment

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

issue (bug_risk): modifiedTime is typed as Date but described as an ISO string, which is inconsistent with the likely runtime value.

The schema currently uses z.date() while the description implies an ISO string, and many APIs return timestamps as strings. If info.modifiedTime is a string, validation will fail; if it’s a Date, the description is inaccurate. Please either switch to z.string() for ISO timestamps or ensure the value is converted with new Date(...) before validation/return.

command: z.string().describe('The shell command to execute'),
workingDirectory: z.string().optional().describe('The working directory to run the command in'),
timeoutMs: z.number().default(30000).describe('Timeout for the command execution in milliseconds'),
captureOutput: z.boolean().default(true).describe('Whether to capture stdout and stderr output'),
Copy link

Choose a reason for hiding this comment

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

suggestion: captureOutput option is defined but never used in runCommand execution logic.

In runCommand.execute, stdout and stderr are always captured and returned, so captureOutput currently has no effect. Please either connect this flag to the underlying sandbox.commands.run behavior (if available) or remove it from the schema to avoid a misleading, no-op option.

Suggested implementation:

  inputSchema: z.object({
    sandboxId: z.string().describe('The sandboxId for the sandbox to run the command in'),
    command: z.string().describe('The shell command to execute'),
    workingDirectory: z.string().optional().describe('The working directory to run the command in'),
    timeoutMs: z.number().default(30000).describe('Timeout for the command execution in milliseconds'),
  1. Remove any captureOutput property from the runCommand inputSchema object if it appears elsewhere in this file (e.g., if the snippet you shared was truncated before the captureOutput line).
  2. If captureOutput is currently destructured or referenced in runCommand.execute or in any type definitions derived from inputSchema, remove those references as well.
  3. If there is public documentation or type exports describing captureOutput for runCommand, update them to reflect that this option is no longer available.

@github-actions
Copy link

github-actions bot commented Jan 5, 2026

🤖 I'm sorry @ssdeanx, but I was unable to process your request. Please see the logs for more details.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request successfully integrates a comprehensive suite of e2b-powered sandbox tools, updates several dependencies to their latest patch or minor versions, and registers a new marketing campaign workflow. The new e2b tools are well-structured with clear input and output schemas, and consistent error handling. The dependency updates are routine and contribute to improved compatibility and maintenance. The removal of obsolete GitHub instruction files is a good cleanup step.

command: z.string().describe('The shell command to execute'),
workingDirectory: z.string().optional().describe('The working directory to run the command in'),
timeoutMs: z.number().default(30000).describe('Timeout for the command execution in milliseconds'),
captureOutput: z.boolean().default(true).describe('Whether to capture stdout and stderr output'),
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The captureOutput parameter is defined in the runCommand tool's input schema but is not used within the execute function. The e2b SDK's commands.run method captures stdout and stderr by default, making this parameter redundant and potentially misleading for users who might expect to control this behavior. Consider removing it if it doesn't offer additional functionality or implementing its control if the SDK supports it.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request adds E2B sandbox integration tools to the Mastra framework. The PR introduces a comprehensive set of tools for managing and interacting with E2B sandboxes, including code execution, file system operations, and command execution capabilities.

Key Changes

  • Added new E2B integration tools with 13 distinct tool functions covering sandbox creation, code execution, file operations, and directory monitoring
  • Updated package dependencies to include @e2b/code-interpreter and several minor version bumps
  • Removed internal GitHub instruction documentation files for memory bank and memory agent

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 21 comments.

Show a summary per file
File Description
src/mastra/tools/e2b.ts New file implementing 13 E2B sandbox tools including createSandbox, runCode, file operations (read/write/delete/list), directory operations, and command execution with comprehensive Zod schemas
src/mastra/index.ts Added import for marketingCampaignWorkflow from workflows module
package.json Updated dependencies: @ai-sdk/google-vertex (4.0.3), @ai-sdk/react (3.0.7), added @e2b/code-interpreter (2.3.3), and minor version bumps for ai-sdk-provider-claude-code, framer-motion, motion, and react-resizable-panels
package-lock.json Lockfile updates reflecting the dependency changes in package.json, including new transitive dependencies for @e2b/code-interpreter
.github/-/memory-bank.instructions.md Removed internal memory bank instruction documentation
.github/-/memory-agent.instruction.md Removed internal memory agent instruction documentation

Comment on lines +89 to +92
outputSchema: z.object({
content: z.string().describe('The content of the file'),
path: z.string().describe('The path of the file that was read'),
}),
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

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

Inconsistent indentation detected in the outputSchema object. The object properties should align with the opening brace, similar to how inputSchema is formatted.

Copilot uses AI. Check for mistakes.
Comment on lines +117 to +120
outputSchema: z.object({
success: z.boolean().describe('Whether the file was written successfully'),
path: z.string().describe('The path where the file was written'),
}),
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

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

Inconsistent indentation detected in the outputSchema object. The object properties should align with the opening brace, similar to how inputSchema is formatted.

Copilot uses AI. Check for mistakes.
const errObj = e instanceof Error ? { message: e.message, stack: e.stack } : { message: String(e) };
throw new Error(JSON.stringify(errObj));
}
}
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

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

Missing trailing comma after the closing brace of the execute function. This is inconsistent with the pattern used in other tool exports in this file.

Suggested change
}
},

Copilot uses AI. Check for mistakes.
.object({
exists: z.boolean().describe('Whether the file or directory exists'),
path: z.string().describe('The path that was checked'),
type: z.enum(FileType).optional().describe('The type if the path exists'),
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

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

Using z.enum with an object instead of an array of string literals. The z.enum() function expects an array of strings like z.enum(['FILE', 'DIR']), not an object type. This will cause a runtime error. Consider using z.nativeEnum() instead if FileType is a TypeScript enum, or define the allowed values as a string array.

Suggested change
type: z.enum(FileType).optional().describe('The type if the path exists'),
type: z.nativeEnum(FileType).optional().describe('The type if the path exists'),

Copilot uses AI. Check for mistakes.
size: z.number().describe('The size in bytes'),
humanReadableSize: z.string().optional().describe('Human-readable size string if requested'),
path: z.string().describe('The path that was checked'),
type: z.enum(FileType).optional().describe('Whether this is a file or directory'),
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

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

Using z.enum with an object instead of an array of string literals. The z.enum() function expects an array of strings like z.enum(['FILE', 'DIR']), not an object type. This will cause a runtime error. Consider using z.nativeEnum() instead if FileType is a TypeScript enum, or define the allowed values as a string array.

Suggested change
type: z.enum(FileType).optional().describe('Whether this is a file or directory'),
type: z.nativeEnum(FileType).optional().describe('Whether this is a file or directory'),

Copilot uses AI. Check for mistakes.
.array(
z.object({
type: z
.enum(FilesystemEventType)
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

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

Using z.enum with an object instead of an array of string literals. The z.enum() function expects an array of strings like z.enum(['WRITE', 'CREATE', 'DELETE']), not an object type. This will cause a runtime error. Consider using z.nativeEnum() instead if FilesystemEventType is a TypeScript enum, or define the allowed values as a string array.

Suggested change
.enum(FilesystemEventType)
.nativeEnum(FilesystemEventType)

Copilot uses AI. Check for mistakes.
Comment on lines +417 to +437
outputSchema: z
.object({
watchStarted: z.boolean().describe('Whether the watch was started successfully'),
path: z.string().describe('The path that was watched'),
events: z
.array(
z.object({
type: z
.enum(FilesystemEventType)
.describe('The type of filesystem event (WRITE, CREATE, DELETE, etc.)'),
name: z.string().describe('The name of the file that changed'),
timestamp: z.string().describe('When the event occurred'),
}),
)
.describe('Array of filesystem events that occurred during the watch period'),
})
.or(
z.object({
error: z.string().describe('The error from a failed directory watch'),
}),
),
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

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

The outputSchema uses .or() to define an error alternative, but the error field is never returned in the execute function. The outer catch block throws an error rather than returning an object with an error field, making this error schema unreachable. Either remove the error alternative from the schema or modify the error handling to return this format instead of throwing.

Suggested change
outputSchema: z
.object({
watchStarted: z.boolean().describe('Whether the watch was started successfully'),
path: z.string().describe('The path that was watched'),
events: z
.array(
z.object({
type: z
.enum(FilesystemEventType)
.describe('The type of filesystem event (WRITE, CREATE, DELETE, etc.)'),
name: z.string().describe('The name of the file that changed'),
timestamp: z.string().describe('When the event occurred'),
}),
)
.describe('Array of filesystem events that occurred during the watch period'),
})
.or(
z.object({
error: z.string().describe('The error from a failed directory watch'),
}),
),
outputSchema: z.object({
watchStarted: z.boolean().describe('Whether the watch was started successfully'),
path: z.string().describe('The path that was watched'),
events: z
.array(
z.object({
type: z
.enum(FilesystemEventType)
.describe('The type of filesystem event (WRITE, CREATE, DELETE, etc.)'),
name: z.string().describe('The name of the file that changed'),
timestamp: z.string().describe('When the event occurred'),
}),
)
.describe('Array of filesystem events that occurred during the watch period'),
}),

Copilot uses AI. Check for mistakes.
Comment on lines +217 to +220
outputSchema: z.object({
success: z.boolean().describe('Whether the file was deleted successfully'),
path: z.string().describe('The path that was deleted'),
}),
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

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

Inconsistent indentation detected in the outputSchema object. The object properties should align with the opening brace, similar to how inputSchema is formatted.

Copilot uses AI. Check for mistakes.
}),
outputSchema: z.object({
name: z.string().describe('The name of the file or directory'),
type: z.enum(FileType).optional().describe('Whether this is a file or directory'),
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

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

Using z.enum with an object instead of an array of string literals. The z.enum() function expects an array of strings like z.enum(['FILE', 'DIR']), not an object type. This will cause a runtime error. Consider using z.nativeEnum() instead if FileType is a TypeScript enum, or define the allowed values as a string array.

Suggested change
type: z.enum(FileType).optional().describe('Whether this is a file or directory'),
type: z.nativeEnum(FileType).optional().describe('Whether this is a file or directory'),

Copilot uses AI. Check for mistakes.
Comment on lines +361 to +372
outputSchema: z
.object({
size: z.number().describe('The size in bytes'),
humanReadableSize: z.string().optional().describe('Human-readable size string if requested'),
path: z.string().describe('The path that was checked'),
type: z.enum(FileType).optional().describe('Whether this is a file or directory'),
})
.or(
z.object({
error: z.string().describe('The error from a failed size check'),
}),
),
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

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

The outputSchema uses .or() to define an error alternative, but the error field is never returned in the execute function. The outer catch block throws an error rather than returning an object with an error field, making this error schema unreachable. Either remove the error alternative from the schema or modify the error handling to return this format instead of throwing.

Suggested change
outputSchema: z
.object({
size: z.number().describe('The size in bytes'),
humanReadableSize: z.string().optional().describe('Human-readable size string if requested'),
path: z.string().describe('The path that was checked'),
type: z.enum(FileType).optional().describe('Whether this is a file or directory'),
})
.or(
z.object({
error: z.string().describe('The error from a failed size check'),
}),
),
outputSchema: z.object({
size: z.number().describe('The size in bytes'),
humanReadableSize: z.string().optional().describe('Human-readable size string if requested'),
path: z.string().describe('The path that was checked'),
type: z.enum(FileType).optional().describe('Whether this is a file or directory'),
}),

Copilot uses AI. Check for mistakes.
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.

1 participant