Adapter Overview¶
Edictum ships six framework adapters that connect the governance pipeline to
popular AI agent frameworks. Every adapter follows the same design principle:
adapters are thin translation layers. They convert framework-specific events
into Edictum envelopes and translate governance decisions back into the format
each framework expects. The adapters contain zero governance logic -- all
allow/deny decisions come from the GovernancePipeline.
This architecture means you get identical enforcement semantics regardless of which framework you use. Switching frameworks requires changing only the adapter wiring, not your contracts or policies.
Adapter Lifecycle¶
Every adapter implements the same six-step lifecycle when a tool call occurs:
Framework Event (tool call requested)
|
v
Create Envelope -- normalize into ToolEnvelope
|
v
Pipeline Pre-Execute -- evaluate preconditions, session limits, hooks
|
+---+---+
| |
DENY ALLOW
| |
v v
Return Execute Tool -- framework runs the actual tool
Denial |
v
Pipeline Post-Execute -- evaluate postconditions, record result
|
v
Emit Audit Event -- structured log with redaction
|
v
Framework Response -- translate back to framework format
On deny, the adapter short-circuits before the tool runs. The tool callable
is never invoked, and the denial reason is returned in whatever format the
framework expects (a ToolMessage, a boolean, a dict, etc.).
On allow, the tool executes normally. After execution, the post-execute phase runs postconditions and records audit events for the outcome.
Common Adapter API¶
All six adapters share the same constructor signature:
from edictum import Edictum, Principal
guard = Edictum.from_yaml("contracts.yaml")
principal = Principal(user_id="alice", role="sre", ticket_ref="JIRA-1234")
adapter = SomeAdapter(
guard=guard, # required -- the Edictum instance
session_id="my-session-123", # optional -- auto-generated UUID if omitted
principal=principal, # optional -- identity context for audit
)
Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
guard |
Edictum |
required | The configured Edictum instance holding contracts, limits, and sinks |
session_id |
str \| None |
auto UUID | Groups related tool calls into a session for limit tracking |
principal |
Principal \| None |
None |
Identity context attached to every audit event in this session |
Session Management¶
Each adapter maintains an internal call counter (_call_index) and a Session
object that tracks attempt and execution counts. Session limits defined in your
contracts (e.g., max 10 tool calls per session) are enforced through this
mechanism. If you pass the same session_id to multiple adapter instances
sharing the same StorageBackend, their counts accumulate.
Observe Mode¶
Every adapter supports observe mode. When the guard is created with
mode="observe", denials are logged as CALL_WOULD_DENY audit events but the
tool call is allowed to proceed. This lets you deploy contracts in production
without enforcement to validate behavior before switching to mode="enforce".
Adapter Reference¶
| Framework | Adapter Class | Import | Integration Method | Returns |
|---|---|---|---|---|
| Claude Agent SDK | ClaudeAgentSDKAdapter |
edictum.adapters.claude_agent_sdk |
adapter.to_sdk_hooks() |
dict with pre_tool_use and post_tool_use async functions |
| LangChain | LangChainAdapter |
edictum.adapters.langchain |
adapter.as_middleware() |
@wrap_tool_call decorated function |
| CrewAI | CrewAIAdapter |
edictum.adapters.crewai |
adapter.register() |
Registers global before/after hooks (no return value) |
| Agno | AgnoAdapter |
edictum.adapters.agno |
adapter.as_tool_hook() |
Wrap-around function for tool_hooks parameter |
| Semantic Kernel | SemanticKernelAdapter |
edictum.adapters.semantic_kernel |
adapter.register(kernel) |
Registers AUTO_FUNCTION_INVOCATION filter on kernel |
| OpenAI Agents SDK | OpenAIAgentsAdapter |
edictum.adapters.openai_agents |
adapter.as_guardrails() |
(input_guardrail, output_guardrail) tuple |
Choosing an Adapter¶
Pick the adapter that matches your agent framework:
- Claude Agent SDK -- You are building with Anthropic's agent SDK and need
hook-based governance via
pre_tool_use/post_tool_use. - LangChain -- You are using LangChain agents with the
tool_call_middlewaresystem introduced inlangchain-core >= 0.3. - CrewAI -- You are using CrewAI crews and want global before/after hooks applied to every tool call across all agents in the crew.
- Agno -- You are using the Agno framework and need a
tool_hookscompatible function that wraps tool execution. - Semantic Kernel -- You are using Microsoft Semantic Kernel and want to register governance as an auto-function-invocation filter on the kernel.
- OpenAI Agents SDK -- You are using the OpenAI Agents SDK and want to wire
governance through the
tool_input_guardrail/tool_output_guardrailsystem.
If your framework is not listed, use Edictum.run() directly -- it provides
the same governance pipeline without any adapter:
result = await guard.run(
tool_name="read_file",
args={"path": "/etc/passwd"},
tool_callable=my_read_file_fn,
)
Installation Extras¶
Each adapter has an optional dependency group in pyproject.toml:
pip install edictum[langchain] # LangChain adapter
pip install edictum[crewai] # CrewAI adapter
pip install edictum[agno] # Agno adapter
pip install edictum[semantic-kernel] # Semantic Kernel adapter
pip install edictum[openai-agents] # OpenAI Agents SDK adapter
pip install edictum[yaml] # YAML contract engine (no framework deps)
pip install edictum[all] # Everything
The Claude Agent SDK adapter has no extra dependencies beyond edictum[yaml].