Metadata-Version: 2.4
Name: ao-kernel
Version: 4.1.0
Summary: Governed AI orchestration runtime — policy-driven, fail-closed, evidence-trail
Author: Halil Kocoglu
License-Expression: MIT
Project-URL: Homepage, https://github.com/Halildeu/ao-kernel
Project-URL: Repository, https://github.com/Halildeu/ao-kernel
Project-URL: Issues, https://github.com/Halildeu/ao-kernel/issues
Keywords: ai,orchestrator,llm,policy,governance,fail-closed,evidence
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Operating System :: POSIX
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: jsonschema>=4.23.0
Requires-Dist: PyYAML>=6.0
Provides-Extra: llm
Requires-Dist: tenacity>=9.0.0; extra == "llm"
Requires-Dist: tiktoken>=0.9.0; extra == "llm"
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: mypy; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Requires-Dist: mutmut; extra == "dev"
Provides-Extra: otel
Requires-Dist: opentelemetry-api; extra == "otel"
Requires-Dist: opentelemetry-sdk; extra == "otel"
Requires-Dist: opentelemetry-exporter-otlp; extra == "otel"
Provides-Extra: mcp
Requires-Dist: mcp>=1.0.0; extra == "mcp"
Provides-Extra: mcp-http
Requires-Dist: mcp>=1.0.0; extra == "mcp-http"
Requires-Dist: starlette>=0.36.0; extra == "mcp-http"
Requires-Dist: uvicorn>=0.27.0; extra == "mcp-http"
Provides-Extra: pgvector
Requires-Dist: pgvector; extra == "pgvector"
Requires-Dist: psycopg2-binary; extra == "pgvector"
Provides-Extra: metrics
Requires-Dist: prometheus-client>=0.20.0; extra == "metrics"
Provides-Extra: policy-service
Requires-Dist: gunicorn>=22.0.0; extra == "policy-service"
Requires-Dist: PyJWT[crypto]>=2.8.0; extra == "policy-service"
Provides-Extra: release-gate-service
Requires-Dist: gunicorn>=22.0.0; extra == "release-gate-service"
Requires-Dist: PyJWT[crypto]>=2.8.0; extra == "release-gate-service"
Provides-Extra: coding
Requires-Dist: ao-kernel[llm]; extra == "coding"
Provides-Extra: enterprise
Requires-Dist: ao-kernel[mcp,metrics,otel,pgvector]; extra == "enterprise"
Dynamic: license-file

# ao-kernel

Governed AI orchestration runtime — policy-driven, fail-closed, evidence-trail.

ao-kernel is **not** a general-purpose agent framework or a blanket "production coding automation platform" claim. It is a **governed runtime** that enforces policies, records evidence, and provides deterministic LLM routing for production Python teams.

## Installation

```bash
pip install ao-kernel                # Core (only jsonschema dependency)
pip install ao-kernel==4.0.0         # Exact stable pin
pip install ao-kernel[llm]           # LLM modules (tenacity + tiktoken)
pip install ao-kernel[mcp]           # MCP server support
pip install ao-kernel[otel]          # OpenTelemetry instrumentation
pip install ao-kernel[llm,mcp,otel]  # Everything
```

`v4.0.0` is live on PyPI. Post-publish verification confirmed both
`pip install ao-kernel` and `pip install ao-kernel==4.0.0` resolve to
`ao-kernel 4.0.0` in fresh virtual environments.

**For production-grade live LLM calls**, install the `[llm]` extra. Without it the runtime still dispatches requests, but two guarantees weaken: **retry / backoff** (`tenacity`) degrades to a single-attempt call so transient 429 / 5xx responses fail the request instead of being retried, and **exact token counting** (`tiktoken`) falls back to a heuristic estimator (~4 chars/token) so budget accounting is approximate. The core install is fully sufficient for policy evaluation, evidence replay, workflow inspection, and MCP server hosting.

`ao-kernel doctor` surfaces the missing extra via a `tenacity/tiktoken (optional)` check that shows `WARN` when the extra is missing. That WARN is **expected** on the core install and clears once you run `pip install 'ao-kernel[llm]'`. The same command now also prints a bundled extension truth inventory so operators can see which manifests are runtime-backed versus contract-only or quarantined candidates.

Requires Python 3.11+. POSIX-only at the moment (Windows support scheduled for a future major release; see `LockPlatformNotSupported` in `docs/COORDINATION.md`).

## Quick Start

```bash
# Create workspace
ao-kernel init

# Check health
ao-kernel doctor
```

```python
# Library mode (no workspace required)
from ao_kernel.config import load_default
policy = load_default("policies", "policy_autonomy.v1.json")

# LLM routing
from ao_kernel.llm import build_request, normalize_response

request = build_request(
    provider_id="openai",
    model="gpt-4",
    messages=[{"role": "user", "content": "Hello"}],
    base_url="https://api.openai.com/v1/chat/completions",
    api_key="sk-...",
)

# Streaming
from ao_kernel.llm import build_request as build_req

stream_request = build_req(
    provider_id="claude",
    model="claude-sonnet-4-20250514",
    messages=[{"role": "user", "content": "Hello"}],
    base_url="https://api.anthropic.com/v1/messages",
    api_key="sk-ant-...",
    stream=True,
)
```

## CLI Reference

| Command | Description |
|---|---|
| `ao-kernel init` | Create `.ao/` workspace |
| `ao-kernel doctor` | Workspace health check + extension truth audit |
| `ao-kernel migrate [--dry-run] [--backup]` | Version migration |
| `ao-kernel version` | Print version |
| `ao-kernel mcp serve` | Start MCP server (stdio) |
| `ao-kernel evidence timeline --run <id>` | Chronological event timeline (table or `--format json`) |
| `ao-kernel evidence replay --run <id>` | Inferred state trace replay (`--mode inspect\|dry-run`) |
| `ao-kernel evidence generate-manifest --run <id>` | On-demand SHA-256 manifest |
| `ao-kernel evidence verify-manifest --run <id>` | Recompute + verify manifest integrity |

### Quick Demo

```bash
python3 examples/demo_review.py --cleanup
```

Run this from an environment where `ao-kernel` is already installed (wheel, venv, or editable install). The script spins up a disposable workspace and invokes `python -m ao_kernel init` inside that temp checkout.

Runs `review_ai_flow` end-to-end against a disposable workspace (`git init` + `ao-kernel init` + `codex-stub` deterministic adapter, no LLM required). The demo verifies the workflow completes (`workflow_completed` event), the `review_findings` artefact materializes and validates against `review-findings.schema.v1.json`, and the evidence timeline is emitted to `.ao/evidence/workflows/<run_id>/events.jsonl`.

See [`docs/PUBLIC-BETA.md`](docs/PUBLIC-BETA.md) for the support matrix (Shipped / Beta / Deferred / Known Bugs). `bug_fix_flow` (full patch-preview flow) stays on the roadmap — see [`docs/roadmap/DEMO-SCRIPT-SPEC.md`](docs/roadmap/DEMO-SCRIPT-SPEC.md). For the opt-in real-adapter benchmark path, see [`docs/BENCHMARK-FULL-MODE.md`](docs/BENCHMARK-FULL-MODE.md).

### Support Boundary

Treat the repo in three layers:

- **Stable shipped baseline**: entrypoint/version commands, `ao-kernel doctor`, bundled `review_ai_flow` + `codex-stub`, `examples/demo_review.py`, policy command enforcement, wheel-installed packaging smoke, and documented read-only `PRJ-KERNEL-API` actions.
- **Operator / evaluation only**: benchmark docs, real-adapter runbooks, prompt experiment runbooks, and other opt-in validation paths that are intentionally outside the default deterministic CI/demo lane.
- **Contract / reference inventory**: bundled JSON defaults, adapter manifests, registry files, and example code such as `examples/hello-llm/`. Their presence in the tree is useful reference material, not blanket proof that every surface is production-ready end to end. The bundled extension inventory is especially narrow at runtime today: `PRJ-HELLO` is the explicit bootstrap-backed smoke path; the rest of the bundled manifests should be treated as contract inventory unless a support doc says otherwise.

### Operational Docs

- [`docs/SUPPORT-BOUNDARY.md`](docs/SUPPORT-BOUNDARY.md)
- [`docs/OPERATIONS-RUNBOOK.md`](docs/OPERATIONS-RUNBOOK.md)
- [`docs/UPGRADE-NOTES.md`](docs/UPGRADE-NOTES.md)
- [`docs/ROLLBACK.md`](docs/ROLLBACK.md)
- [`docs/KNOWN-BUGS.md`](docs/KNOWN-BUGS.md)

## Python API

### ao_kernel.config

| Function | Description |
|---|---|
| `workspace_root(override=None)` | Resolve workspace (returns `None` in library mode) |
| `load_default(resource_type, filename)` | Load bundled JSON default |
| `load_with_override(resource_type, filename, workspace)` | Workspace override > bundled default |

### ao_kernel.llm

| Function | Description |
|---|---|
| `resolve_route(intent, ...)` | Deterministic LLM routing |
| `build_request(provider_id, model, messages, ...)` | Provider-native HTTP request |
| `normalize_response(resp_bytes, provider_id)` | Extract text + usage + tool_calls |
| `extract_text(resp_bytes)` | Extract text from response |
| `execute_request(url, headers, body_bytes, ...)` | HTTP with retry + circuit breaker |
| `stream_request(url, headers, ...)` | SSE streaming with OK/PARTIAL/FAIL |
| `get_circuit_breaker(provider_id)` | Per-provider circuit breaker |
| `count_tokens(messages, provider_id, model)` | Token counting |

### Supported Providers

| Provider | Streaming | Tool Use | Embedding |
|----------|-----------|----------|-----------|
| Claude | Yes | Yes | No |
| OpenAI | Yes | Yes | Yes |
| Google Gemini | Yes | No | Yes |
| DeepSeek | Yes | Yes | No |
| Qwen | Yes | Yes | No |
| xAI | Yes | Yes | No |

### AoKernelClient — Unified SDK

Full governed pipeline: route → capabilities → context → build → execute → normalize → decisions → eval → telemetry.

```python
from ao_kernel import AoKernelClient

with AoKernelClient(workspace_root=".") as client:
    result = client.llm_call(
        messages=[{"role": "user", "content": "Hello"}],
        intent="FAST_TEXT",
    )
    print(result["text"])
```

## MCP Server

ao-kernel runs as an MCP (Model Context Protocol) server, exposing governance tools:

```bash
ao-kernel mcp serve                          # stdio transport (default)
ao-kernel mcp serve --transport http --port 8080   # HTTP (needs ao-kernel[mcp-http])
```

**Tools:**
- `ao_policy_check` — Validate action against policy (allow/deny)
- `ao_llm_route` — Resolve provider/model for intent
- `ao_llm_call` — Execute governed LLM call (thin executor — see matrix below)
- `ao_quality_gate` — Check output quality
- `ao_workspace_status` — Workspace health
- `ao_memory_read` — Read canonical decisions + workspace facts (policy-gated, fail-closed, read-only)
- `ao_memory_write` — Promote a decision to canonical memory (policy-gated, fail-closed, server-side fixed confidence)

**Resources:**
- `ao://policies/{name}` — Policy JSON
- `ao://schemas/{name}` — Schema JSON
- `ao://registry/{name}` — Registry JSON

### SDK vs MCP — Which one should I use?

`AoKernelClient` (SDK) runs the **full governed pipeline**. `ao_llm_call` (MCP) is a **thin executor** — by design, not a limitation. Pick the surface that matches your trust boundary.

| Stage | `AoKernelClient.llm_call` (SDK) | MCP `ao_llm_call` |
|---|:---:|:---:|
| Route resolution (provider/model) | ✅ | ✅ |
| Capability gap check | ✅ | ✅ (inside build) |
| Context injection (4-lane compile: session/canonical/facts/consultations) | ✅ | ❌ |
| Transport + retry + circuit breaker | ✅ | ✅ |
| Normalize (text/usage/tool_calls) | ✅ | ✅ |
| Decision extraction + memory loop | ✅ | ❌ |
| Evidence trail (JSONL) | ✅ | ❌ |
| Eval scorecard (diagnostic) | ✅ | ❌ |
| Quality gates (policy-enforced) | ✅ (`evaluate_quality`) | ✅ (`ao_quality_gate`) |
| OTEL telemetry | ✅ | ❌ |

**Rule of thumb:**
- **SDK** — your own Python process runs the governed loop. Full context, full audit.
- **MCP** — an external agent (Claude Desktop, Cursor, your own MCP client) delegates a single LLM call through the governance boundary. Context, memory, and telemetry stay in the caller's process, not in the server.

Mixing is fine: an MCP client can call `ao_policy_check` and `ao_quality_gate` for governance decisions, run its own LLM, and call back for `ao_workspace_status`. The server stays thin on purpose.

## Context Management

Governed context loop — decisions extracted, scored, and injected automatically.

```python
from ao_kernel.context import start_session, process_turn, compile_context, end_session

# Start session
ctx = start_session(workspace_root=".", session_id="my-session")

# After each LLM turn — automatic extraction + compaction
ctx = process_turn(llm_output, ctx, workspace_root=".", request_id="req-1")

# Compile context for next LLM call (relevance-scored, budget-aware)
compiled = compile_context(ctx, profile="TASK_EXECUTION", max_tokens=4000)
# compiled.preamble → inject into system prompt

# End session — compact + distill + promote
end_session(ctx, workspace_root=".")
```

**SDK Hooks (multi-agent):**
```python
from ao_kernel.context.agent_coordination import record_decision, query_memory

record_decision(ws, key="arch.pattern", value="microservices", confidence=0.9)
items = query_memory(ws, key_pattern="arch.*")
```

**Profiles:** STARTUP (minimal), TASK_EXECUTION (full), REVIEW (quality focus)

## What Makes ao-kernel Different

| | ao-kernel | LangGraph | CrewAI | Pydantic AI |
|---|---|---|---|---|
| Policy engine | 100+ policy files | No | No | No |
| Fail-closed | Yes | No | No | No |
| Evidence trail | Self-hosted JSONL | LangSmith SaaS | No | No |
| Migration CLI | Yes | No | No | No |
| Doctor | Yes | No | No | No |
| MCP server | Yes | No | No | No |
| Streaming | SSE (6 providers) | Yes | Yes | Yes |

> Counts as of `v3.13.0`: `ao_kernel/defaults/` ships **377** bundled JSON files — 106 policies + 231 schemas + 19 extensions + 9 registry + 4 workflows + 3 operations + 3 adapters + 1 catalogs + 1 intent_rules. Run `find ao_kernel/defaults -name '*.json' | wc -l` for the live number. This is an inventory count, not a support-matrix count; use [`docs/PUBLIC-BETA.md`](docs/PUBLIC-BETA.md) for what is actually supported.

## Architecture

```
ao_kernel/              <- Public facade (clean API)
  client.py             <- AoKernelClient — unified SDK
  llm.py                <- LLM routing, building, normalization
  governance.py         <- Policy SSOT (4 policy types, fail-closed)
  mcp_server.py         <- MCP server (7 tools, 3 resources)
  context/              <- Context pipeline (compile, inject, extract, promote)
  _internal/            <- Private implementation (do not import directly)
  defaults/             <- 377 bundled JSON (policies, schemas, registry, extensions, operations, adapters, workflows, catalogs, intent_rules)
```

## Development

```bash
pip install -e ".[dev,llm,mcp]"          # Dev environment
pytest tests/ -x                          # Run tests
ruff check ao_kernel/ tests/              # Lint
mypy ao_kernel/ --ignore-missing-imports  # Type check
```

Coverage target: 70% branch coverage (excluding `_internal`).

## License

MIT
