Skip to content

feat: Runtime resolution of sandbox environment - #814

Open
thesujai wants to merge 3 commits into
feat/sandbox-environmentsfrom
feat/wire-sandbox-env
Open

thesujai wants to merge 3 commits into
feat/sandbox-environmentsfrom
feat/wire-sandbox-env

Conversation

@thesujai

@thesujai thesujai commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes AGE-2288

Changes

  • feat: Runtime resolution of sandbox environment

How was this tested?

Checklist

  • I have read the contributing guidelines
  • pnpm build, pnpm test, pnpm typecheck, pnpm lint:ci, and pnpm format:check pass locally
  • Tests added/updated where it makes sense
  • No hand-edits to generated code (packages/trueforge-sdk, python/trueforge_sdk, .github/fern/openapi/openapi.json, docs/openapi.json) — fork PRs omit SDK regen; maintainers regenerate after merge
  • Docs / .env.example updated if configuration or behavior changed

Note

Medium Risk
Changes agent turn sandbox provisioning (network rules, secrets, GPU/images) and session VM reuse rules; misconfiguration could affect isolation or availability but paths are validated and caller-scoped.

Overview
Adds caller-owned sandbox environments with paginated CRUD under /api/v1/sandbox-environments, Daytona manifests (image, resources/GPU, lifecycle, networking, secrets), tenant CREATE permission for sandbox-environment, and generated SDK/OpenAPI types.

Agents can pin a sandbox via config.sandbox.environment. At turn time the server validates ownership and provider match, maps the manifest into Daytona create overrides (snapshot vs docker image, network policy, org secrets, lifecycle), and passes createOptions only on fresh creates. SandboxInfo.environment and sandbox.created events record which environment was used.

Reattach now requires the same environment name as the prior turn (via existingSandboxIdForProvider); changing or clearing environment forces a new VM. Turn resolution passes full SandboxInfo into the sandbox factory instead of only sandbox_id.

Reviewed by Cursor Bugbot for commit 0390cfa. Bugbot is set up for automated code reviews on this repo. Configure here.

@changeset-bot

changeset-bot Bot commented Sep 18, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 0390cfa

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes changesets to release 2 packages
Name Type
@truefoundry/trueforge Minor
@truefoundry/trueforge-core Minor

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.


return {
...image,
...(manifest.resources ? { resources: mapResources(manifest.resources) } : {}),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Snapshot creates reject valid resources

Medium Severity

mapDaytonaEnvironmentToCreateParams always forwards resources for every image kind, including trueforge-default and named snapshots. createNewSandbox then throws a generic Error when resources are present without a docker image, so a schema-valid environment fails at turn time with a 500 instead of creating the sandbox or returning a 422.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 41e921f. Configure here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 0390cfa. Configure here.

}

const resources = createParams?.resources;
const wantsGpu = !!resources?.gpu || !!resources?.gpuType;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

GPU detection mismatch between schema and runtime

Low Severity

The GPU detection logic differs between schema validation and runtime. The schema uses value.resources?.gpu != null (treats gpu: 0 as wanting GPU), while the runtime uses !!resources?.gpu (treats gpu: 0 as NOT wanting GPU). When gpu: 0 is explicitly set without gpu_type, the schema validation enforces ephemeral constraints (auto_delete_interval_in_minutes must be 0) but the runtime does not force autoDeleteInterval: 0. This inconsistency means the two layers disagree on what constitutes a GPU request.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 0390cfa. Configure here.

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