Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

car-runtime (Python)

Python bindings for Common Agent Runtime (CAR) — a deterministic execution layer for AI agents. Models propose; the runtime validates and executes.

As of v0.8, this package is a thin daemon client: every method proxies to a singleton car-server daemon over WebSocket. Inference, the per-session memory graph, and tool dispatch all live on the daemon side. Start car-server once per host before using the bindings (car-server ships in the same wheel; see "Start the daemon" below).

Pre-built wheels (abi3, Python 3.9+) for:

  • macosx_15_0_arm64 — macOS 15+ on Apple Silicon (Intel Macs dropped — see CHANGELOG)
  • manylinux_2_17_x86_64, manylinux_2_28_aarch64

Building from source on macOS: set MACOSX_DEPLOYMENT_TARGET=15.0 when invoking maturin build. MLX's bundled Metal shaders don't compile against the default 11.0 target, and our release wheels target 15.0 because the compiled extension pulls in libc++ symbols (notably std::exception_ptr::__from_native_exception_pointer) that only exist on macOS 15+. A lower target produces a wheel whose tag doesn't match what the binary actually requires at dlopen time.

Install

From a release wheel (substitute the current version for X.Y.Z):

pip install https://github.com/Parslee-ai/car-releases/releases/download/vX.Y.Z/car_runtime-X.Y.Z-cp39-abi3-macosx_15_0_arm64.whl

Or build from source:

pip install maturin
cd car-rs/crates/car-ffi-pyo3
maturin develop --release

The import name is car_runtime (matching the PyPI package name).

Call the daemon

The same five-line Node example appears in every package landing page and in the Node scaffold so it cannot drift from the agent-facing skill:

async function daemonCallExample() {
// BEGIN CALL_DAEMON_FIVE_LINES
  const { CarRuntime } = (await import('car-runtime')).default;
  const car = new CarRuntime();
  car.registerDaemonHandler('tools.execute', async () => JSON.stringify({ ok: true }));
  const methods = JSON.parse(await car.daemonCall('capabilities.list', '{}'));
  return { car, methods, agents: JSON.parse(await car.agentsList('{}')) };
// END CALL_DAEMON_FIVE_LINES
}

Python uses the equivalent daemon_call, agents_list, and register_daemon_handler names; the complete runnable Python block is in the car-capabilities skill.

Start the daemon

# The car-server binary ships inside the wheel. Default port 9100;
# auth on by default. Foreground (Ctrl-C to stop):
python -m car_runtime.server

# Or background:
python -m car_runtime.server &

# Override the URL the bindings use:
export CAR_DAEMON_URL=ws://127.0.0.1:9100

On macOS the SwiftUI menubar host (CAR Host.app) launches the daemon for you. Install it once from the .pkg installer on the latest GitHub release; from then on it supervises car-server and keeps itself up to date via Sparkle.

Quickstart

import json
from car_runtime import CarRuntime, verify

rt = CarRuntime()   # lazy-connects to ws://127.0.0.1:9100/

# Tools + policies — proxied to the daemon's per-session runtime
# and persist for the lifetime of this CarRuntime's WS connection.
rt.register_tool("shell")
rt.register_policy(
    "no_rm",
    "deny_tool_param",
    target="shell",
    key="command",
    pattern="rm -rf",
)

# Ground with facts (proxied to the daemon's per-session memgine).
rt.add_fact("project_language", "Python", "pattern")

# Static verification — runs on the daemon side, no model needed.
proposal = json.dumps({
    "actions": [{
        "id": "a1",
        "type": "tool_call",
        "tool": "shell",
        "parameters": {"command": "ls"},
        "dependencies": [],
    }],
})

check = json.loads(rt.verify_proposal(proposal))
if not check["valid"]:
    raise RuntimeError(f"invalid proposal: {check['issues']}")

rt.close()  # disconnect() is an alias; a later call reconnects lazily

# For a complete agent cycle, use the packaged helper shown below. It wires
# register_tool_handler + submit_proposal for you.

Packaged agent loop

Do not copy a harness into each agent. Import the versioned loop and keep the project entry file declarative:

from car_runtime.agent_loop import main

main({
    "agent_name": "Lookup Agent",
    "identity": "Use lookup before answering; never guess.",
    "tool_schemas": [{
        "name": "lookup", "description": "Look up one key",
        "parameters": {"type": "object", "properties": {"key": {"type": "string"}},
                       "required": ["key"]},
    }],
    "tools": {"lookup": lambda p: {"key": p["key"], "value": lookup(p["key"])}},
    "policies": [],
    "max_turns": 8,
})

run_agent(config, goal) is also exported for embedding and tests. Put one long-lived runtime in config["runtime"] to reuse its daemon connection across runs; otherwise the loop creates and closes a runtime for each call. The loop registers its tools and policies once per daemon session: when that runtime is closed and reused, or reconnects after a daemon restart (connection_epoch() changes), the next run or serve_chat chat turn registers them again on the new session. serve_chat(config) uses the same option and returns the runtime it serves on. Its AgentOutcome["run_id"] is the durable key accepted by runs_get_trace; it is None when an older daemon has no runs.* surface or did not acknowledge the start. run_chat_turn keeps returning bare text by default; pass include_run_id=True to receive {"text": str, "run_id": str | None}. It registers its tool schemas and config["policies"] on the runtime, so tool-using turns need no earlier register_tool_handler or serve_chat call. The helpers pass their own tool handler to each execute_proposal call, so a handler you registered with register_tool_handler stays in place. main(config) provides --task, --json, and --serve. The loop adds finish, statically verifies every proposal before submit_proposal, preserves tool-call/result IDs, honors per-schema timeoutMs, traces task and chat runs, and uses request-shaped inference with prompt-cache breakpoints. Each inference is recorded before its requested actions with assistant text, normalized call IDs, model id, token usage, and duration; runs_get_trace returns those model turns interleaved with action turns. Recording is best-effort, so an older daemon without the method still runs the agent. Importing car_runtime.agent_loop has no daemon side effect; running it requires car-server. The wheel includes car_runtime/agent_loop.pyi, while the top-level car_runtime.pyi advertises the submodule.

Streaming inference

Streaming is WebSocket-only. Connect to car-server, call the infer_stream JSON-RPC method, and consume inference.stream.event notifications. CarRuntime.infer_stream remains only as an ABI-compatibility stub; it always raises RuntimeError and never invokes its callback. See the streaming cookbook.

Multi-agent coordination

import json
from car_runtime import register_agent_runner, run_swarm

def agent_fn(spec_json: str, task: str) -> str:
    spec = json.loads(spec_json)
    # Call your LLM of choice, returning an AgentOutput JSON.
    return json.dumps({"name": spec["name"], "response": "...", "tool_calls": []})

# Option A: register once, then call run_* without passing agent_fn each time.
register_agent_runner(agent_fn)
result = run_swarm(
    "parallel",
    json.dumps([
        {"name": "researcher", "role": "gather facts", "model": "gpt-5"},
        {"name": "writer",     "role": "compose summary", "model": "claude-opus-4-7"},
    ]),
    "summarize the CAR paper",
)

# Option B: pass agent_fn per call.
result = run_swarm("parallel", agents_json, task, agent_fn=agent_fn)

API surface

The runtime (CarRuntime) exposes:

  • State: state_set, state_get, state_exists, state_snapshot, state_keys
  • Memory: add_fact, query_facts, fact_count, build_context, build_context_fast, persist_memory, load_memory, consolidate
  • Skills: ingest_skill, find_skill, report_outcome, distill_skills, ingest_distilled_skills, list_skills, domains_needing_evolution, repair_skill, evolve_skills
  • Tools + policies: register_tool, register_agent_basics, register_policy, set_replan_config
  • Inference: infer, infer_tracked, infer_tracked_with_request (request-shaped GenerateRequest, including params.strict_model), infer_with_context, infer_with_context_tracked, embed, rerank, classify, prepare_speech_runtime, transcribe, synthesize
  • Models: list_models, pull_model, remove_model, list_models_unified, register_model, route_model, model_stats
  • Execution: event_count, verify_proposal, execute_proposal

Module-level standalone functions:

  • Verification: verify, simulate, optimize, equivalent
  • Stateless execute: execute (creates a fresh Runtime; for long-lived use, prefer CarRuntime.execute_proposal)
  • Multi-agent: register_agent_runner, run_swarm, run_pipeline, run_supervisor, run_map_reduce, run_vote
  • Scheduler: create_task, run_task, run_task_loop, ensure_dream_task
  • Planner: rank_proposals

Compatibility-only method: infer_stream (always raises; use WebSocket).

Structured returns are JSON-encoded strings — json.loads them on the Python side. This keeps the FFI surface stable across binding and protocol changes.

Type stubs

The wheel ships the canonical car_runtime.pyi plus a byte-identical package mirror (car_runtime/__init__.pyi) and package-local py.typed marker (PEP 561). mypy, pyright, Pylance, and similar tools pick up the full native method signatures and the typed agent_loop submodule — no extra install needed.

If you're editing the source tree, update crates/car-ffi-pyo3/car_runtime.pyi and copy it to car_runtime/__init__.pyi. scripts/check-ffi-parity.sh rejects drift between them and continues to check the canonical stub against src/lib.rs. See CLAUDE.md for the FFI-bindings parity rule.

Offline reference docs

The wheel also ships a car_runtime_docs/ directory alongside the compiled extension (find it with python3 -c "import car_runtime, pathlib; print(pathlib.Path(car_runtime.__file__).parent / 'car_runtime_docs')" if your install layout differs) — SPEC.md, GUIDE.md, CLI.md, ASSISTANT.md, MCP.md, agent-ir-spec.md. So an agent with pip install car-runtime and no network access can still read how the car CLI, the flagship assistant's tools, and car-mcp actually work, not just the typed surface above. car_runtime_docs/websocket-protocol.md is a short pointer, not the full reference (~510KB, deliberately not bundled) — read the real thing at https://car.parslee.ai/websocket-protocol.md.

Development

# Install dev deps.
pip install maturin pytest

# Build and install in editable mode.
cd car-rs/crates/car-ffi-pyo3
maturin develop

# Run the smoke tests.
pytest tests/ -v

Architecture

This package is a thin PyO3 client to the singleton car-server daemon over WebSocket — CarRuntime() lazy-connects, every method proxies through the JSON-RPC dispatcher, and the daemon owns inference / memory / tool dispatch / per-session state.

Pre-v0.8 (the RuntimeMode::Embedded path) the wheel hosted an in-process car-engine + car-memgine and ran inference under py.allow_threads(...). That path was retired to close the multi-tenant overcommit hazard CAR-issue #139 was opened for — two FFI consumers in different processes each spawned a fresh admission semaphore + model cache, and concurrent runs could overwhelm the host. v0.8 takes the harder path: one daemon per host, every client attaches.

See the car-releases README for the broader CAR architecture.

License

Free for any use including commercial; free to redistribute unmodified. Modification, reverse engineering, and derivative works are not permitted. See LICENSE for the full text. Copyright © 2026 Parslee AI.

Metadata

Release files for car-runtime 0.59.0.dev20261018

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

Built distributions (wheels)

Table of built distributions (wheels) for car-runtime 0.59.0.dev20261018
File Interpreter ABI Platform
car_runtime-0.59.0.dev20261018-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details
car_runtime-0.59.0.dev20261018-cp39-abi3-manylinux_2_28_x86_64.whl CPython 3.9 abi3 Linux glibc 2.28+ x86-64 Details
car_runtime-0.59.0.dev20261018-cp39-abi3-macosx_15_0_arm64.whl CPython 3.9 abi3 macOS 15.0+ ARM64 Details

Total release size: 119.2 MB

Release files / car_runtime-0.59.0.dev20261018-cp39-abi3-win_amd64.whl

Download URL car_runtime-0.59.0.dev20261018-cp39-abi3-win_amd64.whl
Size 37.8 MB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
30fcdb1bc547d12a22360f9fce1963c5a9cd77c0177afdd4c091899d95e58138
BLAKE2b-256 checksum
How to use checksums
3ecf7f88747858213a164fdcd5455ae8e42270a95547af2d730152e5fda57aa5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.

Transparency log

Release files / car_runtime-0.59.0.dev20261018-cp39-abi3-manylinux_2_28_x86_64.whl

Download URL car_runtime-0.59.0.dev20261018-cp39-abi3-manylinux_2_28_x86_64.whl
Size 47.2 MB
Tags CPython 3.9 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
50fd91e3b0afedce74697f8482b3cd3473564e0af9c929458396afdc934bc8d0
BLAKE2b-256 checksum
How to use checksums
f472061d87af4fddf979daea1cdc7640cb8b8b8a56ef10d7cc151f75d0fdf074
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.

Transparency log

Release files / car_runtime-0.59.0.dev20261018-cp39-abi3-macosx_15_0_arm64.whl

Download URL car_runtime-0.59.0.dev20261018-cp39-abi3-macosx_15_0_arm64.whl
Size 34.2 MB
Tags CPython 3.9 abi3 macOS 15.0+ ARM64
SHA-256 checksum
How to use checksums
355a88a4ac0c349305b3a1eedce3031ff657983989150c1c722fc5084f7575cc
BLAKE2b-256 checksum
How to use checksums
87893efa211a36242f0e89d0ddc173da88bfba950c70b530e546603f433909e7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.

Transparency log

Security for car-runtime 0.59.0.dev20261018

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 3 files in this release have been uploaded with provenance metadata.

Select from 3 files

Attestation for car_runtime-0.59.0.dev20261018-cp39-abi3-win_amd64.whl

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

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