Skip to main content

kinetgraph

A pure, event-sourced ECS framework for building autonomous agents over Redis Streams.

The framework models agent state as a deterministic fold over an immutable event log. Side effects (LLM calls, HTTP requests, tool execution) run outside the fold, in isolated workers. The result is an agent whose entire history is replayable, whose state is a pure function of events, and whose tool calls are at-most-once even under at-least-once delivery.

When to use

  • You need agents whose decisions are auditable and replayable from first principles.
  • You want to run LLM calls in process-pool workers so the event loop never blocks.
  • You need idempotent tool execution across retries and dispatcher restarts.
  • You want a single Redis Stream as the source of truth, with no separate state DB.
  • You are building multi-tenant systems where each agent has its own isolated event log.

Install

uv add kntgraph

Optional extras (install only what you need):

uv add "kntgraph[cli]"          # knt scaffold CLI
uv add "kntgraph[falkordb]"     # graph projection + Cypher (FalkorDB)
uv add "kntgraph[ollama]"       # local LLM / embeddings
uv add "kntgraph[gliner]"       # GLiNER2 NER — intent routing and PII redaction
uv add "kntgraph[api]"          # HTTP gateway (FastAPI)
uv add "kntgraph[crypto]"       # Ed25519 event signing
uv add "kntgraph[llm]"          # LiteLLM adapter
uv add "kntgraph[all-runtime]"  # everything above

To install the unreleased main between tagged releases: uv add "kntgraph @ git+https://github.com/kinetgraph/kinetgraph.git". Tagged releases on PyPI are the canonical, supported path.

Hello world

import asyncio
from kntgraph.core.event import Event
from kntgraph.core.world import World


async def main() -> None:
    e1 = Event.create(
        event_type="agent.spawned",
        agent_id="a-1",
        event_class="lifecycle",
    )
    e2 = Event.create(
        event_type="document.received",
        agent_id="a-1",
        event_class="domain",
        data={"doc_id": "NF-001"},
    )
    world = World.fold([e1, e2], tick=2)
    print(world.agents["a-1"].operational_phase)  # "spawned"
    print(world.agents["a-1"].domain_phase)       # "document.received"


asyncio.run(main())

The agents sub-module ships concrete LLM, cache, and PII adapters on top of the framework:

from kntgraph.agents.tools import LiteLLMToolWorker

worker = LiteLLMToolWorker()
result = await worker.invoke(
    system="You are a helpful assistant.",
    user="What is the capital of France?",
    idempotency_key="k1",
)
# ``result`` is a ``Result[dict, ToolError]``; the dict
# envelope carries ``text`` / ``model`` / ``usage`` /
# ``finish_reason`` / ``cost_usd`` / ``latency_ms``.

What the framework provides

Capability How it works
Replayable state World is a pure fold over the EventLog. Re-fold from event 0 to reproduce any past state exactly.
At-most-once tools idempotency_key on every tool call deduplicates side effects across retries and restarts.
Non-blocking LLM Workers run in a ProcessPoolExecutor; the async event loop is never blocked by an LLM call.
Three-gate authorisation Role persona (gate 2) → per-tool ACL in WorkerManager (gate 1) → worker-level check (gate 3).
Resilience primitives Circuit breaker, retry, bulkhead, timeout, fallback, and a Dead Letter Queue — all composable.
Durable checkpoints ReactiveDispatcher commits a Redis checkpoint after emitted events are durably appended, so a crash replays the same batch on restart.
Domain memory Fold domain events into frozen ECS @dataclass components attached to the World entity (no volatile sliding window required).
Zero-Token Architecture RuleBasedChatSystem short-circuits deterministic intents; SolutionLookupSystem synthesises cached completions before calling the LLM.
Semantic routing Opt-in GLiNER2 intent classification and argument extraction in the agents sub-module.
Solution tier Successful tool calls are promoted to reusable Solution nodes in FalkorDB, with per-tenant allow-list and human-in-the-loop review.

CLI scaffold

knt is the first-party CLI for scaffolding ADR-compliant projects and contexts:

# Install with the [cli] extra
uv add "kntgraph[cli]"

# Scaffold a new application
knt init project my_platform --use-intent-http

# Or choose a routing mode explicitly
knt init project my_platform --routing-mode external
# external   — routes intents from outside the agent boundary
# autonomous — agent resolves intents internally
# collaborate — multiple agents coordinate on a shared intent

# Add domain contexts and systems
cd my_platform
knt new context weather
knt new system weather.WeatherRouter
knt new tool weather.OpenMeteoApi

# Check for framework drift in boilerplate
knt upgrade check

See the CLI Guide for a full walkthrough.

Architecture

kntgraph/
├── src/kntgraph/
│   ├── core/        # Pure: ECS, Event, World, System
│   ├── stream/      # Redis Streams (EventLog, fold)
│   ├── runner/      # Side effects (Runner, ReactiveDispatcher,
│   │                #   WorldProjection, MemoryHydrationProjection,
│   │                #   ToolCallTTLSweeperSystem)
│   ├── events/      # Dead Letter Queue
│   ├── resilience/  # Circuit breaker, retry, bulkhead, etc.
│   ├── infra/       # Config, Redis pool, hashing
│   ├── tools/       # Tool Protocol, WorkerManager, worker, ACL
│   ├── api/         # Optional HTTP gateway
│   ├── security/    # Ed25519 signing, principal, ACL, PrincipalLevel
│   ├── memory/      # Session, Profile, Continuity managers
│   ├── knowledge/   # Embedding, FalkorDB graph, GraphRAG, GLiNER2
│   ├── testing/     # Public test utilities (fakes, stubs)
│   ├── cli/         # knt CLI — scaffold generator
│   └── agents/      # LLM/PII adapters, role_systems
│       ├── role_systems/ # ChatRoleSystem, PlannerRoleSystem, etc.
│       ├── tools/   # LiteLLMToolWorker, PiiRedactionTool
│       └── memory/  # Solution extractor/promoter
├── tests/
│   ├── unit/        # No external dependencies
│   ├── integration/ # Real Redis required
│   ├── agents/      # agents sub-module tests
│   ├── stress/      # 5 agents × 3 tools × 5 s concurrent load
│   └── scripts/     # CI contract tests (workflow split, etc.)
├── ADRs/            # Architecture Decision Records
├── docs/            # Public documentation
└── examples/        # Runnable end-to-end examples

Configuration

All settings live under the KNT_ env-var prefix and are loaded via Pydantic v2 BaseSettings. The canonical schema is Settings in kntgraph.infra.config.

Env var Default
KNT_REDIS_URL redis://localhost:6379
KNT_FALKORDB_HOST localhost
KNT_FALKORDB_PORT 16379
KNT_STREAM_MAXLEN 100_000
KNT_TICK_INTERVAL 1.0 (seconds)
KNT_ENV dev (set to prod in deploy)

Run the tests

# Unit (fast, no Redis required)
uv run pytest tests/unit/

# Integration (requires Redis on localhost:6379)
uv run pytest tests/integration/

# Agents sub-module tests
uv run pytest tests/agents/

# Stress suite (requires Redis on localhost:6379)
uv run pytest tests/stress/

# CI contract tests
uv run pytest tests/scripts/

Documentation

  • Getting Started — mental model and your first agent.
  • Quick Start — 5-minute install and "hello world".
  • Architecture — the three pillars (ECS, event sourcing, resilience) and how the pieces fit together.
  • Zero Token Architecture — software handlers before LLM, read-side cache, hybrid dispatcher stack.
  • API Reference — the public API map, env-var table, and common patterns.
  • CLI Guide — scaffolding projects, contexts, systems, tools, and agents.
  • docs/ — full index of all docs.
  • ADRs/ — Architecture Decision Records.

Quality gates

The badges below mirror the gates in scripts/ci.py. Values are generated by scripts/quality_report.py on every CI run and pinned in docs/quality.md.

Code quality

cc mi pyright Version pypi

Tests

coverage tests

Security

security audit

Pyright: 0 errors above the baseline (870 warnings tracked separately; see DEBT.md §4.2 for the warning budget).

Project status

Version Highlights
0.14.1 (current) Reliability fixes on top of the Three-Gate Model cycle.
0.14.0 Three-Gate authorisation (RoleComponent + WorkerManager ACL + worker-level). PrincipalLevel replaces the legacy Role enum. Pluggable WorldProjection on ReactiveDispatcher. ToolRegistry deprecated in favour of WorkerManager. Fixes CorrelationContext binding inside dispatcher ticks.
0.13.0 Domain Memory via ECS Components (ADR-059). Data durability strategy and disaster recovery (ADR-057, ADR-058).
0.12.1 Reliability fixes, worker invocation module.
0.11.0 First PyPI release (pip install kntgraph). Two-workflow publish flow with Trusted Publishing (PEP 740). CLI Boilerplate Generation v2 with knt upgrade.
0.10.0 Zero Token Architecture (RuleBasedChatSystem, SolutionLookupSystem). Removes legacy _legacy_principal fallback (breaking — run scripts/migrate_principals.py before upgrading).
0.9.0 Drops deprecated LiteLLMTool / ToolInvoker / kntgraph.agents.roles. ECS role systems (ChatRoleSystem, PlannerRoleSystem, etc.).
0.7.0 Public release under the kntgraph package name.

Full changelog: CHANGELOG.md.

License

Apache License 2.0. See LICENSE.

Contributing

See CONTRIBUTING.md for development setup, the CI gate, and the pull request workflow. Bug reports and security disclosures follow SECURITY.md.

Project metrics

Source modules Test modules ADRs Docs
250 214 (2,305 tests collected) 62 27 pages

Release files for kntgraph 0.14.2

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

Built distribution (wheel)

Table of built distributions (wheels) for kntgraph 0.14.2
File Interpreter ABI Platform
kntgraph-0.14.2-py3-none-any.whl Python 3 none any Details

Release files / kntgraph-0.14.2-py3-none-any.whl

Download URL kntgraph-0.14.2-py3-none-any.whl
Size 565.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3cff2425153ca103c993d6440d547896e2bca0d42632d20e89aa732500a53b8c
BLAKE2b-256 checksum
How to use checksums
63ed66365500dd000a703c8cc0dde87bcd65a17ba0bd6ab11c16529ee0d9e7ed
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 1, 2026.

Transparency log

Release history Release notifications | RSS feed

0.16.0

1 release file

0.15.3

1 release file

0.15.2

1 release file

0.15.1

1 release file

0.15.0

1 release file

This release

0.14.2 This release

1 release file

0.14.1

1 release file

0.14.0

1 release file

0.13.0

1 release file

0.12.1

1 release file

0.11.2

1 release file

0.11.1

1 release file

0.11.0

1 release file

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