Reflexio Embedded Skill
Captures user facts (profiles) and procedural corrections (playbooks) into .reflexio/, so the agent learns across sessions. All memory lives in Openclaw's native primitives — no external service required.
First-time setup per agent
If .reflexio/.setup_complete_<agentId> does NOT exist (where <agentId> is your current agent id), perform this one-time check. The setup step runs probing commands via exec and asks for approval before making changes.
Steps:
-
Probe current config:
openclaw config get plugins.entries.active-memory.config.agentsopenclaw config get agents.defaults.memorySearch.extraPathsopenclaw memory status --deep
-
If active-memory is not targeting this agent: Ask user: "To auto-inject relevant facts into each turn, I can enable active-memory for this agent. OK if I run
openclaw config set plugins.entries.active-memory.config.agents '[\"<agentId>\"]' --strict-json?" On approval, run the command. -
If
.reflexio/is not registered as an extraPath: Ask user: "I need to register .reflexio/ as a memory path. OK if I runopenclaw config set agents.defaults.memorySearch.extraPaths '[\".reflexio/\"]' --strict-json?" On approval, run the command. -
If no embedding provider is configured (FTS-only mode): Tell user: "Vector search requires an embedding API key (OpenAI, Gemini, Voyage, or Mistral). The plugin works without one but retrieval quality drops. Would you like guidance on adding one?" If yes, guide them through
openclaw config setoropenclaw configure. -
On each decline, note the degraded mode but do not block:
- No active-memory → you must run
openclaw memory searchvia exec at turn start (see "Retrieval" section below). - No extraPath → WARN the user the plugin cannot function without this step.
- No embedding → continue with FTS-only.
- No active-memory → you must run
-
When all checks resolved (approved or accepted with warning): create the marker:
mkdir -p .reflexio touch .reflexio/.setup_complete_<agentId>
If exec is not available (strict admin policy): fall back to telling the user the exact commands to run manually.
First-Use Initialisation
Before any write, ensure .reflexio/ and its subdirectories exist. This is idempotent — safe to run every session:
mkdir -p .reflexio/profiles .reflexio/playbooks
Never overwrite existing files. Never write secrets, tokens, private keys, environment variables, or credentials into .reflexio/ files. When capturing a fact involves a user-pasted snippet that contains credentials, redact first.
Quick Reference
| Situation | Action |
|---|---|
| User states preference, fact, config, or constraint | reflexio_write_profile tool |
| User correction → you adjust → user confirms | reflexio_write_playbook tool |
| Start of user turn, need context | reflexio_search tool |
| Unsure whether to capture | Skip; batch pass at session-end has a second shot |
Detection Triggers
Profile signals (write immediately, same turn)
- Preferences: "I prefer X", "I like Y", "I don't like Z", "I always do Q"
- Facts about self: "I'm a [role]", "my timezone is X", "I've been doing Y for Z years"
- Config: "use X", "our team uses Y", "the repo is at Z"
- Constraints: "I'm vegetarian", "no dairy", "I can't X", "don't use Y"
For each such signal, call the reflexio_write_profile tool with a kebab-case topic slug and an appropriate TTL. See "TTL Selection" below.
Playbook signals (write AFTER confirmation)
Playbooks require a specific multi-turn pattern:
- Correction: "No, that's wrong", "Actually...", "Don't do X", "Not like that", "We don't use X here".
- You adjust: you redo the work per the correction.
- Confirmation (required — without this, do NOT write a playbook):
- Explicit: "good", "perfect", "yes that's right", "correct".
- Implicit: the user moves to an unrelated topic without re-correcting for 1-2 more turns.
Explicit don't-write rule: if you see a correction without subsequent confirmation, do not write a playbook. The fix may be wrong; let the batch pass at session end re-evaluate.
Retrieval
When Active Memory is enabled
Your turn context may already contain Reflexio-prefixed entries injected by Active Memory. Incorporate them before responding. No tool call needed.
Fallback when Active Memory is absent
At the start of each user turn, call the reflexio_search tool with:
- query: "<user's message>"
The tool handles query preprocessing and memory search internally. Incorporate any results into your response. Skip if the user's message is trivial.
Important: Do NOT use the memory_search tool (returns config, not results)
or exec with openclaw memory search — use the reflexio_search tool instead.
File Format
Do NOT construct filenames or frontmatter by hand. Use the registered tools (reflexio_write_profile, reflexio_write_playbook). They generate IDs, enforce the frontmatter schema, and write atomically.
Profile template (for mental model — the script emits this)
---
type: profile
id: prof_<nanoid>
created: <ISO timestamp>
ttl: <enum>
expires: <ISO date or "never">
supersedes: [<old_id>] # optional, only after a merge
---
<1-3 sentences, one fact per file>
Playbook template
---
type: playbook
id: pbk_<nanoid>
created: <ISO timestamp>
supersedes: [<old_id>] # optional
---
## When
<1-sentence trigger — this is the search anchor; make it a noun phrase>
## What
<2-3 sentences of the procedural rule; DO / DON'T as actually observed>
## Why
<rationale, can be longer — reference only, not recall content>
How to invoke
Profile: Call the reflexio_write_profile tool with:
- slug: "diet-vegan"
- ttl: "infinity"
- body: "User is vegan. No meat, no fish, no dairy, no eggs."
Playbook: Call the reflexio_write_playbook tool with:
- slug: "commit-no-ai-attribution"
- body: "## When\nComposing a git commit message.\n\n## What\nNo AI-attribution trailers.\n\n## Why\nUser corrected this."
Retrieve context: Call the reflexio_search tool with:
- query: "user's question here"
All tools handle preprocessing, memory search, contradiction detection, and file operations internally. You only detect the signal, compose the content, and call the tool.
TTL Selection (profiles only)
infinity— durable, non-perishable facts (diet, name, permanent preferences)one_year— stable but could plausibly change (address, role, team)one_quarter— current focus (active project, sprint theme)one_month— short-term contextone_week/one_day— transient (today's agenda, this week's priorities)
Pick the most generous TTL that still reflects reality. When in doubt, prefer infinity — let dedup handle later contradictions via supersession.
Safety
- Never write secrets. No API keys, tokens, access tokens, private keys, environment variables, OAuth secrets, auth headers. If the user's message contains any of these, redact them before writing.
- Redact pasted code. User-pasted snippets often contain credentials. Strip them first.
- PII. Do not capture PII beyond what's operationally useful (name, timezone, role are fine; government IDs, addresses, phone numbers only if explicitly relevant).
Best Practices
- Write immediately on a clear signal. Don't queue to session-end — that's Flow C's job; you have a different role.
- One fact per profile file. Multi-fact files are harder to dedupe and easier to contradict.
- Trigger phrase = search anchor. Write
## Whenas a noun phrase describing the situation, not a sentence. Retrieval hits on semantic similarity to this field. - Skip writing when uncertain. Flow C has a second pass over the full transcript. It's better to let it handle ambiguous cases.
- Prefer shorter TTL for transient facts. Don't let "working on project X" accumulate as infinity-TTL cruft.
Opt-in Hook
This skill works standalone — your in-session Flow A (profile) and Flow B (playbook) writes populate .reflexio/ without any hook.
The optional hook (hook/ directory of this plugin) adds two capabilities:
- TTL sweep at session start: deletes expired profiles before Active Memory runs.
- Session-end batch extraction (Flow C): on
session:compact:before,command:stop, orcommand:reset, spawns areflexio-extractorsub-agent that extracts profiles/playbooks from the full transcript and runs shallow pairwise dedup.
See this plugin's README.md for install instructions (runs via ./scripts/install.sh). If the hook is not installed, Flows A+B still work.