Guides / Python / Agent frameworks
OpenAI Agents SDK and LangChain
One function call turns a kosa8 sandbox into the tools an agent framework expects. The agent writes and runs code in its own microVM; your machine is not in reach.
Needs kosa8 0.2.0 or later and a daemon with the toolbox routes (the release
after v0.12.1). The adapters were tested with openai-agents and
langchain-core against the SDK's mock daemon: the tool schemas, and calls going
through to the right routes. They have not yet been run against a live daemon.
Install
pip install 'kosa8[openai-agents]' # the OpenAI Agents SDK pip install 'kosa8[langchain]' # LangChain or LangGraph
OpenAI Agents SDK
from agents import Agent, Runner
from kosa8 import Kosa8Client
from kosa8.integrations.openai_agents import sandbox_tools
client = Kosa8Client()
sbx = client.create_sandbox(name="coder-1", ephemeral=True, auto_stop_min=15)
agent = Agent(
name="coder",
instructions="You work in a Linux sandbox. Keep your files in /workspace.",
tools=sandbox_tools(client, sbx["id"]),
)
result = Runner.run_sync(agent, "Write fizzbuzz.py, run it for 1..15 and show the output.")
print(result.final_output)
client.stop_sandbox(sbx["id"]) # ephemeral: stopping deletes it
LangChain and LangGraph
from langchain_anthropic import ChatAnthropic
from langgraph.prebuilt import create_react_agent
from kosa8 import Kosa8Client
from kosa8.integrations.langchain import sandbox_tools
client = Kosa8Client()
sbx = client.create_sandbox(name="coder-2", ephemeral=True)
agent = create_react_agent(ChatAnthropic(model="claude-sonnet-5-5"), sandbox_tools(client, sbx["id"]))
agent.invoke({"messages": [("user", "Clone https://github.com/pallets/click and run its tests.")]})
The tools are StructuredTools, so they also work with bind_tools
and any LangChain agent.
The tools
| Tool | What it does |
|---|---|
sandbox_run_code | Runs Python, JavaScript or TypeScript. Starts in /workspace. Reports charts it drew. |
sandbox_shell | Runs a command line. cd and export carry to the next call. |
sandbox_read_file | Reads a text file from the workspace. |
sandbox_write_file | Creates or replaces a file, making its folders. |
sandbox_list_files | Lists a folder; folders end in /. |
sandbox_git | clone, status, add, commit, push, pull, checkout, branches, log, diff. |
sandbox_preview | A signed link to a web server the agent started, which expires. |
Pick a subset with tools=["shell", "read_file"], change the prefix with
name_prefix=, and pass a signed approval to every call with approval=.
Long output is cut to 20,000 characters, keeping the start and the end.
When something is refused
A tool never raises a kosa8 error into the framework. It returns text starting with
error:, with the daemon's reason and what to do, so the model can change course:
error: egress to pypi.org is not allowed by this sandbox's policy what to do: create the sandbox with egress_allow=["pypi.org", "files.pythonhosted.org"]
Open the network only as far as the task needs, when you create the sandbox:
client.create_sandbox(name="coder-3", egress_allow=["pypi.org", "files.pythonhosted.org"])
Another framework
The adapters are thin. kosa8.integrations.sandbox_functions(client, sandbox)
returns the same tools as plain Python functions with type hints and docstrings. Most frameworks
(CrewAI, Pydantic AI, smolagents, the Anthropic SDK's tool runner) turn such functions into
tools directly.
from kosa8.integrations import sandbox_functions
fns = sandbox_functions(client, "coder-1", tools=["run_code", "shell"])
print(fns[1]("cd /tmp && pwd"))
Without a framework
The same calls are on the client, for your own loop:
sb = client.sandbox("coder-1")
r = sb.run_code("import sys; print(sys.version)")
print(r.exit_code, r.stdout)
sb.shell("cd /workspace && python3 -m venv .venv")
sb.shell(". .venv/bin/activate && pip --version") # still in /workspace, venv still active
sb.write_file("notes.md", "# done\n")
See also: RL rollouts and evals, the Python developer guide and the native API.