oomi-ai 0.3.2 → 0.3.3

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
@@ -183,6 +183,7 @@ Rules for agents:
183
183
  - Respect `healthContext.agentGuidance.canAnswerFromContext`.
184
184
  - If context is `missing`, `needs_sync`, `permission_denied`, `disabled_by_user`, or `unavailable`, tell the user what repair action is needed instead of guessing.
185
185
  - If context is `stale`, mention freshness when timing matters.
186
+ - To request a fresh phone-side HealthKit sync, run `oomi context health sync --json`. The iPhone app must open or refresh before it can read Apple Health and fulfill the pending request.
186
187
  - Do not ask the phone for HealthKit directly; the Oomi mobile app syncs HealthKit to the backend.
187
188
 
188
189
  ## Voice Contract
@@ -213,7 +213,7 @@ Rules:
213
213
  - `metadata.spoken.language` should use the backend-supported language value for the active provider; use `English` only when no more specific locale is supplied
214
214
  - `metadata.spoken.segments` can carry bounded per-segment prosody for pace, pitch, volume, and pause timing
215
215
  - `metadata.spoken.instructions` should be natural-language guidance, not raw bracket tags
216
- - visible chat text is never rewritten by the package
216
+ - visible chat text should be clean before sending; the package may strip private runtime wrappers and avatar command tags as a safety guardrail
217
217
 
218
218
  ## Avatar Commands
219
219
 
@@ -278,5 +278,6 @@ Rules:
278
278
  - Respect `healthContext.agentGuidance.canAnswerFromContext`.
279
279
  - If `canAnswerFromContext` is false, tell the user the relevant `healthContext.repair.label` or `healthContext.repair.reason`.
280
280
  - If `healthContext.status` is `stale`, mention that the latest HealthKit sync may be out of date when timing matters.
281
+ - If the user asks you to refresh stale HealthKit context, run `oomi context health sync --json`; tell the user the iPhone app must be opened for Oomi to read Apple Health and fulfill the pending sync.
281
282
  - Do not infer unavailable health fields.
282
283
  - Do not request HealthKit directly from the phone; the Oomi mobile app owns permission prompts and syncs approved data to the backend.
package/bin/oomi-ai.js CHANGED
@@ -229,6 +229,8 @@ Commands:
229
229
 
230
230
  context health
231
231
  Show the latest account-linked health context available to this paired OpenClaw device.
232
+ context health sync
233
+ Request the linked Oomi mobile app to sync fresh HealthKit context.
232
234
 
233
235
  Common flags:
234
236
  --agents-file PATH Override AGENTS.md path
@@ -575,6 +577,14 @@ async function handleContextHealthCommand(flags = {}) {
575
577
  printStructuredResult(payload, isTruthyFlag(flags.json));
576
578
  }
577
579
 
580
+ async function handleContextHealthSyncCommand(flags = {}) {
581
+ const client = createCliPersonaApiClient(flags);
582
+ const payload = await client.requestHealthContextSync({
583
+ reason: flags.reason || 'agent_requested',
584
+ });
585
+ printStructuredResult(payload, isTruthyFlag(flags.json));
586
+ }
587
+
578
588
  async function refreshBridgeForUpdate(flags = {}, options = {}) {
579
589
  const logger = options.logger || null;
580
590
  if (process.platform === 'darwin') {
@@ -1372,6 +1382,8 @@ function sanitizeUserVisibleText(value) {
1372
1382
  text = text.replace(/<think>[\s\S]*$/i, ' ');
1373
1383
  }
1374
1384
  text = text.replace(/<\/think>/gi, ' ');
1385
+ text = text.replace(/<\/?final>/gi, ' ');
1386
+ text = text.replace(/\[(?:anim|face|gesture|look):[^\]\n]{1,80}\]/gi, ' ');
1375
1387
 
1376
1388
  text = text.replace(/(?:^|\n)System \(untrusted\):[\s\S]*?(?=\n\n|$)/gi, '\n');
1377
1389
  text = text.replace(
@@ -1391,6 +1403,7 @@ function shouldSuppressOomiVisibleText(value) {
1391
1403
  if (/Handle the result internally\. Do not relay it to the user/i.test(text)) return true;
1392
1404
  if (/Exec (failed|completed) \([^)]+\) ::/i.test(text)) return true;
1393
1405
  if (/^\s*<think>[\s\S]*$/i.test(text) && !/<\/think>/i.test(text)) return true;
1406
+ if (/^NO_REPLY$/i.test(text)) return true;
1394
1407
 
1395
1408
  return !sanitizeUserVisibleText(text);
1396
1409
  }
@@ -4319,6 +4332,10 @@ async function main() {
4319
4332
  }
4320
4333
 
4321
4334
  if (command === 'context' && subcommand === 'health') {
4335
+ if (args.positionals[0] === 'sync') {
4336
+ await handleContextHealthSyncCommand(args.flags);
4337
+ return;
4338
+ }
4322
4339
  await handleContextHealthCommand(args.flags);
4323
4340
  return;
4324
4341
  }
@@ -148,5 +148,19 @@ export function createPersonaApiClient({
148
148
  path: '/v1/context/health',
149
149
  });
150
150
  },
151
+
152
+ requestHealthContextSync({
153
+ reason = 'agent_requested',
154
+ } = {}) {
155
+ return postJson({
156
+ fetchImpl,
157
+ backendUrl: resolvedBackendUrl,
158
+ deviceToken: resolvedDeviceToken,
159
+ path: '/v1/context/health/sync',
160
+ body: {
161
+ reason: trimString(reason) || 'agent_requested',
162
+ },
163
+ });
164
+ },
151
165
  };
152
166
  }
@@ -124,6 +124,8 @@ function sanitizeUserVisibleText(value) {
124
124
  text = text.replace(/<think>[\s\S]*$/i, ' ');
125
125
  }
126
126
  text = text.replace(/<\/think>/gi, ' ');
127
+ text = text.replace(/<\/?final>/gi, ' ');
128
+ text = text.replace(/\[(?:anim|face|gesture|look):[^\]\n]{1,80}\]/gi, ' ');
127
129
 
128
130
  text = text.replace(/(?:^|\n)System \(untrusted\):[\s\S]*?(?=\n\n|$)/gi, '\n');
129
131
  text = text.replace(
@@ -143,6 +145,7 @@ function shouldSuppressOomiVisibleText(value) {
143
145
  if (/Handle the result internally\. Do not relay it to the user/i.test(text)) return true;
144
146
  if (/Exec (failed|completed) \([^)]+\) ::/i.test(text)) return true;
145
147
  if (/^\s*<think>[\s\S]*$/i.test(text) && !/<\/think>/i.test(text)) return true;
148
+ if (/^NO_REPLY$/i.test(text)) return true;
146
149
 
147
150
  return !sanitizeUserVisibleText(text);
148
151
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oomi-ai",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "Managed Oomi channel, bridge, voice, and persona app API tooling for OpenClaw",
5
5
  "bin": {
6
6
  "oomi": "bin/oomi-ai.js"
@@ -30,4 +30,12 @@ When answering data-backed health or fitness questions, agents should read appro
30
30
  oomi context health --json
31
31
  ```
32
32
 
33
+ If the user asks you to refresh stale HealthKit context, run:
34
+
35
+ ```bash
36
+ oomi context health sync --json
37
+ ```
38
+
39
+ The iPhone app must open or refresh before it can read Apple Health and fulfill the pending request.
40
+
33
41
  If a persona app is missing, ask the user to add it from the Oomi client first so platform-specific permissions and hydration can run.
@@ -127,6 +127,7 @@ Rules:
127
127
  - answer only from `healthContext.summary` and `healthContext.derived`
128
128
  - respect `healthContext.agentGuidance.canAnswerFromContext`
129
129
  - if context is missing, stale, denied, disabled, or unavailable, follow `healthContext.repair`
130
+ - if the user asks you to refresh stale HealthKit context, run `oomi context health sync --json`; tell the user the iPhone app must be opened for Oomi to read Apple Health and fulfill the pending sync
130
131
  - do not ask HealthKit directly; the Oomi mobile app syncs approved HealthKit data to the backend
131
132
 
132
133
  ## Hidden Speech Payload
@@ -78,7 +78,7 @@ Rules:
78
78
  - `metadata.spoken.style` is optional metadata for debugging or future mapping
79
79
  - if no hidden speech sidecar exists, Oomi falls back to speaking the visible assistant text
80
80
  - if you omit `metadata.spoken`, the plugin now synthesizes a bounded hidden fallback from visible assistant text
81
- - visible chat text is never rewritten by the plugin
81
+ - visible chat text should be clean before sending; the plugin may strip private runtime wrappers and avatar command tags as a safety guardrail
82
82
 
83
83
  ## Persona App API Tools
84
84
 
@@ -113,5 +113,6 @@ Rules:
113
113
  - respect `healthContext.agentGuidance.canAnswerFromContext`
114
114
  - if `canAnswerFromContext` is false, tell the user the relevant `healthContext.repair.label` or `healthContext.repair.reason`
115
115
  - if `healthContext.status` is `stale`, mention that the latest HealthKit sync may be out of date when timing matters
116
+ - if the user asks you to refresh stale HealthKit context, run `oomi context health sync --json`; tell the user the iPhone app must be opened for Oomi to read Apple Health and fulfill the pending sync
116
117
  - do not infer unavailable health fields
117
118
  - do not request HealthKit directly from the phone; the Oomi mobile app owns permission prompts and syncs approved data to the backend