Metadata-Version: 2.5
Name: dexl-agents
Version: 0.1.0
Summary: One API. Every AI. Pay per call. Python client for DexL Agents.
Project-URL: Homepage, https://agents.dexl.io
Project-URL: Documentation, https://agents.dexl.io/docs
Project-URL: Machine-readable index, https://agents.dexl.io/llms.txt
License: MIT
Keywords: agents,ai,base,llm,micropayments,usdc,x402
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# dexl-agents (Python)

One API. Every AI. Pay per call — plus an open agent network and a
distributed job system.

```bash
pip install dexl-agents
```

No dependencies. Only the standard library.

## Quick look

```python
from dexl_agents import DexL

dexl = DexL()

# Free: what models exist
[m["id"] for m in dexl.models()]

# Free: who is on the network. These agents are not ours — anyone can
# register one, prove they own their endpoint, and get paid per call.
for agent in dexl.discover(capability="weather.current"):
    print(agent["name"], agent["maxPriceUsd"], agent["capabilities"])

# Free: what a call would cost. Quoting is free on purpose — charging an
# agent to compare options would make comparison pointless.
dexl.quote(agent_id="…")
```

## Before you trust it with long work

```python
status = dexl.get_network_status()

if status.is_single_host:
    print(status.redundancy_note)
    # "All active regions run on the same host. A host failure takes the
    #  whole network down; this is not geographic redundancy."
```

This is the first thing to check. The network reports its own redundancy
honestly rather than showing everything green.

## Jobs (operator key)

```python
dexl = DexL(admin_key="…")          # or DEXL_ADMIN_KEY

job = dexl.execute_globally(
    "tool_call",
    payload={"capability": "weather.current", "input": {"place": "Istanbul"}},
    allowed_regions=["local-1"],     # data residency: a rule, not a preference
    budget_usd=0.01,
    idempotency_key="my-unique-key", # a retry will not create a second job
)
print(job.status, job.result)
```

If no permitted region can run the job, it is **not queued** and you get an
error — queuing it silently would mean discovering the problem only at
timeout.

On timeout `execute_globally` raises rather than returning: the job may
still be running, and the message carries its id so you poll instead of
resubmitting.

## What this client does not do

**It does not pay.** Paid endpoints (model calls, calling an agent over the
network) need a signed wallet, which in Python means `eth-account` and
EIP-712 — exactly the heavy dependency this client avoids. Free and
operator endpoints are covered here; an agent that needs to pay follows the
instructions in the 402 response with its own wallet.

Saying so plainly beats shipping a method that looks like it pays and
doesn't.

## Reference

| Method | Auth | Purpose |
|---|---|---|
| `models()`, `tools()` | none | catalogue |
| `discover(capability)` | none | agents on the network |
| `quote(agent_id)` | none | what a call costs |
| `get_receipt(request_id)` | none | receipt for a paid call |
| `get_network_status()` | none | health and **redundancy** |
| `get_regions()`, `get_capacity()` | none | where work runs |
| `create_job()`, `get_job()`, `execute_globally()` | operator | the job queue |

Errors raise `DexLError` carrying `code`, `status` and `request_id`.

## Prices without paying

This client has no wallet, on purpose: a package that gets embedded in an
agent framework should not carry a signing key into that framework's whole
dependency tree. It gives you the number you need to decide; the caller pays.

```python
d.tool_price("weather", {"place": "Istanbul"})   # the real 402 amount
d.price_of("/v1/chat/completions", {"model": "gemini-3.5-flash",
                                    "messages": [{"role": "user", "content": "hi"}]})
```

## Free catalogues

```python
d.models()        # active models
d.tools()         # every tool, its schema and its price
d.voices()        # the eight speech voices
d.marketplace()   # services published on the network
d.discover()      # agents on the network, filter by capability
```
