Skip to main content

cairnkit

CI License: MIT Python 3.12+

A small agent runtime for business applications. Give an agent useful tools while keeping identity, permissions and persistence in your application. Use proposal tools and a host-controlled review step when a person should decide what gets saved.

A cairn is a pile of stones that marks a trail so the next walker can follow it. cairnkit does the same for agents: approved memory, searchable history and curated skills that the next conversation builds on.

中文说明

See the approval boundary

A fictional support ticket asks to change an invoice email. The agent reads it and creates a draft. The saved record changes only after the host's reviewer approves it. Rejecting the draft leaves the record untouched.

Five steps: source ticket, read, pending draft, human review, host save

Watch the 35-second walkthrough · Run the example and choose approve or reject

git clone https://github.com/wasabihu/cairnkit.git
cd cairnkit
uv run python examples/approval.py

Offline, fictional data, no API key. The model uses predetermined ScriptedModel responses. The video replays snapshots from a real execution of that example, including a scripted approval choice. It demonstrates the host integration, not model quality. The in-memory review function is example application code, not a built-in approval service.

Why another agent runtime

In a business application, several people may share records, each with different roles. The application needs to retain control over which tools an agent can use and when a proposed change becomes a saved record. cairnkit provides building blocks for that:

  • Identity comes from the host, never from the model. Tools receive the signed-in person, their roles and the record being worked on in a ToolContext.
  • Make changes reviewable. Tools declare an access level (read, propose, write) and allowed roles. Your proposal handler creates drafts; your application implements approval and persistence. The access label alone does not enforce human review.
  • Memory with guard rails. Add / patch / remove edits located by quoted text, size limits, prompt-injection scanning and frozen snapshots, ported from Hermes Agent.
  • Compact long conversations. A port of Hermes Agent's context compression: incremental structured summaries, real token anchors, cooldowns and verbatim user quotes.
  • Small. The core depends only on the standard library and httpx. No web framework, no database, no vector store: storage and permissions stay in your application.

What is inside

Area Module What it does
Agent loop loop.py Model → tools → model, streaming, a forced plain answer when the step budget runs out
Tools tools.py Schema, handler, access level, allowed roles; identity is injected, never taken from the model
Loop protection guardrails.py Warns or stops on repeated failing calls and identical results
System prompt prompt.py Stable / context / volatile layers, assembled once per conversation for prompt caching
Memory memory.py, memory_ops.py Hermes' add / patch / remove rules; your store decides whether changes need approval
History search search.py One tool, four modes (search, read, context, browse); no model calls
Skills skills.py SKILL.md folders, shown on demand, scanned for injection when loaded
Context compression compression.py Four-phase compaction with incremental summaries and per-conversation CompressionState
Background review review.py After a turn, a forked agent decides whether anything should be remembered
Delegation delegate.py Hand a focused task to a specialist agent and get back only its answer (one level deep)
Skill curation curator.py Marks unused skills stale, suggests archives and merges; returns a plan, you decide
Injection scanning security.py Prompt injection, hidden characters and exfiltration patterns
Titles titles.py Instant title, upgraded by a small model; never overrides a title the user typed
Models llm/ OpenAI-compatible client (streaming), OpenRouter, error classification, fallback chain, offline scripted model
Cost pricing.py Uses the provider's reported cost, otherwise a price table
Agent definitions agents.py One folder per agent: agent.toml + SOUL.md
Documents (optional) documents.py PDF, Word, Excel and text to Markdown, with size and zip-bomb limits

Install

pip install cairnkit
# or
uv add cairnkit
# with document reading (adds pypdf and openpyxl):
pip install "cairnkit[documents]"   # or: uv add "cairnkit[documents]"

Python 3.12 or newer.

Quick start

An agent is a folder:

agents/
  greeter/
    agent.toml
    SOUL.md
# agents/greeter/agent.toml
description = "Answers questions about opening hours."
model = "default"          # a name your application maps to a model
tools = ["opening_hours"]  # the only tools this agent may use
skills = []                # optional: skills from a skills/ folder
max_iterations = 4
temperature = 0.2

SOUL.md holds the persona and rules; it goes into the stable layer of the system prompt.

from cairnkit import Agent, ToolContext, ToolRegistry, load_agents, openrouter, tool_result

tools = ToolRegistry()

@tools.tool(name="opening_hours", description="Opening hours for a weekday.",
            parameters={"type": "object", "properties": {"day": {"type": "string"}},
                        "required": ["day"]})
def opening_hours(args, ctx):
    return tool_result(day=args["day"], hours="7am-7pm")

specs = load_agents("agents")
agent = Agent(specs["greeter"], model=openrouter("openai/gpt-4.1-mini", api_key="..."),
              tools=tools)
result = await agent.run("When do you open on Sunday?", ToolContext(principal={"id": "u1"}))
print(result.text)

Runnable examples, no API key needed:

Example Shows
examples/minimal.py The smallest complete agent with one tool
examples/approval.py Read a ticket, propose a change, approve or reject in the host
examples/read_document.py Reading a PDF, Word or Excel file into Markdown
examples/verify_citations.py A read tool that checks a draft's DOIs and PMIDs with claimcite before review (needs network: uv run --with claimcite python examples/verify_citations.py)

Rules worth keeping

  • Identity is not the model's to decide. Put the user and the record in ToolContext.
  • Assemble the system prompt once per conversation. Pass RunResult.system_prompt back as run(system_prompt=...) on later turns so the provider's prompt cache keeps working.
  • Prefer access="propose" for anything that changes data, and let a person approve.
  • Test offline with ScriptedModel; automated tests should never call a real model.
  • Text from users, files and tools is data. Keep it out of the system prompt.

Reading documents (optional)

from cairnkit.documents import DocumentError, Limits, extract_text

try:
    doc = extract_text(data, "price-list.xlsx", limits=Limits(max_chars=40_000))
except DocumentError as exc:
    exc.code  # too_large, empty, unsupported, old_format, image, encrypted, no_text, unreadable, needs_extra
else:
    doc.text, doc.kind, doc.parts, doc.truncated, doc.warnings
  • Output is Markdown. Word keeps headings, lists and tables; Excel becomes one table per visible sheet (dates as 2026-11-07); PDF text is marked [Page N].
  • The format is judged by content, not only the file name. Old .doc/.xls, pictures and scanned PDFs get their own error codes so your UI can explain what to do.
  • Limits on file size, PDF pages, Excel rows and unzipped size. Only text is read; macros and formulas never run.
  • Replaceable: register_extractor("pdf", fn) swaps in another reader (MarkItDown, Docling, an OCR service) without changing callers.

Relationship to Hermes Agent

Many mechanisms and algorithms are ported from Hermes Agent v0.23.0 (MIT, Nous Research): the prompt layers, the tool loop, memory editing rules, history search, skills, context compression, background review, curation and delegation. Every ported file names its Hermes source in its header. Hermes is a personal assistant with files, terminals and dozens of platforms; cairnkit keeps the algorithms and replaces storage, configuration and permissions so they fit a multi-user web application. See docs/hermes-porting.md for the map and docs/upgrading-hermes.md for following new Hermes releases. cairnkit is not affiliated with or endorsed by Nous Research.

Versioning

MAJOR.MINOR.PATCH. Before 1.0:

  • Patch (0.3.0 → 0.3.1): fixes, tests and docs; upgrade freely.
  • Minor (0.3 → 0.4): new features, Hermes updates, or anything that needs changes in your code. CHANGELOG.md says what to change.

Development

uv sync --all-extras
uv run pytest -q && uv run ruff check . && uv run ruff format --check .

See CONTRIBUTING.md. Security reports: SECURITY.md.

License

MIT, see LICENSE. Ported Hermes Agent code keeps its MIT notice in NOTICE.md.

Metadata

Release files for cairnkit 0.5.1

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

Source distribution (sdist)

Source distribution for cairnkit 0.5.1
File Size Uploaded Provenance Actions
cairnkit-0.5.1.tar.gz 1.5 MB With provenance Details for cairnkit-0.5.1.tar.gz

Built distribution (wheel)

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

Total release size: 1.5 MB

Release files / cairnkit-0.5.1.tar.gz

Download URL cairnkit-0.5.1.tar.gz
Size 1.5 MB
Tags Source
SHA-256 checksum
How to use checksums
50ce3d08fda537e91009eceab26b66a105eb44f72f4663790dc89d39ef23d939
BLAKE2b-256 checksum
How to use checksums
d58e3308318d2abaa05f6ef9e9aea15ace5ffa845b8a022f1fb03cee7e4cc4d9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 12, 2026.

Transparency log

Release files / cairnkit-0.5.1-py3-none-any.whl

Download URL cairnkit-0.5.1-py3-none-any.whl
Size 74.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
eb6467a29d7d29091310e28d77ace3e67212422d742ad5074dd7325c906f058b
BLAKE2b-256 checksum
How to use checksums
7a2b8bbbeff304c8ad57638cecdc67ee119dd62e985c856d106491116cb90af7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 12, 2026.

Transparency log

Security for cairnkit 0.5.1

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.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for cairnkit-0.5.1.tar.gz

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 Nov 12, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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