Skip to main content

kntgraph

A pure, event-sourced agent framework over Redis Streams.

Quality gates

The badges below mirror the nine gates in scripts/ci.py — the single source of truth for the project's quality bar. Each badge is a Shields.io static image; the values are pinned in docs/quality.md (auto-generated by scripts/quality_report.py).

Code quality

cc mi pyright pypi Version

Tests

coverage tests

Security

security audit

The current value of each badge is generated locally by scripts/quality_report.py; the script reads each gate's output and updates docs/quality.md on every CI run. Keep the snapshot in sync with this block when you remove badges or change the gate count.

A full breakdown of the current technical debt is in DEBT.md. All pyright errors are resolved (0 errors / 1043 warnings; the warning budget is tracked separately under §4.2 and is out of scope for the strict error budget).

kntgraph is the renamed and unified successor of two internal packages (formerly fmh_backend and fmh_agents). It provides the core abstractions needed to build autonomous, replayable agents:

  • Pure ECS — World is a deterministic function of events.
  • Event Sourcing — Redis Streams is the single source of truth.
  • Idempotency — replay produces the same World; idempotency_key on Tool makes at-least-once delivery into at-most-once side effects.
  • Dual lifecycle — operational (framework) and domain (application) lifecycles are orthogonal; the same World carries both views.
  • Resilience — circuit breaker, retry, bulkhead, timeout, fallback, and a Dead Letter Queue for failed events.
  • Durable checkpoints — the ReactiveDispatcher commits a Redis checkpoint after the batch's emitted events are durably appended to the EventLog, so a crash between append and save replays the same events on restart (idempotency window).
  • Solution tier (ADR-010) — tool-call re-use: when a tool call succeeds for a given (problem, params) pair across multiple agents, the framework promotes the call into a reusable Solution node in FalkorDB, with per-tenant allow-list and man-in-the-loop review.
  • Semantic routing (ADR-013) — opt-in GLiNER2 intent classification and argument extraction in the agents sub-module.

Install

Install from PyPI:

uv add kntgraph

The version is the git tag (v0.11.0 → 0.11.0), discoverable on PyPI:

pip show kntgraph
# Version: 0.11.0
# License: Apache-2.0

Optional extras (install only what you need):

uv add "kntgraph[cli]"          # CLI Boilerplate Generator (ADR-038)
uv add "kntgraph[falkordb]"     # graph projection + Cypher
uv add "kntgraph[ollama]"       # local LLM / embeddings
uv add "kntgraph[gliner]"       # NER-based 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), pin to the GitHub repo: uv add "kntgraph @ git+https://github.com/kinetgraph/kinetgraph.git". The tagged releases on PyPI are the canonical, supported install 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``.

Run the tests

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

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

CLI Boilerplate Generator

Kinetgraph provides a first-party CLI (knt) to scaffold complete, ADR-compliant Modular Monoliths and Contexts.

Install the framework with the [cli] extra and initialize a new project:

# 1. Install Kinetgraph with the CLI extra globally or in your venv
uv add "kntgraph[cli]"

# 2. Scaffold a new application with the HTTP Gateway included
knt init project my_platform --use-intent-http

# or generate an intent-routing scaffold with an explicit mode
knt init project my_platform --routing-mode external
# supported values: external, autonomous, collaborate
# external: routes intents from outside the agent boundary
# autonomous: lets the agent resolve intents internally
# collaborate: coordinates multiple agents or roles for a shared intent

# 3. Enter the project and scaffold domain contexts
cd my_platform
knt new context weather
knt new system weather.WeatherRouter
knt new tool weather.OpenMeteoApi

For a comprehensive walkthrough on building an application from scratch using the CLI, refer to the CLI Guide.

Architecture

kntgraph/
├── src/kntgraph/
│   ├── core/        # Pure: ECS, Event, World, System
│   ├── stream/      # Redis Streams (EventLog, fold)
│   ├── runner/      # Side effects (Runner, ReactiveDispatcher)
│   ├── events/      # Dead Letter Queue
│   ├── resilience/  # Circuit breaker, retry, bulkhead, etc.
│   ├── infra/       # Config, Redis pool, hashing
│   ├── tools/       # Tool Protocol, registry, worker
│   ├── api/         # Optional HTTP gateway
│   ├── security/    # Ed25519 signing, principal, ACL
│   └── agents/      # LLM/cache/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
├── 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. Highlights:

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)

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 (ADR-049).
  • API Reference — the public API map, env-var table, and common patterns.
  • CLI Guide — walkthrough on scaffolding projects, contexts, systems, tools, and agents with the CLI.
  • docs/ — full index of the docs.
  • ADRs — Architecture Decision Records.

ADRs Accepted in v0.8.0 / v0.9.0 (closed in this cycle)

ADR Título Status
ADR-042 Memory Model Exposure in ECS Pattern (Systems vs. Tools) and CLI Support Accepted (Implemented; CLI follow-up outstanding)
ADR-043 LiteLLM worker migration + ToolInvoker deprecation Accepted (Implemented; surpassed removal target)
ADR-044 Tool-call Overlay Accumulation (slot persistence across ticks) Accepted (Implemented)
ADR-046 CLI Scaffold for Intent Routing Modes Accepted (Implemented)
ADR-047 Standardizing Tool Construction via Adapters Draft (sync ToolWorker stable; §6 follow-ups open)

ADRs Accepted in v0.10.0 / v0.11.0 (closed in this cycle)

ADR Título Status
ADR-050 CLI command consistency (sub-Typer, Typer Enum, template helper) Accepted (v0.10.0)
ADR-051 Release versioning via git tags + setuptools_scm Accepted (v0.10.0)
ADR-052 PyPI publishing via Trusted Publishing (PEP 740) Accepted (v0.11.0; first PyPI release cut via the two-workflow flow: release.yml then publish.yml)
ADR-053 CLI Boilerplate Generation v2 (in-template rendering, knt upgrade workflow) Accepted (v0.11.0; 23-test render suite enforces the framework's symbol contracts; the knt upgrade check mode is the CI-quality drift detector)

ADRs Proposed in discussion

ADR Título Status
ADR-035 Sharding and Dispatcher Coordination for Horizontal Scaling Proposed (Under Review)
ADR-040 Messaging Adapter for Intent Ingestion Proposed (Under Discussion)
ADR-048 Observability Dashboard and Control Panel API Proposed
ADR-049 Zero Token Architecture support (RuleBasedChatSystem + SolutionLookupSystem) Proposed (items 3 + 4 shipped in v0.10.0; Redis adapter shipped; FalkorDB adapter §6 still pending)

Design evaluations (decisions not to migrate). ADR-054 records the evaluation of executor and transport alternatives for the WorkerManager and confirms the current design: ProcessPoolExecutor as the function executor, Redis Streams as the per-tool queue. The realistic local alternatives (ThreadPoolExecutor, pure asyncio, external subprocess JSON-lines workers) are listed in ADR-054 §3.2 with the criteria that would justify a future revisit (ADR-054 §3.3).

Project status

  • 0.11.0 — first PyPI release. Shipping pip install kntgraph as the canonical install path (ADR-052). The release process is now two workflows: release.yml cuts the git tag
    • opens the GitHub Release; publish.yml builds the wheel from the tag and uploads to PyPI via Trusted Publishing (PEP 740). The pypi GitHub Environment is the human-in- the-loop gate. The publish workflow also enforces a git ls-remote pre-check (the tag must exist on the remote before the checkout can fool setuptools_scm into a misleading 0.0.0 derivation) and a git config step in release.yml resolves the empty ident name failure from the GitHub Actions runner. pyproject.toml now declares PEP 639 license = "Apache-2.0" (the License :: OSI Approved :: Apache Software License classifier is rejected by setuptools ≥ 77 when the license = field is set) plus 11 canonical PyPI classifiers; [build-system] ::requires is bumped to setuptools>=77 to make the PEP 639 floor explicit. 16 contract tests in tests/scripts/test_workflow_split.py enforce the split. The PyPI project page is live at https://pypi.org/project/kntgraph/ (license Apache-2.0, version 0.11.0). Operator runbook at docs/pypi_publishing_runbook.md.
  • 0.10.0 — breaking: removes the _legacy_principal fallback in the API key verifier (ADR-017 §7.3). Plain-string bindings (pre-ADR-017) are now rejected as AuthError(kind="malformed", ...). Operators with legacy bindings MUST run scripts/migrate_principals.py --apply before upgrading (the script is idempotent and safe to dry-run). The KNT_AUTH_MODE flag that ADR-017 §2.4 promised was never implemented; the wire-format detection in RedisAPIKeyVerifier is the only path that distinguished JSON from legacy, and that path is now closed. Adds Zero Token Architecture support (ADR-049): RuleBasedChatSystem short-circuits user.intent events with deterministic replies and SolutionLookupSystem synthesises cached tool.<name>.completed events. The lookup system ships with two SolutionStoreLike adapters: InMemorySolutionStore (tests / 09b example) and RedisSolutionStore (production; one Hash per tool with the canonical knt:solution:<tool_name> layout). Also fixes the dispatcher's drain contract so a synthetic completion queued by run_pending_lookups actually lands in the EventLog on the next tick. See docs/zta.md, examples/09b_solution_lookup_zta.py (in-memory) and examples/09c_solution_lookup_zta_redis.py (Redis). Also adds release versioning via git tags (ADR-051): the project version is now derived from the git tag by setuptools_scm (no more pyproject.toml::version); the new CI gates check_version and bump_dry_run catch drift before a release ships; the CONTRIBUTING.md::Release checklist is the 6-step ritual for cutting a release. Retroactive tags for v0.7.0, v0.8.0, v0.10.0 are pushed so git log v0.8.0..v0.10.0 and uv sync work today. PyPI publishing is deferred to ADR-052.
  • 0.9.0 — predecessor release. Drops the legacy LiteLLMTool / ToolInvoker / kntgraph.agents.roles paths (the canonical path is LiteLLMToolWorker + the WorkerManager, and the role_systems ECS-shaped counterparts). Adds the HttpClientLike Protocol and the HttpxHttpClientAdapter for HTTP-bound ToolWorkers (ADR-047). CLI tests ship a conftest.py for the optional [cli] extra (DEBT §2.25). CC refactor of 10 functions over the CC=10 ceiling (DEBT §2.26); the gate_complexity in scripts/ci.py now flags new CC offenders that bypass the previous baseline-only check. Pyright errors down from 68 → 51 (17-error delta).
  • 0.7.0 — public release under the kntgraph package name. Backwards-incompatible with the old fmh_backend / fmh_agents imports; the source is structurally the same (same modules, same tests).
  • 0.6.x — internal releases under the fmh_* package names (no longer distributed).

License

Apache License 2.0. See LICENSE.

Contributing

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

Project metrics

Source modules Test modules ADRs Docs
243 (39,199 LOC) 190 (42,076 LOC, 1,968 tests collected) 51 24 pages

Release files for kntgraph 0.11.1

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.11.1
File Interpreter ABI Platform
kntgraph-0.11.1-py3-none-any.whl Python 3 none any Details

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

Download URL kntgraph-0.11.1-py3-none-any.whl
Size 540.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c9176c108889012c14acb32bfa999fb90464f080dc71a96e4d783461c015ddbf
BLAKE2b-256 checksum
How to use checksums
9e98d63d72665c3cf08d75287e6bf022a07ea14e363ee32ff16282629d2f8138
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 Aug 5, 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

0.14.2

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

This release

0.11.1 This release

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