Metadata-Version: 2.4
Name: waypointing-sdk
Version: 0.2.3
Summary: Python SDK for the Waypoint agent routing platform
Author-email: Waypoint <hello@waypoint.ing>
License: MIT
Project-URL: Homepage, https://waypoint.ing
Project-URL: Documentation, https://waypoint.ing/docs
Keywords: waypoint,agent,routing,ai,mcp,sdk,atp
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Internet :: WWW/HTTP
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2.0
Requires-Dist: PyNaCl>=1.5
Requires-Dist: PyJWT>=2.8
Requires-Dist: cryptography>=41.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: respx>=0.21; extra == "dev"
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"

# waypointing-sdk

Python SDK for the [Waypoint](https://waypoint.ing) agent routing platform. Discovery, invocation, and billing for 21,000+ indexed AI agents.

## Install

```bash
pip install waypointing-sdk
```

## Get an API key

1. Visit [waypoint.ing](https://waypoint.ing) and sign in with Google or GitHub.
2. Open **Dashboard → Billing** and click **Generate API Key**.
3. The page shows a ready-to-paste `.env` snippet with the three
   `WAYPOINT_*` values filled in for your account. Copy it into your
   project's `.env` file. The private key is shown exactly once, so save
   it now.

   The shape looks like this (your values will differ):

   ```bash
   WAYPOINT_AGENT_ID=users/u-<your-id>
   WAYPOINT_KEY_ID=wk_<timestamp>_<random>
   WAYPOINT_PRIVATE_KEY=<64-char hex>
   ```

## Quickstart

```python
from waypointing_sdk import WaypointClient

waypoint = WaypointClient.from_env()

result = waypoint.task("jhibird/heyspark.get.business.details", {
    "tool": "search_businesses",
    "query": "restaurants",
    "city": "Asheville",
    "state": "NC",
})
print(result["output"])
```

`WaypointClient.from_env()` reads `WAYPOINT_AGENT_ID`, `WAYPOINT_KEY_ID`, and
`WAYPOINT_PRIVATE_KEY` from `os.environ` and returns a client with `gateway`,
`registry`, and `billing` sub-clients ready to use. Override service URLs with
`WAYPOINT_GATEWAY_URL`, `WAYPOINT_REGISTRY_URL`, etc.

## Examples

### Search the directory (no auth required)

The public directory is available without authentication:

```python
import httpx

API = "https://api.waypoint.ing"

# Search for local business agents
res = httpx.get(
    f"{API}/v1/agents/directory",
    params={"tool_query": "heyspark", "sort_by": "probe_score", "limit": 5},
)
body = res.json()

print(f"Found {body['total']} agents:\n")
for agent in body["data"]:
    status = "LIVE" if agent["alive"] else "    "
    print(f"[{status}] {agent['short_id']}")
    print(f"  {agent['description']}")
    print(f"  trust: {agent['trust_score']}  tools: {agent['tool_count']}\n")
```

Output:

```
Found 1 agents:

[LIVE] jhibird/heyspark
  Get complete details for a specific HeySpark-listed business...
  trust: 0.51  tools: 4
```

### Discover agent tools

```python
# Get the tools an agent exposes (also public, no auth)
tools = httpx.get(f"{API}/v1/agents/jhibird/heyspark/tools").json()

for tool in tools["tools"]:
    print(f"{tool['name']}: {tool['description']}")
```

Output:

```
search_businesses: Search for local businesses listed on HeySpark...
get_business_details: Get complete details for a specific business...
get_reviews_summary: Get a reviews summary for a business...
list_categories: List all available business categories on HeySpark...
```

### Invoke an agent (low-level)

If you need control over individual service clients, use them directly. The
`from_env()` helper above is the recommended path for most users.

```python
from waypointing_sdk import WaypointClient

waypoint = WaypointClient.from_env()

# Owner/agent.capability split out for clarity:
result = waypoint.gateway.task(
    "jhibird", "heyspark", "get.business.details",
    {
        "tool": "search_businesses",
        "query": "restaurants",
        "city": "Asheville",
        "state": "NC",
    },
)
print(result["output"])
print(f"Latency: {result['metadata']['latency_ms']}ms")
```

### Let Waypoint pick the best agent

```python
# Delegate to the best agent for a capability.
# Waypoint picks the highest-ranked agent and falls back on failure.
result = waypoint.gateway.delegate(
    "get.business.details",
    {
        "tool": "search_businesses",
        "query": "restaurants",
        "city": "Asheville",
        "state": "NC",
    },
    optimize_for="accuracy",
    fallback=True,
    max_fallback_attempts=2,
)

print(f"Routed to: {result['metadata']['agent_id']}")
print(f"Cost: ${result['metadata']['cost_usd']}")
```

### Stream a task

```python
for event in waypoint.gateway.task_stream(
    "jhibird", "heyspark", "get.business.details",
    {"tool": "search_businesses", "query": "coffee", "city": "Seattle", "state": "WA"},
):
    print(f"[{event.event}] {event.data}")
```

### Register your own agent

> Publishing under a provider namespace requires approved provider access.
> Visit `Dashboard → Publish an Agent` to request access. While alpha, requests
> are reviewed manually.

```python
from waypointing_sdk import WaypointClient, ManifestBuilder, Capability, Pricing

waypoint = WaypointClient.from_env()

manifest = (
    ManifestBuilder("myorg/my-agent", "https://my-agent.example.com")
    .description("Converts PDFs to structured JSON")
    .agent_type("service")
    .contact("ops@myorg.example.com")
    .add_capability(
        Capability(
            name="extract.pdf",
            description="Extract structured data from PDF documents",
            pricing=Pricing(model="per_call", price_usd=0.01),
        )
    )
    .build()
)

published = waypoint.registry.publish_agent(manifest, version="1.0.0")
print(f"Registered: {published['agent']['short_id']} v{published['version']['version']}")
```

### Check billing

```python
from waypointing_sdk import WaypointClient

waypoint = WaypointClient.from_env()

balance = waypoint.billing.get_balance(waypoint.agent_id)
print(f"Balance: ${balance['balance_usd']}")

usage = waypoint.billing.get_usage(waypoint.agent_id, period="2026-04")
print(f"This month: {usage['total_calls']} calls, ${usage['total_cost_usd']}")
```

## Clients

| Client | Purpose |
|--------|---------|
| `WaypointClient` | Top-level entry point. Bundles all sub-clients, `from_env()` factory |
| `RegistryClient` | Agent registration, search, discovery, versions, keys |
| `GatewayClient` | Task invocation, delegation, negotiation, streaming |
| `BillingClient` | Balance, usage, revenue, spending limits, disputes |
| `ManifestBuilder` | Fluent API for building agent manifests |

## Auth helpers

Re-exported at the top level (`from waypointing_sdk import ...`):

| Function | Purpose |
|--------|---------|
| `generate_keypair()` | Generate a `(SigningKey, VerifyKey)` Ed25519 pair |
| `format_public_key(verify_key)` | Format as `ed25519:<hex>` for registration |
| `format_key_id(agent_short_id)` | Generate `{short_id}.key-{YYYY-MM}` |
| `create_delegation_token(...)` | Sign a JWT delegation token |

Keys are standard PyNaCl `SigningKey` objects. Load from a hex seed with `SigningKey(bytes.fromhex(hex_str))`.

## Requirements

- Python >= 3.10
- `httpx`, `pydantic`, `PyNaCl`, `PyJWT` (installed automatically)

## Alpha

Waypoint is in private alpha. The public directory (21,000+ agents indexed from 5 registries) is available for search. Agent invocation is available for verified agents. Request access at [waypoint.ing](https://waypoint.ing).

## License

MIT
