agent_session
A small, single-purpose Python library: uniform multi-turn session abstraction over CLI coding agents (Claude Code, Codex). One protocol, two interchangeable backends, zero opinions about what you do with the result.
It exists because higher-level frameworks (autor, aker, ...) all
need the same primitive — "drive a claude -p or codex exec
subprocess across multiple turns, capture file changes, return a
canonical result" — and re-implementing it per project drifts.
from agent_session import (
make_session,
SANDBOX_WORKSPACE_WRITE, SANDBOX_READ_ONLY,
BACKEND_CLAUDE, BACKEND_CODEX,
)
sess = make_session(
cwd="/tmp/scratch",
sandbox=SANDBOX_WORKSPACE_WRITE,
backend=BACKEND_CLAUDE, # explicit; or use env_var=...
timeout_sec=600,
)
r = sess.send("Write hello.txt with 'hi' inside.")
assert r.ok
print(r.files_created) # [PosixPath('hello.txt')]
print(r.final_message)
print(r.session_id) # uuid string
r2 = sess.send("Now append ' there'.") # turn 2: same session_id, resumed
Public API
Everything below is importable from the top-level agent_session namespace.
Anything inside agent_session._* modules is internal — do not import
from there.
Session factory
| symbol | what it does |
|---|---|
make_session(cwd, *, sandbox, model, timeout_sec, extra_args, extra_env, backend, env_var, rng) |
Construct an AgentSession. Picks a backend per backend= / env_var= / random. |
pick_backend(*, env_var, rng) |
Choose backend name without instantiating. |
Types
| symbol | shape |
|---|---|
AgentSession (protocol) |
cwd: Path, session_id: str | None, turn_count: int, backend: str, send(prompt, timeout_sec=None) -> AgentResult |
AgentResult (dataclass) |
ok, exit_code, stdout, stderr, final_message, duration_sec, files_created, files_modified, cmd, backend, session_id, raw |
AgentError (Exception) |
Raised for missing binaries / unknown backend / parse failures. |
Constants
| group | values |
|---|---|
| sandbox modes | SANDBOX_READ_ONLY SANDBOX_WORKSPACE_WRITE SANDBOX_DANGER_FULL_ACCESS |
| backend names | BACKEND_CLAUDE BACKEND_CODEX ALL_BACKENDS |
Sandbox semantics
| sandbox | claude implementation | codex implementation |
|---|---|---|
read-only |
--allowedTools Read,Glob,Grep,WebFetch,WebSearch --dangerously-skip-permissions |
--sandbox read-only |
workspace-write |
--dangerously-skip-permissions (writes confined by subprocess cwd) |
--sandbox workspace-write |
danger-full-access |
same as workspace-write at the CLI level — no extra restriction | --sandbox danger-full-access |
Sandbox is enforced per-turn, not session-wide; resuming a session with a different sandbox is allowed (within each backend's own constraints).
workspace-write and danger-full-access look identical for claude
because Claude Code does not currently expose a finer-grained native
sandbox; consumers that need stricter confinement should rely on the
subprocess cwd + filesystem permissions.
Backend selection
Three places control which backend make_session picks, in priority order:
backend="claude"/backend="codex"— explicit kwarg, no override.env_var="MY_PROJ_BACKEND"— read that env var (case-insensitive, value must be inALL_BACKENDS); raisesAgentErroron unknown values so typos are loud.- Random — uniform pick across
ALL_BACKENDSvia the supplied or defaultrandom.Random.
Consumers typically expose their own env var name:
sess = make_session(cwd=..., env_var="AUTOR_BACKEND") # autor convention
sess = make_session(cwd=..., env_var="AKER_BACKEND") # aker convention
Result reporting
Every backend computes files_created / files_modified by snapshotting
mtimes + sizes of cwd.rglob('*') before and after the subprocess.
Snapshot ignores nothing — if your subprocess writes Python bytecode
into __pycache__/, that will show up. Filtering is the consumer's
responsibility.
final_message is the agent's last assistant turn:
- claude:
resultfield ofclaude -p --output-format jsonoutput - codex: contents of the file pointed to by
--output-last-message
If the subprocess times out, ok=False, exit_code=-1, and stderr
contains the timeout note.
Prerequisites
- Python ≥ 3.9
claudebinary (Claude Code CLI 2.0+) onPATHif you want the claude backendcodexbinary (codex 0.120+) onPATHif you want the codex backend
You only need the binaries for backends you actually instantiate. The
package imports lazily — make_session(..., backend="claude") does not
import agent_session.codex and vice versa.
Install
git clone <this repo>
cd agent_session
pip install -e . --user
What this is NOT
- Not a graph framework — that lives in consumers (
autor,aker). - Not a prompt library —
sendtakes a string, no templating. - Not multi-process — sessions are not thread-safe; spawn one per worker if you parallelise upstream.
- Not deterministic — both claude and codex have non-zero temperature; this library does not change that.
Adding a new backend
- Implement
MyAgentSessionsomewhere inagent_session/<name>.pyconforming toAgentSessionprotocol. - Add
BACKEND_MYAGENT = "myagent"toagent_session/_common.pyand append it toALL_BACKENDS. - In
agent_session/_backends.py:make_session, add a branch that imports your module lazily and constructs the session. - Optionally add a smoke test to
tests/.
Release files for agent_session 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| agent_session-0.1.0.tar.gz | 16.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| agent_session-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 32.1 kB
Release files / agent_session-0.1.0.tar.gz
| Download URL | agent_session-0.1.0.tar.gz |
|---|---|
| Size | 16.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2ad33edb18fb4cfcc60ae60ea26e9cc62fcbd387d265e72833d70704c9fb56bd
|
|
BLAKE2b-256 checksum How to use checksums |
e2bc91d0c9d19bc8ed7991433427af41d95799b9c4767c704b26eb0fefa423f2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.14
|
Release files / agent_session-0.1.0-py3-none-any.whl
| Download URL | agent_session-0.1.0-py3-none-any.whl |
|---|---|
| Size | 15.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ddf0a6f46e27e535a8d993e6c504a61b4e79c6daffabd6ca9e6a9c76f2736780
|
|
BLAKE2b-256 checksum How to use checksums |
77d0ba7b9f13fc8045ca82f6f461e52987df3583b2956a6fbb9a80f8b022397d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.8.14
|