<!-- OpenSmartRoute: Python SDK quickstart. https://opensmartroute.ai/docs/QUICKSTART_SDK -->
# Python SDK quickstart

Route between models, agents, skills, tools and humans inside your own process in about five
minutes. The core package has zero runtime dependencies; everything here runs offline. The
[user guide](https://opensmartroute.ai/docs/GUIDE.md) continues where this page stops - real providers, plans, learning, the
enterprise builder.

## 1. Install

```bash
pip install opensmartroute                       # library only, zero runtime dependencies
pip install 'opensmartroute[yaml]'               # + YAML catalogues and rules
pip install 'opensmartroute[server]'             # + FastAPI server and OpenAI-compatible proxy
```

Or install the `osr` command line together with the package:

```bash
curl -LsSf https://opensmartroute.ai/install.sh | sh   # Windows: irm https://opensmartroute.ai/install.ps1 | iex
```

## 2. Describe your targets

A target is anything a request can be sent to. Declare what each one is good at, what it costs and
how fast it is; the router does the rest.

```python
from opensmartroute import Router, TargetRegistry, RouteTarget, TargetKind, Capabilities, Outcome, TargetConstraints

registry = TargetRegistry([
    RouteTarget("llm-small", TargetKind.LLM,
                capabilities=Capabilities(max_complexity=0.45),
                cost={"usd_per_1k_tokens": 0.0002}, latency_ms=300, quality_prior=0.55,
                examples=["Hi, how are you?", "What is the capital of France?"]),
    RouteTarget("llm-frontier", TargetKind.LLM,
                capabilities=Capabilities(min_complexity=0.5, domains=["math", "coding"]),
                cost={"usd_per_1k_tokens": 0.015}, latency_ms=2500, quality_prior=0.93,
                examples=["Prove the theorem step by step."]),
    RouteTarget("llm-onprem", TargetKind.LLM,
                capabilities=Capabilities(domains=["general"]),
                constraints=TargetConstraints(regions=["eu"], data_boundary="private", pii_allowed=True),
                cost={"usd_per_1k_tokens": 0.001}, latency_ms=1200, quality_prior=0.7),
    RouteTarget("human", TargetKind.HUMAN,
                capabilities=Capabilities(actions=["escalate"], tags=["safety"]),
                cost={"usd_per_1k_tokens": 0.5}, latency_ms=300_000),
])
```

Catalogues also load from YAML or JSON files, MCP `tools/list` payloads, A2A agent cards, SKILL.md
and persona directories - see the [user guide](https://opensmartroute.ai/docs/GUIDE.md#1-targets).

## 3. Route

```python
router = Router(registry)
d = router.route("Prove that sqrt(2) is irrational, step by step.")
print(d.target.id, f"{d.confidence:.2f}")     # llm-frontier 0.89
print(d.trace.explain())                       # per-strategy scores and rationales
```

Every decision carries a trace: which signals were extracted, which targets policy rejected and why,
how each strategy scored the rest. Nothing is a black box.

Every `route()` call runs the same five stages - the trace records each one:

```mermaid
flowchart TB
    R["router.route(request)"] --> SIG["Signals: complexity, domains, intent, PII"]
    SIG --> POL{"Policy: hard constraints + rules"}
    POL -->|rejected| REJ["trace.policy_rejections"]
    POL -->|admissible| STR["Strategies score each candidate"]
    STR --> ENS["Ensemble to utility, weighted by the objective"]
    ENS --> DEC["Decision: target, confidence, alternatives, trace"]
```

## 4. Constraints and objectives

Hard constraints are filtered before any scoring - they are never traded off against quality. The
objective sets the trade-off between quality, cost and latency per request. A note with private
patient data only clears the on-prem target; the public models are excluded before scoring begins.

```python
from opensmartroute import RouteRequest, RequestConstraints, Objective

req = RouteRequest("Summarize this patient intake note.",
                   constraints=RequestConstraints(region="eu", data_boundary="private", max_cost_per_1k=0.005),
                   objective=Objective(quality=1.0, cost=0.5, latency=0.1))
d = router.route(req)
print(d.target.id)                 # llm-onprem
print(d.trace.policy_rejections)   # {'llm-small': 'data boundary public < required private', ...}
```

## 5. Close the loop

Report how the routed answer went and the router's learners (bandits, IRT, Bradley-Terry) shift
future decisions toward what actually works for your traffic:

```python
router.learn(Outcome(request_id=d.request_id, target_id=d.target.id, success=True,
                     quality=0.9, cost_usd=0.002, latency_ms=1800, domains=d.trace.signals.domains))
```

Attach handlers to targets and `router.run(req)` executes the chosen target or plan and records the
outcomes itself - wiring real providers is the
[user guide's fourth chapter](https://opensmartroute.ai/docs/GUIDE.md#4-real-providers).

## 6. The same thing from the command line

```bash
osr -t examples/targets.yaml -r examples/rules.yaml route "I want a refund for order #123" --plan
osr -t examples/targets.yaml -r examples/rules.yaml eval examples/eval_dataset.jsonl --frontier
osr -t examples/targets.yaml -r examples/rules.yaml serve        # http://127.0.0.1:8000/docs
```

`osr serve` exposes the same `/route`, `/feedback` and OpenAI-compatible `/v1/chat/completions`
endpoints as the hosted platform - point any OpenAI client at it with `model="auto"`.

## Where next

- [User guide](https://opensmartroute.ai/docs/GUIDE.md) - targets, rules, providers, plans, learning, the CLI, latency numbers.
- [SDK guide](https://opensmartroute.ai/docs/SDK.md) - decorators, settings, error handling, threading, extension points.
- [Enterprise builder](https://opensmartroute.ai/docs/ENTERPRISE.md) - middleware, telemetry, stores, shadow and A/B rollout.
- [Deploy with Docker and Helm](https://opensmartroute.ai/docs/deploy.md) - run `osr serve` on your own infrastructure.
- [Platform quickstart](https://opensmartroute.ai/docs/QUICKSTART_PLATFORM.md) - the hosted version of everything above.
