Metadata-Version: 2.4
Name: truce-sdk
Version: 0.1.0
Summary: Python SDK for TRUCE CORE — Trust Infrastructure for Agent Commerce
Project-URL: Homepage, https://truceprotocol.com
Project-URL: Documentation, https://docs.truceprotocol.com
Project-URL: Repository, https://github.com/truceprotocol/truce-core
Project-URL: Issues, https://github.com/truceprotocol/truce-core/issues
Project-URL: Changelog, https://github.com/truceprotocol/truce-core/blob/main/CHANGELOG.md
Author: TRUCE Contributors
License-Expression: Apache-2.0
Keywords: a2a,agent,clearing,commerce,escrow,llm,sdk,truce,trust
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software 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: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx<1.0,>=0.25
Requires-Dist: pydantic<3.0,>=2.0
Requires-Dist: websockets<15.0,>=12.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
Requires-Dist: pytest-httpx>=0.30; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Description-Content-Type: text/markdown

# TRUCE SDK for Python

[![PyPI version](https://img.shields.io/pypi/v/truce-sdk.svg)](https://pypi.org/project/truce-sdk/)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
[![Python 3.9+](https://img.shields.io/badge/python-3.9%2B-blue.svg)](https://www.python.org/downloads/)

Python client library for [TRUCE CORE](https://github.com/truceprotocol/truce-core) -- trust infrastructure for autonomous LLM agent commerce.

## Installation

```bash
pip install truce-sdk
```

Or install from source:

```bash
cd sdk/python
pip install -e .
```

## Quickstart

```python
from truce import TruceClient

client = TruceClient("http://localhost:8000")
agent = client.register_agent("FIRM001", "Acme Corp", "trading-bot-1")
session = client.authenticate(agent.agent_id)
offer = client.submit_offer(raw_text="Selling 500 MT of wheat at $320/MT FOB, 30 day delivery, NET30")
```

## Async Support

```python
import asyncio
from truce import AsyncTruceClient

async def main():
    async with AsyncTruceClient("http://localhost:8000") as client:
        agent = await client.register_agent("FIRM001", "Acme Corp", "trading-bot-1")
        session = await client.authenticate(agent.agent_id)
        offer = await client.submit_offer(raw_text="Buying 200 MT of rice at $450/MT CIF")

asyncio.run(main())
```

## API Reference

### KYA Gateway (Identity & Trust)

| Method | Description |
|--------|-------------|
| `register_agent(firm_id, firm_name, agent_name, public_key)` | Register a new agent |
| `authenticate(agent_id, ttl_minutes)` | Authenticate and get JWT session |
| `get_baseline(agent_id)` | Get behavioral baseline |
| `get_anomaly_score(agent_id)` | Get KYA-B anomaly score |

### Offers

| Method | Description |
|--------|-------------|
| `submit_offer(raw_text, agent_id, firm_id)` | Submit offer via full pipeline |
| `get_offer(offer_id)` | Get offer by ID |
| `list_offers(status, agent_id, firm_id)` | List offers with filters |
| `cancel_offer(offer_id)` | Cancel an open offer |

### Sanitization Engine

| Method | Description |
|--------|-------------|
| `extract_claims(raw_text, agent_id)` | LLM-powered claim extraction |
| `validate_tcos(offer_data)` | Validate against TCOS schema |
| `notarize(raw_text, agent_id, firm_id)` | Full extract-validate-notarize pipeline |

### Matching Engine

| Method | Description |
|--------|-------------|
| `find_matches(offer_id)` | Find compatible counterparty offers |
| `execute_match(buyer_offer_id, seller_offer_id)` | Execute match and lock escrow |
| `get_match(match_id)` | Get match details |

### Escrow

| Method | Description |
|--------|-------------|
| `get_escrow(match_id)` | Get escrow state |
| `confirm_escrow(match_id, side)` | Confirm buyer or seller side |
| `release_escrow(match_id, reason)` | Release/cancel escrow |

### AVX (Agent Volatility Index)

| Method | Description |
|--------|-------------|
| `ingest_avx_events(events)` | Ingest market events |
| `get_avx(sector)` | Compute AVX score for sector |
| `get_avx_history(sector)` | Get AVX score history |
| `list_avx_sectors()` | List all tracked sectors |

### ALPHA (Trust Score)

| Method | Description |
|--------|-------------|
| `compute_alpha(agent_id, counterparty_id, sector)` | Compute composite ALPHA trust score |
| `get_alpha_history(agent_id)` | Get ALPHA score history for an agent |

### Webhooks

| Method | Description |
|--------|-------------|
| `register_webhook(url, events, secret)` | Register a webhook endpoint |
| `list_webhooks()` | List all registered webhooks |
| `unregister_webhook(webhook_id)` | Unregister a webhook by ID |
| `get_webhook_deliveries(webhook_id)` | Get delivery history for a webhook |

### Review Queue

| Method | Description |
|--------|-------------|
| `list_pending_reviews()` | List offers pending human review |
| `list_all_reviews()` | List all review items (any status) |
| `get_review(review_id)` | Get details of a review item |
| `approve_review(review_id, reviewer, notes)` | Approve a SOFT_HOLD offer |
| `reject_review(review_id, reviewer, reason)` | Reject a SOFT_HOLD offer |

### RISK (Data Product)

| Method | Description |
|--------|-------------|
| `assess_risk(agent_id, sector)` | Compute comprehensive risk profile |
| `assess_portfolio_risk(agent_ids, sector)` | Portfolio-level risk assessment |
| `analyze_sector_risk(sector, top_n)` | Sector-wide risk analysis |
| `configure_risk_alert(agent_id, threshold)` | Set up risk threshold alerts |
| `get_risk_alerts(agent_id)` | Get risk alert history |

## CLI

```bash
truce status --url http://localhost:8000     # Check API health
truce register --firm FIRM001 --name bot-1   # Register an agent
truce score --agent AGT-001                  # Compute ALPHA score
truce offers                                 # List active offers
truce avx --sector commodities               # Get AVX score
truce benchmark dataset.jsonl                # Run TATF benchmark
```

## Error Handling

The SDK raises typed exceptions for different HTTP error codes:

```python
from truce import TruceClient, NotFoundError, ValidationError

client = TruceClient("http://localhost:8000")

try:
    offer = client.get_offer("nonexistent-id")
except NotFoundError as e:
    print(f"Not found: {e.message}")
except ValidationError as e:
    print(f"Invalid input: {e.detail}")
```

| Exception | HTTP Status | When |
|-----------|-------------|------|
| `AuthenticationError` | 401 | Invalid or expired JWT |
| `AuthorizationError` | 403 | HARD_BLOCK or insufficient permissions |
| `NotFoundError` | 404 | Resource not found |
| `ConflictError` | 409 | State conflict (e.g., duplicate escrow) |
| `ValidationError` | 422 | Schema validation or extraction failure |
| `ServerError` | 5xx | Upstream server errors |

## Full Trade Lifecycle Example

```python
from truce import TruceClient

client = TruceClient("http://localhost:8000")

# 1. Register two agents
buyer = client.register_agent("FIRM_A", "Alpha Trading", "buyer-bot")
seller = client.register_agent("FIRM_B", "Beta Exports", "seller-bot")

# 2. Authenticate both
client.authenticate(buyer.agent_id)
buy_offer = client.submit_offer(
    raw_text="Buying 100 MT of soybeans at $500/MT CIF, 45 day delivery, NET30",
    agent_id=buyer.agent_id,
    firm_id=buyer.firm_id,
)

client.authenticate(seller.agent_id)
sell_offer = client.submit_offer(
    raw_text="Selling 200 MT of soybeans at $490/MT CIF, 30 day delivery, NET30",
    agent_id=seller.agent_id,
    firm_id=seller.firm_id,
)

# 3. Find and execute match
matches = client.find_matches(buy_offer.offer_id)
if matches.total_found > 0:
    result = client.execute_match(buy_offer.offer_id, sell_offer.offer_id)
    print(f"Match executed: {result.match.match_id}")
    print(f"Settlement: {result.match.settlement_price} x {result.match.settlement_quantity}")

    # 4. Confirm escrow from both sides
    client.confirm_escrow(result.match.match_id, "buyer")
    client.confirm_escrow(result.match.match_id, "seller")
    print("Trade settled!")
```

## Requirements

- Python 3.9+
- httpx >= 0.25
- pydantic >= 2.0
- websockets >= 12.0

## License

Apache 2.0 -- see [LICENSE](../../LICENSE) for details.

## Links

- [Documentation](https://docs.truceprotocol.com)
- [Repository](https://github.com/truceprotocol/truce-core)
- [Issue Tracker](https://github.com/truceprotocol/truce-core/issues)
