Skip to content

Fix SDK Explorer sandbox execution hangs - #1559

Merged
parteeksingh24 merged 2 commits into
mainfrom
fix/explorer-handler-context-executing
Jun 12, 2026
Merged

parteeksingh24 merged 2 commits into
mainfrom
fix/explorer-handler-context-executing

Conversation

@parteeksingh24

@parteeksingh24 parteeksingh24 commented Jun 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fixes SDK Explorer sandbox runs that could stay on Executing... even after the route sent a command.

  • Keeps the public execute({ files }) API, but stages files before calling /execute
  • Lets sandboxRun() return failed terminal states without waiting for output streams that stay open
  • Limits the Explorer object-storage demo to reusable child-sandbox storage env
  • Adds route and SDK client regressions for the file staging, env filtering, and failed-stream paths

Why

The Explorer route was using the same high-level shape everywhere: send a bundled script file, then run it inside a sandbox. That is the right API for callers, but the live execute path can hang when files are sent inside the execute request.

The safer flow is two steps:

  1. write the files into the sandbox workspace
  2. execute the command that reads those files

The object-storage demo had a second boundary issue. Some deployment-provided storage values are scoped to the parent runtime. A child sandbox needs reusable storage env, so the route now forwards only the compatible S3-shaped values for that demo.

Implementation

The public caller shape stays the same:

await sandbox.execute({
  command: ['bun', 'run', 'dist/run/hello.js'],
  files,
});

Under the hood, sandboxExecute() now stages files before it sends the execute request:

if (options.files && options.files.length > 0) {
  await sandboxWriteFiles(client, {
    sandboxId,
    files: options.files,
    orgId,
    signal: signal ?? options.signal,
  });
}

The execute request then carries the command, timeout, and stream options. It does not send file payloads inline.

sandboxRun() also checks the terminal execution status before waiting for output streams to drain:

const execution = await completionPromise;
finalExecution = execution;
if (execution.status !== 'completed') {
  abortController.abort();
}
await streamsPromise;

That lets failed creates and failed executions return promptly instead of waiting on streams that may remain open until the client deadline.

For SDK Explorer object storage, the route copies storage env only for the object-storage script:

if (scriptName === 'objectstore') {
  copyObjectStorageEnv(envVars);
}

The helper prefers reusable S3_* values and skips parent-scoped credential values that cannot be reused inside a child sandbox.

Verification

  • git diff --cached --check
  • bun test src/api/test/sandbox-route.test.ts
  • bun test test/sandbox-client.test.ts
  • bunx biome check docs/src/api/sandbox/route.ts docs/src/api/test/sandbox-route.test.ts packages/core/src/services/sandbox/execute.ts packages/core/src/services/sandbox/run.ts packages/server/test/sandbox-client.test.ts
  • cd docs && bun run typecheck
  • cd packages/core && bun run typecheck
  • cd packages/server && bun run typecheck
  • cd packages/core && bun run build
  • cd packages/server && bun run build
  • cd docs && bun run build:run
  • Local agentuity dev SDK Explorer sweep: all 18 sandbox route scripts emitted terminal done

Summary by CodeRabbit

  • Bug Fixes

    • Improved sandbox execution reliability with better error handling to catch execution failures before stream processing.
    • Enhanced storage credential management and isolation in sandbox environments.
  • Tests

    • Added comprehensive test coverage for sandbox execution flows and proper credential forwarding behavior.

- Write `execute({ files })` inputs before `/execute`
- Stop failed `run()` calls from waiting on output streams
- Filter non-reusable storage env in Explorer demos
@agentuity-agent

agentuity-agent Bot commented Jun 12, 2026 •

Copy link
Copy Markdown

The latest Agentuity deployment details.

Project Deployment Preview Updated (UTC)
docs 🟢 Ready (deploy_fd15e58f293bd07f238118d6caadc60f) - 2026-06-12T22:56:44Z

@coderabbitai

coderabbitai Bot commented Jun 12, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@parteeksingh24, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 48 minutes and 9 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more credits in the billing tab to continue.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8b535c4b-8e8a-452f-b62d-0040e4d74ce9

📥 Commits

Reviewing files that changed from the base of the PR and between ce775d0 and 5daa8b3.

📒 Files selected for processing (3)
  • packages/core/src/services/sandbox/execute.ts
  • packages/core/src/services/sandbox/run.ts
  • packages/server/test/sandbox-client.test.ts
📝 Walkthrough

Walkthrough

This PR refines sandbox execution to handle credentials more carefully, stages files via a dedicated endpoint before execution, and fixes control flow to prevent hung output streams from masking execution failures. The changes span sandbox route handlers, core execution services, and corresponding test suites.

Changes

Sandbox Credential and Execution Flow Improvements

Layer / File(s) Summary
Object storage credential handling in route
docs/src/api/sandbox/route.ts
Helper functions select reusable S3 environment variables (filtering ags- prefixed values) and inject object-storage credentials into sandbox execution only when all required fields are present.
Sandbox route test infrastructure and app wiring
docs/src/api/test/sandbox-route.test.ts
Test harness with mocked sandbox lifecycle functions, dynamic script generation, and app factory that conditionally wires KV/thread state for interactive mode.
Sandbox route tests for execution flows and credential forwarding
docs/src/api/test/sandbox-route.test.ts
Tests verify one-shot and interactive execution paths return expected streamed events, correct sandbox lifecycle call counts, and that object-storage scripts receive only reusable S3_* credentials with preference over hashed AWS aliases.
File staging refactored to separate step before execution
packages/core/src/services/sandbox/execute.ts, packages/server/test/sandbox-client.test.ts
Sandbox execution no longer embeds base64-encoded files in request body; instead sandboxWriteFiles stages files via a dedicated endpoint before submitting the execute request.
Execution completion resolved before stream draining
packages/core/src/services/sandbox/run.ts, packages/server/test/sandbox-client.test.ts
Sandbox run now awaits execution completion first, then aborts if execution failed, then awaits output stream draining; this prevents hung stdout/stderr streams from masking execution failures.
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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


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

github-actions Bot commented Jun 12, 2026 •

Copy link
Copy Markdown

📦 Canary Packages Published

version: 3.0.8-5daa8b3

Packages
Package Version URL
@agentuity/webhook 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-webhook-3.0.8-5daa8b3.tgz
@agentuity/schema 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-schema-3.0.8-5daa8b3.tgz
@agentuity/adapter 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-adapter-3.0.8-5daa8b3.tgz
@agentuity/schedule 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-schedule-3.0.8-5daa8b3.tgz
@agentuity/core 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-core-3.0.8-5daa8b3.tgz
@agentuity/server 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-server-3.0.8-5daa8b3.tgz
@agentuity/vite 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-vite-3.0.8-5daa8b3.tgz
@agentuity/keyvalue 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-keyvalue-3.0.8-5daa8b3.tgz
@agentuity/queue 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-queue-3.0.8-5daa8b3.tgz
@agentuity/analytics 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-analytics-3.0.8-5daa8b3.tgz
@agentuity/local 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-local-3.0.8-5daa8b3.tgz
@agentuity/cli 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-cli-3.0.8-5daa8b3.tgz
@agentuity/postgres 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-postgres-3.0.8-5daa8b3.tgz
@agentuity/db 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-db-3.0.8-5daa8b3.tgz
@agentuity/coder-tui 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-coder-tui-3.0.8-5daa8b3.tgz
@agentuity/opencode 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-opencode-3.0.8-5daa8b3.tgz
@agentuity/aigateway 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-aigateway-3.0.8-5daa8b3.tgz
@agentuity/email 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-email-3.0.8-5daa8b3.tgz
@agentuity/sandbox 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-sandbox-3.0.8-5daa8b3.tgz
@agentuity/hono 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-hono-3.0.8-5daa8b3.tgz
@agentuity/runtime 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-runtime-3.0.8-5daa8b3.tgz
@agentuity/task 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-task-3.0.8-5daa8b3.tgz
@agentuity/storage 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-storage-3.0.8-5daa8b3.tgz
@agentuity/stream 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-stream-3.0.8-5daa8b3.tgz
@agentuity/drizzle 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-drizzle-3.0.8-5daa8b3.tgz
@agentuity/claude-code 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-claude-code-3.0.8-5daa8b3.tgz
@agentuity/pi 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-pi-3.0.8-5daa8b3.tgz
@agentuity/telemetry 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-telemetry-3.0.8-5daa8b3.tgz
@agentuity/migrate 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-migrate-3.0.8-5daa8b3.tgz
create-agentuity 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/create-agentuity-3.0.8-5daa8b3.tgz
@agentuity/coder 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-coder-3.0.8-5daa8b3.tgz
@agentuity/vector 3.0.8-5daa8b3 https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-vector-3.0.8-5daa8b3.tgz
Install

Add to your package.json:

{
  "dependencies": {
    "@agentuity/webhook": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-webhook-3.0.8-5daa8b3.tgz",
    "@agentuity/schema": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-schema-3.0.8-5daa8b3.tgz",
    "@agentuity/adapter": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-adapter-3.0.8-5daa8b3.tgz",
    "@agentuity/schedule": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-schedule-3.0.8-5daa8b3.tgz",
    "@agentuity/core": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-core-3.0.8-5daa8b3.tgz",
    "@agentuity/server": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-server-3.0.8-5daa8b3.tgz",
    "@agentuity/vite": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-vite-3.0.8-5daa8b3.tgz",
    "@agentuity/keyvalue": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-keyvalue-3.0.8-5daa8b3.tgz",
    "@agentuity/queue": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-queue-3.0.8-5daa8b3.tgz",
    "@agentuity/analytics": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-analytics-3.0.8-5daa8b3.tgz",
    "@agentuity/local": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-local-3.0.8-5daa8b3.tgz",
    "@agentuity/cli": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-cli-3.0.8-5daa8b3.tgz",
    "@agentuity/postgres": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-postgres-3.0.8-5daa8b3.tgz",
    "@agentuity/db": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-db-3.0.8-5daa8b3.tgz",
    "@agentuity/coder-tui": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-coder-tui-3.0.8-5daa8b3.tgz",
    "@agentuity/opencode": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-opencode-3.0.8-5daa8b3.tgz",
    "@agentuity/aigateway": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-aigateway-3.0.8-5daa8b3.tgz",
    "@agentuity/email": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-email-3.0.8-5daa8b3.tgz",
    "@agentuity/sandbox": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-sandbox-3.0.8-5daa8b3.tgz",
    "@agentuity/hono": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-hono-3.0.8-5daa8b3.tgz",
    "@agentuity/runtime": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-runtime-3.0.8-5daa8b3.tgz",
    "@agentuity/task": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-task-3.0.8-5daa8b3.tgz",
    "@agentuity/storage": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-storage-3.0.8-5daa8b3.tgz",
    "@agentuity/stream": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-stream-3.0.8-5daa8b3.tgz",
    "@agentuity/drizzle": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-drizzle-3.0.8-5daa8b3.tgz",
    "@agentuity/claude-code": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-claude-code-3.0.8-5daa8b3.tgz",
    "@agentuity/pi": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-pi-3.0.8-5daa8b3.tgz",
    "@agentuity/telemetry": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-telemetry-3.0.8-5daa8b3.tgz",
    "@agentuity/migrate": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-migrate-3.0.8-5daa8b3.tgz",
    "create-agentuity": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/create-agentuity-3.0.8-5daa8b3.tgz",
    "@agentuity/coder": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-coder-3.0.8-5daa8b3.tgz",
    "@agentuity/vector": "https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-vector-3.0.8-5daa8b3.tgz"
  }
}

Or install directly:

bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-webhook-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-schema-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-adapter-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-schedule-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-core-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-server-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-vite-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-keyvalue-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-queue-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-analytics-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-local-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-cli-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-postgres-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-db-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-coder-tui-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-opencode-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-aigateway-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-email-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-sandbox-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-hono-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-runtime-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-task-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-storage-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-stream-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-drizzle-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-claude-code-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-pi-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-telemetry-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-migrate-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/create-agentuity-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-coder-3.0.8-5daa8b3.tgz
bun add https://agentuity-sdk-objects.t3.storageapi.dev/npm/3.0.8-5daa8b3/agentuity-vector-3.0.8-5daa8b3.tgz

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

Caution

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

⚠️ Outside diff range comments (1)
packages/server/test/sandbox-client.test.ts (1)

261-338: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Assert the /fs → /execute call order explicitly.

This regression currently proves that both requests happen and that /execute omits files, but it does not prove that file staging happens first. A reversed implementation would still satisfy these assertions and reintroduce the race this test is meant to catch.

💡 Tighten the regression
 test('execute with files should stage files before executing command', async () => {
+	const calls: string[] = [];
 	let executeRequestBody: Record<string, unknown> | null = null;
 	let writeFilesRequestBody: Record<string, unknown> | null = null;

 	mockFetch(async (url, opts) => {
 		if (opts?.method === 'POST' && url.includes('/fs/sandbox-123')) {
+			calls.push('fs');
 			writeFilesRequestBody = JSON.parse(opts.body as string);
 			return new Response(
 				JSON.stringify({
 					success: true,
 					data: { filesWritten: 2 },
@@
 		if (opts?.method === 'POST' && url.includes('/execute')) {
+			calls.push('execute');
 			executeRequestBody = JSON.parse(opts.body as string);
 			return new Response(
 				JSON.stringify({
 					success: true,
@@
 	expect(writeFilesRequestBody!.files).toEqual([
 		{ path: 'script.ts', content: Buffer.from('console.log("hello")').toString('base64') },
 		{ path: 'data.json', content: Buffer.from('{"key": "value"}').toString('base64') },
 	]);
 	expect(executeRequestBody).not.toBeNull();
 	expect(executeRequestBody!.command).toEqual(['bun', 'run', 'script.ts']);
 	expect(executeRequestBody!.files).toBeUndefined();
+	expect(calls).toEqual(['fs', 'execute']);
 });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/server/test/sandbox-client.test.ts` around lines 261 - 338, The test
currently only checks that both the /fs write and /execute requests occurred and
that execute omitted files, but doesn't assert their order; update the mockFetch
handlers in the test (the POST handler for URLs containing '/fs/sandbox-123' and
the POST handler for URLs containing '/execute') to push markers into a local
sequence array (e.g., push 'write' in the fs handler and 'execute' in the
execute handler) when each handler runs, then after calling
SandboxClient.create() and sandbox.execute(...) assert that the sequence array
equals ['write','execute'] to guarantee files are staged before execution; keep
existing checks for writeFilesRequestBody and executeRequestBody.
🧹 Nitpick comments (1)
docs/src/api/test/sandbox-route.test.ts (1)

10-11: 📐 Maintainability & Code Quality | 💤 Low value

Consider using process.env consistently for portability.

While Bun.env is valid and works in Bun runtime, using process.env throughout the test file (as done in setStorageEnv on lines 131-138) would improve consistency and make the code more portable across different runtimes.

♻️ Optional refactor for consistency
-Bun.env.SANDBOX_SNAPSHOT_ID = 'snapshot_test';
-Bun.env.AGENTUITY_SDK_KEY = 'sdk_test';
+process.env.SANDBOX_SNAPSHOT_ID = 'snapshot_test';
+process.env.AGENTUITY_SDK_KEY = 'sdk_test';
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/src/api/test/sandbox-route.test.ts` around lines 10 - 11, The test uses
Bun.env.SANDBOX_SNAPSHOT_ID and Bun.env.AGENTUITY_SDK_KEY while other helpers
(setStorageEnv) use process.env; change the two assignments to
process.env.SANDBOX_SNAPSHOT_ID = 'snapshot_test' and
process.env.AGENTUITY_SDK_KEY = 'sdk_test' to keep environment access consistent
and portable, leaving the same keys/values and any existing tear-down or restore
behavior intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core/src/services/sandbox/execute.ts`:
- Around line 88-94: The current execute flow calls sandboxWriteFiles (in
execute.ts) before attempting the execute request, causing the workspace to be
mutated even if the subsequent execute fails; either defer file staging into the
same request (create an atomic executeWithFiles server endpoint that accepts
files + execute in one call) or add a reliable rollback path: after calling
sandboxWriteFiles(sandboxId, files, orgId, signal) invoke the execute RPC and if
it returns non-2xx, 409/404, is cancelled, or errors on transport, call a
cleanup API (e.g., sandboxDeleteFiles or sandboxCleanupFiles) with the same
sandboxId/files (and propagate the original error) and ensure the same
signal/timeout is used so partial staging is cleaned up; update execute.ts to
use the new atomic endpoint or implement the try -> finally rollback logic
around sandboxWriteFiles and reference sandboxWriteFiles, sandboxId,
options.files, and the execute RPC call.

In `@packages/core/src/services/sandbox/run.ts`:
- Around line 255-264: The race between executionGet and sandboxGetStatus in
waitForRunCompletion leaves the losing long-poll alive; after completionPromise
(the Promise.race) resolves in sandboxRun(), explicitly abort the still-pending
waiter so its underlying request is cancelled. Modify waitForRunCompletion()/the
callers to use separate AbortController(s) for each branch (or return a cancel
function) and, once completionPromise settles (the variable finalExecution is
set), call abort() on the controller for the branch that lost the race; ensure
abortController used for streamsPromise is not confused with the per-waiter
controllers so streamsPromise behavior remains unchanged.

---

Outside diff comments:
In `@packages/server/test/sandbox-client.test.ts`:
- Around line 261-338: The test currently only checks that both the /fs write
and /execute requests occurred and that execute omitted files, but doesn't
assert their order; update the mockFetch handlers in the test (the POST handler
for URLs containing '/fs/sandbox-123' and the POST handler for URLs containing
'/execute') to push markers into a local sequence array (e.g., push 'write' in
the fs handler and 'execute' in the execute handler) when each handler runs,
then after calling SandboxClient.create() and sandbox.execute(...) assert that
the sequence array equals ['write','execute'] to guarantee files are staged
before execution; keep existing checks for writeFilesRequestBody and
executeRequestBody.

---

Nitpick comments:
In `@docs/src/api/test/sandbox-route.test.ts`:
- Around line 10-11: The test uses Bun.env.SANDBOX_SNAPSHOT_ID and
Bun.env.AGENTUITY_SDK_KEY while other helpers (setStorageEnv) use process.env;
change the two assignments to process.env.SANDBOX_SNAPSHOT_ID = 'snapshot_test'
and process.env.AGENTUITY_SDK_KEY = 'sdk_test' to keep environment access
consistent and portable, leaving the same keys/values and any existing tear-down
or restore behavior intact.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: da411d9a-2382-4cf7-8510-c3c9df89c362

📥 Commits

Reviewing files that changed from the base of the PR and between 4b10cb9 and ce775d0.

📒 Files selected for processing (5)
  • docs/src/api/sandbox/route.ts
  • docs/src/api/test/sandbox-route.test.ts
  • packages/core/src/services/sandbox/execute.ts
  • packages/core/src/services/sandbox/run.ts
  • packages/server/test/sandbox-client.test.ts
📜 Review details
⏰ 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). (12)
  • GitHub Check: Migrate Chain (v1 → v2 → v3)
  • GitHub Check: Queue CLI Tests (bun)
  • GitHub Check: Queue CLI Tests (node)
  • GitHub Check: Package Installation & Usage Test (node)
  • GitHub Check: Postgres SSL Integration Test
  • GitHub Check: Framework Demo Tests
  • GitHub Check: Package Installation & Usage Test (bun)
  • GitHub Check: Service Client Smoke Tests
  • GitHub Check: Windows WSL CLI Smoke Test
  • GitHub Check: Pack & Upload
  • GitHub Check: Build
  • GitHub Check: Agentuity Deployment
🧰 Additional context used
📓 Path-based instructions (5)
packages/core/src/**/*.ts

📄 CodeRabbit inference engine (packages/core/AGENTS.md)

packages/core/src/**/*.ts: Build TypeScript code using bun run build which compiles with tsc
Run TypeScript type checking with bun run typecheck
Ensure runtime compatibility with both Browser and Node/Bun environments - no runtime-specific code
Use ESNext as build target with TypeScript declaration files
Use TypeScript-first development - all code must be TypeScript
Prefer interfaces for public APIs
Use generics for reusable type utilities
Ensure no framework coupling - code must work in any JavaScript environment
Many exports are type or interface only - use type keyword for type-only exports
Ensure all exports are pure with no side effects or global mutations
All relative imports in TypeScript files MUST include the .ts extension for proper ESM module resolution

Files:

  • packages/core/src/services/sandbox/execute.ts
  • packages/core/src/services/sandbox/run.ts
packages/core/src/services/**/*.ts

📄 CodeRabbit inference engine (packages/core/AGENTS.md)

packages/core/src/services/**/*.ts: Follow StandardSchemaV1 spec for validation interfaces
Storage services must take a FetchAdapter for HTTP abstraction

Files:

  • packages/core/src/services/sandbox/execute.ts
  • packages/core/src/services/sandbox/run.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Run bun run format using Biome with tabs (width 3), single quotes, semicolons, lineWidth 100, and trailingCommas es5

Files:

  • packages/core/src/services/sandbox/execute.ts
  • packages/core/src/services/sandbox/run.ts
  • packages/server/test/sandbox-client.test.ts
  • docs/src/api/sandbox/route.ts
  • docs/src/api/test/sandbox-route.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use TypeScript in strict mode with ESNext target and bundler moduleResolution
Use StructuredError from @agentuity/core for error handling

Files:

  • packages/core/src/services/sandbox/execute.ts
  • packages/core/src/services/sandbox/run.ts
  • packages/server/test/sandbox-client.test.ts
  • docs/src/api/sandbox/route.ts
  • docs/src/api/test/sandbox-route.test.ts
**/packages/*/test/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/packages/*/test/**/*.{ts,tsx}: Place tests in test/ folder parallel to src/ directory, never inside src/ or under __tests__/
Import from ../src/ in test files
Use @agentuity/test-utils for shared mocks in tests

Files:

  • packages/server/test/sandbox-client.test.ts
🧠 Learnings (5)
📚 Learning: 2025-12-21T00:31:41.858Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 274
File: packages/cli/src/cmd/build/vite/server-bundler.ts:12-41
Timestamp: 2025-12-21T00:31:41.858Z
Learning: In Bun runtime, BuildMessage and ResolveMessage are global types and are not exported from the bun module. Do not import { BuildMessage } from 'bun' or similar; these types are available globally and should be used without import. This applies to all TypeScript files that target the Bun runtime within the repository.

Applied to files:

  • packages/core/src/services/sandbox/execute.ts
  • packages/core/src/services/sandbox/run.ts
  • packages/server/test/sandbox-client.test.ts
  • docs/src/api/sandbox/route.ts
  • docs/src/api/test/sandbox-route.test.ts
📚 Learning: 2025-12-30T00:13:37.849Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 355
File: packages/server/src/api/sandbox/util.ts:2-6
Timestamp: 2025-12-30T00:13:37.849Z
Learning: In the packages/server tree, treat code as runtime-agnostic between Node.js and Bun. Ensure TypeScript files (e.g., util.ts) import and use APIs in a way that works under both runtimes. It is acceptable to rely on Bun’s Node.js compatibility for built-ins accessed via the node: namespace (e.g., node:events, node:stream, node:buffer). During reviews, prefer patterns and imports that remain compatible with Bun's environment, and flag any hard dependencies on runtime-specific globals or non-portable Node APIs.

Applied to files:

  • packages/server/test/sandbox-client.test.ts
📚 Learning: 2026-02-21T02:05:57.982Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 1010
File: packages/drizzle/test/proxy.test.ts:594-603
Timestamp: 2026-02-21T02:05:57.982Z
Learning: Do not rely on StructuredError from agentuity/core in test files or simple error handling paths. In tests and straightforward error handling, use plain Error objects to represent failures, reserving StructuredError for more complex error scenarios in application logic.

Applied to files:

  • packages/server/test/sandbox-client.test.ts
  • docs/src/api/test/sandbox-route.test.ts
📚 Learning: 2025-12-19T14:19:33.765Z
Learnt from: jhaynie
Repo: agentuity/sdk PR: 259
File: packages/cli/src/cmd/build/vite/registry-generator.ts:306-312
Timestamp: 2025-12-19T14:19:33.765Z
Learning: Route files under src/api should use the .ts extension only (no .tsx) and regex patterns for such paths should anchor to \.ts$ (e.g., /\/.ts$/). Agent files may support both .ts and .tsx, but route files in the Agentuity SDK codebase are restricted to .ts. This guideline applies to all similar route files under src/api across the repository.

Applied to files:

  • docs/src/api/sandbox/route.ts
  • docs/src/api/test/sandbox-route.test.ts
📚 Learning: 2026-02-25T22:13:01.823Z
Learnt from: Huijiro
Repo: agentuity/sdk PR: 1063
File: apps/testing/vite-rsc-app/agentuity/src/api/index.ts:26-26
Timestamp: 2026-02-25T22:13:01.823Z
Learning: Agentuity SDK requires default exports for API route files (e.g., src/api/**/index.ts and src/api/**/route.ts) because the CLI's generateRouteRegistry relies on default exports to discover routes. Using named exports will skip route generation and lead to runtime 500 errors. This overrides typical guidance about named exports in index.ts files; ensure a default export is present in all relevant API route files under src/api/**/.

Applied to files:

  • docs/src/api/sandbox/route.ts
🔇 Additional comments (5)
docs/src/api/sandbox/route.ts (3)

85-126: LGTM!


288-293: LGTM!


13-13: 📐 Maintainability & Code Quality

Relative imports in docs/src/api don’t use .ts extensions
docs/src/api/** (including docs/src/api/sandbox/route.ts) consistently uses extensionless relative imports like import { sse } from '../http';, and there are no relative imports with .ts extensions in docs/src/api. The .ts-extension convention appears to be specific to packages/core/src/**, not the docs layer.

docs/src/api/test/sandbox-route.test.ts (2)

106-192: LGTM!


208-338: LGTM!

Comment thread packages/core/src/services/sandbox/execute.ts
Comment thread packages/core/src/services/sandbox/run.ts
- Roll back staged execute files when `/execute` is rejected
- Abort the losing `run()` completion waiter after a race win
- Cover both paths in sandbox client tests
@parteeksingh24
parteeksingh24 merged commit 5764795 into main Jun 12, 2026
28 of 29 checks passed
@parteeksingh24
parteeksingh24 deleted the fix/explorer-handler-context-executing branch June 12, 2026 23:52
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