inis.run
Integrations

Strands Agents

Native sandbox providers for Strands Agents, Python and TypeScript.

Native inis.run sandbox providers for Strands Agents' Sandbox surface — gives Strands its standard sandbox_bash and sandbox_file_editor tools backed by a real, isolated inis.run session instead of the local host.

Verified against strands-agents==1.50.2 (Python) and @strands-agents/sdk==1.11.2 (TypeScript).

Install

pip install inis-strands-agents                                # Python
npm install @inis-run/strands-agents @strands-agents/sdk @inis-run/sdk  # TypeScript / Node

One inis.run session for the whole conversation, owned by your app.

from inis import AsyncClient
from strands import Agent
from inis_strands_agents import InisSandbox

client = AsyncClient()
session = await client.sessions.create(egress_default="deny")
sandbox = InisSandbox.wrap(session)

agent = Agent(model="...", sandbox=sandbox)
await agent.invoke_async("list files in /workspace")
await agent.invoke_async("now write hello.txt")
await session.destroy()  # this app owns the session; the adapter never will
import { Client } from "@inis-run/sdk";
import { Agent } from "@strands-agents/sdk";
import { InisSandbox } from "@inis-run/strands-agents";

const client = new Client();
const session = await client.sessions.create({ egress: { mode: "deny" } });
const sandbox = InisSandbox.wrap(session);

const agent = new Agent({ model, sandbox });
await agent.invoke("list files in /workspace");
await agent.invoke("now write hello.txt");
await session.destroy(); // this app owns the session; the adapter never will

Owned: the adapter creates and destroys the session for you

from strands import Agent
from inis_strands_agents import InisSandbox

async with await InisSandbox.create(egress_default="deny") as sandbox:
    agent = Agent(model="...", sandbox=sandbox)
    await agent.invoke_async("...")
# session destroyed on exit
import { Agent } from "@strands-agents/sdk";
import { InisSandbox } from "@inis-run/strands-agents";

const sandbox = await InisSandbox.create(undefined, { egress: { mode: "deny" } });
try {
  const agent = new Agent({ model, sandbox });
  await agent.invoke("...");
} finally {
  await sandbox.close();
}

InisSandbox.create()'s options also accept connections — inline Connections to create alongside the session.

Either way, Agent({ sandbox }) registers sandbox_bash and sandbox_file_editor automatically — no separate tool wiring needed. Session create/destroy, egress, pause/resume, and fork stay host-controlled.

What it does

  • Streaming shell execution — distinct stdout/stderr chunks, then a final result
  • Binary-safe file read/write/remove/list, routed to inis.run's native /files endpoints
  • Per-call timeout — genuinely kills the remote process on expiry
  • Per-call env — via a validated shell-export prefix (inis.run's exec API fixes env at session creation)
  • Cancellation: Python asyncio task cancellation preempts a running command outright; TypeScript AbortSignal can only preempt at a chunk boundary (Session.execStream has no cancellation parameter of its own) — a real, tested asymmetry between the two packages, not a bug in one of them.

Notes

PTY isn't implemented in either language: the Sandbox/PosixShellSandbox shell/file contract has no PTY concept to hook into. Output-file collection is always empty, same as every other shell-based Sandbox — read a produced file back explicitly instead.

On this page