EnroutiaEU

SDKs for Python and JavaScript

Two thin layers over the official OpenAI SDKs. Your calls stay exactly as they are; the SDK adds tags to each one, keeps what the router decided, and gives you a live tail of the project's calls.

Install

Neither is on PyPI or npm yet. Install the Python one straight from the repository; build the JavaScript one from a checkout and install the folder.

# Python 3.10+
pip install "git+https://github.com/rafa-sealmetrics/enroutia.git#subdirectory=sdk/python"

# Node 20+
git clone https://github.com/rafa-sealmetrics/enroutia.git
(cd enroutia/sdk/js && pnpm install && pnpm build)
npm install /path/to/enroutia/sdk/js

Python

Enroutia(...) builds an openai.OpenAI pointed at the gateway. chat.completions.create sends the client's tags plus the call's own as metadata.tags; after the call, last_resolved_model and last_auto_reason hold the X-Resolved-Model and X-Auto-Reason headers, streamed answers included. Everything else is the OpenAI client unchanged.

from enroutia import Enroutia

client = Enroutia(
    api_key="YOUR_KEY",
    base_url="https://api.enroutia.com/v1",
    tags={"workflow": "lead-scoring", "client": "acme"},
)
answer = client.chat.completions.create(
    model="auto",
    messages=[{"role": "user", "content": "Classify this lead: …"}],
    tags={"node": "classify"},
)
print(client.last_resolved_model, client.last_auto_reason)  # mistral-small short

JavaScript and TypeScript

The same contract over the openai npm package: pass tags to new Enroutia and, per call, to chat.completions.create; then read lastResolvedModel and lastAutoReason. client.openai is the wrapped client for everything else.

import { Enroutia } from "enroutia";

const client = new Enroutia({
  apiKey: "YOUR_KEY",
  baseURL: "https://api.enroutia.com/v1",
  tags: { workflow: "lead-scoring", client: "acme" },
});
const answer = await client.chat.completions.create({
  model: "auto",
  messages: [{ role: "user", content: "Classify this lead: …" }],
  tags: { node: "classify" },
});
console.log(client.lastResolvedModel, client.lastAutoReason);

Tags

At most eight per call, keys of lowercase letters, digits, underscore and hyphen up to 32 characters, values up to 64. The gateway drops a pair that does not fit; the SDKs refuse it before sending, so a workflow never vanishes from the bill silently. withTags / with_tags gives a client that shares the connection and adds tags.

Live tail

tail() yields every new call of the project, from the same stream as the panel's Live tab. It needs an account token with the read scope, not an inference key. It reconnects on its own when the server closes the stream after ten minutes, resuming from the last event, waits out a 429 when three tails are already open and any other error (a 502 during a deploy, a 503, a dropped connection) with a backoff that doubles up to a minute, and stops with an error only on 401, 403 or 404.

# Python
import enroutia
for call in enroutia.tail("pat_…", base_url="https://platform.enroutia.com"):
    print(call["served_alias"], call["tags"], call["cents"])

// JavaScript
import { tail } from "enroutia";
for await (const call of tail({ token: "pat_…", baseURL: "https://platform.enroutia.com" })) {
  console.log(call.served_alias, call.tags, call.cents);
}

See also: Tags and cost per automation · Start in five minutes · Guide per tool