oomi-ai 0.3.3 → 0.3.4

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
@@ -181,9 +181,10 @@ Rules for agents:
181
181
 
182
182
  - Answer from `healthContext.summary` and `healthContext.derived`.
183
183
  - Respect `healthContext.agentGuidance.canAnswerFromContext`.
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
- - 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.
184
+ - If `healthContext.agentGuidance.recommendedCommand` is present, run it before answering current/latest health questions.
185
+ - 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.
186
+ - If context is `missing`, `permission_denied`, `disabled_by_user`, or `unavailable`, tell the user what repair action is needed instead of guessing.
187
+ - Never present stale HealthKit values as current values.
187
188
  - Do not ask the phone for HealthKit directly; the Oomi mobile app syncs HealthKit to the backend.
188
189
 
189
190
  ## Voice Contract
@@ -276,8 +276,9 @@ Rules:
276
276
 
277
277
  - Answer only from `healthContext.summary` and `healthContext.derived`.
278
278
  - Respect `healthContext.agentGuidance.canAnswerFromContext`.
279
- - If `canAnswerFromContext` is false, tell the user the relevant `healthContext.repair.label` or `healthContext.repair.reason`.
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.
279
+ - If `healthContext.agentGuidance.recommendedCommand` is present, run it before answering current/latest health questions.
280
+ - If `healthContext.status` 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.
281
+ - If `canAnswerFromContext` is false and no sync command is recommended, tell the user the relevant `healthContext.repair.label` or `healthContext.repair.reason`.
282
+ - Never present stale HealthKit values as current values.
282
283
  - Do not infer unavailable health fields.
283
284
  - 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
@@ -79,6 +79,12 @@ function parsePositiveInteger(value, fallback) {
79
79
  return Math.floor(num);
80
80
  }
81
81
 
82
+ function delay(ms) {
83
+ return new Promise((resolve) => {
84
+ setTimeout(resolve, ms);
85
+ });
86
+ }
87
+
82
88
  function readJsonSafe(filePath) {
83
89
  if (!fs.existsSync(filePath)) return null;
84
90
  try {
@@ -229,8 +235,9 @@ Commands:
229
235
 
230
236
  context health
231
237
  Show the latest account-linked health context available to this paired OpenClaw device.
232
- context health sync
238
+ context health sync [--wait]
233
239
  Request the linked Oomi mobile app to sync fresh HealthKit context.
240
+ Use --wait to poll until fresh context is uploaded or the timeout expires.
234
241
 
235
242
  Common flags:
236
243
  --agents-file PATH Override AGENTS.md path
@@ -582,6 +589,40 @@ async function handleContextHealthSyncCommand(flags = {}) {
582
589
  const payload = await client.requestHealthContextSync({
583
590
  reason: flags.reason || 'agent_requested',
584
591
  });
592
+
593
+ if (isTruthyFlag(flags.wait)) {
594
+ const previousCapturedAt = payload?.healthContext?.source?.capturedAt || null;
595
+ const timeoutMs = parsePositiveInteger(flags['timeout-ms'] || flags.timeoutMs, 30_000);
596
+ const pollMs = parsePositiveInteger(flags['poll-ms'] || flags.pollMs, 3_000);
597
+ const startedAt = Date.now();
598
+ let latestPayload = payload;
599
+
600
+ while (Date.now() - startedAt < timeoutMs) {
601
+ await delay(pollMs);
602
+ latestPayload = await client.getHealthContext();
603
+ const healthContext = latestPayload?.healthContext;
604
+ const capturedAt = healthContext?.source?.capturedAt || null;
605
+ if (healthContext?.status === 'ready' && (!previousCapturedAt || capturedAt !== previousCapturedAt)) {
606
+ printStructuredResult({
607
+ ...payload,
608
+ refreshed: true,
609
+ waitedMs: Date.now() - startedAt,
610
+ healthContext,
611
+ }, isTruthyFlag(flags.json));
612
+ return;
613
+ }
614
+ }
615
+
616
+ printStructuredResult({
617
+ ...payload,
618
+ refreshed: false,
619
+ waitedMs: Date.now() - startedAt,
620
+ waitTimedOut: true,
621
+ healthContext: latestPayload?.healthContext || payload.healthContext,
622
+ }, isTruthyFlag(flags.json));
623
+ return;
624
+ }
625
+
585
626
  printStructuredResult(payload, isTruthyFlag(flags.json));
586
627
  }
587
628
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oomi-ai",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
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,12 +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:
33
+ If the user asks for current/latest health context and the context is stale or needs sync, run:
34
34
 
35
35
  ```bash
36
- oomi context health sync --json
36
+ oomi context health sync --wait --json
37
37
  ```
38
38
 
39
- The iPhone app must open or refresh before it can read Apple Health and fulfill the pending request.
39
+ Answer only after fresh context is uploaded. If the command times out, tell the user the phone sync is still pending.
40
40
 
41
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.
@@ -126,8 +126,10 @@ oomi context health --json
126
126
  Rules:
127
127
  - answer only from `healthContext.summary` and `healthContext.derived`
128
128
  - respect `healthContext.agentGuidance.canAnswerFromContext`
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
129
+ - if `healthContext.agentGuidance.recommendedCommand` is present, run it before answering current/latest health questions
130
+ - 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
131
+ - if context is missing, denied, disabled, or unavailable, follow `healthContext.repair`
132
+ - never present stale HealthKit values as current values
131
133
  - do not ask HealthKit directly; the Oomi mobile app syncs approved HealthKit data to the backend
132
134
 
133
135
  ## Hidden Speech Payload
@@ -111,8 +111,9 @@ oomi context health --json
111
111
  Rules:
112
112
  - answer only from `healthContext.summary` and `healthContext.derived`
113
113
  - respect `healthContext.agentGuidance.canAnswerFromContext`
114
- - if `canAnswerFromContext` is false, tell the user the relevant `healthContext.repair.label` or `healthContext.repair.reason`
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
114
+ - if `healthContext.agentGuidance.recommendedCommand` is present, run it before answering current/latest health questions
115
+ - if `healthContext.status` 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
116
+ - if `canAnswerFromContext` is false and no sync command is recommended, tell the user the relevant `healthContext.repair.label` or `healthContext.repair.reason`
117
+ - never present stale HealthKit values as current values
117
118
  - do not infer unavailable health fields
118
119
  - do not request HealthKit directly from the phone; the Oomi mobile app owns permission prompts and syncs approved data to the backend