inis.run
Integrations

OpenAI Agents SDK

Native sandbox providers for the OpenAI Agents SDK, Python and TypeScript.

Native inis.run sandbox providers for the OpenAI Agents SDK's SandboxAgent path — agents.sandbox in Python, @openai/agents-core/sandbox in TypeScript.

Beta, upstream and here. The Agents SDK documents its own sandbox surface as beta. Verified against openai-agents==0.19.1 (Python) and @openai/agents-core==0.14.1/@openai/agents==0.14.1 (TypeScript).

Install

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

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

from inis import AsyncClient
from agents import Runner, RunConfig
from agents.run_config import SandboxRunConfig
from agents.sandbox import SandboxAgent
from inis_openai_agents import InisSandboxSession

client = AsyncClient()
inis_session = await client.sessions.create(egress_default="deny")
sandbox_session = InisSandboxSession.wrap(inis_session)

agent = SandboxAgent(name="assistant", model="gpt-5.1")
run_config = RunConfig(sandbox=SandboxRunConfig(session=sandbox_session))
try:
    result = await Runner.run(agent, "list files in /workspace", run_config=run_config)
    result2 = await Runner.run(agent, "now write hello.txt", run_config=run_config)
finally:
    await inis_session.destroy()  # this app owns the session; the SDK never will
import { Client } from "@inis-run/sdk";
import { run } from "@openai/agents";
import { SandboxAgent } from "@openai/agents-core/sandbox";
import { InisSandboxSession } from "@inis-run/openai-agents";

const client = new Client();
const inisSession = await client.sessions.create({ egress: { mode: "deny" } });
const sandboxSession = InisSandboxSession.wrap(inisSession);

const agent = new SandboxAgent({ name: "assistant", model: "gpt-5.1" });
try {
  const result = await run(agent, "list files in /workspace", {
    sandbox: { session: sandboxSession },
  });
} finally {
  await inisSession.destroy(); // this app owns the session; the SDK never will
}

The Agents SDK's own sandbox runtime never destroys a session passed via sandbox.session — that lifecycle stays entirely host-controlled: one persistent session across a whole conversation, not one sandbox per model turn.

Owned: one run at a time

The SDK can also create and destroy a fresh session for a single Runner.run()/run() call:

from agents.run_config import SandboxRunConfig
from inis_openai_agents import InisSandboxClient, InisSandboxClientOptions

run_config = RunConfig(
    sandbox=SandboxRunConfig(
        client=InisSandboxClient(),
        options=InisSandboxClientOptions(egress_default="deny"),
    )
)
result = await Runner.run(agent, "...", run_config=run_config)

To resume a conversation in a later process, pass result._sandbox_resume_state back in — the SDK creates a new session and restores the workspace from a tar snapshot; it does not reattach to the original session ID. Prefer the attached path above for a real multi-turn agent.

import { InisSandboxClient, InisSandboxClientOptions } from "@inis-run/openai-agents";

const result = await run(agent, "...", {
  sandbox: {
    client: new InisSandboxClient(),
    options: { egressDefault: "deny" } satisfies InisSandboxClientOptions,
  },
});

InisSandboxClientOptions also accepts connections — inline Connections to create alongside the session.

What it does

  • exec/execCommand (shell), with a real interactive PTY (tty: true) and writeStdin for a running session
  • File read/write, symlink-safe path validation (Python); readFile and plain file/dir manifest entries (TypeScript)
  • Exposed ports, via session.expose()
  • Owned/attached lifetime split — see above
  • Snapshot persist/hydrate (owned path's resume) — tar+base64 over exec()

Notes

Docker-volume-mount manifests are not implemented (supports_docker_volume_mounts() stays False in Python; nested Dir/local_file/local_dir/git_repo manifest entries throw in TypeScript). True remote cancellation of an in-flight command is not implemented in either language — the sandbox contract is timeout-only, with no abort handle to route through.

InisSandboxSession.exec() returns a result type extending upstream's own with one added field, truncated — set directly from inis.run's own per-stream capture-limit signal (never derived from stream content, so it can't be spoofed by a guest command printing fake marker text).

Fallback: plain function tools

Not using SandboxAgent? Use an ordinary Agent with function tools against the Python or TypeScript SDK directly.

On this page