Files
iris_x_hermes/docs/17-future-control-surface.md
ARIA 7a6d922d12
CI / Kotlin tests (android host + desktop) (push) Successful in 8m5s
CI / Gateway plugin tests (push) Successful in 9m47s
Add QR pairing (terminal QR, in-app scanner, iris://pair deep link)
2026-08-22 22:43:13 +02:00

173 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 17 — Future Control Surface (post-M7)
> **Status: research / backlog — not scheduled.** M0–M7 cover the chat surface
> (messages, streaming, tools, media, push, channels, search). This doc records
> what the app could *additionally* control through the gateway, based on a
> survey of the hermes-agent source (2026-08-21). Nothing here is locked; it is
> a menu of options, each with the hermes backend that already implements it.
## The key insight
Hermes already ships a **complete REST API** — `hermes_cli/web_server.py` plus
`hermes_cli/web_routers/` — which is the backend of the desktop/dashboard UI.
Our gateway plugin runs **inside the same `hermes gateway` process**, so every
capability below is reachable by importing and calling the same functions the
web server calls. Exposing one from the app = a new request/response frame pair
in our protocol (`protocol.py` → `Protocol.kt` → `frames.schema.json`, the
usual three-way mirror).
The constraint is never "can hermes do it?" (it can — all of it) — it is how
many frame pairs we want to add and the security review each one needs.
## Implementation paths
1. **Direct function calls (preferred).** The plugin imports the hermes
modules (`cron.jobs`, `hermes_cli.kanban_db`, config loaders, …) and calls
them. No extra process, no extra port, zero new deps.
2. **Proxy to the web server's REST API.** Only works if `hermes web` /
`hermes dashboard` is running — it is not by default. Rejected for v1.
## Capability menu
### Cron jobs — fully controllable
| App action | Hermes backend |
|---|---|
| List jobs (incl. disabled) | `cron/jobs.py` `list_jobs()` |
| Create job | `cron/jobs.py` `create_job()` (schedules: `30m`, `every monday 9am`, 5-field cron, ISO one-shot) |
| Edit job | `cron/jobs.py` `update_job(job_id, updates)` |
| Pause / resume | `cron/jobs.py` `pause_job()` / `resume_job()` |
| Trigger now | `cron/jobs.py` `trigger_job()` |
| Delete job | web router `web_routers/cron.py` `DELETE /api/cron/jobs/{id}` |
| Run history | `web_routers/cron.py` `GET /api/cron/jobs/{id}/runs`; `hermes_state_portability.py` `list_cron_job_runs()` |
| Delivery targets | `web_routers/cron.py` `GET /api/cron/delivery-targets` |
| One-tap suggestions | `cron/suggestions.py` — ready-to-run job specs the user accepts/dismisses; `accept_suggestion()` calls `create_job` directly. **Designed for a UI; ideal first feature.** |
| Blueprints | `cron/blueprint_catalog.py`, `web_routers/cron.py` `GET /api/cron/blueprints` + `POST /api/cron/blueprints/instantiate` |
Per-job fields worth surfacing: `model`/`provider` overrides, `skills`,
`script`, `context_from` (chain job A's output into job B), `workdir`,
multi-platform delivery.
### Kanban board — fully controllable
| App action | Hermes backend |
|---|---|
| Boards: list / create / rename / delete / switch | `hermes_cli/kanban_db.py` `create_board()` / `list_boards()`; REST `plugins/kanban/dashboard/plugin_api.py` `/boards*` |
| Tasks: create / list / show / update / delete | `kanban_db.py` `create_task()` / `list_tasks()` / `complete_task()`; REST `/tasks*` |
| Comments / links / attachments | REST `/tasks/{id}/comments`, `/links`, `/tasks/{id}/attachments` |
| Bulk operations | REST `POST /tasks/bulk` |
| Dispatch / reassign / reclaim / estimate | REST `/dispatch`, `/tasks/{id}/reassign`, `/tasks/{id}/reclaim`, `/estimate` |
| Runs: inspect / terminate | REST `/runs/{run_id}`, `/runs/{run_id}/terminate` |
| Stats / diagnostics / active workers | REST `/stats`, `/diagnostics`, `/workers/active` |
| Per-task model options | REST `/model-options` |
Bonus: the kanban dispatcher already runs **inside the gateway** by default
(`kanban.dispatch_in_gateway: true`), so a phone app would see dispatch
activity live. The full REST surface (~30 endpoints) is in
`plugins/kanban/dashboard/plugin_api.py`.
### Model / provider registry — fully controllable
| App action | Hermes backend |
|---|---|
| Set active model | `web_server.py` `POST /api/model/set` |
| List model options / info / recommended default | `GET /api/model/options`, `/api/model/info`, `/api/model/recommended-default` |
| Auxiliary (side-LLM) models | `GET/PUT /api/model/auxiliary` |
| MoA config | `GET/PUT /api/model/moa` |
| Per-profile model | `web_routers/profiles.py` `PUT /api/profiles/{name}/model` |
| Per-toolset model / provider / env | `web_routers/tools.py` `PUT /api/tools/toolsets/{name}/model` / `/provider` / `/env` |
| Custom endpoints: CRUD + validate + activate | `web_server.py` `/api/providers/custom-endpoints*` |
| Provider validation / OAuth flows | `POST /api/providers/validate`, `/api/providers/oauth*` |
| API keys (`.env`): set / reveal / delete | `web_server.py` `GET/PUT/DELETE /api/env`, `POST /api/env/reveal` |
| `config.yaml`: read / write / schema | `GET/PUT /api/config`, `GET /api/config/schema` |
### Webhooks
| App action | Hermes backend |
|---|---|
| Subscribe / list / remove / test inbound webhook routes | `hermes_cli/webhook.py` (`hermes webhook` CLI: `_cmd_subscribe`, `_cmd_list`, `_cmd_remove`, `_cmd_test`); subscriptions stored in `~/.hermes/webhooks/subscriptions.json` |
### Sessions
List, FTS search, rename, delete, bulk-delete, export (md/html), prune —
`web_routers/sessions.py` (`/api/sessions*`). Overlaps with what the app
already shows from its own chat; useful for browsing *other* platforms'
sessions (Telegram, CLI, cron runs).
### Profiles
CRUD, switch active profile, edit soul/description, per-profile model,
export/import — `web_routers/profiles.py` (`/api/profiles*`).
### Skills
List, toggle, create/edit content, hub search/install/uninstall/update —
`web_routers/skills.py` (`/api/skills*`, `/api/skills/hub/*`).
### Tools / toolsets
Enable/disable per platform, per-toolset config/model/provider/env —
`web_routers/tools.py` (`/api/tools/toolsets*`).
### MCP servers
CRUD, test, auth/OAuth flows, catalog browse + install —
`web_routers/mcp.py` (`/api/mcp/*`).
### Git
Status, branches, worktrees, and a full review flow (stage/unstage/revert/
commit/push/create-PR) — `web_routers/git.py` (`/api/git/*`).
### Files
Upload/download/read/write, fs list/mkdir — `web_server.py` `/api/files*`,
`/api/fs/*`. (Complements the existing media frames in `07-media.md`.)
### Messaging platforms
List/configure/test other platforms (Telegram, WhatsApp onboarding) —
`web_server.py` `/api/messaging/*`.
### Memory providers
Config + setup per provider — `web_server.py` `/api/memory/providers/*`.
### Ops / system
| App action | Hermes backend |
|---|---|
| Gateway restart / drain | `web_server.py` `POST /api/gateway/restart`, `/api/gateway/drain` |
| Hermes update check / install | `POST /api/hermes/update`, `GET /api/hermes/update/check` |
| Curator (skill maintenance) status / pause / run | `GET /api/curator`, `PUT /api/curator/paused`, `POST /api/curator/run` |
| Audio: transcribe / TTS / voices | `POST /api/audio/transcribe`, `POST /api/audio/speak`, `GET /api/audio/elevenlabs/voices` |
| System stats / status / health | `GET /api/system/stats`, `/api/status`, `/api/health` |
| Learning graph node CRUD | `GET/PUT/DELETE /api/learning/node*` |
## Design notes
1. **Protocol cost is low.** The existing frame model (`type` + payload,
request/response correlated by `id`) already fits; we would add pairs like
`cron.list`/`cron.create`, `kanban.task.create`, `model.set`, following the
standard three-way mirror (`gateway-plugin/protocol.py` →
`app/shared/.../protocol/Protocol.kt` → `docs/protocol/frames.schema.json`).
2. **Security is the real gate.** The single-user model in
`09-pairing-security.md` still holds, but control frames widen the blast
radius of a leaked `IRIS_TOKEN`. Sensitive operations (env/secrets,
config writes, gateway restart, profile deletion) should get either an
in-app confirmation step or a capability flag negotiated at pairing.
3. **Read-heavy first.** Most of the value is in list/view frames (cheap,
low-risk); write frames can follow per domain.
4. **Broadcast routing applies.** Frames broadcast to all connected devices
(locked decision, `16-open-questions.md`); a control *response* should be
routed to the requesting device only, like other request/response pairs.
## Natural first picks (suggested order)
1. **Cron** — list / create / pause / trigger + one-tap suggestions (the
suggestion flow was literally designed for a UI).
2. **Kanban** — view board, add task, complete task.
3. **Model switch** — `model.set` + `model.options` (small, high value).
4. **Sessions** — list/search across platforms.
All four are read-heavy with cheap writes and low security risk.