Skip to content

feat: migrate ModelRelay → 9Router (port 7352 stays) - #53

Open
thiamricko wants to merge 24 commits into
mainfrom
replace-modelrelay-9router
Open

thiamricko wants to merge 24 commits into
mainfrom
replace-modelrelay-9router

Conversation

@thiamricko

Copy link
Copy Markdown
Collaborator

This PR contains Phase 1 of Issue #52.

Summary

Migrate ModelRelay → 9Router, keeping port 7352 unchanged.

  • npm: modelrelay@1.22.1 → 9router@0.5.81
  • 2 renames: ModelRelay.desktop → 9Router.desktop, start-modelrelay.sh → start-ninerouter.sh
  • 7352 port preserved end-to-end
  • New docker/9router-config.sh: REST API combo setup
  • Docs: architecture.md, README, excalidraw all updated

Verification

  • grep -rni modelrelay --include="*" . 2>/dev/null | grep -v ".git/" → empty
  • npm package confirmed live: curl https://registry.npmjs.org/9router/0.5.81
  • 13 files touched, 2 renames, 1 new file

Conflicts / follow-on

  • Phase 2 (PI branch fix + dep bumps) still pending on branch
  • Phase 3 (.agents/skills) not in this commit — planned for follow-on PR

Refs: #52 #52

…installation, add boot and self-check commands, and remove unused files
- npm: modelrelay@1.22.1 → 9router@0.5.81 (verified on npm registry)
- 2 renames: ModelRelay.desktop → 9Router.desktop, start-modelrelay.sh → start-ninerouter.sh
- 7352 port preserved end-to-end (Dockerfile, docker-compose, pi-models, self-check, docs)
- Launch: setsid modelrelay --disable → nohup 9router --host 0.0.0.0 --port 7352 --no-browser --skip-update
- New docker/9router-config.sh: REST API combo setup (login, disable auth, create auto-fastest with 8 free oc/ models, smoke test)
- Docs: architecture.md, README, excalidraw all updated to 9Router
- Verified: zero remaining modelrelay refs in repo, npm package confirmed live

Reference: PR #57 (gitricko/hermes-codespace) — canonical rename mapping
Issue: #52
- docker/start-ninerouter.sh: capture 9router-config.sh stdout/stderr to /tmp/9router-config.log
- .github/workflows/docker-publish.yml: add 'Collect boot logs' + 'Upload boot logs' steps
  (if: always()) that tar /tmp/*.log and ~/.hermes/logs/*.log into boot-logs-{run_id}.
  Both jobs (build-test and push-to-ghcr) updated identically.
Problem: 9router-config.sh was copied into /custom-cont-init.d/ (along with
all *.sh), making it an s6 boot init script. It runs alphabetically BEFORE
start-ninerouter.sh, hitting 9Router's /api/auth/login on a port with no
listening service — HTML error response → jq parse error → exit 7. No model
catalog, no auto-fastest combo, 9Router returns 500 forever.

Fix: move it to /usr/local/bin/9router-config (same pattern as self-check.sh).
Now only start-ninerouter.sh (after 9Router + sleep 10) invokes it.
Also update the path reference in start-ninerouter.sh.
- 9router-config.sh: login uses HttpOnly cookie auth (not Bearer token) — matches
  actual 9Router behavior (response has no .token field). Fixes jq parse error.
- start-ninerouter.sh: replace 'while true; do 9router ... sleep 3; done' with
  simple nohup (like OmniRoute). 9Router is a persistent daemon, not a short-lived
  process; the ModelRelay restart loop was cargo-culted and masked crashes.
  Also disable the premature config call pending the Dockerfile fix.
…fig at boot

- 9router-config.sh: match reference exactly — cookie auth via -c/-b jar,
  combo delete by ID lookup, -contributor-free model suffixes, smoke test
  with stream:false + max_tokens:16
- start-ninerouter.sh: replace blind sleep 10 with /api/health readiness
  poll (up to 300s, same as post-create-cmd.sh), then actually run
  /usr/local/bin/9router-config (was disabled — root cause of missing
  combo + HTTP 500)
- Dockerfile: drop commented-out github install line
- docker-publish.yml: retention-days: 7 on both failure-log upload steps
- start-ninerouter.sh: add --log to 9Router launch for runtime visibility
Root cause found via --log flag (d504db0):
  EACCES: permission denied, open '/config/.9router/jwt-secret'
  EACCES: permission denied, open '/config/.9router/model-catalog.json.tmp'

9Router's state dir didn't exist at boot → every login/combo/models
endpoint returned 500 → health poll passed (stateless /api/health)
but config script + self-check both failed.

Fix: mkdir -p /config/.9router && chown -R abc:abc before launch,
same pattern as OmniRoute's /config/.omniroute.
- Inline all config logic (cookie auth, disable auth, combo create,
  round-robin strategy, smoke test) into start-ninerouter.sh
- Remove separate 9router-config.sh file and its /usr/local/bin install
- Reduces boot-time files, eliminates cross-script dependency
- pi-settings.json: hermes-impl -> main (branch not found)
- start-pi.sh: hermes-impl -> main
- Dockerfile: NODE_VERSION 26.7.0 -> 26.10.0, PI_VERSION 0.85.1 -> 0.87.1
…re, docker-test-shell)

- Copied core CI/Docker workflow skills for repo portability
- parallel-delegation was already present
- docker-build-remote-only and simple-architecture-diagram were planned but not in minions
@thiamricko
thiamricko force-pushed the replace-modelrelay-9router branch 2 times, most recently from 73e796d to 4ac7dd8 Compare September 25, 2026 13:31
thiamricko and others added 7 commits September 25, 2026 13:38
Change ownership of hermes-agent directory recursively to avoid permission issues.
…config

- AGENTS.md: agent guidelines (single source, merged Core Procedures)
- self-check.sh: report 'unknown' when model/provider cannot be parsed
- start-hermes.sh: literal ${PWD} for terminal.cwd, auxiliary provider
  config for title_generation/vision/compression, move busy_input_mode up
- scripts/check-deps.sh: npm registry version checker
…rovider grep + JSON escaping

- docker-publish.yml: wait for OmniRoute:20128 -> 9Router:7352 -> HermesGateway:9119
  in dependency order (200×3s max each) instead of blind 600s sleep
- self-check.sh:
  - grep '^ *default:'/'^ *provider:' skips YAML comment lines
  - proper json.dumps escaping prevents SyntaxError when value contains quotes
Comment thread scripts/check-deps.sh
echo ""
echo "Other (manual check needed):"
echo " node: 26.10.0"
echo " ollama: 0.34.1"

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

9router is missing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants