AEL SDK
Git for AI Agent Decisions - Complete audit trail, replay, and divergence detection for enterprise AI agents.
Why AEL?
When your AI agent approves a $10,000 refund or denies a loan application, can you answer:
- Why did the agent make that decision?
- What context did it have at the time?
- Would it decide the same way if we ran it again?
- Who overrode the agent's recommendation?
AEL captures every decision your agent makes with full context, enabling audit trails, replay verification, and divergence detection.
Installation
pip install ael-sdk
With framework integrations:
pip install ael-sdk[langchain] # LangChain
pip install ael-sdk[google-adk] # Google ADK
pip install ael-sdk[crewai] # CrewAI
pip install ael-sdk[openai] # OpenAI Assistants
pip install ael-sdk[all] # All integrations
30-Second Quickstart
from ael import AELClient, ActionOption, ResultType
ael = AELClient(api_key="ael_your_key")
with ael.intent("Process refund request", agent_id="support-agent") as intent:
# 1. Capture what the agent saw
intent.snapshot_context({
"customer_tier": "gold",
"order_amount": 149.99,
"days_since_delivery": 5,
})
# 2. Record the decision with options considered
intent.decide(
options=[
ActionOption(action="approve_refund", score=0.95, reason="Gold customer, within policy"),
ActionOption(action="deny_refund", score=0.05, reason="N/A"),
],
chosen_action="approve_refund",
confidence=0.95,
reasoning="Customer eligible per 30-day return policy"
)
# 3. Record execution
intent.execute(action="approve_refund", target={"order_id": "ORD-123"}, result=ResultType.SUCCESS)
Now query any decision: "Why did we approve this refund?" - Full context, reasoning, and alternatives considered.
Key Features
1. Decision Replay with Divergence Detection
Store the prompt and re-run decisions to verify consistency:
from ael import AELClient, ActionOption, ReplayConfig
ael = AELClient(api_key="ael_your_key")
# Record decision WITH replay data
with ael.intent("Handle support ticket") as intent:
intent.snapshot_context({"ticket_id": "T-123", "priority": "high"})
intent.decide(
options=[ActionOption(action="escalate", score=0.9)],
chosen_action="escalate",
confidence=0.9,
reasoning="High priority ticket requires escalation",
# Enable replay
replay_prompt="You are a support agent. Ticket: high priority. Action?",
replay_config=ReplayConfig(model="gpt-4o-mini", temperature=0.0),
)
exec_id = intent.execute(action="escalate", target={"ticket_id": "T-123"}, result=ResultType.SUCCESS)
# Later: Verify the decision is still consistent
replay_result = ael.replay(exec_id, force_llm_call=True)
if replay_result["diverged"]:
print(f"WARNING: Model behavior changed!")
print(f"Original: {replay_result['original_decision']['chosen_action']}")
print(f"Replayed: {replay_result['replayed_decision']['chosen_action']}")
print(f"Reason: {replay_result['divergence_reason']}")
else:
print("Decision verified - model behavior consistent")
2. Multi-Agent Tracking (Parent-Child Intents)
Track complex workflows with multiple agents or MCP tool calls:
with ael.intent("Process customer request", agent_id="orchestrator") as parent:
parent.snapshot_context({"request": "refund for order 123"})
# Spawn child intent for sub-agent
with parent.child_intent("Search order history", mcp_server="database") as child:
child.snapshot_context({"query": "order 123"})
child.decide(
options=[ActionOption(action="query_db", score=1.0)],
chosen_action="query_db",
confidence=1.0
)
child.execute(action="query_db", target={"order_id": "123"}, result=ResultType.SUCCESS)
# Parent continues with child's result
parent.decide(...)
parent.execute(...)
3. Human Override Tracking
When humans override agent decisions:
intent.execute(
action="deny_refund", # Human chose differently
target={"order_id": "123"},
result=ResultType.SUCCESS,
actor=ActorType.HUMAN,
override_reason="Customer has history of fraud"
)
Getting Started
1. Create an Account
Go to agent-execution-ledger.vercel.app and sign in with Google.
2. Create a Workspace
After signing in, create a workspace (e.g., "Production Agents").
3. Generate an API Key
Navigate to API Keys > Create API Key > Copy your key (ael_xxxx...).
4. Use the SDK
from ael import AELClient
ael = AELClient(api_key="ael_your_key")
Framework Integrations
LangChain
from langchain_openai import ChatOpenAI
from ael import AELClient, ActionOption, ResultType
ael = AELClient(api_key="ael_xxx")
llm = ChatOpenAI(model="gpt-4o-mini")
def run_agent(query: str):
with ael.intent(query, agent_id="langchain-agent") as intent:
intent.snapshot_context({"query": query})
response = llm.invoke(query)
intent.decide(
options=[ActionOption(action="respond", score=0.9)],
chosen_action="respond",
confidence=0.9,
reasoning=response.content[:100]
)
intent.execute(action="respond", result=ResultType.SUCCESS)
return response.content
Google ADK
from google.adk.agents import Agent
from ael import AELClient
from ael.integrations.google_adk import AELTracker
ael = AELClient(api_key="ael_xxx")
tracker = AELTracker(ael, agent_id="support-agent")
agent = Agent(name="support", model="gemini-2.0-flash")
with tracker.track("Handle customer request") as t:
t.context({"customer_id": "123"})
# ... run agent ...
t.decision(chosen="resolve", confidence=0.92, options=[...])
t.execute(action="resolve", result="success")
CrewAI
from crewai import Agent, Task, Crew
from ael import AELClient
from ael.integrations.crewai import AELCrewTracker
ael = AELClient(api_key="ael_xxx")
tracker = AELCrewTracker(ael)
crew = Crew(agents=[...], tasks=[...])
with tracker.track_crew("Content pipeline") as t:
result = crew.kickoff()
t.record_result(result, agents=[...], tasks=[...])
API Reference
AELClient
ael = AELClient(
api_key="ael_xxx", # Required
endpoint="https://ael-backend.onrender.com", # Optional (default: production)
timeout=30.0 # Optional
)
Core Methods
| Method | Description |
|---|---|
ael.intent(goal, agent_id) |
Context manager for tracking an intent |
intent.snapshot_context(inputs) |
Capture what the agent sees |
intent.decide(options, chosen_action, confidence) |
Record a decision |
intent.execute(action, target, result) |
Record execution |
ael.replay(execution_id, force_llm_call) |
Replay and verify a decision |
ael.get_execution(id) |
Get execution details |
ael.get_session_timeline(session_id) |
Get full session timeline |
Replay Methods
| Method | Description |
|---|---|
ael.replay(exec_id) |
Compare against original (no LLM call) |
ael.replay(exec_id, force_llm_call=True) |
Re-run LLM and check for divergence |
Multi-Agent Methods
| Method | Description |
|---|---|
intent.child_intent(goal, mcp_server) |
Create child intent |
ael.get_intent_hierarchy(id) |
Get parent chain (breadcrumbs) |
ael.get_intent_tree(id) |
Get full descendant tree |
Dashboard
View your agent's decisions at agent-execution-ledger.vercel.app:
- Execution Timeline: See all decisions chronologically
- Session View: Group related decisions by session
- Decision Details: Full context, options considered, and reasoning
- Hierarchy View: Navigate parent-child intent relationships
Use Cases
| Industry | Use Case |
|---|---|
| FinTech | Audit loan decisions, fraud detection reasoning |
| Healthcare | Track triage recommendations, document clinical AI decisions |
| E-commerce | Refund approvals, pricing decisions, inventory management |
| Legal | Contract analysis decisions, compliance checking |
| HR | Resume screening, candidate ranking explanations |
License
MIT License - see LICENSE for details.
Links
- Dashboard: agent-execution-ledger.vercel.app
- GitHub: github.com/vinayb21/ael
- PyPI: pypi.org/project/ael-sdk
Metadata
Release files for ael-sdk 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| ael_sdk-0.3.0.tar.gz | 22.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ael_sdk-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 47.2 kB
Release files / ael_sdk-0.3.0.tar.gz
| Download URL | ael_sdk-0.3.0.tar.gz |
|---|---|
| Size | 22.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
643dd295dd0c68fa92522ec38d4ef545e97bdcb3e3db6fb8b1dd309a18d438e6
|
|
BLAKE2b-256 checksum How to use checksums |
6c70207c22115295814365ac97acf055865ae841456e86f9488636ceb66abed1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.8
|
Release files / ael_sdk-0.3.0-py3-none-any.whl
| Download URL | ael_sdk-0.3.0-py3-none-any.whl |
|---|---|
| Size | 24.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3a37ca11f6cfa40349d9496d2a5f10b3d3534e8d0c743440a311f41741864dff
|
|
BLAKE2b-256 checksum How to use checksums |
f9e9176cc7f3c9d4befa7291d4c82b27d56c7d0722a523c3d89623f930a979f1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.8
|
Security for ael-sdk 0.3.0
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.