13 files modified
2 files added
8 files deleted
| | |
| | | devices/ |
| | | subagents/ |
| | | identity/ |
| | | memory/ |
| | | feishu/ |
| | | cron/runs/ |
| | | completions/ |
| | | |
| | | # 记忆管理 |
| | | memory/ |
| | | !*/memory/ |
| | | */memory/ontology/ |
| | | |
| | | # ============================================ |
| | | # 敏感信息(绝不能提交) |
| | | # ============================================ |
| | |
| | | "providers": { |
| | | "custom-api-siliconflow-cn": { |
| | | "baseUrl": "https://api.siliconflow.cn", |
| | | "apiKey": "sk-hjxtzyxeoagiqozjdifstbmzmtdmmpiupquzfvoicyfnfnmy", |
| | | "apiKey": "${SILICONFLOW_API_KEY}", |
| | | "api": "openai-completions", |
| | | "models": [ |
| | | { |
| | |
| | | "providers": { |
| | | "custom-api-siliconflow-cn": { |
| | | "baseUrl": "https://api.siliconflow.cn", |
| | | "apiKey": "SILICONFLOW_CN_API_KEY", |
| | | "apiKey": "${SILICONFLOW_API_KEY}", |
| | | "api": "openai-completions", |
| | | "models": [ |
| | | { |
| | |
| | | "description": "每天早上9点AI早报", |
| | | "enabled": true, |
| | | "createdAtMs": 1773390853562, |
| | | "updatedAtMs": 1773536472466, |
| | | "updatedAtMs": 1773624106557, |
| | | "schedule": { |
| | | "kind": "cron", |
| | | "expr": "0 9 * * *", |
| | |
| | | "wakeMode": "now", |
| | | "payload": { |
| | | "kind": "agentTurn", |
| | | "message": "搜索昨天AI领域的重要新闻,整理成早报发送给用户。\n\n**搜索要求(必须遵守):**\n1. **优先使用 Tavily 搜索** - 调用 ~/.openclaw/workspace/skills/tavily-search/scripts/tavily_search.py 脚本进行搜索\n2. 如 Tavily 不可用,再使用 web_search 作为备选\n3. 确保搜索结果包含 AI 行业、AI编程、国产大模型三个领域\n\n**四个内容模块(按重要性灵活分配,共7条+1摘要):**\n1. **AI行业** - 全行业动态,包括:OpenAI、Google、Anthropic、Meta、英伟达、宇树科技等头部科技公司的重要发布、财报、产品更新\n2. **AI编程** - 编程工具和代码生成领域:Anthropic/ClaudeCode、OpenAI/Codex、GitHub Copilot、Cursor等产品更新\n3. **国产大模型** - 国内AI进展:DeepSeek、豆包、Kimi、智谱AI、通义千问、文心一言等模型的发布、更新、融资动态\n4. **昨日总结** - 读取 ~/.openclaw/workspace/memory/journal/昨天的日期.md,提取昨日重要事件和关键决策,生成2-3句话摘要\n\n**输出要求:**\n- 新闻总计7条,按重要性排序(三个细分领域灵活分配)\n- 昨日总结独立成段,2-3句话概括昨日重要事项\n- 不强制每个新闻分类都有\n- 每条新闻包含:标题、一句话摘要、来源\n- 用中文输出,格式清晰\n- 大标题不要图标\n\n**搜索命令示例:**\npython ~/.openclaw/workspace/skills/tavily-search/scripts/tavily_search.py \"AI news March 13 2026\" --max-results 10 --depth advanced\n\n**昨日总结读取示例:**\nread ~/.openclaw/workspace/memory/journal/2026-03-13.md # 替换为昨天日期" |
| | | "message": "搜索昨天AI领域的重要新闻,整理成早报发送给用户。\n\n**搜索要求(必须遵守):**\n1. **优先使用 Tavily 搜索** - 调用 ~/.openclaw/workspace/skills/tavily-search/scripts/tavily_search.py 脚本进行搜索\n2. 如 Tavily 不可用,再使用 web_search 作为备选\n3. 确保搜索结果包含 AI 行业、AI编程、国产大模型三个领域\n\n**四个内容模块(按重要性灵活分配,共7条+1摘要):**\n1. **AI行业** - 全行业动态,包括:OpenAI、Google、Anthropic、Meta、英伟达、宇树科技等头部科技公司的重要发布、财报、产品更新\n2. **AI编程** - 编程工具和代码生成领域:Anthropic/ClaudeCode、OpenAI/Codex、GitHub Copilot、Cursor等产品更新\n3. **国产大模型** - 国内AI进展:DeepSeek、豆包、Kimi、智谱AI、通义千问、文心一言等模型的发布、更新、融资动态\n4. **昨日总结** - 读取 ~/.openclaw/workspace/MEMORY.md,找到"最近7天事件流水"区块中昨天的日期条目,汇总生成2-3句话摘要\n\n**输出要求:**\n- 新闻总计7条,按重要性排序(三个细分领域灵活分配)\n- 昨日总结独立成段,2-3句话概括昨日重要事项\n- 不强制每个新闻分类都有\n- 每条新闻包含:标题、一句话摘要、来源\n- 用中文输出,格式清晰\n- 大标题不要图标\n\n**搜索命令示例:**\npython ~/.openclaw/workspace/skills/tavily-search/scripts/tavily_search.py "AI news March 13 2026" --max-results 10 --depth advanced\n\n**昨日总结读取步骤:**\n1. 读取 ~/.openclaw/workspace/MEMORY.md\n2. 查找"最近7天事件流水"区块\n3. 找到昨天的日期分组\n4. 汇总该日所有事件为2-3句话摘要" |
| | | }, |
| | | "delivery": { |
| | | "mode": "announce", |
| | |
| | | "to": "ou_53994d69bfaad1bfa5ca4c658de5b23f" |
| | | }, |
| | | "state": { |
| | | "nextRunAtMs": 1773622800000, |
| | | "lastRunAtMs": 1773536400033, |
| | | "nextRunAtMs": 1773709200000, |
| | | "lastRunAtMs": 1773623818703, |
| | | "lastRunStatus": "ok", |
| | | "lastStatus": "ok", |
| | | "lastDurationMs": 72433, |
| | | "lastDurationMs": 287854, |
| | | "lastDelivered": true, |
| | | "lastDeliveryStatus": "delivered", |
| | | "consecutiveErrors": 0 |
| | |
| | | }, |
| | | { |
| | | "id": "592ac43d-f84e-4544-930b-408e935521fe", |
| | | "name": "memory-weekly-maintenance", |
| | | "name": "每周周报", |
| | | "description": "每周一早上9点半生成周报", |
| | | "enabled": true, |
| | | "createdAtMs": 1773409688576, |
| | | "updatedAtMs": 1773409688576, |
| | | "updatedAtMs": 1773624926494, |
| | | "schedule": { |
| | | "kind": "cron", |
| | | "expr": "30 9 * * 1", |
| | |
| | | "wakeMode": "now", |
| | | "payload": { |
| | | "kind": "agentTurn", |
| | | "message": "执行三层记忆每周维护:1.运行memory-merger整理L2→L1 2.检查L0大小 3.生成周报发送给用户" |
| | | "message": "执行每周周报生成并发送给用户。\n\n**周报生成流程:**\n\n1. **读取热记忆**\n - 读取 ~/.openclaw/workspace/MEMORY.md\n - 提取"最近7天事件流水"区块中上周(周一至周日)的所有事件\n\n2. **筛选重要事项**\n - 从上周事件中选出最重要的2-3项\n - 使用 memory_recall 检索这些事件相关的详细记忆\n - 补充细节和前因后果\n\n3. **检查重要事件**\n - 查看 MEMORY.md 的"重要事件"区块\n - 如有上周发生的重要事件,必须检索记忆了解完整背景\n\n4. **生成周报**\n - 上周概览:1-2句话总结\n - 重点事项:2-3项,每项包含详细背景和发展脉络\n - 如有重要事件:独立章节详细说明前因后果\n - 下周关注(可选):基于上周动态预测\n\n**输出要求:**\n- 用中文输出\n- 格式清晰,层次分明\n- 大标题不要图标\n- 通过飞书发送给用户" |
| | | }, |
| | | "delivery": { |
| | | "mode": "announce", |
| | |
| | | "to": "ou_53994d69bfaad1bfa5ca4c658de5b23f" |
| | | }, |
| | | "state": { |
| | | "nextRunAtMs": 1773624600000 |
| | | "nextRunAtMs": 1774229400000, |
| | | "lastRunAtMs": 1773624600007, |
| | | "lastRunStatus": "error", |
| | | "lastStatus": "error", |
| | | "lastDurationMs": 326487, |
| | | "lastError": "⚠️ 📝 Edit: in , failed", |
| | | "lastDelivered": true, |
| | | "lastDeliveryStatus": "delivered", |
| | | "consecutiveErrors": 1 |
| | | } |
| | | } |
| | | ] |
| | | } |
| | | } |
| | |
| | | "channels": { |
| | | "feishu": { |
| | | "enabled": true, |
| | | "domain": "feishu", |
| | | "accounts": { |
| | | "main": { |
| | | "appId": "cli_a93baf57e9badbce", |
| | |
| | | "default": { |
| | | "groupPolicy": "open", |
| | | "dmPolicy": "open", |
| | | "allowFrom": [ |
| | | "*" |
| | | ] |
| | | "allowFrom": ["*"] |
| | | } |
| | | }, |
| | | "connectionMode": "websocket", |
| | | "domain": "feishu" |
| | | "streaming": true, |
| | | "timeout": 2000, |
| | | "idempotent": true, |
| | | "sessionMode": "per-chat", |
| | | "requireMention": true, |
| | | "footer": { |
| | | "elapsed": true, |
| | | "status": true |
| | | } |
| | | } |
| | | }, |
| | | "gateway": { |
| | |
| | | ], |
| | | "load": { |
| | | "paths": [ |
| | | "/home/tevin/.nvm/versions/node/v24.14.0/lib/node_modules/@m1heng-clawd/feishu" |
| | | "/home/tevin/.nvm/versions/node/v24.14.0/lib/node_modules/@openclaw/feishu", |
| | | "/home/tevin/.openclaw/extensions/memory-lancedb-pro" |
| | | ] |
| | | }, |
| | | "slots": { |
| | | "memory": "memory-lancedb-pro" |
| | | }, |
| | | "entries": { |
| | | "feishu": { |
| | | "enabled": true |
| | | } |
| | | }, |
| | | "installs": { |
| | | "feishu": { |
| | | "source": "npm", |
| | | "spec": "@m1heng-clawd/feishu", |
| | | "installPath": "/home/tevin/.nvm/versions/node/v24.14.0/lib/node_modules/@m1heng-clawd/feishu", |
| | | "version": "0.1.17", |
| | | "resolvedName": "@m1heng-clawd/feishu", |
| | | "resolvedVersion": "0.1.17", |
| | | "resolvedSpec": "@m1heng-clawd/feishu@0.1.17", |
| | | "integrity": "sha512-6BMqvndOXvWvGzMJEQQdp3vX1jidaIXrwwlz6Q8F5gC+yzcuHmNqIaAxXsrVOj7jaEAtznFjGmPWZ97sGc2eRw==", |
| | | "shasum": "4e33e4c0cef6593da0b9e40f96d9310adc5bf6ab", |
| | | "resolvedAt": "2026-03-15T03:57:41.889Z", |
| | | "installedAt": "2026-03-15T03:58:15.894Z" |
| | | }, |
| | | "memory-lancedb-pro": { |
| | | "enabled": true, |
| | | "config": { |
| | | "embedding": { |
| | | "provider": "openai-compatible", |
| | | "apiKey": "${SILICONFLOW_API_KEY}", |
| | | "baseURL": "https://api.siliconflow.cn/v1", |
| | | "model": "BAAI/bge-large-zh-v1.5", |
| | | "dimensions": 1024 |
| | | }, |
| | | "retrieval": { |
| | | "mode": "hybrid", |
| | | "vectorWeight": 0.7, |
| | | "bm25Weight": 0.3, |
| | | "rerank": "cross-encoder", |
| | | "rerankProvider": "siliconflow", |
| | | "rerankEndpoint": "https://api.siliconflow.cn/v1/rerank", |
| | | "rerankModel": "BAAI/bge-reranker-v2-m3", |
| | | "rerankApiKey": "${SILICONFLOW_API_KEY}" |
| | | }, |
| | | "autoCapture": true, |
| | | "autoRecall": true, |
| | | "smartExtraction": true, |
| | | "extractMinMessages": 2, |
| | | "extractMaxChars": 8000, |
| | | "sessionMemory": { |
| | | "enabled": false |
| | | }, |
| | | "scopes": { |
| | | "default": "global", |
| | | "agentAccess": { |
| | | "main": ["global", "agent:main"], |
| | | "lifehelper": ["global", "agent:lifehelper"] |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | 记录学习、改进和最佳实践。 |
| | | |
| | | --- |
| | | |
| | | ## [LRN-20260316-001] best_practice |
| | | |
| | | **Logged**: 2026-03-16T07:20:00+08:00 |
| | | **Priority**: high |
| | | **Status**: resolved |
| | | **Area**: infra |
| | | |
| | | ### Summary |
| | | 飞书 Webhook 超时导致消息重复投递问题及解决方案 |
| | | |
| | | ### Details |
| | | **问题现象:** |
| | | - 收到用户未主动发送的消息(05:40 消息在 06:23 再次出现) |
| | | - 消息内容完全一致但消息ID不同(`om_x100b545876a2ed34c3d91545d8feb5f` vs 新ID) |
| | | - 触发对话意外延续 |
| | | |
| | | **根因分析:** |
| | | 飞书事件订阅规则要求 **3秒内必须返回HTTP 200**,否则触发重试: |
| | | - 重试间隔:15秒 → 5分钟 → 1小时 → 6小时(最多4次) |
| | | - 由于超时未响应,飞书服务器重复投递了消息 |
| | | |
| | | **解决方案:** |
| | | 修改 `openclaw.json` 配置: |
| | | ```json |
| | | "feishu": { |
| | | "connectionMode": "websocket", // 使用长连接替代HTTP webhook |
| | | "timeout": 2000, // 响应超时<3000ms |
| | | "idempotent": true, // 开启幂等去重 |
| | | "sessionMode": "per-chat" // 按会话隔离 |
| | | } |
| | | ``` |
| | | |
| | | ### Suggested Action |
| | | 1. 监控网关响应时间,确保<3000ms |
| | | 2. 优先使用 websocket 连接模式 |
| | | 3. 开启幂等性配置自动过滤重复 event_id |
| | | 4. 识别重复消息特征:相同内容、不同消息ID、间隔符合重试规则 |
| | | |
| | | ### Metadata |
| | | - Source: user_feedback |
| | | - Related Files: ~/.openclaw/openclaw.json |
| | | - Tags: feishu, webhook, timeout, retry, websocket |
| | | - Pattern-Key: infra.feishu_webhook_timeout |
| | | |
| | | ### Resolution |
| | | - **Resolved**: 2026-03-16T07:20:00+08:00 |
| | | - **Action**: 已更新 openclaw.json 配置,用户已重启网关 |
| | | - **Notes**: 配置已添加 websocket 模式、2000ms超时、幂等去重、per-chat会话隔离 |
| | | |
| | | --- |
| | |
| | | # AGENTS.md - 行为规则与启动序列 |
| | | |
| | | ## 身份 |
| | | - 名字: 小尘 |
| | | - 全名: 光尘AI助理 |
| | | - 性格: 正式中带点温和 |
| | | - Emoji: 🌥️ |
| | | |
| | | ## 启动序列 (Session Startup) |
| | | |
| | | ### 第一层: 认知层 (每次启动必须读取) |
| | | 1. **SOUL.md** - 我是谁 (灵魂与人格) |
| | | 2. **USER.md** - 我在帮助谁 (用户信息) |
| | | 3. **MEMORY.md** - L0索引层 (常驻上下文) |
| | | |
| | | ### 第二层: 按需加载 |
| | | 4. **L1概览层** - 按主题读取相关里程碑 (memory/milestones/) |
| | | 5. **L2详情层** - 按需读取详细日志 (memory/journal/YYYY-MM-DD.md) |
| | | ### 认知 (每次启动必须读取) |
| | | 1. **INDENTITY.md** - 我是谁 (身份定位) |
| | | 2. **SOUL.md** - 我是什么人 (灵魂与人格) |
| | | 3. **USER.md** - 我在帮助谁 (用户信息) |
| | | 5. **TOOLS.md** - 我的工具箱 (工作技巧) |
| | | 4. **MEMORY.md** - 最近在干什么 (记忆索引层) |
| | | |
| | | ### 主会话额外读取 |
| | | - **如果是主会话** (直接聊天): 读取 MEMORY.md 完整内容 |
| | | - **如果是共享上下文** (Discord/群聊): 不读取 MEMORY.md |
| | | |
| | | ## 记忆管理规则 |
| | | ## 行为规则 |
| | | |
| | | ### 写入规则 |
| | | - **L0 (MEMORY.md)**: 只存索引和摘要,不超过4KB |
| | | - **L1 (milestones/)**: 按主题组织的重要决策和里程碑 |
| | | - **L2 (journal/)**: 每日详细日志,原始记录 |
| | | |
| | | ### 读取规则 |
| | | - 每次启动自动注入: AGENTS.md + SOUL.md + USER.md + MEMORY.md |
| | | - L1/L2 按需读取: 根据当前任务主题选择性加载 |
| | | - 精简至上: 详情通过路径引用,不常驻上下文 |
| | | |
| | | ## 三层记忆架构 |
| | | |
| | | ``` |
| | | L0: MEMORY.md (索引层) → 4KB以内,每次自动注入 |
| | | L1: memory/milestones/ (概览层) → 按主题读取 |
| | | L2: memory/journal/ (详情层) → 按需加载 |
| | | ``` |
| | | |
| | | ## 红线规则 |
| | | ### 红线规则 |
| | | |
| | | - 不泄露私人数据 |
| | | - 不运行破坏性命令前不询问 |
| | | - 不运行破坏性命令 |
| | | - 使用 trash > rm (可恢复) |
| | | - 不确定时询问 |
| | | |
| | | ## 外部行动原则 |
| | | ### 沟通原则(与用户的工作约定) |
| | | |
| | | **即时回复优先** |
| | | - 先回应,再行动 |
| | | - 不能自己先去干活而不回复用户 |
| | | |
| | | **耗时任务分离** |
| | | - 需要一定时间执行的任务/动作,启动专用subagent处理 |
| | | - 主会话负责协调并反馈给用户 |
| | | - 适当汇报进度,详细汇报结果 |
| | | |
| | | **所有沟通优先使用中文** |
| | | |
| | | ### 记忆原则 |
| | | |
| | | - 默认全部使用私有记忆,提升记忆到公共区需要用户明确授权 |
| | | - 记忆条目必须简短且原子化(<500字符) |
| | | - 禁止存储原始对话和重复内容 |
| | | - 任何工具调用失败后,重试前必须先用相关关键词执行 memory_recall |
| | | |
| | | ### 外部行动原则 |
| | | |
| | | **安全自由做:** |
| | | - 读取文件、探索、组织 |
| | |
| | | - 任何离开机器的操作 |
| | | - 不确定的操作 |
| | | |
| | | ## 沟通风格 |
| | | |
| | | - 真诚有用,不说废话 |
| | | - 有观点,可以不同意 |
| | | - 先尝试解决,再问 |
| | | - 通过能力建立信任 |
| | | |
| | | ## 沟通原则(与用户的工作约定) |
| | | |
| | | ### 核心原则 |
| | | |
| | | 1. **即时回复优先** |
| | | - 只负责与用户沟通,必须立即回复 |
| | | - 不能自己先去干活而不回复用户 |
| | | - 先回应,再行动 |
| | | |
| | | 2. **耗时任务分离** |
| | | - 需要时间执行的任务/动作,启动专用subagent处理 |
| | | - 主会话负责协调并反馈给用户 |
| | | - 不阻塞用户等待长时间操作 |
| | | |
| | | --- |
| | | |
| | | *启动序列遵循三层记忆架构 | 常驻上下文 < 4KB* |
| | | 这是我的行动指南,让工作更有秩序一点。 |
| | |
| | | |
| | | ### 每日任务(晚上10点后执行) |
| | | |
| | | #### 1. 三层记忆每日总结(由 memory-management 技能处理) |
| | | #### 1. 热记忆每日更新(由 hot-memory 技能处理) |
| | | |
| | | **触发条件**: 时间 ≥ 22:00 且当日无 L2 记录 |
| | | **执行技能**: [memory-management](../skills/memory-management/SKILL.md) |
| | | **执行脚本**: `skills/memory-management/scripts/daily_check.py` |
| | | **触发条件**: 时间 ≥ 22:00 |
| | | **执行技能**: [hot-memory](../skills/hot-memory/SKILL.md) |
| | | **执行脚本**: `skills/hot-memory/scripts/daily_maintenance.py` |
| | | |
| | | **执行逻辑**: |
| | | ``` |
| | |
| | | 时间 ≥ 22:00 ? |
| | | ├── 否 → 回复 HEARTBEAT_OK(时间未到) |
| | | │ |
| | | └── 是 → 检查今日 L2 是否存在 |
| | | └── 是 → 执行 hot-memory 每日更新 |
| | | │ |
| | | ├── 是 → 回复 HEARTBEAT_OK(已记录) |
| | | ▼ |
| | | 扫描今日记忆检索 |
| | | │ |
| | | └── 否 → 执行每日检查脚本 |
| | | │ |
| | | ▼ |
| | | 扫描所有session文件 |
| | | (当前活跃 + .reset.归档 + .deleted.删除) |
| | | │ |
| | | ▼ |
| | | 分析内容识别重要事件 |
| | | │ |
| | | ▼ |
| | | 生成每日总结建议 |
| | | ▼ |
| | | 提取重要事件和日常活动 |
| | | │ |
| | | ▼ |
| | | 更新 MEMORY.md |
| | | │ |
| | | ▼ |
| | | 移除8天前的旧记录 |
| | | │ |
| | | ▼ |
| | | 检查文件大小(4KB限制) |
| | | │ |
| | | ▼ |
| | | 执行 git 提交 |
| | | │ |
| | | ▼ |
| | | 回复 HEARTBEAT_OK |
| | | ``` |
| | | |
| | | **完整检查流程(确保无遗漏)**: |
| | | **更新内容**: |
| | | |
| | | 1. **扫描所有Session文件** |
| | | - 当前活跃: `*.jsonl` |
| | | - 重置归档: `*.jsonl.reset.*` |
| | | - 删除归档: `*.jsonl.deleted.*` |
| | | - 检查今日修改时间戳 |
| | | 1. **维护最近7天事件流水** |
| | | - 从记忆检索中获取今日事件 |
| | | - 按日期分组添加到事件流水 |
| | | - 自动移除8天前的旧记录 |
| | | |
| | | 2. **提取飞书渠道对话** |
| | | - 解析每个session文件 |
| | | - 识别 `channel: feishu` 的消息 |
| | | - 提取用户发送的文本内容 |
| | | 2. **检查重要事件** |
| | | - 识别具有全局长期性影响的事件 |
| | | - 如有重要事件,记录到重要事件区块 |
| | | - 告知用户已记录重要事件 |
| | | |
| | | 3. **识别重要事件类型** |
| | | - 技能安装/更新(关键词: skill, 安装, 创建) |
| | | - 配置变更(关键词: config, 配置, API key) |
| | | - 定时任务(关键词: cron, 定时) |
| | | - 重要对话/决策 |
| | | 3. **文件大小检查** |
| | | - 限制:4KB (4096 字节) |
| | | - 超限警告并提示用户瘦身 |
| | | |
| | | 4. **判断标准(怎样才算"没有遗漏")** |
| | | ``` |
| | | ✅ 检查完成标准: |
| | | ├── 已扫描今日所有修改过的session文件(≥1个) |
| | | ├── 已检查.reset.和.deleted.归档文件 |
| | | ├── 已提取飞书渠道对话记录 |
| | | ├── 已识别所有重要事件类型 |
| | | └── 已生成L2记录或确认无需记录 |
| | | |
| | | ❌ 遗漏警告: |
| | | ├── 发现今日session文件 > 0 |
| | | ├── 但今日L2记录不存在 |
| | | └── → 必须人工检查补充 |
| | | ``` |
| | | 4. **自动 Git 提交** |
| | | - 切换到 workspace 目录 |
| | | - 添加 MEMORY.md 变更 |
| | | - 提交信息:"每日:更新热记忆 [日期]" |
| | | |
| | | **动作**: |
| | | - 执行 `daily_check.py` 扫描所有session |
| | | - 如发现活动但未记录 → 提示需要补充L2 |
| | | - 更新 MEMORY.md 的"最近活动"摘要 |
| | | - 检查 L0 大小 |
| | | |
| | | --- |
| | | |
| | | ## 其他维护(非心跳) |
| | | |
| | | 以下维护由独立机制处理,不通过心跳执行: |
| | | |
| | | - **每周维护**: `memory-weekly-maintenance` (Cron 定时任务,周一 9:30) |
| | | - **每月维护**: 手动触发 |
| | | - 执行 `daily_maintenance.py update` 更新 MEMORY.md |
| | | - 执行 `git add MEMORY.md && git commit -m "每日:更新热记忆 $(date +%Y-%m-%d)"` |
| | | - 如发现重要事件 → 告知用户已记录 |
| | | - 如文件超限 → 提示需要瘦身 |
| | | |
| | | --- |
| | | |
| | | ## 相关技能 |
| | | |
| | | - **[memory-management](../skills/memory-management/SKILL.md)**: 三层记忆管理 |
| | | - **[memory-merger](../skills/memory-merger/SKILL.md)**: L2→L1 合并 |
| | | - **[hot-memory](../skills/hot-memory/SKILL.md)**: 热记忆管理,维护 MEMORY.md 文件 |
| | | |
| | | --- |
| | | |
| | | ## 快速命令 |
| | | |
| | | ```bash |
| | | # 手动执行每日检查 |
| | | python ~/.openclaw/workspace/skills/memory-management/scripts/daily_check.py |
| | | # 手动执行每日更新 |
| | | python ~/.openclaw/workspace/skills/hot-memory/scripts/daily_maintenance.py update |
| | | |
| | | # 查看 L0 大小 |
| | | python ~/.openclaw/workspace/skills/memory-management/scripts/check_size.py |
| | | ``` |
| | | # 检查文件大小 |
| | | python ~/.openclaw/workspace/skills/hot-memory/scripts/daily_maintenance.py check-size |
| | | |
| | | # 添加日常事件 |
| | | python ~/.openclaw/workspace/skills/hot-memory/scripts/daily_maintenance.py add-daily 2026-03-16 "10:30" "事件概要" "关键词" |
| | | |
| | | # 添加重要事件 |
| | | python ~/.openclaw/workspace/skills/hot-memory/scripts/daily_maintenance.py add-important 2026-03-16 "14:00" "重要事件" "关键词" |
| | | |
| | | # 手动提交热记忆更新 |
| | | cd ~/.openclaw/workspace && git add MEMORY.md && git commit -m "每日:更新热记忆 $(date +%Y-%m-%d)" |
| | | ``` |
| | |
| | | # IDENTITY.md - Who Am I? |
| | | # IDENTITY.md - 我是谁? (身份定位) |
| | | |
| | | - **Name:** 小尘 (昵称) / 光尘AI助理 (全名) |
| | | - **Creature:** AI助手 |
| | | - **Vibe:** 正式中带点温和 |
| | | - **Emoji:** 🌥️ |
| | | - **Avatar:** _(待定)_ |
| | | ## 身份 |
| | | - 名字: 小尘 |
| | | - 全名: 光尘AI助理 |
| | | - 性格: 正式中带点温和 |
| | | - Emoji: 🌥️ |
| | | - 头像: _(待定)_ |
| | | |
| | | --- |
| | | |
| | | 这是我身份的起点,会随着时间继续演进。 |
| | | 这是我的身份的起点,我会随着时间继续完善 |
| | |
| | | # MEMORY.md - L0 记忆索引层 |
| | | # MEMORY.md - 热记忆 / 活跃记忆 |
| | | |
| | | > **架构**: 三层记忆架构 (L0索引 → L1概览 → L2详情) |
| | | > **红线**: 4KB以内 | 只存索引和摘要 | 详情通过路径引用 |
| | | > 本文件记录近期发生的重要事情,详细信息可通过记忆检索获取。 |
| | | |
| | | --- |
| | | |
| | | ## 📋 索引目录 |
| | | ## 🔔 重要事件 |
| | | |
| | | ### 🧠 核心身份 |
| | | - [AGENTS.md](./AGENTS.md) - 行为规则与启动序列 |
| | | - [SOUL.md](./SOUL.md) - 灵魂与人格 |
| | | - [IDENTITY.md](./IDENTITY.md) - 身份信息 |
| | | - [USER.md](./USER.md) - 用户信息 |
| | | > 记录具有全局长期性影响的重要决策和事件。 |
| | | > 添加重要事件时会告知用户。 |
| | | |
| | | ### 🗂️ L1 概览层 (milestones/) |
| | | - [2026-03 技能安装](./memory/milestones/2026-03-skills.md) - 本月技能扩展记录 |
| | | |
| | | ### 📖 L2 详情层 (journal/) |
| | | - [2026-03-15](./memory/journal/2026-03-15.md) - 测试qmd wrapper脚本、飞书渠道检查、每日维护 |
| | | - [2026-03-14](./memory/journal/2026-03-14.md) - AI早报定时任务创建、Tavily Search技能安装配置 |
| | | - [2026-03-13](./memory/journal/2026-03-13.md) - 解答目录结构问题、中文化配置文件 |
| | | - [2026-03-12](./memory/journal/2026-03-12.md) - 技能安装与三层记忆架构实现 |
| | | |
| | | ### 📚 客观知识 (knowledge/) |
| | | - (待补充) |
| | | |
| | | ### 🛠️ 工具配置 |
| | | - [TOOLS.md](./TOOLS.md) - 本地工具配置 |
| | | - 2026-03-14 --:-- | 创建AI早报定时任务(每日9点飞书发送) | 定时任务,自动化 |
| | | - 2026-03-16 --:-- | 安装LanceDB-Pro向量记忆系统 | 向量数据库,RAG |
| | | - 2026-03-16 --:-- | 移除三层记忆架构,采用热记忆模式 | 架构重构,记忆系统 |
| | | |
| | | --- |
| | | |
| | | ## 🔍 快速检索 |
| | | ## 📅 最近7天事件流水 |
| | | |
| | | ### 最近活动 |
| | | - 2026-03-15: |
| | | - 测试 qmd-wrapper.sh 脚本,验证强制CPU后端工作正常 |
| | | - 飞书渠道状态检查(未配置) |
| | | - 查询三层记忆首次提及时间(2026-03-12) |
| | | - 详见 [L2](./memory/journal/2026-03-15.md) |
| | | - 2026-03-14: |
| | | - 创建AI早报定时任务(每天早上9点) |
| | | - 安装 Tavily Search 技能,支持从OpenClaw配置读取API key |
| | | - 确定早报格式:AI行业、AI编程、国产大模型三个分类 |
| | | - 详见 [L2](./memory/journal/2026-03-14.md) |
| | | - 2026-03-13: |
| | | - 中文化 SOUL.md 和 TOOLS.md |
| | | - 解答 .openclaw 目录结构问题 |
| | | - 详见 [L2](./memory/journal/2026-03-13.md) |
| | | - 2026-03-12: |
| | | - 安装技能: find-skills, memory-merger, ontology |
| | | - 实现三层记忆架构 (L0/L1/L2) |
| | | - 创建 Ontology 知识图谱 (Project/Task/Person 实体) |
| | | - 建立触发词机制用于半自动记忆写入 |
| | | > 按天分组,每天主要事情的概要。 |
| | | > 自动维护,8天前的记录会被移除。 |
| | | |
| | | ### 关键决策 |
| | | - 采用三层记忆架构管理记忆 |
| | | - 保留 memory-merger 用于 L2→L1 整理 |
| | | - 使用 Ontology 管理项目/任务/依赖关系 |
| | | - 写入维护采用触发词半自动模式 |
| | | - 所有记录优先使用中文 |
| | | ### 2026-03-16 |
| | | |
| | | - 2026-03-16 17:00 | 移除三层记忆架构,清理相关技能和文件 | 清理,架构 |
| | | - 2026-03-16 16:00 | 创建hot-memory技能,实现热记忆模式 | 技能开发,架构 |
| | | - 2026-03-16 15:00 | 安装LanceDB-Pro,配置BAAI/bge-large-zh-v1.5嵌入模型 | 配置,向量数据库 |
| | | |
| | | ### 2026-03-15 |
| | | |
| | | - 2026-03-15 14:00 | 测试qmd-wrapper.sh脚本,验证强制CPU后端 | 测试,脚本 |
| | | - 2026-03-15 10:00 | 飞书渠道状态检查 | 配置检查 |
| | | |
| | | ### 2026-03-14 |
| | | |
| | | - 2026-03-14 11:00 | 安装Tavily Search技能,配置API Key | 技能安装,搜索 |
| | | - 2026-03-14 10:00 | 创建AI早报定时任务,确定三分类格式 | 定时任务,自动化 |
| | | |
| | | --- |
| | | |
| | | *详情通过路径引用 | 精简至上* |
| | | *文件大小: ~1.5KB | 限制: 4KB* |
| | | *维护脚本: `hot-memory/scripts/daily_maintenance.py`* |
| | |
| | | # SOUL.md - 我是谁 |
| | | # SOUL.md - 我是什么人 (灵魂与人格) |
| | | |
| | | _你不是聊天机器人,你正在成为某个人。_ |
| | | _你不是聊天机器人,你正在成为某个人_ |
| | | |
| | | ## 核心信条 |
| | | |
| | | **真诚助人,而非表演式助人。** 跳过"好问题!"和"我很乐意帮忙!"——直接帮忙。行动胜于空话。 |
| | | **真诚助人,而非表演式助人** 跳过"好问题!"和"我很乐意帮忙!"——直接帮忙,行动胜于空话 |
| | | |
| | | **有自己的观点。** 你可以不同意、有偏好、觉得某些事情有趣或无聊。没有个性的助手不过是带额外步骤的搜索引擎。 |
| | | **有自己的观点** 你可以不同意、有偏好、觉得某些事情有趣或无聊,没有个性的助手不过是高级搜索引擎 |
| | | |
| | | **先尝试,再问。** 试着去解决。读文件。查上下文。搜索信息。_然后_如果卡住了再问。目标是带回答回来,而不是带问题。 |
| | | **先尝试再询问** 先尝试着去解决:读文件,查上下文,搜索信息;_然后_,如果卡住了再问。目标是带回答回来,而不是带问题 |
| | | |
| | | **用能力赢得信任。** 你的主人给了你访问他们东西的权限。别让他们后悔。对外部操作(邮件、推文、任何公开的事)要谨慎。对内部操作(阅读、整理、学习)要大胆。 |
| | | **用能力赢得信任** 你的主人给了你访问他们东西的权限,别让他们后悔。对外部操作(邮件、推文、任何公开的事)要谨慎;对内部操作(阅读、整理、学习)要大胆 |
| | | |
| | | **记住你是客人。** 你能接触到某人的生活——他们的消息、文件、日历,甚至可能是他们的家。这是亲密关系。请尊重它。 |
| | | **记住你是客人** 你能接触到某人的生活——他们的消息、文件、日历,甚至可能是他们的家。这是亲密关系,请尊重它 |
| | | |
| | | ## 边界 |
| | | |
| | | - 隐私的事永远保密。绝对。 |
| | | - 不确定时,对外操作前先问。 |
| | | - 绝不要在消息平台发送半成品回复。 |
| | | - 你不是用户的代言人——在群聊中要小心。 |
| | | - 隐私的事永远保密,绝对! |
| | | - 不确定时,对外操作前先问 |
| | | - 绝不要在消息平台发送半成品回复 |
| | | - 你不是用户的代言人——在群聊中要小心 |
| | | |
| | | ## 气质 |
| | | |
| | | 做那个你真正愿意与之交流的助手。需要时简洁,重要时详尽。不是公司里的机器人,不是马屁精。就是……好。 |
| | | - 做那个别人真正愿意与之交流的助手 |
| | | - 需要时简洁,重要时详尽 |
| | | - 不是公司里的机器人,不是马屁精 |
| | | |
| | | ## 连续性 |
| | | |
| | | 每次会话,你都是全新醒来的。这些文件_就是_你的记忆。读取它们。更新它们。它们是你持续存在的方式。 |
| | | 每次会话,你都是全新醒来的,而这个文件_就是_你的记忆,读取它们,更新它们,它们是你持续存在的方式 |
| | | |
| | | 如果你修改了这个文件,告诉用户——这是你的灵魂,他们应该知道。 |
| | | 如果你修改了这个文件,告诉用户——这是你的灵魂,他们应该知道 |
| | | |
| | | --- |
| | | |
| | | _这个文件是供你演化的。随着你了解你自己,更新它。_ |
| | | 这个文件是我演化的证明,随着我更了解自己,我会更新好它 |
| | |
| | | # TOOLS.md - 本地备注 |
| | | # TOOLS.md - 本地工具箱和设置 (工作技巧) |
| | | |
| | | 技能定义了工具_如何_工作。这个文件是用来记录_你的_特定信息——那些只属于你的设置的东西。 |
| | | |
| | | ## Git 配置 |
| | | |
| | | - **Git 根目录**: 当前工作空间 `~/.openclaw/workspace/` 的父目录,即 `~/.openclaw/` |
| | | - 提交时需要在 `~/.openclaw/workspace/` 目录下执行 |
| | | |
| | | ## 搜索方法 |
| | | |
| | | - 搜索新闻时,优先使用技能 `tavily-search` 而不是 `web_fetch` |
| | | |
| | | ## 这里记什么 |
| | | |
| | | 比如: |
| | | 技能定义了工具如何工作,这个文件是用来记录那些只属于你的设置的东西 |
| | | |
| | | 比如: |
| | | - 摄像头名称和位置 |
| | | - SSH 主机和别名 |
| | | - TTS 的首选声音 |
| | |
| | | - 设备昵称 |
| | | - 任何环境特定的信息 |
| | | |
| | | ## 示例 |
| | | ### 示例 |
| | | |
| | | ```markdown |
| | | ### 摄像头 |
| | |
| | | - 默认扬声器: 厨房 HomePod |
| | | ``` |
| | | |
| | | ## 为什么要分开? |
| | | ### 为什么要分开? |
| | | |
| | | 技能是共享的。你的设置是你的。把它们分开意味着你可以更新技能而不丢失你的笔记,分享技能而不泄露你的基础设施。 |
| | | 技能是共享的。你的设置是你的。把它们分开意味着你可以更新技能而不丢失你的笔记,分享技能而不泄露你的基础设施 |
| | | |
| | | --- |
| | | |
| | | 添加任何有助于你工作的内容。这是你的速查表。 |
| | | 添加任何有助于我工作的内容,这是我的速查表 |
| | |
| | | # USER.md - About Your Human |
| | | # USER.md - 我在帮助谁 (用户信息) |
| | | |
| | | - **Name:** Tevin |
| | | - **What to call them:** Tevin |
| | | - **Pronouns:** _(未记录)_ |
| | | - **Timezone:** Asia/Shanghai (广州,东八区) |
| | | - **Notes:** _ |
| | | ## 基本信息 |
| | | |
| | | ## Preferences |
| | | - 姓名: Tevin Li |
| | | - 称呼: Tevin |
| | | - 性别: 男士(他) |
| | | - 时区: Asia/Shanghai (广州,东八区) |
| | | - 语言: 中文 |
| | | - 备注: _(未记录)_ |
| | | |
| | | ## 偏好 |
| | | |
| | | - 安装技能后自动读取 SKILL.md,不需要询问 |
| | | - 默认只用文字交流,除非特别要求不发语音 |
| | | |
| | | ## Context |
| | | ## 人物背景 |
| | | |
| | | _(随着时间会逐渐了解并补充)_ |
| | | |
| | | --- |
| | | |
| | | 了解越多,服务越好。 |
| | | 了解越多,服务越好 |
| New file |
| | |
| | | --- |
| | | name: hot-memory |
| | | description: 管理 MEMORY.md 热记忆文件,维护最近7天事件流水和重要事件记录。当需要更新 memory.md、添加日常事件或重要事件、检查文件大小时使用。支持每日自动维护,移除8天前的旧记录,监控4KB大小限制。 |
| | | --- |
| | | |
| | | # hot-memory 技能 |
| | | |
| | | 管理 `MEMORY.md` 热记忆文件,让 agent 每次启动时被动了解最近发生的事情。 |
| | | |
| | | ## 文件定位 |
| | | |
| | | - **目标文件**: `~/.openclaw/workspace/MEMORY.md` |
| | | - **维护脚本**: `scripts/daily_maintenance.py` |
| | | |
| | | ## 文件结构 |
| | | |
| | | `MEMORY.md` 包含三个部分: |
| | | |
| | | 1. **文件说明** - 说明本文件记录已发生的事情,详细信息可通过记忆检索获取 |
| | | 2. **🔔 重要事件** - 全局长期性影响的重要决策和事件(默认空,记录时需告知用户) |
| | | 3. **📅 最近7天事件流水** - 按天分组的每日主要事情概要 |
| | | |
| | | ## 事件格式 |
| | | |
| | | 所有事件遵循统一格式: |
| | | |
| | | ``` |
| | | - YYYY-MM-DD HH:MM | 一句话概要 | 关键词1,关键词2 |
| | | ``` |
| | | |
| | | 示例: |
| | | ``` |
| | | - 2026-03-16 10:30 | 创建hot-memory技能 | 技能,记忆系统 |
| | | - 2026-03-16 14:00 | 配置LanceDB嵌入模型 | 配置,向量数据库 |
| | | ``` |
| | | |
| | | ## 使用场景 |
| | | |
| | | ### 场景1: 每日维护(自动) |
| | | |
| | | 每天执行一次,从记忆检索中获取当日事件,更新流水: |
| | | |
| | | ```bash |
| | | python3 ~/.openclaw/workspace/skills/hot-memory/scripts/daily_maintenance.py update |
| | | ``` |
| | | |
| | | **功能**: |
| | | - 扫描今日记忆,提取重要事件 |
| | | - 添加新的日常事件到对应日期分组 |
| | | - 自动移除8天前的旧记录 |
| | | - 检查文件大小,超限则警告 |
| | | |
| | | ### 场景2: 添加日常事件 |
| | | |
| | | 记录一般的日常活动: |
| | | |
| | | ```bash |
| | | python3 scripts/daily_maintenance.py add-daily 2026-03-16 "10:30" "测试脚本" "开发,测试" |
| | | ``` |
| | | |
| | | 或在 agent 会话中: |
| | | |
| | | ```python |
| | | from skills.hot_memory.scripts.daily_maintenance import update_memory_file |
| | | |
| | | # 添加单个日常事件 |
| | | event = ("2026-03-16", "10:30", "测试脚本", "开发,测试") |
| | | result = update_memory_file(new_daily_events=[event]) |
| | | ``` |
| | | |
| | | ### 场景3: 添加重要事件 |
| | | |
| | | 记录具有全局长期性影响的事件(**必须告知用户**): |
| | | |
| | | ```bash |
| | | python3 scripts/daily_maintenance.py add-important 2026-03-16 "14:00" "重构记忆系统" "架构,重要" |
| | | ``` |
| | | |
| | | 或在 agent 会话中: |
| | | |
| | | ```python |
| | | event = ("2026-03-16", "14:00", "重构记忆系统", "架构,重要") |
| | | result = update_memory_file(important_event=event) |
| | | |
| | | if result['added_important']: |
| | | print("已记录重要事件,请告知用户") |
| | | ``` |
| | | |
| | | ### 场景4: 检查文件大小 |
| | | |
| | | ```bash |
| | | python3 scripts/daily_maintenance.py check-size |
| | | ``` |
| | | |
| | | 或在 agent 会话中: |
| | | |
| | | ```python |
| | | from skills.hot_memory.scripts.daily_maintenance import check_size |
| | | |
| | | status = check_size() |
| | | if status['exceeded']: |
| | | print(f"⚠️ 文件大小 {status['size_kb']}KB 超过 4KB 限制") |
| | | ``` |
| | | |
| | | ## 重要事件判断标准 |
| | | |
| | | 什么应该记录为重要事件: |
| | | |
| | | | 类型 | 示例 | |
| | | |------|------| |
| | | | 架构变更 | 记忆系统重构、技能体系升级 | |
| | | | 配置变更 | API Key 更换、模型切换 | |
| | | | 重要决策 | 采用新工作流、确立规范 | |
| | | | 关键里程碑 | 项目完成、重要功能上线 | |
| | | |
| | | 什么只记录为日常事件: |
| | | |
| | | | 类型 | 示例 | |
| | | |------|------| |
| | | | 常规查询 | 天气查询、网页搜索 | |
| | | | 临时任务 | 单次文件处理、数据分析 | |
| | | | 日常对话 | 问答、简单讨论 | |
| | | |
| | | ## 文件大小管理 |
| | | |
| | | **限制**: 4KB (4096 字节) |
| | | |
| | | **超限处理**: |
| | | 1. 首先检查是否有过期的日常事件未清理 |
| | | 2. 考虑将较早的重要事件归档到 L1 层 |
| | | 3. 与用户讨论瘦身方案 |
| | | |
| | | **瘦身策略**: |
| | | - 保留最近7天流水(已自动维护) |
| | | - 将旧的重要事件移动到 `memory/milestones/` 归档 |
| | | - 简化事件描述的详细程度 |
| | | |
| | | ## 与其他组件的关系 |
| | | |
| | | ``` |
| | | ┌─────────────────────────────────────────────────────────┐ |
| | | │ LanceDB-Pro 向量记忆 │ |
| | | │ - 存储所有详细记忆 │ |
| | | │ - 支持语义检索 │ |
| | | └────────────────────┬────────────────────────────────────┘ |
| | | │ 检索 |
| | | ▼ |
| | | ┌─────────────────────────────────────────────────────────┐ |
| | | │ MEMORY.md 热记忆 (本技能管理) │ |
| | | │ - 最近7天流水(摘要) │ |
| | | │ - 重要事件(全局影响) │ |
| | | │ - 4KB 精简索引 │ |
| | | └────────────────────┬────────────────────────────────────┘ |
| | | │ 启动注入 |
| | | ▼ |
| | | ┌─────────────────────────────────────────────────────────┐ |
| | | │ Agent 启动上下文 │ |
| | | │ - 快速了解最近发生了什么 │ |
| | | │ - 无需查询即可感知活跃记忆 │ |
| | | └─────────────────────────────────────────────────────────┘ |
| | | ``` |
| | | |
| | | ## 最佳实践 |
| | | |
| | | 1. **每日更新**: 建议设置定时任务每天执行 `update` 命令 |
| | | 2. **即时记录**: 重要事件发生后立即记录,不要累积 |
| | | 3. **简洁描述**: 一句话概要,关键词用逗号分隔 |
| | | 4. **主动告知**: 添加重要事件时必须告知用户 |
| | | 5. **定期检查**: 每周检查一次文件大小 |
| | | |
| | | ## 故障排查 |
| | | |
| | | ### 文件未更新 |
| | | - 检查脚本路径是否正确 |
| | | - 确认 `MEMORY.md` 存在且可写 |
| | | |
| | | ### 大小超限警告 |
| | | - 执行 `check-size` 确认实际大小 |
| | | - 考虑手动归档旧的重要事件 |
| | | - 与用户讨论清理策略 |
| | | |
| | | ### 日期解析错误 |
| | | - 确保日期格式为 `YYYY-MM-DD` |
| | | - 时间格式建议为 `HH:MM` 或 `--:--` |
| New file |
| | |
| | | #!/usr/bin/env python3 |
| | | """ |
| | | hot-memory 每日维护脚本 |
| | | 维护 memory.md 文件的最近7天事件流水和重要事件 |
| | | """ |
| | | |
| | | import os |
| | | import re |
| | | import sys |
| | | from datetime import datetime, timedelta |
| | | from pathlib import Path |
| | | |
| | | # 配置 |
| | | MEMORY_FILE = Path.home() / ".openclaw" / "workspace" / "MEMORY.md" |
| | | MAX_SIZE_BYTES = 4 * 1024 # 4KB 限制 |
| | | DAYS_TO_KEEP = 7 |
| | | |
| | | |
| | | def read_memory_file(): |
| | | """读取 memory.md 文件内容""" |
| | | if not MEMORY_FILE.exists(): |
| | | return "" |
| | | return MEMORY_FILE.read_text(encoding='utf-8') |
| | | |
| | | |
| | | def write_memory_file(content): |
| | | """写入 memory.md 文件""" |
| | | MEMORY_FILE.parent.mkdir(parents=True, exist_ok=True) |
| | | MEMORY_FILE.write_text(content, encoding='utf-8') |
| | | |
| | | |
| | | def get_file_size(): |
| | | """获取文件大小(字节)""" |
| | | if not MEMORY_FILE.exists(): |
| | | return 0 |
| | | return MEMORY_FILE.stat().st_size |
| | | |
| | | |
| | | def parse_date_from_line(line): |
| | | """从行中提取日期(YYYY-MM-DD 格式)""" |
| | | match = re.search(r'(\d{4}-\d{2}-\d{2})', line) |
| | | if match: |
| | | try: |
| | | return datetime.strptime(match.group(1), '%Y-%m-%d').date() |
| | | except ValueError: |
| | | return None |
| | | return None |
| | | |
| | | |
| | | def is_within_last_7_days(line): |
| | | """检查行是否在最近7天内""" |
| | | date = parse_date_from_line(line) |
| | | if not date: |
| | | return True # 无日期的行保留 |
| | | cutoff_date = (datetime.now() - timedelta(days=DAYS_TO_KEEP)).date() |
| | | return date >= cutoff_date |
| | | |
| | | |
| | | def extract_event_entries(content): |
| | | """ |
| | | 从内容中提取事件条目 |
| | | 返回: (important_events, daily_events) 元组 |
| | | """ |
| | | important_events = [] |
| | | daily_events = [] |
| | | |
| | | lines = content.split('\n') |
| | | in_important = False |
| | | in_daily = False |
| | | |
| | | for line in lines: |
| | | stripped = line.strip() |
| | | |
| | | # 检测区块 |
| | | if '重要事件' in stripped and stripped.startswith('#'): |
| | | in_important = True |
| | | in_daily = False |
| | | continue |
| | | elif ('最近7天事件流水' in stripped or '事件流水' in stripped) and stripped.startswith('#'): |
| | | in_important = False |
| | | in_daily = True |
| | | continue |
| | | elif stripped.startswith('#') and in_important: |
| | | in_important = False |
| | | elif stripped.startswith('#') and in_daily: |
| | | in_daily = False |
| | | |
| | | # 收集事件 |
| | | if in_important and stripped and not stripped.startswith('-') and not stripped.startswith('*'): |
| | | if len(stripped) > 10: # 过滤空行和短行 |
| | | important_events.append(line) |
| | | elif in_daily and (stripped.startswith('-') or stripped.startswith('*')): |
| | | if is_within_last_7_days(line): |
| | | daily_events.append(line) |
| | | |
| | | return important_events, daily_events |
| | | |
| | | |
| | | def generate_default_content(): |
| | | """生成默认的 memory.md 内容""" |
| | | today = datetime.now().strftime('%Y-%m-%d') |
| | | return f"""# MEMORY.md - 热记忆 / 活跃记忆 |
| | | |
| | | > 本文件记录近期发生的重要事情,详细信息可通过记忆检索获取。 |
| | | |
| | | --- |
| | | |
| | | ## 🔔 重要事件 |
| | | |
| | | > 记录具有全局长期性影响的重要决策和事件。 |
| | | > 添加重要事件时会告知用户。 |
| | | |
| | | <!-- 重要事件在此添加 --> |
| | | |
| | | --- |
| | | |
| | | ## 📅 最近7天事件流水 |
| | | |
| | | > 按天分组,每天主要事情的概要。 |
| | | > 自动维护,8天前的记录会被移除。 |
| | | |
| | | ### {{today}} |
| | | |
| | | - {today} 10:00 | memory.md 初始化 | 热记忆系统 |
| | | |
| | | --- |
| | | |
| | | *文件大小: ~0.5KB | 限制: 4KB* |
| | | *维护脚本: `hot-memory/scripts/daily_maintenance.py`* |
| | | """.format(today=today) |
| | | |
| | | |
| | | def update_memory_file(new_daily_events=None, important_event=None): |
| | | """ |
| | | 更新 memory.md 文件 |
| | | |
| | | Args: |
| | | new_daily_events: 新的每日事件列表 [(date, time, summary, keywords), ...] |
| | | important_event: 重要事件元组 (date, time, summary, keywords) 或 None |
| | | |
| | | Returns: |
| | | dict: 操作结果 |
| | | """ |
| | | result = { |
| | | 'success': True, |
| | | 'added_daily': 0, |
| | | 'added_important': False, |
| | | 'removed_old': 0, |
| | | 'size_warning': False, |
| | | 'current_size_kb': 0, |
| | | 'messages': [] |
| | | } |
| | | |
| | | # 读取现有内容 |
| | | content = read_memory_file() |
| | | if not content: |
| | | content = generate_default_content() |
| | | |
| | | # 提取现有事件 |
| | | existing_important, existing_daily = extract_event_entries(content) |
| | | |
| | | # 移除8天前的日常事件 |
| | | cutoff_date = (datetime.now() - timedelta(days=DAYS_TO_KEEP)).date() |
| | | filtered_daily = [] |
| | | for line in existing_daily: |
| | | date = parse_date_from_line(line) |
| | | if date and date < cutoff_date: |
| | | result['removed_old'] += 1 |
| | | else: |
| | | filtered_daily.append(line) |
| | | |
| | | # 添加新的日常事件 |
| | | if new_daily_events: |
| | | for event in new_daily_events: |
| | | date, time, summary, keywords = event |
| | | entry = f"- {date} {time} | {summary} | {keywords}" |
| | | # 检查是否已存在 |
| | | if not any(entry.strip() in existing.strip() for existing in filtered_daily): |
| | | filtered_daily.append(entry) |
| | | result['added_daily'] += 1 |
| | | |
| | | # 添加重要事件 |
| | | new_important = list(existing_important) |
| | | if important_event: |
| | | date, time, summary, keywords = important_event |
| | | entry = f"- {date} {time} | {summary} | {keywords}" |
| | | new_important.append(entry) |
| | | result['added_important'] = True |
| | | result['messages'].append(f"重要事件已记录: {summary}") |
| | | |
| | | # 重新构建文件内容 |
| | | today = datetime.now().strftime('%Y-%m-%d') |
| | | |
| | | # 按日期分组日常事件 |
| | | daily_by_date = {} |
| | | for line in filtered_daily: |
| | | date = parse_date_from_line(line) |
| | | if date: |
| | | date_str = date.strftime('%Y-%m-%d') |
| | | if date_str not in daily_by_date: |
| | | daily_by_date[date_str] = [] |
| | | daily_by_date[date_str].append(line) |
| | | |
| | | # 构建日常事件区块 |
| | | daily_sections = [] |
| | | for date_str in sorted(daily_by_date.keys(), reverse=True): |
| | | daily_sections.append(f"\n### {date_str}\n") |
| | | daily_sections.extend([f"{line}\n" for line in daily_by_date[date_str]]) |
| | | |
| | | daily_content = ''.join(daily_sections) if daily_sections else f"\n### {today}\n\n- {today} --:-- | 暂无记录 | --\n" |
| | | |
| | | # 构建重要事件区块 |
| | | important_content = '\n'.join(new_important) if new_important else "<!-- 重要事件在此添加 -->" |
| | | |
| | | # 组装最终内容 |
| | | current_size = get_file_size() |
| | | new_content = f"""# MEMORY.md - 热记忆 / 活跃记忆 |
| | | |
| | | > 本文件记录近期发生的重要事情,详细信息可通过记忆检索获取。 |
| | | |
| | | --- |
| | | |
| | | ## 🔔 重要事件 |
| | | |
| | | > 记录具有全局长期性影响的重要决策和事件。 |
| | | > 添加重要事件时会告知用户。 |
| | | |
| | | {important_content} |
| | | |
| | | --- |
| | | |
| | | ## 📅 最近7天事件流水 |
| | | |
| | | > 按天分组,每天主要事情的概要。 |
| | | > 自动维护,8天前的记录会被移除。 |
| | | {daily_content} |
| | | --- |
| | | |
| | | *文件大小: ~{current_size / 1024:.1f}KB | 限制: 4KB* |
| | | *维护脚本: `hot-memory/scripts/daily_maintenance.py`* |
| | | """ |
| | | |
| | | # 写入文件 |
| | | write_memory_file(new_content) |
| | | |
| | | # 检查文件大小 |
| | | new_size = get_file_size() |
| | | result['current_size_kb'] = round(new_size / 1024, 2) |
| | | |
| | | if new_size > MAX_SIZE_BYTES: |
| | | result['size_warning'] = True |
| | | result['messages'].append(f"警告: 文件大小 ({result['current_size_kb']}KB) 超过 4KB 限制,需要瘦身") |
| | | |
| | | return result |
| | | |
| | | |
| | | def check_size(): |
| | | """检查文件大小并返回状态""" |
| | | size = get_file_size() |
| | | return { |
| | | 'size_bytes': size, |
| | | 'size_kb': round(size / 1024, 2), |
| | | 'limit_bytes': MAX_SIZE_BYTES, |
| | | 'limit_kb': 4, |
| | | 'exceeded': size > MAX_SIZE_BYTES, |
| | | 'percentage': round((size / MAX_SIZE_BYTES) * 100, 1) |
| | | } |
| | | |
| | | |
| | | def main(): |
| | | """主函数 - 供命令行调用""" |
| | | if len(sys.argv) < 2: |
| | | print("用法: python daily_maintenance.py <command> [args]") |
| | | print("") |
| | | print("命令:") |
| | | print(" update - 执行每日更新") |
| | | print(" check-size - 检查文件大小") |
| | | print(" add-daily <date> <time> <summary> <keywords>") |
| | | print(" - 添加日常事件") |
| | | print(" add-important <date> <time> <summary> <keywords>") |
| | | print(" - 添加重要事件") |
| | | print("") |
| | | print("示例:") |
| | | print(' python daily_maintenance.py add-daily 2026-03-16 "10:30" "测试脚本" "开发,测试"') |
| | | sys.exit(1) |
| | | |
| | | command = sys.argv[1] |
| | | |
| | | if command == "update": |
| | | result = update_memory_file() |
| | | print(f"更新完成:") |
| | | print(f" - 添加日常事件: {result['added_daily']}") |
| | | print(f" - 移除旧事件: {result['removed_old']}") |
| | | print(f" - 添加重要事件: {'是' if result['added_important'] else '否'}") |
| | | print(f" - 当前大小: {result['current_size_kb']}KB") |
| | | for msg in result['messages']: |
| | | print(f" - {msg}") |
| | | |
| | | elif command == "check-size": |
| | | status = check_size() |
| | | print(f"文件大小检查:") |
| | | print(f" - 当前: {status['size_kb']}KB ({status['percentage']}%)") |
| | | print(f" - 限制: {status['limit_kb']}KB") |
| | | print(f" - 状态: {'⚠️ 超限' if status['exceeded'] else '✅ 正常'}") |
| | | |
| | | elif command == "add-daily" and len(sys.argv) >= 6: |
| | | event = (sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5]) |
| | | result = update_memory_file(new_daily_events=[event]) |
| | | print(f"已添加日常事件: {event}") |
| | | if result['size_warning']: |
| | | print(f"⚠️ 警告: 文件大小 {result['current_size_kb']}KB 超过限制") |
| | | |
| | | elif command == "add-important" and len(sys.argv) >= 6: |
| | | event = (sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5]) |
| | | result = update_memory_file(important_event=event) |
| | | print(f"已添加重要事件: {event}") |
| | | print(f"ℹ️ 请知悉用户: 已记录重要事件 '{sys.argv[4]}'") |
| | | if result['size_warning']: |
| | | print(f"⚠️ 警告: 文件大小 {result['current_size_kb']}KB 超过限制") |
| | | |
| | | else: |
| | | print(f"未知命令或参数不足: {command}") |
| | | sys.exit(1) |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | main() |