// orquestación local-first para agentes ia

SANCTUM

Traza el círculo. Liga los sigils. Invoca — un motor mínimo para grafos de estados cíclicos ejecutados por supersteps, hecho para los modelos de tu máquina. Núcleo en pura librería estándar de Python. Sin nube, sin cuentas, sin telemetría.

$ pip install sanctum-engine
0dependencias del núcleo
~60µspor superstep
140tests, sin modelos
MITlicencia
El modelo

Un agente es un ciclo, no una cadena

Sanctum ejecuta un grafo de estados cíclico — no un DAG. Cada superstep corre los Sigils activos (nodos) en paralelo sobre un Aether compartido (estado), funde sus deltas parciales mediante reducers por canal, y deja que los edges condicionales decidan qué despierta después. Pensar → actuar → observar → pensar de nuevo: el ciclo es el agente, acotado por un límite de recursión y con checkpoint en cada paso.

Determinista por construcción: los deltas se aplican en orden de inserción de los Sigils, así que las corridas paralelas resuelven idéntico, siempre.

from sanctum import END, Ritual

ritual = Ritual()
ritual.add_sigil("think", think)
ritual.add_sigil("act", act)
ritual.set_entry_point("think")
ritual.add_edge("think", "act")
ritual.add_conditional_edge("act",
    lambda aether: END if aether["done"] else "think")

rite = ritual.compile()          # validado, sellado
rite.invoke({"task": "..."})     # el ciclo se despliega
La maquinaria

Superficie pequeña, maquinaria seria

Un builder de grafos, un plan ejecutable, y todo lo que un runtime agéntico necesita de verdad — nada que no.

BSP supersteps

Lockstep estilo Pregel: Sigils en paralelo, orden determinista de reducers, edges condicionales evaluados sobre el estado fundido.

Joins wait-all

join="all" vuelve un Sigil una barrera sobre sus predecesores — ramas desiguales convergen bien, entre supersteps, sobreviviendo checkpoints.

Circles — subgrafos

Monta un Rite compilado como un solo Sigil. Un agente invocado se vuelve un nodo de un pipeline mayor; su vida interna sigue visible como eventos ecoados.

Scatter — map-reduce

Fan-out sobre una lista de tamaño dinámico con concurrencia acotada; los resultados llegan en orden de item. Paralelismo dinámico sin tocar el modelo de frontier.

summon()

El ciclo ReAct canónico — oracle → spells → oracle → END — armado por completo con primitivas públicas. Tu agente en una llamada.

Tool-calling robusto

Hecho para modelos locales de 7–14B: JSON malformado reparado, Spells desconocidos corregidos conversacionalmente, fallback prompted cuando el servidor no tiene tools nativas.

Seals y time-travel

Checkpoints JSON por superstep (memoria / SQLite / Postgres); reanudación, interrupt() para human-in-the-loop, replay desde cualquier Seal histórico.

Omens en streaming

Eventos tipados y con timestamp para cada punto del ciclo de vida; modos combinables; tokens en vivo desde dentro de un Sigil corriendo.

Políticas de resiliencia

Timeout por Sigil, reintentos con backoff y jitter, Sigils de fallback leyendo un canal de error reservado. El fallo es un camino, no un crash.

Middleware de Wards

Transforma o veta cualquier delta antes de que toque el estado: auditoría, conteo de uso, redacción — aplicados antes de que Seals y logs vean los datos.

Trazas locales

Una traza de ejecución completa renderizada a un solo HTML autocontenido. Cero requests externos — tu LangSmith es un archivo en disco.

Núcleo sin dependencias

El motor es pura stdlib de Python. Adapters HTTP, Postgres, GGUF in-process — todos extras opcionales, todos con import perezoso.

Local first

Hecho para los modelos que sí corres

Un adapter OpenAI-compatible cubre llama-server, vLLM, LM Studio y el /v1 de Ollama; el adapter nativo de Ollama y la carga de GGUF in-process lo completan. El transcript se traduce al formato de tools de cada servidor, así que los modelos locales ven de verdad los resultados de sus herramientas — y los modelos chicos dejan de re-llamar la misma tool por siempre.

Los tests jamás requieren un modelo: un oracle guionado vuelve determinista cada flujo, y la suite de integración contra un servidor real es estrictamente opt-in.

from sanctum.oracle.openai_compat import OpenAICompatibleOracle

oracle = OpenAICompatibleOracle(
    arcana="qwen2.5-7b",
    base_url="http://127.0.0.1:8080/v1",  # llama-server
)
entity = summon(oracle, tome,
    role="You are a scryer.",
    spell_calling="auto")  # fallback prompted incluido
La tabla honesta

Una comparación honesta

SanctumLangGraphn8n
Dependencias del núcleo0 (stdlib)langchain-core + moreNode.js platform
Modelos locales de primera clasesí — el puntoposiblevía nodos
Grafos cíclicos / superstepssí (BSP)sí (Pregel)DAG-ish
Checkpoints y time-travelsí, JSONlog de ejecuciones
Reparación de tools para modelos chicosincluidanono
Trazas sin SaaSun archivo HTMLLangSmith (cloud)UI incluida

Comparación completa de 13 filas, incluyendo dónde LangGraph es la mejor opción →

El ecosistema

El motor y el libro de hechizos

sanctum-engine

Ejecución: el grafo, el estado, el scheduler, los Oracles, la resiliencia. Todo lo de esta página.

GitHub · PyPI

AgentGrimoire

Capacidad: una biblioteca de herramientas con carpeta por Spell, cargable por convención con Tome.load_from_directory(). Cada lado evoluciona sin tocar al otro.

GitHub