Catalog PyPI
Back to packageRELEASE DETAILS

0.2.6

PyPI

agendex

Governance SDK for AI Agents - Runtime policy enforcement, activity capture, and approval workflows

agentsaicrewaigovernancelangchainsecurity
Published23 Mar 2026
Direct dependencies6
Transitive dependenciesNot calculated

README

Version 0.2.6 documentation

Agendex SDK

Resource-Level Governance for AI Agents - Dynamic task-scoped access control, parameter inspection, and tamper-evident audit trails.

What Makes Agendex Different

Traditional IAMAgendex
"Agent can use payment tool""Agent doing vendor_payment task can call payments API if amount < $1000"
Static permissionsDynamic, task-scoped
No parameter inspectionFull body/query inspection
Tool-level controlResource-level control

Installation

pip install agendex

With framework extras:

pip install agendex[langchain]   # LangChain integration
pip install agendex[crewai]      # CrewAI integration
pip install agendex[all]         # All integrations

Quick Start: Resource-Level Governance (~30 lines)

from agendex import AgendexClient, GovernedDBClient, GovernedS3Client, GovernedHTTPSession
from agendex.errors import DeniedError, PendingApprovalError

# 1. Create client (reads config from env vars)
client = AgendexClient()

# 2. Create governed resource clients
db = GovernedDBClient(client, task="monthly_report")
s3 = GovernedS3Client(client, task="monthly_report")
http = GovernedHTTPSession(client, task="monthly_report")

# 3. Use in your tools - governance happens automatically
def fetch_revenue(month: str) -> str:
    try:
        result = db.query("monthly_revenue", {"month": month})
        return json.dumps(result.get("rows", []))
    except DeniedError as e:
        return f"[DENIED] {e.reason}"
    except PendingApprovalError as e:
        return f"[APPROVAL REQUIRED] ID: {e.approval_id}"

def initiate_payment(amount: float, vendor: str) -> str:
    try:
        result = http.post(
            "https://payments.api/v1/pay",
            json={"amount": amount, "vendor": vendor}
        )
        return json.dumps(result)
    except DeniedError as e:
        return f"[DENIED] {e.reason}"  # e.g., "amount > 5000"

Environment Variables

VariableDescriptionDefault
AGENDEX_URLProxy URLhttp://localhost:8000
AGENDEX_AGENT_IDAgent identifierrequired
AGENDEX_TOKENBearer tokenrequired

How It Works

+-----------------------------------------------------------------+
|  Agent Process                                                   |
|                                                                  |
|  Tool: fetch_revenue("2025-01")                                  |
|         |                                                        |
|         v                                                        |
|  GovernedDBClient.query("monthly_revenue", {month: "2025-01"})   |
|         |                                                        |
+---------+--------------------------------------------------------+
          |
          v
+-----------------------------------------------------------------+
|  Agendex Proxy                                                   |
|                                                                  |
|  /evaluate: {                                                    |
|    action: "db.query.run",                                       |
|    params: {query_id: "monthly_revenue"},                        |
|    task: "monthly_report"                                        |
|  }                                                               |
|         |                                                        |
|         v                                                        |
|  Policy: Allow db.query.run IF query_id=monthly_revenue          |
|          AND task IN [monthly_report, demo]                      |
|         |                                                        |
|         v                                                        |
|  /invoke -> DBQueryAdapter -> SQLite -> rows                     |
|                                                                  |
+-----------------------------------------------------------------+

Policy Examples

agents:
  finance_bot:
    allow:
      # DB: Only specific queries, scoped by task
      - action: "db.query.run"
        resources:
          - type: db_query
            query_id: "monthly_revenue"
        tasks: ["monthly_report", "demo"]

      # S3: Only specific buckets/prefixes
      - action: "s3.reports.fetch"
        resources:
          - type: s3
            bucket: "reports-bucket"
            key_prefix: "monthly/"

      # HTTP: Parameter-aware decisions
      - action: "http.service.call"
        condition: "body.amount < 1000"

      - action: "http.service.call"
        condition: "1000 <= body.amount <= 5000"
        require_approval: true

      # CRM: Scoped to lookup only
      - action: "crm.lookup"
        tasks: ["support"]

    deny:
      - action: "http.service.call"
        condition: "body.amount > 5000"

Resource Clients

ClientActionWhat It Governs
GovernedDBClientdb.query.runQuery ID, parameters
GovernedS3Clients3.reports.fetchBucket, key prefix
GovernedHTTPSessionhttp.service.callDomain, path, method, body
GovernedCRMClientcrm.lookup, crm.updateAccount ID, status changes
GovernedToolany custom actionArbitrary params

GovernedTool: Custom Actions

For actions that don't fit a built-in client, use GovernedTool:

from agendex import GovernedTool

# Wrap any action
slack = GovernedTool(client, action="slack.post", task="alerts")
slack.invoke(channel="#ops", message="System alert!")

# Or call it directly
email = GovernedTool(client, action="email.send", task="notifications")
email(to="admin@co.com", subject="Report ready")

Configuration

Override default action names globally:

from agendex import configure_actions

configure_actions(
    db_query="database.execute",    # db.query -> database.execute
    http_request="api.call",        # http.request -> api.call
    crm_lookup="salesforce.lookup", # crm.lookup -> salesforce.lookup
)

Integration Overhead

~31 lines to add Agendex to an existing agent:

  • 2 lines: imports
  • 3 lines: config
  • 3 lines: tool signatures
  • 18 lines: error handling (6 per tool)
  • 5 lines: initialization

Documentation

License

MIT

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Declared dependencies 9

Native requirements
6 direct targetsNot calculated transitive count
Package / targetRequirementRelationship
requests
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.9",
  "evaluation": "NOT_EVALUATED"
}
requests>=2.28.0runtime
langchain
Environment
{
  "extras": "",
  "marker": "extra == \"langchain\"",
  "requires_python": ">=3.9",
  "evaluation": "NOT_EVALUATED"
}
langchain>=0.2.0; extra == "langchain"runtime
langchain-core
Environment
{
  "extras": "",
  "marker": "extra == \"langchain\"",
  "requires_python": ">=3.9",
  "evaluation": "NOT_EVALUATED"
}
langchain-core>=0.2.0; extra == "langchain"runtime
crewai
Environment
{
  "extras": "",
  "marker": "extra == \"crewai\"",
  "requires_python": ">=3.9",
  "evaluation": "NOT_EVALUATED"
}
crewai>=0.30.0; extra == "crewai"runtime
langchain
Environment
{
  "extras": "",
  "marker": "extra == \"all\"",
  "requires_python": ">=3.9",
  "evaluation": "NOT_EVALUATED"
}
langchain>=0.2.0; extra == "all"runtime
langchain-core
Environment
{
  "extras": "",
  "marker": "extra == \"all\"",
  "requires_python": ">=3.9",
  "evaluation": "NOT_EVALUATED"
}
langchain-core>=0.2.0; extra == "all"runtime
crewai
Environment
{
  "extras": "",
  "marker": "extra == \"all\"",
  "requires_python": ">=3.9",
  "evaluation": "NOT_EVALUATED"
}
crewai>=0.30.0; extra == "all"runtime
pytest
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.9",
  "evaluation": "NOT_EVALUATED"
}
pytest>=8.0.0; extra == "dev"runtime
pytest-asyncio
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.9",
  "evaluation": "NOT_EVALUATED"
}
pytest-asyncio>=0.23.0; extra == "dev"runtime

Distribution files

2 collected
agendex-0.2.6-py3-none-any.whl

bdist_wheel · 52.6 KB · Python py3

Source file
agendex-0.2.6.tar.gz

sdist · 54.92 KB · Python source

Source file

Repository

PENDING
agendex/agendex-sdk

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 21:25 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package_version:45f7e7697442277f2e2b7f4b7ff220c794fec8646d81839227f481406fe538c8

Other collected versions

View all collected versions →