← Về thư mục
📄 / / proc / 45 / cwd / root / .hermes / skills-backup-20260914-152439 / devops / 9router-ops / SKILL.md

name: 9router-ops description: "Administer and configure 9Router local infrastructure, including model mapping, provider injection, and database-level troubleshooting." version: 1.0.0 author: CEO Assistant


9Router Operations

Guidelines for managing the local 9Router (Open-SSE) instance used as the model gateway for Hermes.

Database Management

The 9Router state is stored in SQLite at /root/.9router/db/data.sqlite.

Bypassing UI Validation (Direct Injection)

The 9Router UI may fail to validate credentials if it hardcodes regions (e.g., Alibaba China instead of Singapore). Bypass this by injecting directly into providerConnections:

import sqlite3, json, uuid
conn = sqlite3.connect('/root/.9router/db/data.sqlite')
c = conn.cursor()
# providerSpecificData must contain 'baseUrl' for openai-compatible types
# Use prefix 'openai-compatible-' in 'provider' field to enable custom endpoints
data = {
    "provider": "openai-compatible-alibaba",
    "apiKey": "REDACTED",
    "providerSpecificData": {"baseUrl": "https://.../v1"}
}
c.execute("INSERT INTO providerConnections (...) VALUES (...)", (...))
conn.commit()

Model Mapping & Combos

Combo Structure

9Router Model Naming Conventions

Troubleshooting

HTTP 401/404 on Valid Keys

infinite Loops

Check the default combo for self-references. If default contains "default", it may cause recursion errors during model resolution.

API Key — Critical Gotchas

LOCAL9R_KEY is stored truncated in .env

The LOCAL9R_KEY value in all Hermes profile .env files is stored in truncated/placeholder form: sk-510...d02a. This is NOT the real usable key — the ... is literally part of the stored string.

To check the actual key stored in 9Router's DB:

python3 -c "import sqlite3; c=sqlite3.connect('/root/.9router/db/data.sqlite'); r=c.execute(\"SELECT key FROM apiKeys WHERE name='hermes'\").fetchone(); print(len(r[0]), r[0])"

The real key is 35 chars including the ... — this IS the full key 9Router accepts. If Bearer auth returns {"error":"API key required for remote API access"}, the request is being treated as remote (not from localhost); 9Router exempts 127.0.0.1 in some modes.

The browser-facing dashboard endpoints (/api/combos, /api/models, etc.) require a browser session cookie, not a Bearer token. They return HTTP 401 for any curl/Bearer request.

Do NOT try to CRUD combos via curl /api/combos. Use direct SQLite + docker restart instead.

DB cache — UI may lag behind direct file edits

9Router loads SQLite at container startup. Direct edits to /root/.9router/db/data.sqlite while the container is running may not appear in UI until restart.

Correct workflow for direct DB edits: 1. Write changes via python3 sqlite3 module to the host-mounted file. 2. docker restart 9router — flushes in-memory state, re-reads DB. 3. Verify in UI or via /v1/models endpoint.

Combo kind field — valid values

The kind column controls routing strategy. If UI shows "No combos yet" after a direct DB insert, check kind:

Value Meaning
NULL Original default — safest for direct inserts
'llm' LLM combo
'fallback' Ordered fallback
'round-robin' Rotates models
'fusion' Parallel + judge synthesis

Setting kind = NULL (matching the original default combo schema) is the most reliable value when inserting via raw SQL.

Verification

Always verify model availability via the local gateway endpoint: GET http://127.0.0.1:20128/v1/models (Bearer LOCAL9R_KEY; see gotchas above).

For detailed staged rollout and verification steps, see references/9router-hermes-staged-rollout.md.