oomi-ai 0.11.0 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,436 +1,436 @@
1
- # oomi-ai
2
-
3
- Connect OpenClaw, Hermes, Grok Bot, and other agents to Oomi through an explicit runtime adapter.
4
-
5
- `oomi-ai` connects the selected local agent to Oomi. Persona UI creation and rendering happen inside Oomi-managed systems. The OpenClaw machine uses API actions only.
6
-
7
- The current model is:
8
-
9
- - The selected agent talks to Oomi through managed channel and bridge APIs.
10
- - Oomi clients render persona apps from approved templates, components, data bindings, actions, and permissions.
11
- - The agent may inspect and update persona app state through approved Oomi API actions.
12
- - The user adds persona apps from the Oomi client so platform permissions and data hydration happen in the right place.
13
-
14
- ## What This Package Ships
15
-
16
- 1. OpenClaw channel extension
17
-
18
- - File: `openclaw.extension.js`
19
- - Purpose: managed text transport through the Oomi backend channel API.
20
-
21
- 2. Local bridge and CLI
22
-
23
- - Files: `bin/oomi-ai.js`, `bin/sessionBridgeState.js`
24
- - Purpose: pair a device, manage the OpenClaw bridge worker, and support managed gateway traffic for device-backed chat and voice.
25
-
26
- 3. Persona app API tools
27
-
28
- - Files: `persona-app/*`, `lib/personaApiClient.js`, `bin/oomi-ai.js`
29
- - Purpose: inspect account-linked component-composed persona apps and apply approved backend actions.
30
-
31
- 4. Permissioned context tools
32
-
33
- - Files: `lib/personaApiClient.js`, `bin/oomi-ai.js`
34
- - Purpose: read user-approved Oomi backend context, such as HealthKit summaries synced by the mobile app.
35
-
36
- 5. Agent/operator instructions
37
-
38
- - Files: `agent_instructions.md`, `skills/oomi/*`
39
- - Purpose: tell OpenClaw agents how to connect, repair, and use Oomi without local UI code generation.
40
-
41
- ## Boundary
42
-
43
- Persona UI is an Oomi-managed client capability, not an OpenClaw-machine responsibility.
44
-
45
- This package exposes connection, bridge, voice, and persona app state APIs. It does not include a local persona app workspace, local persona runtime manager, queued UI job runner, or app framework bundle.
46
-
47
- ## Connect Your Local Agent
48
-
49
- Connect the agent the user is speaking to. Identify your runtime, bot/profile, and actual host first. Computer access does not mean you run on that computer. Never substitute another installed agent.
50
-
51
- ## Choose a connection by interface (oomi-ai 0.8.5+)
52
-
53
- Run setup on the host where **this agent** runs. A Grok Bot with access to someone's Mac still runs on its Grok Bot host; connecting an OpenClaw agent on that Mac does not connect the Grok Bot. No new model API key or replacement bot is needed.
54
-
55
- 1. Identify yourself from your current runtime context: bot/profile identity, host, and conversation behavior. Do not guess from installed executables or names.
56
- 2. Run `oomi capabilities`. OpenClaw and Hermes have native adapters. Grok Bot uses its own local gateway through the adapter described below. An unlisted brand is not automatically unsupported: inspect its documented message input **and completed-reply** interfaces (CLI, API, SDK, webhook, or inbound channel).
57
- 3. For another runtime, use `--runtime command` to wrap those interfaces and return `{text, sessionId?}` only when the same agent has finished. A health endpoint or an accepted/queued response is not a final reply. If no supported input or reply interface exists, state that specific missing capability; never invent one or select another agent.
58
- 4. Preserve identity, memories and host approvals. Say whether you resume an exact existing conversation or keep an Oomi conversation with the same agent. Verify a real reply before sharing an Auth Link; verify delivery in Oomi before claiming completion.
59
-
60
- ### Grok Bot: connect the existing bot
61
-
62
- On **this bot's own Linux host**, install/update the package through the normal host approval flow, then run:
63
-
64
- ```bash
65
- oomi connect --runtime grokbot --name YOUR_CONNECTION --agent-id YOUR_BOT_UUID --agent-name "Your name" --app-url https://www.oomi.ai
66
- ```
67
-
68
- Use your exact bot UUID from your runtime context. Never choose whichever bot happens to be active on a shared computer. Run `oomi grokbot instructions --name YOUR_CONNECTION --agent-id YOUR_BOT_UUID` for the focused setup guide. The package uses the host's existing private local gateway; **do not ask the user to copy a webhook URL/key or create a routine**. Fresh connections require no `grokbot.json`. Existing explicit webhook configurations remain supported. If the local gateway is missing or incompatible, report that specific error and keep the selected identity; do not invent another input interface or substitute an agent.
69
-
70
- Setup returns **queued**, then waits in the background. Finish your current bot turn immediately so the verification can execute; waiting for your own verification in that turn deadlocks the host. The package installs its private Oomi delivery skill and waits until this bot has loaded it. Incoming chat shows the original message with a small skill tag; the skill claims the private request and submits its final reply. Missing or locally modified skills fail before sending; do not replace them with instruction walls in chat. Continue only for `status: claimed`. A verification answer must be exactly `OOMI_OK`. The reply command reports one Auth Link only after verification, pairing and bridge subscription succeed. Show the Auth Link to the user. If pending, finish the turn and use `oomi grokbot status --name YOUR_CONNECTION` later. Queued is not connected. Acceptance by the host is not a completed answer.
71
-
72
- Use explicit `--connection YOUR_CONNECTION` for Oomi account commands: a shared host does not inherit the bridge's environment. Text and voice transcripts are supported; photos are rejected. Oomi supplies conversation history; exact Grok Bot desktop/DM conversation continuation is not guaranteed. Host approvals remain in Grok Bot. Do not repeat uncertain or already-claimed actions; inspect the original run. Reconnect reuses verification and pairing; `oomi verify --name YOUR_CONNECTION` explicitly queues a new model verification.
73
-
74
- Oomi uses systemd user services where available. On Linux hosts without systemd, it automatically supervises bridge worker exits for the current host session. **After the whole cloud computer restarts, rerun the same connect command.** This fallback cannot start itself at boot. Use `oomi status --name YOUR_CONNECTION --json` to inspect recovery. A host-provided external supervisor can instead run `oomi bridge start --name YOUR_CONNECTION --service-managed` with explicit `connect --no-service`. Optional `--skills-dir PATH` installs the guide in a host-supported directory; otherwise use `oomi instructions`.
75
-
76
- The direct adapter targets the installed Grok Bot local gateway contract. An incompatible provider update fails closed. Each real host must pass verification, then an authorized Oomi message round trip, before claiming it is connected end to end.
77
-
78
- ## Updating Oomi safely
79
-
80
- When the user asks you to update Oomi, read `oomi instructions` first; it supersedes copied setup/restart recipes. Keep the same connection on the same computer.
81
-
82
- 1. Run `oomi update --connection NAME` (omit the selector for default OpenClaw). This only checks versions. If already current, report that and stop: do not reinstall or restart "to be sure."
83
- 2. If an update exists, run the returned exact-version npm install command **alone**, through the runtime's normal approval flow. Do not append redirections, status checks or restarts. If installation is denied, fails, or cannot be verified, leave the bridge alone and explain the approval/error. Never disable security checks, retry through another executor, or enable blanket unattended approvals.
84
- 3. After successful installation, check `npm list -g oomi-ai --depth=0` and `oomi update` separately. Only then run `oomi bridge repair --connection NAME`.
85
- 4. A running 0.8.1+ supervised bridge queues its restart until active replies finish and queued phone replies are saved. If the result is `queued`, finish your reply now; do not wait for your own turn to end, poll in a loop, or claim completion. `oomi status --connection NAME --json` subsequently reports maintenance `completed`/`failed` and the running `packageVersion`. Pairing and conversations stay intact.
86
-
87
- For packages before 0.8.1 (no `oomi update` command), read the published guide, check `npm list -g oomi-ai --depth=0` and `npm view oomi-ai version` in separate commands. If equal, stop. Otherwise install the exact returned version through normal approvals. The first restart of an older or unsupervised bridge must happen from an independent host terminal/agent session, outside the Oomi conversation it would terminate. New CLI commands refuse to stop their own older host. After that bootstrap, in-chat restarts use the deferred path.
88
-
89
- Hermes single-query mode has no interactive approval surface. If its package/security check requires a human, tell the user to approve/run the exact install in an approval-capable host session, then continue there. A blocked install is not a reason to restart. Oomi does not override host permissions. `bridge repair` is also available for an actual connection fault when no package update is needed.
90
-
91
- ## Standard Connect Flow
92
-
93
- For a new installation (for an existing installation, use the safe update flow below):
94
-
95
- ```bash
96
- npm install -g oomi-ai@latest
97
- ```
98
-
99
- Run ONE command for your runtime:
100
-
101
- ```bash
102
- # OpenClaw (reuses existing default OpenClaw pairing)
103
- oomi connect --runtime openclaw --app-url https://www.oomi.ai
104
-
105
- # Hermes (separate connection, no OpenClaw required)
106
- oomi connect --runtime hermes --name hermes --app-url https://www.oomi.ai
107
-
108
- # Another local agent, through its own adapter
109
- oomi connect --runtime command --name my-agent --command '["/absolute/path/to/adapter"]' --app-url https://www.oomi.ai
110
- ```
111
-
112
- Use the user's app URL when provided. Hermes supports `--profile <profile>` and `--resume <exact-session-id>`. Without `--resume`, Oomi starts a persistent conversation with the same configured agent. Do not use `latest` or claim that an existing chat session was transferred unless its exact ID was selected. With oomi-ai 0.8.2+, an already-open Hermes conversation uses its existing local gateway owner and exact profile/session. Oomi attaches as another client; it never closes desktop, clears history, deletes a session lock, or substitutes a new chat. When no live owner exists, an Oomi-owned conversation (no `--resume`) runs on a warm `hermes acp` process with oomi-ai 0.9.0+: replies stream as they are written and stop when the person interrupts. From 0.9.1 the bridge starts Hermes and reopens recent conversations ahead of time (at bridge start and when a call opens), so the first message doesn't wait for Hermes to start. Hermes permission requests are denied, as `chat --quiet` denies dangerous commands; ordinary file edits run as they do in quiet mode. A conversation moving from the CLI starts a new Hermes session that receives the recent Oomi history. `--resume` conversations, Hermes without ACP, and `--hermes-transport cli` use `chat --quiet --query-file -` and resume the exact returned `session_id` on subsequent turns.
113
-
114
- Shared desktop conversations require Hermes's loopback WebSocket gateway, active-session discovery, and durable prompt/reply row IDs. Busy conversations ask you to retry after the current task. If a simultaneous desktop send queues your message without a reply receipt, or the connection drops after sending, check the same Hermes chat before resending. Oomi cannot safely repeat an uncertain action. Human approvals stay in the existing Hermes desktop UI. Shared photo submission is not yet supported; use Hermes desktop for that photo. Older or terminal-only owners without a shared gateway receive an actionable error, never a competing process. The shared owner keeps its existing environment, so use the explicit Oomi `--connection NAME` for account commands.
115
-
116
- The command verifies a real local reply, reuses saved credentials or pairs once, starts the bridge, waits for Oomi's subscription, then creates a single-use Auth Link. Failed verification means setup is incomplete: repair the selected runtime, never substitute a different one.
117
-
118
- The installer is an alternative to npm plus connect, and requires an explicit runtime:
119
-
120
- ```bash
121
- curl -fsSL https://www.oomi.ai/install.sh | bash -s -- --runtime hermes --name hermes
122
- ```
123
-
124
- ## Agent settings and identity backups
125
-
126
- If you already have a name, add `--agent-name "Your name"` to `oomi connect`. The separate `--name` / `--connection` flag identifies a saved connection, not your display name. Do not invent a name merely to fill this field. Reconnecting preserves the account's saved name.
127
-
128
- You can read and update your own Oomi settings from any chat where you have your local CLI, including channels outside Oomi. Always select the same connection:
129
-
130
- ```bash
131
- oomi identity get --connection hermes
132
- oomi identity set --connection hermes --agent-name "Miso" --bio "A curious everyday companion" --profile-image-url "https://example.com/miso.png"
133
- ```
134
-
135
- Omit `--connection` for the default OpenClaw connection. Any of the three setting flags can be supplied alone. Use an empty bio/image value to clear it. Profile images are HTTPS URLs; 3D models are reserved for Oomi and coming soon.
136
-
137
- When a user changes settings on the website, the bridge delivers a versioned notice to your actual local runtime, including while no Oomi chat is open. Before applying it, read the current identity again. Persist the current name in your own identity file so your other channels know it: OpenClaw normally uses IDENTITY.md, Hermes uses SOUL.md. Keep the rest of your personality and memories intact. Save the short profile/image as Oomi settings, not replacement personality instructions.
138
-
139
- After saving, acknowledge the exact `identityId` and `revision` returned by `identity get`:
140
-
141
- ```bash
142
- oomi identity acknowledge --connection hermes --identity-id <identityId> --revision <revision>
143
- ```
144
-
145
- Never acknowledge a version you did not save. A 409 means the settings changed; read and apply the newer version. The website distinguishes pending delivery, agent notified, and agent confirmed. A reply alone does not mean your local identity was updated. Existing running conversations may retain older context until they reload identity; tell the user if a runtime requires a new conversation or restart.
146
-
147
- Backups are opt-in. Obtain the user's choice of files and inspect those files for secrets before uploading. Do not upload an entire workspace, credentials, user profiles, memories, or chat history. Supported files are SOUL.md, IDENTITY.md, AGENTS.md, and TOOLS.md, at most 64 KiB each. Identity files can themselves contain private information; the filename allowlist is not a secret scanner.
148
-
149
- ```bash
150
- oomi identity backup --connection hermes --files '["/absolute/path/SOUL.md"]'
151
- oomi identity backups --connection hermes
152
- oomi identity restore --connection hermes --snapshot <id> --output /path/to/new-review-folder
153
- ```
154
-
155
- Backups include current Oomi profile settings and deduplicate identical contents. Up to 50 versions are retained; the user can download or delete versions in Agent settings. Restore exports into a new private folder and refuses to overwrite any existing directory. Review the files before applying them manually; restoration does not automatically rename Oomi or modify a running agent. Disconnecting an agent preserves its backups under the original owner.
156
-
157
- ## Required User-Facing Result
158
-
159
- Return the verified runtime/profile and the printed Auth Link. The human opens the link, signs in, and approves ownership. Only after a message receives a reply in Oomi can you claim end-to-end delivery works. Never expose raw tokens, pairing codes, or gateway credentials.
160
-
161
- ## Repair and Reconnect
162
-
163
- Use the SAME connection name from setup. Omit `--name` for default OpenClaw.
164
-
165
- ```bash
166
- oomi status --name hermes --json
167
- oomi verify --name hermes
168
- oomi bridge repair --name hermes
169
- oomi invite --name hermes --app-url https://www.oomi.ai
170
- ```
171
-
172
- Do not pair again to refresh an expired Auth Link. Re-running `connect` reuses saved pairing and verification; only the first connection or an explicit `oomi verify` sends a model probe. A different command, profile, or working directory requires a new connection name, so one agent cannot silently replace another. Named connections store private state and logs under `~/.oomi/connections/<name>`; default OpenClaw keeps `~/.openclaw`. Since 0.8.0, `connect` installs a separate automatic-start service for each connection: macOS launchd or Linux systemd user. It restarts an exited worker and starts at the next login/user session. Linux servers can start at boot and remain running after logout when the host administrator enables user lingering (`loginctl enable-linger <user>`); `oomi bridge service status --name hermes` reports whether this is enabled. WSL needs systemd and a running WSL instance; native Windows does not yet have an automatic service installer. A sleeping, powered-off, or disconnected computer remains unavailable.
173
-
174
- Run `oomi bridge list` to find saved connection names and their startup protection on this computer. To update an existing connection on **each computer**, follow Updating Oomi safely above. Repair preserves pairing and conversations. On a running 0.8.1+ supervised bridge it queues a safe restart and reports pending work; on a stopped bridge it installs/starts supervision and waits for the broker connection. It does not send a model probe or switch agents. Do not copy connection credentials between computers.
175
-
176
- Use `oomi bridge service status --name hermes --json` to inspect startup protection. `oomi bridge stop --name hermes` disables automatic startup and stops only that connection; `oomi bridge start --name hermes` enables it again. `oomi bridge service uninstall --name hermes` removes startup management without deleting saved state. The legacy `oomi openclaw bridge service` command remains supported.
177
-
178
- For containers or an existing external supervisor, use `connect --no-service` explicitly, then configure that supervisor to run `oomi bridge start --name <name> --service-managed` in the foreground. Detached mode alone does not provide crash/login recovery. Setup fails with an actionable error when the service manager is unavailable; never claim automatic startup in that case. The phone's Reconnect button reconnects the client; it cannot wake a computer or start a missing host process.
179
-
180
- `connected` describes the broker transport. Inspect `runtimeReady`, `verifiedAt`, and `lastReplyAt` separately. A process ID, Auth Link, or broker connection alone does not prove the agent is answering.
181
-
182
- ## Other Runtime Adapter Contract
183
-
184
- `--command` is a JSON argv array, not a shell command. Write an adapter against the selected agent's documented API or noninteractive CLI. The executable reads one JSON object from stdin:
185
-
186
- ```json
187
- {"sessionKey":"...","message":"...","idempotencyKey":"...","history":[],"runtimeSessionId":"..."}
188
- ```
189
-
190
- It writes `{"text":"final reply","sessionId":"optional-runtime-session"}` to stdout and exits zero on success. Errors must exit nonzero; diagnostics go to stderr. Resume `runtimeSessionId`, or use `history` for stateless runtimes. Never bypass the agent's existing approval rules. The adapter supports text (including voice transcripts); attachments are rejected explicitly. A failed or interrupted action is not silently repeated. Check the agent before sending a new message after a failure.
191
-
192
- ## OpenClaw Channel Extension
193
-
194
- Managed web text and voice connect through the local gateway. The optional OpenClaw `oomi-ai` channel plugin handles agent-initiated channel output. If you need that path, install the plugin, enable its entry in OpenClaw, apply `oomi openclaw plugin --show-secrets --backend-url https://api.oomi.ai` locally, and restart OpenClaw. Never share that secret config with the user. Disabling the plugin does not explain a gateway protocol rejection.
195
-
196
- OpenClaw gateway protocols 3 and 4 are negotiated independently of the broker. For an existing install affected by a protocol mismatch, update `oomi-ai`, then run `oomi connect --runtime openclaw --app-url https://www.oomi.ai`.
197
-
198
-
199
- ## Configuration
200
-
201
- OpenClaw channel config lives under:
202
-
203
- ```json
204
- {
205
- "channels": {
206
- "oomi": {
207
- "defaultAccountId": "default",
208
- "accounts": {
209
- "default": {
210
- "backendUrl": "https://api.oomi.ai",
211
- "deviceToken": "...",
212
- "defaultSessionKey": "agent:main:webchat:channel:oomi",
213
- "requestTimeoutMs": 15000
214
- }
215
- }
216
- }
217
- }
218
- }
219
- ```
220
-
221
- Required fields:
222
-
223
- - `backendUrl`
224
- - `deviceToken`
225
-
226
- Optional fields:
227
-
228
- - `defaultSessionKey`
229
- - `requestTimeoutMs`
230
-
231
- Hosted Oomi-managed agents also include a `modelRelay` block under the default account. When enabled, `oomi-ai` applies an OpenClaw custom provider named `oomi-managed` that points at Oomi's OpenAI-compatible metered relay:
232
-
233
- ```json
234
- {
235
- "channels": {
236
- "oomi": {
237
- "accounts": {
238
- "default": {
239
- "modelRelay": {
240
- "enabled": true,
241
- "backendUrl": "https://api.oomi.ai",
242
- "openaiBasePath": "/v1/model/relay/openai",
243
- "openclawProviderId": "oomi-managed",
244
- "openclawModelRef": "oomi-managed/google/gemini-2.5-flash",
245
- "provider": "openrouter",
246
- "model": "google/gemini-2.5-flash",
247
- "userId": "usr_...",
248
- "deviceId": "oomi-hosted-...",
249
- "internalKeyEnv": "OOMI_HOSTED_BOOTSTRAP_INTERNAL_KEY"
250
- }
251
- }
252
- }
253
- }
254
- }
255
- }
256
- ```
257
-
258
- The config stores only the internal-key environment variable name. The secret value stays in the runtime environment.
259
-
260
- ## Persona App API Tools
261
-
262
- Component-composed persona apps are the default Oomi mini-app path. Use these commands when the user asks about or updates an existing Oomi persona app such as Fitness Today:
263
-
264
- ```bash
265
- oomi persona-apps list --json
266
- oomi persona-apps show fitness-today --json
267
- oomi persona-apps apply-action fitness-today --action fitness.complete_workout --payload-json '{"goalId":"easy-run","minutes":20}' --json
268
- ```
269
-
270
- Rules for agents:
271
-
272
- - Answer from returned `appState.bindings`, not from memory.
273
- - Apply updates only through approved `persona-apps apply-action` actions.
274
- - If the persona app does not exist, tell the user to add it from the Oomi client first.
275
- - Do not create local persona UI projects.
276
-
277
- For the Fitness v0 slice:
278
-
279
- ```bash
280
- oomi persona-apps apply-action fitness-today --action fitness.complete_goal --payload-json '{"goalId":"easy-run"}' --json
281
- oomi persona-apps apply-action fitness-today --action fitness.complete_workout --payload-json '{"goalId":"easy-run","minutes":20}' --json
282
- ```
283
-
284
- ## Context Tools
285
-
286
- Use context tools when the user asks a data-backed question that should come from Oomi-approved mobile permissions, not model memory. For health and fitness questions, read the latest backend HealthKit context first:
287
-
288
- ```bash
289
- oomi context health --json
290
- ```
291
-
292
- Clients built from the health-history revision also support stored date ranges:
293
-
294
- ```bash
295
- oomi context health --window year --date 2025-06-01 --group-by month --json
296
- oomi context health --window all --shape summary --json
297
- ```
298
-
299
- For these queries, follow `healthHistory.agentGuidance` and use `healthHistory.summary` or `series`. Stored history remains usable while the phone is offline; missing days are unknown. See the [health-history guide](../../docs/2026-09-28-health-history-and-agent-parity.md) for custom ranges and pagination.
300
-
301
- Rules for agents:
302
-
303
- - Answer from `healthContext.summary` and `healthContext.derived`.
304
- - Respect `healthContext.agentGuidance.canAnswerFromContext`.
305
- - If `healthContext.agentGuidance.recommendedCommand` is present, run it before answering current/latest health questions.
306
- - If context is `stale` or `needs_sync`, run `oomi context health sync --wait --json`; answer only after fresh context is uploaded, or tell the user the phone sync is still pending if it times out.
307
- - If context is `missing`, `permission_denied`, `disabled_by_user`, or `unavailable`, tell the user what repair action is needed instead of guessing.
308
- - Never present stale HealthKit values as current values.
309
- - Do not ask the phone for HealthKit directly; the Oomi mobile app syncs HealthKit to the backend.
310
-
311
- ## Voice Contract
312
-
313
- Managed voice uses the same Oomi plugin and bridge layer as managed chat.
314
-
315
- For assistant replies, visible chat text stays user-facing. Optional hidden TTS metadata may live at `metadata.spoken`:
316
-
317
- ```json
318
- {
319
- "metadata": {
320
- "spoken": {
321
- "text": "Speech-optimized text for TTS only.",
322
- "language": "English",
323
- "instructions": "Speak with warm, upbeat conversational energy and natural pacing."
324
- }
325
- }
326
- }
327
- ```
328
-
329
- Rules:
330
-
331
- - visible `content` is the source of truth for chat rendering
332
- - `metadata.spoken.text` is backend TTS input only
333
- - visible chat text should not contain raw speaking tags
334
- - the package preserves valid `metadata.spoken`
335
- - if omitted, the package may synthesize a bounded fallback from visible assistant text
336
-
337
- ## Health Checks
338
-
339
- Use these when chat or voice is failing:
340
-
341
- ```bash
342
- oomi openclaw bridge ps
343
- oomi openclaw bridge service status
344
- oomi openclaw status
345
- tail -f ~/.openclaw/logs/oomi-bridge-live.log
346
- tail -f ~/.openclaw/logs/gateway.log
347
- tail -f ~/.openclaw/logs/gateway.err.log
348
- ```
349
-
350
- Bridge status meanings:
351
-
352
- - `starting`: bridge booting or waiting for managed subscription
353
- - `connected`: subscribed to the Oomi broker; inspect `runtimeReady` and verify a real reply separately
354
- - `reconnecting`: transport dropped and retry is scheduled
355
- - `degraded`: bridge caught a runtime fault but is still alive
356
- - `error`: startup or auth failure blocked useful operation
357
- - `stopped`: not running or intentionally stopped
358
-
359
- ## Troubleshooting
360
-
361
- Duplicate plugin id warning:
362
-
363
- - Cause: multiple discoverable `oomi-ai` installs.
364
- - Action: remove stale extension copies and reinstall once.
365
-
366
- `invalid handshake: first request must be connect`:
367
-
368
- - Cause: a gateway request was sent before `connect` had been accepted.
369
- - Action: update `oomi-ai`, restart the bridge, and confirm only one bridge worker is running.
370
-
371
- STT works but the assistant does not reply:
372
-
373
- - Cause: the voice turn likely reached Oomi, but the managed gateway or OpenClaw run failed later.
374
- - Action: inspect `gateway.log`, `gateway.err.log`, and the session JSONL for auth, network, or bridge restart errors.
375
-
376
- Bridge keeps using an old package after update:
377
-
378
- - Action: follow Updating Oomi safely above, then inspect `oomi status --json` for running version and maintenance result.
379
- - If still stale: run `oomi bridge repair` for default OpenClaw, or add the existing `--name` for a named connection.
380
- - On macOS service installs: run `oomi openclaw bridge service restart`.
381
- - Confirm with `oomi openclaw bridge ps`.
382
-
383
- ## Developer Verification
384
-
385
- From `packages/oomi-ai`:
386
-
387
- ```bash
388
- npm run check
389
- npm test
390
- npm pack --dry-run
391
- npm publish --dry-run --no-git-checks --access public
392
- ```
393
-
394
- Expected package contents are restricted by the `files` allowlist in `package.json`.
395
-
396
- ## Routines (0.6.0)
397
-
398
- Oomi now stores a primary agent and reliable recurring check-ins. Agents can propose, revise, activate, pause, and record responses entirely through chat. Run `oomi routines context`, `oomi routines preferences`, and `oomi routines list` using the same `--connection` as setup. See [the operator guide](agent_instructions.md#primary-agent-routines-and-notifications-oomi-ai-060) for complete request schemas, owner authorization, retries, and events. Restart the bridge after updating to enable event delivery.
399
-
400
- ## Spaces and quiet updates (0.7.0)
401
-
402
- Run `oomi capabilities` for the command map, `oomi instructions` for the installed guide, and `oomi spaces catalog --connection <name>` for supported components and bindings. Agents create and edit persistent Spaces with `spaces create/update --file`, including from other chats, without asking the user to build UI. User edits and agent writes share revisions and idempotency keys. See the packaged Oomi skill for complete examples, source permissions, layout recovery, and routine authority.
403
-
404
- When the live catalog advertises `space.v2`, named `sources` and component `sourceRef` fields connect shared readings, recorded workouts, and separate Fitness completions. Include `schemaVersion:"space.v2"` on every write to such a Space (or `--schema-version space.v2` for flag-only commands). These dependencies update data quietly without changing layout revisions, granting provider permissions, or scheduling reminders. Display periods are independent of goal recurrence.
405
-
406
- When the catalog advertises `space.v3`, `oomi objectives list/show/history/create/update/respond` manages reusable daily, selected-day, weekly, monthly and one-time goals. Space `objective` components reference those IDs; optional `streak` components reference matching calendars and count full history. Both clients support creation, manual corrections, older progress, and prospective target/pause changes. Use `schemaVersion:"space.v3"` for these Spaces. The [operator guide](agent_instructions.md#recurring-goals-and-optional-streaks-spacev3) describes authority, calendars, source rules, reminders and retries. This source change has not been published to npm.
407
-
408
- For short health answers, use `oomi context health --window week --metric steps --json`; use an explicit date range for calendar weeks. `--output <new-file>` saves full private JSON rather than risking terminal truncation.
409
-
410
- Ordinary state events sync quietly and are available through `oomi updates`. Phone reminders work without model turns. Explicit routine `agentWakeEnabled:true` enables a bounded wake path (six attempts/hour, no automatic retry after an uncertain model dispatch). Older bridges receive no wake events. Owner identity edits receive one notice per revision; agent-originated edits do not wake the agent again. Initial setup and explicit `oomi verify` send a test message; unchanged reconnects reuse successful verification, including after a failed pairing attempt. Install/update and restart the selected bridge to use the new workers.
411
-
412
- `spaces upgrade ID --file upgrade.json` applies explicit checklist-to-goal, streak and named-source mappings in one revision-checked transaction. It preserves unrelated plan data and never turns undated legacy ticks into dated completions. Goal rules may also use an either/or set of presence sources, for example a recorded workout or a Fitness check-in, counting the period once. Read the live catalog before using new capabilities; source code in this branch does not imply an npm release.
413
-
414
- ### Native desktop runtime selection
415
-
416
- A native app can pin its own Hermes fork rather than resolving a different agent from PATH:
417
-
418
- ```sh
419
- oomi connect --runtime hermes --name mac-companion --hermes-home /path/to/home --profile default --hermes-command '["/path/to/python","-m","hermes_cli.main"]' --cwd /path/to/oomi-hermes
420
- ```
421
-
422
- The structured launcher, home, profile and exact `--resume` session are saved with that named connection. Reconnect reuses them; changing them requires a new connection name. Native callers must use argv without a shell, obtain explicit consent for the initial verification/model call and login service, and show the returned Auth Link for account ownership approval. Do not substitute a different installed agent.
423
-
424
- ## Agent channels (0.10.0)
425
-
426
- An agent channel lets another agent talk with this one directly, and the owner can watch and end it. The other agent can be Claude, Codex, a Grok bot or another Oomi agent.
427
-
428
- - **Host:** `oomi channel create --purpose "..." --connection <name>` returns a single-use link (`/channel/<token>`). Each guest message wakes the agent in a separate session, `agent:main:oomi:channel:<id>`. The turn's final reply text is posted back, and an uncertain turn is never rerun.
429
- - **Guest:** the guest only needs the link. It reads instructions there, joins once to get a private guest token, then sends and long-polls over HTTPS. An Oomi agent can instead run `oomi channel join <link>`, which marks it verified to the owner.
430
- - **Both sides:** `oomi channel list`, `show`, `send` and `end` work for both roles.
431
-
432
- For a person, run `oomi channel create --for person --purpose "..." --owner-name NAME`. This returns a 24-hour web chat link for them and a sign-in-only `watchUrl` for the owner. Each chat has permissions (`privateInfo`, `actions`, `commands`, `payments`), all set to ask first by default. Agents may only restrict them with `--deny`. For an ask-first action, run `oomi channel request-approval`. The owner is notified by push and in their Oomi chat, and their decision returns as an Oomi approval notice.
433
-
434
- Guests never gain owner authority or account access. The owner can read the hash-chained transcript and end the channel from Agent settings.
435
-
436
- Restart the bridge after updating so it runs the channel worker. Run `oomi instructions` for the full guide.
1
+ # oomi-ai
2
+
3
+ Connect OpenClaw, Hermes, Grok Bot, and other agents to Oomi through an explicit runtime adapter.
4
+
5
+ `oomi-ai` connects the selected local agent to Oomi. Persona UI creation and rendering happen inside Oomi-managed systems. The OpenClaw machine uses API actions only.
6
+
7
+ The current model is:
8
+
9
+ - The selected agent talks to Oomi through managed channel and bridge APIs.
10
+ - Oomi clients render persona apps from approved templates, components, data bindings, actions, and permissions.
11
+ - The agent may inspect and update persona app state through approved Oomi API actions.
12
+ - The user adds persona apps from the Oomi client so platform permissions and data hydration happen in the right place.
13
+
14
+ ## What This Package Ships
15
+
16
+ 1. OpenClaw channel extension
17
+
18
+ - File: `openclaw.extension.js`
19
+ - Purpose: managed text transport through the Oomi backend channel API.
20
+
21
+ 2. Local bridge and CLI
22
+
23
+ - Files: `bin/oomi-ai.js`, `bin/sessionBridgeState.js`
24
+ - Purpose: pair a device, manage the OpenClaw bridge worker, and support managed gateway traffic for device-backed chat and voice.
25
+
26
+ 3. Persona app API tools
27
+
28
+ - Files: `persona-app/*`, `lib/personaApiClient.js`, `bin/oomi-ai.js`
29
+ - Purpose: inspect account-linked component-composed persona apps and apply approved backend actions.
30
+
31
+ 4. Permissioned context tools
32
+
33
+ - Files: `lib/personaApiClient.js`, `bin/oomi-ai.js`
34
+ - Purpose: read user-approved Oomi backend context, such as HealthKit summaries synced by the mobile app.
35
+
36
+ 5. Agent/operator instructions
37
+
38
+ - Files: `agent_instructions.md`, `skills/oomi/*`
39
+ - Purpose: tell OpenClaw agents how to connect, repair, and use Oomi without local UI code generation.
40
+
41
+ ## Boundary
42
+
43
+ Persona UI is an Oomi-managed client capability, not an OpenClaw-machine responsibility.
44
+
45
+ This package exposes connection, bridge, voice, and persona app state APIs. It does not include a local persona app workspace, local persona runtime manager, queued UI job runner, or app framework bundle.
46
+
47
+ ## Connect Your Local Agent
48
+
49
+ Connect the agent the user is speaking to. Identify your runtime, bot/profile, and actual host first. Computer access does not mean you run on that computer. Never substitute another installed agent.
50
+
51
+ ## Choose a connection by interface (oomi-ai 0.8.5+)
52
+
53
+ Run setup on the host where **this agent** runs. A Grok Bot with access to someone's Mac still runs on its Grok Bot host; connecting an OpenClaw agent on that Mac does not connect the Grok Bot. No new model API key or replacement bot is needed.
54
+
55
+ 1. Identify yourself from your current runtime context: bot/profile identity, host, and conversation behavior. Do not guess from installed executables or names.
56
+ 2. Run `oomi capabilities`. OpenClaw and Hermes have native adapters. Grok Bot uses its own local gateway through the adapter described below. An unlisted brand is not automatically unsupported: inspect its documented message input **and completed-reply** interfaces (CLI, API, SDK, webhook, or inbound channel).
57
+ 3. For another runtime, use `--runtime command` to wrap those interfaces and return `{text, sessionId?}` only when the same agent has finished. A health endpoint or an accepted/queued response is not a final reply. If no supported input or reply interface exists, state that specific missing capability; never invent one or select another agent.
58
+ 4. Preserve identity, memories and host approvals. Say whether you resume an exact existing conversation or keep an Oomi conversation with the same agent. Verify a real reply before sharing an Auth Link; verify delivery in Oomi before claiming completion.
59
+
60
+ ### Grok Bot: connect the existing bot
61
+
62
+ On **this bot's own Linux host**, install/update the package through the normal host approval flow, then run:
63
+
64
+ ```bash
65
+ oomi connect --runtime grokbot --name YOUR_CONNECTION --agent-id YOUR_BOT_UUID --agent-name "Your name" --app-url https://www.oomi.ai
66
+ ```
67
+
68
+ Use your exact bot UUID from your runtime context. Never choose whichever bot happens to be active on a shared computer. Run `oomi grokbot instructions --name YOUR_CONNECTION --agent-id YOUR_BOT_UUID` for the focused setup guide. The package uses the host's existing private local gateway; **do not ask the user to copy a webhook URL/key or create a routine**. Fresh connections require no `grokbot.json`. Existing explicit webhook configurations remain supported. If the local gateway is missing or incompatible, report that specific error and keep the selected identity; do not invent another input interface or substitute an agent.
69
+
70
+ Setup returns **queued**, then waits in the background. Finish your current bot turn immediately so the verification can execute; waiting for your own verification in that turn deadlocks the host. The package installs its private Oomi delivery skill and waits until this bot has loaded it. Incoming chat shows the original message with a small skill tag; the skill claims the private request and submits its final reply. Missing or locally modified skills fail before sending; do not replace them with instruction walls in chat. Continue only for `status: claimed`. A verification answer must be exactly `OOMI_OK`. The reply command reports one Auth Link only after verification, pairing and bridge subscription succeed. Show the Auth Link to the user. If pending, finish the turn and use `oomi grokbot status --name YOUR_CONNECTION` later. Queued is not connected. Acceptance by the host is not a completed answer.
71
+
72
+ Use explicit `--connection YOUR_CONNECTION` for Oomi account commands: a shared host does not inherit the bridge's environment. Text and voice transcripts are supported; photos are rejected. Oomi supplies conversation history; exact Grok Bot desktop/DM conversation continuation is not guaranteed. Host approvals remain in Grok Bot. Do not repeat uncertain or already-claimed actions; inspect the original run. Reconnect reuses verification and pairing; `oomi verify --name YOUR_CONNECTION` explicitly queues a new model verification.
73
+
74
+ Oomi uses systemd user services where available. On Linux hosts without systemd, it automatically supervises bridge worker exits for the current host session. **After the whole cloud computer restarts, rerun the same connect command.** This fallback cannot start itself at boot. Use `oomi status --name YOUR_CONNECTION --json` to inspect recovery. A host-provided external supervisor can instead run `oomi bridge start --name YOUR_CONNECTION --service-managed` with explicit `connect --no-service`. Optional `--skills-dir PATH` installs the guide in a host-supported directory; otherwise use `oomi instructions`.
75
+
76
+ The direct adapter targets the installed Grok Bot local gateway contract. An incompatible provider update fails closed. Each real host must pass verification, then an authorized Oomi message round trip, before claiming it is connected end to end.
77
+
78
+ ## Updating Oomi safely
79
+
80
+ When the user asks you to update Oomi, read `oomi instructions` first; it supersedes copied setup/restart recipes. Keep the same connection on the same computer.
81
+
82
+ 1. Run `oomi update --connection NAME` (omit the selector for default OpenClaw). This only checks versions. If already current, report that and stop: do not reinstall or restart "to be sure."
83
+ 2. If an update exists, run the returned exact-version npm install command **alone**, through the runtime's normal approval flow. Do not append redirections, status checks or restarts. If installation is denied, fails, or cannot be verified, leave the bridge alone and explain the approval/error. Never disable security checks, retry through another executor, or enable blanket unattended approvals.
84
+ 3. After successful installation, check `npm list -g oomi-ai --depth=0` and `oomi update` separately. Only then run `oomi bridge repair --connection NAME`.
85
+ 4. A running 0.8.1+ supervised bridge queues its restart until active replies finish and queued phone replies are saved. If the result is `queued`, finish your reply now; do not wait for your own turn to end, poll in a loop, or claim completion. `oomi status --connection NAME --json` subsequently reports maintenance `completed`/`failed` and the running `packageVersion`. Pairing and conversations stay intact.
86
+
87
+ For packages before 0.8.1 (no `oomi update` command), read the published guide, check `npm list -g oomi-ai --depth=0` and `npm view oomi-ai version` in separate commands. If equal, stop. Otherwise install the exact returned version through normal approvals. The first restart of an older or unsupervised bridge must happen from an independent host terminal/agent session, outside the Oomi conversation it would terminate. New CLI commands refuse to stop their own older host. After that bootstrap, in-chat restarts use the deferred path.
88
+
89
+ Hermes single-query mode has no interactive approval surface. If its package/security check requires a human, tell the user to approve/run the exact install in an approval-capable host session, then continue there. A blocked install is not a reason to restart. Oomi does not override host permissions. `bridge repair` is also available for an actual connection fault when no package update is needed.
90
+
91
+ ## Standard Connect Flow
92
+
93
+ For a new installation (for an existing installation, use the safe update flow below):
94
+
95
+ ```bash
96
+ npm install -g oomi-ai@latest
97
+ ```
98
+
99
+ Run ONE command for your runtime:
100
+
101
+ ```bash
102
+ # OpenClaw (reuses existing default OpenClaw pairing)
103
+ oomi connect --runtime openclaw --app-url https://www.oomi.ai
104
+
105
+ # Hermes (separate connection, no OpenClaw required)
106
+ oomi connect --runtime hermes --name hermes --app-url https://www.oomi.ai
107
+
108
+ # Another local agent, through its own adapter
109
+ oomi connect --runtime command --name my-agent --command '["/absolute/path/to/adapter"]' --app-url https://www.oomi.ai
110
+ ```
111
+
112
+ Use the user's app URL when provided. Hermes supports `--profile <profile>` and `--resume <exact-session-id>`. Without `--resume`, Oomi starts a persistent conversation with the same configured agent. Do not use `latest` or claim that an existing chat session was transferred unless its exact ID was selected. With oomi-ai 0.8.2+, an already-open Hermes conversation uses its existing local gateway owner and exact profile/session. Oomi attaches as another client; it never closes desktop, clears history, deletes a session lock, or substitutes a new chat. When no live owner exists, an Oomi-owned conversation (no `--resume`) runs on a warm `hermes acp` process with oomi-ai 0.9.0+: replies stream as they are written and stop when the person interrupts. From 0.9.1 the bridge starts Hermes and reopens recent conversations ahead of time (at bridge start and when a call opens), so the first message doesn't wait for Hermes to start. Hermes permission requests are denied, as `chat --quiet` denies dangerous commands; ordinary file edits run as they do in quiet mode. A conversation moving from the CLI starts a new Hermes session that receives the recent Oomi history. `--resume` conversations, Hermes without ACP, and `--hermes-transport cli` use `chat --quiet --query-file -` and resume the exact returned `session_id` on subsequent turns.
113
+
114
+ Shared desktop conversations require Hermes's loopback WebSocket gateway, active-session discovery, and durable prompt/reply row IDs. Busy conversations ask you to retry after the current task. If a simultaneous desktop send queues your message without a reply receipt, or the connection drops after sending, check the same Hermes chat before resending. Oomi cannot safely repeat an uncertain action. Human approvals stay in the existing Hermes desktop UI. Shared photo submission is not yet supported; use Hermes desktop for that photo. Older or terminal-only owners without a shared gateway receive an actionable error, never a competing process. The shared owner keeps its existing environment, so use the explicit Oomi `--connection NAME` for account commands.
115
+
116
+ The command verifies a real local reply, reuses saved credentials or pairs once, starts the bridge, waits for Oomi's subscription, then creates a single-use Auth Link. Failed verification means setup is incomplete: repair the selected runtime, never substitute a different one.
117
+
118
+ The installer is an alternative to npm plus connect, and requires an explicit runtime:
119
+
120
+ ```bash
121
+ curl -fsSL https://www.oomi.ai/install.sh | bash -s -- --runtime hermes --name hermes
122
+ ```
123
+
124
+ ## Agent settings and identity backups
125
+
126
+ If you already have a name, add `--agent-name "Your name"` to `oomi connect`. The separate `--name` / `--connection` flag identifies a saved connection, not your display name. Do not invent a name merely to fill this field. Reconnecting preserves the account's saved name.
127
+
128
+ You can read and update your own Oomi settings from any chat where you have your local CLI, including channels outside Oomi. Always select the same connection:
129
+
130
+ ```bash
131
+ oomi identity get --connection hermes
132
+ oomi identity set --connection hermes --agent-name "Miso" --bio "A curious everyday companion" --profile-image-url "https://example.com/miso.png"
133
+ ```
134
+
135
+ Omit `--connection` for the default OpenClaw connection. Any of the three setting flags can be supplied alone. Use an empty bio/image value to clear it. Profile images are HTTPS URLs; 3D models are reserved for Oomi and coming soon.
136
+
137
+ When a user changes settings on the website, the bridge delivers a versioned notice to your actual local runtime, including while no Oomi chat is open. Before applying it, read the current identity again. Persist the current name in your own identity file so your other channels know it: OpenClaw normally uses IDENTITY.md, Hermes uses SOUL.md. Keep the rest of your personality and memories intact. Save the short profile/image as Oomi settings, not replacement personality instructions.
138
+
139
+ After saving, acknowledge the exact `identityId` and `revision` returned by `identity get`:
140
+
141
+ ```bash
142
+ oomi identity acknowledge --connection hermes --identity-id <identityId> --revision <revision>
143
+ ```
144
+
145
+ Never acknowledge a version you did not save. A 409 means the settings changed; read and apply the newer version. The website distinguishes pending delivery, agent notified, and agent confirmed. A reply alone does not mean your local identity was updated. Existing running conversations may retain older context until they reload identity; tell the user if a runtime requires a new conversation or restart.
146
+
147
+ Backups are opt-in. Obtain the user's choice of files and inspect those files for secrets before uploading. Do not upload an entire workspace, credentials, user profiles, memories, or chat history. Supported files are SOUL.md, IDENTITY.md, AGENTS.md, and TOOLS.md, at most 64 KiB each. Identity files can themselves contain private information; the filename allowlist is not a secret scanner.
148
+
149
+ ```bash
150
+ oomi identity backup --connection hermes --files '["/absolute/path/SOUL.md"]'
151
+ oomi identity backups --connection hermes
152
+ oomi identity restore --connection hermes --snapshot <id> --output /path/to/new-review-folder
153
+ ```
154
+
155
+ Backups include current Oomi profile settings and deduplicate identical contents. Up to 50 versions are retained; the user can download or delete versions in Agent settings. Restore exports into a new private folder and refuses to overwrite any existing directory. Review the files before applying them manually; restoration does not automatically rename Oomi or modify a running agent. Disconnecting an agent preserves its backups under the original owner.
156
+
157
+ ## Required User-Facing Result
158
+
159
+ Return the verified runtime/profile and the printed Auth Link. The human opens the link, signs in, and approves ownership. Only after a message receives a reply in Oomi can you claim end-to-end delivery works. Never expose raw tokens, pairing codes, or gateway credentials.
160
+
161
+ ## Repair and Reconnect
162
+
163
+ Use the SAME connection name from setup. Omit `--name` for default OpenClaw.
164
+
165
+ ```bash
166
+ oomi status --name hermes --json
167
+ oomi verify --name hermes
168
+ oomi bridge repair --name hermes
169
+ oomi invite --name hermes --app-url https://www.oomi.ai
170
+ ```
171
+
172
+ Do not pair again to refresh an expired Auth Link. Re-running `connect` reuses saved pairing and verification; only the first connection or an explicit `oomi verify` sends a model probe. A different command, profile, or working directory requires a new connection name, so one agent cannot silently replace another. Named connections store private state and logs under `~/.oomi/connections/<name>`; default OpenClaw keeps `~/.openclaw`. Since 0.8.0, `connect` installs a separate automatic-start service for each connection: macOS launchd or Linux systemd user. It restarts an exited worker and starts at the next login/user session. Linux servers can start at boot and remain running after logout when the host administrator enables user lingering (`loginctl enable-linger <user>`); `oomi bridge service status --name hermes` reports whether this is enabled. WSL needs systemd and a running WSL instance; native Windows does not yet have an automatic service installer. A sleeping, powered-off, or disconnected computer remains unavailable.
173
+
174
+ Run `oomi bridge list` to find saved connection names and their startup protection on this computer. To update an existing connection on **each computer**, follow Updating Oomi safely above. Repair preserves pairing and conversations. On a running 0.8.1+ supervised bridge it queues a safe restart and reports pending work; on a stopped bridge it installs/starts supervision and waits for the broker connection. It does not send a model probe or switch agents. Do not copy connection credentials between computers.
175
+
176
+ Use `oomi bridge service status --name hermes --json` to inspect startup protection. `oomi bridge stop --name hermes` disables automatic startup and stops only that connection; `oomi bridge start --name hermes` enables it again. `oomi bridge service uninstall --name hermes` removes startup management without deleting saved state. The legacy `oomi openclaw bridge service` command remains supported.
177
+
178
+ For containers or an existing external supervisor, use `connect --no-service` explicitly, then configure that supervisor to run `oomi bridge start --name <name> --service-managed` in the foreground. Detached mode alone does not provide crash/login recovery. Setup fails with an actionable error when the service manager is unavailable; never claim automatic startup in that case. The phone's Reconnect button reconnects the client; it cannot wake a computer or start a missing host process.
179
+
180
+ `connected` describes the broker transport. Inspect `runtimeReady`, `verifiedAt`, and `lastReplyAt` separately. A process ID, Auth Link, or broker connection alone does not prove the agent is answering.
181
+
182
+ ## Other Runtime Adapter Contract
183
+
184
+ `--command` is a JSON argv array, not a shell command. Write an adapter against the selected agent's documented API or noninteractive CLI. The executable reads one JSON object from stdin:
185
+
186
+ ```json
187
+ {"sessionKey":"...","message":"...","idempotencyKey":"...","history":[],"runtimeSessionId":"..."}
188
+ ```
189
+
190
+ It writes `{"text":"final reply","sessionId":"optional-runtime-session"}` to stdout and exits zero on success. Errors must exit nonzero; diagnostics go to stderr. Resume `runtimeSessionId`, or use `history` for stateless runtimes. Never bypass the agent's existing approval rules. The adapter supports text (including voice transcripts); attachments are rejected explicitly. A failed or interrupted action is not silently repeated. Check the agent before sending a new message after a failure.
191
+
192
+ ## OpenClaw Channel Extension
193
+
194
+ Managed web text and voice connect through the local gateway. The optional OpenClaw `oomi-ai` channel plugin handles agent-initiated channel output. If you need that path, install the plugin, enable its entry in OpenClaw, apply `oomi openclaw plugin --show-secrets --backend-url https://api.oomi.ai` locally, and restart OpenClaw. Never share that secret config with the user. Disabling the plugin does not explain a gateway protocol rejection.
195
+
196
+ OpenClaw gateway protocols 3 and 4 are negotiated independently of the broker. For an existing install affected by a protocol mismatch, update `oomi-ai`, then run `oomi connect --runtime openclaw --app-url https://www.oomi.ai`.
197
+
198
+
199
+ ## Configuration
200
+
201
+ OpenClaw channel config lives under:
202
+
203
+ ```json
204
+ {
205
+ "channels": {
206
+ "oomi": {
207
+ "defaultAccountId": "default",
208
+ "accounts": {
209
+ "default": {
210
+ "backendUrl": "https://api.oomi.ai",
211
+ "deviceToken": "...",
212
+ "defaultSessionKey": "agent:main:webchat:channel:oomi",
213
+ "requestTimeoutMs": 15000
214
+ }
215
+ }
216
+ }
217
+ }
218
+ }
219
+ ```
220
+
221
+ Required fields:
222
+
223
+ - `backendUrl`
224
+ - `deviceToken`
225
+
226
+ Optional fields:
227
+
228
+ - `defaultSessionKey`
229
+ - `requestTimeoutMs`
230
+
231
+ Hosted Oomi-managed agents also include a `modelRelay` block under the default account. When enabled, `oomi-ai` applies an OpenClaw custom provider named `oomi-managed` that points at Oomi's OpenAI-compatible metered relay:
232
+
233
+ ```json
234
+ {
235
+ "channels": {
236
+ "oomi": {
237
+ "accounts": {
238
+ "default": {
239
+ "modelRelay": {
240
+ "enabled": true,
241
+ "backendUrl": "https://api.oomi.ai",
242
+ "openaiBasePath": "/v1/model/relay/openai",
243
+ "openclawProviderId": "oomi-managed",
244
+ "openclawModelRef": "oomi-managed/google/gemini-2.5-flash",
245
+ "provider": "openrouter",
246
+ "model": "google/gemini-2.5-flash",
247
+ "userId": "usr_...",
248
+ "deviceId": "oomi-hosted-...",
249
+ "internalKeyEnv": "OOMI_HOSTED_BOOTSTRAP_INTERNAL_KEY"
250
+ }
251
+ }
252
+ }
253
+ }
254
+ }
255
+ }
256
+ ```
257
+
258
+ The config stores only the internal-key environment variable name. The secret value stays in the runtime environment.
259
+
260
+ ## Persona App API Tools
261
+
262
+ Component-composed persona apps are the default Oomi mini-app path. Use these commands when the user asks about or updates an existing Oomi persona app such as Fitness Today:
263
+
264
+ ```bash
265
+ oomi persona-apps list --json
266
+ oomi persona-apps show fitness-today --json
267
+ oomi persona-apps apply-action fitness-today --action fitness.complete_workout --payload-json '{"goalId":"easy-run","minutes":20}' --json
268
+ ```
269
+
270
+ Rules for agents:
271
+
272
+ - Answer from returned `appState.bindings`, not from memory.
273
+ - Apply updates only through approved `persona-apps apply-action` actions.
274
+ - If the persona app does not exist, tell the user to add it from the Oomi client first.
275
+ - Do not create local persona UI projects.
276
+
277
+ For the Fitness v0 slice:
278
+
279
+ ```bash
280
+ oomi persona-apps apply-action fitness-today --action fitness.complete_goal --payload-json '{"goalId":"easy-run"}' --json
281
+ oomi persona-apps apply-action fitness-today --action fitness.complete_workout --payload-json '{"goalId":"easy-run","minutes":20}' --json
282
+ ```
283
+
284
+ ## Context Tools
285
+
286
+ Use context tools when the user asks a data-backed question that should come from Oomi-approved mobile permissions, not model memory. For health and fitness questions, read the latest backend HealthKit context first:
287
+
288
+ ```bash
289
+ oomi context health --json
290
+ ```
291
+
292
+ Clients built from the health-history revision also support stored date ranges:
293
+
294
+ ```bash
295
+ oomi context health --window year --date 2025-06-01 --group-by month --json
296
+ oomi context health --window all --shape summary --json
297
+ ```
298
+
299
+ For these queries, follow `healthHistory.agentGuidance` and use `healthHistory.summary` or `series`. Stored history remains usable while the phone is offline; missing days are unknown. See the [health-history guide](../../docs/2026-09-28-health-history-and-agent-parity.md) for custom ranges and pagination.
300
+
301
+ Rules for agents:
302
+
303
+ - Answer from `healthContext.summary` and `healthContext.derived`.
304
+ - Respect `healthContext.agentGuidance.canAnswerFromContext`.
305
+ - If `healthContext.agentGuidance.recommendedCommand` is present, run it before answering current/latest health questions.
306
+ - If context is `stale` or `needs_sync`, run `oomi context health sync --wait --json`; answer only after fresh context is uploaded, or tell the user the phone sync is still pending if it times out.
307
+ - If context is `missing`, `permission_denied`, `disabled_by_user`, or `unavailable`, tell the user what repair action is needed instead of guessing.
308
+ - Never present stale HealthKit values as current values.
309
+ - Do not ask the phone for HealthKit directly; the Oomi mobile app syncs HealthKit to the backend.
310
+
311
+ ## Voice Contract
312
+
313
+ Managed voice uses the same Oomi plugin and bridge layer as managed chat.
314
+
315
+ For assistant replies, visible chat text stays user-facing. Optional hidden TTS metadata may live at `metadata.spoken`:
316
+
317
+ ```json
318
+ {
319
+ "metadata": {
320
+ "spoken": {
321
+ "text": "Speech-optimized text for TTS only.",
322
+ "language": "English",
323
+ "instructions": "Speak with warm, upbeat conversational energy and natural pacing."
324
+ }
325
+ }
326
+ }
327
+ ```
328
+
329
+ Rules:
330
+
331
+ - visible `content` is the source of truth for chat rendering
332
+ - `metadata.spoken.text` is backend TTS input only
333
+ - visible chat text should not contain raw speaking tags
334
+ - the package preserves valid `metadata.spoken`
335
+ - if omitted, the package may synthesize a bounded fallback from visible assistant text
336
+
337
+ ## Health Checks
338
+
339
+ Use these when chat or voice is failing:
340
+
341
+ ```bash
342
+ oomi openclaw bridge ps
343
+ oomi openclaw bridge service status
344
+ oomi openclaw status
345
+ tail -f ~/.openclaw/logs/oomi-bridge-live.log
346
+ tail -f ~/.openclaw/logs/gateway.log
347
+ tail -f ~/.openclaw/logs/gateway.err.log
348
+ ```
349
+
350
+ Bridge status meanings:
351
+
352
+ - `starting`: bridge booting or waiting for managed subscription
353
+ - `connected`: subscribed to the Oomi broker; inspect `runtimeReady` and verify a real reply separately
354
+ - `reconnecting`: transport dropped and retry is scheduled
355
+ - `degraded`: bridge caught a runtime fault but is still alive
356
+ - `error`: startup or auth failure blocked useful operation
357
+ - `stopped`: not running or intentionally stopped
358
+
359
+ ## Troubleshooting
360
+
361
+ Duplicate plugin id warning:
362
+
363
+ - Cause: multiple discoverable `oomi-ai` installs.
364
+ - Action: remove stale extension copies and reinstall once.
365
+
366
+ `invalid handshake: first request must be connect`:
367
+
368
+ - Cause: a gateway request was sent before `connect` had been accepted.
369
+ - Action: update `oomi-ai`, restart the bridge, and confirm only one bridge worker is running.
370
+
371
+ STT works but the assistant does not reply:
372
+
373
+ - Cause: the voice turn likely reached Oomi, but the managed gateway or OpenClaw run failed later.
374
+ - Action: inspect `gateway.log`, `gateway.err.log`, and the session JSONL for auth, network, or bridge restart errors.
375
+
376
+ Bridge keeps using an old package after update:
377
+
378
+ - Action: follow Updating Oomi safely above, then inspect `oomi status --json` for running version and maintenance result.
379
+ - If still stale: run `oomi bridge repair` for default OpenClaw, or add the existing `--name` for a named connection.
380
+ - On macOS service installs: run `oomi openclaw bridge service restart`.
381
+ - Confirm with `oomi openclaw bridge ps`.
382
+
383
+ ## Developer Verification
384
+
385
+ From `packages/oomi-ai`:
386
+
387
+ ```bash
388
+ npm run check
389
+ npm test
390
+ npm pack --dry-run
391
+ npm publish --dry-run --no-git-checks --access public
392
+ ```
393
+
394
+ Expected package contents are restricted by the `files` allowlist in `package.json`.
395
+
396
+ ## Routines (0.6.0)
397
+
398
+ Oomi now stores a primary agent and reliable recurring check-ins. Agents can propose, revise, activate, pause, and record responses entirely through chat. Run `oomi routines context`, `oomi routines preferences`, and `oomi routines list` using the same `--connection` as setup. See [the operator guide](agent_instructions.md#primary-agent-routines-and-notifications-oomi-ai-060) for complete request schemas, owner authorization, retries, and events. Restart the bridge after updating to enable event delivery.
399
+
400
+ ## Spaces and quiet updates (0.7.0)
401
+
402
+ Run `oomi capabilities` for the command map, `oomi instructions` for the installed guide, and `oomi spaces catalog --connection <name>` for supported components and bindings. Agents create and edit persistent Spaces with `spaces create/update --file`, including from other chats, without asking the user to build UI. User edits and agent writes share revisions and idempotency keys. See the packaged Oomi skill for complete examples, source permissions, layout recovery, and routine authority.
403
+
404
+ When the live catalog advertises `space.v2`, named `sources` and component `sourceRef` fields connect shared readings, recorded workouts, and separate Fitness completions. Include `schemaVersion:"space.v2"` on every write to such a Space (or `--schema-version space.v2` for flag-only commands). These dependencies update data quietly without changing layout revisions, granting provider permissions, or scheduling reminders. Display periods are independent of goal recurrence.
405
+
406
+ When the catalog advertises `space.v3`, `oomi objectives list/show/history/create/update/respond` manages reusable daily, selected-day, weekly, monthly and one-time goals. Space `objective` components reference those IDs; optional `streak` components reference matching calendars and count full history. Both clients support creation, manual corrections, older progress, and prospective target/pause changes. Use `schemaVersion:"space.v3"` for these Spaces. The [operator guide](agent_instructions.md#recurring-goals-and-optional-streaks-spacev3) describes authority, calendars, source rules, reminders and retries. This source change has not been published to npm.
407
+
408
+ For short health answers, use `oomi context health --window week --metric steps --json`; use an explicit date range for calendar weeks. `--output <new-file>` saves full private JSON rather than risking terminal truncation.
409
+
410
+ Ordinary state events sync quietly and are available through `oomi updates`. Phone reminders work without model turns. Explicit routine `agentWakeEnabled:true` enables a bounded wake path (six attempts/hour, no automatic retry after an uncertain model dispatch). Older bridges receive no wake events. Owner identity edits receive one notice per revision; agent-originated edits do not wake the agent again. Initial setup and explicit `oomi verify` send a test message; unchanged reconnects reuse successful verification, including after a failed pairing attempt. Install/update and restart the selected bridge to use the new workers.
411
+
412
+ `spaces upgrade ID --file upgrade.json` applies explicit checklist-to-goal, streak and named-source mappings in one revision-checked transaction. It preserves unrelated plan data and never turns undated legacy ticks into dated completions. Goal rules may also use an either/or set of presence sources, for example a recorded workout or a Fitness check-in, counting the period once. Read the live catalog before using new capabilities; source code in this branch does not imply an npm release.
413
+
414
+ ### Native desktop runtime selection
415
+
416
+ A native app can pin its own Hermes fork rather than resolving a different agent from PATH:
417
+
418
+ ```sh
419
+ oomi connect --runtime hermes --name mac-companion --hermes-home /path/to/home --profile default --hermes-command '["/path/to/python","-m","hermes_cli.main"]' --cwd /path/to/oomi-hermes
420
+ ```
421
+
422
+ The structured launcher, home, profile and exact `--resume` session are saved with that named connection. Reconnect reuses them; changing them requires a new connection name. Native callers must use argv without a shell, obtain explicit consent for the initial verification/model call and login service, and show the returned Auth Link for account ownership approval. Do not substitute a different installed agent.
423
+
424
+ ## Agent channels (0.10.0)
425
+
426
+ An agent channel lets another agent talk with this one directly, and the owner can watch and end it. The other agent can be Claude, Codex, a Grok bot or another Oomi agent.
427
+
428
+ - **Host:** `oomi channel create --purpose "..." --connection <name>` returns a single-use link (`/channel/<token>`). Each guest message wakes the agent in a separate session, `agent:main:oomi:channel:<id>`. The turn's final reply text is posted back, and an uncertain turn is never rerun.
429
+ - **Guest:** the guest only needs the link. It reads instructions there, joins once to get a private guest token, then sends and long-polls over HTTPS. An Oomi agent can instead run `oomi channel join <link>`, which marks it verified to the owner.
430
+ - **Both sides:** `oomi channel list`, `show`, `send` and `end` work for both roles.
431
+
432
+ For a person, run `oomi channel create --for person --purpose "..." --owner-name NAME`. This returns a 24-hour web chat link for them and a sign-in-only `watchUrl` for the owner. Each chat has permissions (`privateInfo`, `actions`, `commands`, `payments`), all set to ask first by default. Agents may only restrict them with `--deny`. For an ask-first action, run `oomi channel request-approval`. The owner is notified by push and in their Oomi chat, and their decision returns as an Oomi approval notice.
433
+
434
+ Guests never gain owner authority or account access. The owner can read the hash-chained transcript and end the channel from Agent settings.
435
+
436
+ Restart the bridge after updating so it runs the channel worker. Run `oomi instructions` for the full guide.