6.9 KiB
Hermes Mobile Direct Gateway Architecture
Hermes Mobile is pivoting to a native Android client that talks directly to a remote upstream Hermes Agent gateway/API server. The apps/companion TypeScript server is legacy compatibility code and must not be required by Android or future releases.
Architecture
Android app
Kotlin/Compose UI
connection/auth storage
transport DTOs
domain repositories
|
| HTTPS, bearer token when configured
v
Upstream Hermes Agent gateway/API server
auth/session authority
chat/completion authority
streaming/tool/artifact authority
provider credentials and Hermes runtime
The Android app remains a thin client. It may store server profiles, non-provider UI preferences, selected session IDs, and Android-secured bearer tokens. It must not embed provider credentials, clone Hermes backend behavior, or make the legacy companion server part of the release path.
Documented Upstream Surface
The current repository/context documents these upstream Hermes API-server endpoints:
| Endpoint | Status | Mobile contract |
|---|---|---|
GET /health |
Documented | Primary reachability and compatibility probe. Response shape beyond a successful JSON response is treated as server-specific. |
GET /v1/models |
Documented | Authenticated compatibility probe for bearer-token connections and future model picker source. |
POST /v1/chat/completions |
Documented | Baseline OpenAI-compatible chat path. Mobile must assume this may not expose Hermes session IDs or structured tool events. |
POST /v1/responses |
Documented | Preferred future request/streaming path if upstream exposes richer response events. Exact Hermes event mapping is not yet verified. |
These are the only upstream API-server routes currently treated as documented by this repository. Any route not listed here must be labeled provisional until checked against official Hermes Agent docs or a running gateway.
Unverified Assumptions
The following are useful design assumptions, not confirmed contracts:
- Bearer authentication is accepted through an
Authorization: Bearer <token>header on/v1/*. /healthreturns a stablestatusfield./v1/responsescan provide enough streaming metadata to preserve Hermes sessions, tool lifecycle, artifacts, cancellation, and reconnect state.- Hermes session listing, creation, continuation, and deletion have stable direct HTTP endpoints.
- Tool result and artifact listing/download have stable direct HTTP endpoints.
- Cancellation has a stable direct HTTP endpoint.
- Error payloads consistently include
messageorerror.
Android contracts may model these needs, but implementation must keep them capability-gated until verified.
Compatibility Policy
- Direct gateway routes are the default target for all new Android transport work.
- Legacy companion routes such as
/api/health,/api/auth/validate,/api/chat,/api/files/*, and/api/terminal/*are temporary compatibility only. - UI and domain terminology should say "gateway", "server", or "upstream Hermes" unless explicitly describing legacy companion behavior.
- The transport/domain model exposes direct gateway capabilities first.
legacyCompanionAdapterexists only to identify old adapters during migration. - Backend behavior belongs upstream in Hermes Agent. Hermes Mobile may add client adapters and mappers, not server-side replacements.
Local-first gateway routing
A server profile can contain two URLs for the same Hermes gateway identity:
- Local URL — preferred when the phone can safely reach the gateway on the home/LAN (for example,
https://hermes.home.arpa). - Remote URL — fallback when local reachability is unavailable (for example, a configured public HTTPS hostname).
The client must choose automatically per connection attempt:
- If a local URL is configured, probe its documented
GET /healthendpoint using a short, bounded timeout. - Use the local URL when the probe succeeds and the gateway identity/auth contract is compatible.
- Otherwise immediately use the configured remote URL; never leave chat blocked waiting for LAN discovery.
- Re-evaluate on app foreground, explicit reconnect, connectivity changes, and after a failed active request. Do not switch a request mid-stream.
- Show the active route (
LocalorRemote) in connection diagnostics, but do not expose bearer tokens or internal host details in message content/logs.
Security and reliability rules:
- Local and remote URLs are explicit user configuration, not guessed IP ranges or silently discovered devices in the MVP.
- Both routes must use HTTPS by default and must be treated as the same intended gateway only after an authenticated compatibility check. The app must not silently send a bearer token to an arbitrary captive portal or unrelated LAN host.
- Remote is a fallback, not a duplicate profile. User preferences, selected session state, and credentials stay associated with one logical gateway profile.
- A later milestone may add opt-in mDNS/QR setup, certificate pinning/identity binding, and richer connectivity observation only after direct-gateway basics are verified.
- The current upstream identity-binding limitation and the stronger contract needed are tracked in
docs/BLOCKERS.md.
Android Contract Milestones
- Auth and connection: validate local + remote URLs, store bearer tokens securely, probe
GET /health, useGET /v1/modelsas the first authenticated check, and make local-first fallback observable/retryable. - Sessions: keep repository interfaces for list/create/select/continue, but mark route mapping provisional until upstream session docs are verified.
- Streaming: support final response and token delta reduction now; gate structured tool/artifact/session events behind server capabilities. Keep each stream bound to its selected local or remote route.
- Companion removal: after direct gateway chat/session/streaming works end to end, remove legacy companion UI routes and then deprecate install/docs around
apps/companion.
Verified Session Capability Boundary — 2026-07-24
Official upstream API server documentation defines authenticated GET /v1/capabilities discovery and advertises session endpoint entries including session_list, session_create, session_get, and session_delete. The Android B3 foundation therefore builds requests only from those returned endpoint strings; a missing entry leaves that operation unavailable rather than falling back to an assumed route.
Source checked: https://hermes-agent.nousresearch.com/docs/user-guide/features/api-server/ on 2026-07-24.
The same official endpoint table does not document session search or a search query schema. Hermes Mobile keeps search in the repository contract and fake implementation for UI/state verification, but does not map search to HTTP until upstream publishes that contract. The exact blocker is tracked in docs/BLOCKERS.md.