Concept · Dependency layering

The dependency graph is the architecture.

KAOS is eighteen Python packages with a strict ordering. The runtime-and-protocol package sits at the bottom. The document model imports from it. Extractors import from the document model. Language-model programs sit higher; the agent runtime sits higher still. Lower packages never import upper ones, and two packages at the same level (the PDF parser and the Office-document parser, for example) never import each other. Composability is enforced by the import graph itself, not by a note in a contributing guide.

The rules

  • Lower layers do not know about upper layers. The core package never imports from the document model; the document model never imports from extractors. Dependency runs in one direction.
  • Two packages at the same layer do not import each other. The PDF parser and the Office-document parser share no Python imports. They share a contract (both produce the same typed document tree) and a registry (both register their tools into the same runtime). They do not share code.
  • Optional dependencies use Python's optional-extras convention. kaos-pdf[ocr] pulls in Tesseract; kaos-pdf[tables] pulls in pdfplumber; kaos-pdf[vision] pulls in the language-model client package. The base install never carries an optional dependency.
  • One extra is universal. Any package that registers tools ships an [mcp] extra that pulls in the MCP bridge package and the FastMCP runtime. Without it, the package is library-only; with it, the same package also serves its tools over the wire.

The layers, drawn out

Reading top-down: each layer depends on the layers below it; nothing depends on anything above. The base is the smallest install footprint; the top is the richest behavior.

ABSTRACTION Recipes + agentic workflows kaos-agents recipes; user-authored plans Agent runtime kaos-agents Runner + 15-section memory LLM programs kaos-llm-core — Signatures · Programs · optimizers LLM transport kaos-llm-client — 7 providers, async-first Extraction + sources kaos-pdf · kaos-web · kaos-office · kaos-tabular · kaos-source Document AST kaos-content — typed ContentDocument with provenance Runtime + protocol kaos-core — KaosTool, KaosRuntime, VFS, ArtifactStore

What this forbids

The PDF parser cannot import from the Office-document parser. If both need a shared helper, the helper goes in the document-model package they both already depend on. If it doesn't fit there, it goes in a brand-new package below them both. Ad-hoc cross-sibling imports are how a polyrepo grows back into a monolith.

The language-model program package cannot import from the agent runtime. The agent runtime depends on the program layer below it, but the program layer does not know it is being driven inside an agent. That direction means a developer can write a typed language-model program standalone, outside any agent loop, and the test surface stays small.

The core package imports nothing from any other KAOS package. It defines the contracts; everything else implements against them. That is how eighteen packages stay an ordered list instead of growing back into a tangle.

Adding a new package

Decide which layer the new package sits in, then write its pyproject.toml with dependencies from that layer or below — never above. The rule makes this mechanical.

kaos-mymodule/pyproject.toml
# kaos-mymodule/pyproject.toml — for an extraction-tier module
[project]
name = "kaos-mymodule"
dependencies = [
"kaos-core>=0.1.0", # OK — lower layer
"kaos-content>=0.1.0", # OK — lower layer
]
[project.optional-dependencies]
mcp = ["kaos-mcp>=0.1.0"] # OK — universal
nlp = ["kaos-nlp-core>=0.1.0"] # OK — primitives layer
# NOT ALLOWED: depending on a sibling extraction package
# dependencies = ["kaos-pdf>=0.1.0"] # ← layering violation
# NOT ALLOWED: depending on a higher layer
# dependencies = ["kaos-agents>=0.1.0"] # ← layering violation

Read next

The runtime page covers the bottom layers (the core protocol, the document model, the MCP bridge) in depth. The packages index lists every module sized by tool count. The full dependency graph is on the learn-kaos architecture page.

On learn-kaos: architecture.