Metadata-Version: 2.4
Name: oriora-c2
Version: 0.1.2
Summary: Oriora c2 — a local proxy that plugs Oriora's model-routing decision into any OpenAI-style agent. Your vendor key and prompts stay on your machine; only the routing decision crosses.
Project-URL: Homepage, https://orioralabs.com
Author: Orioralabs OÜ
License: MIT
License-File: LICENSE
Keywords: agent,ai,byok,litellm,llm,model-routing,openai,proxy,router
Requires-Python: <3.14,>=3.10
Requires-Dist: httpx>=0.24
Requires-Dist: litellm[proxy]>=1.0
Description-Content-Type: text/markdown

# oriora-c2

**Use Oriora's model-routing decision in any OpenAI-style agent — without your key or prompts ever
leaving your machine.**

`oriora-c2` runs a tiny **local proxy** on `127.0.0.1`. Your agent points at it; before each call it
asks Oriora's `/api/select` *"which model is best for this task?"*, then dispatches the call
**directly to the vendor on your own key**. Only the routing decision (task type + your candidate
models) crosses to Oriora — never the key, the prompt, or the response.

This is for **off-the-shelf agents** (Cursor, Aider, Continue, the raw `openai` SDK, LangChain
`ChatOpenAI`, …) that can't easily insert a "ask Oriora first" step. *Writing your own code?* You
don't need this — call `/api/select` directly (or `pip install oriora` and use `model_select()`).

## Install
```bash
pip install oriora-c2     # Python 3.10–3.13
```
> Python 3.14 is not supported yet — a dependency (litellm's pinned `orjson`) has no
> 3.14 build. If `python3 --version` says 3.14, create the venv with `python3.13 -m venv`.

## Run
```bash
oriora-c2 init                       # scaffolds config.yaml + .env.oriora-c2.example
# set your keys:
export ORIORA_API_KEY=sk_oriora_...  # the decision call only
export DEEPSEEK_API_KEY=...          # your own vendor keys (the actual call runs on these, locally)
export MINIMAX_API_KEY=...
oriora-c2 serve                      # local proxy on http://127.0.0.1:4000
```

Point any OpenAI client at it:
```python
from openai import OpenAI
c = OpenAI(base_url="http://127.0.0.1:4000/v1", api_key="anything")
c.chat.completions.create(model="oriora-auto", messages=[{"role":"user","content":"…"}])
# task type is auto-detected locally (free); or force it: model="oriora-auto:coding" (or :coding_hard)
```

> **Reasoning models behave vendor-native through the proxy.** The proxy never touches the
> response, so models like `deepseek-v4-pro` return their `reasoning_content` raw — and a tiny
> `max_tokens` budget can be consumed by reasoning before any answer text appears. Budget
> `max_tokens` generously (or pick non-reasoning candidates) for short-answer use.

## How it works
1. Agent → `http://127.0.0.1:4000` (`model="oriora-auto"`). Prompt never leaves your box.
2. The pre-call hook classifies the task **locally** (free regex rules + overshoot-biased difficulty escalation to `*_hard`, no LLM) → calls
   `POST /api/select` `{task_type, models}` — the **one** Oriora touch ($0.001/decision).
3. It rewrites `data["model"]` to the recommended model.
4. LiteLLM dispatches **direct to the vendor on your local key**; the stream flows vendor → you.

**Privacy / c2 invariant:** the proxy is **customer-hosted** (`127.0.0.1`). Only `{task_type, model
candidates}` reach Oriora. If a third party ever hosted this, it would no longer be c2.

**Fail-open:** if `/api/select` is slow (>`ORIORA_SELECT_TIMEOUT_S`, default 2.5s) or down, the hook
falls back to `ORIORA_FALLBACK_MODEL` so your agent is never blocked.

## Configuration (env)
| Var | Purpose |
|---|---|
| `ORIORA_API_KEY` | Oriora key for the decision call (required) |
| `DEEPSEEK_API_KEY`, `MINIMAX_API_KEY`, … | your own vendor keys (the call runs on these) |
| `ORIORA_CANDIDATES` | comma-sep catalog ids you hold keys for (sent to `/api/select`) |
| `ORIORA_FALLBACK_MODEL` | model used if the decision call fails (default `deepseek-v4-flash`) |
| `ORIORA_SELECT_TIMEOUT_S` | decision-call budget before fail-open (default `2.5`) |

Add a vendor = add its key + a `model_list` entry in `config.yaml` + its catalog id to
`ORIORA_CANDIDATES`. v1 ships configured for **DeepSeek + MiniMax** (OpenAI-format).

MIT © Orioralabs OÜ · https://orioralabs.com
