Getting started
Draw the circle, bind the Sigils, perform the Rite — five minutes from install to a local model casting tools.
Install
pip install sanctum-engine # core: zero dependencies
pip install "sanctum-engine[openai-compat]" # + httpx, for local model servers
Your first Ritual (no model needed)
A Ritual is a graph builder; Sigils are nodes — plain callables
that receive the full state (the Aether) and return a partial delta.
compile() validates the graph and returns an executable Rite:
from sanctum import END, Ritual
ritual = Ritual()
ritual.add_sigil("cleanse", lambda aether: {"text": aether["text"].strip()})
ritual.add_sigil("transmute", lambda aether: {"text": aether["text"].upper()})
ritual.set_entry_point("cleanse")
ritual.add_edge("cleanse", "transmute")
ritual.add_edge("transmute", END)
rite = ritual.compile()
print(rite.invoke({"text": " fiat lux "}))
# {'text': 'FIAT LUX'}
An agent on Ollama, with a tool
Install Ollama, pull a model
(ollama pull qwen2.5:7b), and summon an Entity — an Oracle bound to a
Tome of Spells, sealed into the canonical ReAct loop:
import asyncio
from sanctum import Tome, spell, summon
from sanctum.oracle.ollama import OllamaOracle
@spell
def word_count(text: str) -> int:
"""Count the words in a text."""
return len(text.split())
entity = summon(
OllamaOracle(arcana="qwen2.5:7b"),
Tome([word_count]),
role="You are a scribe. Use your Spells when counting.",
)
result = asyncio.run(entity.ainvoke({"messages": [
{"role": "user", "content": "How many words in 'fiat lux'?"},
]}))
print(result["messages"][-1]["content"])
If your model has no native tool support, pass
spell_calling="prompted" (or "auto") to summon — see
Robust tool-calling.
Where to go next
- The examples gallery runs entirely on scripted oracles by default — no model required.
- Concepts explain each piece of the vocabulary.
- Guides cover pausing for humans, time-travel, tool-calling with small models, and tracing.