Skip to main content

Python library for programmatically invoking AI coding agents

Project description

agentrunner (Python)

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

Supported CLIs

Runner CLI Version Status
Claude Code >= 1.0.12

Requirements

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

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
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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

driangle_agentrunner-0.1.0.tar.gz (21.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

driangle_agentrunner-0.1.0-py3-none-any.whl (20.5 kB view details)

Uploaded Python 3

File details

Details for the file driangle_agentrunner-0.1.0.tar.gz.

File metadata

  • Download URL: driangle_agentrunner-0.1.0.tar.gz
  • Upload date:
  • Size: 21.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.8

File hashes

Hashes for driangle_agentrunner-0.1.0.tar.gz
Algorithm Hash digest
SHA256 9fecf64758a0d74c4b6035cddc853372626b2e468b71f9f0be6f294ff86c2557
MD5 5c653bafee7531b68f894c7f043a0db4
BLAKE2b-256 0fcaa1a1da7ebca8d2f556b79a19e5c89fbca7b45b9efd0da1dd977b850b2d6b

See more details on using hashes here.

File details

Details for the file driangle_agentrunner-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for driangle_agentrunner-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7a18e09fa3a6e39ed398437dad8ab92d5a6560eb00f8162138945cd600c26b9b
MD5 f5c746e3d5c59c433c4d3a21f02bd435
BLAKE2b-256 d053749f46270bef8874f57933ed975a50be003c1f6858cb63f332c3f8a88604

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page