名称: context-recovery
描述: 在会话被压缩或上下文缺失但暗示需要延续时,自动恢复工作上下文。支持 Discord、Slack、Telegram、Signal 及其他已接入的通信渠道。
元数据: {"clawdbot":{"emoji":"🔄"}}
当会话因压缩而上下文不完整,或用户暗示需要延续但缺少上下文时,自动恢复工作状态。支持 Discord、Slack、Telegram、Signal 及其他已接入的通信渠道。
适用场景:会话以被截断的上下文开始;用户提及先前工作但未说明细节;出现会话压缩指示。
<summary> 标签开始(检测到压缩)从运行时上下文中提取:
- channel — discord | slack | telegram | signal | 等
- channelId — 特定频道/对话的 ID
- threadId — 用于线程对话(Slack、Discord 线程)
初始获取:
message:read
channel: <detected-channel>
channelId: <detected-channel-id>
limit: 50
自适应扩展逻辑:
1. 解析返回消息的时间戳
2. 计算时间跨度:最新时间戳 - 最旧时间戳
3. 如果时间跨度 < 2 小时 且 消息数量 == 限制数:
- 再获取 50 条消息(如果支持,使用 before 参数)
- 重复此过程,直到时间跨度 ≥ 2 小时 或 总消息数 ≥ 100
4. 硬性上限:最多 100 条消息(受令牌预算限制)
线程感知恢复(Slack/Discord):
# 如果存在 threadId,首先获取线程消息
message:read
channel: <detected-channel>
threadId: <thread-id>
limit: 50
# 然后获取父频道以获取更广泛的上下文
message:read
channel: <detected-channel>
channelId: <parent-channel-id>
limit: 30
解析内容:
- 最近的用户请求(询问了什么)
- 最近的助手回复(做了什么)
- URL、文件路径、分支名、PR 编号
- 未完成的操作(承诺但未执行)
- 项目标识符和工作目录
# 查找此代理最近的会话文件
SESSION_DIR=$(ls -d ~/.clawdbot-*/agents/*/sessions 2>/dev/null | head -1)
SESSIONS=$(ls -t "$SESSION_DIR"/*.jsonl 2>/dev/null | head -3)
for SESSION in $SESSIONS; do
echo "=== 会话:$SESSION ==="
# 提取用户请求
jq -r 'select(.message.role == "user") | .message.content[0].text // empty' "$SESSION" | tail -20
# 提取助手操作(查找工具调用和回复)
jq -r 'select(.message.role == "assistant") | .message.content[]? | select(.type == "text") | .text // empty' "$SESSION" | tail -50
done
# 从频道历史记录中提取关键词(项目名、PR 编号、分支名)
# 在内存中搜索相关条目
grep -ri "<keyword>" ~/clawd-*/memory/ 2>/dev/null | head -10
# 检查最近的每日日志
ls -t ~/clawd-*/memory/202*.md 2>/dev/null | head -3 | xargs grep -l "<keyword>" 2>/dev/null
编译结构化的摘要:
## 已恢复的上下文
**频道:** #<频道名称> (<平台>)
**时间范围:** <最早消息> 至 <最新消息>
**已分析消息数:** <数量>
### 活跃项目/任务
- **代码库:** <代码库名称>
- **分支:** <分支名称>
- **PR:** #<编号> — <标题>
### 近期工作时间线
1. [<时间戳>] <操作/请求>
2. [<时间戳>] <操作/请求>
3. [<时间戳>] <操作/请求>
### 待处理/未完成的操作
- ⏳ “<引用的未完成操作>”
- ⏳ “<另一项未完成事项>”
### 关键引用
| 类型 | 值 |
|------|-------|
| PR | #<编号> |
| 分支 | <名称> |
| 文件 | <路径> |
| URL | <链接> |
### 最后的用户请求
> “<可能未完成的引用请求>”
### 置信度
- 频道上下文:<高/中/低>
- 会话日志:<可用/部分可用/不可用>
- 内存条目:<已找到/无>
持久化到内存以供将来参考:
# 写入每日内存文件
MEMORY_FILE=~/clawd-*/memory/$(date +%Y-%m-%d).md
cat >> "$MEMORY_FILE" << EOF
## 上下文恢复 — $(date +%H:%M)
**频道:** #<频道名称>
**恢复的上下文用于:** <项目/任务摘要>
### 关键状态
- <关键上下文的要点>
### 待处理事项
- <未完成的操作>
EOF
这确保了上下文在未来的压缩中得以保留。
呈现恢复的上下文,然后提示:
“上下文已恢复。您最后的请求是 [X]。此操作 [已完成/未完成]。我应该 [继续/重试/请求澄清] 吗?”
channelIdthreadIdchannel 参数threadId — 始终首先检查线程上下文message:read 接口在会话开始时,扫描压缩指示:
# 触发检测的伪代码
if message contains "<summary>":
trigger_context_recovery()
elif message contains any of ["Summary unavailable", "context limits", "truncated", "compacted"]:
trigger_context_recovery()
elif message matches continuation_patterns:
# "continue", "where were we", "did this happen", 等
trigger_context_recovery()
无需等待用户询问 — 如果检测到压缩,主动恢复并呈现上下文。
场景: 会话以压缩摘要开始
用户消息:“<summary>由于上下文限制,摘要不可用...</summary>”
用户消息:“刚才发生了什么?”
代理执行:
1. 通过 <summary> 标签检测到压缩
2. message:read channel=discord channelId=1460342116516364533 limit=50
3. 计算时间跨度:2.5 小时 — 足够,无需扩展
4. 解析消息,找到最后一个操作:“现在让我提取关键编排决策……”
5. 检查会话日志 — 提取最近的用户请求
6. 将上下文摘要写入 memory/YYYY-MM-DD.md
7. 回复:
“上下文已恢复。您最后的请求是从 Nexus 归档会话中为 PR #137(技能与代理系统)提取编排决策。此操作在上下文被截断前未完成。
恢复的状态:
- PR #137:15,053 行新增,91 个文件,合并状态为 CONFLICTING
- 规范位置:content/spec-skills-agents-system.md(2,067 行)
- Nexus 会话:~/.clawdbot-duke-leto/archive/nexus-sessions/(96 个文件)我应该继续执行提取操作吗?”