docs: initial Hermes Mobile planning scaffold

This commit is contained in:
Hermes Agent
2026-07-09 03:45:48 +00:00
commit 2cd4730324
14 changed files with 2139 additions and 0 deletions
+254
View File
@@ -0,0 +1,254 @@
# Companion Server Plan
## Purpose
The companion server is the local service installed beside Hermes Agent. It turns Hermes into a phone-friendly app backend without forcing Hermes core to become a mobile backend.
Responsibilities:
- Authenticate/pair phones
- Accept prompts, voice recordings, and files
- Start/continue Hermes tasks
- Stream Hermes activity to the app
- Store app metadata
- Send push notifications
- Expose cron/job/session/file APIs
- Provide health checks and install/update status
## Runtime
Preferred MVP runtime: Node.js + TypeScript.
Reasons:
- Great fit for HTTP/WebSocket/SSE/file uploads.
- Easy bundling for one-liner installs.
- PM2/systemd deployment is straightforward in Zeb's environment.
- Frontend and backend can share TypeScript event schemas.
Potential framework:
- Fastify: mature, fast, good plugins.
- Hono: simple, edge-like API, also good.
Initial pick: Fastify unless we want ultra-minimal.
## Config
Config locations:
System mode:
```text
/etc/hermes-mobile/config.yaml
/var/lib/hermes-mobile/
```
User mode:
```text
~/.config/hermes-mobile/config.yaml
~/.local/share/hermes-mobile/
```
Example:
```yaml
server:
host: 0.0.0.0
port: 8787
public_url: https://hermes-mobile.molberg.cloud
auth:
pairing_enabled: true
token_ttl_days: 90
passkeys_enabled: false
hermes:
home: /root/.hermes
mode: python # python | api | cli
cli_bin: /root/.local/bin/hermes
api_base_url: http://127.0.0.1:18793/v1
api_key: ""
storage:
data_dir: /var/lib/hermes-mobile
max_upload_mb: 512
retention_days: 30
notifications:
provider: webpush # webpush | ntfy | gotify | none
ntfy_url: https://ntfy.example.com/hermes
```
## Hermes Adapter Strategy
### Phase 1: CLI/API hybrid
- Use Hermes CLI for health tests and simple prompts.
- Use Hermes API server if available for OpenAI-compatible chat.
- Parse coarse progress where possible.
Pros:
- Requires few/no Hermes changes.
- Easy to prove app UX.
Cons:
- Tool-call visibility limited.
### Phase 2: Direct Python adapter
Run a Python worker process that imports Hermes `AIAgent` and communicates with Node over stdio or local socket.
Benefits:
- Can pass `stream_delta_callback` and `tool_progress_callback`.
- More structured event stream.
- Better session control.
Potential shape:
```text
Node companion <-- JSON lines --> Python hermes_worker.py <-- imports --> AIAgent
```
Worker commands:
- `health`
- `start_task`
- `continue_session`
- `cancel_task`
- `list_sessions`
- `cron_action`
Worker emits events:
- `assistant.delta`
- `tool_call.started`
- `tool_call.output`
- `tool_call.finished`
- `assistant.final`
### Phase 3: Hermes-native plugin/API
If Hermes Agent grows a stable event API, switch adapter implementation without rewriting app/server.
## Task Lifecycle
```text
created -> queued -> running -> finished
-> failed
-> cancelled
-> waiting_approval
```
Task record:
```ts
type Task = {
id: string
sessionId?: string
title?: string
status: TaskStatus
inputText: string
attachmentIds: string[]
createdAt: string
startedAt?: string
finishedAt?: string
error?: string
}
```
## Upload Handling
Use multipart upload endpoint.
Pipeline:
1. Validate file count/size/type.
2. Store under `uploads/<task-id-or-upload-id>/original-name`.
3. Record metadata in SQLite.
4. Include absolute file paths in Hermes prompt.
Prompt augmentation example:
```text
The user uploaded these files:
- screenshot.png: /var/lib/hermes-mobile/uploads/abc/screenshot.png (image/png, 320 KB)
- source.zip: /var/lib/hermes-mobile/uploads/abc/source.zip (application/zip, 12 MB)
User prompt:
<actual user prompt>
```
## Voice Handling
MVP options:
1. Client records `.webm`/`.ogg`, server stores it, then sends file path to Hermes with instruction to transcribe/analyze.
2. Server transcribes with local faster-whisper and sends text prompt.
Recommended MVP:
- Server-side transcription using local faster-whisper if available.
- Fallback: pass audio file to Hermes as attachment.
## Notifications
Events that trigger notifications:
- task completed after app backgrounded
- task failed
- approval required
- cron job finished/failed
Use provider abstraction:
```ts
interface NotificationProvider {
sendCompletion(task: Task): Promise<void>
sendFailure(task: Task): Promise<void>
sendApproval(approval: Approval): Promise<void>
sendCron(job: CronEvent): Promise<void>
}
```
## Pairing/Auth
MVP pairing:
1. Installer/server logs one-time code.
2. Phone opens `/pair` and enters code or uses link.
3. Server stores device and creates token.
4. Token stored in secure-ish PWA storage. Later use passkeys.
For public exposure, add:
- Rate limiting
- Token rotation
- Session revoke UI
- Optional Tailscale-only mode
## Cron Integration
Initial implementation can shell out to Hermes CLI:
```bash
hermes cron list --json
hermes cron run <id>
hermes cron pause <id>
hermes cron resume <id>
```
If CLI JSON is not available, import cron modules from Hermes Python or parse job files carefully.
## System Health
Health endpoint should check:
- companion server up
- DB writable
- upload dir writable
- Hermes CLI exists
- Hermes config exists
- Hermes API server reachable if configured
- Python worker reachable if configured
- notification provider configured
## Logging
- Structured JSON logs for service.
- Human-readable recent logs in UI.
- Do not log secrets, bearer tokens, or full uploaded file content.
## Open Questions
- Should companion run as same user as Hermes Agent for direct module/file access?
- Should public access be Cloudflare Access/Tailscale-first instead of app auth-first?
- How much Hermes core should be extended for better event streaming?