Files
2026-07-09 03:50:27 +00:00

7.7 KiB

Architecture

Overview

Hermes Mobile is split into two deployable parts:

  1. Mobile app

    • Native Android app built with Capacitor around a shared React UI.
    • PWA/web build remains available as fallback and dev target.
    • Talks only to the companion server.
    • Does not need direct access to Hermes files or credentials.
  2. Companion server

    • Runs on the same Linux machine as Hermes Agent.
    • Bridges mobile UI actions to Hermes Agent.
    • Owns upload storage, push notifications, pairing/auth, app metadata, and realtime event fanout.
+---------------------------+
| Android App               |
| - Chat                    |
| - Tool timeline           |
| - Cron UI                 |
| - Files                   |
| - Approvals               |
+-------------+-------------+
              |
              | HTTPS REST + WebSocket/SSE + native push/Web Push fallback
              v
+---------------------------+
| Hermes Companion Server   |
| - Auth/pairing            |
| - Task orchestrator       |
| - Hermes adapters         |
| - Event bus               |
| - Upload store            |
| - Cron wrapper            |
| - Notification providers  |
+------+------+-------------+
       |      |
       |      +--------------------+
       |                           |
       v                           v
+-------------+             +--------------+
| Hermes CLI  |             | Hermes files |
| Hermes API  |             | sessions/db  |
| AIAgent     |             | cron jobs    |
+-------------+             +--------------+

Key Architectural Rule

The companion server should depend on stable Hermes surfaces first, but isolate every integration behind interfaces.

interface HermesAdapter {
  health(): Promise<HermesHealth>
  startTask(input: StartTaskInput): AsyncIterable<HermesEvent>
  continueSession(sessionId: string, input: StartTaskInput): AsyncIterable<HermesEvent>
  stopTask(taskId: string): Promise<void>
}

Possible implementations:

  • CliHermesAdapter: spawns hermes chat -q or interactive process. Easiest baseline, weakest event detail.
  • ApiHermesAdapter: calls Hermes API server. Good for compatibility, but generic OpenAI API hides some tool events.
  • PythonHermesAdapter: imports Hermes Agent modules and uses callbacks for stream/tool progress. Best long-term event fidelity.
  • GatewayHermesAdapter: uses existing gateway/session machinery if exposed.

Companion Server Modules

companion/
  src/
    app.ts                    # server bootstrap
    config/                   # env/yaml config loading
    auth/                     # pairing, sessions, tokens, passkeys later
    db/                       # SQLite schema/migrations/repositories
    events/                   # event bus + SSE/WebSocket fanout
    hermes/                   # adapter interface + implementations
    tasks/                    # task lifecycle/orchestration
    uploads/                  # multipart upload handling + retention
    notifications/            # webpush/ntfy/gotify providers
    cron/                     # Hermes cron wrapper
    approvals/                # approval queue + Hermes callbacks later
    routes/                   # REST API routes
    ws/                       # realtime endpoints
    system/                   # service health, logs, install info

Event Bus

Everything that happens in the companion becomes an event.

Core event shape:

type CompanionEvent = {
  id: string
  type: string
  taskId?: string
  sessionId?: string
  ts: string
  level?: 'debug' | 'info' | 'warn' | 'error'
  payload: unknown
}

Important event types:

task.created
task.started
task.status
task.finished
task.failed
task.cancelled

assistant.delta
assistant.message
assistant.final

tool_call.started
tool_call.output
tool_call.finished
tool_call.failed

file.uploaded
file.generated

approval.required
approval.resolved

cron.job.listed
cron.job.updated
cron.job.finished

notification.sent
notification.failed

The mobile app subscribes by:

  • WebSocket for active app foreground.
  • SSE fallback.
  • Push notifications when app is background/closed.

Data Storage

SQLite

Companion-owned metadata:

  • paired devices
  • auth sessions
  • tasks
  • task events
  • uploaded files metadata
  • notification subscriptions
  • user settings/cache

Do not duplicate full Hermes session content unless needed for mobile indexing. Hermes session DB remains source of truth.

Filesystem

Default paths:

/var/lib/hermes-mobile/
  hermes-mobile.db
  uploads/
    <task-id>/
  generated/
  cache/
  logs/

User-mode install paths:

~/.local/share/hermes-mobile/
~/.config/hermes-mobile/config.yaml

API Surface

Auth / Pairing

POST /api/pair/start
POST /api/pair/confirm
POST /api/auth/login
POST /api/auth/logout
GET  /api/me

Pairing flow:

  1. Installer prints https://host/pair?code=123-456.
  2. User opens on phone.
  3. Server binds device and issues token.
  4. Future sessions use secure cookie or bearer token.

Tasks

POST /api/tasks
GET  /api/tasks
GET  /api/tasks/:id
POST /api/tasks/:id/stop
GET  /api/tasks/:id/events
WS   /api/tasks/:id/stream

Uploads

POST /api/uploads
GET  /api/files
GET  /api/files/:id/download
DELETE /api/files/:id

Sessions

GET  /api/sessions
GET  /api/sessions/:id
POST /api/sessions/:id/continue
PATCH /api/sessions/:id

Cron

GET  /api/cron/jobs
POST /api/cron/jobs/:id/run
POST /api/cron/jobs/:id/pause
POST /api/cron/jobs/:id/resume
DELETE /api/cron/jobs/:id

System

GET  /api/health
GET  /api/hermes/health
POST /api/hermes/test
GET  /api/logs

Hermes Integration Notes

Existing useful surfaces observed:

  • Hermes API server exposes /v1/chat/completions, /v1/responses, /v1/models, /health.
  • AIAgent supports stream_delta_callback and tool_progress_callback constructor params.
  • Cron jobs are manageable through Hermes CLI/tooling and stored under Hermes home.
  • Gateway platforms already handle STT/media patterns, but mobile should not depend on Telegram.

Long-term ideal:

  • Add/consume a Hermes-native event stream from AIAgent that emits structured tool events.
  • Companion server can either import Hermes modules or call a local IPC endpoint.

Security Model

Default deployments:

  1. LAN/Tailscale only, simple pairing token.
  2. Public HTTPS, pairing token + device token + optional passkey.

Security requirements:

  • No unauthenticated access to prompt endpoints.
  • Upload size limits.
  • File paths normalized; no arbitrary file read from upload endpoints.
  • CSRF protection if cookie auth used.
  • Audit log for approvals.
  • Secrets remain in Hermes config/vault, not in mobile app.

Notification Architecture

Provider interface:

interface NotificationProvider {
  send(device: Device, message: NotificationMessage): Promise<void>
  test(device: Device): Promise<void>
}

Providers:

  • WebPushProvider
  • NtfyProvider
  • GotifyProvider
  • NoopProvider

Deployment Modes

User mode

  • Runs as current user.
  • Uses ~/.config/hermes-mobile and ~/.local/share/hermes-mobile.
  • Good for dev/single-user boxes.

System mode

  • Creates hermes-mobile system user or runs under Hermes user.
  • Uses /etc/hermes-mobile and /var/lib/hermes-mobile.
  • systemd service.
  • Better production posture.

Native Android Shell

Capacitor Android is part of the primary architecture, not a future contingency.

  • The shared React UI builds into apps/mobile/dist.
  • Capacitor packages that build into an Android APK.
  • PWA/web access remains useful for dev, desktop, and fallback.
  • Native plugins provide share target, richer push, haptics, status bar, splash screen, microphone/file improvements, and Android lifecycle hooks.