Stacklink

Workbench

A safe scratch computer where your agent can run code, crunch data, and make files.

Sometimes an agent needs to do work, not just call an API — crunch numbers, parse a messy spreadsheet, generate a PDF, or run a quick script. The workbench gives it a safe, temporary computer to do exactly that, with the rest of Stacklink one call away.

Screenshot placeholderAn agent writing and running a script in the workbench

What it's good for

Crunch & transform data

Clean a spreadsheet, reshape JSON, run pandas or numpy.

Make files

Generate a PDF report, a chart, or an Excel export.

Glue steps together

Call a tool, process the result, call the next one.

Read documents

Pull text and tables out of PDFs, Word, and Excel files.

Turn it on

Enable it on the session. Your agent gets one Workbench gateway, STACKLINK_REMOTE_WORKBENCH. It loads the exact deferred schema it needs before running code, using Bash, managing files, or working with reusable runs:

const session = await stacklink.create({
  tenantId, userId,
  workbench: { enable: true, sandboxSize: 'standard' },
});

Safe by design

The sandbox is isolated and disposable, and your credentials never enter it. When a script needs to call a provider, the workbench asks Stacklink to make the call — secrets stay on our side, never in the agent's code.

Retry a submission safely

Both /v1/workbench/bash and run_code accept idempotencyKey in the body or Idempotency-Key in the header. If both are sent, they must match. Identical repeats in the same project and tenant return the original execution before any new budget admission. A changed request with the same key returns 409. Without a key, each submission starts a new job.

The SDK passes this key through and can safely retry a keyed POST. Keep the key when retrying after a timeout. A queued response confirms admission; a later budget failure is recorded on the execution before any compute starts. Repeating the same job from a new session in that tenant returns its original execution and workspace. The SDK observes and controls that execution using the original session; your newly bound sandbox keeps its own workspace.

For saved progress across explicit steps, use Workflows. A single script is still one Workbench execution.

Pick a size

Most jobs run fine on the smallest size. Step up only when a job is data- or compute-heavy.

StandardMost jobs — start here

Scripts, file generation, and light data work.

MediumData-heavy

Bigger datasets and more memory-hungry libraries.

LargeHeavy compute

The most demanding jobs — large transforms and parallel work.

Limits at a glance

Every run is bounded, so a runaway job can't run forever or flood your agent with output.

60 minBackground run limitsubject to admitted capacity; foreground runs up to 3 min
2 MBOutput caplarger results become a file
DisposableSandboxcleaned up when idle
ZeroSecrets insidecredentials stay server-side

A long job doesn't have to block the agent — start it in the background and collect the result later with execution control.

What a script can reach from inside

The workbench isn't a sealed box. From inside a script, the agent can reach back into Stacklink and the web:

Provider tools

Search, fetch schemas, and run any connected provider tool.

AI helper

Call a language model for a sub-task — summarize, classify, extract.

Web search

Look something up on the web.

Document extraction

Turn a PDF, Word, or Excel file into clean text or data.

Packages

Install common Python libraries (pandas, numpy, pillow, requests…) on demand.

Files & artifacts

Read and write files; finished outputs become downloadable artifacts.

Results come back as files

Anything the agent produces — a report, an export, a chart — is saved as an artifact with a download link, instead of being dumped into the conversation. Large tool responses are handled the same way: the agent gets a short preview plus a link, not a wall of text.

What it costs

Workbench is billed by active customer workload time at the published rate for its size, paid from prepaid credits when Workbench's spending switch is on. Queueing, platform startup, warm idle and cleanup are free. Optional Keep ready holds a sandbox through an approved wait at the same rate. Individual commands add no second runtime charge. Pricing lists the rates; Billing & usage covers leases and limits.

✦ 30-day trial

Try Workbench within a bounded trial

The trial includes a bounded amount of Workbench to try it. Pricing lists what the current trial includes.

Start free trial→No card required. Nothing charged automatically.

For developers

STACKLINK_REMOTE_WORKBENCH accepts a small wrapper:

{
  operation: 'run' | 'workspace' | 'files' | 'artifacts' | 'runs',
  input: {},
  contractVersion?: string,
}

The canonical STACKLINK_REMOTE_WORKBENCH schema contains its five typed operations. The run operation supports Python, JavaScript, TypeScript, and Bash through the same durable execution lifecycle. Provider discovery and execution remain in their canonical Stacklink provider tools; session-bound helper clients are available inside the runtime.

Successful code and Bash runs are reusable by default. Before execution, Stacklink captures the exact workspace/package/tier manifest. After completion, it creates one immutable version and returns its state under execution.reusableRun. Use reusableRun: { mode: 'off' } for a scratch run that should not become a version. To create the next version of an existing run, pass its exact seriesId; Stacklink never guesses series membership from similar code or names.

Replay compares only stable observable behavior: terminal status and exit code, ordered output digests, stdout/stderr digests, structured-result digest, byte count, and artifact digest. Execution IDs, timestamps, cursors, duration, usage, and cost are deliberately excluded. A version can be published only after a replay matches, and publish or rollback requires the caller's expected currently published version so concurrent changes fail clearly instead of overwriting each other.

Per-tenant budgets cap maxCostMicros, maxDurationMs, maxLlmTokens, and maxArtifactBytes over a daily, weekly, monthly, or all-time period.

New and migrated policies use measurementVersion: 2:

  • maxDurationMs limits active sandbox runtime, including admitted reservations. Concurrent workloads in the same sandbox count once; separate sandboxes count separately.
  • maxCostMicros limits actual additional Workbench customer charges, including paid keep-ready, within the workspace's approved spending. A zero charge limit still permits included trial minutes.
  • Tenant and session limits both apply, including when a long execution renews its capacity.
  • Token limits and retained artifact bytes remain separate measurements.

Existing policies are migrated in place after their old reservations settle. Their numerical limits, scope and period remain unchanged. Unverifiable historical runtime receives an audited policy waiver; original invoices, receipts and estimates remain intact. Existing admissions complete under their original terms. Calendar policy windows remain separate from subscription billing periods. A command's requested timeout no longer reserves that entire amount against the active-time policy; admission uses bounded sandbox runtime intervals.

Interactive Python and JavaScript contexts preserve variables while compute remains available. Their interpreter threads and child processes pause between cells. Use a tracked background execution for work that must continue between requests. The warm sandbox may be suspended after 30 seconds without active work; saved files and committed output remain available, while in-memory variables do not survive suspension.

Save work while waiting

Use afterExecution on a code or bash run to finish a step, save its files and output, and wait before a declared continuation. This is an explicit step boundary, not a snapshot of an arbitrary running process. A running script waiting on OTP, an HTTP response or a sleep remains active work. Pre-dispatch approval queues are free.

const started = await session.workbench.run({
  language: "python",
  code: "from pathlib import Path\nPath('/mnt/files/result.txt').write_text('saved')",
  timeoutMs: 120_000,
  afterExecution: {
    mode: "saved",
    reason: "user_input",
    maximumWaitMs: 3_600_000,
    continuation: {
      language: "python",
      code: "from pathlib import Path\nprint(Path('/mnt/files/result.txt').read_text())",
      timeoutMs: 60_000,
    },
  },
});

Saved waiting releases unused active capacity and suspends unused compute. It has zero runtime cost and may require startup on resume. Its maximum lifetime is seven days. get and wait expose checkpointing, waiting_saved, waiting_ready and resuming without falsely reporting completion. The original execution remains the handle for output and terminal status. Its active timeout covers both steps.

Resume through POST /v1/workbench/resume with sessionId, executionId, expectedWaitRevision and checkpointId from the latest execution's waitState. The TypeScript/Python Workbench client and MCP workspace resume action expose the same operation. Duplicate resume requests create one continuation. Current auth, approvals, files and capacity are rechecked. Changed workspace files or packages produce a conflict instead of silently overwriting another task's work. Cancelling or closing the session also cancels its wait and any continuation.

For mode: "keep_ready", fetch /v1/workbench/runtime-tiers and pass its selected size's keepReady quote with maximumWaitMs, maximumChargeMicros, priceMicros, unitQuantity and rateVersion. Obtain explicit consent before submitting this choice. Round the maximum charge up to a whole cent to cover invoice rounding. The maximum is 30 minutes, bounded by the current billing and policy window. It needs a purchased plan and approved additional spending. Its same-size runtime price applies only after the free 30-second grace, and never to overlapping active work. Trial minutes are not used. A failed retention admission exposes retentionFailure and retains the free saved continuation. Provider shutdown can still require a cold start; live variables are not guaranteed. Keep-ready approval does not approve code, connection access or external mutations.

On this page