Metadata-Version: 2.4
Name: agentomy-sdk
Version: 0.4.0
Summary: Python SDK for Agentomy AI Governance Platform
Home-page: https://agentomy.com
Author: Agentomy
Author-email: governance@agentomy.com
License: MIT
Project-URL: Homepage, https://agentomy.com
Project-URL: Documentation, https://agentomy.com/docs
Project-URL: Source, https://github.com/getagentomy
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Topic :: Security
Classifier: Programming Language :: Python :: 3
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.28.0
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: license
Dynamic: license-file
Dynamic: project-url
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# Agentomy Python SDK

Python client for the Agentomy AI Governance Platform -- wraps the Claw Bridge API for authorization, audit logging, emergency halt, status, and health checks.

## Install

```bash
pip install agentomy-sdk
```

The platform itself is a hosted service and its repository is not public, so there is no
source install for the SDK outside the platform checkout.

## Quick Start

```python
from agentomy import AgentomyClient

# An API key is required -- an Agentomy instance answers 401 without one. The client reads
# AGENTOMY_API_KEY from the environment, so keys stay out of your source:
#     export AGENTOMY_API_KEY=<key from your workspace dashboard>
client = AgentomyClient("http://localhost:3000")

# Or pass it explicitly, if you are loading it from a secret manager:
#     client = AgentomyClient("http://localhost:3000", api_key=my_secret_manager.get(...))

# Check if action is permitted
result = client.authorize("my-agent", "read", scope="customer-data")
print(result.tier)       # Analyst
print(result.audit_id)   # claw_1712345678_abc123

# Log an action
log = client.log("my-agent", "read", input_data="query", output_data="result")
print(log.chain_position)

# Emergency halt
halt = client.halt("my-agent", reason="Security incident")
print(halt.agents_affected)

# Fleet-wide halt (no agent_id)
client.halt(reason="Full fleet lockdown")

# Check status
status = client.status("my-agent")
print(status.quarantined)  # True after halt

# Bridge health
health = client.health()
print(health.bridge)  # "active"
```

## Authentication

In production (when `ENABLE_AUTH` is set on the bridge), pass your API key:

```python
# The client reads AGENTOMY_API_KEY from the environment when no api_key is passed.
client = AgentomyClient("https://your-instance.agentomy.com")

# Passing api_key="" asks for an explicitly UNAUTHENTICATED client, which ignores the
# environment. Only the public health surface answers without a key.
```

## Quarantine and Release

A halted agent is quarantined and refused until an operator releases it. `quarantined()`
answers which agents are in that state -- `health()` only reports a count, and `release()`
needs an id.

```python
listing = client.quarantined()
print(listing["count"], listing["quarantinedAgents"])

client.release("my-agent", operator_id="operator-alice", reason="investigated")
```

`release()` clears one agent's quarantine. It does NOT lift a fleet halt: the authorize gate
checks the fleet halt first, so under an active halt a released agent stays refused. Call
`resume()` first, then `release()`.

A quarantined agent raises `AgentQuarantined`, which subclasses `AuthorizationDenied` -- so
existing `except AuthorizationDenied` handlers keep working, and code that needs to tell a
quarantine from a tier denial can now catch the specific one.

## Error Handling

```python
from agentomy import AuthorizationDenied, AgentQuarantined, ConnectionError, AgentomyError

try:
    client.authorize("my-agent", "delete")
except AuthorizationDenied as e:
    print(f"Denied: {e}")
except ConnectionError:
    print("Bridge unreachable")
except AgentomyError as e:
    print(f"API error: {e}")
```

## Tier Permissions

| Tier | Allowed Actions |
|------|----------------|
| Analyst    | read, query, list, search, status |
| Builder    | Analyst + write, create, update, execute |
| Operator   | Builder + delete, deploy, configure |
| Strategist | Operator + halt, override, admin |

## Governed Execution

The SDK provides two helpers that combine authorize + execute + log into a single call:

```python
# governed() -- pass a callable
result = client.governed(
    "my-agent",
    fn=lambda: my_agent.run_task(),
    action="read",
    scope="documents"
)
print(result["authorized"])   # True
print(result["result"])       # whatever my_agent.run_task() returned

# governance() -- context manager (Pythonic style)
with client.governance("my-agent", action="write", scope="reports") as auth:
    if auth.authorized:
        report = generate_report()
        # log is called automatically on context exit
```

Both helpers: authorize before execution, log the result after, and raise `AuthorizationDenied` if the agent is not permitted.

## Running Tests

The SDK's tests run against a live Agentomy instance at `localhost:3000` and live in the
platform repository alongside the source, so they are not part of this distribution.
