The plugin is named 'iris' (IrisAdapter, IRIS_HOME_CHANNEL, label Iris), but several docs still referred to it as the android platform/plugin and to the product as 'the Android app'. Rename name-mentions to iris/IRIS and product-mentions to 'Iris app'; keep legitimate OS references (androidApp, Android SDK, Android 10, androidx, test_android.py, ...). Also includes pi-lens markdown-lint autofixes (table spacing, trailing newlines) in the touched files.
94 lines
4.8 KiB
Markdown
94 lines
4.8 KiB
Markdown
# 00 — Overview
|
||
|
||
## Vision
|
||
|
||
A **native, Telegram-quality chat experience** for a personal hermes-agent:
|
||
install an app on your phone (and a desktop app on your PC), pair it to your
|
||
running `hermes gateway`, and talk to your agent with streaming replies,
|
||
visible reasoning, structured tool activity, channels/threads, media, search,
|
||
and push notifications — with cron jobs able to post into any channel you
|
||
create.
|
||
|
||
## Goals
|
||
|
||
- **Native feel.** Real native app (Iris on Android, Kotlin/Compose), not a
|
||
WebView. Desktop app that is the same app, resized for a big screen.
|
||
- **First-class gateway citizen.** The app is a hermes *messaging platform*, so
|
||
everything the gateway already does "just works": slash commands, cron
|
||
delivery, `send_message` routing, coexistence with Telegram/Discord/etc.
|
||
- **Full agent transparency.** Streaming text, reasoning shown *before* the
|
||
answer, structured tool events (the app chooses how much to show), and
|
||
intermediate assistant beats.
|
||
- **Organized by default.** A default chat with optional threads, plus
|
||
user-created channels that cron jobs can target.
|
||
- **Reachable anywhere.** Live over a WebSocket; background push via FCM
|
||
(primary) or ntfy (fallback).
|
||
|
||
## In scope (v1)
|
||
|
||
Everything in the feature checklist below.
|
||
|
||
## Out of scope / stretch (v1)
|
||
|
||
- **Standalone-cron delivery while the gateway process is fully down** —
|
||
best-effort FCM/ntfy only (the outbox is served by the running gateway).
|
||
- **Multi-user / group chat** — this is a *personal* 1-user agent.
|
||
- **End-to-end encryption** — transport security (WSS) only.
|
||
- **iOS** — Android + Desktop only (the protocol is transport-agnostic, so an
|
||
iOS client is a future port, not a v1 goal).
|
||
|
||
## Feature checklist → where it's handled
|
||
|
||
| Requirement | Gateway plugin | App |
|
||
| --- | --- | --- |
|
||
| Input box, auto-grow (max height) | — | Compose `TextField` + bounded `heightIn` |
|
||
| Menu button → all slash commands | Dispatches `/…`; serves command catalog | Bottom-sheet menu + `/` autocomplete |
|
||
| Tool output (app decides how much) | Emits **structured** tool events | App setting: everything / truncated / nothing |
|
||
| Reasoning shown before message | Captures + splits reasoning | Collapsible "Reasoning" block above message |
|
||
| Intermediate messages | Forwards `Commentary` events | Distinct dimmed bubble |
|
||
| Threading + channels; default chat; user channels for cron | `chat_id`/`thread_id` model; cron `deliver=iris:<chat>[:<thread>]` | Channel list, thread toggle, "new channel" |
|
||
| Search ("everywhere" / "this chat/channel") | FTS5 session search bridge | Search UI + scope toggle |
|
||
| Attach media (music/video/images/docs) | Inbound cache; outbound `send_*` | Pickers + chunked upload + preview |
|
||
| Push notifications | FCM (primary) / ntfy (fallback) | FCM token / ntfy topic + notification service |
|
||
| Live playback of AI-sent music/video | Serves media bytes over WS | ExoPlayer inline player |
|
||
|
||
## Locked decisions (from planning)
|
||
|
||
| Decision | Choice |
|
||
| --- | --- |
|
||
| Desktop app tech | **Compose Multiplatform** (shares Android code; "tweaked" for big screen) |
|
||
| Push backend | **Both** — ntfy default, FCM optional (`IRIS_PUSH_BACKEND`) |
|
||
| Media transport | **Over the WebSocket** (chunked binary frames; no extra Python deps) |
|
||
| Phone default layout | **User-toggleable, single-pane default** (auto two-pane on large screens) |
|
||
|
||
## Disclaimers (hard rules)
|
||
|
||
1. **`hermes-agent/` is a read-only research reference.** It lives next to this
|
||
folder for study only. It is **git-ignored** and must **never** be committed,
|
||
pushed, or included in any artifact. Our plugin is *installed* into a live
|
||
hermes home (`~/.hermes/plugins/iris`); we never edit hermes core files.
|
||
2. **ADB is available and a device is connected** (`a5ca2a4b`, Xiaomi MIX 2S,
|
||
Android 10 / API 29). Use `adb install` / `adb logcat` / `adb shell am start`
|
||
to install, launch, and debug the app on-device throughout the build.
|
||
|
||
## Verified environment state (2026-08-19)
|
||
|
||
| Item | State |
|
||
| --- | --- |
|
||
| OS | CachyOS (Arch-based), `pacman` present |
|
||
| JDK | **Not installed** → Milestone M0 (`pacman -S jdk17-openjdk`) |
|
||
| Android SDK | **Not installed** → M0 (cmdline-tools + sdkmanager) |
|
||
| Gradle | Via project wrapper (`gradlew`), no system install |
|
||
| ADB | Installed; device `a5ca2a4b` (MIX 2S, API 29) connected |
|
||
| Python | 3.14.7; `uv` 0.12.3 present |
|
||
| hermes venv | **Not created** → M0 (`cd hermes-agent && uv sync`) |
|
||
| hermes core deps | `websockets==15.0.1` and `httpx` are **core** deps → plugin needs **zero new Python deps** |
|
||
| Disk / RAM | 522 GB free / 62 GB RAM — ample |
|
||
|
||
## Naming
|
||
|
||
- Product/effort name: **Iris × Hermes** (folder `iris_x_hermes`).
|
||
- hermes platform name: **`iris`** (the plugin registers `Platform("iris")`).
|
||
- WS default port: **8790** (configurable).
|
||
- Default chat id: **`default`** (the home channel).
|