Skip to main content

The two-faced AI routing gateway

Project description

Janus

The two-faced gateway for AI coding tools. Janus sits at the threshold of every AI call — facing the developer on one side and every provider on the other.

Janus is a local-first, single-user AI routing gateway. It exposes OpenAI/Anthropic/Gemini-compatible HTTP endpoints that your coding tools (Claude Code, Codex, Cursor, Cline, ...) talk to, then translates and routes each request to 40+ AI providers — without either side needing to know the other exists.

First-time setup

Janus needs Python 3.11+. Everything lives under ~/.janus/ — a seed config.yaml and a SQLite database (janus.db) that becomes the source of truth after the first startup.

1. Install

From PyPI (recommended):

pip install janus-ai

From source (development):

git clone https://github.com/amanverasia/Janus.git
cd Janus
python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -e ".[dev]"

2. Create config

janus config-init

This writes ~/.janus/config.yaml. Open it and add at least one provider with your API keys. Environment variables in ${VAR} form are resolved at startup:

export OPENAI_API_KEY=sk-...
export ANTHROPIC_API_KEY=sk-ant-...

Example provider block:

providers:
  - id: openai
    prefix: openai
    api_type: openai_compat
    base_url: https://api.openai.com/v1
    api_key: ${OPENAI_API_KEY}
    models: [gpt-4o, gpt-4o-mini]

You can also add providers later from the dashboard — no restart required.

3. Start the server

janus serve --port 20128

For access from other machines on your LAN or Tailscale:

janus serve --host 0.0.0.0 --port 20128

Janus serves plain HTTP only. Use http://, not https://, unless you put a reverse proxy with TLS in front.

4. Verify

curl http://localhost:20128/v1/health
# {"status":"ok"}

Open the dashboard at http://localhost:20128/dashboard. The root URL / redirects there.

5. Configure via dashboard

On first startup, Janus imports providers, combos, token_savers, and pricing from YAML into SQLite. After that, the database is authoritative — editing YAML and restarting will not re-apply changes. Use the dashboard instead.

Step Where What
Add providers Providers Pick from the catalog or add custom; fetch models, test connection
Create a client key API Keys sk-janus-... shown once — save it
Enable auth Settings Toggle Require API key (recommended for remote access)
Set dashboard login Settings → Dashboard Login Username + password for remote browser sign-in
Connect your tools Tool Setup Copy-paste env vars for Claude Code, Codex, Cursor, Cline

Dashboard access rules:

  • localhost — no sign-in required
  • Remote (LAN, Tailscale, Docker on 0.0.0.0) — sign in at /dashboard/login with your dashboard username/password or a Janus API key

Create a key from the CLI instead:

janus keys create --name "my-laptop"

6. Send a test request

curl http://localhost:20128/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4o",
    "messages": [{"role": "user", "content": "Hello!"}],
    "max_tokens": 50
  }'

List registered models:

curl http://localhost:20128/v1/models

7. Point your coding tool at Janus

Claude Code / Anthropic tools:

export ANTHROPIC_BASE_URL=http://localhost:20128/v1
export ANTHROPIC_API_KEY=sk-janus-yourkey   # if require_api_key is on

OpenAI-compatible tools (Codex, Cursor, Cline, etc.):

export OPENAI_BASE_URL=http://localhost:20128/v1
export OPENAI_API_KEY=sk-janus-yourkey      # if require_api_key is on

Use prefix/model in requests (e.g. openai/gpt-4o, anthropic/claude-sonnet-4-20250514) or a combo name like best-effort.

📚 Documentation · Contributing · Changelog

Docker

mkdir -p janus-data
janus config-init --path janus-data/config.yaml
# Edit janus-data/config.yaml — add providers and ${ENV_VAR} keys

# Optional: pass API keys via .env in the repo root
echo 'OPENAI_API_KEY=sk-...' >> .env

docker compose up -d

The image binds to 0.0.0.0:20128. SQLite and config persist in ./janus-data/. After first startup, manage providers and settings from the dashboard — not by editing YAML alone.

Remote dashboard: enable Require API key in Settings, create a Janus API key, and set a dashboard username/password under Dashboard Login.

curl http://localhost:20128/v1/health
open http://localhost:20128/dashboard    # macOS; or visit in your browser

Configuration

Janus reads YAML from ~/.janus/config.yaml (or --config) with ${ENV_VAR} token resolution. Generate a template with janus config-init.

On first startup only, YAML seeds the SQLite database. Subsequent changes should be made via the dashboard or Export Config / Reset to Defaults on the Settings page.

server:
  port: 20128
  host: 127.0.0.1
  require_api_key: false

providers:
  - id: openai
    prefix: openai
    api_type: openai_compat
    base_url: https://api.openai.com/v1
    api_key: ${OPENAI_API_KEY}
    models: [gpt-4o, gpt-4o-mini, o3, o4-mini]

  - id: anthropic
    prefix: anthropic
    api_type: anthropic
    base_url: https://api.anthropic.com
    api_key: ${ANTHROPIC_API_KEY}
    models: [claude-sonnet-4-20250514, claude-opus-4-20250514]

combos:
  - name: best-effort
    models: [anthropic/claude-sonnet-4-20250514, openai/gpt-4o]

Supported Provider Types

api_type Use For
openai_compat Any OpenAI-compatible API (OpenAI, Groq, Together, DeepSeek, OpenRouter, Mistral, Fireworks, Perplexity, xAI, ...)
anthropic Direct Anthropic API
gemini Direct Google Gemini API
opencode_free OpenCode Zen free tier

Known Provider Base URLs

Provider base_url
OpenAI https://api.openai.com/v1
Groq https://api.groq.com/openai/v1
Together AI https://api.together.xyz/v1
DeepSeek https://api.deepseek.com/v1
OpenRouter https://openrouter.ai/api/v1
Mistral https://api.mistral.ai/v1
Fireworks https://api.fireworks.ai/inference/v1
Perplexity https://api.perplexity.ai
xAI (Grok) https://api.x.ai/v1
Qwen/DashScope https://dashscope.aliyuncs.com/compatible-mode/v1

Client Setup

See step 7 in First-time setup for the basics. The dashboard Tool Setup page (/dashboard/tools) generates copy-paste env vars for your exact server URL and auth settings.

Claude Code / Anthropic tools:

export ANTHROPIC_BASE_URL=http://localhost:20128/v1

OpenAI tools (Codex, Cursor, etc.):

export OPENAI_BASE_URL=http://localhost:20128/v1
export OPENAI_API_KEY=sk-janus-yourkey  # if require_api_key is on

Features

  • Fallback routing — multi-account rotation with cooldowns (429->60s, 5xx->30s, auth->300s, network->15s)
  • Combos — named ordered model sequences (e.g., "model": "best-effort")
  • Token savers — RTK compression (default ON), Caveman terse prompt, Ponytail lazy-dev prompt
  • Budgets — daily spending limits per API key or global, with warn/block thresholds
  • Analytics — cost tracking, spend trends, success rates, per-model/provider/key breakdowns
  • Pricing — 28 builtin model prices, YAML-overridable, cache token rates
  • Dashboard — HTMX UI at /dashboard with charts, budget management, usage stats, and remote username/password login
  • Upstream key inventory — validate, monitor, and route through a multi-key pool for 29 providers (/dashboard/inventory)

Upstream Key Inventory

Built-in dashboard for upstream provider API keys: health checks, credit tracking, and automatic routing through the best available key.

Dashboard: http://127.0.0.1:20128/dashboard/inventory

  • Overview stats, paginated/sortable keys table, key detail modal, best-keys widget
  • Add keys, bulk submit, import from Dashboard export JSON, re-identify misclassified keys
  • Encryption at rest; routable keys wired into gateway fallback rotation
  • Background recheck scheduler (twice daily by default)
Variable Purpose
INVENTORY_ENCRYPTION_KEY Fernet key for encrypting upstream keys at rest
INVENTORY_PUSH_TOKEN Auth token for POST /dashboard/api/inventory/push
INVENTORY_SCHEDULER_ENABLED Set to false to disable background rechecks (default: true)
janus inventory generate-encryption-key          # create Fernet key
janus inventory migrate export.json --verify     # import Dashboard export + summary
janus inventory verify                           # cutover verification summary
janus inventory encrypt-keys                       # encrypt plaintext keys in DB

CLI Reference

Command Description
janus serve Start the gateway server
janus config-init Generate default config YAML
janus config-path Print config file path
janus keys create/list/revoke Manage API keys
janus usage stats/cost/by-key Usage and cost reports
janus budgets list/set/delete Manage spending budgets
janus pricing list/show View model pricing
janus inventory migrate/verify/encrypt-keys/generate-encryption-key Upstream key inventory and cutover

Development

git clone https://github.com/amanverasia/Janus.git
cd Janus
python -m venv .venv
pip install -e ".[dev]"

# Run tests
.venv/bin/python -m pytest

# Lint + typecheck
.venv/bin/ruff check src/janus/ tests/
.venv/bin/mypy src/janus/

# Start dev server
.venv/bin/janus serve --port 20128 --reload

Tech Stack

Python 3.11+ / FastAPI / httpx / Pydantic v2 / aiosqlite / Jinja2 / HTMX / Chart.js

License

GPL-3.0 © 2026 Aman Verasia

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

janus_ai-0.3.2.tar.gz (309.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

janus_ai-0.3.2-py3-none-any.whl (177.0 kB view details)

Uploaded Python 3

File details

Details for the file janus_ai-0.3.2.tar.gz.

File metadata

  • Download URL: janus_ai-0.3.2.tar.gz
  • Upload date:
  • Size: 309.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for janus_ai-0.3.2.tar.gz
Algorithm Hash digest
SHA256 790571bf0473619d855464513c4d2ede54fdd465739487e4d3a98dccb9fe044a
MD5 18f6d9ec5629b344bec2e157078aeecd
BLAKE2b-256 a73a114a3d3abc345a654b09948406cf3126cc4f003d13b08aa2500e044bc677

See more details on using hashes here.

Provenance

The following attestation bundles were made for janus_ai-0.3.2.tar.gz:

Publisher: publish.yml on amanverasia/Janus

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file janus_ai-0.3.2-py3-none-any.whl.

File metadata

  • Download URL: janus_ai-0.3.2-py3-none-any.whl
  • Upload date:
  • Size: 177.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for janus_ai-0.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 c61ec9f4e6b5ebfe9385d72394c16b6897463390d1dcaf05ff482731cff7942e
MD5 8756ce88d78ec8967c10e698d3515f66
BLAKE2b-256 c309f7fb61a1debf3f023556fe949f65674192952d49ae0a03f053774ed5795d

See more details on using hashes here.

Provenance

The following attestation bundles were made for janus_ai-0.3.2-py3-none-any.whl:

Publisher: publish.yml on amanverasia/Janus

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page