Skip to main content
Pre-release

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

Chassis

CI PyPI Python License Docs

Chassis is a transactional runtime composition layer for dynamic agent systems.

It owns the runtime environment in which agents execute — plugins, capabilities, scoped resources, reversible effects, immutable runtime generations, policy, budgets, secrets, configuration, diagnostics, and observability metadata — and hands an immutable view of that environment to an execution engine.

Composition may change over time; every in-flight run stays pinned to the immutable runtime generation it started with. LangGraph is the first-class execution engine mounted within Chassis. Chassis is not a graph framework.

Install

pip install chassis-harness==1.0.0b2                        # beta core lifecycle kernel
pip install "chassis-harness[langgraph]==1.0.0b2"           # LangGraph adapter
pip install "chassis-harness[langsmith]==1.0.0b2"           # LangSmith telemetry + evaluation
pip install "chassis-harness[opentelemetry]==1.0.0b2"       # OpenTelemetry telemetry adapter
pip install "chassis-harness[langgraph,langsmith,opentelemetry]==1.0.0b2"

Python 3.12 or 3.13. The import package is chassis. These commands select the published beta explicitly; an unqualified install selects the latest stable release, currently 0.9.1.

The core has no dependency on langgraph, langchain-core, or langsmith: importing chassis, the plugin lifecycle, generations, budgets, and diagnostics all work without them. The extras add the LangGraph adapter, the langchain-core test doubles, and the LangSmith backend; using an integration whose extra is missing raises a MissingExtraError that names the extra to install.

Quickstart

from chassis import MODEL, Harness
from chassis.langgraph import AgentDefinition, GraphBuildInputs, LangGraphAgent
from chassis.runtime import HarnessRunContext

harness = Harness(name="quickstart")
harness.provide(MODEL, my_chat_model)                      # a langchain-core chat model
harness.register_agent(
    LangGraphAgent(
        AgentDefinition(name="research-agent", version="1", state_schema=ChatState, build=build_agent),
        checkpointer=InMemorySaver(),
    )
)

async with harness:
    result = await harness.agents.invoke(
        "research-agent", {"messages": [HumanMessage("hi")]}, thread_id="thread-1"
    )
    print(result.text, result.generation_id)        # hello … gen_0001

A run acquires one immutable generation and keeps it: swapping a provider publishes a new generation without mutating the environment underneath an in-flight run.

The LangGraph quickstart needs the adapter extra: pip install "chassis-harness[langgraph]".

Runnable end to end — no credentials, scripted model, asserts its own output:

uv run python examples/quickstart.py

Full walkthrough: docs/getting-started.md.

A plugin in ten lines

from chassis import DATABASE, PluginContext, plugin
from chassis.tools import ToolPolicy

@plugin(name="web-search", version="1.0.0", provides={"tools": "1.0.0"}, requires={"database": ">=1,<2"})
async def web_search(ctx: PluginContext) -> None:
    store = ctx.require(DATABASE)                       # resolved for this composition
    ctx.tools.register(search_tool, policy=ToolPolicy(permissions=("network.fetch",)))
    ctx.create_task(warm_cache(store), name="cache-warmer")

No activation logic, no deregistration calls, no task bookkeeping: the harness orders plugins by declared capabilities, owns every effect through the plugin's scope, and cancels its tasks on unload.

Hierarchical composition scopes

Composition can be a tree, not a list. A scope inherits the providers visible from its ancestors, adds its own, narrows what it exposes, and owns what it declares — and it is still only desired state until a generation is published:

harness.install(postgres, entry_id="postgres")                 # shared, at the root
tier = harness.composition.child("tier-a", capabilities=[MODEL, DATABASE])
research = tier.child("research")
research.install(search, entry_id="search")
research.require(MODEL, ">=1,<2")

async with harness:
    harness.diagnostics.explain_requirement("agent", "database").to_text()
    harness.diagnostics.explain_scope("/tier-a/research").to_dict()
    harness.diagnostics.diff_generations(old_id, new_id).to_text()

Sibling-local composition stays invisible, an ambiguity between a local and an inherited provider stays explicit until a preference resolves it, and a run that acquired a scope tree keeps observing exactly that tree.

Full guide: docs/scopes.md. Runnable: uv run python examples/scoped_composition.py.

Versioned agent composition

A logical agent is described once, versioned, and materialized into the same composition scopes — without Chassis becoming an agent framework:

from chassis.agent_spec import AgentSpec

harness.agents.install(AgentSpec(
    name="finance",
    revision="17",
    runtime_ref="finance-graph",                      # a registered AgentRuntime
    capabilities=["model", "database", "tools"],      # visibility, not authority
    requires={"model": ">=1,<2", "database": ">=1,<2"},
    tools=["spreadsheet"],
    profile="reasoning",
    plugins={"ledger": {}},                           # resolved via the catalog
))

result = await harness.agents.invoke("finance", {"messages": [...]})
assert (result.agent, result.agent_revision) == ("finance", "17")

harness.diagnostics.explain_agent("finance", revision="17").to_text()
harness.diagnostics.diff_agents("finance", "17", "18").to_text()

A revision, once published, is immutable; a run keeps the revision (and generation) it started under even when a newer revision is published; retiring an agent stops new runs without destroying old executions; and unchanged contributions are reused across a revision change by the same semantic-identity machinery everything else uses.

AgentSpec is what composition an agent sees; LangGraph's AgentDefinition stays how a specific engine builds and runs a graph. The core imports without LangGraph.

Full guide: docs/agent-composition.md. Runnable: uv run python examples/agent_composition.py.

The core proposition

Chassis allows agent runtime composition to change over time while active runs retain a coherent environment, dependencies react correctly, resources have explicit ownership, and obsolete components are disposed only when they are no longer reachable.

Guarantees and deliberate absences states what that buys you, and what Chassis refuses to promise.

What Chassis is not

  • not a graph engine — LangGraph owns graph execution and durability;
  • not a replacement for langchain-core models, tools, or runnables;
  • not a replacement for LangSmith tracing or experiment management;
  • not a sandbox — in-process Python plugins are trusted code, and policy is not presented as isolation;
  • not a system that claims deterministic replay of arbitrary clocks, networks, databases, or external services.

Status

Latest published beta: 1.0.0b2, published on 2026-09-24. The latest stable release is 0.9.1; its documentation archive remains available. The surface covered by tests/test_public_api.py is classified and checked against the released 0.8.1 contract and the current b2 candidate (compatibility); every persisted format has a deterministic current fixture under tests/compat/v1.0.0b2/, with b1 fixtures preserved as historical candidate artifacts. migrations lists the 0.9 → 1.0 beta, 0.8 → 0.9, 0.8 → 0.8.1, 0.7 → 0.8, 0.6 → 0.7, 0.5.1 → 0.6, 0.5 → 0.5.1, 0.4 → 0.5, 0.3 → 0.4, 0.2 → 0.3, and 0.1 → 0.2 changes. The release reviews are recorded in 1.0-beta2-readiness.md (published 1.0.0b2 review), 1.0-beta-readiness.md (published 1.0.0b1 review), production-readiness.md (0.9.0), and beta-readiness.md (0.8.0).

Development

Chassis uses uv as its canonical project manager. Python 3.12 or 3.13 is required.

uv sync
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv run pyright
uv build

pyproject.toml and uv.lock are the canonical dependency state. Do not introduce alternative project managers or parallel requirements.txt files.

Releasing

  1. record the change in CHANGELOG.md under a ## [x.y.z] heading;
  2. bump version in pyproject.toml to the same number;
  3. tag and push: git tag vX.Y.Z && git push origin vX.Y.Z.

Prereleases use canonical PEP 440 versions (1.0.0b1) and matching tags (v1.0.0b1). They publish as GitHub prereleases. The documentation homepage follows the published beta; the previous stable documentation is preserved at /0.9.1/.

.github/workflows/release.yml runs the full check suite, then refuses to build unless the tag, the project version, and the changelog agree. It builds and smoke-tests the distribution once through the reusable CI matrix, publishes the same verified bytes through PyPI trusted publishing, creates the GitHub Release with wheel, sdist, SHA-256 digests, and SBOM assets, and deploys documentation only from a stable released tag. A separate manual Docs workflow publishes beta documentation with the stable archive. Release workflow_dispatch runs the complete matrix and assembles the release bundle without publishing.

To refresh the beta documentation after a reviewed main change, run gh workflow run docs.yml --ref main -f deploy=true. The deployment includes the immutable v0.9.1 documentation at /0.9.1/.

Examples

uv run python examples/quickstart.py                  # smallest useful app
uv run python examples/basic_agent.py                 # LangGraph agent end to end
uv run python examples/reactive_cascade.py            # database → memory → extension
uv run python examples/safe_provider_replacement.py   # generations across a provider swap
uv run python examples/scoped_composition.py          # hierarchical composition scopes
uv run python examples/agent_composition.py           # versioned agents: revisions, pinning, reuse

Each example asserts what it prints, so running it verifies the behaviour. The test suite runs all of them.

Documentation

  • Rendered beta documentation
  • examples/production_reference/ — the production reference application: one self-contained support-desk system composing configuration, catalog, scopes, AgentSpec, policy, secrets, invoke and streaming, replay, hot replacement with pinned runs, planning, diagnostics, rollback, and graceful shutdown — executing its own assertions.
  • docs/getting-started.md — install and first run.
  • docs/recipes.md — behind a web service, per-tenant composition, hot provider swaps, budgets, durable runs.
  • docs/troubleshooting.md — symptom, cause, and the exact diagnostics output for each.
  • docs/roadmap.md — the ordered 0.5.1–1.0 audit-remediation, production-confidence, and stable-release plan, with acceptance criteria, release gates, and traceability.
  • docs/migration.md — every compatibility change from 0.1 through 0.8 → 0.9 and how to migrate.
  • docs/agent-composition.md — AgentSpec, immutable agent revisions, materialization, revision pinning, retirement, and agent diagnostics.
  • docs/incremental-composition.md — how composition changes incrementally: semantic identity, impact analysis, structural sharing, reuse diagnostics.
  • docs/ — lifecycle, scoped composition, plugin authoring, LangGraph, observability, security assumptions, replay limitations, configuration, and design guarantees.

Layout

src/chassis/
  core/          scopes, effects, generations, errors
  composition.py composition scopes and resolved scope trees
  agent_spec.py  AgentSpec and AgentRevision (agent composition descriptions)
  agents.py      agent revision registry, materialization, invocation
  capabilities/  versioned contracts, provider registry, snapshots
  plugins/       manifests, author API, resolver, registry
  hooks/         scope-owned hook registry
  tasks/         scope-owned background work
  tools/         tool registry and the execution boundary
  policy/        permissions and the evaluation boundary
  budget/        hierarchical budget governor
  secrets/       providers and redaction
  langgraph/     agent definitions, graph cache, LangGraph runtime
  telemetry/     instrumentation protocol, LangSmith, recording
  persistence/   canonical hashing and runtime snapshots
  replay/        bounded record/replay
  config/        declarative configuration and reconciliation
  testing/       TestHarness and fakes

Contributing

Issues and pull requests are welcome. Start with CONTRIBUTING.md for the gates a change must pass and what a reviewable commit looks like. Questions belong in Discussions; security reports go through private advisories instead of a public issue — see SECURITY.md for what is in scope.

License

Apache-2.0 — see LICENSE.

Metadata

Release files for chassis-harness 1.0.0b2

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

Source distribution (sdist)

Source distribution for chassis-harness 1.0.0b2
File Size Uploaded
chassis_harness-1.0.0b2.tar.gz 651.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for chassis-harness 1.0.0b2
File Interpreter ABI Platform
chassis_harness-1.0.0b2-py3-none-any.whl Python 3 none any Details

Total release size: 888.4 kB

Release files / chassis_harness-1.0.0b2.tar.gz

Download URL chassis_harness-1.0.0b2.tar.gz
Size 651.6 kB
Tags Source
SHA-256 checksum
How to use checksums
175e4f6de90f5f876fda0ee8e210eff0ff9cd86dd4b8c0e51c18cf40f3f667a9
BLAKE2b-256 checksum
How to use checksums
0d78d387a8ed53c9e27585c7f4c7d7f825dee5b64e91d748b6fbf8c15c48157e
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 Sep 24, 2026.

Transparency log

Release files / chassis_harness-1.0.0b2-py3-none-any.whl

Download URL chassis_harness-1.0.0b2-py3-none-any.whl
Size 236.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
abcce26a4c845b213cab70adfcfa41e7f505c46ca41661df8cde58e3605c8e84
BLAKE2b-256 checksum
How to use checksums
23c73c73522f3e68ac5d5ba8b59003b469130feaa326187da25c4aaf5f10ac4f
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 Sep 24, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0b2 This release

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

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