# KOAN

**Knowledge-Oriented Agent Network**

A context graph-native framework for intelligent, grounded, and traceable AI agents.

KOAN connects LLM-powered agents to property graph databases, so every decision an agent makes is recorded as a traceable node in a decision graph. This enables precedent search, policy governance, gap detection, and full audit trails across multi-agent systems.

## Features

- **Unified LLM Client** -- OpenAI and Anthropic with automatic retry, streaming, and cost tracking
- **Structured Output** -- Parse LLM responses into typed Pydantic models
- **Tool System** -- `@tool` decorator with automatic JSON schema generation
- **Agent Orchestration** -- ReAct agents, sequential chains, parallel fan-out, supervisor, and orchestrator patterns
- **Streaming** -- Token-by-token streaming for agents, orchestrators, and SSE endpoints
- **MCP Integration** -- Build and connect to Model Context Protocol servers
- **Context Graphs** -- Trace every agent decision into Neo4j, Memgraph, or FalkorDB
- **Graph-Augmented Reasoning** -- Agents read past decisions, entity history, and policies from the graph before reasoning, then write new traces back (closed loop)
- **Self-Organizing Policies** -- Policies emerge automatically from repeated tool patterns, gate available tools, and retire when feedback turns negative
- **Feedback-Weighted Precedents** -- Past decisions carry feedback scores so agents learn which approaches worked and which didn't
- **Precedent Search** -- Find past decisions for the same entity, with confidence and outcome data
- **Policy Governance** -- Link decisions to policies, detect ungoverned gaps
- **Memory** -- Thread-scoped conversation history (SQLite), vector memory (ChromaDB), forkable threads with checkpoint/rewind (time travel)
- **Observability** -- OpenTelemetry tracing, structured logging, per-call cost tracking
- **CLI** -- `koan verify`, `koan init`, `koan mcp dev`, `koan graph init`

## Install

```bash
pip install koan-ai
```

With LLM providers:

```bash
pip install koan-ai[llm]          # OpenAI + Anthropic
pip install koan-ai[openai]       # OpenAI only
pip install koan-ai[anthropic]    # Anthropic only
```

With context graphs:

```bash
pip install koan-ai[graph-neo4j]     # Neo4j
pip install koan-ai[graph-memgraph]  # Memgraph
pip install koan-ai[graph-falkordb]  # FalkorDB
```

Everything:

```bash
pip install koan-ai[all]
```

> **Note**: The PyPI package is `koan-ai`, but the import name is `koan`:
> ```python
> import koan
> from koan.agents import ReactAgent
> ```

## Quickstart

### 1. Basic LLM Call

```python
import asyncio
from koan.llm.client import LLMClient
from koan.llm.config import LLMConfig
from koan.types import Message

async def main():
    async with LLMClient() as client:
        config = LLMConfig(provider="openai", model="gpt-4o-mini")
        messages = [Message(role="user", content="What is KOAN?")]
        response = await client.complete(config, messages)
        print(response.text)

asyncio.run(main())
```

### 2. Agent with Tools

```python
import asyncio
from koan.agents import AgentConfig, ReactAgent
from koan.llm.client import LLMClient
from koan.tools import ToolRegistry, tool

@tool
def get_weather(city: str) -> str:
    """Get the current weather for a city."""
    return f"22C and sunny in {city}"

async def main():
    async with LLMClient() as client:
        registry = ToolRegistry()
        registry.add(get_weather)

        agent = ReactAgent(
            "weather-bot",
            client=client,
            config=AgentConfig(
                provider="openai",
                model="gpt-4o-mini",
                system_prompt="Use tools to answer questions.",
            ),
            tools=registry,
        )

        result = await agent.run("What's the weather in Tokyo?")
        print(result.output)

asyncio.run(main())
```

### 3. Multi-Agent Orchestrator

```python
from koan.agents import Orchestrator, ReactAgent, RuleRouter

orchestrator = Orchestrator(
    agents={
        "finance": finance_agent,
        "hr": hr_agent,
    },
    router=RuleRouter({
        "stock": "finance", "price": "finance",
        "employee": "hr", "pto": "hr",
    }),
)

result = await orchestrator.run("What is the stock price of AAPL?")
```

### 4. Decision Tracing with Context Graphs

```python
from koan.graph import DecisionTracer, GraphConfig, create_graph_client

config = GraphConfig(provider="falkordb", uri="redis://localhost:6379")

async with create_graph_client(config) as graph:
    async with DecisionTracer(graph, run_id="r-1", agent_id="bot", thread_id="t-1") as tracer:
        decision_id = await tracer.record_decision(
            description="Classified as billing inquiry",
            decision_type="classification",
            confidence=0.95,
            reasoning="Keywords: invoice, payment",
        )
        await tracer.record_action(
            decision_id=decision_id,
            action_type="tool_call",
            tool_name="lookup_billing",
        )
        await tracer.record_outcome(status="success", result="Resolved")
```

### 5. Streaming Agent Events

```python
from koan.agents import StreamingReactAgent, ToolCallStart, TextDelta, AgentComplete

agent = StreamingReactAgent("bot", client=client, config=config, tools=registry)

async for event in agent.run_stream("What is 17 + 28?"):
    if isinstance(event, TextDelta):
        print(event.text, end="", flush=True)
    elif isinstance(event, ToolCallStart):
        print(f"\n[calling {event.tool_name}...]")
    elif isinstance(event, AgentComplete):
        print(f"\nDone ({event.tool_calls_made} tool calls)")
```

## Architecture

```
koan/
├── llm/          # Unified LLM client (OpenAI, Anthropic)
├── output/       # Structured output parsing (Pydantic)
├── prompts/      # Jinja2 prompt templates
├── streaming/    # Token streaming, SSE helpers
├── tools/        # @tool decorator, registry, execution
├── memory/       # Thread store (SQLite), vector memory (ChromaDB)
├── agents/       # ReAct, Chain, Parallel, Orchestrator, Supervisor
├── mcp/          # MCP server builder + client
├── graph/        # Context graphs (Neo4j, Memgraph, FalkorDB)
├── telemetry/    # OpenTelemetry, structured logging, cost tracking
└── cli/          # Developer CLI (verify, init, mcp dev, graph init)
```

### Context Graph Schema

```
Agent -EXECUTED-> Run -CONTAINS-> Decision -LED_TO-> Action
                   |                  |
                   +-PRODUCED-> Outcome  |-GOVERNED_BY-> Policy
                                         |-REFERENCED-> Entity
                                         +-CITED_PRECEDENT-> Decision
```

## Graph Database Setup

Start a graph database with Docker:

```bash
# FalkorDB (Redis protocol)
docker compose -f docker/docker-compose.graph.yml --profile falkordb up -d

# Neo4j (Bolt protocol)
docker compose -f docker/docker-compose.graph.yml --profile neo4j up -d

# Memgraph (Bolt protocol)
docker compose -f docker/docker-compose.graph.yml --profile memgraph up -d
```

## CLI

```bash
koan verify          # Check API keys and installed packages
koan init [path]     # Scaffold a new KOAN project
koan mcp dev <file>  # Run an MCP server in dev mode
koan graph init      # Initialize graph database schema
```

## Examples

See the [examples/](examples/) directory for working demonstrations:

| Example | Description |
|---------|-------------|
| `01_basic_completion.py` | Simplest LLM call |
| `02_structured_output.py` | Pydantic model as output |
| `03_streaming_chat.py` | Token-by-token streaming |
| `04_tool_agent.py` | Agent with custom tools |
| `05_multi_agent.py` | Orchestrator + sub-agents |
| `09_streaming_tool_agent.py` | Streaming agent with tools |
| `10_streaming_orchestrator.py` | Streaming multi-agent |
| `12_supervisor.py` | Supervisor pattern |
| `13_mcp_server_client.py` | MCP server + client |
| `15_supervisor_mcp_agents.py` | Per-agent MCP servers |
| `16_context_graph.py` | Full context graph lifecycle |
| `17_graph_augmented_agent.py` | Graph-augmented agent (closed loop) |
| `18_feedback_and_calibration.py` | Human feedback and confidence calibration |

## Demos

Eight interactive demo apps (FastAPI + browser UI) showcasing KOAN in action:

| Demo | Port | Features |
|------|------|----------|
| **Demo 1** — Simple Chat | 8001 | ReactAgent, tools, SQLite threads, SSE streaming |
| **Demo 2** — Graph Chat | 8002 | GraphAugmentedAgent, feedback, context graph |
| **Demo 3** — Multi-Agent | 8003 | Orchestrator, RuleRouter, 3 agents |
| **Demo 4** — Full Stack | 8004 | Multi-agent + graph, evaluation, calibration |
| **Demo 5** — Self-Organizing | CLI | Full policy lifecycle: emergence → gating → retirement |
| **Demo 6** — Legal Assistant | 8006 | Case lookup, document search, motion drafting |
| **Demo 7** — Medical Triage | 8007 | Patient vitals, labs, medication & allergy checks |
| **Demo 8** — Investment Advisor | 8008 | Portfolio risk, trade execution, market data |

Demos 5-8 demonstrate the self-organizing policy lifecycle across different domains. See [demos/](demos/) for setup instructions and [demos/TEST_QUESTIONS.md](demos/TEST_QUESTIONS.md) for copy-paste test scripts.

## Development

```bash
# Install uv
curl -Ls https://astral.sh/uv/install.sh | sh

# Clone and setup
git clone https://github.com/koan-framework/koan.git
cd koan
uv sync --group dev

# Run tests
uv run pytest                                      # Unit tests (no external deps)
uv run pytest -m integration                       # Integration tests (needs API keys)
uv run pytest -m graph                             # Graph tests (needs Docker)

# Lint and type check
uv run ruff check src/
uv run pyright src/
```

## License

MIT
