Skip to main content

agentrunner (Python)

Python library for programmatically invoking AI coding agents. Part of the agentrunner monorepo.

Supported CLIs

Runner CLI Version Status
Claude Code >= 2.1.0 ✅

Requirements

  • Python >= 3.11
  • Claude Code CLI >= 2.1.0

Installation

pip install driangle-agentrunner

Quick Start

import asyncio
from agentrunner.claudecode import create_claude_runner, ClaudeRunOptions

runner = create_claude_runner()

async def main():
    # Simple run
    result = await runner.run("What files are in this directory?", ClaudeRunOptions(
        working_dir="/path/to/project",
        skip_permissions=True,
    ))
    print(result.text)

    # Streaming
    stream = await runner.run_stream("Explain this codebase")
    async for message in stream:
        print(message.type, message.raw)

asyncio.run(main())

API

create_claude_runner(config?)

Creates a runner for the Claude Code CLI.

Config options (ClaudeRunnerConfig):

Field Type Default Description
binary str "claude" CLI binary name or path
spawn SpawnFn — Custom spawn function (for testing)
logger Logger — Logger for debug output (opt-in)

runner.run(prompt, options?)

Execute a prompt and return the final Result.

runner.run_stream(prompt, options?)

Execute a prompt and stream messages as they arrive. Returns AsyncIterable[Message].

runner.start(prompt, options?)

Launch an agent process and return a Session for full lifecycle control.

Run Options

Common options (RunOptions):

Field Type Description
model str Model name or alias
system_prompt str System prompt override
append_system_prompt str Appended to default system prompt
working_dir str Working directory for subprocess
env dict[str, str] Additional environment variables
max_turns int Maximum agentic turns
timeout float Timeout in milliseconds
skip_permissions bool Skip permission prompts

Claude-specific options (ClaudeRunOptions extends RunOptions):

Field Type Description
allowed_tools list[str] Tools the agent may use
disallowed_tools list[str] Tools the agent may not use
permission_mode str Permission mode (wins over dangerously_skip_permissions)
settings str Additional settings: file path or inline JSON
mcp_config str Path to MCP server config
json_schema str JSON Schema for structured output
max_budget_usd float Cost limit in USD
resume str Session ID to resume
continue_session bool Continue most recent session
session_id str Specific session ID
include_partial_messages bool Stream partial/incremental messages

Result

Field Type Description
text str Final response text
is_error bool Whether the run ended in error
exit_code int Process exit code
usage Usage Token counts
cost_usd float Estimated cost in USD
duration_ms float Wall-clock duration in ms
session_id str Session ID for resumption

Session

Attribute Type Description
messages AsyncIterable[Message] Iterate messages as they arrive
result Future[Result] Resolves when the agent finishes
abort() — Terminate the agent process
send() — Reserved (raises RuntimeError)

Error Classes

All errors extend RunnerError:

  • NotFoundError — CLI binary not found
  • TimeoutError — execution timed out
  • NonZeroExitError — CLI exited with non-zero code (has .exit_code)
  • ParseError — failed to parse CLI output
  • CancelledError — execution cancelled
  • NoResultError — stream ended without a result message
from agentrunner import TimeoutError

try:
    await runner.run("complex task", ClaudeRunOptions(timeout=30_000))
except TimeoutError:
    print("Timed out!")

Usage Examples

Session Resume

# First run — capture the session ID.
result = await runner.run("Set up the project structure")
session_id = result.session_id

# Resume the same session later.
result = await runner.run("Now add tests", ClaudeRunOptions(resume=session_id))

Session Object

session = runner.start("Explain this code", ClaudeRunOptions(max_turns=1, timeout=30_000))

async for msg in session.messages:
    print(f"[{msg.type}] {msg.raw[:80]}")

result = await session.result
print(f"Response: {result.text}")

Streaming with Partial Messages

from agentrunner.claudecode import parse

stream = await runner.run_stream("List fun facts", ClaudeRunOptions(
    include_partial_messages=True,
))
async for msg in stream:
    if msg.type == "assistant":
        parsed = parse(msg.raw)
        if parsed.type == "stream_event":
            import json
            raw = json.loads(msg.raw)
            delta = raw.get("event", {}).get("delta", {})
            if delta.get("type") == "text_delta":
                print(delta["text"], end="", flush=True)

Development

cd python
pip install -e ".[dev]"   # install with dev dependencies
ruff check src/ tests/    # lint
python -m pytest           # run tests

Or from the repo root:

make check-python  # build + lint + test
make check         # all libraries

Release files for driangle-agentrunner 0.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for driangle-agentrunner 0.0.2
File Size Uploaded
driangle_agentrunner-0.0.2.tar.gz 22.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for driangle-agentrunner 0.0.2
File Interpreter ABI Platform
driangle_agentrunner-0.0.2-py3-none-any.whl Python 3 none any Details

Total release size: 43.4 kB

Release files / driangle_agentrunner-0.0.2.tar.gz

Download URL driangle_agentrunner-0.0.2.tar.gz
Size 22.2 kB
Tags Source
SHA-256 checksum
How to use checksums
c6eb7d41e41fccf98df940a0876468facd352f49a90ab59f53a47ed518a7e04b
BLAKE2b-256 checksum
How to use checksums
d3160d048bd1f399c87fbe95c64531e0b32a8f90726a76188b9e9321a2116d16
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release files / driangle_agentrunner-0.0.2-py3-none-any.whl

Download URL driangle_agentrunner-0.0.2-py3-none-any.whl
Size 21.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fb410ca39a6fdb40c002140cdb963c3eb95682a4463264eb86a2a7cc0eeef60e
BLAKE2b-256 checksum
How to use checksums
a21dd83c583924403ec55769cd1af15ea1a9fc3183ca80fe50875bd0b23ff4ae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release history Release notifications | RSS feed

0.1.0

2 release files

This release

0.0.2 This release

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page