Metadata-Version: 2.4
Name: governance-sdk
Version: 0.1.0
Summary: A plug-and-play SDK to capture and audit tool calls in Agentic AI applications
Author-email: Sanjay Nithin <sanjaynithin220@gmail.com>
License: MIT
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: requests>=2.25.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: langchain-core>=0.1.0; extra == "dev"

# Governance SDK (AI Frameworks Edition)

A lightweight, non-blocking, plug-and-play Python SDK to automatically intercept, evaluate, and authorize tool calls in LangChain, LangGraph, and CrewAI agentic applications.

## Features

- **Multi-Framework Auto-Interception**: Automatically intercepts tool calls in **LangChain**, **LangGraph**, and **CrewAI** (by hooking base tool run/arun methods) with zero configuration.
- **Zero-Touch Automatic Context Capture**: Walks up the Python execution stack frames to auto-resolve active context details such as `session_id`, `agent_name`, `purpose`, and `trace_id` by inspecting local variables. No manual wrapping required!
- **Three-Tier Governance Workflow**: Evaluates risk and routes tool execution decisions:
  - `allow`: Automatically executes the tool.
  - `preview_and_confirmation`: Triggers an interactive CLI prompt to confirm execution.
  - `needs_full_review`: Triggers an interactive CLI prompt indicating full review is required.
- **Exception-Based Control**: If a developer/user denies an execution prompt, the SDK raises `PermissionDeniedError` or `ReviewRequiredError`, letting the calling application abort or handle it gracefully.
- **Non-Blocking Asynchronous Auditing**: Completed tool logs are queued in-memory and batch-shipped to the Governance Server asynchronously by a background worker thread.
- **Fail-safe & Resilient**: Operates with exponential backoff on server log shipment delivery failure.

---

## Installation

Install the package in editable mode:
```bash
pip install -e .
```

---

## Quickstart

Initialize the SDK at the entry point of your agentic application.

### 1. SDK Initialization
```python
import governance_sdk

governance_sdk.init(
    server_url="http://127.0.0.1:8000/api/v1/tool-calls",
    risk_check_url="http://127.0.0.1:8000/api/v1/risk-checks",
    project_name="customer-support-agent"
)
```

You can also use environment variables:
```bash
export GOVERNANCE_SERVER_URL="http://127.0.0.1:8000/api/v1/tool-calls"
export GOVERNANCE_RISK_CHECK_URL="http://127.0.0.1:8000/api/v1/risk-checks"
export GOVERNANCE_PROJECT_NAME="customer-support-agent"
```
And simply call `init()`:
```python
import governance_sdk
governance_sdk.init()
```

### 2. Auto-Interception & Context Capture
Once `init()` is called, any tool executed by your agent in LangChain, LangGraph, or CrewAI will be automatically intercepted:

```python
from langchain_core.tools import tool

@tool
def delete_user_data(user_id: str) -> str:
    """Deletes sensitive user information."""
    return f"User {user_id} deleted."

# In your agent logic:
# When this tool is called, the SDK automatically walks the stack to extract:
# - session_id (resolves from variables named session_id, sid, session, etc.)
# - agent_name (resolves from class name or variable agent_name)
# - purpose (resolves from variables named purpose, intent, reason, etc.)
# Then it verifies the risk score on the server side.
delete_user_data.run({"user_id": "usr_992"})
```

### 3. Explicit Context Override (Optional)
If you want to manually specify context instead of relying on the auto-captured stack frames, use the `agent_context` manager:

```python
import governance_sdk

with governance_sdk.agent_context(agent_name="Supervisor-Agent", session_id="session_override_123", purpose="cleanup"):
    # All tool calls executed inside this block will prioritize these values
    agent.run("delete temporary files")
```

---

## Captured Payload Format

The JSON payload sent to the governance logging server has the following structure:

```json
{
  "project_name": "customer-support-agent",
  "tool_calls": [
    {
      "tool_name": "delete_user_data",
      "tool_description": "Deletes sensitive user information.",
      "arguments": { "user_id": "usr_992" },
      "output": "User usr_992 deleted.",
      "error": null,
      "status": "success",
      "timestamp_start": "2026-07-30T13:30:00Z",
      "timestamp_end": "2026-07-30T13:30:00.045Z",
      "duration_ms": 45,
      "context": {
        "agent_name": "Supervisor-Agent",
        "session_id": "session_override_123",
        "purpose": "cleanup",
        "caller_filename": "main.py",
        "caller_line_number": 42,
        "caller_function": "execute_task"
      },
      "risk_score": 0.90,
      "risk_category": "high_risk",
      "governance_decision": "allow"
    }
  ]
}
```
