Skip to content

chore(js): remove templates, pools, and volumes from sandbox SDK#2758

Merged
Daniel Kneipp (DanielKneipp) merged 3 commits intomainfrom
daniel/js-sdk-sandbox-cleanup
Apr 22, 2026
Merged

chore(js): remove templates, pools, and volumes from sandbox SDK#2758
Daniel Kneipp (DanielKneipp) merged 3 commits intomainfrom
daniel/js-sdk-sandbox-cleanup

Conversation

@DanielKneipp
Copy link
Copy Markdown
Contributor

Summary

JS counterpart of #2757 (Python) — mirrors the same cleanup (plus the backend/frontend deprecations) in the JavaScript sandbox SDK. Template, pool, and volume concepts are gone from the backend, so the JS client now exposes only the snapshot-based surface.

What changed

  • types.ts: removed ResourceSpec, VolumeMountSpec, Volume, SandboxTemplate, Pool, and all Create/Update {Volume,Template,Pool}Options. Dropped template_name from SandboxData and snapshotId from CreateSandboxOptions (now a positional argument).
  • client.ts: deleted every volume/template/pool CRUD method. createSandbox now takes snapshotId as a required positional argument followed by the options object, matching the shape of other sandbox methods (e.g. getSandbox, stopSandbox).
  • sandbox.ts: removed the template_name field/JSDoc from the Sandbox class and refreshed the class-level example to use snapshots.
  • helpers.ts: deleted handleVolumeCreationError, handlePoolError, handleConflictError, and handleResourceInUseError; dropped the volume_count branch in extractQuotaType.
  • errors.ts: scrubbed template/pool/volume references from the JSDoc comments.
  • index.ts: stopped re-exporting the deleted types and refreshed the module-level example.
  • README.md: rewritten to be snapshot-only — quick start, snapshots workflow, API reference, and error handling — with no template/volume/pool sections.
  • src/tests/sandbox.test.ts: stripped template_name from mocks, rewrote the createSandbox tests to use the new positional snapshotId argument, and removed the template/snapshot mutual-exclusion cases.

Drive-by fix

js/package.json has pinned packageManager to [email protected] since #2635, but .pre-commit-config.yaml was still calling yarn run … for the JS hooks. Yarn 1.x refuses to run in a project whose packageManager names a different manager, so the hooks always failed locally. This PR flips the three JS hooks to pnpm run … so they match the pinned package manager.

Breaking changes

This is a breaking change for any consumer still using template/pool/volume APIs. The backend has already removed these endpoints, so those consumers are already broken; this PR just brings the types into line with reality. createSandbox callers will need to migrate from createSandbox({ templateName: "…" }) (or createSandbox({ snapshotId: "…" })) to createSandbox(snapshotId, options).

Made with Cursor

- Drop ResourceSpec, VolumeMountSpec, Volume, SandboxTemplate, Pool and all Create/Update {Volume,Template,Pool}Options from types.ts
- Remove template_name from SandboxData and drop snapshotId from CreateSandboxOptions
- Delete all volume/template/pool CRUD methods from SandboxClient
- Tighten createSandbox to createSandbox(snapshotId: string, options?: CreateSandboxOptions)
- Remove template_name field (and its JSDoc) from the Sandbox class
- Delete handleVolumeCreationError, handlePoolError, handleConflictError, and handleResourceInUseError; drop the volume_count branch in extractQuotaType
- Scrub template/pool/volume references from errors.ts JSDoc comments
- Remove deleted type re-exports from the module index and refresh the module example
- Rewrite README to be snapshot-only (quick start, snapshots, API reference, error handling) with no template/volume/pool sections
- Update sandbox tests: strip template_name from mocks, rewrite createSandbox tests to use the new positional snapshotId, and drop the template/snapshot mutual-exclusion tests
- Fix .pre-commit-config.yaml JS hooks to call pnpm instead of yarn (js/ pins packageManager to [email protected] since #2635, which made yarn 1.x refuse to run)
…int kwarg

- Remove the `checkpoint` field from `CaptureSnapshotOptions` and
  `SandboxClient.captureSnapshot` / `Sandbox.captureSnapshot`. The SDK exposes
  no way to obtain a valid checkpoint name, so the option could not be used in
  practice. Omitting `checkpoint` matches the backend default behavior of
  capturing a fresh checkpoint from the running VM.
- Expand the README capture example to install a package, write to a
  persistent path (`/opt`), and show `source_sandbox_id` on the returned
  snapshot. Also show that `sandbox.captureSnapshot(name, options)` and
  `client.captureSnapshot(sandboxName, name, options)` are equivalent.
- Add a note clarifying capture preserves the persistent filesystem only;
  processes, sockets, in-memory state, and `/tmp` (tmpfs) are not carried
  over.

Made-with: Cursor
Made-with: Cursor

# Conflicts:
#	js/src/experimental/sandbox/helpers.ts
@DanielKneipp Daniel Kneipp (DanielKneipp) merged commit b75bedf into main Apr 22, 2026
48 of 51 checks passed
@DanielKneipp Daniel Kneipp (DanielKneipp) deleted the daniel/js-sdk-sandbox-cleanup branch April 22, 2026 13:44
Daniel Kneipp (DanielKneipp) added a commit that referenced this pull request Apr 22, 2026
…ilters

- Relax `createSandbox(snapshotId, options?)` so `snapshotId` is optional and
  add a new `snapshotName` field on `CreateSandboxOptions`. Exactly one of
  the two must be set (validated via `LangSmithValidationError`). The SDK
  forwards the identifier verbatim on the wire as `snapshot_id` /
  `snapshot_name`. `snapshotId` stays positional — it is intentionally not
  duplicated on the options object.
- Add a new `ListSnapshotsOptions` type (nameContains / limit / offset /
  signal) and extend `listSnapshots` to build a URLSearchParams query string
  only when at least one option is set, preserving the zero-arg URL.
- Re-export `ListSnapshotsOptions` from the sandbox public index.
- Tests: cover the snapshotName create path, the zero-identifier and
  both-identifier rejection cases, the listSnapshots zero-arg URL shape, and
  the filtered URL shape.
- README: add snapshotName and listSnapshots examples in the Snapshots
  section, update the API Reference rows for `createSandbox` and
  `listSnapshots`, add a `snapshotName` row to the `CreateSandboxOptions`
  table, and add a new `ListSnapshotsOptions` table.

Stacked on top of #2758. Sibling to #2769 (Python).

Made-with: Cursor
Daniel Kneipp (DanielKneipp) added a commit that referenced this pull request Apr 22, 2026
## Summary

Follow-up to #2758 — extends the snapshot-only sandbox surface so
callers can boot from a snapshot **name** (not just an ID) and so
`listSnapshots` supports server-side filtering and pagination.

Sibling to the Python SDK change: #2769.

> Stacked on #2758. GitHub will auto-retarget the base to `main` once
that PR merges.

### `createSandbox` — accept `snapshotName`

`snapshotId` becomes optional (positional) and a new `snapshotName`
field is added to `CreateSandboxOptions`. Exactly one must be provided.
To avoid confusion, `snapshotId` is intentionally not duplicated on the
options object.

```ts
// By ID (unchanged):
const sandbox = await client.createSandbox(snapshot.id);

// By name — server resolves the snapshot against the caller's tenant:
const sandbox = await client.createSandbox(undefined, {
  snapshotName: "my-snap",
});
```

Validation throws a `LangSmithValidationError` if neither (or both) is
provided.

### `listSnapshots` — add `ListSnapshotsOptions`

```ts
const all = await client.listSnapshots();
const page = await client.listSnapshots({
  nameContains: "python",
  limit: 10,
  offset: 20,
});
```

All three options are optional and independent. Omitting them keeps
today's zero-arg behavior — the request URL has no query string. The new
type is re-exported from the sandbox public index.

### Tests (`src/tests/sandbox.test.ts`)

- createSandbox: new \`snapshot_name\` payload test + zero-identifier
and both-identifier rejection tests.
- listSnapshots: existing zero-arg test extended to assert an empty
query string; new test asserts \`name_contains\`, \`limit\`, \`offset\`
appear on the request URL.

All 80 sandbox tests pass locally.

### README

- Added a \`snapshotName\` example in the Snapshots section alongside
the existing \`snapshotId\` example.
- Added a \`listSnapshots({ nameContains, limit, offset })\` example.
- Updated the API Reference rows for \`createSandbox\` and
\`listSnapshots\`.
- Added a \`snapshotName\` row to the \`CreateSandboxOptions\` table.
- Added a new \`ListSnapshotsOptions\` table.

### Breaking changes

None. \`createSandbox(snapshotId)\` calls keep working unchanged; the
positional arg is now optional, but the payload behavior is identical
when it is provided.

Made with [Cursor](https://cursor.com)
Daniel Kneipp (DanielKneipp) added a commit to langchain-ai/docs that referenced this pull request Apr 24, 2026
## Overview

Mirrors the SDK-side deprecation of sandbox templates, warm pools, and
volumes for the public docs. Sandboxes now boot directly from snapshots;
there are no templates or pools left in the public API surface.

- Deletes `langsmith/sandbox-templates` and
`langsmith/sandbox-warm-pools` plus their screenshots.
- Adds `langsmith/sandbox-snapshots` covering build-from-Docker,
capture-from-sandbox, CRUD, and stop/start flows with Python +
TypeScript `<CodeGroup>` examples.
- Rewrites `sandboxes.mdx`, `sandbox-sdk.mdx`,
`sandbox-service-urls.mdx`, and `sandbox-auth-proxy.mdx` so every
example uses `snapshot_id` (Python) / positional `snapshotId`
(TypeScript). Removes every `create_template` / `createTemplate` call.
- Updates the Sandboxes nav group in `docs.json`: Overview → Snapshots →
Service URLs → Auth proxy → SDK usage.

## Type of change

**Type:** Remove outdated content

## Related issues/PRs

- Python SDK: langchain-ai/langsmith-sdk#2757
- JS SDK: langchain-ai/langsmith-sdk#2758

## Checklist

- [x] I have read the [contributing guidelines](README.md), including
the [language
policy](https://docs.langchain.com/oss/python/contributing/overview#language-policy)
- [x] I have tested my changes locally using `docs dev`
- [x] All code examples have been tested and work correctly
- [x] I have used **root relative** paths for internal links
- [x] I have updated navigation in `src/docs.json` if needed

## Additional notes

`oss/deepagents/*` docs still reference `template_name` because the
deepagents CLI/package still uses templates. Deepagents owns its own
migration; one dangling link to `/langsmith/sandbox-templates` remains
in `oss/deepagents/frontend/sandbox.mdx` until they update.
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.

2 participants