Metadata-Version: 2.4
Name: aiarbitration
Version: 0.1.0
Summary: Python SDK for the AIArbitration intelligent AI model router
Project-URL: Homepage, https://theaiarbitration.com
Project-URL: Documentation, https://theaiarbitration.com/docs
Project-URL: Repository, https://github.com/Neural-Systems-Ltd/AIArbitration
Project-URL: Bug Tracker, https://github.com/Neural-Systems-Ltd/AIArbitration/issues
License: MIT
Keywords: ai,anthropic,arbitration,llm,openai,routing
Requires-Python: >=3.11
Requires-Dist: httpx>=0.27
Provides-Extra: dev
Requires-Dist: pytest; extra == 'dev'
Requires-Dist: pytest-asyncio; extra == 'dev'
Requires-Dist: respx; extra == 'dev'
Description-Content-Type: text/markdown

# aiarbitration · Python SDK

Intelligent AI model routing for Python applications.  
AIArbitration selects the best model for every request — balancing cost, latency, capability, and compliance — and falls back automatically on failure.

```bash
pip install aiarbitration
```

Requires Python 3.11+.

---

## Quick start

```python
from aiarbitration import AIArbitrationClient

# Option A — supply a JWT obtained from your login flow
client = AIArbitrationClient(
    base_url="https://api.theaiarbitration.com",
    api_key="<your-jwt-token>",
)

# Option B — let the SDK authenticate for you
client = AIArbitrationClient.login(
    base_url="https://api.theaiarbitration.com",
    email="you@example.com",
    password="s3cr3t",
)

response = client.execute("Explain quantum entanglement in one sentence.")
print(response.content)
# → "Quantum entanglement is a phenomenon where two particles ..."
print(f"Model: {response.model_used}  Cost: ${response.cost:.6f}")
```

---

## Streaming

```python
for chunk in client.stream("Write a short poem about the ocean."):
    print(chunk.content, end="", flush=True)
    if chunk.is_done:
        break
```

### Async streaming

```python
import asyncio
from aiarbitration import AIArbitrationClient

async def main():
    client = AIArbitrationClient(base_url="...", api_key="...")
    async for chunk in client.stream_async("Tell me about black holes."):
        print(chunk.content, end="", flush=True)

asyncio.run(main())
```

---

## Structured request

```python
from aiarbitration import AIArbitrationClient, ChatRequest, ChatMessage

request = ChatRequest(
    messages=[
        ChatMessage.system("You are a concise technical assistant."),
        ChatMessage.user("What is a transformer model?"),
    ],
    task_type="general",
    max_cost_usd=0.05,          # reject models over $0.05 for this request
    required_region="eu-west-1" # GDPR: EU-only providers
)

response = client.execute(request)
```

---

## Cost estimate (dry run)

```python
estimate = client.estimate("Summarise this 10,000-word document.")
print(f"Selected model : {estimate.selected_model.model_id}")
print(f"Estimated cost : ${estimate.estimated_cost:.6f}")
print(f"Candidates     : {len(estimate.all_candidates)}")
```

---

## Image generation

```python
from aiarbitration import ImageGenerationRequest

result = client.generate_image(ImageGenerationRequest(
    prompt="Futuristic smart city at golden hour, photorealistic",
    size="1024x1024",
))
print(result.image_url)
```

---

## Batch execution

```python
from aiarbitration import ChatRequest, ChatMessage

requests = [
    ChatRequest(messages=[ChatMessage.user(q)])
    for q in ["What is Python?", "What is Rust?", "What is Go?"]
]

batch = client.execute_batch(requests)
print(f"Success rate: {batch.success_rate:.0%}  Total cost: ${batch.total_cost:.6f}")
for r in batch.successful_responses:
    print(r.content[:80])
```

---

## List available models

```python
models = client.get_models(vision=True, tier="flagship")
for m in models:
    print(f"{m.display_name:30}  {m.context_window:,} ctx  ${m.cost_per_million_input_tokens}/M")
```

---

## Drop-in OpenAI replacement

AIArbitration exposes an OpenAI-compatible endpoint at `/v1`.  
Point the official OpenAI SDK at it and your existing code works unchanged:

```python
import openai

openai.base_url = "https://api.theaiarbitration.com/v1"
openai.api_key  = "<your-jwt-token>"

response = openai.chat.completions.create(
    model="arbitrated",  # let the engine choose, or pin a specific model
    messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)
```

---

## Error handling

```python
from aiarbitration import (
    AIArbitrationError,
    AuthenticationError,
    BudgetExceededError,
    RateLimitError,
    ServiceUnavailableError,
)

try:
    response = client.execute("...")
except AuthenticationError:
    print("Invalid or expired token — re-authenticate.")
except RateLimitError:
    print("Quota reached — upgrade your plan.")
except BudgetExceededError:
    print("Request cost would exceed your budget cap.")
except ServiceUnavailableError:
    print("All models are currently unavailable — try again shortly.")
except AIArbitrationError as e:
    print(f"API error {e.status_code}: {e}")
```

---

## Configuration reference

| Parameter | Default | Description |
|---|---|---|
| `base_url` | — | API base URL (required) |
| `api_key` | `None` | JWT bearer token |
| `timeout` | `120.0` | Request timeout in seconds |
| `streaming_timeout` | `300.0` | Streaming request timeout in seconds |

---

## Links

- [API reference](https://theaiarbitration.com/docs)
- [GitHub](https://github.com/Neural-Systems-Ltd/AIArbitration)
- [.NET SDK on NuGet](https://www.nuget.org/packages/AIArbitration.Client)
