mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-09 16:53:13 +03:00
New package that wires OpenHands agent-server to OmniRoute: - env.ts: generates OpenHands .env (LLM_MODEL, LLM_BASE_URL, LLM_API_KEY, OH_PERSISTENCE_DIR, PERMITTED_CORS_ORIGINS) - docker.ts: Docker Compose + docker run generators with the field-proven fixes baked in (privileged sandbox, host.docker.internal:host-gateway, persistence volume, CORS) - model-map.ts: OpenHands model names → OmniRoute model/combo IDs - cli.ts: omniroute-openhands <env|compose|docker-run|models> - tests: 8 cases (env, model map, compose, docker run) — all passing - skills/omni-openhands/SKILL.md + README catalog entry
@omniroute/openhands-plugin
OpenHands integration for the OmniRoute AI Gateway. Generates the OpenHands environment and Docker config that wires an OpenHands agent-server to a running OmniRoute instance — with the integration gotchas already handled.
Why
Running OpenHands against OmniRoute directly hits several wall:
- Model name mismatch — OpenHands sends
model: "deepseek-chat", OmniRoute uses provider-prefixed IDs (ds/deepseek-v4-flash) or combos. - Python 3.13 sandbox —
socket.socketpair()fails under Docker's default seccomp profile; the agent-server needsprivileged: true. - Host reachability — the sandbox can't resolve
localhostto the OmniRoute host; needshost.docker.internal:host-gateway. - Lost state — conversations die with the container unless
OH_PERSISTENCE_DIRis a host volume. - CORS — the dashboard origin can't reach agent-server unless
PERMITTED_CORS_ORIGINSallows it.
This plugin encodes all of that into one command.
Install
npm install -g @omniroute/openhands-plugin
# or: npx @omniroute/openhands-plugin ...
Quick start
Generate the OpenHands .env:
omniroute-openhands env \
--api-key sk-... \
--model deepseek-chat \
--url http://192.168.3.106:20128
Generate a docker-compose.yml service:
omniroute-openhands compose \
--api-key sk-... \
--model glm-5.2 \
--persistence-dir /Users/me/.openhands-state \
--cors-origins http://100.73.44.17:3000
Or a plain docker run:
omniroute-openhands docker-run \
--api-key sk-... \
--model vivanta-core \
--persistence-dir /Users/me/.openhands-state
Commands
| Command | Description |
|---|---|
env |
Print OpenHands .env contents |
compose |
Print a Docker Compose service block |
docker-run |
Print a full docker run command |
models |
Print the default OpenHands → OmniRoute model map |
Common options
| Flag | Description | Default |
|---|---|---|
--api-key |
OmniRoute API key (sk-...) |
— |
--model |
OpenHands model name or OmniRoute combo | — |
--url |
OmniRoute base URL | http://localhost:20128 |
--persistence-dir |
Host dir for conversation state | .openhands-state |
--cors-origins |
Comma-separated allowed origins | localhost:3000,3001 |
--sandbox-image |
OpenHands sandbox base image | — |
Model mapping
OpenHands-friendly names are mapped to OmniRoute IDs/combo names:
| OpenHands sends | OmniRoute resolves to |
|---|---|
deepseek-chat |
ds/deepseek-v4-flash |
deepseek-reasoner |
ds/deepseek-v4-pro |
glm-5.2 |
nvidia/z-ai/glm-5.2 |
gpt-4o |
openai/gpt-4o |
claude-sonnet-4.5 |
anthropic/claude-sonnet-4.5 |
| ... | ... |
Or just pass an OmniRoute combo name (e.g. --model vivanta-core) — the Model
Alias Resolver and combo router accept it directly.
Library usage
import {
buildOpenHandsEnv,
serializeOpenHandsEnv,
buildOpenHandsCompose,
resolveOpenHandsModel,
} from "@omniroute/openhands-plugin";
const env = buildOpenHandsEnv({
apiKey: "sk-...",
model: resolveOpenHandsModel("deepseek-chat"),
omnirouteUrl: "http://localhost:20128",
persistenceDir: "/Users/me/.openhands-state",
});
console.log(serializeOpenHandsEnv(env));
License
MIT — same as OmniRoute.