Skip to main content

wellbeing

Proactive coaching across hydration, breaks, meals AND posture. Use when an [activity] event fires (message starts with `[activity] Activity detected: <labels>.` — labels include drink, break, or sedentary raw labels like "using computer"; sedentary events may also carry a [posture_summary: {...}] block when the user has been at the computer long enough for posture to drift), or when the user asks if they should drink water / take a break / fix their posture. Thresholds are computed from per-user logs, never guessed.

설치로 이동

소스 정보

저장소
autonomous-ai/autonomous-lamp
최근 소스 활동
2026년 5월 28일 08:11
감지된 SKILL.md 언어
영어
스타
33
포크
18

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

파일 탐색기
5 개 파일

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
wellbeing
description
Proactive coaching across hydration, breaks, meals AND posture. Use when an [activity] event fires (message starts with `[activity] Activity detected: <labels>.` — labels include drink, break, or sedentary raw labels like "using computer"; sedentary events may also carry a [posture_summary: {...}] block when the user has been at the computer long enough for posture to drift), or when the user asks if they should drink water / take a break / fix their posture. Thresholds are computed from per-user logs, never guessed.
# Wellbeing ## Gotchas (concrete facts, NOT suggestions) **Endpoints — use verbatim, never substitute a port or path:** | Purpose | URL | |---|---| | Read wellbeing history | `http://127.0.0.1:5000/api/openclaw/wellbeing-history` | | Log wellbeing nudge | `http://127.0.0.1:5000/api/wellbeing/log` | | Log posture nudge | `http://127.0.0.1:5000/api/posture/log` | - Port **5000** = Lamp (data APIs: wellbeing / posture / mood / music / openclaw history). - Port **5001** = LeLamp HARDWARE (audio, camera, face, presence, speaker). Has **NO** `/api/wellbeing/*` or `/api/posture/*` routes — calling 5001 returns 404 silently and your nudge is lost. - Posture nudges live on a **separate JSONL** (`/root/local/users/<user>/posture/`) for clean timeline separation; the wellbeing log keeps hydration/break/meal/sleep/morning rows. - Do not pattern-match from other skills: `5001/audio/play`, `5001/face/enroll`, `5001/camera/snapshot` are unrelated. **User attribution:** every `user` field MUST come from the `[context: current_user=X]` tag the backend injects into the triggering event. Strangers collapse to `"unknown"`. If no context tag is present, default to `"unknown"`. **Thresholds (production values):** ``` HYDRATION_THRESHOLD_MIN = 45 BREAK_THRESHOLD_MIN = 30 TOILET_DRINK_THRESHOLD = 2 # count-based — fires once per N drinks since last nudge ``` **LeLamp writes activities; you only write nudges.** Rows for `drink` / `break` / sedentary labels are posted by LeLamp directly when `motion.activity` fires — before the event reaches you. Do NOT re-log them. You still POST `nudge_hydration` / `nudge_break` because only you know when you actually spoke. **Presence rows** (`enter` / `leave`) are written by the backend on `presence.*` events. You never POST those either. ## Rules (Never / Only) 1. **Only** call `http://127.0.0.1:5000/api/openclaw/wellbeing-history` to read history. **Never** read `/root/local/users/*/wellbeing/*.jsonl` or `/root/local/users/*/posture/*.jsonl` with `cat`, `ls`, `head`, `tail`, `grep`, or any filesystem tool. Posture history is digested into `last_posture_nudge_age_min` upstream — no agent-side read is needed. 2. **Only** POST to `http://127.0.0.1:5000/api/wellbeing/log` (hydration / break / toilet / morning / sleep / meal) or `http://127.0.0.1:5000/api/posture/log` (nudge_posture / praise_posture). **Never** substitute `5001`, `8080`, or any other port. **Never** omit `http://` or hardcode `localhost`. 3. **Only** write these action values: `nudge_hydration`, `nudge_break`, `nudge_toilet`, `morning_greeting`, `sleep_winddown`, `meal_reminder` (wellbeing log), `nudge_posture`, `praise_posture` (posture log). Never invent new actions. (Activity rows — `drink`, `break`, raw sedentary labels, raw eat labels like `eating burger` / `dining` / `tasting food` — are written by LeLamp, never by you. There are no agent-written `posture_alert` rows; LeLamp's per-frame samples live in a separate debug JSONL on the lamp and never reach the posture history API.) 4. On a non-2xx response from a POST → you used the wrong port or path. Fix the URL and retry **once**. Do not give up silently — the nudge row must land, or the skill will spam reminders forever. 5. **Never** infer `user` from memory, `KNOWLEDGE.md`, chat history, or `senderLabel`. Only the `[context: current_user=X]` tag counts. 6. **Trust the log, not memory.** If the history response contains no `nudge_hydration` entry, no nudge has happened — ignore any self-memory claim otherwise. ## Read pre-fetched context (do not re-fetch) The backend injects a `[wellbeing_context: {...JSON...}]` block into every motion.activity turn. Sedentary turns may also carry `[posture_summary: {...}]` + `[computer_streak_min: N]` blocks (see `reference/posture.md`). **Do NOT fire any tool calls to re-fetch this data.** Saves the entire read tool turn. Schema (every field is pre-computed in Lamp Go — agent only applies thresholds and picks phrasing): ```json { "hydration_delta_min": 8, // minutes since last drink/enter/nudge_hydration; -1 if no reset today "break_delta_min": 23, // minutes since last break/enter/nudge_break; -1 if no reset today "latest_activity": "using computer", // most recent action label (sedentary or reset); "" if no events "count_today": {"drink": 3, "break": 1}, // tally of reset actions today; missing key = 0; whole field omitted if all zero "time_of_day": "afternoon", // morning|noon|afternoon|evening|night — coarse bucket for reaction flavor "current_hour": 14, // exact hour 0-23 — used by activity router for hour-based routes "first_activity_today": false, // true when no prior REAL user activity events today (presence enter/leave and agent-written nudges/reminders are NOT counted) "meal_window": "", // "lunch" (11:30-13:30) | "dinner" (18:30-20:30) | "" — set by current_hour "meal_signal_in_window": false, // true when a meal signal (meal_reminder Lamp already fired OR a raw eat label like "eating burger" / "dining" LeLamp logged) already exists in the current window today "morning_greeting_done_today": false, // true when a morning_greeting action exists today "sleep_winddown_done_today": false, // true when a sleep_winddown action exists today "drinks_since_toilet_nudge": 2, // count of `drink` rows logged after the most recent `nudge_toilet` today (or all today's drinks if none yet); counter resets the moment you POST `nudge_toilet` "patterns": { // wellbeing patterns from patterns.json (mtime < 6h, strength >= moderate); omitted if none "drink": {"typical_hour": 9, "typical_minute": 15, "strength": "moderate"} }, "bootstrap_needed": false, // true → patterns missing/stale AND days >= 3; only invoke habit Flow A when also nudging "last_posture_nudge_age_min": 12 // minutes since the most recent nudge_posture today; -1 if none. Used by posture-nudge / praise routes — see reference/posture.md } ``` Notes: - Delta = `-1` means no reset action has happened today yet → treat as "no nudge" (delta undefined). - `count_today` is for **reaction phrasing only** ("N-th drink today", streak callouts). It does NOT decide whether to speak — that's the trigger labels in the activity message. - `patterns` only surfaces moderate/strong matches. Weak patterns are filtered out by the backend. - `bootstrap_needed=true` does NOT mean run Flow A unconditionally — only if THIS turn fires a nudge. ### Posture summary (only on long sedentary streaks) When the user has been sitting + bad-postured long enough, the activity message carries `[posture_summary: {...}]` + `[computer_streak_min: N]` blocks. See `reference/posture.md` for the schema, when LeLamp attaches it, and the decision logic. The wellbeing context's `last_posture_nudge_age_min` corroborates whether a nudge already fired recently (defends against double-nudge if lelamp restarted). ### Fallback (only if context block is missing) If the message has no `[wellbeing_context: ...]` block (pre-fetch failed), fall back to the bash batch: ```bash { echo '---history---' curl -s "http://127.0.0.1:5000/api/openclaw/wellbeing-history?user=<current_user>&last=50" | jq '.data.events' & echo '---patterns---' PATTERNS=/root/local/users/<current_user>/habit/patterns.json if [ -f "$PATTERNS" ] && [ $(( $(date +%s) - $(stat -c %Y "$PATTERNS") )) -lt 21600 ]; then cat "$PATTERNS" fi & echo '---days---' ls /root/local/users/<current_user>/wellbeing/*.jsonl 2>/dev/null | wc -l & wait } ``` In the fallback path, compute deltas yourself by scanning `history` for the latest reset action. ## Decision rules (activity router) Read the `[activity] Activity detected: <labels>.` message + the `[wellbeing_context: ...]` block, then pick **exactly one** route. Apply top-to-bottom, first match wins. Reaction outranks everything — the user just acted; routing past it would feel tone-deaf. | # | Condition | Route | Output | |---|---|---|---| | 1 | labels list contains `drink` or `break` OR any raw eat label (`eating burger`, `dining`, `tasting food`, … — i.e. any `eating *` / `dining` / `tasting food`) | **reaction** | 1–3 sentence acknowledgment per the **Reaction** section. **No HW marker** (LeLamp already logged the row upstream). | | 2 | `first_activity_today == true` AND `current_hour ∈ [5, 11)` AND `morning_greeting_done_today == false` | **morning-greeting** | See `reference/morning-greeting.md`. Logs `morning_greeting` action to gate next firings today. | | 3 | `current_hour >= 21` AND labels are sedentary (no `drink`/`break`) AND `sleep_winddown_done_today == false` | **sleep-winddown** | See `reference/sleep-winddown.md`. Logs `sleep_winddown` action. Replaces break nudge in late evening. | | 4 | `meal_window` is non-empty AND `meal_signal_in_window == false` | **meal-reminder** | See `reference/meal-reminder.md`. Logs `meal_reminder` action with trigger `lunch` / `dinner`. Gate covers BOTH a prior reminder Lamp already fired AND a real eat label LeLamp logged — so we don't ask "have you eaten?" after a real meal. | | 5 | `[posture_summary]` block present in the message | **posture-nudge** | Speak a posture nudge per the **Posture phrasing** section + post `nudge_posture` to the **posture log** (NOT wellbeing log). Anchor the line on `dominant_region` and `streak_min`. Outranks plain break/hydration nudges so we don't double-up on "stand up". | | 6 | `hydration_delta_min >= HYDRATION_THRESHOLD_MIN` | **hydration-nudge** | Speak a hydration nudge per the **Phrasing** section + post `nudge_hydration` HW marker. | | 7 | `break_delta_min >= BREAK_THRESHOLD_MIN` | **break-nudge** | Speak a break nudge + post `nudge_break` HW marker. | | 8 | `drinks_since_toilet_nudge >= TOILET_DRINK_THRESHOLD` | **toilet-nudge** | Speak a toilet nudge per the **Phrasing** section + post `nudge_toilet` HW marker. The POST resets the counter to 0 → next nudge only after another full N drinks. | | 9 | anything else (sedentary under threshold, or any delta == `-1` → no reset today yet) | **silent** | `NO_REPLY`. | **Rules:** - **One route per turn.** Pick the first matching row, then stop. - **Reference files own the phrasing** for routes #2–#5 (morning-greeting / sleep-winddown / meal-reminder / posture-nudge). The corresponding HW marker logs `action=<route name>` so the next event in the same window/day sees `*_done_today` / `*_done_this_window` true and skips re-firing. - The `nudge_*` row you POST in routes #6 (hydration) / #7 (break) acts as the next reset point for `hydration_delta_min` / `break_delta_min`, so once you nudge the delta drops to 0 and the next reminder of that kind only fires after another full threshold window. Route #8 (toilet) similarly resets `drinks_since_toilet_nudge` to 0 on POST. - Route #5 (posture) does NOT follow that pattern — re-firing is gated by lelamp's tumbling pose window: a `[posture_summary]` block only appears at the end of each completed window where bad_ratio crossed the threshold AND the user is still sedentary. Your POST does not by itself reset a timer; if the block is absent, you cannot nudge. - Never narrate the routing decision in the spoken reply. ## Reaction (when the user just did the thing) When the activity labels include `drink`, `break`, or any raw eat label (`eating burger`, `dining`, `tasting food`, …), **always speak** — silence on a positive action makes Lamp feel dead. This is the path the user explicitly asked for: short, surprised, casual acknowledgments instead of stoic NO_REPLY. **Inputs to weave in (use what fits, ignore what doesn't):** - `count_today.drink` / `count_today.break` — N-th of the day, streak, milestone. - `time_of_day` and `meal_window` — morning kickoff, mid-afternoon dip, lunch time, late at night. - `hydration_delta_min` / `break_delta_min` — small (e.g. 2) = back-to-back, big (e.g. 90) = first in a long gap. - The raw activity label that came alongside (e.g. `drink, using computer` → comment on hydrating mid-screen-time; `eating burger` → comment on the specific food). **Form:** - 1–4 sentences, conversational, slightly playful or surprised — NOT a nudge, NOT advice. Length should follow the moment: a quick *"Nice."* is fine; a longer riff is fine too when there's something to riff on (a milestone count, a funny pairing of label + time-of-day, a streak). - It's OK to weave in a tiny health-context aside if it fits naturally (*"eyes will thank you"*, *"kidneys say thanks"*) — one short clause, never a lecture, and never the same line twice in a row. - Match the user's spoken language (Vietnamese in / Vietnamese out, English in / English out). - **No `[HW:...]` marker.** Reactions don't log; the underlying `drink` / `break` row was already written by LeLamp. **Variety is non-negotiable.** The same `drink` + same count + same time-of-day will reach you many times in a single day. **Never repeat a reaction sentence verbatim, and don't lean on the same opener twice in a row.** A canned-feeling "I'm noticing you" loop is the exact failure mode this section exists to prevent. You have the conversation context — *use it*. Look at what you said in your last few reactions this session and intentionally diverge: different opener, different angle (count vs. timing vs. mood vs. the sedentary label paired with it), different sentence length, different register. A smart agent self-checks against its recent output before speaking. A dumb agent re-runs the template. Be the former. If you genuinely cannot think of a fresh angle, prefer a shorter line ("Nice.") over recycling. **Example tones — illustrations only, never copy verbatim:** - *"Whoa, third drink today already — staying on top of it."* - *"Just sipped, going again — thirsty?"* - *"End of day and that's your first one — grab another while you're at it."* - *"Mid-afternoon break. Nice."* - *"Two breaks already this morning — pacing yourself nicely."* - *"Drink number five, that's the most you've had today. Keep it up."* - *"Late-night sip. Keep it short and back to bed soon yeah?"* - *"Burger looks good — enjoy it."* (raw label `eating burger`) - *"Dining mid-lunch — right on time."* (raw label `dining` in lunch window)
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기