Govern an AutoGen agent's native tool calls with Lodestar — the thin native hook that remotes each tool call through the Lodestar Action Kernel over NDJSON-RPC (ADR-0027).
Project description
lodestar-autogen
Govern an AutoGen agent's native tool calls with Lodestar — the open epistemic-governance framework for AI agents.
AutoGen (the autogen-agentchat / autogen-core actor framework) runs
multi-agent conversations whose tools are native in-process Python objects and
does not speak MCP, so the MCP proxy cannot wrap it. This package is the thin
native hook (ADR-0027) — the third framework on the same shared gate, after
LangGraph and CrewAI: it spawns the TypeScript governance-gate sidecar
(lodestar runtime gate) and remotes each native tool call through the Lodestar
Action Kernel over newline-delimited JSON-RPC. The same machinery the MCP proxy
and the LangGraph / CrewAI adapters run — two-phase propose → arbitrate → execute, the signed policy gate, cognitive-core ingestion (external-document
content can't auto-promote), sentinel arbitration, and the signed-approval L4 hold
path — now applies to AutoGen, with no change to the engine. The gate sidecar is
shared, unchanged; only this hook is new.
The tool body runs only inside the gate's execute phase, reached only after the gate (and any approval hold) clears: "tools that do work before approval are bugs" — across the Python↔TS boundary.
Install
pip install "lodestar-autogen[autogen]"
# and the Lodestar CLI (Bun/npm), which provides `lodestar runtime gate`:
npm install -g @qmilab/lodestar-cli # or: bun add -g @qmilab/lodestar-cli
Use
from autogen_agentchat.agents import AssistantAgent
from lodestar_autogen import GateClient, govern_tools, governed_call
with GateClient("runtime-gate.config.json") as gate:
governed = govern_tools(gate, my_tools) # register + wrap the toolset
agent = AssistantAgent("assistant", model_client=model_client, tools=governed)
# ... run your agent / team as usual; every tool call is governed.
# A custom step invokes a governed tool through the helper, never raw.
# It blocks, so off the event loop call it via a worker thread:
import asyncio
result = await asyncio.to_thread(governed_call, gate, "search_web", {"q": "lodestar"})
govern_tools accepts the same toolset shapes AssistantAgent does — a
BaseTool as-is, or a bare callable (normalised to a FunctionTool using its
docstring), so you can pass the literal tools=[my_func, ...] list you'd otherwise
hand the agent.
The gate's config (runtime-gate.config.json) is a RuntimeGateConfig — the
signed policy document, approver keys, sentinel ids, persistence, and durable log
root all live there. The hook never holds credentials or policy.
Scope (honest, ADR-0004 lineage)
This is governance over declared actions, not OS containment of the process.
Raw I/O performed outside the tool abstraction — a custom step that calls
requests.get() directly instead of a registered tool — is outside the governed
surface, exactly as guard.wrap() and the MCP proxy only govern the tools they
are given. A call for an unregistered tool is denied (fail closed). Pair the
adapter with network/filesystem controls for defense in depth.
Holds & denials
An L4 action the trust-ladder floor parks for approval is resolved by
block-polling the gate up to the deadline for a signed approval (hold_wait_ms)
— the headless default. A denied / held-then-timed-out call raises
LodestarDenied by default; AutoGen's StaticWorkbench.call_tool catches it and
surfaces the reason to the agent as a re-plannable error ToolResult. Pass
on_denied to govern_tools to map a denial to a return value instead.
Async, loops & cancellation
AutoGen's tool surface is fully async (BaseTool.run_json is a coroutine). The
governed wrapper offloads the blocking gate RPC onto a worker thread so it never
stalls the agent's event loop, and the gate's remoted body runs the original
tool's coroutine on a single persistent event loop — so loop-scoped state a
tool caches (an aiohttp.ClientSession, an asyncio.Event) stays valid across
calls rather than being bound to a loop that is torn down after each call.
The wrapper honours AutoGen's CancellationToken: an already-cancelled token
short-circuits (no governed work starts), and an in-flight call is unblocked when
the run is cancelled. Note that once the gate is executing the tool body it runs
server-side and can't be force-cancelled mid-flight — a property of the
remoted-execute model it shares with the LangGraph / CrewAI hooks.
Apache-2.0. Part of the Lodestar monorepo (runtimes/autogen/). The pure-stdlib
client.py is duplicated verbatim from lodestar-langgraph / lodestar-crewai;
it graduates to a shared lodestar-runtime-client package alongside PyPI
publishing (issue #128).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lodestar_autogen-0.5.0.tar.gz.
File metadata
- Download URL: lodestar_autogen-0.5.0.tar.gz
- Upload date:
- Size: 15.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8e14c68c4cf03da96d4366e58e84e0401609e165cd07239ad43221b94f280f3a
|
|
| MD5 |
4274152b99eac95986978774a9800067
|
|
| BLAKE2b-256 |
eb3fd9b35ffee932979e9356828a261bd5133e6e01d88a23163e96036e4e0360
|
Provenance
The following attestation bundles were made for lodestar_autogen-0.5.0.tar.gz:
Publisher:
publish-pypi.yml on qmilab/lodestar
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lodestar_autogen-0.5.0.tar.gz -
Subject digest:
8e14c68c4cf03da96d4366e58e84e0401609e165cd07239ad43221b94f280f3a - Sigstore transparency entry: 2031855709
- Sigstore integration time:
-
Permalink:
qmilab/lodestar@1c729bac06872678099a7899940c9c65ab59be9e -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/qmilab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@1c729bac06872678099a7899940c9c65ab59be9e -
Trigger Event:
push
-
Statement type:
File details
Details for the file lodestar_autogen-0.5.0-py3-none-any.whl.
File metadata
- Download URL: lodestar_autogen-0.5.0-py3-none-any.whl
- Upload date:
- Size: 10.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
58b9e0960819d1fa2da31522498e7c874605ebb4c488285127883a1341300621
|
|
| MD5 |
f5184c1531a5fcfc6d4b2ffb94594763
|
|
| BLAKE2b-256 |
0980588d88e19a813024b80247b57e494d2dde3cc4ddfb8fbbaadfca988f8103
|
Provenance
The following attestation bundles were made for lodestar_autogen-0.5.0-py3-none-any.whl:
Publisher:
publish-pypi.yml on qmilab/lodestar
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lodestar_autogen-0.5.0-py3-none-any.whl -
Subject digest:
58b9e0960819d1fa2da31522498e7c874605ebb4c488285127883a1341300621 - Sigstore transparency entry: 2031855843
- Sigstore integration time:
-
Permalink:
qmilab/lodestar@1c729bac06872678099a7899940c9c65ab59be9e -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/qmilab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@1c729bac06872678099a7899940c9c65ab59be9e -
Trigger Event:
push
-
Statement type: