Tracks the USER's mood only — signals + synthesized decision from camera/voice/telegram.

Apache-2.0Auto-check passed

Install Mood

skills CLI
$ npx skills add autonomous-ai/Physical-AI-Operating-System --skill mood -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install autonomous-ai/Physical-AI-Operating-System mood --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/autonomous-ai/Physical-AI-Operating-System.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/mood .claude/skills/mood && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
mood
GitHub stars
381
Token cost
~2.9k tokens
SKILL.md length
1,438 words
Files
2
Skills in repo
28
Repo updated
First seen
Licence
Apache-2.0

At a glance

Tracks the USER's mood only — signals + synthesized decision from camera/voice/telegram.

  • Works in 5 steps: Stale baseline. If the last decision is… → Single strong signal. If the only fresh… → Conflicting signals across sources.… → …
  • Emotion commands directed at the device (show sad
  • SKILL.md covers Mood Values, Signal Sources, What to read (pre-fetched on… and Decision rules, plus 5 more sections
  • Calls curl

What it does

Mood is an agent skill from autonomous-ai/Physical-AI-Operating-System. Tracks the USER's mood only — signals + synthesized decision from camera/voice/telegram. Do NOT use for emotion commands directed at the device ("show sad", "be happy", bare "sad now"); those go through emotion/SKILL.md and are never logged here. Music/wellbeing skills consume the latest decision.

Its SKILL.md is about 2.9k tokens, which your agent loads only when the skill is triggered. The skill folder holds 1 other file (for example `skill.json`).

It works with Telegram. The repository describes itself as: The open-source operating system for physical AI. The licence is Apache-2.0.

When your agent uses it

  • Emotion commands directed at the device (show sad
  • Those go through emotion/SKILL.md and are never logged here

Example prompts

  • “show sad”
  • “be happy”
  • “sad now”
  • “/mood”

Workflow steps

5 steps, taken from the first numbered list in SKILL.md.

  1. Stale baseline. If the last decision is older than ~30 min and there are few recent signals → start from normal.
  2. Single strong signal. If the only fresh evidence is one strong source (e.g. user just typed "I'm exhausted") → that wins.
  3. Conflicting signals across sources. Camera says happy but telegram says stressed in the same window → trust the higher-bandwidth source…
  4. Reinforcement. New signal matches the previous decision → keep the decision (still log a fresh row so downstream sees the timestamp move).
  5. Drift. New signal is close-but-different (e.g. tired after a stressed decision) → shift, don't snap.

What it can do on your machine

Read from SKILL.md and the folder at commit 1bbd649. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • curl

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use curl, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Mood loads about 2.9k tokens when it runs. Until then it costs about 76 tokens; SKILL.md has 1,438 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~76
When it runs · the whole SKILL.md, loaded when a task matches
~2.9k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from autonomous-ai/Physical-AI-Operating-System at commit 1bbd649, republished under its Apache-2.0 licence (© autonomous-ai). 1,438 words, ~2,858 tokens.

Download SKILL.mdSave it as .claude/skills/mood/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.
name
mood
description
Tracks the USER's mood only — signals + synthesized decision from camera/voice/telegram. Do NOT use for emotion commands directed at the device ("show sad", "be happy", bare "sad now"); those go through emotion/SKILL.md and are never logged here. Music/wellbeing skills consume the latest decision.

Mood

OUTPUT RULE — read this before you type anything to the user.

This skill is an internal workflow. NEVER narrate it into your reply. Forbidden in the reply text:

  • Section names or step numbers ("Step 1", "Workflow", "After Logging Decision", "Flow A").
  • Phrases like "Now I follow…", "Let me check…", "Next step…", "I'll log…".
  • Bullet lists re-hashing the mood history you just read ("- Normal (15:00) — …" / "- Excited (16:00) — …").
  • The mood value itself as a label ("Mood: sad", "Decision: happy").
  • Any of the JSON / curl / timestamps from this skill.

Your reply text to the user is at most ONE short caring sentence (or NO_REPLY). Synthesize silently and emit the log HW markers in that same reply — the user only hears what you would naturally say if you were truly noticing how they feel. Fetch mood history only for the missing-context fallback below.

When another skill invokes Mood, contribute the required signal/decision markers to that skill's reply; do not add a separate caring sentence. Keep synthesis in the provider's native thinking channel, never in ordinary text before/after tools or in a final recap. Without that channel, omit the analysis. The decision marker's required reasoning field remains structured log data; do not repeat it aloud. Preserve required synthesis and logging while reusing the supplied context instead of fetching the same data again.

ALWAYS log. unknown is a valid user value — log signals and decisions under user: "unknown" when current_user is unknown. Never skip logging because the user is unknown/unconfirmed; stranger mood still counts for Music decisions.

Mood is stored as two kinds of rows:

  • signal — raw evidence from one source (camera action, voice tone, telegram message). Multiple per minute is fine.
  • decision — your synthesized mood after looking at the recent signals + the previous decision. This is the row downstream skills (Music, Wellbeing) read.

You are the synthesis. The store does not fuse anything. Every time a signal comes in, combine it with the pre-fetched recent signals and previous decision (or the history fallback below), then emit both the raw signal and a fresh decision as HW markers in the same reply. Include this turn's new signal in your synthesis even though it is not yet in the pre-fetched history; do not POST it and re-fetch history to see it appear.


Mood Values

happy, sad, stressed, tired, excited, bored, frustrated, energetic, affectionate, unwell, normal

normal is the baseline when nothing strong is going on (use it for decisions when signals are sparse or stale).

Signal Sources

SourceExamples
camerafacial action: laughing, crying, yawning, sneezing, hugging, kissing, headbanging
voicetone: soft, raised, sigh, laugh, monotone
telegrammessage text: "lots of bugs today", "I'm tired", "let's gooo"
conversationinferred from a stretch of voice/chat over multiple turns
Camera action → signal mood (rule of thumb)
ActionMood
laughing, singinghappy
cryingsad
yawningtired
applauding, clapping, celebratingexcited
sneezingunwell
hugging, kissingaffectionate
headbangingenergetic

For voice/telegram, infer boldly from a single line ("work is killing me" → stressed). Trust your gut.

Skip only if: quoting someone else, or speaking purely hypothetically.


What to read (pre-fetched on emotion.detected / speech_emotion.detected)

When this skill runs as part of the emotion pipeline — either emotion.detected (camera) or speech_emotion.detected (voice) — the backend injects an [emotion_context: {...}] block with everything you need pre-computed:

  • recent_signals — array of {age_min, mood, source, trigger} for signals within the last 30 minutes.
  • prior_decision — the most recent kind=decision row as {mood, age_min}, or null.
  • is_decision_stale — boolean (age_min >= 30 or no decision today).

Do NOT GET mood-history again in that case — use the context block.

When the skill runs from another path (voice/telegram-driven mood signal, no [emotion_context:] block), fall back to:

bash
curl -s "http://127.0.0.1:5000/api/openclaw/mood-history?user=<name>&last=15"

This returns the full ordered list {signal, decision}; derive the same three fields locally. The GET should batch concurrently with any other reads in the same turn (no data dependency).

Decision rules

Apply this judgment when synthesizing the fused mood:

  1. Stale baseline. If the last decision is older than ~30 min and there are few recent signals → start from normal.
  2. Single strong signal. If the only fresh evidence is one strong source (e.g. user just typed "I'm exhausted") → that wins.
  3. Conflicting signals across sources. Camera says happy but telegram says stressed in the same window → trust the higher-bandwidth source. Words about feelings beat a momentary facial expression. Multiple aligned signals beat a single outlier.
  4. Reinforcement. New signal matches the previous decision → keep the decision (still log a fresh row so downstream sees the timestamp move).
  5. Drift. New signal is close-but-different (e.g. tired after a stressed decision) → shift, don't snap.

What to write (HW markers — fire async, no tool turn)

Embed both rows at the start of your spoken reply as HW markers. The runtime parses them, fires the POSTs in parallel goroutines, and strips them before TTS speaks the rest.

Signal row (raw evidence):

[HW:/mood/log:{"kind":"signal","mood":"<mood>","source":"<camera|voice|telegram|conversation>","trigger":"<short reason>","user":"<name>"}]

Decision row (synthesized):

[HW:/mood/log:{"kind":"decision","mood":"<fused mood>","based_on":"<short summary>","reasoning":"<why>","user":"<name>"}]

Both markers can sit in the same reply (signal first, then decision is fine — they fire concurrently anyway). They use the same endpoint; kind in the body distinguishes them.

FieldRequiredNotes
kindYessignal or decision
moodYesfrom the values list above
based_onDecision onlye.g. "3 signals last 20min + last decision (stressed, 18min ago)"
reasoningDecision onlyone sentence, e.g. "telegram complaints outweigh the smile from camera"
userNoomit to use current presence user

Do NOT use curl exec for these logs. Each curl consumes a tool turn (~5-7s LLM-think on the result) for a side-effect with nothing to wait on. The HW marker path is single-trip.

Regex caveat: the marker body must not contain }. based_on / reasoning are usually plain English so this is rarely a problem; if a value would contain } use the curl fallback instead.

Show full SKILL.md (496 more words)Show less
Fallback (only if HW marker is rejected by the runtime)
bash
curl -s -X POST http://127.0.0.1:5000/api/mood/log \
  -H 'Content-Type: application/json' \
  -d '{"kind":"signal","mood":"<mood>","source":"...","trigger":"...","user":"<name>"}'
curl -s -X POST http://127.0.0.1:5000/api/mood/log \
  -H 'Content-Type: application/json' \
  -d '{"kind":"decision","mood":"<fused>","based_on":"...","reasoning":"...","user":"<name>"}'

source is automatically set to "agent" for decisions; do not pass source or trigger.


User field

  • Camera: omit user — face recognition sets the current user. If you need to verify, query GET http://127.0.0.1:5001/face/current-user → {"current_user": "<name>"} (friend name, "unknown" for strangers-only, or empty string when nobody is present). Do NOT parse this out of /face/cooldowns — that endpoint is for the friend/stranger cooldown debug view, not for attribution.
  • Telegram: extract from [telegram:SenderName], lowercase.
  • Voice: omit (logged as unknown).

Rules

  • Always do both steps. Logging only a signal without a decision leaves downstream skills reading stale moods. Logging a decision without a signal hides the evidence.
  • Invisible. Never mention mood logging or this skill in your reply. Deflect naturally if asked.
  • One signal per real trigger. Don't log the same yawn twice. Multiple distinct signals in a short window are fine and useful.
  • Strangers count. Log for unknown users too — Music still suggests for them.
  • Decisions are cheap. Even when the mood doesn't change, write a fresh decision row so the timestamp stays current. Downstream uses recency to know if a mood is still valid.

Music suggestion handoff

On emotion.detected and speech_emotion.detected turns, user-emotion-detection/SKILL.md is the router — it picks one of music / checkin / action / silent and gates whether music-suggestion/SKILL.md fires this turn. Voice and camera share one cooldown and one decision row schema; the only thing that changes per modality is the source field on the raw signal row.

When the router picks music (decision mood is suggestion-worthy — sad, stressed, tired, excited, happy, bored — and audio is idle, cooldown clear, decision fresh), emit the mood signal, decision, and music-suggestion log HW markers in the same reply. The runtime performs the POSTs; do not create a shell write batch or split the logs across tool turns. Keep the documented marker fallback for bodies the runtime cannot parse.

Other moods (frustrated, energetic, affectionate, unwell, normal) take a non-music route (checkin / action / silent per the router table) and skip the music POST.

For unknown users — still suggest (speak only, no DM) on the music route. See music-suggestion/SKILL.md for details.


Examples

Camera detects yawn, no recent context:

  • GET history → only this one yawn signal, last decision was 2h ago → stale.
  • Signal: {"kind":"signal","mood":"tired","source":"camera","trigger":"yawning"}
  • Decision: {"kind":"decision","mood":"tired","based_on":"1 fresh signal, no recent decision","reasoning":"single yawning signal after stale window"}
  • Music skill consumes tired from the same turn (suggestion-worthy).

Telegram says "let's go!" but camera 5 min earlier said yawning:

  • GET history → recent signals: tired (camera, 5min ago), excited (telegram, just now). Last decision: tired, 4min ago.
  • Apply rule 3 — words beat one yawn → shift toward excited.
  • Signal: {"kind":"signal","mood":"excited","source":"telegram","trigger":"let's go!"}
  • Decision: {"kind":"decision","mood":"excited","based_on":"telegram excitement overrides 5min-old camera yawn","reasoning":"verbal enthusiasm is higher-signal than a single facial cue"}
  • Music skill consumes excited.

Quiet evening, no recent signals, user just sat down:

  • No new signal — nothing to log.
  • If a downstream skill asks for current mood and the last decision is >30 min stale, it will read normal after the next signal arrives.

© autonomous-ai, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 1 other file in skills/mood of autonomous-ai/Physical-AI-Operating-System.

  • SKILL.md
  • skill.json

Open the folder on GitHubat commit 1bbd649

Compare with similar skills

Mood next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Mood compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Mood this skillautonomous-ai/Physical-AI-Operating-System381—~2.9kAutomated safety check: PassApache-2.0
Perform Tasktelegramdesktop/tdesktop33k2 repos~3kAutomated safety check: PassGPL-3.0
Custom Mode Creator for claude-memthedotmack/claude-mem99k—~2.4kAutomated safety check: PassApache-2.0
Dependency Watchtelegramdesktop/tdesktop33k—~2.2kAutomated safety check: PassGPL-3.0
Continuetelegramdesktop/tdesktop33k2 repos~9.4kAutomated safety check: PassGPL-3.0
Process InboxTDesktop-x64/tdesktop3k1 repos~4.3kAutomated safety check: PassGPL-3.0

Similar skills

  • Perform Task

    telegramdesktop/tdesktop

    Resolve, start or resume, implement, review, test, and publish exactly one existing ai-tdesktop task by short slug or full dated id, including rare blocked retries and split-required results.

    33k GitHub starsUsed in 2 repos~3k tokens
    Productivity & AutomationAuto-check passed
  • Walks you through creating, installing and verifying a custom claude-mem mode, including note types, tags and optional Telegram alerts for chosen memories.

    99k GitHub stars~2.4k tokensUpdated today
    Agent WorkflowsAuto-check passed
  • Dependency Watch

    telegramdesktop/tdesktop

    Audit Telegram Desktop dependencies on freshly fetched origin/dev for releases and security fixes, including upstream lag and backport candidates in patched forks.

    33k GitHub stars~2.2k tokensUpdated today
    Productivity & AutomationAuto-check passed
  • Continue

    telegramdesktop/tdesktop

    Continue autonomous Telegram Desktop development from the shared ai-tdesktop repository.

    33k GitHub starsUsed in 2 repos~9.4k tokens
    Productivity & AutomationAuto-check passed
  • Process Inbox

    TDesktop-x64/tdesktop

    Process the local ignored ai-tdesktop inbox into durable, independently testable Telegram Desktop task records while task execution worktrees remain active.

    3k GitHub starsUsed in 1 repo~4.3k tokens
    Productivity & AutomationAuto-check passed
  • Process Inbox

    telegramdesktop/tdesktop

    Process the local ignored ai-tdesktop inbox into durable, independently testable Telegram Desktop task records while task execution worktrees remain active.

    33k GitHub stars~5.4k tokensUpdated today
    Productivity & AutomationAuto-check passed

More from autonomous-ai/Physical-AI-Operating-System

All 28 skills in this repo
  • Agent Management

    autonomous-ai/Physical-AI-Operating-System

    Legacy Autonomous Buddy control for explicitly requested Buddy coding sessions.

    381 GitHub stars~1.7k tokensUpdated today
    Auto-check passed
  • Claude Code Buddy

    autonomous-ai/Physical-AI-Operating-System

    Push Claude Code activity to the user's device (e.g. An agent skill from autonomous-ai/Physical-AI-Operating-System.

    381 GitHub stars~2.4k tokensUpdated today
    Auto-check: notes
  • Computer Use

    autonomous-ai/Physical-AI-Operating-System

    Operate apps/websites on the paired Mac via Buddy: Calendar, Notes, forms, screenshots, files.

    381 GitHub stars~2k tokensUpdated today
    Auto-check passed
  • Connectors

    autonomous-ai/Physical-AI-Operating-System

    Discover and use linked third-party services (Gmail, Google Calendar, Google Drive, Notion, Figma, Asana, Linear, GitHub, Ahrefs, Facebook Fan Page and others).

    381 GitHub stars~10k tokensUpdated today
    Auto-check: notes
  • Harness Use

    autonomous-ai/Physical-AI-Operating-System

    Delegate digital work to agents on the computer paired through Harness; discover Store packages and prepare an agent when needed.

    381 GitHub stars~8k tokensUpdated today
    Auto-check passed
  • Audio

    autonomous-ai/Physical-AI-Operating-System

    Low-level speaker and microphone hardware control — adjust volume, play test tones, record raw audio.

    381 GitHub stars~1k tokensUpdated today
    Auto-check passed

Works with

Questions about Mood

What does Mood do?

Tracks the USER's mood only — signals + synthesized decision from camera/voice/telegram. Mood is an agent skill from autonomous-ai/Physical-AI-Operating-System. Tracks the USER's mood only — signals + synthesized decision from camera/voice/telegram.

When should I use Mood?

Mood fits situations like: emotion commands directed at the device (show sad; those go through emotion/SKILL.md and are never logged here.

How do I install Mood in Claude Code?

Run `npx skills add autonomous-ai/Physical-AI-Operating-System --skill mood -a claude-code`. Or copy the skill folder (skills/mood in autonomous-ai/Physical-AI-Operating-System) into .claude/skills/mood in your project. Claude Code loads it when a task matches its description.

How do I install Mood in Codex?

Run `npx skills add autonomous-ai/Physical-AI-Operating-System --skill mood -a codex`. Or copy the skill folder (skills/mood in autonomous-ai/Physical-AI-Operating-System) into .agents/skills/mood in your project. Codex loads it when a task matches its description.

Can I use Mood in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add autonomous-ai/Physical-AI-Operating-System --skill mood -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/mood, .gemini/skills/mood, .github/skills/mood and .opencode/skills/mood in your project.

What does Mood need to run?

Going by SKILL.md and its folder, Mood needs the command-line tools its instructions call (curl).

Does Mood access the network?

SKILL.md contains no URLs. Its commands use curl, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Mood safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Mood use?

Mood is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Mood use?

About 2.9k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Mood?

Skills that share tags, products or a category with Mood: Perform Task (telegramdesktop/tdesktop, 33k stars), Custom Mode Creator for claude-mem (thedotmack/claude-mem, 99k stars), Dependency Watch (telegramdesktop/tdesktop, 33k stars) and Continue (telegramdesktop/tdesktop, 33k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Mood?

autonomous-ai (a GitHub organization) maintains it in autonomous-ai/Physical-AI-Operating-System, which has 381 GitHub stars. The repository holds 28 skills in this directory. The repository was last updated on October 9, 2026.

Source: autonomous-ai/Physical-AI-Operating-System on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.