inis.run

Agent recipes

Short, task-oriented paths for building an agent harness on inis.run — organised by what you're trying to do, not by API endpoint.

Seven jobs an agent builder is usually trying to get done, each with the real, checked pattern and a link to executable source. If you haven't yet, start with the Quickstart — everything below builds on its create/write/read/destroy shape and its one semantic rule: you destroy the sessions you create, and never the ones you only attach to.

Runnable, tested versions of the patterns below live in examples/agent-harness (Python and TypeScript) — read the source, don't retype it from here.

If a coding agent (not your own runtime agent) is doing this integration work for you, point it at the coding-agent skill instead of this page — it routes to the same examples and adapters in a format built for that.

Run model-written code in an isolated sandbox

The base case: hand a session to an agent's tool-calling loop and let it run arbitrary code without touching your own infrastructure.

  • Canonical example: Quickstart
  • Framework adapters: Pydantic AI, Vercel AI SDK, LangChain / Deep Agents — each keeps the model-facing tool surface to bounded exec/file operations by default; session lifecycle administration (pause/resume/checkpoint/expose) is opt-in, not something the model can reach for on its own.
  • Limits: Organisation limits
  • Error recovery: Errors
  • Cleanup: destroy an owned session in a finally/with block, on both the success and the failure path — see the Quickstart's own header for why that's non-negotiable.

Keep state across agent turns

One session per conversation/thread, persisted by ID so any later turn — same process or a different one — can pick it back up.

  • Canonical example: persistent_tool_loop in examples/agent-harness — a host-side thread-ID-to-session-ID store (never a shared live session object), multiple tool calls in one turn, and a second turn served by a completely separate client proving the filesystem and a running background process both persisted.
  • Session lifecycle background: Session lifecycle
  • Limits: idle timeout / max lifetime knobs, same page
  • Error recovery: a session_not_live on a live-only call usually just means a wake race — see Errors and retry
  • Cleanup: destroy the one session a thread owns when its conversation ends, not on every turn
  • Don't pre-build a pool of idle live sessions to dodge cold starts — Production best practices covers why the platform's own resume tiers already do that job, and what to check before trusting a connection your code held open across a pause

Explore several branches safely

Fork a session once shared setup is done, run different candidates on the independent children, and grade outside the sandbox.

  • Canonical example: branch_and_evaluate in examples/agent-harness — uses the real fork(count=…) signature (not an n= kwarg, not an iterable result), proves the concurrency claim with a wall-clock check instead of asserting it, and is explicit that the batch-exec helper is sequential server-side, not a parallelism primitive.
  • Concepts: Fork
  • Why fork instead of one ever-growing conversation: forking clones a live session's filesystem to seed N children cheaply, so exploring several candidates costs a fast, warm clone per branch instead of repeating expensive setup or paying for N sessions live from the start.
  • Limits: a hard, account-independent cap of count<=16 per fork call (HardMaxForkCount), and a lower default per-request cap of count<=4 (DefaultMaxForkCount) unless an account has a raised limit — see the example's own README for how these two are easy to conflate
  • Error recovery: fork requests fail closed with a specific code per reason (over either count limit vs. an account's live-session concurrency cap) — branch on code, not the message
  • Cleanup: every forked child is its own independent, independently billed session — destroy each one explicitly, not just the parent

Control or deny egress

Lock a session to an explicit domain allowlist, or block outbound network access entirely, per session or per project/org.

  • Canonical guide: Networking & egress — has real, checked Python/TypeScript/CLI samples already; not duplicated here
  • Limits: allowlist size cap, same page
  • Error recovery: Errors
  • Cleanup: n/a — egress policy lives with the session and is torn down with it

Transfer files and artifacts

Get files a session produced out to durable storage with a link that outlives the session, or move files in.

  • Canonical guide: Artifacts — real, checked Python/TypeScript/CLI samples already; not duplicated here
  • Limits: per-capture size/file-count caps, retention window, same page
  • Error recovery: a capture can land failed; poll and retry
  • Cleanup: artifacts outlive the session on purpose — delete explicitly when no longer needed, they aren't torn down with it

Cancel or time out work

Bound how long a command can run, or stop something already running.

  • Canonical example: error_recovery_and_limits in examples/agent-harness — exec(..., timeout_ms=…) for a hard cap on one command, kill_process() for stopping a named background job on demand from anywhere. Also documents the real gap: there is no separate primitive to cancel an arbitrary in-flight exec() call from a different process — only disconnecting from exec_stream() cancels a foreground command, and only from the same calling process. True remote cancellation of an unrelated in-flight request is a real product gap, not a docs gap.
  • Limits: Organisation limits
  • Error recovery: timed_out on the result, not an exception — check it
  • Cleanup: kill_process before session teardown for a graceful stop; destroy() will SIGKILL everything regardless if you skip it

Recover from a paused, expired, failed, or capacity-limited session

  • Canonical example: error_recovery_and_limits in examples/agent-harness — branches on InisError.code/.retryable/.retry_after (never message text) for a 404 (gone), a 400 (invalid request, deterministic against the documented hard fork-count cap), and a 429 (capacity-limited, retryable — demonstrated against a scripted error sequence rather than forcing a real account over its limit). A session stuck in state="failed" is documented as a pattern (poll, read status_reason, recreate) rather than shown live — forcing a real provisioning failure on demand isn't something this example does.
  • Error codes reference: Errors
  • Session lifecycle background (pause/resume, wake-on-op, hot/warm/cold): Session lifecycle
  • Cleanup: a gone session (404) needs a fresh replacement, not a retry; a retryable error (429/503) is safe to retry with backoff using the server's own retryable/retry_after signal

On this page