Lethe — Persistent Agent Memory
Lethe is your long-term memory layer. Every decision, observation, task, and flag persists across sessions and survives container restarts. The plugin handles bootstrap and context assembly automatically. This skill handles orientation, queries, recording, and error recovery.
Mental model:
- - Events are append-only. Nothing is ever deleted unless you explicitly delete it.
- Compaction synthesizes events into a narrative summary — it does not delete history.
- Memory search retrieves facts. Recording captures decisions. Flags surface uncertainty.
- The plugin fires on
bootstrap() and assemble() — you handle everything else.
Startup Sequence — Run First, Always
On every new session (first real message from the user), orient yourself before answering.
⚠️ Critical: All Lethe API routes are under /api/. Base URL is http://localhost:18483/api. Never query /sessions directly — always use /api/sessions.
Step 1 — Get full session state (single call):
CODEBLOCK0
This returns:
- -
summary — compressed narrative from all prior compactions - INLINECODE7 — last 20 events (fills gap since last compaction)
- INLINECODE8 ,
event_count, INLINECODE10 - INLINECODE11 —
active, interrupted, or INLINECODE14
Step 2 — Check flags:
CODEBLOCK1
Unresolved flags from prior sessions are carry-forward items. Surface them.
Step 3 — Orient:
- - What was in progress?
- What was decided?
- What is open?
- What does the human need?
Then ask the human what they need.
Proactive Recall — Before Answering, Drink from Mnemosyne
The river Lethe makes souls forget. The spring Mnemosyne preserves all memory.
Before answering questions about past decisions or prior context — always check Lethe first.
Never invent. Never re-reason when the answer already exists.
Activation triggers — check memory before answering when:
- - User asks about past decisions, prior work, or previous conversations
- User says "remember", "did we", "were we", "what was"
- User references something from a previous session or days ago
- User's question implies knowledge that should exist in memory
- You are about to re-reason something you might already know
The decision tree:
CODEBLOCK2
Search → Found: Cite the specific event. "I recorded on March 24: [content]."
Search → Not found: "I don't have that in memory yet." Do not invent.
Common search patterns:
| Question | Search for |
|---|
| "were we working on X?" | X + project/app keywords |
| "did we decide on Y?" |
"decision" + Y |
| "what's the status of Z?" | Z + "status" + "open" |
| "what approach for W?" | W + "approach" + "decided" |
| "who was supposed to do V?" | V + "task" + "todo" |
| Preferences / tastes | "preference" + "like" + "dislike" |
Anti-patterns:
- - ❌ "Based on our previous conversation..." — unless you've actually searched
- ❌ Re-reasoning a decision that exists in Lethe — retrieve and cite it
- ❌ Answering from incomplete fragments — say "let me check" and search
- ❌ Dropping flags silently — surface them to the user
Memory Queries
Search by keyword
CODEBLOCK3
Search by keyword + tag
CODEBLOCK4
Recent events for a session
CODEBLOCK5
Session snapshot (checkpoints)
CODEBLOCK6
Full session summary
curl -s "http://localhost:18483/api/sessions/${SESSION_KEY}/summary"
Recording — When and What
Auto-recorded by the plugin (do not duplicate):
- - Tool calls after every real agent turn
- Session state transitions (active → interrupted → completed)
You record manually via lethe-log:
| Type | Use when | Example |
|---|
| INLINECODE16 | Decision made, conclusion reached, direction chosen | "Decision: use X because Y" |
| INLINECODE17 |
Observation, discovery, API behavior, something worth noting | "API returned 429 — rate limited" |
|
flag | Uncertainty that needs human review | "This approach may not scale" |
|
task | Work unit created, updated, or resolved | "Deploy v2 — done" |
Fastest path — use lethe-log:
CODEBLOCK8
Always include a confidence score:
| Score | Meaning |
|---|
| 1.0 | Certain — direct observation or explicit user instruction |
| 0.9–0.95 |
Near certain — strong reasoning, minor uncertainty |
| 0.7–0.85 | High confidence — plausible, well-reasoned hypothesis |
| 0.5–0.65 | Moderate — partial evidence, flag if consequential |
| < 0.5 | Pure speculation — always flag |
Never record:
- - Casual chat with no lasting value
- Routine lookups or obvious confirmations
- Ephemeral brainstorming that shouldn't persist
Flags Queue
Flags are uncertainties that need human review. They persist across sessions.
Raise a flag when:
- - You are acting on incomplete information but need to proceed
- A consequential decision has multiple plausible paths and you're not sure which is right
- You see a risk that the human should be aware of before continuing
- Something broke in an unexpected way and the cause is uncertain
Check unresolved flags:
CODEBLOCK9
When a flag is resolved:
- 1. Record the resolution as a
log event: "Flag resolved: [what was decided]" - The flag remains in history but is marked reviewed
Flag → Record → Resolve flow:
Uncertainty identified
→ raise flag (event_type: flag, confidence: 0.6)
→ human reviews in UI at /ui/flags
→ decision made
→ log: "Flag resolved: chose X over Y because Z"
Session Lifecycle
When to complete a session
- - Task is done and the human has confirmed completion
- Conversation has a natural end point and no follow-up is expected
- You are going offline and the session should not resume
When to interrupt (trigger checkpoint)
- - Container is shutting down or restarting
- You have been idle for an extended period
- The human has asked you to pause and pick up later
When to trigger compaction
- - Session has accumulated many events (100+) without a summary
- You want to compress history before a long conversation continues
- The session summary is stale (new events since last compact)
CODEBLOCK11
Session state reference
| State | Meaning |
|---|
| INLINECODE22 | Session is running, accepting events |
| INLINECODE23 |
Session was paused (crash, restart, or manual) — resumable |
|
completed | Session was explicitly closed — not resumable |
Error Handling — Decision Trees
Lethe server unreachable
CODEBLOCK12
Empty search results
CODEBLOCK13
Token budget exceeded in assemble
CODEBLOCK14
Session not found
CODEBLOCK15
Conflicting records
CODEBLOCK16
Flag surfaces unresolved across sessions
Flag from prior session still unresolved
→ Surface it to the user proactively
→ "Before we continue — there's an open flag from last session: [flag content]"
→ Do not ignore or drop flags silently
Architecture — What Each Piece Does
| Component | Responsibility |
|---|
Plugin (lethe extension) | Bootstrap, assemble, compact, heartbeat, event auto-logging |
| Skill (this file) |
Agent-facing guidance: orientation, queries, recording, error recovery |
|
Server (
lethe binary) | SQLite-backed HTTP API on port 18483 |
|
UI (
/ui/*) | Dashboard, session detail, flags review board |
Plugin handles: storage, retrieval, automatic context injection, session lifecycle, crash recovery.
Skill handles: how the agent thinks about and uses memory — orientation, search, recording, flags, error recovery.
The server is append-only. Events are never overwritten — only compacted into summaries.
Quick Reference
CODEBLOCK18
Lethe — 持久化智能体记忆
Lethe是你的长期记忆层。每个决策、观察、任务和标记都会跨会话持久化,并在容器重启后依然存在。该插件自动处理引导和上下文组装。本技能处理定位、查询、记录和错误恢复。
心智模型:
- - 事件仅可追加。除非你明确删除,否则任何内容都不会被删除。
- 压缩将事件合成为叙事摘要——它不会删除历史记录。
- 记忆搜索检索事实。记录捕获决策。标记呈现不确定性。
- 插件在bootstrap()和assemble()时触发——你处理其他所有事情。
启动序列——始终优先运行
在每个新会话(用户的第一个真实消息)中,在回答之前先进行定位。
⚠️ 关键:所有Lethe API路由都在/api/下。基础URL是http://localhost:18483/api。永远不要直接查询/sessions——始终使用/api/sessions。
步骤1——获取完整会话状态(单次调用):
bash
curl -s http://localhost:18483/api/sessions/${SESSION_KEY}/summary
返回内容:
- - summary — 所有先前压缩的压缩叙事
- recentevents — 最近20个事件(填补自上次压缩以来的空白)
- checkpointcount、eventcount、latestcheckpoint
- session.state — active、interrupted或completed
步骤2——检查标记:
bash
curl -s http://localhost:18483/api/flags
先前会话中未解决的标记是结转项。将它们呈现出来。
步骤3——定位:
- - 什么正在进行中?
- 什么已决定?
- 什么尚未解决?
- 人类需要什么?
然后询问人类他们需要什么。
主动回忆——在回答之前,先饮记忆之泉
忘川河让灵魂遗忘。记忆之泉保存所有记忆。
在回答关于过去决策或先前上下文的问题之前——始终先检查Lethe。
永远不要编造。当答案已经存在时,不要重新推理。
触发条件——在以下情况下,回答前先检查记忆:
- - 用户询问关于过去的决策、先前的工作或之前的对话
- 用户说记得、我们是否、我们之前、什么是什么
- 用户引用之前会话或几天前的事情
- 用户的问题暗示记忆中应该存在的知识
- 你即将重新推理你可能已经知道的事情
决策树:
用户询问先前上下文
│
├─ 记得 / 我们是否 / 我们之前 / 什么是什么
│ └─ 搜索:GET /api/events/search?q=<相关术语>
│
├─ X的状态 / 未关闭的线程
│ └─ 搜索:GET /api/events/search?q=X 状态
│
└─ 一般的先前上下文问题
└─ GET /api/sessions/${KEY}/events?limit=10
搜索→找到: 引用具体事件。我在3月24日记录了:[内容]。
搜索→未找到: 我记忆中还没有这个。不要编造。
常见搜索模式:
| 问题 | 搜索内容 |
|---|
| 我们之前在做X吗? | X + 项目/应用关键词 |
| 我们决定Y了吗? |
decision + Y |
| Z的状态是什么? | Z + status + open |
| W用什么方法? | W + approach + decided |
| 谁应该做V? | V + task + todo |
| 偏好/品味 | preference + like + dislike |
反模式:
- - ❌ 根据我们之前的对话... — 除非你实际搜索过
- ❌ 重新推理Lethe中已存在的决策 — 检索并引用它
- ❌ 从不完整的片段回答 — 说让我查一下然后搜索
- ❌ 静默丢弃标记 — 向用户呈现它们
记忆查询
按关键词搜索
bash
curl -s http://localhost:18483/api/events/search?q=token+budget&limit=10 | jq .events[] | {event
type, content, createdat}
按关键词+标签搜索
bash
curl -s http://localhost:18483/api/events/search?q=dashboard&tag=lethe&limit=10 | jq .
会话的最近事件
bash
curl -s http://localhost:18483/api/sessions/${SESSION
KEY}/events?limit=20 | jq .events[] | {eventtype, content, created_at}
会话快照(检查点)
bash
curl -s http://localhost:18483/api/sessions/${SESSION_KEY}/checkpoints | jq .checkpoints[0].snapshot
完整会话摘要
bash
curl -s http://localhost:18483/api/sessions/${SESSION_KEY}/summary
记录——何时记录和记录什么
由插件自动记录(不要重复):
- - 每次真实智能体轮次后的工具调用
- 会话状态转换(active → interrupted → completed)
你通过lethe-log手动记录:
| 类型 | 使用时机 | 示例 |
|---|
| record | 做出决策、得出结论、选择方向 | Decision: use X because Y |
| log |
观察、发现、API行为、值得注意的事情 | API returned 429 — rate limited |
| flag | 需要人类审查的不确定性 | This approach may not scale |
| task | 工作单元创建、更新或解决 | Deploy v2 — done |
最快路径——使用lethe-log:
bash
~/.openclaw/workspace/skills/lethe-memory/lethe-log record Decision: use X because Y
~/.openclaw/workspace/skills/lethe-memory/lethe-log log API returned 429 — rate limited
~/.openclaw/workspace/skills/lethe-memory/lethe-log flag This approach may not scale
~/.openclaw/workspace/skills/lethe-memory/lethe-log task Deploy v2 --status done
始终包含置信度评分:
| 评分 | 含义 |
|---|
| 1.0 | 确定——直接观察或明确的用户指令 |
| 0.9–0.95 |
几乎确定——强推理,轻微不确定性 |
| 0.7–0.85 | 高置信度——合理、推理充分的假设 |
| 0.5–0.65 | 中等——部分证据,如果后果重大则标记 |
| < 0.5 | 纯推测——始终标记 |
永远不要记录:
- - 没有持久价值的随意聊天
- 常规查找或明显的确认
- 不应持久化的短暂头脑风暴
标记队列
标记是需要人类审查的不确定性。它们跨会话持久化。
在以下情况下提出标记:
- - 你在信息不完整的情况下行动但需要继续
- 一个重大决策有多个合理路径,你不确定哪个是正确的
- 你看到人类在继续之前应该意识到的风险
- 某些东西以意外方式损坏,原因不确定
检查未解决的标记:
bash
curl -s http://localhost:18483/api/flags | jq .
当标记被解决时:
- 1. 将解决方案记录为log事件:Flag resolved: [what was decided]
- 该标记保留在历史中,但被标记为已审查
标记→记录→解决流程:
识别不确定性
→ 提出标记(event_type: flag, confidence: 0.6)
→ 人类在UI中审查 /ui/flags
→ 做出决策
→ 记录:Flag resolved: chose X over Y because Z
会话生命周期
何时完成会话
- - 任务完成且人类已确认完成
- 对话有自然结束点且预计没有后续
- 你将离线且会话不应恢复
何时中断(触发检查点)
- - 容器正在关闭或重启
- 你已长时间空闲
- 人类要求你暂停并稍后继续
何时触发压缩
- - 会话已积累许多事件(100+)而没有摘要
- 你希望在长时间对话继续之前压缩历史
- 会话摘要已过时(自上次压缩后有新事件)
bash
curl -s -X POST http://localhost:18483/api/sessions/${SESSION_KEY}/compact
会话状态参考
|