feat: Added leap0 as sandbox#1
Conversation
📝 WalkthroughWalkthroughAdds Leap0 as a third sandbox provider: new env var, README updates, an npm dependency, provider selection wiring, and a Leap0 implementation module with sandbox, filesystem, and execution tools. Changes
Sequence DiagramsequenceDiagram
participant Caller as Caller (tools index)
participant Selector as Provider Selector
participant Client as Leap0 Client
participant Sandbox as Leap0 Sandbox
participant FS as Filesystem / Process
Caller->>Selector: request tool (createSandbox / runCode / fs ops)
Selector->>Selector: check envs (DAYTONA, E2B, LEAP0)
Selector-->>Caller: provider = leap0
Caller->>Client: getLeap0Client()
Client-->>Caller: Leap0Client (cached)
Caller->>Sandbox: createSandbox(envs, timeout)
Sandbox->>FS: initialize workspace
FS-->>Sandbox: ready
Sandbox-->>Caller: { sandboxId }
Caller->>Sandbox: runCode(sandboxId, code, opts)
alt language == js
Sandbox->>FS: write temp .js file
FS->>FS: spawn node process (timeout mapped)
else language == ts/python
Sandbox->>Client: codeInterpreter.execute(language, opts)
end
FS-->>Sandbox: execution result
Sandbox-->>Caller: execution output / contextId
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.env.example:
- Around line 8-9: The .env.example sets MODEL=groq/llama-3.3-70b-versatile
which conflicts with the README/setup that only instructs users to add
OPENAI_API_KEY; update .env.example so its default MODEL matches the documented
setup (e.g., revert MODEL to openai/gpt-4o-mini) or add a note and the required
GROQ_API_KEY variable; specifically change the MODEL entry and, if keeping the
Groq default, add GROQ_API_KEY and an explanatory comment near MODEL to keep
credentials and docs in sync.
In `@README.md`:
- Line 99: Edit the provider overview sentence to explicitly call out that Leap0
does not support live directory monitoring: update the README line that
currently says "Automatically uses Daytona, E2B, or Leap0 based on which API key
you set" to note that Leap0 lacks watchDirectory/live directory monitoring;
reference the implementation in src/mastra/tools/leap0/tools.ts and its
watchDirectory function which returns a fixed unsupported error, and add a short
caveat like "Note: Leap0 does not support live directory monitoring
(watchDirectory) at this time." Ensure the wording is concise and visible in the
provider overview.
In `@src/mastra/tools/leap0/tools.ts`:
- Around line 147-159: The sandbox.codeInterpreter.execute call in this tool
auto-creates a persistent interpreter context (execution.context_id) when none
is supplied, leaking sessions; either modify the tool's input schema to accept a
contextId and pass it into sandbox.codeInterpreter.execute so callers can
control lifecycle (and return the contextId in the response), or immediately
clean up after execution by calling
sandbox.codeInterpreter.delete_context(execution.context_id) before returning;
update the code path around sandbox.codeInterpreter.execute and the returned
object (serializeCodeResult) to include or account for the context_id as
appropriate.
In `@src/mastra/tools/leap0/utils.ts`:
- Around line 20-35: normalizeSandboxPath currently concatenates strings and can
return workspace-prefixed paths that still contain "."/".." segments (e.g.,
"/workspace/../etc"), causing filesystem calls to target outside the workspace;
change it to canonicalize with Node's path utilities: compute a resolved
absolute path using path.resolve(WORKSPACE_ROOT, trimmed) for relative inputs
(and path.resolve(trimmed) for absolute inputs), then normalize, and enforce
confinement by rejecting/throwing if the resolved path is outside WORKSPACE_ROOT
(check resolved === WORKSPACE_ROOT or resolved.startsWith(WORKSPACE_ROOT +
path.sep)); ensure all return values are the canonical resolved path without any
"."/".." segments and keep references to normalizeSandboxPath and WORKSPACE_ROOT
when locating the fix.
🪄 Autofix (Beta)
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
Run ID: e3b5873f-2985-4bc7-ae13-7d5327cb94f0
📒 Files selected for processing (6)
.env.exampleREADME.mdpackage.jsonsrc/mastra/tools/index.tssrc/mastra/tools/leap0/tools.tssrc/mastra/tools/leap0/utils.ts
1e8934a to
59523c6
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (3)
src/mastra/tools/leap0/tools.ts (2)
578-599: Zod defaults make null-coalescing redundant.The input schema defines
.default(30000)fortimeoutMsand.default(true)forcaptureOutput, so Zod provides these values beforeexecuteruns. The??operators on lines 582 and 591 are unnecessary.♻️ Suggested simplification
- const timeoutSeconds = timeoutMsToSeconds(timeoutMs ?? 30000); + const timeoutSeconds = timeoutMsToSeconds(timeoutMs); const cwd = workingDirectory ? normalizeSandboxPath(workingDirectory) : undefined; ... const executionTime = Date.now() - startTime; - const capture = captureOutput ?? true; return { success: result.exitCode === 0, exitCode: result.exitCode, - stdout: capture ? result.stdout : '', - stderr: capture ? result.stderr : '', + stdout: captureOutput ? result.stdout : '', + stderr: captureOutput ? result.stderr : '',🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/mastra/tools/leap0/tools.ts` around lines 578 - 599, The execute handler applies redundant null-coalescing because the input Zod schema already supplies defaults for timeoutMs and captureOutput; remove the unnecessary "??" uses so timeoutMs is passed directly into timeoutMsToSeconds and captureOutput is used directly when building the return (i.e., drop "timeoutMs ?? 30000" and "captureOutput ?? true" and simplify the local variable "capture" to use captureOutput directly); update references in execute (function name execute, timeoutMsToSeconds call, captureOutput usage, and the result construction that sets stdout/stderr) accordingly.
39-48: Guard against negative byte values.
Math.log(bytes)returnsNaNfor negative inputs, which would propagate through the calculation. While unlikely from valid filesystem stats, a defensive check prevents unexpected output.🛡️ Suggested fix
function formatBytes(bytes: number): string { const sizes = ['B', 'KB', 'MB', 'GB', 'TB']; - if (bytes === 0) { + if (bytes <= 0) { return '0 B'; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/mastra/tools/leap0/tools.ts` around lines 39 - 48, The formatBytes function can produce NaN for negative inputs because Math.log(bytes) is invalid; add a defensive guard at the top of formatBytes (before computing rawIndex) to handle non-positive or non-finite inputs—e.g., if bytes <= 0 || !isFinite(bytes) return '0 B'—so the subsequent use of rawIndex, i and sizes remains safe and predictable..env.example (1)
19-19: Consider alphabetical ordering for API keys.The static analysis tool suggests placing
LEAP0_API_KEYbeforeMISTRAL_API_KEYto maintain alphabetical order among the API key entries. This is a minor consistency improvement.♻️ Suggested reordering
GROQ_API_KEY= CEREBRAS_API_KEY= +LEAP0_API_KEY= MISTRAL_API_KEY= DAYTONA_API_KEY= E2B_API_KEY= -LEAP0_API_KEY=🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.env.example at line 19, Reorder the API key entries in .env.example to be alphabetically consistent by moving the LEAP0_API_KEY line so it appears before MISTRAL_API_KEY; update the file by locating the LEAP0_API_KEY and MISTRAL_API_KEY entries and swapping their positions to ensure alphabetical ordering of API key environment variables.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In @.env.example:
- Line 19: Reorder the API key entries in .env.example to be alphabetically
consistent by moving the LEAP0_API_KEY line so it appears before
MISTRAL_API_KEY; update the file by locating the LEAP0_API_KEY and
MISTRAL_API_KEY entries and swapping their positions to ensure alphabetical
ordering of API key environment variables.
In `@src/mastra/tools/leap0/tools.ts`:
- Around line 578-599: The execute handler applies redundant null-coalescing
because the input Zod schema already supplies defaults for timeoutMs and
captureOutput; remove the unnecessary "??" uses so timeoutMs is passed directly
into timeoutMsToSeconds and captureOutput is used directly when building the
return (i.e., drop "timeoutMs ?? 30000" and "captureOutput ?? true" and simplify
the local variable "capture" to use captureOutput directly); update references
in execute (function name execute, timeoutMsToSeconds call, captureOutput usage,
and the result construction that sets stdout/stderr) accordingly.
- Around line 39-48: The formatBytes function can produce NaN for negative
inputs because Math.log(bytes) is invalid; add a defensive guard at the top of
formatBytes (before computing rawIndex) to handle non-positive or non-finite
inputs—e.g., if bytes <= 0 || !isFinite(bytes) return '0 B'—so the subsequent
use of rawIndex, i and sizes remains safe and predictable.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3b52fc1d-41f9-46db-bfe2-d94715fe8150
📒 Files selected for processing (6)
.env.exampleREADME.mdpackage.jsonsrc/mastra/tools/index.tssrc/mastra/tools/leap0/tools.tssrc/mastra/tools/leap0/utils.ts
✅ Files skipped from review due to trivial changes (2)
- package.json
- src/mastra/tools/index.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- README.md
- src/mastra/tools/leap0/utils.ts
Added leap0 as sandbox
Summary by CodeRabbit
New Features
Chores