Metadata-Version: 2.4
Name: ael-sdk
Version: 0.3.0
Summary: Python SDK for Agent Execution Ledger - Audit trail for AI agents
Home-page: https://github.com/vinayb21-work/Agent-Execution-Ledger
Author: Vinay Badhan
Author-email: vinay.badhan21.work@gmail.com
Project-URL: Bug Tracker, https://github.com/vinayb21-work/Agent-Execution-Ledger/issues
Project-URL: Documentation, https://github.com/vinayb21-work/Agent-Execution-Ledger#readme
Keywords: ai agents audit logging llm observability
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Logging
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.26.0
Requires-Dist: pydantic>=2.5.0
Provides-Extra: google-adk
Requires-Dist: google-adk>=1.0.0; extra == "google-adk"
Provides-Extra: langchain
Requires-Dist: langchain-core>=0.1.0; extra == "langchain"
Provides-Extra: crewai
Requires-Dist: crewai>=0.1.0; extra == "crewai"
Provides-Extra: openai
Requires-Dist: openai>=1.0.0; extra == "openai"
Provides-Extra: autogen
Requires-Dist: pyautogen>=0.2.0; extra == "autogen"
Provides-Extra: all
Requires-Dist: google-adk>=1.0.0; extra == "all"
Requires-Dist: langchain-core>=0.1.0; extra == "all"
Requires-Dist: crewai>=0.1.0; extra == "all"
Requires-Dist: openai>=1.0.0; extra == "all"
Requires-Dist: pyautogen>=0.2.0; extra == "all"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: license-file
Dynamic: project-url
Dynamic: provides-extra
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# AEL SDK

**Git for AI Agent Decisions** - Complete audit trail, replay, and divergence detection for enterprise AI agents.

[![PyPI version](https://badge.fury.io/py/ael-sdk.svg)](https://pypi.org/project/ael-sdk/)
[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## 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

```bash
pip install ael-sdk
```

With framework integrations:
```bash
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

```python
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:

```python
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:

```python
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:

```python
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](https://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

```python
from ael import AELClient

ael = AELClient(api_key="ael_your_key")
```

---

## Framework Integrations

### LangChain

```python
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

```python
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

```python
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

```python
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](https://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](LICENSE) for details.

---

## Links

- **Dashboard**: [agent-execution-ledger.vercel.app](https://agent-execution-ledger.vercel.app)
- **GitHub**: [github.com/vinayb21/ael](https://github.com/vinayb21/ael)
- **PyPI**: [pypi.org/project/ael-sdk](https://pypi.org/project/ael-sdk/)
