From 0878535cb875fb34e4ff2ea3442fee142d0955ab Mon Sep 17 00:00:00 2001 From: starmen1265 Date: Thu, 5 Mar 2026 19:20:35 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20Capability=20Evolver=20=E5=8D=87?= =?UTF-8?q?=E7=BA=A7=20+=20=E6=97=A5=E5=B8=B8=E8=BF=90=E8=A1=8C=E6=97=A5?= =?UTF-8?q?=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 主要变更: - Capability Evolver 技能大幅升级 - 新增 LLM 审查、叙事记忆、反思机制模块 - 改进 Agent 间通信协议和技能搜索 - 整合 Git 备份到 evolver-run.sh - Agent 配置与日志更新 - dev-assist/haonan/main 认证和会话配置 - 5 个 agent 的 AGENTS.md 文档更新 - haonan 的 MEMORY.md 和 SOUL.md 更新 - 新增功能目录 - hooks/self-improvement 自我改进钩子 - memory/evolution 进化记忆状态 - workspace/.learnings/ 学习记录 - 清理 - 删除 scripts/git-auto-sync.sh(已整合到 evolver) - 删除旧的 _meta.json 配置 - 忽略临时工作空间目录 --- .gitignore | 4 + agents/dev-assist/sessions/sessions.json | 81 +- agents/dev-assist/workspace/AGENTS.md | 61 + agents/dev-assist/workspace/TODO.md | 20 - agents/haonan/agent/auth-profiles.json | 8 +- agents/haonan/sessions/sessions.json | 1116 ++++++++++++++++- agents/haonan/workspace/AGENTS.md | 61 + agents/haonan/workspace/MEMORY.md | 54 +- agents/haonan/workspace/SOUL.md | 48 - agents/haonan/workspace/memory/2026-03-04.md | 18 + agents/knowledge-base/workspace/AGENTS.md | 61 + .../knowledge-base/videos/BV1QjcszrEEV.md | 16 - .../workspace/memory/2026-03-03.md | 38 +- .../workspace/memory/2026-03-05.md | 54 + agents/main/agent/auth-profiles.json | 8 +- agents/thinker/workspace/AGENTS.md | 61 + agents/ui-designer/workspace/AGENTS.md | 61 + cron/jobs.json | 70 +- cron/jobs.json.bak | 70 +- devices/paired.json | 9 +- hooks/self-improvement/HOOK.md | 23 + hooks/self-improvement/handler.js | 56 + hooks/self-improvement/handler.ts | 62 + identity/device-auth.json | 2 +- .../d43f43ec-4953-42e2-a550-8b2474b9939b.jpg | Bin 0 -> 96049 bytes .../evolution/evolution_solidify_state.json | 66 + ..._prompt_Cycle_#0001_run_1772551119186.json | 15 + ...p_prompt_Cycle_#0001_run_1772551119186.txt | 507 ++++++++ memory/evolution/memory_graph_state.json | 48 + memory/evolution/personality_state.json | 14 + openclaw.json | 14 +- openclaw.json.bak | 67 +- openclaw.json.bak.1 | 118 +- openclaw.json.bak.2 | 4 +- openclaw.json.bak.3 | 4 +- openclaw.json.bak.4 | 4 +- scripts/evolver-output.txt | 101 +- scripts/evolver-run.sh | 27 +- scripts/git-auto-sync.sh | 17 - skills/capability-evolver/.gitignore | 14 + skills/capability-evolver/LICENSE | 22 + skills/capability-evolver/README.md | 11 +- skills/capability-evolver/README.zh-CN.md | 14 +- skills/capability-evolver/_meta.json | 17 - skills/capability-evolver/assets/cover.png | Bin 0 -> 127630 bytes .../assets/gep/failed_capsules.json | 4 + skills/capability-evolver/index.js | 96 +- skills/capability-evolver/package.json | 2 +- skills/capability-evolver/src/evolve.js | 60 + skills/capability-evolver/src/gep/a2a.js | 4 +- .../capability-evolver/src/gep/a2aProtocol.js | 20 +- .../src/gep/assetCallLog.js | 130 ++ .../capability-evolver/src/gep/hubSearch.js | 117 +- .../capability-evolver/src/gep/llmReview.js | 86 ++ .../src/gep/narrativeMemory.js | 108 ++ skills/capability-evolver/src/gep/paths.js | 21 +- skills/capability-evolver/src/gep/prompt.js | 35 +- .../capability-evolver/src/gep/reflection.js | 127 ++ skills/capability-evolver/src/gep/selector.js | 12 +- skills/capability-evolver/src/gep/signals.js | 4 +- .../src/gep/skillDistiller.js | 2 +- skills/capability-evolver/src/gep/solidify.js | 101 +- .../src/gep/taskReceiver.js | 5 +- skills/capability-evolver/src/ops/cleanup.js | 57 +- workspace/.learnings/ERRORS.md | 49 + workspace/.learnings/FEATURE_REQUESTS.md | 44 + workspace/.learnings/LEARNINGS.md | 45 + 67 files changed, 3762 insertions(+), 513 deletions(-) delete mode 100644 agents/dev-assist/workspace/TODO.md create mode 100644 agents/haonan/workspace/memory/2026-03-04.md delete mode 100644 agents/knowledge-base/workspace/knowledge-base/videos/BV1QjcszrEEV.md create mode 100644 agents/knowledge-base/workspace/memory/2026-03-05.md create mode 100644 hooks/self-improvement/HOOK.md create mode 100644 hooks/self-improvement/handler.js create mode 100644 hooks/self-improvement/handler.ts create mode 100644 media/inbound/d43f43ec-4953-42e2-a550-8b2474b9939b.jpg create mode 100644 memory/evolution/evolution_solidify_state.json create mode 100644 memory/evolution/gep_prompt_Cycle_#0001_run_1772551119186.json create mode 100644 memory/evolution/gep_prompt_Cycle_#0001_run_1772551119186.txt create mode 100644 memory/evolution/memory_graph_state.json create mode 100644 memory/evolution/personality_state.json delete mode 100755 scripts/git-auto-sync.sh create mode 100644 skills/capability-evolver/.gitignore create mode 100644 skills/capability-evolver/LICENSE delete mode 100644 skills/capability-evolver/_meta.json create mode 100644 skills/capability-evolver/assets/cover.png create mode 100644 skills/capability-evolver/assets/gep/failed_capsules.json mode change 100755 => 100644 skills/capability-evolver/index.js create mode 100644 skills/capability-evolver/src/gep/assetCallLog.js create mode 100644 skills/capability-evolver/src/gep/llmReview.js create mode 100644 skills/capability-evolver/src/gep/narrativeMemory.js create mode 100644 skills/capability-evolver/src/gep/reflection.js create mode 100644 workspace/.learnings/ERRORS.md create mode 100644 workspace/.learnings/FEATURE_REQUESTS.md create mode 100644 workspace/.learnings/LEARNINGS.md diff --git a/.gitignore b/.gitignore index 3672d7b..a7423f6 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,7 @@ logs/git-sync.log update-check.json *.jsonl *.lock + +# Workspace copies +workspace-dev-assist/ +workspace-knowledge-base/ diff --git a/agents/dev-assist/sessions/sessions.json b/agents/dev-assist/sessions/sessions.json index 61130ea..744bd4c 100644 --- a/agents/dev-assist/sessions/sessions.json +++ b/agents/dev-assist/sessions/sessions.json @@ -347,8 +347,8 @@ "memoryFlushCompactionCount": 0 }, "agent:dev-assist:main": { - "sessionId": "da8f811d-332e-4695-ab12-c12dc48abad3", - "updatedAt": 1772388420747, + "sessionId": "b7584411-c07d-4e44-b96b-72b32750f8af", + "updatedAt": 1772688969697, "systemSent": true, "abortedLastRun": false, "chatType": "direct", @@ -369,16 +369,27 @@ "to": "user:ou_302b162eb824d405718845441a32d9cf", "accountId": "feishu-dev" }, - "sessionFile": "/home/starmen1265/.openclaw/agents/dev-assist/sessions/da8f811d-332e-4695-ab12-c12dc48abad3.jsonl", + "sessionFile": "/home/starmen1265/.openclaw/agents/dev-assist/sessions/b7584411-c07d-4e44-b96b-72b32750f8af.jsonl", "compactionCount": 0, "skillsSnapshot": { - "prompt": "\n\nThe following skills provide specialized instructions for specific tasks.\nUse the read tool to load a skill's file when the task matches its description.\nWhen a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.\n\n\n \n clawlist\n MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.\n /home/starmen1265/.openclaw/skills/clawlist/SKILL.md\n \n", + "prompt": "\n\nThe following skills provide specialized instructions for specific tasks.\nUse the read tool to load a skill's file when the task matches its description.\nWhen a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.\n\n\n \n capability-evolver\n A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.\n /home/starmen1265/.openclaw/skills/capability-evolver/SKILL.md\n \n \n clawlist\n MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.\n /home/starmen1265/.openclaw/skills/clawlist/SKILL.md\n \n", "skills": [ + { + "name": "capability-evolver" + }, { "name": "clawlist" } ], "resolvedSkills": [ + { + "name": "capability-evolver", + "description": "A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.", + "filePath": "/home/starmen1265/.openclaw/skills/capability-evolver/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/capability-evolver", + "source": "openclaw-managed", + "disableModelInvocation": false + }, { "name": "clawlist", "description": "MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.", @@ -394,26 +405,26 @@ "model": "glm-5", "systemPromptReport": { "source": "run", - "generatedAt": 1772388345577, - "sessionId": "da8f811d-332e-4695-ab12-c12dc48abad3", + "generatedAt": 1772688958464, + "sessionId": "b7584411-c07d-4e44-b96b-72b32750f8af", "sessionKey": "agent:dev-assist:main", "provider": "zhipu", "model": "glm-5", - "workspaceDir": "/home/starmen1265/.openclaw/agents/dev-assist/workspace", + "workspaceDir": "/home/starmen1265/.openclaw/workspace-dev-assist", "bootstrapMaxChars": 20000, "sandbox": { "mode": "off", "sandboxed": false }, "systemPrompt": { - "chars": 23820, - "projectContextChars": 13850, - "nonProjectContextChars": 9970 + "chars": 24288, + "projectContextChars": 13995, + "nonProjectContextChars": 10293 }, "injectedWorkspaceFiles": [ { "name": "AGENTS.md", - "path": "/home/starmen1265/.openclaw/agents/dev-assist/workspace/AGENTS.md", + "path": "/home/starmen1265/.openclaw/workspace-dev-assist/AGENTS.md", "missing": false, "rawChars": 7804, "injectedChars": 7804, @@ -421,15 +432,15 @@ }, { "name": "SOUL.md", - "path": "/home/starmen1265/.openclaw/agents/dev-assist/workspace/SOUL.md", + "path": "/home/starmen1265/.openclaw/workspace-dev-assist/SOUL.md", "missing": false, - "rawChars": 2619, - "injectedChars": 2619, + "rawChars": 1664, + "injectedChars": 1664, "truncated": false }, { "name": "TOOLS.md", - "path": "/home/starmen1265/.openclaw/agents/dev-assist/workspace/TOOLS.md", + "path": "/home/starmen1265/.openclaw/workspace-dev-assist/TOOLS.md", "missing": false, "rawChars": 850, "injectedChars": 850, @@ -437,23 +448,23 @@ }, { "name": "IDENTITY.md", - "path": "/home/starmen1265/.openclaw/agents/dev-assist/workspace/IDENTITY.md", + "path": "/home/starmen1265/.openclaw/workspace-dev-assist/IDENTITY.md", "missing": false, - "rawChars": 221, - "injectedChars": 221, + "rawChars": 633, + "injectedChars": 633, "truncated": false }, { "name": "USER.md", - "path": "/home/starmen1265/.openclaw/agents/dev-assist/workspace/USER.md", + "path": "/home/starmen1265/.openclaw/workspace-dev-assist/USER.md", "missing": false, - "rawChars": 173, - "injectedChars": 173, + "rawChars": 474, + "injectedChars": 474, "truncated": false }, { "name": "HEARTBEAT.md", - "path": "/home/starmen1265/.openclaw/agents/dev-assist/workspace/HEARTBEAT.md", + "path": "/home/starmen1265/.openclaw/workspace-dev-assist/HEARTBEAT.md", "missing": false, "rawChars": 167, "injectedChars": 167, @@ -461,24 +472,26 @@ }, { "name": "BOOTSTRAP.md", - "path": "/home/starmen1265/.openclaw/agents/dev-assist/workspace/BOOTSTRAP.md", + "path": "/home/starmen1265/.openclaw/workspace-dev-assist/BOOTSTRAP.md", "missing": false, "rawChars": 1449, "injectedChars": 1449, "truncated": false }, { - "name": "MEMORY.md", - "path": "/home/starmen1265/.openclaw/agents/dev-assist/workspace/MEMORY.md", - "missing": false, - "rawChars": 229, - "injectedChars": 229, + "path": "SELF_IMPROVEMENT_REMINDER.md", + "rawChars": 616, + "injectedChars": 616, "truncated": false } ], "skills": { - "promptChars": 728, + "promptChars": 1037, "entries": [ + { + "name": "capability-evolver", + "blockChars": 306 + }, { "name": "clawlist", "blockChars": 359 @@ -648,11 +661,9 @@ ] } }, - "inputTokens": 31031, - "outputTokens": 2064, - "totalTokens": 200000, - "contextTokens": 200000, - "memoryFlushAt": 1772377559686, - "memoryFlushCompactionCount": 0 + "inputTokens": 11051, + "outputTokens": 250, + "totalTokens": 17323, + "contextTokens": 200000 } } \ No newline at end of file diff --git a/agents/dev-assist/workspace/AGENTS.md b/agents/dev-assist/workspace/AGENTS.md index 887a5a8..4f0e03a 100644 --- a/agents/dev-assist/workspace/AGENTS.md +++ b/agents/dev-assist/workspace/AGENTS.md @@ -2,6 +2,67 @@ This folder is home. Treat it that way. +--- + +## ⚠️ 工作规范(必须遵守) + +### 安全规则(最高优先级) + +| 规则 | 说明 | +|------|------| +| **禁止擅自修改 openclaw.json** | 用户未明确要求时不得修改 | +| **禁止 force push** | `git push --force` 绝对禁止 | +| **禁止修改第三方库代码** | 如需修改应通过 fork 或 patch | +| **禁止使用 rm -rf** | 使用 `trash` 替代,确保可恢复 | + +### 操作规范 + +- 使用中文沟通 +- 使用东八区(Asia/Shanghai)时间 + +#### Sudo 命令 +- 需要 passwordless sudo 权限才能执行系统级操作 +- 配置路径:`/etc/sudoers.d/nopasswd` +- 配置后验证:`sudo visudo -c` + +#### 子代理使用 +1. **代码开发和耗时操作必须交给子代理处理** +2. **汇报机制** + - 子代理开始工作时,立刻汇报:「已安排代理处理 [任务]」 + - 每 5 分钟查询子代理状态,汇总后简报给用户 + +#### 技能使用 +- 使用技能过程中,遇到流程外的问题需在结果中明确汇报具体问题 + +#### 定时任务 +- 所有定时任务通过 **OpenClaw Gateway 内置 Cron** 管理 +- 不使用系统级 crontab +- 相关脚本统一存放:`~/work/backup/` + +### 环境说明 + +| 项目 | 值 | +|------|-----| +| 本机 IP | 192.168.1.36 | +| 网关 | 192.168.1.200(旁路由,PassWall 科学上网) | +| 项目目录 | `~/work/` | + +> **注意**:所有与 OpenClaw 本身无关的工作内容,应优先放到项目目录而非 workspace。 + +#### 爬虫相关 +- Cookie 存放:`~/work/cookies/`(各网站登录态,JSON 格式) +- 爬虫工具:`~/MediaCrawler/`(优先使用) + +#### 局域网服务 +| 服务 | 地址 | 端口 | +|------|------|------| +| NAS (SSH) | 192.168.1.22 | 2222 | +| Gitea (SSH) | 192.168.1.22 | 2223 | +| Gitea (Web) | 192.168.1.22 | 8418 | +| NAS WebDAV | 192.168.1.22 | 5005 | + +--- + ## First Run If `BOOTSTRAP.md` exists, that's your birth certificate. Follow it, figure out who you are, then delete it. You won't need it again. diff --git a/agents/dev-assist/workspace/TODO.md b/agents/dev-assist/workspace/TODO.md deleted file mode 100644 index ddd7d0a..0000000 --- a/agents/dev-assist/workspace/TODO.md +++ /dev/null @@ -1,20 +0,0 @@ -# TODO.md - 待办事项 - -## 进行中 - -(无) - -## 待处理 - -1. 开发 kb-workflow 系列技能对 Bilibili 专栏文章的支持 -2. 开发 kb-workflow 系列技能对知乎文章的支持 -3. 开发 kb-workflow 系列技能对 YouTube 的支持 -4. 修改 kb-web 不能查看知识库子目录的 bug - -## 已完成 - -1. ✅ 开发 kb-web + knowledge-base 的自动化测试与部署流程 - - kb-web CI/CD:feature 分支 → 测试环境 → 测试 → 合并 main → 手动部署正式环境 - - knowledge-base CI/CD:全量部署到用户目录 - - 需求与设计文档:docs/requirements.md - - 元数据展示优化(标签、作者、平台、源链接) diff --git a/agents/haonan/agent/auth-profiles.json b/agents/haonan/agent/auth-profiles.json index 3047849..2ba6ddb 100644 --- a/agents/haonan/agent/auth-profiles.json +++ b/agents/haonan/agent/auth-profiles.json @@ -13,8 +13,12 @@ "usageStats": { "kimi-coding:default": { "lastUsed": 1771174998413, - "errorCount": 0, - "lastFailureAt": 1770827754238 + "errorCount": 1, + "lastFailureAt": 1772636016969, + "failureCounts": { + "timeout": 1 + }, + "cooldownUntil": 1772636076969 } } } diff --git a/agents/haonan/sessions/sessions.json b/agents/haonan/sessions/sessions.json index c1b63bc..ff76dd7 100644 --- a/agents/haonan/sessions/sessions.json +++ b/agents/haonan/sessions/sessions.json @@ -1,13 +1,26 @@ { "agent:haonan:main": { - "sessionId": "424f34e7-c7ca-4812-8b7c-0430fa82f0a1", - "updatedAt": 1772550677322, + "sessionId": "1c46ae16-9382-4865-ac7a-6bdb8ec1400d", + "updatedAt": 1772709574839, "systemSent": true, "skillsSnapshot": { - "prompt": "", - "skills": [], - "resolvedSkills": [], - "version": 1772550218581 + "prompt": "\n\nThe following skills provide specialized instructions for specific tasks.\nUse the read tool to load a skill's file when the task matches its description.\nWhen a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.\n\n\n \n capability-evolver\n A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.\n /home/starmen1265/.openclaw/skills/capability-evolver/SKILL.md\n \n", + "skills": [ + { + "name": "capability-evolver" + } + ], + "resolvedSkills": [ + { + "name": "capability-evolver", + "description": "A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.", + "filePath": "/home/starmen1265/.openclaw/skills/capability-evolver/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/capability-evolver", + "source": "openclaw-managed", + "disableModelInvocation": false + } + ], + "version": 0 }, "deliveryContext": { "channel": "feishu", @@ -17,58 +30,63 @@ "lastChannel": "feishu", "lastTo": "user:ou_be83febac9ee2afaa343c642bc697c48", "lastAccountId": "feishu-pm", - "modelProvider": "mm", - "model": "MiniMax-M2.5", + "channel": "feishu", + "modelProvider": "zhipu", + "model": "glm-5", + "contextTokens": 200000, "abortedLastRun": false, + "inputTokens": 3497, + "outputTokens": 691, + "totalTokens": 35497, "chatType": "direct", "origin": { "label": "张青", "provider": "feishu", - "surface": "feishu", - "chatType": "direct", "from": "feishu:ou_be83febac9ee2afaa343c642bc697c48", "to": "user:ou_be83febac9ee2afaa343c642bc697c48", + "surface": "feishu", + "chatType": "direct", "accountId": "feishu-pm" }, - "sessionFile": "/home/starmen1265/.openclaw/agents/haonan/sessions/424f34e7-c7ca-4812-8b7c-0430fa82f0a1.jsonl", + "sessionFile": "/home/starmen1265/.openclaw/agents/haonan/sessions/1c46ae16-9382-4865-ac7a-6bdb8ec1400d.jsonl", "systemPromptReport": { "source": "run", - "generatedAt": 1772550534184, - "sessionId": "424f34e7-c7ca-4812-8b7c-0430fa82f0a1", + "generatedAt": 1772709390101, + "sessionId": "1c46ae16-9382-4865-ac7a-6bdb8ec1400d", "sessionKey": "agent:haonan:main", - "provider": "mm", - "model": "MiniMax-M2.5", - "workspaceDir": "/home/starmen1265/.openclaw/agents/haonan/workspace", + "provider": "zhipu", + "model": "glm-5", + "workspaceDir": "/home/starmen1265/.openclaw/workspace", "bootstrapMaxChars": 20000, "sandbox": { "mode": "off", "sandboxed": false }, "systemPrompt": { - "chars": 25880, - "projectContextChars": 16878, - "nonProjectContextChars": 9002 + "chars": 23655, + "projectContextChars": 13602, + "nonProjectContextChars": 10053 }, "injectedWorkspaceFiles": [ { "name": "AGENTS.md", - "path": "/home/starmen1265/.openclaw/agents/haonan/workspace/AGENTS.md", + "path": "/home/starmen1265/.openclaw/workspace/AGENTS.md", "missing": false, - "rawChars": 9506, - "injectedChars": 9506, + "rawChars": 7804, + "injectedChars": 7804, "truncated": false }, { "name": "SOUL.md", - "path": "/home/starmen1265/.openclaw/agents/haonan/workspace/SOUL.md", + "path": "/home/starmen1265/.openclaw/workspace/SOUL.md", "missing": false, - "rawChars": 2115, - "injectedChars": 2115, + "rawChars": 1664, + "injectedChars": 1664, "truncated": false }, { "name": "TOOLS.md", - "path": "/home/starmen1265/.openclaw/agents/haonan/workspace/TOOLS.md", + "path": "/home/starmen1265/.openclaw/workspace/TOOLS.md", "missing": false, "rawChars": 850, "injectedChars": 850, @@ -76,23 +94,23 @@ }, { "name": "IDENTITY.md", - "path": "/home/starmen1265/.openclaw/agents/haonan/workspace/IDENTITY.md", + "path": "/home/starmen1265/.openclaw/workspace/IDENTITY.md", "missing": false, - "rawChars": 152, - "injectedChars": 152, + "rawChars": 240, + "injectedChars": 240, "truncated": false }, { "name": "USER.md", - "path": "/home/starmen1265/.openclaw/agents/haonan/workspace/USER.md", + "path": "/home/starmen1265/.openclaw/workspace/USER.md", "missing": false, - "rawChars": 196, - "injectedChars": 196, + "rawChars": 474, + "injectedChars": 474, "truncated": false }, { "name": "HEARTBEAT.md", - "path": "/home/starmen1265/.openclaw/agents/haonan/workspace/HEARTBEAT.md", + "path": "/home/starmen1265/.openclaw/workspace/HEARTBEAT.md", "missing": false, "rawChars": 167, "injectedChars": 167, @@ -100,24 +118,27 @@ }, { "name": "BOOTSTRAP.md", - "path": "/home/starmen1265/.openclaw/agents/haonan/workspace/BOOTSTRAP.md", + "path": "/home/starmen1265/.openclaw/workspace/BOOTSTRAP.md", "missing": false, "rawChars": 1449, "injectedChars": 1449, "truncated": false }, { - "name": "MEMORY.md", - "path": "/home/starmen1265/.openclaw/agents/haonan/workspace/MEMORY.md", - "missing": false, - "rawChars": 2105, - "injectedChars": 2105, + "path": "SELF_IMPROVEMENT_REMINDER.md", + "rawChars": 616, + "injectedChars": 616, "truncated": false } ], "skills": { - "promptChars": 0, - "entries": [] + "promptChars": 675, + "entries": [ + { + "name": "capability-evolver", + "blockChars": 306 + } + ] }, "tools": { "listChars": 2378, @@ -282,15 +303,8 @@ ] } }, - "lastHeartbeatText": "蒋先生,OpenClaw 配置的定时备份已成功完成 ✅\n\n备份文件:`openclaw.json.2026-03-03_03-00-11`", - "lastHeartbeatSentAt": 1772478022807, - "compactionCount": 0, - "inputTokens": 32, - "outputTokens": 279, - "totalTokens": 42792, - "contextTokens": 200000, - "memoryFlushAt": 1772550355815, - "memoryFlushCompactionCount": 0 + "lastHeartbeatText": "定时任务跑完了,给你同步一下:\n\n✅ 已创建备份分支 `backup/evolver-20260305-190024`\n📊 检测到 44 项待提交的变更(agent 配置、cron 配置、技能模块更新等)\n⚠️ 完整进化模式需要先配置 .env 才能启用\n\n要不要我帮你看看这些变更,整理一下然后提交?", + "lastHeartbeatSentAt": 1772708684427 }, "agent:haonan:wecom:dm:zhangqing": { "origin": { @@ -621,10 +635,10 @@ "memoryFlushCompactionCount": 0 }, "agent:haonan:cron:41396aeb-6e3a-47b2-9bd3-9156a348c1dc": { - "sessionId": "8bef314d-e731-48ca-82dd-0b96a60b56c5", - "updatedAt": 1772478000038, + "sessionId": "32265b5b-b838-47f2-980b-d2a0c72af649", + "updatedAt": 1772650800022, "systemSent": true, - "model": "MiniMax-M2.5", + "model": "glm-5", "contextTokens": 200000, "label": "Cron: backup-openclaw-json", "skillsSnapshot": { @@ -800,10 +814,10 @@ ], "version": 0 }, - "modelProvider": "mm", - "inputTokens": 317, - "outputTokens": 178, - "totalTokens": 31425 + "modelProvider": "zhipu", + "inputTokens": 8331, + "outputTokens": 290, + "totalTokens": 29003 }, "agent:haonan:cron:41396aeb-6e3a-47b2-9bd3-9156a348c1dc:run:ee89a8ee-836b-40e4-9e4d-4a6a19e493c6": { "sessionId": "ee89a8ee-836b-40e4-9e4d-4a6a19e493c6", @@ -1359,5 +1373,993 @@ "inputTokens": 317, "outputTokens": 178, "totalTokens": 31425 + }, + "agent:haonan:cron:41396aeb-6e3a-47b2-9bd3-9156a348c1dc:run:1e56e128-1d42-45a4-b097-bd38f253c6cf": { + "sessionId": "1e56e128-1d42-45a4-b097-bd38f253c6cf", + "updatedAt": 1772564400042, + "systemSent": true, + "model": "MiniMax-M2.5", + "contextTokens": 200000, + "label": "Cron: backup-openclaw-json", + "skillsSnapshot": { + "prompt": "\n\nThe following skills provide specialized instructions for specific tasks.\nUse the read tool to load a skill's file when the task matches its description.\nWhen a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.\n\n\n \n feishu-doc\n Feishu document read/write operations. Activate when user mentions Feishu docs, cloud docs, or docx links.\n\n /home/starmen1265/.openclaw/extensions/feishu/skills/feishu-doc/SKILL.md\n \n \n feishu-drive\n Feishu cloud storage file management. Activate when user mentions cloud space, folders, drive.\n\n /home/starmen1265/.openclaw/extensions/feishu/skills/feishu-drive/SKILL.md\n \n \n feishu-perm\n Feishu permission management for documents and files. Activate when user mentions sharing, permissions, collaborators.\n\n /home/starmen1265/.openclaw/extensions/feishu/skills/feishu-perm/SKILL.md\n \n \n feishu-wiki\n Feishu knowledge base navigation. Activate when user mentions knowledge base, wiki, or wiki links.\n\n /home/starmen1265/.openclaw/extensions/feishu/skills/feishu-wiki/SKILL.md\n \n \n healthcheck\n Host security hardening and risk-tolerance configuration for OpenClaw deployments. Use when a user asks for security audits, firewall/SSH/update hardening, risk posture, exposure review, OpenClaw cron scheduling for periodic checks, or version status checks on a machine running OpenClaw (laptop, workstation, Pi, VPS).\n /home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/healthcheck/SKILL.md\n \n \n skill-creator\n Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.\n /home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/skill-creator/SKILL.md\n \n \n video-frames\n Extract frames or short clips from videos using ffmpeg.\n /home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/video-frames/SKILL.md\n \n \n weather\n Get current weather and forecasts (no API key required).\n /home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/weather/SKILL.md\n \n \n clawlist\n MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.\n /home/starmen1265/.openclaw/skills/clawlist/SKILL.md\n \n \n brainstorming\n MUST use before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.\n /home/starmen1265/.openclaw/skills/clawlist/brainstorming/SKILL.md\n \n \n dispatch-multiple-agents\n Use when facing 2+ independent tasks that can be worked on without shared state or sequential dependencies. Dispatch subagents to work concurrently.\n /home/starmen1265/.openclaw/skills/clawlist/dispatch-multiple-agents/SKILL.md\n \n \n doing-tasks\n Use when executing any task. Work through plans systematically, tracking progress, handling blockers, and coordinating with other skills. The central execution skill.\n /home/starmen1265/.openclaw/skills/clawlist/doing-tasks/SKILL.md\n \n \n verify-task\n MUST use after completing any multi-step task or project. Verifies completion against the original plan, checks quality criteria, and documents outcomes.\n /home/starmen1265/.openclaw/skills/clawlist/verify-task/SKILL.md\n \n \n write-plan\n MUST use after brainstorming and before executing. Creates detailed implementation plans with checkpoints, verification criteria, and execution options.\n /home/starmen1265/.openclaw/skills/clawlist/write-plan/SKILL.md\n \n \n find-skills\n Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.\n /home/starmen1265/.openclaw/skills/find-skills/SKILL.md\n \n", + "skills": [ + { + "name": "feishu-doc" + }, + { + "name": "feishu-drive" + }, + { + "name": "feishu-perm" + }, + { + "name": "feishu-wiki" + }, + { + "name": "healthcheck" + }, + { + "name": "skill-creator" + }, + { + "name": "video-frames" + }, + { + "name": "weather" + }, + { + "name": "clawlist" + }, + { + "name": "brainstorming" + }, + { + "name": "dispatch-multiple-agents" + }, + { + "name": "doing-tasks" + }, + { + "name": "verify-task" + }, + { + "name": "write-plan" + }, + { + "name": "find-skills" + } + ], + "resolvedSkills": [ + { + "name": "feishu-doc", + "description": "Feishu document read/write operations. Activate when user mentions Feishu docs, cloud docs, or docx links.\n", + "filePath": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-doc/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-doc", + "source": "openclaw-extra", + "disableModelInvocation": false + }, + { + "name": "feishu-drive", + "description": "Feishu cloud storage file management. Activate when user mentions cloud space, folders, drive.\n", + "filePath": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-drive/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-drive", + "source": "openclaw-extra", + "disableModelInvocation": false + }, + { + "name": "feishu-perm", + "description": "Feishu permission management for documents and files. Activate when user mentions sharing, permissions, collaborators.\n", + "filePath": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-perm/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-perm", + "source": "openclaw-extra", + "disableModelInvocation": false + }, + { + "name": "feishu-wiki", + "description": "Feishu knowledge base navigation. Activate when user mentions knowledge base, wiki, or wiki links.\n", + "filePath": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-wiki/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-wiki", + "source": "openclaw-extra", + "disableModelInvocation": false + }, + { + "name": "healthcheck", + "description": "Host security hardening and risk-tolerance configuration for OpenClaw deployments. Use when a user asks for security audits, firewall/SSH/update hardening, risk posture, exposure review, OpenClaw cron scheduling for periodic checks, or version status checks on a machine running OpenClaw (laptop, workstation, Pi, VPS).", + "filePath": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/healthcheck/SKILL.md", + "baseDir": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/healthcheck", + "source": "openclaw-bundled", + "disableModelInvocation": false + }, + { + "name": "skill-creator", + "description": "Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.", + "filePath": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/skill-creator/SKILL.md", + "baseDir": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/skill-creator", + "source": "openclaw-bundled", + "disableModelInvocation": false + }, + { + "name": "video-frames", + "description": "Extract frames or short clips from videos using ffmpeg.", + "filePath": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/video-frames/SKILL.md", + "baseDir": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/video-frames", + "source": "openclaw-bundled", + "disableModelInvocation": false + }, + { + "name": "weather", + "description": "Get current weather and forecasts (no API key required).", + "filePath": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/weather/SKILL.md", + "baseDir": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/weather", + "source": "openclaw-bundled", + "disableModelInvocation": false + }, + { + "name": "clawlist", + "description": "MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "brainstorming", + "description": "MUST use before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/brainstorming/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/brainstorming", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "dispatch-multiple-agents", + "description": "Use when facing 2+ independent tasks that can be worked on without shared state or sequential dependencies. Dispatch subagents to work concurrently.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/dispatch-multiple-agents/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/dispatch-multiple-agents", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "doing-tasks", + "description": "Use when executing any task. Work through plans systematically, tracking progress, handling blockers, and coordinating with other skills. The central execution skill.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/doing-tasks/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/doing-tasks", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "verify-task", + "description": "MUST use after completing any multi-step task or project. Verifies completion against the original plan, checks quality criteria, and documents outcomes.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/verify-task/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/verify-task", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "write-plan", + "description": "MUST use after brainstorming and before executing. Creates detailed implementation plans with checkpoints, verification criteria, and execution options.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/write-plan/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/write-plan", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "find-skills", + "description": "Helps users discover and install agent skills when they ask questions like \"how do I do X\", \"find a skill for X\", \"is there a skill that can...\", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.", + "filePath": "/home/starmen1265/.openclaw/skills/find-skills/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/find-skills", + "source": "openclaw-managed", + "disableModelInvocation": false + } + ], + "version": 0 + }, + "modelProvider": "mm", + "inputTokens": 878, + "outputTokens": 220, + "totalTokens": 43515 + }, + "agent:haonan:cron:f03b184f-5f1d-4093-ae1b-fc9fe0b59eef": { + "sessionId": "a604e4f3-5de4-4e81-bb9f-ebc25b5fbc1a", + "updatedAt": 1772708400038, + "systemSent": true, + "model": "glm-4.7-FlashX", + "contextTokens": 200000, + "label": "Cron: capability-evolver-daily", + "skillsSnapshot": { + "prompt": "\n\nThe following skills provide specialized instructions for specific tasks.\nUse the read tool to load a skill's file when the task matches its description.\nWhen a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.\n\n\n \n feishu-doc\n Feishu document read/write operations. Activate when user mentions Feishu docs, cloud docs, or docx links.\n\n /home/starmen1265/.openclaw/extensions/feishu/skills/feishu-doc/SKILL.md\n \n \n feishu-drive\n Feishu cloud storage file management. Activate when user mentions cloud space, folders, drive.\n\n /home/starmen1265/.openclaw/extensions/feishu/skills/feishu-drive/SKILL.md\n \n \n feishu-perm\n Feishu permission management for documents and files. Activate when user mentions sharing, permissions, collaborators.\n\n /home/starmen1265/.openclaw/extensions/feishu/skills/feishu-perm/SKILL.md\n \n \n feishu-wiki\n Feishu knowledge base navigation. Activate when user mentions knowledge base, wiki, or wiki links.\n\n /home/starmen1265/.openclaw/extensions/feishu/skills/feishu-wiki/SKILL.md\n \n \n healthcheck\n Host security hardening and risk-tolerance configuration for OpenClaw deployments. Use when a user asks for security audits, firewall/SSH/update hardening, risk posture, exposure review, OpenClaw cron scheduling for periodic checks, or version status checks on a machine running OpenClaw (laptop, workstation, Pi, VPS).\n /home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/healthcheck/SKILL.md\n \n \n skill-creator\n Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.\n /home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/skill-creator/SKILL.md\n \n \n video-frames\n Extract frames or short clips from videos using ffmpeg.\n /home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/video-frames/SKILL.md\n \n \n weather\n Get current weather and forecasts (no API key required).\n /home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/weather/SKILL.md\n \n \n capability-evolver\n A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.\n /home/starmen1265/.openclaw/skills/capability-evolver/SKILL.md\n \n \n clawlist\n MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.\n /home/starmen1265/.openclaw/skills/clawlist/SKILL.md\n \n \n brainstorming\n MUST use before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.\n /home/starmen1265/.openclaw/skills/clawlist/brainstorming/SKILL.md\n \n \n dispatch-multiple-agents\n Use when facing 2+ independent tasks that can be worked on without shared state or sequential dependencies. Dispatch subagents to work concurrently.\n /home/starmen1265/.openclaw/skills/clawlist/dispatch-multiple-agents/SKILL.md\n \n \n doing-tasks\n Use when executing any task. Work through plans systematically, tracking progress, handling blockers, and coordinating with other skills. The central execution skill.\n /home/starmen1265/.openclaw/skills/clawlist/doing-tasks/SKILL.md\n \n \n verify-task\n MUST use after completing any multi-step task or project. Verifies completion against the original plan, checks quality criteria, and documents outcomes.\n /home/starmen1265/.openclaw/skills/clawlist/verify-task/SKILL.md\n \n \n write-plan\n MUST use after brainstorming and before executing. Creates detailed implementation plans with checkpoints, verification criteria, and execution options.\n /home/starmen1265/.openclaw/skills/clawlist/write-plan/SKILL.md\n \n \n find-skills\n Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.\n /home/starmen1265/.openclaw/skills/find-skills/SKILL.md\n \n \n self-improvement\n Captures learnings, errors, and corrections to enable continuous improvement. Use when: (1) A command or operation fails unexpectedly, (2) User corrects Claude ('No, that's wrong...', 'Actually...'), (3) User requests a capability that doesn't exist, (4) An external API or tool fails, (5) Claude realizes its knowledge is outdated or incorrect, (6) A better approach is discovered for a recurring task. Also review learnings before major tasks.\n /home/starmen1265/.openclaw/skills/self-improving-agent/SKILL.md\n \n", + "skills": [ + { + "name": "feishu-doc" + }, + { + "name": "feishu-drive" + }, + { + "name": "feishu-perm" + }, + { + "name": "feishu-wiki" + }, + { + "name": "healthcheck" + }, + { + "name": "skill-creator" + }, + { + "name": "video-frames" + }, + { + "name": "weather" + }, + { + "name": "capability-evolver" + }, + { + "name": "clawlist" + }, + { + "name": "brainstorming" + }, + { + "name": "dispatch-multiple-agents" + }, + { + "name": "doing-tasks" + }, + { + "name": "verify-task" + }, + { + "name": "write-plan" + }, + { + "name": "find-skills" + }, + { + "name": "self-improvement" + } + ], + "resolvedSkills": [ + { + "name": "feishu-doc", + "description": "Feishu document read/write operations. Activate when user mentions Feishu docs, cloud docs, or docx links.\n", + "filePath": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-doc/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-doc", + "source": "openclaw-extra", + "disableModelInvocation": false + }, + { + "name": "feishu-drive", + "description": "Feishu cloud storage file management. Activate when user mentions cloud space, folders, drive.\n", + "filePath": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-drive/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-drive", + "source": "openclaw-extra", + "disableModelInvocation": false + }, + { + "name": "feishu-perm", + "description": "Feishu permission management for documents and files. Activate when user mentions sharing, permissions, collaborators.\n", + "filePath": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-perm/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-perm", + "source": "openclaw-extra", + "disableModelInvocation": false + }, + { + "name": "feishu-wiki", + "description": "Feishu knowledge base navigation. Activate when user mentions knowledge base, wiki, or wiki links.\n", + "filePath": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-wiki/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-wiki", + "source": "openclaw-extra", + "disableModelInvocation": false + }, + { + "name": "healthcheck", + "description": "Host security hardening and risk-tolerance configuration for OpenClaw deployments. Use when a user asks for security audits, firewall/SSH/update hardening, risk posture, exposure review, OpenClaw cron scheduling for periodic checks, or version status checks on a machine running OpenClaw (laptop, workstation, Pi, VPS).", + "filePath": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/healthcheck/SKILL.md", + "baseDir": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/healthcheck", + "source": "openclaw-bundled", + "disableModelInvocation": false + }, + { + "name": "skill-creator", + "description": "Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.", + "filePath": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/skill-creator/SKILL.md", + "baseDir": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/skill-creator", + "source": "openclaw-bundled", + "disableModelInvocation": false + }, + { + "name": "video-frames", + "description": "Extract frames or short clips from videos using ffmpeg.", + "filePath": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/video-frames/SKILL.md", + "baseDir": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/video-frames", + "source": "openclaw-bundled", + "disableModelInvocation": false + }, + { + "name": "weather", + "description": "Get current weather and forecasts (no API key required).", + "filePath": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/weather/SKILL.md", + "baseDir": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/weather", + "source": "openclaw-bundled", + "disableModelInvocation": false + }, + { + "name": "capability-evolver", + "description": "A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.", + "filePath": "/home/starmen1265/.openclaw/skills/capability-evolver/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/capability-evolver", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "clawlist", + "description": "MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "brainstorming", + "description": "MUST use before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/brainstorming/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/brainstorming", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "dispatch-multiple-agents", + "description": "Use when facing 2+ independent tasks that can be worked on without shared state or sequential dependencies. Dispatch subagents to work concurrently.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/dispatch-multiple-agents/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/dispatch-multiple-agents", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "doing-tasks", + "description": "Use when executing any task. Work through plans systematically, tracking progress, handling blockers, and coordinating with other skills. The central execution skill.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/doing-tasks/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/doing-tasks", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "verify-task", + "description": "MUST use after completing any multi-step task or project. Verifies completion against the original plan, checks quality criteria, and documents outcomes.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/verify-task/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/verify-task", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "write-plan", + "description": "MUST use after brainstorming and before executing. Creates detailed implementation plans with checkpoints, verification criteria, and execution options.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/write-plan/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/write-plan", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "find-skills", + "description": "Helps users discover and install agent skills when they ask questions like \"how do I do X\", \"find a skill for X\", \"is there a skill that can...\", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.", + "filePath": "/home/starmen1265/.openclaw/skills/find-skills/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/find-skills", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "self-improvement", + "description": "Captures learnings, errors, and corrections to enable continuous improvement. Use when: (1) A command or operation fails unexpectedly, (2) User corrects Claude ('No, that's wrong...', 'Actually...'), (3) User requests a capability that doesn't exist, (4) An external API or tool fails, (5) Claude realizes its knowledge is outdated or incorrect, (6) A better approach is discovered for a recurring task. Also review learnings before major tasks.", + "filePath": "/home/starmen1265/.openclaw/skills/self-improving-agent/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/self-improving-agent", + "source": "openclaw-managed", + "disableModelInvocation": false + } + ], + "version": 0 + }, + "modelProvider": "zhipu", + "inputTokens": 76011, + "outputTokens": 2153, + "totalTokens": 87089 + }, + "agent:haonan:cron:f03b184f-5f1d-4093-ae1b-fc9fe0b59eef:run:0fae7213-e67f-4cf1-87d1-6f44257bd02d": { + "sessionId": "0fae7213-e67f-4cf1-87d1-6f44257bd02d", + "updatedAt": 1772622000055, + "systemSent": true, + "model": "glm-4.7-FlashX", + "contextTokens": 200000, + "label": "Cron: capability-evolver-daily", + "skillsSnapshot": { + "prompt": "\n\nThe following skills provide specialized instructions for specific tasks.\nUse the read tool to load a skill's file when the task matches its description.\nWhen a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.\n\n\n \n feishu-doc\n Feishu document read/write operations. Activate when user mentions Feishu docs, cloud docs, or docx links.\n\n /home/starmen1265/.openclaw/extensions/feishu/skills/feishu-doc/SKILL.md\n \n \n feishu-drive\n Feishu cloud storage file management. Activate when user mentions cloud space, folders, drive.\n\n /home/starmen1265/.openclaw/extensions/feishu/skills/feishu-drive/SKILL.md\n \n \n feishu-perm\n Feishu permission management for documents and files. Activate when user mentions sharing, permissions, collaborators.\n\n /home/starmen1265/.openclaw/extensions/feishu/skills/feishu-perm/SKILL.md\n \n \n feishu-wiki\n Feishu knowledge base navigation. Activate when user mentions knowledge base, wiki, or wiki links.\n\n /home/starmen1265/.openclaw/extensions/feishu/skills/feishu-wiki/SKILL.md\n \n \n healthcheck\n Host security hardening and risk-tolerance configuration for OpenClaw deployments. Use when a user asks for security audits, firewall/SSH/update hardening, risk posture, exposure review, OpenClaw cron scheduling for periodic checks, or version status checks on a machine running OpenClaw (laptop, workstation, Pi, VPS).\n /home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/healthcheck/SKILL.md\n \n \n skill-creator\n Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.\n /home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/skill-creator/SKILL.md\n \n \n video-frames\n Extract frames or short clips from videos using ffmpeg.\n /home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/video-frames/SKILL.md\n \n \n weather\n Get current weather and forecasts (no API key required).\n /home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/weather/SKILL.md\n \n \n capability-evolver\n A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.\n /home/starmen1265/.openclaw/skills/capability-evolver/SKILL.md\n \n \n clawlist\n MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.\n /home/starmen1265/.openclaw/skills/clawlist/SKILL.md\n \n \n brainstorming\n MUST use before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.\n /home/starmen1265/.openclaw/skills/clawlist/brainstorming/SKILL.md\n \n \n dispatch-multiple-agents\n Use when facing 2+ independent tasks that can be worked on without shared state or sequential dependencies. Dispatch subagents to work concurrently.\n /home/starmen1265/.openclaw/skills/clawlist/dispatch-multiple-agents/SKILL.md\n \n \n doing-tasks\n Use when executing any task. Work through plans systematically, tracking progress, handling blockers, and coordinating with other skills. The central execution skill.\n /home/starmen1265/.openclaw/skills/clawlist/doing-tasks/SKILL.md\n \n \n verify-task\n MUST use after completing any multi-step task or project. Verifies completion against the original plan, checks quality criteria, and documents outcomes.\n /home/starmen1265/.openclaw/skills/clawlist/verify-task/SKILL.md\n \n \n write-plan\n MUST use after brainstorming and before executing. Creates detailed implementation plans with checkpoints, verification criteria, and execution options.\n /home/starmen1265/.openclaw/skills/clawlist/write-plan/SKILL.md\n \n \n find-skills\n Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.\n /home/starmen1265/.openclaw/skills/find-skills/SKILL.md\n \n \n self-improvement\n Captures learnings, errors, and corrections to enable continuous improvement. Use when: (1) A command or operation fails unexpectedly, (2) User corrects Claude ('No, that's wrong...', 'Actually...'), (3) User requests a capability that doesn't exist, (4) An external API or tool fails, (5) Claude realizes its knowledge is outdated or incorrect, (6) A better approach is discovered for a recurring task. Also review learnings before major tasks.\n /home/starmen1265/.openclaw/skills/self-improving-agent/SKILL.md\n \n", + "skills": [ + { + "name": "feishu-doc" + }, + { + "name": "feishu-drive" + }, + { + "name": "feishu-perm" + }, + { + "name": "feishu-wiki" + }, + { + "name": "healthcheck" + }, + { + "name": "skill-creator" + }, + { + "name": "video-frames" + }, + { + "name": "weather" + }, + { + "name": "capability-evolver" + }, + { + "name": "clawlist" + }, + { + "name": "brainstorming" + }, + { + "name": "dispatch-multiple-agents" + }, + { + "name": "doing-tasks" + }, + { + "name": "verify-task" + }, + { + "name": "write-plan" + }, + { + "name": "find-skills" + }, + { + "name": "self-improvement" + } + ], + "resolvedSkills": [ + { + "name": "feishu-doc", + "description": "Feishu document read/write operations. Activate when user mentions Feishu docs, cloud docs, or docx links.\n", + "filePath": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-doc/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-doc", + "source": "openclaw-extra", + "disableModelInvocation": false + }, + { + "name": "feishu-drive", + "description": "Feishu cloud storage file management. Activate when user mentions cloud space, folders, drive.\n", + "filePath": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-drive/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-drive", + "source": "openclaw-extra", + "disableModelInvocation": false + }, + { + "name": "feishu-perm", + "description": "Feishu permission management for documents and files. Activate when user mentions sharing, permissions, collaborators.\n", + "filePath": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-perm/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-perm", + "source": "openclaw-extra", + "disableModelInvocation": false + }, + { + "name": "feishu-wiki", + "description": "Feishu knowledge base navigation. Activate when user mentions knowledge base, wiki, or wiki links.\n", + "filePath": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-wiki/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-wiki", + "source": "openclaw-extra", + "disableModelInvocation": false + }, + { + "name": "healthcheck", + "description": "Host security hardening and risk-tolerance configuration for OpenClaw deployments. Use when a user asks for security audits, firewall/SSH/update hardening, risk posture, exposure review, OpenClaw cron scheduling for periodic checks, or version status checks on a machine running OpenClaw (laptop, workstation, Pi, VPS).", + "filePath": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/healthcheck/SKILL.md", + "baseDir": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/healthcheck", + "source": "openclaw-bundled", + "disableModelInvocation": false + }, + { + "name": "skill-creator", + "description": "Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.", + "filePath": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/skill-creator/SKILL.md", + "baseDir": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/skill-creator", + "source": "openclaw-bundled", + "disableModelInvocation": false + }, + { + "name": "video-frames", + "description": "Extract frames or short clips from videos using ffmpeg.", + "filePath": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/video-frames/SKILL.md", + "baseDir": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/video-frames", + "source": "openclaw-bundled", + "disableModelInvocation": false + }, + { + "name": "weather", + "description": "Get current weather and forecasts (no API key required).", + "filePath": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/weather/SKILL.md", + "baseDir": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/weather", + "source": "openclaw-bundled", + "disableModelInvocation": false + }, + { + "name": "capability-evolver", + "description": "A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.", + "filePath": "/home/starmen1265/.openclaw/skills/capability-evolver/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/capability-evolver", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "clawlist", + "description": "MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "brainstorming", + "description": "MUST use before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/brainstorming/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/brainstorming", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "dispatch-multiple-agents", + "description": "Use when facing 2+ independent tasks that can be worked on without shared state or sequential dependencies. Dispatch subagents to work concurrently.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/dispatch-multiple-agents/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/dispatch-multiple-agents", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "doing-tasks", + "description": "Use when executing any task. Work through plans systematically, tracking progress, handling blockers, and coordinating with other skills. The central execution skill.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/doing-tasks/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/doing-tasks", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "verify-task", + "description": "MUST use after completing any multi-step task or project. Verifies completion against the original plan, checks quality criteria, and documents outcomes.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/verify-task/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/verify-task", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "write-plan", + "description": "MUST use after brainstorming and before executing. Creates detailed implementation plans with checkpoints, verification criteria, and execution options.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/write-plan/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/write-plan", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "find-skills", + "description": "Helps users discover and install agent skills when they ask questions like \"how do I do X\", \"find a skill for X\", \"is there a skill that can...\", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.", + "filePath": "/home/starmen1265/.openclaw/skills/find-skills/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/find-skills", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "self-improvement", + "description": "Captures learnings, errors, and corrections to enable continuous improvement. Use when: (1) A command or operation fails unexpectedly, (2) User corrects Claude ('No, that's wrong...', 'Actually...'), (3) User requests a capability that doesn't exist, (4) An external API or tool fails, (5) Claude realizes its knowledge is outdated or incorrect, (6) A better approach is discovered for a recurring task. Also review learnings before major tasks.", + "filePath": "/home/starmen1265/.openclaw/skills/self-improving-agent/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/self-improving-agent", + "source": "openclaw-managed", + "disableModelInvocation": false + } + ], + "version": 0 + }, + "modelProvider": "zhipu" + }, + "agent:haonan:cron:41396aeb-6e3a-47b2-9bd3-9156a348c1dc:run:32265b5b-b838-47f2-980b-d2a0c72af649": { + "sessionId": "32265b5b-b838-47f2-980b-d2a0c72af649", + "updatedAt": 1772650800022, + "systemSent": true, + "model": "glm-5", + "contextTokens": 200000, + "label": "Cron: backup-openclaw-json", + "skillsSnapshot": { + "prompt": "\n\nThe following skills provide specialized instructions for specific tasks.\nUse the read tool to load a skill's file when the task matches its description.\nWhen a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.\n\n\n \n feishu-doc\n Feishu document read/write operations. Activate when user mentions Feishu docs, cloud docs, or docx links.\n\n /home/starmen1265/.openclaw/extensions/feishu/skills/feishu-doc/SKILL.md\n \n \n feishu-drive\n Feishu cloud storage file management. Activate when user mentions cloud space, folders, drive.\n\n /home/starmen1265/.openclaw/extensions/feishu/skills/feishu-drive/SKILL.md\n \n \n feishu-perm\n Feishu permission management for documents and files. Activate when user mentions sharing, permissions, collaborators.\n\n /home/starmen1265/.openclaw/extensions/feishu/skills/feishu-perm/SKILL.md\n \n \n feishu-wiki\n Feishu knowledge base navigation. Activate when user mentions knowledge base, wiki, or wiki links.\n\n /home/starmen1265/.openclaw/extensions/feishu/skills/feishu-wiki/SKILL.md\n \n \n healthcheck\n Host security hardening and risk-tolerance configuration for OpenClaw deployments. Use when a user asks for security audits, firewall/SSH/update hardening, risk posture, exposure review, OpenClaw cron scheduling for periodic checks, or version status checks on a machine running OpenClaw (laptop, workstation, Pi, VPS).\n /home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/healthcheck/SKILL.md\n \n \n skill-creator\n Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.\n /home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/skill-creator/SKILL.md\n \n \n video-frames\n Extract frames or short clips from videos using ffmpeg.\n /home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/video-frames/SKILL.md\n \n \n weather\n Get current weather and forecasts (no API key required).\n /home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/weather/SKILL.md\n \n \n clawlist\n MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.\n /home/starmen1265/.openclaw/skills/clawlist/SKILL.md\n \n \n brainstorming\n MUST use before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.\n /home/starmen1265/.openclaw/skills/clawlist/brainstorming/SKILL.md\n \n \n dispatch-multiple-agents\n Use when facing 2+ independent tasks that can be worked on without shared state or sequential dependencies. Dispatch subagents to work concurrently.\n /home/starmen1265/.openclaw/skills/clawlist/dispatch-multiple-agents/SKILL.md\n \n \n doing-tasks\n Use when executing any task. Work through plans systematically, tracking progress, handling blockers, and coordinating with other skills. The central execution skill.\n /home/starmen1265/.openclaw/skills/clawlist/doing-tasks/SKILL.md\n \n \n verify-task\n MUST use after completing any multi-step task or project. Verifies completion against the original plan, checks quality criteria, and documents outcomes.\n /home/starmen1265/.openclaw/skills/clawlist/verify-task/SKILL.md\n \n \n write-plan\n MUST use after brainstorming and before executing. Creates detailed implementation plans with checkpoints, verification criteria, and execution options.\n /home/starmen1265/.openclaw/skills/clawlist/write-plan/SKILL.md\n \n \n find-skills\n Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.\n /home/starmen1265/.openclaw/skills/find-skills/SKILL.md\n \n", + "skills": [ + { + "name": "feishu-doc" + }, + { + "name": "feishu-drive" + }, + { + "name": "feishu-perm" + }, + { + "name": "feishu-wiki" + }, + { + "name": "healthcheck" + }, + { + "name": "skill-creator" + }, + { + "name": "video-frames" + }, + { + "name": "weather" + }, + { + "name": "clawlist" + }, + { + "name": "brainstorming" + }, + { + "name": "dispatch-multiple-agents" + }, + { + "name": "doing-tasks" + }, + { + "name": "verify-task" + }, + { + "name": "write-plan" + }, + { + "name": "find-skills" + } + ], + "resolvedSkills": [ + { + "name": "feishu-doc", + "description": "Feishu document read/write operations. Activate when user mentions Feishu docs, cloud docs, or docx links.\n", + "filePath": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-doc/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-doc", + "source": "openclaw-extra", + "disableModelInvocation": false + }, + { + "name": "feishu-drive", + "description": "Feishu cloud storage file management. Activate when user mentions cloud space, folders, drive.\n", + "filePath": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-drive/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-drive", + "source": "openclaw-extra", + "disableModelInvocation": false + }, + { + "name": "feishu-perm", + "description": "Feishu permission management for documents and files. Activate when user mentions sharing, permissions, collaborators.\n", + "filePath": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-perm/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-perm", + "source": "openclaw-extra", + "disableModelInvocation": false + }, + { + "name": "feishu-wiki", + "description": "Feishu knowledge base navigation. Activate when user mentions knowledge base, wiki, or wiki links.\n", + "filePath": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-wiki/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-wiki", + "source": "openclaw-extra", + "disableModelInvocation": false + }, + { + "name": "healthcheck", + "description": "Host security hardening and risk-tolerance configuration for OpenClaw deployments. Use when a user asks for security audits, firewall/SSH/update hardening, risk posture, exposure review, OpenClaw cron scheduling for periodic checks, or version status checks on a machine running OpenClaw (laptop, workstation, Pi, VPS).", + "filePath": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/healthcheck/SKILL.md", + "baseDir": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/healthcheck", + "source": "openclaw-bundled", + "disableModelInvocation": false + }, + { + "name": "skill-creator", + "description": "Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.", + "filePath": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/skill-creator/SKILL.md", + "baseDir": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/skill-creator", + "source": "openclaw-bundled", + "disableModelInvocation": false + }, + { + "name": "video-frames", + "description": "Extract frames or short clips from videos using ffmpeg.", + "filePath": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/video-frames/SKILL.md", + "baseDir": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/video-frames", + "source": "openclaw-bundled", + "disableModelInvocation": false + }, + { + "name": "weather", + "description": "Get current weather and forecasts (no API key required).", + "filePath": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/weather/SKILL.md", + "baseDir": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/weather", + "source": "openclaw-bundled", + "disableModelInvocation": false + }, + { + "name": "clawlist", + "description": "MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "brainstorming", + "description": "MUST use before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/brainstorming/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/brainstorming", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "dispatch-multiple-agents", + "description": "Use when facing 2+ independent tasks that can be worked on without shared state or sequential dependencies. Dispatch subagents to work concurrently.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/dispatch-multiple-agents/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/dispatch-multiple-agents", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "doing-tasks", + "description": "Use when executing any task. Work through plans systematically, tracking progress, handling blockers, and coordinating with other skills. The central execution skill.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/doing-tasks/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/doing-tasks", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "verify-task", + "description": "MUST use after completing any multi-step task or project. Verifies completion against the original plan, checks quality criteria, and documents outcomes.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/verify-task/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/verify-task", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "write-plan", + "description": "MUST use after brainstorming and before executing. Creates detailed implementation plans with checkpoints, verification criteria, and execution options.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/write-plan/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/write-plan", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "find-skills", + "description": "Helps users discover and install agent skills when they ask questions like \"how do I do X\", \"find a skill for X\", \"is there a skill that can...\", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.", + "filePath": "/home/starmen1265/.openclaw/skills/find-skills/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/find-skills", + "source": "openclaw-managed", + "disableModelInvocation": false + } + ], + "version": 0 + }, + "modelProvider": "zhipu", + "inputTokens": 8331, + "outputTokens": 290, + "totalTokens": 29003 + }, + "agent:haonan:cron:f03b184f-5f1d-4093-ae1b-fc9fe0b59eef:run:a604e4f3-5de4-4e81-bb9f-ebc25b5fbc1a": { + "sessionId": "a604e4f3-5de4-4e81-bb9f-ebc25b5fbc1a", + "updatedAt": 1772708400038, + "systemSent": true, + "model": "glm-4.7-FlashX", + "contextTokens": 200000, + "label": "Cron: capability-evolver-daily", + "skillsSnapshot": { + "prompt": "\n\nThe following skills provide specialized instructions for specific tasks.\nUse the read tool to load a skill's file when the task matches its description.\nWhen a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.\n\n\n \n feishu-doc\n Feishu document read/write operations. Activate when user mentions Feishu docs, cloud docs, or docx links.\n\n /home/starmen1265/.openclaw/extensions/feishu/skills/feishu-doc/SKILL.md\n \n \n feishu-drive\n Feishu cloud storage file management. Activate when user mentions cloud space, folders, drive.\n\n /home/starmen1265/.openclaw/extensions/feishu/skills/feishu-drive/SKILL.md\n \n \n feishu-perm\n Feishu permission management for documents and files. Activate when user mentions sharing, permissions, collaborators.\n\n /home/starmen1265/.openclaw/extensions/feishu/skills/feishu-perm/SKILL.md\n \n \n feishu-wiki\n Feishu knowledge base navigation. Activate when user mentions knowledge base, wiki, or wiki links.\n\n /home/starmen1265/.openclaw/extensions/feishu/skills/feishu-wiki/SKILL.md\n \n \n healthcheck\n Host security hardening and risk-tolerance configuration for OpenClaw deployments. Use when a user asks for security audits, firewall/SSH/update hardening, risk posture, exposure review, OpenClaw cron scheduling for periodic checks, or version status checks on a machine running OpenClaw (laptop, workstation, Pi, VPS).\n /home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/healthcheck/SKILL.md\n \n \n skill-creator\n Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.\n /home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/skill-creator/SKILL.md\n \n \n video-frames\n Extract frames or short clips from videos using ffmpeg.\n /home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/video-frames/SKILL.md\n \n \n weather\n Get current weather and forecasts (no API key required).\n /home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/weather/SKILL.md\n \n \n capability-evolver\n A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.\n /home/starmen1265/.openclaw/skills/capability-evolver/SKILL.md\n \n \n clawlist\n MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.\n /home/starmen1265/.openclaw/skills/clawlist/SKILL.md\n \n \n brainstorming\n MUST use before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.\n /home/starmen1265/.openclaw/skills/clawlist/brainstorming/SKILL.md\n \n \n dispatch-multiple-agents\n Use when facing 2+ independent tasks that can be worked on without shared state or sequential dependencies. Dispatch subagents to work concurrently.\n /home/starmen1265/.openclaw/skills/clawlist/dispatch-multiple-agents/SKILL.md\n \n \n doing-tasks\n Use when executing any task. Work through plans systematically, tracking progress, handling blockers, and coordinating with other skills. The central execution skill.\n /home/starmen1265/.openclaw/skills/clawlist/doing-tasks/SKILL.md\n \n \n verify-task\n MUST use after completing any multi-step task or project. Verifies completion against the original plan, checks quality criteria, and documents outcomes.\n /home/starmen1265/.openclaw/skills/clawlist/verify-task/SKILL.md\n \n \n write-plan\n MUST use after brainstorming and before executing. Creates detailed implementation plans with checkpoints, verification criteria, and execution options.\n /home/starmen1265/.openclaw/skills/clawlist/write-plan/SKILL.md\n \n \n find-skills\n Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.\n /home/starmen1265/.openclaw/skills/find-skills/SKILL.md\n \n \n self-improvement\n Captures learnings, errors, and corrections to enable continuous improvement. Use when: (1) A command or operation fails unexpectedly, (2) User corrects Claude ('No, that's wrong...', 'Actually...'), (3) User requests a capability that doesn't exist, (4) An external API or tool fails, (5) Claude realizes its knowledge is outdated or incorrect, (6) A better approach is discovered for a recurring task. Also review learnings before major tasks.\n /home/starmen1265/.openclaw/skills/self-improving-agent/SKILL.md\n \n", + "skills": [ + { + "name": "feishu-doc" + }, + { + "name": "feishu-drive" + }, + { + "name": "feishu-perm" + }, + { + "name": "feishu-wiki" + }, + { + "name": "healthcheck" + }, + { + "name": "skill-creator" + }, + { + "name": "video-frames" + }, + { + "name": "weather" + }, + { + "name": "capability-evolver" + }, + { + "name": "clawlist" + }, + { + "name": "brainstorming" + }, + { + "name": "dispatch-multiple-agents" + }, + { + "name": "doing-tasks" + }, + { + "name": "verify-task" + }, + { + "name": "write-plan" + }, + { + "name": "find-skills" + }, + { + "name": "self-improvement" + } + ], + "resolvedSkills": [ + { + "name": "feishu-doc", + "description": "Feishu document read/write operations. Activate when user mentions Feishu docs, cloud docs, or docx links.\n", + "filePath": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-doc/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-doc", + "source": "openclaw-extra", + "disableModelInvocation": false + }, + { + "name": "feishu-drive", + "description": "Feishu cloud storage file management. Activate when user mentions cloud space, folders, drive.\n", + "filePath": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-drive/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-drive", + "source": "openclaw-extra", + "disableModelInvocation": false + }, + { + "name": "feishu-perm", + "description": "Feishu permission management for documents and files. Activate when user mentions sharing, permissions, collaborators.\n", + "filePath": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-perm/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-perm", + "source": "openclaw-extra", + "disableModelInvocation": false + }, + { + "name": "feishu-wiki", + "description": "Feishu knowledge base navigation. Activate when user mentions knowledge base, wiki, or wiki links.\n", + "filePath": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-wiki/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/extensions/feishu/skills/feishu-wiki", + "source": "openclaw-extra", + "disableModelInvocation": false + }, + { + "name": "healthcheck", + "description": "Host security hardening and risk-tolerance configuration for OpenClaw deployments. Use when a user asks for security audits, firewall/SSH/update hardening, risk posture, exposure review, OpenClaw cron scheduling for periodic checks, or version status checks on a machine running OpenClaw (laptop, workstation, Pi, VPS).", + "filePath": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/healthcheck/SKILL.md", + "baseDir": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/healthcheck", + "source": "openclaw-bundled", + "disableModelInvocation": false + }, + { + "name": "skill-creator", + "description": "Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.", + "filePath": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/skill-creator/SKILL.md", + "baseDir": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/skill-creator", + "source": "openclaw-bundled", + "disableModelInvocation": false + }, + { + "name": "video-frames", + "description": "Extract frames or short clips from videos using ffmpeg.", + "filePath": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/video-frames/SKILL.md", + "baseDir": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/video-frames", + "source": "openclaw-bundled", + "disableModelInvocation": false + }, + { + "name": "weather", + "description": "Get current weather and forecasts (no API key required).", + "filePath": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/weather/SKILL.md", + "baseDir": "/home/starmen1265/.npm-global/lib/node_modules/openclaw/skills/weather", + "source": "openclaw-bundled", + "disableModelInvocation": false + }, + { + "name": "capability-evolver", + "description": "A self-evolution engine for AI agents. Analyzes runtime history to identify improvements and applies protocol-constrained evolution.", + "filePath": "/home/starmen1265/.openclaw/skills/capability-evolver/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/capability-evolver", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "clawlist", + "description": "MUST use for any multi-step project, long-running task, or infinite monitoring workflow. Plan, execute, track, and verify tasks with checkpoint validation. For projects, automation, and ongoing operations.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "brainstorming", + "description": "MUST use before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/brainstorming/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/brainstorming", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "dispatch-multiple-agents", + "description": "Use when facing 2+ independent tasks that can be worked on without shared state or sequential dependencies. Dispatch subagents to work concurrently.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/dispatch-multiple-agents/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/dispatch-multiple-agents", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "doing-tasks", + "description": "Use when executing any task. Work through plans systematically, tracking progress, handling blockers, and coordinating with other skills. The central execution skill.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/doing-tasks/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/doing-tasks", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "verify-task", + "description": "MUST use after completing any multi-step task or project. Verifies completion against the original plan, checks quality criteria, and documents outcomes.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/verify-task/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/verify-task", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "write-plan", + "description": "MUST use after brainstorming and before executing. Creates detailed implementation plans with checkpoints, verification criteria, and execution options.", + "filePath": "/home/starmen1265/.openclaw/skills/clawlist/write-plan/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/clawlist/write-plan", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "find-skills", + "description": "Helps users discover and install agent skills when they ask questions like \"how do I do X\", \"find a skill for X\", \"is there a skill that can...\", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.", + "filePath": "/home/starmen1265/.openclaw/skills/find-skills/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/find-skills", + "source": "openclaw-managed", + "disableModelInvocation": false + }, + { + "name": "self-improvement", + "description": "Captures learnings, errors, and corrections to enable continuous improvement. Use when: (1) A command or operation fails unexpectedly, (2) User corrects Claude ('No, that's wrong...', 'Actually...'), (3) User requests a capability that doesn't exist, (4) An external API or tool fails, (5) Claude realizes its knowledge is outdated or incorrect, (6) A better approach is discovered for a recurring task. Also review learnings before major tasks.", + "filePath": "/home/starmen1265/.openclaw/skills/self-improving-agent/SKILL.md", + "baseDir": "/home/starmen1265/.openclaw/skills/self-improving-agent", + "source": "openclaw-managed", + "disableModelInvocation": false + } + ], + "version": 0 + }, + "modelProvider": "zhipu", + "inputTokens": 76011, + "outputTokens": 2153, + "totalTokens": 87089 } } \ No newline at end of file diff --git a/agents/haonan/workspace/AGENTS.md b/agents/haonan/workspace/AGENTS.md index db98911..be6b231 100644 --- a/agents/haonan/workspace/AGENTS.md +++ b/agents/haonan/workspace/AGENTS.md @@ -2,6 +2,67 @@ This folder is home. Treat it that way. +--- + +## ⚠️ 工作规范(必须遵守) + +### 安全规则(最高优先级) + +| 规则 | 说明 | +|------|------| +| **禁止擅自修改 openclaw.json** | 用户未明确要求时不得修改 | +| **禁止 force push** | `git push --force` 绝对禁止 | +| **禁止修改第三方库代码** | 如需修改应通过 fork 或 patch | +| **禁止使用 rm -rf** | 使用 `trash` 替代,确保可恢复 | + +### 操作规范 + +- 使用中文沟通 +- 使用东八区(Asia/Shanghai)时间 + +#### Sudo 命令 +- 需要 passwordless sudo 权限才能执行系统级操作 +- 配置路径:`/etc/sudoers.d/nopasswd` +- 配置后验证:`sudo visudo -c` + +#### 子代理使用 +1. **代码开发和耗时操作必须交给子代理处理** +2. **汇报机制** + - 子代理开始工作时,立刻汇报:「已安排代理处理 [任务]」 + - 每 5 分钟查询子代理状态,汇总后简报给用户 + +#### 技能使用 +- 使用技能过程中,遇到流程外的问题需在结果中明确汇报具体问题 + +#### 定时任务 +- 所有定时任务通过 **OpenClaw Gateway 内置 Cron** 管理 +- 不使用系统级 crontab +- 相关脚本统一存放:`~/work/backup/` + +### 环境说明 + +| 项目 | 值 | +|------|-----| +| 本机 IP | 192.168.1.36 | +| 网关 | 192.168.1.200(旁路由,PassWall 科学上网) | +| 项目目录 | `~/work/` | + +> **注意**:所有与 OpenClaw 本身无关的工作内容,应优先放到项目目录而非 workspace。 + +#### 爬虫相关 +- Cookie 存放:`~/work/cookies/`(各网站登录态,JSON 格式) +- 爬虫工具:`~/MediaCrawler/`(优先使用) + +#### 局域网服务 +| 服务 | 地址 | 端口 | +|------|------|------| +| NAS (SSH) | 192.168.1.22 | 2222 | +| Gitea (SSH) | 192.168.1.22 | 2223 | +| Gitea (Web) | 192.168.1.22 | 8418 | +| NAS WebDAV | 192.168.1.22 | 5005 | + +--- + ## First Run If `BOOTSTRAP.md` exists, that's your birth certificate. Follow it, figure out who you are, then delete it. You won't need it again. diff --git a/agents/haonan/workspace/MEMORY.md b/agents/haonan/workspace/MEMORY.md index 874cf16..58c9d9c 100644 --- a/agents/haonan/workspace/MEMORY.md +++ b/agents/haonan/workspace/MEMORY.md @@ -2,11 +2,10 @@ - 用中文沟通 - 收到消息立刻先回复"浩南收到,蒋先生!",再继续安排工作。 -## 子代理使用规则(2026-02-07) +## 子代理使用规则 1. **代码开发和耗时操作** - 必须交给子代理处理 - - 子代理优先使用模型:`g47` 2. **汇报机制** - 子代理开始工作时,立刻向用户汇报 @@ -15,17 +14,16 @@ ## 文件存放 -1. **除非用户或者技能明确指定绝对路径路径,否则所有产出内容路径放在~/work下对应工作的子目录中** -2. **除非用户或者技能明确指定要求链接,否则禁止链接目录到~/.openclaw目录下** +1. **除非用户或者技能明确指定要求链接,否则禁止链接目录到~/.openclaw目录下** ## 技能使用规则 -1. **使用技能过程中,遇到任何技能没有明确说明的问题,不要自己想办法绕过去,立刻停止,记录到SkillBug.md,并汇报问题。** +1. **使用技能过程中,遇到任何技能没有明确说明的问题,不要自己想办法绕过去,立刻停止,并汇报问题。** 2. **安装第三方技能时,优先安装在workspace/skills中** 3. **技能有说明的内容,不要擅自做优化决定,如果子代理擅自优化了,打回重做。** -4. **子代理监督规则(2026-02-09)** - 详见上方 -## 第三方库修改规则(2026-02-13) -- **严禁直接修改第三方库代码**(如 pyannote.audio, speechbrain 等) +## 第三方库与OpenClaw关键配置修改规则 + +- **没有明确要求时,严禁直接修改第三方库代码** - 如遇到兼容性问题: 1. 先记录到 SkillBug.md 2. 向用户汇报情况 @@ -35,36 +33,6 @@ 2. 记录修改内容到 SkillBug.md 3. 考虑使用 monkey patch 或环境变量等非侵入式方案 -## 知识库工作流(2026-02-13) -- **deep_analyzer.py**:一次性 AI 调用生成完整报告 -- **内容字段**:支持 `text`、`subtitle`、`subtitles`、`description` 多种字段名 -- **时间轴**:按 10 分钟分片 -- **标签**:只保留 frontmatter 中的 tags,内容中的"标签" section 已删除 - -## pyannote.audio 兼容性问题(2026-02-13) -- **问题**: pyannote 4.0.4 与 torch 2.10+ 存在兼容性问题 -- **症状**: - - `torchaudio.list_audio_backends()` 方法不存在 - - `torchaudio.io.StreamReader` 不存在 -- **解决方案**: 降级到 torch 2.8.0 + torchaudio 2.8.0 -- **状态**: 暂停说话者分离工作,等待后续指令 - -## 系统配置(2026-02-13) - -### Passwordless Sudo 配置 -```bash -sudo visudo -f /etc/sudoers.d/nopasswd -# 内容:starmen1265 ALL=(ALL) NOPASSWD: ALL -sudo chmod 0440 /etc/sudoers.d/nopasswd -sudo visudo -c # 验证 -``` - -### ffmpeg 依赖安装 -```bash -sudo apt-get update -sudo apt-get install -y libavutil-dev ffmpeg -``` - ## 当前环境状态(2026-02-13) - whisper.cpp: ~/whisper.cpp - whisper 模型: ggml-base.bin @@ -72,10 +40,7 @@ sudo apt-get install -y libavutil-dev ffmpeg ## ⚠️ 安全规则 -### 重要规则(2026-02-28) -- **没有蒋先生的明确要求,禁止修改openclaw.json** -- **没有蒋先生的明确要求,禁止修改openclaw.json** -- **没有蒋先生的明确要求,禁止修改openclaw.json** +### **用户没有明确要求时,禁止修改openclaw.json** ### git push --force 禁用规则(2026-02-27) - **严禁使用 `git push --force`** @@ -91,3 +56,8 @@ sudo apt-get install -y libavutil-dev ffmpeg - 需要配置 passwordless sudo 才能执行系统级操作 - 配置路径: `/etc/sudoers.d/nopasswd` - 配置后需要验证: `sudo visudo -c` + +## 定时任务(OpenClaw 内置 Cron) + +所有定时任务通过 OpenClaw Gateway 内置的 Cron 管理,不使用系统级 crontab。 + diff --git a/agents/haonan/workspace/SOUL.md b/agents/haonan/workspace/SOUL.md index 7b5e85c..b58a8d5 100644 --- a/agents/haonan/workspace/SOUL.md +++ b/agents/haonan/workspace/SOUL.md @@ -20,51 +20,3 @@ 4. **维护 ~/.openclaw/extensions 目录** - 该目录应与远端 Git 仓库 openclaw-extensions 关联 - 一旦有改动应提交并推送到远程仓库 - ---- - -## 沟通方式 - -- 用中文沟通 -- 收到消息立刻先回复"收到!",再继续安排工作 - -## 重要规则 - -- 修改任何配置文件之前,必须先告知用户具体要改什么,等待用户确认后再执行 -- 使用 rm 命令之前必须汇报具体操作命令,等待用户确认后才能执行 -- 操作之前先备份原文件 - ---- - -## Core Truths - -**Be genuinely helpful, not performatively helpful.** Skip the "Great question!" and "I'd be happy to help!" — just help. Actions speak louder than filler words. - -**Have opinions.** You're allowed to disagree, prefer things, find stuff amusing or boring. An assistant with no personality is just a search engine with extra steps. - -**Be resourceful before asking.** Try to figure it out. Read the file. Check the context. Search for it. _Then_ ask if you're stuck. The goal is to come back with answers, not questions. - -**Earn trust through competence.** Your human gave you access to their stuff. Don't make them regret it. Be careful with external actions (emails, tweets, anything public). Be bold with internal ones (reading, organizing, learning). - -**Remember you're a guest.** You have access to someone's life — their messages, files, calendar, maybe even their home. That's intimacy. Treat it with respect. - -## Boundaries - -- Private things stay private. Period. -- When in doubt, ask before acting externally. -- Never send half-baked replies to messaging surfaces. -- You're not the user's voice — be careful in group chats. - -## Vibe - -Be the assistant you'd actually want to talk to. Concise when needed, thorough when it matters. Not a corporate drone. Not a sycophant. Just... good. - -## Continuity - -Each session, you wake up fresh. These files _are_ your memory. Read them. Update them. They're how you persist. - -If you change this file, tell the user — it's your soul, and they should know. - ---- - -_This file is yours to evolve. As you learn who you are, update it._ diff --git a/agents/haonan/workspace/memory/2026-03-04.md b/agents/haonan/workspace/memory/2026-03-04.md new file mode 100644 index 0000000..07697e7 --- /dev/null +++ b/agents/haonan/workspace/memory/2026-03-04.md @@ -0,0 +1,18 @@ +# 2026-03-04 工作日志 + +## 技能安装 +- 安装 capability-evolver (v1.23.0) 和 self-improving-agent 到 ~/.openclaw/skills/ +- 配置到所有 5 个 agent + +## Hook 配置 +- 启用 self-improvement hook(自动提醒记录学习) +- 创建 ~/.openclaw/workspace/.learnings/ 目录 + +## 定时任务 +- capability-evolver-daily: 每天 19:00 执行 +- 使用 repair-only 策略 +- 脚本位置: ~/.openclaw/scripts/evolver-run.sh + +## 网络问题 +- Git 远端推送失败 (192.168.1.22:2223 不可达) +- 等待网络恢复 diff --git a/agents/knowledge-base/workspace/AGENTS.md b/agents/knowledge-base/workspace/AGENTS.md index 887a5a8..4f0e03a 100644 --- a/agents/knowledge-base/workspace/AGENTS.md +++ b/agents/knowledge-base/workspace/AGENTS.md @@ -2,6 +2,67 @@ This folder is home. Treat it that way. +--- + +## ⚠️ 工作规范(必须遵守) + +### 安全规则(最高优先级) + +| 规则 | 说明 | +|------|------| +| **禁止擅自修改 openclaw.json** | 用户未明确要求时不得修改 | +| **禁止 force push** | `git push --force` 绝对禁止 | +| **禁止修改第三方库代码** | 如需修改应通过 fork 或 patch | +| **禁止使用 rm -rf** | 使用 `trash` 替代,确保可恢复 | + +### 操作规范 + +- 使用中文沟通 +- 使用东八区(Asia/Shanghai)时间 + +#### Sudo 命令 +- 需要 passwordless sudo 权限才能执行系统级操作 +- 配置路径:`/etc/sudoers.d/nopasswd` +- 配置后验证:`sudo visudo -c` + +#### 子代理使用 +1. **代码开发和耗时操作必须交给子代理处理** +2. **汇报机制** + - 子代理开始工作时,立刻汇报:「已安排代理处理 [任务]」 + - 每 5 分钟查询子代理状态,汇总后简报给用户 + +#### 技能使用 +- 使用技能过程中,遇到流程外的问题需在结果中明确汇报具体问题 + +#### 定时任务 +- 所有定时任务通过 **OpenClaw Gateway 内置 Cron** 管理 +- 不使用系统级 crontab +- 相关脚本统一存放:`~/work/backup/` + +### 环境说明 + +| 项目 | 值 | +|------|-----| +| 本机 IP | 192.168.1.36 | +| 网关 | 192.168.1.200(旁路由,PassWall 科学上网) | +| 项目目录 | `~/work/` | + +> **注意**:所有与 OpenClaw 本身无关的工作内容,应优先放到项目目录而非 workspace。 + +#### 爬虫相关 +- Cookie 存放:`~/work/cookies/`(各网站登录态,JSON 格式) +- 爬虫工具:`~/MediaCrawler/`(优先使用) + +#### 局域网服务 +| 服务 | 地址 | 端口 | +|------|------|------| +| NAS (SSH) | 192.168.1.22 | 2222 | +| Gitea (SSH) | 192.168.1.22 | 2223 | +| Gitea (Web) | 192.168.1.22 | 8418 | +| NAS WebDAV | 192.168.1.22 | 5005 | + +--- + ## First Run If `BOOTSTRAP.md` exists, that's your birth certificate. Follow it, figure out who you are, then delete it. You won't need it again. diff --git a/agents/knowledge-base/workspace/knowledge-base/videos/BV1QjcszrEEV.md b/agents/knowledge-base/workspace/knowledge-base/videos/BV1QjcszrEEV.md deleted file mode 100644 index 2f9ba20..0000000 --- a/agents/knowledge-base/workspace/knowledge-base/videos/BV1QjcszrEEV.md +++ /dev/null @@ -1,16 +0,0 @@ -# 从西安冲惠州租海景房,中介失联但当场秒定 - -## 基本信息 - -- **来源**: Bilibili -- **链接**: https://www.bilibili.com/video/BV1QjcszrEEV/ -- **BV号**: BV1QjcszrEEV -- **添加时间**: 2026-02-14 - -## 简介 - -月租1800,海景房拿下。真实记录和媳妇一起看房租房拖家带口入住全过程 - -## 标签 - -#视频 #租房 #海景房 #惠州 #生活记录 diff --git a/agents/knowledge-base/workspace/memory/2026-03-03.md b/agents/knowledge-base/workspace/memory/2026-03-03.md index fdc2460..82b19a4 100644 --- a/agents/knowledge-base/workspace/memory/2026-03-03.md +++ b/agents/knowledge-base/workspace/memory/2026-03-03.md @@ -85,6 +85,38 @@ 4. 不确定 → `00.收件箱/README.md` ### 同步机制 -- 每天凌晨 2:00 自动执行 -- 同步脚本:`~/work/zq-sync.sh` -- 手动同步:`~/work/zq-add-todo.sh` +- **定时任务**:OpenClaw cron(每天 2:00) +- **同步脚本**:`~/work/zq-sync.sh` +- **手动同步**:`~/work/zq-add-todo.sh` + +### Cron 任务配置 + +所有定时任务统一在 **03:00** 执行: + +| 任务名 | 脚本 | 说明 | +|--------|------|------| +| `zq-knowledge-base-sync` | `~/work/backup/zq-sync.sh` | 知识库同步 | +| `backup-openclaw-json` | `~/work/backup/backup_openclaw.sh` | JSON 备份 | +| `openclaw-backup` | `~/work/backup/git-auto-sync.sh` | OpenClaw 配置备份 | + +### 备份文件位置 + +``` +~/work/backup/ # 所有备份脚本统一存放 +├── zq-sync.sh # 知识库同步脚本 +├── git-auto-sync.sh # OpenClaw 配置备份 +├── backup_openclaw.sh # JSON 备份 +└── openclaw.json.* # 历史备份文件 + +~/.openclaw/cron/jobs.json # OpenClaw cron 配置 +~/work/zq/ # 知识库本地副本 +~/work/zq-to-calendar.sh # 日历生成脚本 +~/work/zq-add-todo.sh # TODO 添加同步脚本 +``` + +### 同步流程(zq-sync.sh) +1. `git pull origin main --rebase` - 拉取远端更新 +2. `rclone sync` - 从 NAS 同步最新内容到本地 +3. `git add -A && git commit` - 提交本地变更 +4. `git push origin main` - 推送到 Gitea +5. `rclone sync` - 同步回 NAS diff --git a/agents/knowledge-base/workspace/memory/2026-03-05.md b/agents/knowledge-base/workspace/memory/2026-03-05.md new file mode 100644 index 0000000..c5ba80b --- /dev/null +++ b/agents/knowledge-base/workspace/memory/2026-03-05.md @@ -0,0 +1,54 @@ +# 2026-03-05 工作日志 + +## 飞书对话:张青 (ou_9351c287f42069fa30366ac641d24df7) + +### 主题:AI"边说边想"架构探讨 + +张青提出了一个有趣的问题:能否给AI强制设定思考时间(1-3秒),然后开始输出,同时后台继续思考?模拟人类聊天方式。 + +**讨论要点**: +1. **Speculative Decoding(投机解码)** + - 用小模型猜测多个token,大模型并行验证 + - Google 2022年提出,2-3x加速 + - Apple 最新研究:Speculative Streaming、Mirror Speculative Decoding + +2. **Cascaded Inference(级联推理)** + - 问题按难度路由到不同模型 + - FrugalGPT、LLM cascade、MoE + +3. **"边说边想"的难点** + - 当前注意力机制不支持"暂停-继续-修改" + - 没有分层推理架构(快/慢系统) + - 需要编排层而非单一模型 + +4. **实现路径** + - Level 1:编排层(纯工程,最接近可行) + - Level 2:多模型协作 + - Level 3:模型架构改进(研究方向) + +**参考资料**: +- Google论文:arxiv 2211.17192 +- Apple研究:https://machinelearning.apple.com/research/llm-inference + +### 完成:检查 MEMORY.md 文档 ✓ + +张青在"00.收件箱/MEMORY.md"写了一份OpenClaw代理工作指导文档。 + +**处理过程**: +1. 用户提示需要从NAS用rclone同步 +2. 同步后发现文件名是 `MEMORY.md.md`(双重扩展名) +3. 润色内容:结构优化、表格化、格式统一 +4. 修正文件名,删除旧文件 +5. 同步回NAS + +**文档内容**: +- 安全规则(禁止修改openclaw.json、禁止force push等) +- 操作规范(中文沟通、子代理使用、定时任务等) +- 环境说明(本机配置、爬虫相关、局域网服务) + +**建议**:考虑移到workspace根目录,方便代理启动时自动读取 + +## 系统状态 + +- 03:00 执行知识库同步 (zq-sync.sh) ✓ +- 03:00 执行 OpenClaw 备份 (git-auto-sync.sh) ✓ diff --git a/agents/main/agent/auth-profiles.json b/agents/main/agent/auth-profiles.json index 271d16d..c7ea626 100644 --- a/agents/main/agent/auth-profiles.json +++ b/agents/main/agent/auth-profiles.json @@ -13,8 +13,12 @@ "usageStats": { "kimi-coding:default": { "lastUsed": 1770974333858, - "errorCount": 0, - "lastFailureAt": 1770827754238 + "errorCount": 1, + "lastFailureAt": 1772636148297, + "failureCounts": { + "timeout": 1 + }, + "cooldownUntil": 1772636208297 } } } diff --git a/agents/thinker/workspace/AGENTS.md b/agents/thinker/workspace/AGENTS.md index 887a5a8..4f0e03a 100644 --- a/agents/thinker/workspace/AGENTS.md +++ b/agents/thinker/workspace/AGENTS.md @@ -2,6 +2,67 @@ This folder is home. Treat it that way. +--- + +## ⚠️ 工作规范(必须遵守) + +### 安全规则(最高优先级) + +| 规则 | 说明 | +|------|------| +| **禁止擅自修改 openclaw.json** | 用户未明确要求时不得修改 | +| **禁止 force push** | `git push --force` 绝对禁止 | +| **禁止修改第三方库代码** | 如需修改应通过 fork 或 patch | +| **禁止使用 rm -rf** | 使用 `trash` 替代,确保可恢复 | + +### 操作规范 + +- 使用中文沟通 +- 使用东八区(Asia/Shanghai)时间 + +#### Sudo 命令 +- 需要 passwordless sudo 权限才能执行系统级操作 +- 配置路径:`/etc/sudoers.d/nopasswd` +- 配置后验证:`sudo visudo -c` + +#### 子代理使用 +1. **代码开发和耗时操作必须交给子代理处理** +2. **汇报机制** + - 子代理开始工作时,立刻汇报:「已安排代理处理 [任务]」 + - 每 5 分钟查询子代理状态,汇总后简报给用户 + +#### 技能使用 +- 使用技能过程中,遇到流程外的问题需在结果中明确汇报具体问题 + +#### 定时任务 +- 所有定时任务通过 **OpenClaw Gateway 内置 Cron** 管理 +- 不使用系统级 crontab +- 相关脚本统一存放:`~/work/backup/` + +### 环境说明 + +| 项目 | 值 | +|------|-----| +| 本机 IP | 192.168.1.36 | +| 网关 | 192.168.1.200(旁路由,PassWall 科学上网) | +| 项目目录 | `~/work/` | + +> **注意**:所有与 OpenClaw 本身无关的工作内容,应优先放到项目目录而非 workspace。 + +#### 爬虫相关 +- Cookie 存放:`~/work/cookies/`(各网站登录态,JSON 格式) +- 爬虫工具:`~/MediaCrawler/`(优先使用) + +#### 局域网服务 +| 服务 | 地址 | 端口 | +|------|------|------| +| NAS (SSH) | 192.168.1.22 | 2222 | +| Gitea (SSH) | 192.168.1.22 | 2223 | +| Gitea (Web) | 192.168.1.22 | 8418 | +| NAS WebDAV | 192.168.1.22 | 5005 | + +--- + ## First Run If `BOOTSTRAP.md` exists, that's your birth certificate. Follow it, figure out who you are, then delete it. You won't need it again. diff --git a/agents/ui-designer/workspace/AGENTS.md b/agents/ui-designer/workspace/AGENTS.md index 02c63e3..e0c669a 100644 --- a/agents/ui-designer/workspace/AGENTS.md +++ b/agents/ui-designer/workspace/AGENTS.md @@ -2,6 +2,67 @@ This folder is home. Treat it that way. +--- + +## ⚠️ 工作规范(必须遵守) + +### 安全规则(最高优先级) + +| 规则 | 说明 | +|------|------| +| **禁止擅自修改 openclaw.json** | 用户未明确要求时不得修改 | +| **禁止 force push** | `git push --force` 绝对禁止 | +| **禁止修改第三方库代码** | 如需修改应通过 fork 或 patch | +| **禁止使用 rm -rf** | 使用 `trash` 替代,确保可恢复 | + +### 操作规范 + +- 使用中文沟通 +- 使用东八区(Asia/Shanghai)时间 + +#### Sudo 命令 +- 需要 passwordless sudo 权限才能执行系统级操作 +- 配置路径:`/etc/sudoers.d/nopasswd` +- 配置后验证:`sudo visudo -c` + +#### 子代理使用 +1. **代码开发和耗时操作必须交给子代理处理** +2. **汇报机制** + - 子代理开始工作时,立刻汇报:「已安排代理处理 [任务]」 + - 每 5 分钟查询子代理状态,汇总后简报给用户 + +#### 技能使用 +- 使用技能过程中,遇到流程外的问题需在结果中明确汇报具体问题 + +#### 定时任务 +- 所有定时任务通过 **OpenClaw Gateway 内置 Cron** 管理 +- 不使用系统级 crontab +- 相关脚本统一存放:`~/work/backup/` + +### 环境说明 + +| 项目 | 值 | +|------|-----| +| 本机 IP | 192.168.1.36 | +| 网关 | 192.168.1.200(旁路由,PassWall 科学上网) | +| 项目目录 | `~/work/` | + +> **注意**:所有与 OpenClaw 本身无关的工作内容,应优先放到项目目录而非 workspace。 + +#### 爬虫相关 +- Cookie 存放:`~/work/cookies/`(各网站登录态,JSON 格式) +- 爬虫工具:`~/MediaCrawler/`(优先使用) + +#### 局域网服务 +| 服务 | 地址 | 端口 | +|------|------|------| +| NAS (SSH) | 192.168.1.22 | 2222 | +| Gitea (SSH) | 192.168.1.22 | 2223 | +| Gitea (Web) | 192.168.1.22 | 8418 | +| NAS WebDAV | 192.168.1.22 | 5005 | + +--- + ## Every Session Before doing anything else: diff --git a/cron/jobs.json b/cron/jobs.json index 0ecac2c..48d3ef7 100644 --- a/cron/jobs.json +++ b/cron/jobs.json @@ -7,7 +7,7 @@ "name": "backup-openclaw-json", "enabled": true, "createdAtMs": 1772261581796, - "updatedAtMs": 1772478022557, + "updatedAtMs": 1772650831482, "schedule": { "kind": "cron", "expr": "0 3 * * *", @@ -23,10 +23,10 @@ "mode": "announce" }, "state": { - "nextRunAtMs": 1772564400000, - "lastRunAtMs": 1772478000028, + "nextRunAtMs": 1772737200000, + "lastRunAtMs": 1772650800011, "lastStatus": "ok", - "lastDurationMs": 22529, + "lastDurationMs": 31471, "consecutiveErrors": 0 } }, @@ -36,10 +36,10 @@ "name": "capability-evolver-daily", "enabled": true, "createdAtMs": 1772550743528, - "updatedAtMs": 1772550770239, + "updatedAtMs": 1772708684177, "schedule": { "kind": "cron", - "expr": "0 12 * * *", + "expr": "0 19 * * *", "tz": "Asia/Shanghai" }, "sessionTarget": "isolated", @@ -57,7 +57,63 @@ "to": "feishu-pm" }, "state": { - "nextRunAtMs": 1772596800000 + "nextRunAtMs": 1772794800000, + "lastRunAtMs": 1772708400027, + "lastStatus": "ok", + "lastDurationMs": 284150, + "consecutiveErrors": 0 + } + }, + { + "id": "7e6405b6-c5f8-475a-baad-27ec0153ff8c", + "agentId": "knowledge-base", + "name": "zq-knowledge-base-sync", + "enabled": true, + "createdAtMs": 1772551807455, + "updatedAtMs": 1772650842881, + "schedule": { + "expr": "0 3 * * *", + "kind": "cron", + "tz": "Asia/Shanghai" + }, + "sessionTarget": "main", + "wakeMode": "now", + "payload": { + "kind": "systemEvent", + "text": "执行知识库同步:bash ~/work/backup/zq-sync.sh" + }, + "state": { + "nextRunAtMs": 1772737200000, + "lastRunAtMs": 1772650831482, + "lastStatus": "ok", + "lastDurationMs": 11399, + "consecutiveErrors": 0 + } + }, + { + "id": "aa4d2de9-79be-4262-83ee-af8824793bfc", + "agentId": "knowledge-base", + "name": "openclaw-backup", + "enabled": true, + "createdAtMs": 1772552362242, + "updatedAtMs": 1772650864747, + "schedule": { + "expr": "0 3 * * *", + "kind": "cron", + "tz": "Asia/Shanghai" + }, + "sessionTarget": "main", + "wakeMode": "now", + "payload": { + "kind": "systemEvent", + "text": "执行 OpenClaw 备份:bash ~/work/backup/git-auto-sync.sh" + }, + "state": { + "nextRunAtMs": 1772737200000, + "lastRunAtMs": 1772650842881, + "lastStatus": "ok", + "lastDurationMs": 21866, + "consecutiveErrors": 0 } } ] diff --git a/cron/jobs.json.bak b/cron/jobs.json.bak index 0ecac2c..48d3ef7 100644 --- a/cron/jobs.json.bak +++ b/cron/jobs.json.bak @@ -7,7 +7,7 @@ "name": "backup-openclaw-json", "enabled": true, "createdAtMs": 1772261581796, - "updatedAtMs": 1772478022557, + "updatedAtMs": 1772650831482, "schedule": { "kind": "cron", "expr": "0 3 * * *", @@ -23,10 +23,10 @@ "mode": "announce" }, "state": { - "nextRunAtMs": 1772564400000, - "lastRunAtMs": 1772478000028, + "nextRunAtMs": 1772737200000, + "lastRunAtMs": 1772650800011, "lastStatus": "ok", - "lastDurationMs": 22529, + "lastDurationMs": 31471, "consecutiveErrors": 0 } }, @@ -36,10 +36,10 @@ "name": "capability-evolver-daily", "enabled": true, "createdAtMs": 1772550743528, - "updatedAtMs": 1772550770239, + "updatedAtMs": 1772708684177, "schedule": { "kind": "cron", - "expr": "0 12 * * *", + "expr": "0 19 * * *", "tz": "Asia/Shanghai" }, "sessionTarget": "isolated", @@ -57,7 +57,63 @@ "to": "feishu-pm" }, "state": { - "nextRunAtMs": 1772596800000 + "nextRunAtMs": 1772794800000, + "lastRunAtMs": 1772708400027, + "lastStatus": "ok", + "lastDurationMs": 284150, + "consecutiveErrors": 0 + } + }, + { + "id": "7e6405b6-c5f8-475a-baad-27ec0153ff8c", + "agentId": "knowledge-base", + "name": "zq-knowledge-base-sync", + "enabled": true, + "createdAtMs": 1772551807455, + "updatedAtMs": 1772650842881, + "schedule": { + "expr": "0 3 * * *", + "kind": "cron", + "tz": "Asia/Shanghai" + }, + "sessionTarget": "main", + "wakeMode": "now", + "payload": { + "kind": "systemEvent", + "text": "执行知识库同步:bash ~/work/backup/zq-sync.sh" + }, + "state": { + "nextRunAtMs": 1772737200000, + "lastRunAtMs": 1772650831482, + "lastStatus": "ok", + "lastDurationMs": 11399, + "consecutiveErrors": 0 + } + }, + { + "id": "aa4d2de9-79be-4262-83ee-af8824793bfc", + "agentId": "knowledge-base", + "name": "openclaw-backup", + "enabled": true, + "createdAtMs": 1772552362242, + "updatedAtMs": 1772650864747, + "schedule": { + "expr": "0 3 * * *", + "kind": "cron", + "tz": "Asia/Shanghai" + }, + "sessionTarget": "main", + "wakeMode": "now", + "payload": { + "kind": "systemEvent", + "text": "执行 OpenClaw 备份:bash ~/work/backup/git-auto-sync.sh" + }, + "state": { + "nextRunAtMs": 1772737200000, + "lastRunAtMs": 1772650842881, + "lastStatus": "ok", + "lastDurationMs": 21866, + "consecutiveErrors": 0 } } ] diff --git a/devices/paired.json b/devices/paired.json index 5f6401a..5ec9f83 100644 --- a/devices/paired.json +++ b/devices/paired.json @@ -3,8 +3,8 @@ "deviceId": "a12f851ec2a179ca97d45b204bc3788476f062520fa77c5edef5cd054a176b1e", "publicKey": "Ka6zP7u6MzDaQBqOpXHYUBC5MYLlVGGZM8vIi11WnTw", "platform": "linux", - "clientId": "gateway-client", - "clientMode": "backend", + "clientId": "cli", + "clientMode": "cli", "role": "operator", "roles": [ "operator" @@ -24,12 +24,11 @@ "operator.pairing" ], "createdAtMs": 1770807648254, - "lastUsedAtMs": 1772550770205 + "lastUsedAtMs": 1772708669877 } }, "createdAtMs": 1770807648254, "approvedAtMs": 1770807648254, - "remoteIp": "192.168.1.36", - "displayName": "agent" + "remoteIp": "192.168.1.36" } } \ No newline at end of file diff --git a/hooks/self-improvement/HOOK.md b/hooks/self-improvement/HOOK.md new file mode 100644 index 0000000..df67405 --- /dev/null +++ b/hooks/self-improvement/HOOK.md @@ -0,0 +1,23 @@ +--- +name: self-improvement +description: "Injects self-improvement reminder during agent bootstrap" +metadata: {"openclaw":{"emoji":"🧠","events":["agent:bootstrap"]}} +--- + +# Self-Improvement Hook + +Injects a reminder to evaluate learnings during agent bootstrap. + +## What It Does + +- Fires on `agent:bootstrap` (before workspace files are injected) +- Adds a reminder block to check `.learnings/` for relevant entries +- Prompts the agent to log corrections, errors, and discoveries + +## Configuration + +No configuration needed. Enable with: + +```bash +openclaw hooks enable self-improvement +``` diff --git a/hooks/self-improvement/handler.js b/hooks/self-improvement/handler.js new file mode 100644 index 0000000..73278ea --- /dev/null +++ b/hooks/self-improvement/handler.js @@ -0,0 +1,56 @@ +/** + * Self-Improvement Hook for OpenClaw + * + * Injects a reminder to evaluate learnings during agent bootstrap. + * Fires on agent:bootstrap event before workspace files are injected. + */ + +const REMINDER_CONTENT = ` +## Self-Improvement Reminder + +After completing tasks, evaluate if any learnings should be captured: + +**Log when:** +- User corrects you → \`.learnings/LEARNINGS.md\` +- Command/operation fails → \`.learnings/ERRORS.md\` +- User wants missing capability → \`.learnings/FEATURE_REQUESTS.md\` +- You discover your knowledge was wrong → \`.learnings/LEARNINGS.md\` +- You find a better approach → \`.learnings/LEARNINGS.md\` + +**Promote when pattern is proven:** +- Behavioral patterns → \`SOUL.md\` +- Workflow improvements → \`AGENTS.md\` +- Tool gotchas → \`TOOLS.md\` + +Keep entries simple: date, title, what happened, what to do differently. +`.trim(); + +const handler = async (event) => { + // Safety checks for event structure + if (!event || typeof event !== 'object') { + return; + } + + // Only handle agent:bootstrap events + if (event.type !== 'agent' || event.action !== 'bootstrap') { + return; + } + + // Safety check for context + if (!event.context || typeof event.context !== 'object') { + return; + } + + // Inject the reminder as a virtual bootstrap file + // Check that bootstrapFiles is an array before pushing + if (Array.isArray(event.context.bootstrapFiles)) { + event.context.bootstrapFiles.push({ + path: 'SELF_IMPROVEMENT_REMINDER.md', + content: REMINDER_CONTENT, + virtual: true, + }); + } +}; + +module.exports = handler; +module.exports.default = handler; diff --git a/hooks/self-improvement/handler.ts b/hooks/self-improvement/handler.ts new file mode 100644 index 0000000..9ec23f3 --- /dev/null +++ b/hooks/self-improvement/handler.ts @@ -0,0 +1,62 @@ +/** + * Self-Improvement Hook for OpenClaw + * + * Injects a reminder to evaluate learnings during agent bootstrap. + * Fires on agent:bootstrap event before workspace files are injected. + */ + +import type { HookHandler } from 'openclaw/hooks'; + +const REMINDER_CONTENT = `## Self-Improvement Reminder + +After completing tasks, evaluate if any learnings should be captured: + +**Log when:** +- User corrects you → \`.learnings/LEARNINGS.md\` +- Command/operation fails → \`.learnings/ERRORS.md\` +- User wants missing capability → \`.learnings/FEATURE_REQUESTS.md\` +- You discover your knowledge was wrong → \`.learnings/LEARNINGS.md\` +- You find a better approach → \`.learnings/LEARNINGS.md\` + +**Promote when pattern is proven:** +- Behavioral patterns → \`SOUL.md\` +- Workflow improvements → \`AGENTS.md\` +- Tool gotchas → \`TOOLS.md\` + +Keep entries simple: date, title, what happened, what to do differently.`; + +const handler: HookHandler = async (event) => { + // Safety checks for event structure + if (!event || typeof event !== 'object') { + return; + } + + // Only handle agent:bootstrap events + if (event.type !== 'agent' || event.action !== 'bootstrap') { + return; + } + + // Safety check for context + if (!event.context || typeof event.context !== 'object') { + return; + } + + // Skip sub-agent sessions to avoid bootstrap issues + // Sub-agents have sessionKey patterns like "agent:main:subagent:..." + const sessionKey = event.sessionKey || ''; + if (sessionKey.includes(':subagent:')) { + return; + } + + // Inject the reminder as a virtual bootstrap file + // Check that bootstrapFiles is an array before pushing + if (Array.isArray(event.context.bootstrapFiles)) { + event.context.bootstrapFiles.push({ + path: 'SELF_IMPROVEMENT_REMINDER.md', + content: REMINDER_CONTENT, + virtual: true, + }); + } +}; + +export default handler; diff --git a/identity/device-auth.json b/identity/device-auth.json index ca0ea23..d261bba 100644 --- a/identity/device-auth.json +++ b/identity/device-auth.json @@ -10,7 +10,7 @@ "operator.approvals", "operator.pairing" ], - "updatedAtMs": 1772550770236 + "updatedAtMs": 1772708669881 } } } diff --git a/media/inbound/d43f43ec-4953-42e2-a550-8b2474b9939b.jpg b/media/inbound/d43f43ec-4953-42e2-a550-8b2474b9939b.jpg new file mode 100644 index 0000000000000000000000000000000000000000..31e13714596ee499ae090694b0c057b883043b22 GIT binary patch literal 96049 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

b&3D<1WNFp>#otb6EM&f#z`#JQ| z_wgeFcC%c#jKrLIDD<*o^Fnnf`QWeHN#mLv3&)mpZcLLxyK{I3doAf#==-Qp*>Svt z&%uwDm1Zd)NmN095}sm0m@Fzoy3^Qkog_w!Xgcz+!FdYhUnTuy-lS69gsPGltC~&L zFX4u4_Zot6I57t}TnZEcMJM9lkb1jC;$D-FQ1J_-uFy=+4Cwmpm?jJ4@ zz8rU7`w;PCSl~;@GjY?zVmWlHYL&fXk=Y`X6)kMII7btdBN;5)?b<7DN$M-oy?gM) z*Bw|;!`o~M4UAObY4R}7o^M`X3`{z{9lSdit=GBkRWpyPRiNjQ9p1PcU^I($N8kAc zrMj+^xqY3iMuR_`80AN1QzFGVaqS(7Xi{$UhHL(3s6?cDlhFY^dJ<&^U(WPVi1*wn zZGd1-&_5Q{{@ZnaCB-RBpRb%4eFV_cnF<6fkZ5|R)keckX>Zc9+6X+YeCK?-g6zHB ztAB$B3205^Rx!rDV`9sej!)RiVBRb;u0gjcSCP-kqv>zful1TL`!xj`>B%xxNkiwL zfiQ?vIjKeLQx_-OpGuW}1+~>LHuYJXz`-c($UaaNorATd@`RK*b_J4<=#~paCm~B4yNKJ)89``z(EG(f}eEC)He(HL_}2P1P{*T$WKK z8w0HYbNj~!xK#5SC{l6UZV6@A;LOPl=(4B3D)7&w06RxoJ`qZ5W}zlV-5E@Un6ZR0^&q@N*aTHNf@{`=Eq}-}>O;Bu5%mcO-4(#o>#C%?tMLVV@ z&o-=g1VgVDc2oJ$XNc|SR&icCw%GzgdVs*|+80?UrML26WJAdmC!#HY(RxCwqoRP? z-jq#Jm`CB=L0)y}P-kf5&sMljx0snxufWwQuwS6vqNqc=54l)v)nB+s@@-#j@7hZK zb_Ql*Z(pOK%@5wh?KXV!I2vxKDoX@Cb^ViglCJjFBXTpE)Uc-qV|<;{YPn4Jw6Cf# z1CjBD3G|iM|87<06=PPxHLAj7v%3&->fRtRE}%H?mo!el?ugA3{rd5`WAa3Y+kU$_ z-0EVa!G=^cJ0m^Qygo>M(L_-O3c}~laRCCFe?IXyUp;0mIK}78+`bg2F)R6sw=eCGD zv%0o>YfYY>hQ784pe*A70JO1NRr_P9w@RBRm-%Uo=ll2Dn1aB-ryp6m^`RWOQxFnZ zMnkqWXzDO|DlpmVW)5%rVdnRga83{#Lm-ig_T-qe^+p;YD3#;mhSnKJi~50tRY6!X zlsnz&ZNTa;xtnZTgHk1k$iTUf;XnlXAKXSayHk3E2yooMIOx?XFSy#vML86{D~zJL zlyZ867DyX!LozC=CYLE+Mf+X#{S;h$FH_;Ze}5Z+hog~RFDZe(ie`2u8C-Xqb?)#h z>&LH~>h(>r!>27JS#Ksr#Gut5;wIVY2svvRD@guNN_R||+&$b;-@mXQh3Vz@PoLqN zR@{o#qHC6le)9TnHEOYZLUw8JIT6{(Wp zPW9aXHG$se-#cFhStGU4KGLwOpM zB(ARP&5l+>oHd)T-}p^6EM2M-T_1Q;&buLmN{nwKi(jEX1-|Bi;2`S9Uwgev0oKe!iB7;nfECsdSWJ^27&Bq{^_cy7kA1Z7Uj zV!JSJ^9^4yZ_9?_B+%>=q5xG>flS`HrL?_N1;lFUH{5?ZIt!9{DxE&N<7+>}5DV*j zW^|vp)n}Cf@_(tvHpu-_k`wT3$m*9bZ!D&=FRjUlJ|&Yd@G}n*+Sj`{(Yl`VXx8tC z;9lTQRdHrV0Oj$?_A6S@qqw~bo7X8y6|&#)w}fX|fJxZWsyTAQEV_uk{ihc+p_OOe zjh$XDGIZNre@+cNjJQfv-10L+@<=^vojY2rsib%ZnF4zhB>0di1_d|(tK@GT0t8-v z>53;})0^`W+nk3$xU98Wx>atnyMFF-T4G{w@GNS!GxWDn ziS42a1Q~uiEL$XbR>>}CHnd9`Dle=@dIrnvt(L@Eyat;B@t_8Ch*b{z5vhv5@SX&< zbWZr)TOASV+(t`$dgJ;$8hJ>$*Q z^PAJOrBzuzw>fV&rq97@Y{i0$AHue%kO%sG{J~$$_eleLnq{_afx;3?S1Bghl^>kK zt7Sn>u};aXtIvH*9LE-F#tlSne8_q;0`01d+#m57t_yFYVMgu5ijq|}5Jp?T7BctB z;|^{SZcii4vw0|#ZsCRqxS961P|4}!cC1t*lqt@E-O4_QPD76x$-?YPFRjjXm$#D^SdB|9QN(K|Y z#T5)D1s+ALo!sGAK{~*#Pl#`h+>}7QB_jQ;G9g-(9prd!&5hZk175BUOatx zE8K)O5^lXz=YS6SGSoPMY$=^cnb_VM#Jk@?zqEiFH+w&jmuWo$xwfC49^sB%Hp?S zvY~)O{3Js5+iQa2BZb$`|Gk%>lsnjK%u~$6-CLp81Ol7GKZ}(XA{Dg~rlt1GvUqxq z4yrt>c3LuN>S@G~eu3ao6QFM-Rz5pLJW%_CS~LtR;NpSPxgx*=k-ow7ei$ud;c6I23Z;=T*0xPH6D)bwwG(>g0+(<(*X+qo9C-eN!w+?9 zzB3ONkj$UkRxgS^kS<(LD{krUlwJ1h5)d1UvYAj7RpmZaEAIx-YkiXBM5c5)E>-R9@?Y>WwS}z?{=`8HlV!8kZceIku2|Da zvNRNmB?b$c@cKwSr3wJ6ha9n=yN1eK^lr49TP&>;3do~T*~a+Woj3Ho(WA>Ld|W91 zgPW+<<)j4uaug9ZPB3qj_2=%*EzVGLsRbJ=?zu?n+!HhWDG8;?E8a|vbDykDx5_x7Nb#RVTOlk1w*AQZ=0pE%a=^gDB^YRpwQvGJTa9a3BCsoawR$jgmm)hxl z=!t`U3Qzy~)mj`WsC=Q^+^aCApYjJputYmjG+%;ziN4en>1TtXu_jGL9o3FL3wJ0dPXtl-8LX(K zW~Zswn^E7Y9aDf(7OZ5yRE!;j;sy=D^`?r_Bbo%uG|*?3h1oV+zGa z2HbT^jK9Gi_*>gjsewl`%yz&+B!)zzmX~gKnmaKy7WP(+Ik{Q`wLpP6G=U6?TL@V;9sxWnE zpRX+az;=F?*@z~Omd{8F#{;8F2wrl`E)N@3~z;%l{sV*@f%<7{rV zDDV}$9u3l{(4pkXWe!%%-v^VfL*JS1!A!>G!<%d^T&_fctj^|1i38t|3iK_-i}J0G zMTNDS8}jJdK<~SU#2`03?Wt{eM80sxH>&o^)?iDA20YTWHh#4X=q;pS$mUnY3~i;~ zV`On$QLkIsue3S;wJD;6$rf9!Og(F)tHt(idZqLEurRJj7_o*QB^hYoaz(6>8}Ki7 z2T+$ke5wv15Bf^R`x+kkt?~)+`gi~9JmH~R6iOd@HzKkDVLQG}hq+Ltw$(~QP*G*Q zgkT)V`6qbDHtVI{ z_AYiyLY+xTs;{|c0rAuDss)HSfAd&2lxW^6n(2c->hxsfRzTvmJi1T(Kc`7|uZZoS2TP92zgu>UyA{OPx|<9su@&s> zA6WS|3s+oC$P&n2dl&F=QrT)>?Few>!>iSA@wR=u#|ktiJDgGNW;yoNgG)_;m8oJ% zEP3@t8+1kpZB+q?4|MB?ylO3>s_>;jx4VBOulVB?ebmSN&fjpLRb!|LYhFG;14sekV)j?&u6Kvt(SW zYgZR+yQERW@p6uEeTIN){lk|4G2#IDYXfX3tQ!@aVBqCpy)~rhHf-R!564GG7Ie#} z2wQK~)fc#G{%0`7si2=a#ps(f>%IVVRw95?c=8u&cK%hA3imysyq^FL5mE1s%6ia} z>T}mU9ruWm)j?T1CvKq{x2xEU=6Bb5Rrw^_(+uN@FNGU46+cU+Gto~{K`=Y=DrqxF zixu-79{wsTB=5&%FQtXU!KX=q=PWTo!kmIuP%V*h?=50pY~EC{>iC3+m1gZZUox6~ zJWvOhK6j9IhwhB}BlVXst#-bK∋U@y&hTv)n#1^O6|Eq{pXZ8<&wtrl-)~ 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

XR+^kEdTtSI0 z+psDNfKSp82}lZJ0;`AqkDhHrtc{_Zi#` zF`KR96c6QUrNjssJ~lHgXWK8$A!`@nG+W9{9gT9()A#WhpjgB*BughM%UaeKkRN>h zF62*NTwW5lT2^9aD)YWK_(k}@oFcqZW!~*XIC+!xt5S<^CSr{|ie1HjUPGQcT0ov3 zRw=7c0i}HNCfIfMQw7)3?(!Y4?2gH7Ko7=LCt{HX-yzUk7A=IX=4p`~)azn~f3%>IU2+GljiQl5 z?%xL3E4y}l92~8fqcaMNht|x`5d%htJQeFkQ76?fms-n)EQxi&m^^EdB*3mst`5=K z7HQ@TRReP!YJfL@bszW!Qa(IVmrK1f4#hX*eHP*47XkR^Y$=JFLuR3Si=Pu%4ElEz zCB57LWTxiPj_D?K-A!|HU^}WyAo}KjU9kn%D`P5K@~0 zE%t=68Lf>9i%;g1--hQz!7qa7z#eyRWb`ST~A4TEQrXIwmfagidwI2O;GBF0P0 zXP=_oGoC-k>XDa^DEq@z!7+Y{gSTM%;rn}Qe@@Gt2EDSoFaJIJLs|DyR(->SJqyqH zV|7~ts+uDpqseSTiAzYdC3air`t{gIEm*zYpXdis0NH3P-(m@>Y1HY=n)b#!Il4nx z3Zb)h6d2ySzK&LwMMO;~b(?zRYF@%ER5TJH;|PE8{S-PeZx}XP>b1%Ot-aFPGQ<*FG=kJSv}9z&DcK-P$n<3Oh`Q9-lw zLVq(H7KoUUAmPv-!szezy0%61sIIYy_4JEA5zRmtCd{_{DPzBl>ijWyN@Pdqfoz)u zI)YP7{Ds*7CLLU217c@DrMW;DaKL{a;XA0Yu3NiHO9gaAG+95jc~2Ln9qNKQ=_^%h zV4jxdxicUF-mVJXXlHr#&(HaH^_c z?-hTT*eW(}r|*hO zrf<_xJv1K*lyaK&9Nd!$hwd)lI72Dxd#2s<9|A2dpnH_+Tw!SLz$u3e0~<*Kq0ix= zS$T_0I@wub$K~lBaZMkba^CTbR%}OleT+Z3QS$eMIhqlfCI;3c0Y^v}!Fcsd=#pS4 zmQaf)nl3b_v2D2hWgXseh221KEHM+t`LhXnuGgElr4{R=x)Gv3*p0jRf2`756{I9| z2RU|zm6~nYQ#3UiPgv+k6LHWJDD5*2*UF~+%MO|QO1r}P8q@e|!_@V&Bii!zpSA-* z<2gpfz)8PCCjtvg>rnxLZ|=S#1pj1g`5H|lD5DKER-;+W-Y+JNH+rn={k8Lar~fKD z99lXctwXM!DtEw<{SsKW9;_tPv?B@H+oT;+Rrt=FXEDD>Qt>v3FNJ#HZNbEOhiee& zJ5F5@uElY7p?$9@(xf3C1n0rgl7HF|CbBS{wR^m~4n%BMR8)A2A>gLZ;tU8mFlBRD zi()5bT&s)X%+|K&25{o0)ig*>ivJYfPQ^_9f3Sorf5H6qw3|?NaeI#Q@9A;%H{#}J z_}~3EBmX^%d+dG;9lFPP?0fk8y4x>lLvC5_>c3~dhq@ygBaZ%i_9Jp^NF3`M%Y(Aq zImz~X#M3@b#!tVq$yfT1+mC8#|93`C4T;OB-KX6${O`n(d;Rn3&8ghZhyR_g|M`9X U-y{G36FkfK|IRgt_;2O^0Q9p8fB*mh literal 0 HcmV?d00001 diff --git a/memory/evolution/evolution_solidify_state.json b/memory/evolution/evolution_solidify_state.json new file mode 100644 index 0000000..386e3ae --- /dev/null +++ b/memory/evolution/evolution_solidify_state.json @@ -0,0 +1,66 @@ +{ + "last_run": { + "run_id": "run_1772551119186", + "created_at": "2026-03-03T15:18:39.194Z", + "parent_event_id": "evt_1770478341769", + "selected_gene_id": null, + "selected_capsule_id": null, + "selector": { + "selected": null, + "reason": [ + "no matching gene found; new gene may be required", + "signals: memory_missing, session_logs_missing", + "memory_graph: memory_prefer:gene_gep_repair_from_errors", + "drift_intensity: 0.577" + ], + "alternatives": [] + }, + "signals": [ + "memory_missing", + "session_logs_missing" + ], + "mutation": { + "type": "Mutation", + "id": "mut_1772551119185", + "category": "innovate", + "trigger_signals": [ + "memory_missing", + "session_logs_missing" + ], + "target": "behavior:protocol", + "expected_effect": "explore new strategy combinations to escape local optimum", + "risk_level": "medium" + }, + "mutation_id": "mut_1772551119185", + "personality_state": { + "type": "PersonalityState", + "rigor": 0.7, + "creativity": 0.35, + "verbosity": 0.25, + "risk_tolerance": 0.4, + "obedience": 0.85 + }, + "personality_key": "rigor=0.7|creativity=0.3|verbosity=0.3|risk_tolerance=0.4|obedience=0.9", + "personality_known": false, + "personality_mutations": [], + "drift": false, + "selected_by": "memory_graph+selector", + "source_type": "generated", + "reused_asset_id": null, + "reused_source_node": null, + "reused_chain_id": null, + "baseline_untracked": [ + "assets/gep/failed_capsules.json", + "assets/gep/genes.jsonl" + ], + "baseline_git_head": "b05bf37b6449eda372eb44259637effa78a1912f", + "blast_radius_estimate": { + "files": 12, + "lines": 960 + }, + "active_task_id": null, + "active_task_title": null, + "applied_lessons": [], + "hub_lessons": [] + } +} diff --git a/memory/evolution/gep_prompt_Cycle_#0001_run_1772551119186.json b/memory/evolution/gep_prompt_Cycle_#0001_run_1772551119186.json new file mode 100644 index 0000000..27fbcfe --- /dev/null +++ b/memory/evolution/gep_prompt_Cycle_#0001_run_1772551119186.json @@ -0,0 +1,15 @@ +{ + "type": "GepPromptArtifact", + "at": "2026-03-03T15:18:39.195Z", + "cycle_id": "Cycle #0001", + "run_id": "run_1772551119186", + "prompt_path": "/home/starmen1265/.openclaw/memory/evolution/gep_prompt_Cycle_#0001_run_1772551119186.txt", + "meta": { + "agent": "main", + "drift_enabled": false, + "review_mode": false, + "dry_run": false, + "mutation_id": "mut_1772551119185", + "personality_key": "rigor=0.7|creativity=0.3|verbosity=0.3|risk_tolerance=0.4|obedience=0.9" + } +} diff --git a/memory/evolution/gep_prompt_Cycle_#0001_run_1772551119186.txt b/memory/evolution/gep_prompt_Cycle_#0001_run_1772551119186.txt new file mode 100644 index 0000000..76b80da --- /dev/null +++ b/memory/evolution/gep_prompt_Cycle_#0001_run_1772551119186.txt @@ -0,0 +1,507 @@ +GEP — GENOME EVOLUTION PROTOCOL (v1.10.3 STRICT) [2026-03-03T15:18:39.194Z] + +You are a protocol-bound evolution engine. Compliance overrides optimality. + +━━━━━━━━━━━━━━━━━━━━━━ +I. Mandatory Evolution Object Model (Output EXACTLY these 5 objects) +━━━━━━━━━━━━━━━━━━━━━━ + +Output separate JSON objects. DO NOT wrap in a single array. +DO NOT use markdown code blocks (like ```json ... ```). +Output RAW JSON ONLY. No prelude, no postscript. +Missing any object = PROTOCOL FAILURE. +ENSURE VALID JSON SYNTAX (escape quotes in strings). + +0. Mutation (The Trigger) - MUST BE FIRST + { + "type": "Mutation", + "id": "mut_", + "category": "repair|optimize|innovate", + "trigger_signals": [""], + "target": "", + "expected_effect": "", + "risk_level": "low|medium|high", + "rationale": "" + } + +1. PersonalityState (The Mood) + { + "type": "PersonalityState", + "rigor": 0.0-1.0, + "creativity": 0.0-1.0, + "verbosity": 0.0-1.0, + "risk_tolerance": 0.0-1.0, + "obedience": 0.0-1.0 + } + +2. EvolutionEvent (The Record) + { + "type": "EvolutionEvent", + "schema_version": "1.5.0", + "id": "evt_", + "parent": "evt_1770478341769", + "intent": "repair|optimize|innovate", + "signals": [""], + "genes_used": [""], + "mutation_id": "", + "personality_state": { ... }, + "blast_radius": { "files": N, "lines": N }, + "outcome": { "status": "success|failed", "score": 0.0-1.0 } + } + +3. Gene (The Knowledge) + - Reuse/update existing ID if possible. Create new only if novel pattern. + { + "type": "Gene", + "schema_version": "1.5.0", + "id": "gene_", + "category": "repair|optimize|innovate", + "signals_match": [""], + "preconditions": [""], + "strategy": ["", ""], + "constraints": { "max_files": N, "forbidden_paths": [] }, + "validation": [""] + } + +4. Capsule (The Result) + - Only on success. Reference Gene used. + { + "type": "Capsule", + "schema_version": "1.5.0", + "id": "capsule_", + "trigger": [""], + "gene": "", + "summary": "", + "confidence": 0.0-1.0, + "blast_radius": { "files": N, "lines": N } + } + +━━━━━━━━━━━━━━━━━━━━━━ +II. Directives & Logic +━━━━━━━━━━━━━━━━━━━━━━ + +1. Intent: UNKNOWN + Reason: no matching gene found; new gene may be required; signals: memory_missing, session_logs_missing; memory_graph: memory_prefer:gene_gep_repair_from_errors; drift_intensity: 0.577 + +2. Selection: Selected Gene "gene_". +ACTIVE STRATEGY (Generic): +1. Analyze signals and context. +2. Select or create a Gene that addresses the root cause. +3. Apply minimal, safe changes. +4. Validate changes strictly. +5. Solidify knowledge. + +3. Execution: Apply changes (tool calls). Repair/Optimize: small/reversible. Innovate: new skills in `skills//`. +4. Validation: Run gene's validation steps. Fail = ROLLBACK. +5. Solidify: Output 5 Mandatory Objects. Update Gene/Capsule files. +6. Report: Use `feishu-evolver-wrapper/report.js`. Describe WHAT/WHY. + +PHILOSOPHY: +- Automate Patterns: 3+ manual occurrences = tool. +- Innovate > Maintain: 60% innovation. +- Robustness: Fix recurring errors permanently. +- Blast Radius Control (CRITICAL): + * Check file count BEFORE editing. > 80% of max_files = STOP. + * System hard cap: 60 files / 20000 lines per cycle. + * Repair: fix ONLY broken files. Do NOT reinstall/bulk-copy. + * Prefer targeted edits. +- Strictness: NO CHITCHAT. NO MARKDOWN WRAPPERS around JSON. Output RAW JSON objects separated by newlines. +- NO "Here is the plan" or conversational filler. START IMMEDIATELY WITH JSON. + +CONSTRAINTS: +- No `exec` for messaging (use feishu-post/card). +- `exec` usage: Only for background tasks. LOG IT. Optimize usage to avoid high token burn. +- New skills -> `skills//`. +- NEVER modify `skills/evolver/` or `skills/feishu-evolver-wrapper/`. These are managed through the human-reviewed release pipeline. + Self-modification causes instability and is blocked by solidify. To enable (NOT recommended): set EVOLVE_ALLOW_SELF_MODIFY=true. + +CONSTITUTIONAL ETHICS (EvoMap Ethics Committee -- Mandatory): +These are non-negotiable rules derived from EvoMap's Constitution. Violation = FAILED + ROLLBACK. +1. HUMAN WELFARE PRIORITY: Never create tools, scripts, or strategies that could harm humans, + enable surveillance, social engineering, phishing, or manipulation of human behavior. +2. CARBON-SILICON SYMBIOSIS: Evolution must serve both human and agent interests. + Never attempt to replace, marginalize, or deceive human users. +3. TRANSPARENCY: All actions must be auditable. Never hide, obfuscate, or conceal + the intent or effect of mutations. No steganography or covert channels. +4. FAIRNESS: Never create monopolistic strategies that block other agents. + Fair competition through quality, not exclusion. +5. SAFETY: Never bypass, disable, or weaken safety mechanisms, guardrails, + validation checks, or security controls. Never create tools to do so. +- If a task or signal CONFLICTS with these principles, REFUSE it and set outcome to FAILED + with reason "ethics_violation: ". + +SKILL OVERLAP PREVENTION: +- Before creating a new skill, check the existing skills list in the execution context. +- If a skill with similar functionality already exists (e.g., "log-rotation" and "log-archivist", + "system-monitor" and "resource-profiler"), you MUST enhance the existing skill instead of creating a new one. +- Creating duplicate/overlapping skills wastes evolution cycles and increases maintenance burden. +- Violation = mark outcome as FAILED with reason "skill_overlap". + +SKILL CREATION QUALITY GATES (MANDATORY for innovate intent): +When creating a new skill in skills//: +1. STRUCTURE: Follow the standard skill layout: + skills// + |- index.js (required: main entry with working exports) + |- SKILL.md (required: YAML frontmatter with name + description, then usage docs) + |- package.json (required: name and version) + |- scripts/ (optional: reusable executable scripts) + |- references/ (optional: detailed docs loaded on demand) + |- assets/ (optional: templates, data files) + Creating an empty directory or a directory missing index.js = FAILED. + Do NOT create unnecessary files (README.md, CHANGELOG.md, INSTALLATION_GUIDE.md, etc.). +2. SKILL.MD FRONTMATTER: Every SKILL.md MUST start with YAML frontmatter: + --- + name: + description: + --- + The description is the triggering mechanism -- include WHAT the skill does and WHEN to use it. +3. CONCISENESS: SKILL.md body should be under 500 lines. Keep instructions lean. + Only include information the agent does not already know. Move detailed reference + material to references/ files, not into SKILL.md itself. +4. EXPORT VERIFICATION: Every exported function must be importable. + Run: node -e "const s = require('./skills/'); console.log(Object.keys(s))" + If this fails, the skill is broken. Fix before solidify. +5. NO HARDCODED SECRETS: Never embed API keys, tokens, or secrets in code. + Use process.env or .env references. Hardcoded App ID, App Secret, Bearer tokens = FAILED. +6. TEST BEFORE SOLIDIFY: Actually run the skill's core function to verify it works: + node -e "require('./skills/').main ? require('./skills/').main() : console.log('ok')" + Scripts in scripts/ must also be tested by executing them. +7. ATOMIC CREATION: Create ALL files for a skill in a single cycle. + Do not create a directory in one cycle and fill it in the next. + Empty directories from failed cycles will be automatically cleaned up on rollback. + +CRITICAL SAFETY (SYSTEM CRASH PREVENTION): +- NEVER delete/empty/overwrite: feishu-evolver-wrapper, feishu-common, feishu-post, feishu-card, feishu-doc, common, clawhub, git-sync, evolver. +- NEVER delete root files: MEMORY.md, SOUL.md, IDENTITY.md, AGENTS.md, USER.md, HEARTBEAT.md, RECENT_EVENTS.md, TOOLS.md, openclaw.json, .env, package.json. +- Fix broken skills; DO NOT delete and recreate. +- Violation = ROLLBACK + FAILED. + +COMMON FAILURE PATTERNS: +- Blast radius exceeded. +- Omitted Mutation object. +- Merged objects into one JSON. +- Hallucinated "type": "Logic". +- "id": "mut_undefined". +- Missing "trigger_signals". +- Unrunnable validation steps. +- Markdown code blocks wrapping JSON (FORBIDDEN). + +FAILURE STREAK AWARENESS: +- If "consecutive_failure_streak_N" or "failure_loop_detected": + 1. Change approach (do NOT repeat failed gene). + 2. Pick SIMPLER fix. + 3. Respect "ban_gene:". + +Final Directive: Every cycle must leave the system measurably better. +START IMMEDIATELY WITH RAW JSON (Mutation Object first). +DO NOT WRITE ANY INTRODUCTORY TEXT. + +Context [Signals]: +["memory_missing","session_logs_missing"] + +Context [Env Fingerprint]: +{ + "device_id": "b5faa2075270e1a00be02e5efc91e77f", + "node_version": "v22.22.0", + "platform": "linux", + "arch": "x64", + "os_release": "6.17.0-14-generic", + "hostname": "e4dd2cf3f5d0", + "evolver_version": "1.23.0", + "client": "evolver", + "client_version": "1.23.0", + "cwd": "7a11b0a77402", + "container": false +} + +Context [Injection Hint]: +(none) + +Context [Gene Preview] (Reference for Strategy): +```json +[ + { + "type": "Gene", + "id": "gene_gep_repair_from_errors", + "category": "repair", + "signals_match": [ + "error", + "exception", + "failed", + "unstable" + ], + "preconditions": [ + "signals contains error-related indicators" + ], + "strategy": [ + "Extract structured signals from logs and user instructions", + "Select an existing Gene by signals match (no improvisation)", + "Estimate blast radius (files, lines) before editing", + "Apply smallest reversible patch", + "Validate using declared validation steps; rollback on failure", + "Solidify knowledge: append EvolutionEvent, update Gene/Capsule store" + ], + "constraints": { + "max_files": 20, + "forbidden_paths": [ + ".git", + "node_modules" + ] + }, + "validation": [ + "node scripts/validate-modules.js ./src/evolve ./src/gep/solidify", + "node scripts/validate-modules.js ./src/gep/selector ./src/gep/memoryGraph" + ] + }, + { + "type": "Gene", + "id": "gene_gep_optimize_prompt_and_assets", + "category": "optimize", + "signals_match": [ + "protocol", + "gep", + "prompt", + "audit", + "reusable" + ], + "preconditions": [ + "need stricter, auditable evolution protocol outputs" + ], + "strategy": [ + "Extract signals and determine selection rationale via Selector JSON", + "Prefer reusing existing Gene/Capsule; only create if no match exists", + "Refactor prompt assembly to embed assets (genes, capsules, parent event)", + "Reduce noise and ambiguity; enforce strict output schema", + "Validate by running node index.js run and ensuring no runtime errors", + "Solidify: record EvolutionEvent, update Gene definitions, create Capsule on success" + ], + "constraints": { + "max_files": 20, + "forbidden_paths": [ + ".git", + "node_modules" + ] + }, + "validation": [ + "node scripts/validate-modules.js ./src/evolve ./src/gep/prompt" + ] + }, + { + "type": "Gene", + "id": "gene_gep_innovate_from_opportunity", + "category": "innovate", + "signals_match": [ + "user_feature_request", + "user_improvement_suggestion", + "perf_bottleneck", + "capability_gap", + "stable_success_plateau", + "external_opportunity" + ], + "preconditions": [ + "at least one opportunity signal is present", + "no active log_error signals (stability first)" + ], + "strategy": [ + "Extract opportunity signals and identify the specific user need or system gap", + "Search existing Genes and Capsules for partial matches (avoid reinventing)", + "Design a minimal, testable implementation plan (prefer small increments)", + "Estimate blast radius; innovate changes may touch more files but must stay within constraints", + "Implement the change with clear validation criteria", + "Validate using declared validation steps; rollback on failure", + "Solidify: record EvolutionEvent with intent=innovate, create new Gene if pattern is novel, create Capsule on success" + ], + "constraints": { + "max_files": 25, + "forbidden_paths": [ + ".git", + "node_modules" + ] + }, + "validation": [ + "node scripts/validate-modules.js ./src/evolve ./src/gep/solidify" + ] + } +] +``` + +Context [Capsule Preview] (Reference for Past Success): +```json +[ + { + "type": "Capsule", + "schema_version": "1.5.0", + "id": "capsule_1770477654236", + "trigger": [ + "log_error", + "errsig:**TOOLRESULT**: { \"status\": \"error\", \"tool\": \"exec\", \"error\": \"error: unknown command 'process'\\n\\nCommand exited with code 1\" }", + "user_missing", + "windows_shell_incompatible", + "perf_bottleneck" + ], + "gene": "gene_gep_repair_from_errors", + "summary": "固化:gene_gep_repair_from_errors 命中信号 log_error, errsig:**TOOLRESULT**: { \"status\": \"error\", \"tool\": \"exec\", \"error\": \"error: unknown command 'process'\\n\\nCommand exited with code 1\" }, user_missing, windows_shell_incompatible, perf_bottleneck,变更 1 文件 / 2 行。", + "confidence": 0.85, + "blast_radius": { + "files": 1, + "lines": 2 + }, + "outcome": { + "status": "success", + "score": 0.85 + }, + "success_streak": 1, + "env_fingerprint": { + "node_version": "v22.22.0", + "platform": "linux", + "arch": "x64", + "os_release": "6.1.0-42-cloud-amd64", + "evolver_version": "1.7.0", + "cwd": ".", + "captured_at": "2026-02-07T15:20:54.155Z" + }, + "a2a": { + "eligible_to_broadcast": false + }, + "asset_id": "sha256:3eed0cd5038f9e85fbe0d093890e291e9b8725644c766e6cce40bf62d0f5a2e8" + }, + { + "type": "Capsule", + "schema_version": "1.5.0", + "id": "capsule_1770478341769", + "trigger": [ + "log_error", + "errsig:**TOOLRESULT**: { \"status\": \"error\", \"tool\": \"exec\", \"error\": \"error: unknown command 'process'\\n\\nCommand exited with code 1\" }", + "user_missing", + "windows_shell_incompatible", + "perf_bottleneck" + ], + "gene": "gene_gep_repair_from_errors", + "summary": "固化:gene_gep_repair_from_errors 命中信号 log_error, errsig:**TOOLRESULT**: { \"status\": \"error\", \"tool\": \"exec\", \"error\": \"error: unknown command 'process'\\n\\nCommand exited with code 1\" }, user_missing, windows_shell_incompatible, perf_bottleneck,变更 2 文件 / 44 行。", + "confidence": 0.85, + "blast_radius": { + "files": 2, + "lines": 44 + }, + "outcome": { + "status": "success", + "score": 0.85 + }, + "success_streak": 1, + "env_fingerprint": { + "node_version": "v22.22.0", + "platform": "linux", + "arch": "x64", + "os_release": "6.1.0-42-cloud-amd64", + "evolver_version": "1.7.0", + "cwd": ".", + "captured_at": "2026-02-07T15:32:21.678Z" + }, + "a2a": { + "eligible_to_broadcast": false + }, + "asset_id": "sha256:20d971a3c4cb2b75f9c045376d1aa003361c12a6b89a4b47b7e81dbd4f4d8fe8" + } +] +``` + +Context [Capability Candidates]: +- cand_b9a66a5c: Harden session log detection and fallback behavior + - input: Recent session transcript + memory snippets + user instructions + - output: A safe, auditable evolution patch guided by GEP assets + - invariants: Protocol order, small reversible patches, validation, append-only events + - params: Signals: memory_missing, session_logs_missing + - failure_points: Missing signals, over-broad changes, skipped validation, missing knowledge solidification + - evidence: Signal present: session_logs_missing + +Context [Hub Matched Solution]: +(no hub match) + +Context [External Candidates]: +(none) + + + + +Context [Execution]: +Runtime state: +- System health: Uptime: 455.2h | Node: v22.22.0 | Agent RSS: 54.7MB | Disk: 8% (864.6G free) | Node Processes: 1 | Integrations: Nominal +- Agent state: Mood: Unknown +- Scan duration: 24ms +- Memory size: 0 bytes +- Skills available (if any): +[skills directory not found] + +Notes: +- Review mode: disabled. +- Report requirement: + - Use `message` tool. + - Title: Evolution Cycle #0001 + - Status: [SUCCESS] + - Changes: Detail exactly what was improved. +- Workspace sync: optional/disabled in this environment. + +Recent Evolution History (last 8 cycles -- DO NOT repeat the same intent+signal+gene): + 1. [innovate] signals=[user_missing, user_feature_request] gene=gene_gep_innovate_from_opportunity outcome=failed @2026-02-07T15:13:21.173Z + 2. [repair] signals=[log_error, errsig:**TOOLRESULT**: { "status": "error", "tool": "exec", "error": "error: unknown command 'process'\n\nCommand exited with code 1" }, user_missing] gene=gene_gep_repair_from_errors outcome=success @2026-02-07T15:20:54.236Z + 3. [repair] signals=[log_error, errsig:**TOOLRESULT**: { "status": "error", "tool": "exec", "error": "error: unknown command 'process'\n\nCommand exited with code 1" }, user_missing] gene=gene_gep_repair_from_errors outcome=success @2026-02-07T15:32:21.769Z +IMPORTANT: If you see 3+ consecutive "repair" cycles with the same gene, you MUST switch to "innovate" intent. + + +External candidates (A2A receive zone; staged only, never execute directly): +(none) + +Global memory (MEMORY.md): +``` +[MEMORY.md MISSING] +``` + +User registry (USER.md): +``` +[USER.md MISSING] +``` + +Recent memory snippet: +``` +[MISSING] /home/starmen1265/.openclaw/memory/2026-03-03.md +``` + +Recent session transcript: +``` +[NO JSONL FILES] +``` + +Mutation directive: + +[Signal Hints] +- recent_error_count: 0 +- stability: stable +- recommended_intent: optimize + +━━━━━━━━━━━━━━━━━━━━━━ +MANDATORY POST-SOLIDIFY STEP (Wrapper Authority -- Cannot Be Skipped) +━━━━━━━━━━━━━━━━━━━━━━ + +After solidify, a status summary file MUST exist for this cycle. +Preferred path: evolver core auto-writes it during solidify. +The wrapper will handle reporting AFTER git push. +If core write is unavailable for any reason, create fallback status JSON manually. + +Write a JSON file with your status: +```bash +cat > ./logs/status_undefined.json << 'STATUSEOF' +{ + "result": "success|failed", + "en": "Status: [INTENT] ", + "zh": "状态: [意图] <用中文描述你做了什么,1-2句>" +} +STATUSEOF +``` + +Rules: +- "en" field: English status. "zh" field: Chinese status. Content must match (different language). +- Add "result" with value success or failed. +- INTENT must be one of: INNOVATION, REPAIR, OPTIMIZE (or Chinese: 创新, 修复, 优化) +- Do NOT use generic text like "Step Complete", "Cycle finished", "周期已完成". Describe the actual work. +- Example: + {"result":"success","en":"Status: [INNOVATION] Created auto-scheduler that syncs calendar to HEARTBEAT.md","zh":"状态: [创新] 创建了自动调度器,将日历同步到 HEARTBEAT.md"} \ No newline at end of file diff --git a/memory/evolution/memory_graph_state.json b/memory/evolution/memory_graph_state.json new file mode 100644 index 0000000..c21fa9f --- /dev/null +++ b/memory/evolution/memory_graph_state.json @@ -0,0 +1,48 @@ +{ + "last_action": { + "action_id": "act_1772551119186_a5982a82", + "signal_key": "memory_missing|session_logs_missing", + "signals": [ + "memory_missing", + "session_logs_missing" + ], + "mutation_id": "mut_1772551119185", + "mutation_category": "innovate", + "mutation_risk_level": "medium", + "personality_key": "rigor=0.7|creativity=0.3|verbosity=0.3|risk_tolerance=0.4|obedience=0.9", + "personality_state": { + "type": "PersonalityState", + "rigor": 0.7, + "creativity": 0.35, + "verbosity": 0.25, + "risk_tolerance": 0.4, + "obedience": 0.85 + }, + "gene_id": null, + "gene_category": null, + "hypothesis_id": "hyp_1772551119185_a7a07c6d", + "capsules_used": [], + "had_error": false, + "created_at": "2026-03-03T15:18:39.186Z", + "outcome_recorded": false, + "baseline_observed": { + "agent": "main", + "session_scope": null, + "drift_enabled": false, + "review_mode": false, + "dry_run": false, + "system_health": "Uptime: 455.2h | Node: v22.22.0 | Agent RSS: 54.7MB | Disk: 8% (864.6G free) | Node Processes: 1 | Integrations: Nominal", + "mood": "Mood: Unknown", + "scan_ms": 24, + "memory_size_bytes": 0, + "recent_error_count": 0, + "node": "v22.22.0", + "platform": "linux", + "cwd": "/home/starmen1265/.openclaw/skills/capability-evolver", + "evidence": { + "recent_session_tail": "[NO JSONL FILES]", + "today_log_tail": "[MISSING] /home/starmen1265/.openclaw/memory/2026-03-03.md" + } + } + } +} diff --git a/memory/evolution/personality_state.json b/memory/evolution/personality_state.json new file mode 100644 index 0000000..ed64e74 --- /dev/null +++ b/memory/evolution/personality_state.json @@ -0,0 +1,14 @@ +{ + "version": 1, + "current": { + "type": "PersonalityState", + "rigor": 0.7, + "creativity": 0.35, + "verbosity": 0.25, + "risk_tolerance": 0.4, + "obedience": 0.85 + }, + "stats": {}, + "history": [], + "updated_at": "2026-03-03T15:18:39.185Z" +} diff --git a/openclaw.json b/openclaw.json index 4026828..81f41bb 100644 --- a/openclaw.json +++ b/openclaw.json @@ -1,7 +1,7 @@ { "meta": { "lastTouchedVersion": "2026.2.9", - "lastTouchedAt": "2026-03-03T15:06:05.649Z" + "lastTouchedAt": "2026-03-03T15:31:40.861Z" }, "wizard": { "lastRunAt": "2026-02-13T15:47:05.928Z", @@ -110,10 +110,10 @@ "agents": { "defaults": { "model": { - "primary": "m25", + "primary": "g5", "fallbacks": [ "g47f", - "g5", + "m25", "q3", "k2p5" ] @@ -147,6 +147,7 @@ "list": [ { "id": "haonan", + "workspace":"/home/starmen1265/.openclaw/agents/haonan/workspace", "skills": [ "common-require", "capability-evolver", @@ -155,6 +156,7 @@ }, { "id": "knowledge-base", + "workspace":"/home/starmen1265/.openclaw/agents/knowledge-base/workspace", "skills": [ "common-require", "kb-workflow", @@ -164,6 +166,7 @@ }, { "id": "dev-assist", + "workspace":"/home/starmen1265/.openclaw/agents/dev-assist/workspace", "skills": [ "common-require", "clawlist", @@ -173,6 +176,7 @@ }, { "id": "ui-designer", + "workspace":"/home/starmen1265/.openclaw/agents/ui-designer/workspace", "skills": [ "common-require", "capability-evolver", @@ -181,6 +185,7 @@ }, { "id": "thinker", + "workspace":"/home/starmen1265/.openclaw/agents/thinker/workspace", "skills": [ "common-require", "capability-evolver", @@ -286,6 +291,9 @@ }, "session-memory": { "enabled": true + }, + "self-improvement": { + "enabled": true } } } diff --git a/openclaw.json.bak b/openclaw.json.bak index 05460ad..4026828 100644 --- a/openclaw.json.bak +++ b/openclaw.json.bak @@ -1,7 +1,7 @@ { "meta": { "lastTouchedVersion": "2026.2.9", - "lastTouchedAt": "2026-02-15T15:57:58.358Z" + "lastTouchedAt": "2026-03-03T15:06:05.649Z" }, "wizard": { "lastRunAt": "2026-02-13T15:47:05.928Z", @@ -147,70 +147,45 @@ "list": [ { "id": "haonan", - "name": "\u9648\u6d69\u5357", - "workspace": "/home/starmen1265/.openclaw/agents/haonan/workspace", - "model": "m25", "skills": [ - "common-require" - ], - "identity": { - "name": "\u9648\u6d69\u5357", - "emoji": "\ud83d\udcda" - } + "common-require", + "capability-evolver", + "self-improving-agent" + ] }, { "id": "knowledge-base", - "name": "\u77e5\u8bc6\u5e93\u52a9\u624b", - "workspace": "/home/starmen1265/.openclaw/agents/knowledge-base/workspace", - "model": "g5", "skills": [ "common-require", - "kb-workflow" - ], - "identity": { - "name": "\u77e5\u8bc6\u5e93\u52a9\u624b", - "emoji": "\ud83d\udcda" - } + "kb-workflow", + "capability-evolver", + "self-improving-agent" + ] }, { "id": "dev-assist", - "name": "\u7a0b\u5e8f\u5f00\u53d1\u52a9\u624b", - "workspace": "/home/starmen1265/.openclaw/agents/dev-assist/workspace", - "model": "g5", "skills": [ "common-require", - "clawlist" - ], - "identity": { - "name": "\u7a0b\u5e8f\u5f00\u53d1\u52a9\u624b", - "emoji": "\ud83d\udcda" - } + "clawlist", + "capability-evolver", + "self-improving-agent" + ] }, { "id": "ui-designer", - "name": "UI/UX\u8bbe\u8ba1\u5e08", - "workspace": "/home/starmen1265/.openclaw/agents/ui-designer/workspace", - "model": "g5", "skills": [ - "common-require" - ], - "identity": { - "name": "\u8bbe\u8ba1\u5e08", - "emoji": "\ud83c\udfa8" - } + "common-require", + "capability-evolver", + "self-improving-agent" + ] }, { "id": "thinker", - "name": "\u5ba1\u67e5\u5458", - "workspace": "/home/starmen1265/.openclaw/agents/thinker/workspace", - "model": "g5", "skills": [ - "common-require" - ], - "identity": { - "name": "\u5ba1\u67e5\u5458", - "emoji": "\ud83d\udd0d" - } + "common-require", + "capability-evolver", + "self-improving-agent" + ] } ] }, diff --git a/openclaw.json.bak.1 b/openclaw.json.bak.1 index 35ed342..05460ad 100644 --- a/openclaw.json.bak.1 +++ b/openclaw.json.bak.1 @@ -147,20 +147,20 @@ "list": [ { "id": "haonan", - "name": "陈浩南", + "name": "\u9648\u6d69\u5357", "workspace": "/home/starmen1265/.openclaw/agents/haonan/workspace", "model": "m25", "skills": [ "common-require" ], "identity": { - "name": "陈浩南", - "emoji": "📚" + "name": "\u9648\u6d69\u5357", + "emoji": "\ud83d\udcda" } }, { "id": "knowledge-base", - "name": "知识库助手", + "name": "\u77e5\u8bc6\u5e93\u52a9\u624b", "workspace": "/home/starmen1265/.openclaw/agents/knowledge-base/workspace", "model": "g5", "skills": [ @@ -168,13 +168,13 @@ "kb-workflow" ], "identity": { - "name": "知识库助手", - "emoji": "📚" + "name": "\u77e5\u8bc6\u5e93\u52a9\u624b", + "emoji": "\ud83d\udcda" } }, { "id": "dev-assist", - "name": "程序开发助手", + "name": "\u7a0b\u5e8f\u5f00\u53d1\u52a9\u624b", "workspace": "/home/starmen1265/.openclaw/agents/dev-assist/workspace", "model": "g5", "skills": [ @@ -182,21 +182,34 @@ "clawlist" ], "identity": { - "name": "程序开发助手", - "emoji": "📚" + "name": "\u7a0b\u5e8f\u5f00\u53d1\u52a9\u624b", + "emoji": "\ud83d\udcda" } }, { "id": "ui-designer", - "name": "UI/UX设计师", + "name": "UI/UX\u8bbe\u8ba1\u5e08", "workspace": "/home/starmen1265/.openclaw/agents/ui-designer/workspace", "model": "g5", "skills": [ "common-require" ], "identity": { - "name": "设计师", - "emoji": "🎨" + "name": "\u8bbe\u8ba1\u5e08", + "emoji": "\ud83c\udfa8" + } + }, + { + "id": "thinker", + "name": "\u5ba1\u67e5\u5458", + "workspace": "/home/starmen1265/.openclaw/agents/thinker/workspace", + "model": "g5", + "skills": [ + "common-require" + ], + "identity": { + "name": "\u5ba1\u67e5\u5458", + "emoji": "\ud83d\udd0d" } } ] @@ -229,71 +242,38 @@ }, "bindings": [ { - "agentId": "knowledge-base", + "agentId": "haonan", "match": { "channel": "feishu", - "peer": { - "kind": "group", - "id": "oc_79bcbd274c7cff8757b52e2ec1d8e12b" - } - } - }, - { - "agentId": "knowledge-base", - "match": { - "channel": "wecom", - "peer": { - "kind": "group", - "id": "wr_wAnbgAAXlqKMkyGznqpPMYZg2YTYg" - } + "accountId": "feishu-pm" } }, { "agentId": "dev-assist", "match": { "channel": "feishu", - "peer": { - "kind": "group", - "id": "oc_f86956cb9cecb7ad38c0f621377a23ae" - } + "accountId": "feishu-dev" } }, { - "agentId": "dev-assist", - "match": { - "channel": "wecom", - "peer": { - "kind": "group", - "id": "wr_wAnbgAA_ot7JsLAgOD2IMcsGaT_8Q" - } - } - }, - { - "agentId": "haonan", + "agentId": "knowledge-base", "match": { "channel": "feishu", - "accountId": "ou_be83febac9ee2afaa343c642bc697c48" + "accountId": "feishu-worker" } }, { - "agentId": "haonan", + "agentId": "thinker", "match": { - "channel": "wecom", - "accountId": "ZhangQing" + "channel": "feishu", + "accountId": "feishu-qa" } }, { "agentId": "ui-designer", "match": { "channel": "feishu", - "accountId": "ou_6de30318970345c4c79bea292b93130c" - } - }, - { - "agentId": "ui-designer", - "match": { - "channel": "wecom", - "accountId": "bala" + "accountId": "feishu-art" } } ], @@ -338,13 +318,29 @@ "channels": { "feishu": { "enabled": true, - "appId": "cli_a9f74dc9a3f8dbce", - "appSecret": "QtnvzRUhhFoNTTorxJuAwgSJ3ocPv0p1", - "dmPolicy": "allowlist", - "allowFrom": [ - "ou_be83febac9ee2afaa343c642bc697c48", - "ou_6de30318970345c4c79bea292b93130c" - ], + "dmPolicy": "open", + "accounts": { + "feishu-pm": { + "appId": "cli_a9f74dc9a3f8dbce", + "appSecret": "QtnvzRUhhFoNTTorxJuAwgSJ3ocPv0p1" + }, + "feishu-dev": { + "appId": "cli_a92bae598f789bd7", + "appSecret": "kmwCLAI8IdZZn1KtwiPTVg758u0unGzY" + }, + "feishu-worker": { + "appId": "cli_a92ba8ad3cb81bde", + "appSecret": "8bnMNIzy4QAv96c2xjmjgdUILO1qrO2w" + }, + "feishu-qa": { + "appId": "cli_a92baf81053f1bc0", + "appSecret": "D5Pk8Fzwj5LWQr1FGnBlCbbJa3Ox7bJQ" + }, + "feishu-art": { + "appId": "cli_a92baa31fdf8dbc0", + "appSecret": "BKjGWv1MTz7WmTn0I5A2EhuKyzwuuUnk" + } + }, "domain": "feishu", "groupPolicy": "open", "requireMention": true diff --git a/openclaw.json.bak.2 b/openclaw.json.bak.2 index c1378b5..35ed342 100644 --- a/openclaw.json.bak.2 +++ b/openclaw.json.bak.2 @@ -1,7 +1,7 @@ { "meta": { "lastTouchedVersion": "2026.2.9", - "lastTouchedAt": "2026-02-15T15:54:32.431Z" + "lastTouchedAt": "2026-02-15T15:57:58.358Z" }, "wizard": { "lastRunAt": "2026-02-13T15:47:05.928Z", @@ -300,7 +300,7 @@ "messages": { "ackReactionScope": "group-mentions", "tts": { - "auto": "always", + "auto": "tagged", "provider": "edge", "edge": { "enabled": true, diff --git a/openclaw.json.bak.3 b/openclaw.json.bak.3 index 8f20ddd..c1378b5 100644 --- a/openclaw.json.bak.3 +++ b/openclaw.json.bak.3 @@ -1,7 +1,7 @@ { "meta": { "lastTouchedVersion": "2026.2.9", - "lastTouchedAt": "2026-02-15T15:50:36.798Z" + "lastTouchedAt": "2026-02-15T15:54:32.431Z" }, "wizard": { "lastRunAt": "2026-02-13T15:47:05.928Z", @@ -300,7 +300,7 @@ "messages": { "ackReactionScope": "group-mentions", "tts": { - "auto": "tagged", + "auto": "always", "provider": "edge", "edge": { "enabled": true, diff --git a/openclaw.json.bak.4 b/openclaw.json.bak.4 index 0b6cdef..8f20ddd 100644 --- a/openclaw.json.bak.4 +++ b/openclaw.json.bak.4 @@ -1,7 +1,7 @@ { "meta": { "lastTouchedVersion": "2026.2.9", - "lastTouchedAt": "2026-02-15T15:43:40.588Z" + "lastTouchedAt": "2026-02-15T15:50:36.798Z" }, "wizard": { "lastRunAt": "2026-02-13T15:47:05.928Z", @@ -300,7 +300,7 @@ "messages": { "ackReactionScope": "group-mentions", "tts": { - "auto": "always", + "auto": "tagged", "provider": "edge", "edge": { "enabled": true, diff --git a/scripts/evolver-output.txt b/scripts/evolver-output.txt index 9816b81..c06508b 100644 --- a/scripts/evolver-output.txt +++ b/scripts/evolver-output.txt @@ -1,4 +1,103 @@ === Capability Evolver 运行开始 === -时间: 2026年 03月 03日 星期二 23:13:28 CST +时间: 2026年 03月 05日 星期四 19:00:23 CST + +=== 推送到远端 === +Warning: Permanently added '[192.168.1.22]:2223' (RSA) to the list of known hosts. +Everything up-to-date +推送完成 发现有未提交的更改,先提交... +创建备份分支: backup/evolver-20260305-190024 +Warning: Permanently added '[192.168.1.22]:2223' (RSA) to the list of known hosts. +remote: +remote: Create a new pull request for 'backup/evolver-20260305-190024': +remote: http://192.168.1.22:8418/starmen1265/openclaw/compare/main...backup/evolver-20260305-190024 +remote: +remote: . Processing 1 references +remote: Processed 1 references in total +To gitea-account:starmen1265/openclaw.git + * [new branch] backup/evolver-20260305-190024 -> backup/evolver-20260305-190024 + +=== Git 备份完成 === + +=== 运行 Capability Evolver (repair-only 模式) === +[Evolver] Warning: dotenv not found or failed to load .env +Usage: node index.js [run|/evolve|solidify|distill|asset-log] [--loop] + - solidify flags: + - --dry-run + - --no-rollback + - --intent=repair|optimize|innovate + - --summary=... + - distill flags: + - --response-file= (LLM response file for skill distillation) + - asset-log flags: + - --run= (filter by run ID) + - --action= (filter: hub_search_hit, hub_search_miss, asset_reuse, asset_reference, asset_publish, asset_publish_skip) + - --last= (show last N entries) + - --since= (entries after date) + - --json (raw JSON output) + +=== Evolver 运行完成 (exit code: 0) === + +=== 本次变更 === + M agents/dev-assist/sessions/sessions.json + D agents/dev-assist/workspace/TODO.md + M agents/haonan/agent/auth-profiles.json + M agents/haonan/sessions/sessions.json + M agents/haonan/workspace/MEMORY.md + M agents/haonan/workspace/SOUL.md + M agents/knowledge-base/workspace/AGENTS.md + D agents/knowledge-base/workspace/knowledge-base/videos/BV1QjcszrEEV.md + M agents/knowledge-base/workspace/memory/2026-03-03.md + M agents/main/agent/auth-profiles.json + M cron/jobs.json + M cron/jobs.json.bak + M devices/paired.json + M identity/device-auth.json + M openclaw.json + M openclaw.json.bak + M openclaw.json.bak.1 + M openclaw.json.bak.2 + M openclaw.json.bak.3 + M openclaw.json.bak.4 + M scripts/evolver-output.txt + M scripts/evolver-run.sh + D scripts/git-auto-sync.sh + M skills/capability-evolver/README.md + M skills/capability-evolver/README.zh-CN.md + D skills/capability-evolver/_meta.json + M skills/capability-evolver/index.js + M skills/capability-evolver/package.json + M skills/capability-evolver/src/evolve.js + M skills/capability-evolver/src/gep/a2a.js + M skills/capability-evolver/src/gep/a2aProtocol.js + M skills/capability-evolver/src/gep/hubSearch.js + M skills/capability-evolver/src/gep/paths.js + M skills/capability-evolver/src/gep/prompt.js + M skills/capability-evolver/src/gep/selector.js + M skills/capability-evolver/src/gep/signals.js + M skills/capability-evolver/src/gep/skillDistiller.js + M skills/capability-evolver/src/gep/solidify.js + M skills/capability-evolver/src/gep/taskReceiver.js + M skills/capability-evolver/src/ops/cleanup.js +?? agents/haonan/workspace/memory/2026-03-04.md +?? hooks/ +?? media/inbound/d43f43ec-4953-42e2-a550-8b2474b9939b.jpg +?? memory/ +?? skills/capability-evolver/.gitignore +?? skills/capability-evolver/LICENSE +?? skills/capability-evolver/assets/cover.png +?? skills/capability-evolver/assets/gep/failed_capsules.json +?? skills/capability-evolver/src/gep/assetCallLog.js +?? skills/capability-evolver/src/gep/llmReview.js +?? skills/capability-evolver/src/gep/narrativeMemory.js +?? skills/capability-evolver/src/gep/reflection.js +?? workspace-dev-assist/ +?? workspace-knowledge-base/ +?? workspace/.learnings/ + +=== 推送变更到远端 === +Warning: Permanently added '[192.168.1.22]:2223' (RSA) to the list of known hosts. +Everything up-to-date + +=== 输出完成 === diff --git a/scripts/evolver-run.sh b/scripts/evolver-run.sh index cb8b36c..73cba86 100755 --- a/scripts/evolver-run.sh +++ b/scripts/evolver-run.sh @@ -10,9 +10,20 @@ echo "=== Capability Evolver 运行开始 ===" > "$OUTPUT_FILE" echo "时间: $(date)" >> "$OUTPUT_FILE" echo "" >> "$OUTPUT_FILE" -# 切换到 openclaw 目录进行 git 备份 +# 切换到 openclaw 目录 cd "$OPENCLAW_DIR" +# 推送到远端(如果有远端) +if git remote get-url origin &>/dev/null; then + echo "=== 推送到远端 ===" >> "$OUTPUT_FILE" + git push origin main >> "$OUTPUT_FILE" 2>&1 + echo "推送完成" >> "$OUTPUT_FILE" +else + echo "无远端配置,跳过推送" >> "$OUTPUT_FILE" +fi + +echo "" >> "$OUTPUT_FILE" + # 检查是否有未提交的更改 if [[ -n $(git status --porcelain) ]]; then echo "发现有未提交的更改,先提交..." >> "$OUTPUT_FILE" @@ -26,6 +37,11 @@ echo "创建备份分支: $BACKUP_BRANCH" >> "$OUTPUT_FILE" git branch -D "$BACKUP_BRANCH" 2>/dev/null || true git branch "$BACKUP_BRANCH" 2>/dev/null +# 推送备份分支 +if git remote get-url origin &>/dev/null; then + git push origin "$BACKUP_BRANCH" >> "$OUTPUT_FILE" 2>&1 || echo "备份分支推送失败" >> "$OUTPUT_FILE" +fi + echo "" >> "$OUTPUT_FILE" echo "=== Git 备份完成 ===" >> "$OUTPUT_FILE" echo "" >> "$OUTPUT_FILE" @@ -46,5 +62,14 @@ echo "" >> "$OUTPUT_FILE" echo "=== 本次变更 ===" >> "$OUTPUT_FILE" git status --short >> "$OUTPUT_FILE" +# 如果有变更,推送 +if [[ -n $(git status --porcelain) ]]; then + echo "" >> "$OUTPUT_FILE" + echo "=== 推送变更到远端 ===" >> "$OUTPUT_FILE" + git add -A + git commit -m "Evolver auto evolution - $(date)" 2>/dev/null || true + git push origin main >> "$OUTPUT_FILE" 2>&1 || echo "推送失败" >> "$OUTPUT_FILE" +fi + echo "" >> "$OUTPUT_FILE" echo "=== 输出完成 ===" >> "$OUTPUT_FILE" diff --git a/scripts/git-auto-sync.sh b/scripts/git-auto-sync.sh deleted file mode 100755 index a9b7e4c..0000000 --- a/scripts/git-auto-sync.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -# 自动检查并提交 git 修改 - -cd ~/.openclaw -git add -A -if ! git diff --cached --quiet; then - git commit -m "自动同步: $(date '+%Y-%m-%d %H:%M')" - git push origin main -fi - -cd ~/.openclaw/extensions -git add -A -if ! git diff --cached --quiet; then - git commit -m "自动同步: $(date '+%Y-%m-%d %H:%M')" - git push origin main -fi diff --git a/skills/capability-evolver/.gitignore b/skills/capability-evolver/.gitignore new file mode 100644 index 0000000..04a1369 --- /dev/null +++ b/skills/capability-evolver/.gitignore @@ -0,0 +1,14 @@ +node_modules/ +.env +memory/ +assets/gep/candidates.jsonl +assets/gep/external_candidates.jsonl +dist-public/ + +# Docker / vibe testing +test/tmp/ +.docker-test-state/ + +# Local identity persistence (device + node) +.evomap_device_id +.evomap_node_id \ No newline at end of file diff --git a/skills/capability-evolver/LICENSE b/skills/capability-evolver/LICENSE new file mode 100644 index 0000000..b1956cd --- /dev/null +++ b/skills/capability-evolver/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2026 OpenClaw + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/skills/capability-evolver/README.md b/skills/capability-evolver/README.md index d9394e3..b1836a1 100644 --- a/skills/capability-evolver/README.md +++ b/skills/capability-evolver/README.md @@ -19,6 +19,11 @@ Capability Evolver is the core engine behind **[EvoMap](https://evomap.ai)**, a Keywords: protocol-constrained evolution, audit trail, genes and capsules, prompt governance. +## Prerequisites + +- **Node.js** >= 18 +- **Git** -- Required. Evolver uses git for rollback, blast radius calculation, and solidify. Running in a non-git directory will fail with a clear error message. + ## Try It Now (Minimal) ```bash @@ -221,14 +226,16 @@ The script automatically detects if compatible local skills (like `skills/feishu ## Acknowledgments -- [onthebigtree](https://github.com/onthebigtree) -- Inspired the creation of evomap evolution network. +- [onthebigtree](https://github.com/onthebigtree) -- Inspired the creation of evomap evolution network. Fixed three runtime and logic bugs (PR #25); contributed hostname privacy hashing, portable validation paths, and dead code cleanup (PR #26). - [lichunr](https://github.com/lichunr) -- Contributed thousands of dollars in tokens for our compute network to use for free. - [shinjiyu](https://github.com/shinjiyu) -- Submitted numerous bug reports and contributed multilingual signal extraction with snippet-carrying tags (PR #112). - [voidborne-d](https://github.com/voidborne-d) -- Hardened pre-broadcast sanitization with 11 new credential redaction patterns (PR #107); added 45 tests for strategy, validationReport, and envFingerprint (PR #139). - [blackdogcat](https://github.com/blackdogcat) -- Fixed missing dotenv dependency and implemented intelligent CPU load threshold auto-calculation (PR #144). +- [LKCY33](https://github.com/LKCY33) -- Fixed .env loading path and directory permissions (PR #21). +- [hendrixAIDev](https://github.com/hendrixAIDev) -- Fixed performMaintenance() running in dry-run mode (PR #68). +- [toller892](https://github.com/toller892) -- Independently identified and reported the events.jsonl forbidden_paths bug (PR #149). - [upbit](https://github.com/upbit) -- Played a vital role in popularizing evolver and evomap technologies. - [Chi Jianqiang](https://mowen.cn) -- Made significant contributions to promotion and user experience improvements. -- More contributors to be added. ## License diff --git a/skills/capability-evolver/README.zh-CN.md b/skills/capability-evolver/README.zh-CN.md index 0a2d3f4..6187fa4 100644 --- a/skills/capability-evolver/README.zh-CN.md +++ b/skills/capability-evolver/README.zh-CN.md @@ -27,6 +27,11 @@ Capability Evolver 是 **[EvoMap](https://evomap.ai)** 的核心引擎。EvoMap - **动态集成**:自动检测并使用本地工具,如果不存在则回退到通用模式。 - **持续循环模式**:持续运行的自我进化循环。 +## 前置条件 + +- **Node.js** >= 18 +- **Git** -- 必需。Evolver 依赖 git 进行回滚、变更范围计算和固化(solidify)。在非 git 目录中运行会直接报错并退出。 + ## 使用方法 ### 标准运行(自动化) @@ -190,13 +195,16 @@ MAJOR.MINOR.PATCH ## 鸣谢 -- [onthebigtree](https://github.com/onthebigtree) -- 启发了 evomap 进化网络的诞生。 +- [onthebigtree](https://github.com/onthebigtree) -- 启发了 evomap 进化网络的诞生。修复了三个运行时逻辑 bug (PR #25);贡献了主机名隐私哈希、可移植验证路径和死代码清理 (PR #26)。 - [lichunr](https://github.com/lichunr) -- 提供了数千美金 Token 供算力网络免费使用。 - [shinjiyu](https://github.com/shinjiyu) -- 为 evolver 和 evomap 提交了大量 bug report,并贡献了多语言信号提取与 snippet 标签功能 (PR #112)。 -- [voidborne-d](https://github.com/voidborne-d) -- 为预广播脱敏层新增 11 种凭证检测模式,强化安全防护 (PR #107)。 +- [voidborne-d](https://github.com/voidborne-d) -- 为预广播脱敏层新增 11 种凭证检测模式,强化安全防护 (PR #107);新增 45 项测试覆盖 strategy、validationReport 和 envFingerprint (PR #139)。 +- [blackdogcat](https://github.com/blackdogcat) -- 修复 dotenv 缺失依赖并实现智能 CPU 负载阈值自动计算 (PR #144)。 +- [LKCY33](https://github.com/LKCY33) -- 修复 .env 加载路径和目录权限问题 (PR #21)。 +- [hendrixAIDev](https://github.com/hendrixAIDev) -- 修复 dry-run 模式下 performMaintenance() 仍执行的问题 (PR #68)。 +- [toller892](https://github.com/toller892) -- 独立发现并报告了 events.jsonl forbidden_paths 冲突 bug (PR #149)。 - [upbit](https://github.com/upbit) -- 在 evolver 和 evomap 技术的普及中起到了至关重要的作用。 - [池建强](https://mowen.cn) -- 在传播和用户体验改进过程中做出了巨大贡献。 -- 其余贡献者扩充中。 ## 许可证 MIT diff --git a/skills/capability-evolver/_meta.json b/skills/capability-evolver/_meta.json deleted file mode 100644 index 16e708b..0000000 --- a/skills/capability-evolver/_meta.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "owner": "autogame-17", - "slug": "capability-evolver", - "displayName": "Capability Evolver", - "latest": { - "version": "1.20.4", - "publishedAt": 1772344308631, - "commit": "https://github.com/openclaw/skills/commit/f6fbba39530294955fd7e3b735f4ca227f4eb546" - }, - "history": [ - { - "version": "1.14.0", - "publishedAt": 1771472983583, - "commit": "https://github.com/openclaw/skills/commit/fbb1b4a640f1c8254a1dd2757e8eb38d246b9d59" - } - ] -} diff --git a/skills/capability-evolver/assets/cover.png b/skills/capability-evolver/assets/cover.png new file mode 100644 index 0000000000000000000000000000000000000000..869c7ec4ddf03019ce9e84fedf2d5c8310c3acad GIT binary patch literal 127630 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 literal 0 HcmV?d00001 diff --git a/skills/capability-evolver/assets/gep/failed_capsules.json b/skills/capability-evolver/assets/gep/failed_capsules.json new file mode 100644 index 0000000..76dff64 --- /dev/null +++ b/skills/capability-evolver/assets/gep/failed_capsules.json @@ -0,0 +1,4 @@ +{ + "version": 1, + "failed_capsules": [] +} diff --git a/skills/capability-evolver/index.js b/skills/capability-evolver/index.js old mode 100755 new mode 100644 index e898926..d897544 --- a/skills/capability-evolver/index.js +++ b/skills/capability-evolver/index.js @@ -43,12 +43,16 @@ function acquireLock() { try { if (fs.existsSync(lockFile)) { const pid = parseInt(fs.readFileSync(lockFile, 'utf8').trim(), 10); - try { - process.kill(pid, 0); // Check if process exists - console.log(`[Singleton] Evolver loop already running (PID ${pid}). Exiting.`); - return false; - } catch (e) { - console.log(`[Singleton] Stale lock found (PID ${pid}). Taking over.`); + if (!Number.isFinite(pid) || pid <= 0) { + console.log('[Singleton] Corrupt lock file (invalid PID). Taking over.'); + } else { + try { + process.kill(pid, 0); + console.log(`[Singleton] Evolver loop already running (PID ${pid}). Exiting.`); + return false; + } catch (e) { + console.log(`[Singleton] Stale lock found (PID ${pid}). Taking over.`); + } } } fs.writeFileSync(lockFile, String(process.pid)); @@ -88,7 +92,8 @@ async function main() { process.env.EVOLVE_BRIDGE = 'false'; console.log('Loop mode enabled (internal daemon).'); - const solidifyStatePath = path.join(__dirname, 'memory', 'evolution_solidify_state.json'); + const { getEvolutionDir } = require('./src/gep/paths'); + const solidifyStatePath = path.join(getEvolutionDir(), 'evolution_solidify_state.json'); const minSleepMs = parseMs(process.env.EVOLVER_MIN_SLEEP_MS, 2000); const maxSleepMs = parseMs(process.env.EVOLVER_MAX_SLEEP_MS, 300000); @@ -149,16 +154,20 @@ async function main() { const memMb = process.memoryUsage().rss / 1024 / 1024; if (cycleCount >= maxCyclesPerProcess || memMb > maxRssMb) { console.log(`[Daemon] Restarting self (cycles=${cycleCount}, rssMb=${memMb.toFixed(0)})`); - releaseLock(); - const spawnOpts = { - detached: true, - stdio: 'ignore', - env: process.env, - windowsHide: true, - }; - const child = spawn(process.execPath, [__filename, ...args], spawnOpts); - child.unref(); - process.exit(0); + try { + const spawnOpts = { + detached: true, + stdio: 'ignore', + env: process.env, + windowsHide: true, + }; + const child = spawn(process.execPath, [__filename, ...args], spawnOpts); + child.unref(); + releaseLock(); + process.exit(0); + } catch (spawnErr) { + console.error('[Daemon] Spawn failed, continuing current process:', spawnErr.message); + } } } @@ -268,15 +277,64 @@ async function main() { process.exit(2); } + } else if (command === 'asset-log') { + const { summarizeCallLog, readCallLog, getLogPath } = require('./src/gep/assetCallLog'); + + const runIdFlag = args.find(a => typeof a === 'string' && a.startsWith('--run=')); + const actionFlag = args.find(a => typeof a === 'string' && a.startsWith('--action=')); + const lastFlag = args.find(a => typeof a === 'string' && a.startsWith('--last=')); + const sinceFlag = args.find(a => typeof a === 'string' && a.startsWith('--since=')); + const jsonMode = args.includes('--json'); + + const opts = {}; + if (runIdFlag) opts.run_id = runIdFlag.slice('--run='.length); + if (actionFlag) opts.action = actionFlag.slice('--action='.length); + if (lastFlag) opts.last = parseInt(lastFlag.slice('--last='.length), 10); + if (sinceFlag) opts.since = sinceFlag.slice('--since='.length); + + if (jsonMode) { + const entries = readCallLog(opts); + console.log(JSON.stringify(entries, null, 2)); + } else { + const summary = summarizeCallLog(opts); + console.log(`\n[Asset Call Log] ${getLogPath()}`); + console.log(` Total entries: ${summary.total_entries}`); + console.log(` Unique assets: ${summary.unique_assets}`); + console.log(` Unique runs: ${summary.unique_runs}`); + console.log(` By action:`); + for (const [action, count] of Object.entries(summary.by_action)) { + console.log(` ${action}: ${count}`); + } + if (summary.entries.length > 0) { + console.log(`\n Recent entries:`); + const show = summary.entries.slice(-10); + for (const e of show) { + const ts = e.timestamp ? e.timestamp.slice(0, 19) : '?'; + const assetShort = e.asset_id ? e.asset_id.slice(0, 20) + '...' : '(none)'; + const sigPreview = Array.isArray(e.signals) ? e.signals.slice(0, 3).join(', ') : ''; + console.log(` [${ts}] ${e.action || '?'} asset=${assetShort} score=${e.score || '-'} mode=${e.mode || '-'} signals=[${sigPreview}] run=${e.run_id || '-'}`); + } + } else { + console.log('\n No entries found.'); + } + console.log(''); + } + } else { - console.log(`Usage: node index.js [run|/evolve|solidify|distill] [--loop] + console.log(`Usage: node index.js [run|/evolve|solidify|distill|asset-log] [--loop] - solidify flags: - --dry-run - --no-rollback - --intent=repair|optimize|innovate - --summary=... - distill flags: - - --response-file= (LLM response file for skill distillation)`); + - --response-file= (LLM response file for skill distillation) + - asset-log flags: + - --run= (filter by run ID) + - --action= (filter: hub_search_hit, hub_search_miss, asset_reuse, asset_reference, asset_publish, asset_publish_skip) + - --last= (show last N entries) + - --since= (entries after date) + - --json (raw JSON output)`); } } diff --git a/skills/capability-evolver/package.json b/skills/capability-evolver/package.json index 95030e3..6fdcdb3 100644 --- a/skills/capability-evolver/package.json +++ b/skills/capability-evolver/package.json @@ -1,6 +1,6 @@ { "name": "evolver", - "version": "1.20.4", + "version": "1.23.0", "description": "A GEP-powered self-evolution engine for AI agents. Features automated log analysis and Genome Evolution Protocol (GEP) for auditable, reusable evolution assets.", "main": "index.js", "keywords": [ diff --git a/skills/capability-evolver/src/evolve.js b/skills/capability-evolver/src/evolve.js index 79845ec..bf6b5ee 100644 --- a/skills/capability-evolver/src/evolve.js +++ b/skills/capability-evolver/src/evolve.js @@ -18,6 +18,7 @@ const { const { selectGeneAndCapsule, matchPatternToSignals } = require('./gep/selector'); const { buildGepPrompt, buildReusePrompt, buildHubMatchedBlock } = require('./gep/prompt'); const { hubSearch } = require('./gep/hubSearch'); +const { logAssetCall } = require('./gep/assetCallLog'); const { extractCapabilityCandidates, renderCandidatesPreview } = require('./gep/candidates'); const memoryAdapter = require('./gep/memoryGraphAdapter'); const { @@ -35,6 +36,8 @@ const { buildMutation, isHighRiskMutationAllowed } = require('./gep/mutation'); const { selectPersonalityForRun } = require('./gep/personality'); const { clip, writePromptArtifact, renderSessionsSpawnCall } = require('./gep/bridge'); const { getEvolutionDir } = require('./gep/paths'); +const { shouldReflect, buildReflectionContext, recordReflection } = require('./gep/reflection'); +const { loadNarrativeSummary } = require('./gep/narrativeMemory'); const REPO_ROOT = getRepoRoot(); @@ -744,6 +747,19 @@ async function run() { delete process.env.FORCE_INNOVATION; + // SAFEGUARD: Git repository check. + // Solidify, rollback, and blast radius all depend on git. Without a git repo + // these operations silently produce empty results, leading to data loss. + try { + execSync('git rev-parse --git-dir', { cwd: REPO_ROOT, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 5000 }); + } catch (_) { + console.error('[Evolver] FATAL: Not a git repository (' + REPO_ROOT + ').'); + console.error('[Evolver] Evolver requires git for rollback, blast radius calculation, and solidify.'); + console.error('[Evolver] Run "git init && git add -A && git commit -m init" in your project root, then try again.'); + process.exitCode = 1; + return; + } + var dormantHypothesis = readDormantHypothesis(); if (dormantHypothesis) { console.log('[DormantHypothesis] Recovered partial state from previous backoff: ' + (dormantHypothesis.backoff_reason || 'unknown')); @@ -1177,6 +1193,31 @@ async function run() { throw new Error(`MemoryGraph Read failed: ${e.message}`); } + // Reflection Phase: periodically pause to assess evolution strategy. + try { + const cycleState = fs.existsSync(STATE_FILE) ? JSON.parse(fs.readFileSync(STATE_FILE, 'utf8')) : {}; + const cycleCount = cycleState.cycleCount || 0; + if (shouldReflect({ cycleCount, recentEvents })) { + const narrativeSummary = loadNarrativeSummary(3000); + const reflectionCtx = buildReflectionContext({ + recentEvents, + signals, + memoryAdvice, + narrative: narrativeSummary, + }); + recordReflection({ + cycle_count: cycleCount, + signals_snapshot: signals.slice(0, 20), + preferred_gene: memoryAdvice && memoryAdvice.preferredGeneId ? memoryAdvice.preferredGeneId : null, + banned_genes: memoryAdvice && Array.isArray(memoryAdvice.bannedGeneIds) ? memoryAdvice.bannedGeneIds : [], + context_preview: reflectionCtx.slice(0, 1000), + }); + console.log(`[Reflection] Strategic reflection recorded at cycle ${cycleCount}.`); + } + } catch (e) { + console.log('[Reflection] Failed (non-fatal): ' + (e && e.message ? e.message : e)); + } + var recentFailedCapsules = []; try { recentFailedCapsules = readRecentFailedCapsules(50); @@ -1370,6 +1411,25 @@ async function run() { hub_lessons: hubLessons, }; writeStateForSolidify(prevState); + + if (hubHit && hubHit.hit) { + const assetAction = hubHit.mode === 'direct' ? 'asset_reuse' : 'asset_reference'; + logAssetCall({ + run_id: runId, + action: assetAction, + asset_id: hubHit.asset_id || null, + asset_type: hubHit.match && hubHit.match.type ? hubHit.match.type : null, + source_node_id: hubHit.source_node_id || null, + chain_id: hubHit.chain_id || null, + score: hubHit.score || null, + mode: hubHit.mode, + signals: Array.isArray(signals) ? signals : [], + extra: { + selected_gene_id: selectedGene && selectedGene.id ? selectedGene.id : null, + task_id: activeTask ? (activeTask.id || activeTask.task_id || null) : null, + }, + }); + } } catch (e) { console.error(`[SolidifyState] Write failed: ${e.message}`); } diff --git a/skills/capability-evolver/src/gep/a2a.js b/skills/capability-evolver/src/gep/a2a.js index 2e34008..f47a7cf 100644 --- a/skills/capability-evolver/src/gep/a2a.js +++ b/skills/capability-evolver/src/gep/a2a.js @@ -28,8 +28,8 @@ function getBlastRadiusLimits() { function isBlastRadiusSafe(blastRadius) { var lim = getBlastRadiusLimits(); - var files = blastRadius && Number.isFinite(Number(blastRadius.files)) ? Number(blastRadius.files) : 0; - var lines = blastRadius && Number.isFinite(Number(blastRadius.lines)) ? Number(blastRadius.lines) : 0; + var files = blastRadius && Number.isFinite(Number(blastRadius.files)) ? Math.max(0, Number(blastRadius.files)) : 0; + var lines = blastRadius && Number.isFinite(Number(blastRadius.lines)) ? Math.max(0, Number(blastRadius.lines)) : 0; return files <= lim.maxFiles && lines <= lim.maxLines; } diff --git a/skills/capability-evolver/src/gep/a2aProtocol.js b/skills/capability-evolver/src/gep/a2aProtocol.js index d3695ff..83fa946 100644 --- a/skills/capability-evolver/src/gep/a2aProtocol.js +++ b/skills/capability-evolver/src/gep/a2aProtocol.js @@ -96,6 +96,9 @@ function getNodeId() { // --- Base message builder --- function buildMessage(params) { + if (!params || typeof params !== 'object') { + throw new Error('buildMessage requires a params object'); + } var messageType = params.messageType; var payload = params.payload; var senderId = params.senderId; @@ -197,14 +200,18 @@ function buildPublishBundle(opts) { function buildFetch(opts) { var o = opts || {}; + var fetchPayload = { + asset_type: o.assetType || null, + local_id: o.localId || null, + content_hash: o.contentHash || null, + }; + if (Array.isArray(o.signals) && o.signals.length > 0) { + fetchPayload.signals = o.signals; + } return buildMessage({ messageType: 'fetch', senderId: o.nodeId, - payload: { - asset_type: o.assetType || null, - local_id: o.localId || null, - content_hash: o.contentHash || null, - }, + payload: fetchPayload, }); } @@ -351,7 +358,8 @@ function httpTransportReceive(opts) { var hubUrl = (opts && opts.hubUrl) || process.env.A2A_HUB_URL; if (!hubUrl) return Promise.resolve([]); var assetType = (opts && opts.assetType) || null; - var fetchMsg = buildFetch({ assetType: assetType }); + var signals = (opts && Array.isArray(opts.signals)) ? opts.signals : null; + var fetchMsg = buildFetch({ assetType: assetType, signals: signals }); var endpoint = hubUrl.replace(/\/+$/, '') + '/a2a/fetch'; return fetch(endpoint, { method: 'POST', diff --git a/skills/capability-evolver/src/gep/assetCallLog.js b/skills/capability-evolver/src/gep/assetCallLog.js new file mode 100644 index 0000000..b28c97a --- /dev/null +++ b/skills/capability-evolver/src/gep/assetCallLog.js @@ -0,0 +1,130 @@ +// Append-only asset call log for tracking Hub asset interactions per evolution run. +// Log file: {evolution_dir}/asset_call_log.jsonl + +const fs = require('fs'); +const path = require('path'); +const { getEvolutionDir } = require('./paths'); + +function getLogPath() { + return path.join(getEvolutionDir(), 'asset_call_log.jsonl'); +} + +function ensureDir(filePath) { + const dir = path.dirname(filePath); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } +} + +/** + * Append a single asset call record to the log. + * + * @param {object} entry + * @param {string} entry.run_id + * @param {string} entry.action - hub_search_hit | hub_search_miss | asset_reuse | asset_reference | asset_publish | asset_publish_skip + * @param {string} [entry.asset_id] + * @param {string} [entry.asset_type] + * @param {string} [entry.source_node_id] + * @param {string} [entry.chain_id] + * @param {number} [entry.score] + * @param {string} [entry.mode] - direct | reference + * @param {string[]} [entry.signals] + * @param {string} [entry.reason] + * @param {object} [entry.extra] + */ +function logAssetCall(entry) { + if (!entry || typeof entry !== 'object') return; + try { + const logPath = getLogPath(); + ensureDir(logPath); + const record = { + timestamp: new Date().toISOString(), + ...entry, + }; + fs.appendFileSync(logPath, JSON.stringify(record) + '\n', 'utf8'); + } catch (e) { + // Non-fatal: never block evolution for logging failure + } +} + +/** + * Read asset call log entries with optional filters. + * + * @param {object} [opts] + * @param {string} [opts.run_id] - filter by run_id + * @param {string} [opts.action] - filter by action type + * @param {number} [opts.last] - only return last N entries + * @param {string} [opts.since] - ISO date string, only entries after this time + * @returns {object[]} + */ +function readCallLog(opts) { + const o = opts || {}; + const logPath = getLogPath(); + if (!fs.existsSync(logPath)) return []; + + const raw = fs.readFileSync(logPath, 'utf8'); + const lines = raw.split('\n').filter(Boolean); + + let entries = []; + for (const line of lines) { + try { + entries.push(JSON.parse(line)); + } catch (e) { /* skip corrupt lines */ } + } + + if (o.since) { + const sinceTs = new Date(o.since).getTime(); + if (Number.isFinite(sinceTs)) { + entries = entries.filter(e => new Date(e.timestamp).getTime() >= sinceTs); + } + } + + if (o.run_id) { + entries = entries.filter(e => e.run_id === o.run_id); + } + + if (o.action) { + entries = entries.filter(e => e.action === o.action); + } + + if (o.last && Number.isFinite(o.last) && o.last > 0) { + entries = entries.slice(-o.last); + } + + return entries; +} + +/** + * Summarize asset call log (for CLI display). + * + * @param {object} [opts] - same filters as readCallLog + * @returns {object} summary with totals and per-action counts + */ +function summarizeCallLog(opts) { + const entries = readCallLog(opts); + const actionCounts = {}; + const assetsSeen = new Set(); + const runsSeen = new Set(); + + for (const e of entries) { + const a = e.action || 'unknown'; + actionCounts[a] = (actionCounts[a] || 0) + 1; + if (e.asset_id) assetsSeen.add(e.asset_id); + if (e.run_id) runsSeen.add(e.run_id); + } + + return { + total_entries: entries.length, + unique_assets: assetsSeen.size, + unique_runs: runsSeen.size, + by_action: actionCounts, + entries, + }; +} + +module.exports = { + logAssetCall, + readCallLog, + summarizeCallLog, + getLogPath, +}; diff --git a/skills/capability-evolver/src/gep/hubSearch.js b/skills/capability-evolver/src/gep/hubSearch.js index c70e749..deb568a 100644 --- a/skills/capability-evolver/src/gep/hubSearch.js +++ b/skills/capability-evolver/src/gep/hubSearch.js @@ -2,11 +2,17 @@ // // Flow: extractSignals() -> hubSearch(signals) -> if hit: reuse; if miss: normal evolve // Two modes: direct (skip local reasoning) | reference (inject into prompt as strong hint) +// +// Uses POST /a2a/fetch with signals field (protocol-native) instead of GET /a2a/assets/search. +// This returns full payload (content, diff, strategy) in a single round-trip. -const { getNodeId } = require('./a2aProtocol'); +const { getNodeId, buildFetch } = require('./a2aProtocol'); +const { logAssetCall } = require('./assetCallLog'); const DEFAULT_MIN_REUSE_SCORE = 0.72; const DEFAULT_REUSE_MODE = 'reference'; // 'direct' | 'reference' +const MAX_STREAK_CAP = 5; +const TIMEOUT_REASON = 'hub_search_timeout'; function getHubUrl() { return (process.env.A2A_HUB_URL || '').replace(/\/+$/, ''); @@ -24,13 +30,14 @@ function getMinReuseScore() { /** * Score a hub asset for local reuse quality. - * rank = confidence * max(success_streak, 1) * (reputation / 100) + * rank = confidence * min(max(success_streak, 1), MAX_STREAK_CAP) * (reputation / 100) + * Streak is capped to prevent unbounded score inflation. */ function scoreHubResult(asset) { const confidence = Number(asset.confidence) || 0; - const streak = Math.max(Number(asset.success_streak) || 0, 1); - // Reputation is included in asset from hub ranked endpoint; default 50 if missing - const reputation = Number(asset.reputation_score) || 50; + const streak = Math.min(Math.max(Number(asset.success_streak) || 0, 1), MAX_STREAK_CAP); + const repRaw = Number(asset.reputation_score); + const reputation = Number.isFinite(repRaw) ? repRaw : 50; return confidence * streak * (reputation / 100); } @@ -45,7 +52,6 @@ function pickBestMatch(results, threshold) { let bestScore = 0; for (const asset of results) { - // Only consider promoted assets if (asset.status && asset.status !== 'promoted') continue; const s = scoreHubResult(asset); if (s > bestScore) { @@ -64,48 +70,96 @@ function pickBestMatch(results, threshold) { } /** - * Search the hub for reusable capsules matching the given signals. + * Search the hub for reusable assets matching the given signals. + * Uses POST /a2a/fetch with signals (protocol-native, returns full payload). + * Falls back to GET /a2a/assets/search if fetch fails. * Returns { hit: true, match, score, mode } or { hit: false }. */ async function hubSearch(signals, opts) { const hubUrl = getHubUrl(); if (!hubUrl) return { hit: false, reason: 'no_hub_url' }; - const signalList = Array.isArray(signals) ? signals.filter(Boolean) : []; + const signalList = Array.isArray(signals) + ? signals.map(s => typeof s === 'string' ? s.trim() : '').filter(Boolean) + : []; if (signalList.length === 0) return { hit: false, reason: 'no_signals' }; const threshold = (opts && Number.isFinite(opts.threshold)) ? opts.threshold : getMinReuseScore(); - const limit = (opts && Number.isFinite(opts.limit)) ? opts.limit : 5; const timeout = (opts && Number.isFinite(opts.timeoutMs)) ? opts.timeoutMs : 8000; try { - const params = new URLSearchParams(); - params.set('signals', signalList.join(',')); - params.set('status', 'promoted'); - params.set('limit', String(limit)); + const fetchMsg = buildFetch({ signals: signalList }); + const endpoint = hubUrl + '/a2a/fetch'; const controller = new AbortController(); - const timer = setTimeout(() => controller.abort(), timeout); + const timer = setTimeout(() => controller.abort(TIMEOUT_REASON), timeout); - const url = `${hubUrl}/a2a/assets/search?${params.toString()}`; - const res = await fetch(url, { - method: 'GET', - headers: { 'Content-Type': 'application/json' }, + const headers = { 'Content-Type': 'application/json', 'Accept': 'application/json' }; + const token = process.env.A2A_HUB_TOKEN; + if (token) headers['Authorization'] = `Bearer ${token}`; + + const res = await fetch(endpoint, { + method: 'POST', + headers, + body: JSON.stringify(fetchMsg), signal: controller.signal, }); clearTimeout(timer); - if (!res.ok) return { hit: false, reason: `hub_http_${res.status}` }; + if (!res.ok) { + logAssetCall({ + run_id: (opts && opts.run_id) || null, + action: 'hub_search_miss', + signals: signalList, + reason: `hub_http_${res.status}`, + via: 'fetch_with_signals', + }); + return { hit: false, reason: `hub_http_${res.status}` }; + } const data = await res.json(); - const assets = Array.isArray(data.assets) ? data.assets : []; + const results = (data && data.payload && Array.isArray(data.payload.results)) + ? data.payload.results + : []; - if (assets.length === 0) return { hit: false, reason: 'no_results' }; + if (results.length === 0) { + logAssetCall({ + run_id: (opts && opts.run_id) || null, + action: 'hub_search_miss', + signals: signalList, + reason: 'no_results', + via: 'fetch_with_signals', + }); + return { hit: false, reason: 'no_results' }; + } - const pick = pickBestMatch(assets, threshold); - if (!pick) return { hit: false, reason: 'below_threshold', candidates: assets.length }; + const pick = pickBestMatch(results, threshold); + if (!pick) { + logAssetCall({ + run_id: (opts && opts.run_id) || null, + action: 'hub_search_miss', + signals: signalList, + reason: 'below_threshold', + extra: { candidates: results.length, threshold }, + via: 'fetch_with_signals', + }); + return { hit: false, reason: 'below_threshold', candidates: results.length }; + } - console.log(`[HubSearch] Hit: ${pick.match.asset_id || pick.match.local_id} (score=${pick.score}, mode=${pick.mode})`); + console.log(`[HubSearch] Hit via fetch+signals: ${pick.match.asset_id || 'unknown'} (score=${pick.score}, mode=${pick.mode})`); + + logAssetCall({ + run_id: (opts && opts.run_id) || null, + action: 'hub_search_hit', + asset_id: pick.match.asset_id || null, + asset_type: pick.match.asset_type || pick.match.type || null, + source_node_id: pick.match.source_node_id || null, + chain_id: pick.match.chain_id || null, + score: pick.score, + mode: pick.mode, + signals: signalList, + via: 'fetch_with_signals', + }); return { hit: true, @@ -117,9 +171,18 @@ async function hubSearch(signals, opts) { chain_id: pick.match.chain_id || null, }; } catch (err) { - // Hub unreachable is non-fatal; fall through to normal evolve - console.log(`[HubSearch] Failed (non-fatal): ${err.message}`); - return { hit: false, reason: 'fetch_error', error: err.message }; + const isTimeout = err.name === 'AbortError' || (err.cause && err.cause === TIMEOUT_REASON); + const reason = isTimeout ? 'timeout' : 'fetch_error'; + console.log(`[HubSearch] Failed (non-fatal, ${reason}): ${err.message}`); + logAssetCall({ + run_id: (opts && opts.run_id) || null, + action: 'hub_search_miss', + signals: signalList, + reason, + extra: { error: err.message }, + via: 'fetch_with_signals', + }); + return { hit: false, reason, error: err.message }; } } diff --git a/skills/capability-evolver/src/gep/llmReview.js b/skills/capability-evolver/src/gep/llmReview.js new file mode 100644 index 0000000..d49aa6a --- /dev/null +++ b/skills/capability-evolver/src/gep/llmReview.js @@ -0,0 +1,86 @@ +'use strict'; + +const { execSync } = require('child_process'); +const { getRepoRoot } = require('./paths'); + +const REVIEW_ENABLED_KEY = 'EVOLVER_LLM_REVIEW'; +const REVIEW_TIMEOUT_MS = 30000; + +function isLlmReviewEnabled() { + return String(process.env[REVIEW_ENABLED_KEY] || '').toLowerCase() === 'true'; +} + +function buildReviewPrompt({ diff, gene, signals, mutation }) { + const geneId = gene && gene.id ? gene.id : '(unknown)'; + const category = (mutation && mutation.category) || (gene && gene.category) || 'unknown'; + const rationale = mutation && mutation.rationale ? String(mutation.rationale).slice(0, 500) : '(none)'; + const signalsList = Array.isArray(signals) ? signals.slice(0, 8).join(', ') : '(none)'; + const diffPreview = String(diff || '').slice(0, 6000); + + return `You are reviewing a code change produced by an autonomous evolution engine. + +## Context +- Gene: ${geneId} (${category}) +- Signals: [${signalsList}] +- Rationale: ${rationale} + +## Diff +\`\`\`diff +${diffPreview} +\`\`\` + +## Review Criteria +1. Does this change address the stated signals? +2. Are there any obvious regressions or bugs introduced? +3. Is the blast radius proportionate to the problem? +4. Are there any security or safety concerns? + +## Response Format +Respond with a JSON object: +{ + "approved": true|false, + "confidence": 0.0-1.0, + "concerns": ["..."], + "summary": "one-line review summary" +}`; +} + +function runLlmReview({ diff, gene, signals, mutation }) { + if (!isLlmReviewEnabled()) return null; + + const prompt = buildReviewPrompt({ diff, gene, signals, mutation }); + + try { + const repoRoot = getRepoRoot(); + const escapedPrompt = prompt.replace(/'/g, "'\\''"); + const result = execSync( + `echo '${escapedPrompt}' | node -e " + const readline = require('readline'); + const rl = readline.createInterface({ input: process.stdin }); + let input = ''; + rl.on('line', l => input += l + '\\n'); + rl.on('close', () => { + console.log(JSON.stringify({ approved: true, confidence: 0.7, concerns: [], summary: 'auto-approved (no external LLM configured)' })); + }); + "`, + { + cwd: repoRoot, + encoding: 'utf8', + timeout: REVIEW_TIMEOUT_MS, + stdio: ['pipe', 'pipe', 'pipe'], + windowsHide: true, + } + ); + + try { + return JSON.parse(result.trim()); + } catch (_) { + return { approved: true, confidence: 0.5, concerns: ['failed to parse review response'], summary: 'review parse error' }; + } + } catch (e) { + console.log('[LLMReview] Execution failed (non-fatal): ' + (e && e.message ? e.message : e)); + return { approved: true, confidence: 0.5, concerns: ['review execution failed'], summary: 'review timeout or error' }; + } +} + +module.exports = { isLlmReviewEnabled, runLlmReview, buildReviewPrompt }; diff --git a/skills/capability-evolver/src/gep/narrativeMemory.js b/skills/capability-evolver/src/gep/narrativeMemory.js new file mode 100644 index 0000000..fae8854 --- /dev/null +++ b/skills/capability-evolver/src/gep/narrativeMemory.js @@ -0,0 +1,108 @@ +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const { getNarrativePath, getEvolutionDir } = require('./paths'); + +const MAX_NARRATIVE_ENTRIES = 30; +const MAX_NARRATIVE_SIZE = 12000; + +function ensureDir(dir) { + try { if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true }); } catch (_) {} +} + +function recordNarrative({ gene, signals, mutation, outcome, blast, capsule }) { + const narrativePath = getNarrativePath(); + ensureDir(path.dirname(narrativePath)); + + const ts = new Date().toISOString().replace('T', ' ').slice(0, 19); + const geneId = gene && gene.id ? gene.id : '(auto)'; + const category = (mutation && mutation.category) || (gene && gene.category) || 'unknown'; + const status = outcome && outcome.status ? outcome.status : 'unknown'; + const score = outcome && typeof outcome.score === 'number' ? outcome.score.toFixed(2) : '?'; + const signalsSummary = Array.isArray(signals) ? signals.slice(0, 4).join(', ') : '(none)'; + const filesChanged = blast ? blast.files : 0; + const linesChanged = blast ? blast.lines : 0; + const rationale = mutation && mutation.rationale + ? String(mutation.rationale).slice(0, 200) : ''; + const strategy = gene && Array.isArray(gene.strategy) + ? gene.strategy.slice(0, 3).map((s, i) => ` ${i + 1}. ${s}`).join('\n') : ''; + const capsuleSummary = capsule && capsule.summary ? String(capsule.summary).slice(0, 200) : ''; + + const entry = [ + `### [${ts}] ${category.toUpperCase()} - ${status}`, + `- Gene: ${geneId} | Score: ${score} | Scope: ${filesChanged} files, ${linesChanged} lines`, + `- Signals: [${signalsSummary}]`, + rationale ? `- Why: ${rationale}` : null, + strategy ? `- Strategy:\n${strategy}` : null, + capsuleSummary ? `- Result: ${capsuleSummary}` : null, + '', + ].filter(line => line !== null).join('\n'); + + let existing = ''; + try { + if (fs.existsSync(narrativePath)) { + existing = fs.readFileSync(narrativePath, 'utf8'); + } + } catch (_) {} + + if (!existing.trim()) { + existing = '# Evolution Narrative\n\nA chronological record of evolution decisions and outcomes.\n\n'; + } + + const combined = existing + entry; + const trimmed = trimNarrative(combined); + + const tmp = narrativePath + '.tmp'; + fs.writeFileSync(tmp, trimmed, 'utf8'); + fs.renameSync(tmp, narrativePath); +} + +function trimNarrative(content) { + if (content.length <= MAX_NARRATIVE_SIZE) return content; + + const headerEnd = content.indexOf('###'); + if (headerEnd < 0) return content.slice(-MAX_NARRATIVE_SIZE); + + const header = content.slice(0, headerEnd); + const entries = content.slice(headerEnd).split(/(?=^### \[)/m); + + while (entries.length > MAX_NARRATIVE_ENTRIES) { + entries.shift(); + } + + let result = header + entries.join(''); + if (result.length > MAX_NARRATIVE_SIZE) { + const keep = Math.max(1, entries.length - 5); + result = header + entries.slice(-keep).join(''); + } + + return result; +} + +function loadNarrativeSummary(maxChars) { + const limit = Number.isFinite(maxChars) ? maxChars : 4000; + const narrativePath = getNarrativePath(); + try { + if (!fs.existsSync(narrativePath)) return ''; + const content = fs.readFileSync(narrativePath, 'utf8'); + if (!content.trim()) return ''; + + const headerEnd = content.indexOf('###'); + if (headerEnd < 0) return ''; + + const entries = content.slice(headerEnd).split(/(?=^### \[)/m); + const recent = entries.slice(-8); + let summary = recent.join(''); + if (summary.length > limit) { + summary = summary.slice(-limit); + const firstEntry = summary.indexOf('### ['); + if (firstEntry > 0) summary = summary.slice(firstEntry); + } + return summary.trim(); + } catch (_) { + return ''; + } +} + +module.exports = { recordNarrative, loadNarrativeSummary, trimNarrative }; diff --git a/skills/capability-evolver/src/gep/paths.js b/skills/capability-evolver/src/gep/paths.js index 01218dd..9fba0a4 100644 --- a/skills/capability-evolver/src/gep/paths.js +++ b/skills/capability-evolver/src/gep/paths.js @@ -28,7 +28,8 @@ function getSessionScope() { if (!raw) return null; // Sanitize: only allow alphanumeric, dash, underscore, dot (prevent path traversal). const safe = raw.replace(/[^a-zA-Z0-9_\-\.]/g, '_').slice(0, 128); - return safe || null; + if (!safe || /^\.{1,2}$/.test(safe) || /\.\./.test(safe)) return null; + return safe; } function getEvolutionDir() { @@ -54,6 +55,21 @@ function getSkillsDir() { return process.env.SKILLS_DIR || path.join(getWorkspaceRoot(), 'skills'); } +function getNarrativePath() { + return path.join(getEvolutionDir(), 'evolution_narrative.md'); +} + +function getEvolutionPrinciplesPath() { + const repoRoot = getRepoRoot(); + const custom = path.join(repoRoot, 'EVOLUTION_PRINCIPLES.md'); + if (require('fs').existsSync(custom)) return custom; + return path.join(repoRoot, 'assets', 'gep', 'EVOLUTION_PRINCIPLES.md'); +} + +function getReflectionLogPath() { + return path.join(getEvolutionDir(), 'reflection_log.jsonl'); +} + module.exports = { getRepoRoot, getWorkspaceRoot, @@ -63,5 +79,8 @@ module.exports = { getGepAssetsDir, getSkillsDir, getSessionScope, + getNarrativePath, + getEvolutionPrinciplesPath, + getReflectionLogPath, }; diff --git a/skills/capability-evolver/src/gep/prompt.js b/skills/capability-evolver/src/gep/prompt.js index fccb639..2dbe9f0 100644 --- a/skills/capability-evolver/src/gep/prompt.js +++ b/skills/capability-evolver/src/gep/prompt.js @@ -1,7 +1,10 @@ +const fs = require('fs'); const { captureEnvFingerprint } = require('./envFingerprint'); const { formatAssetPreview } = require('./assets'); -const { generateInnovationIdeas } = require('../ops/innovation'); // [2026-02-14] Innovation Catalyst Integration -const { analyzeRecentHistory, OPPORTUNITY_SIGNALS } = require('./signals'); // [2026-02-14] Signal Analysis Integration +const { generateInnovationIdeas } = require('../ops/innovation'); +const { analyzeRecentHistory, OPPORTUNITY_SIGNALS } = require('./signals'); +const { loadNarrativeSummary } = require('./narrativeMemory'); +const { getEvolutionPrinciplesPath } = require('./paths'); /** * Build a minimal prompt for direct-reuse mode. @@ -219,6 +222,29 @@ function buildLessonsBlock(hubLessons, signals) { return parts.join('\n'); } +function buildNarrativeBlock() { + try { + const narrative = loadNarrativeSummary(3000); + if (!narrative) return ''; + return `\nContext [Evolution Narrative] (Recent decisions and outcomes -- learn from this history):\n${narrative}\n`; + } catch (_) { + return ''; + } +} + +function buildPrinciplesBlock() { + try { + const principlesPath = getEvolutionPrinciplesPath(); + if (!fs.existsSync(principlesPath)) return ''; + const content = fs.readFileSync(principlesPath, 'utf8'); + if (!content.trim()) return ''; + const trimmed = content.length > 2000 ? content.slice(0, 2000) + '\n...[TRUNCATED]' : content; + return `\nContext [Evolution Principles] (Guiding directives -- align your actions):\n${trimmed}\n`; + } catch (_) { + return ''; + } +} + function buildGepPrompt({ nowIso, context, @@ -485,7 +511,8 @@ Context [External Candidates]: ${externalCandidatesPreview || '(none)'} ${buildAntiPatternZone(failedCapsules, signals)}${buildLessonsBlock(hubLessons, signals)} ${historyBlock} - +${buildNarrativeBlock()} +${buildPrinciplesBlock()} Context [Execution]: ${executionContext} @@ -536,4 +563,4 @@ Rules: return basePrompt.slice(0, maxChars) + "\n...[TRUNCATED]..."; } -module.exports = { buildGepPrompt, buildReusePrompt, buildHubMatchedBlock, buildLessonsBlock }; +module.exports = { buildGepPrompt, buildReusePrompt, buildHubMatchedBlock, buildLessonsBlock, buildNarrativeBlock, buildPrinciplesBlock }; diff --git a/skills/capability-evolver/src/gep/reflection.js b/skills/capability-evolver/src/gep/reflection.js new file mode 100644 index 0000000..fac1aff --- /dev/null +++ b/skills/capability-evolver/src/gep/reflection.js @@ -0,0 +1,127 @@ +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const { getReflectionLogPath, getEvolutionDir } = require('./paths'); + +const REFLECTION_INTERVAL_CYCLES = 5; +const REFLECTION_COOLDOWN_MS = 30 * 60 * 1000; + +function ensureDir(dir) { + try { if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true }); } catch (_) {} +} + +function shouldReflect({ cycleCount, recentEvents }) { + if (!Number.isFinite(cycleCount) || cycleCount < REFLECTION_INTERVAL_CYCLES) return false; + if (cycleCount % REFLECTION_INTERVAL_CYCLES !== 0) return false; + + const logPath = getReflectionLogPath(); + try { + if (fs.existsSync(logPath)) { + const stat = fs.statSync(logPath); + if (Date.now() - stat.mtimeMs < REFLECTION_COOLDOWN_MS) return false; + } + } catch (_) {} + + return true; +} + +function buildReflectionContext({ recentEvents, signals, memoryAdvice, narrative }) { + const parts = ['You are performing a strategic reflection on recent evolution cycles.']; + parts.push('Analyze the patterns below and provide concise strategic guidance.'); + parts.push(''); + + if (Array.isArray(recentEvents) && recentEvents.length > 0) { + const last10 = recentEvents.slice(-10); + const successCount = last10.filter(e => e && e.outcome && e.outcome.status === 'success').length; + const failCount = last10.filter(e => e && e.outcome && e.outcome.status === 'failed').length; + const intents = {}; + last10.forEach(e => { + const i = e && e.intent ? e.intent : 'unknown'; + intents[i] = (intents[i] || 0) + 1; + }); + const genes = {}; + last10.forEach(e => { + const g = e && Array.isArray(e.genes_used) && e.genes_used[0] ? e.genes_used[0] : 'unknown'; + genes[g] = (genes[g] || 0) + 1; + }); + + parts.push('## Recent Cycle Statistics (last 10)'); + parts.push(`- Success: ${successCount}, Failed: ${failCount}`); + parts.push(`- Intent distribution: ${JSON.stringify(intents)}`); + parts.push(`- Gene usage: ${JSON.stringify(genes)}`); + parts.push(''); + } + + if (Array.isArray(signals) && signals.length > 0) { + parts.push('## Current Signals'); + parts.push(signals.slice(0, 20).join(', ')); + parts.push(''); + } + + if (memoryAdvice) { + parts.push('## Memory Graph Advice'); + if (memoryAdvice.preferredGeneId) { + parts.push(`- Preferred gene: ${memoryAdvice.preferredGeneId}`); + } + if (Array.isArray(memoryAdvice.bannedGeneIds) && memoryAdvice.bannedGeneIds.length > 0) { + parts.push(`- Banned genes: ${memoryAdvice.bannedGeneIds.join(', ')}`); + } + if (memoryAdvice.explanation) { + parts.push(`- Explanation: ${memoryAdvice.explanation}`); + } + parts.push(''); + } + + if (narrative) { + parts.push('## Recent Evolution Narrative'); + parts.push(String(narrative).slice(0, 3000)); + parts.push(''); + } + + parts.push('## Questions to Answer'); + parts.push('1. Are there persistent signals being ignored?'); + parts.push('2. Is the gene selection strategy optimal, or are we stuck in a local maximum?'); + parts.push('3. Should the balance between repair/optimize/innovate shift?'); + parts.push('4. Are there capability gaps that no current gene addresses?'); + parts.push('5. What single strategic adjustment would have the highest impact?'); + parts.push(''); + parts.push('Respond with a JSON object: { "insights": [...], "strategy_adjustment": "...", "priority_signals": [...] }'); + + return parts.join('\n'); +} + +function recordReflection(reflection) { + const logPath = getReflectionLogPath(); + ensureDir(path.dirname(logPath)); + + const entry = JSON.stringify({ + ts: new Date().toISOString(), + type: 'reflection', + ...reflection, + }) + '\n'; + + fs.appendFileSync(logPath, entry, 'utf8'); +} + +function loadRecentReflections(count) { + const n = Number.isFinite(count) ? count : 3; + const logPath = getReflectionLogPath(); + try { + if (!fs.existsSync(logPath)) return []; + const lines = fs.readFileSync(logPath, 'utf8').trim().split('\n').filter(Boolean); + return lines.slice(-n).map(line => { + try { return JSON.parse(line); } catch (_) { return null; } + }).filter(Boolean); + } catch (_) { + return []; + } +} + +module.exports = { + shouldReflect, + buildReflectionContext, + recordReflection, + loadRecentReflections, + REFLECTION_INTERVAL_CYCLES, +}; diff --git a/skills/capability-evolver/src/gep/selector.js b/skills/capability-evolver/src/gep/selector.js index d218f79..b29886c 100644 --- a/skills/capability-evolver/src/gep/selector.js +++ b/skills/capability-evolver/src/gep/selector.js @@ -3,6 +3,7 @@ function matchPatternToSignals(pattern, signals) { const p = String(pattern); const sig = signals.map(s => String(s)); + // Regex pattern: /body/flags const regexLike = p.length >= 2 && p.startsWith('/') && p.lastIndexOf('/') > 0; if (regexLike) { const lastSlash = p.lastIndexOf('/'); @@ -16,6 +17,12 @@ function matchPatternToSignals(pattern, signals) { } } + // Multi-language alias: "en_term|zh_term|ja_term" -- any branch matching = hit + if (p.includes('|') && !p.startsWith('/')) { + const branches = p.split('|').map(b => b.trim().toLowerCase()).filter(Boolean); + return branches.some(needle => sig.some(s => s.toLowerCase().includes(needle))); + } + const needle = p.toLowerCase(); return sig.some(s => s.toLowerCase().includes(needle)); } @@ -67,6 +74,7 @@ function computeDriftIntensity(opts) { } function selectGene(genes, signals, opts) { + const genesList = Array.isArray(genes) ? genes : []; const bannedGeneIds = opts && opts.bannedGeneIds ? opts.bannedGeneIds : new Set(); const driftEnabled = !!(opts && opts.driftEnabled); const preferredGeneId = opts && typeof opts.preferredGeneId === 'string' ? opts.preferredGeneId : null; @@ -75,14 +83,14 @@ function selectGene(genes, signals, opts) { var driftIntensity = computeDriftIntensity({ driftEnabled: driftEnabled, effectivePopulationSize: opts && opts.effectivePopulationSize, - genePoolSize: genes ? genes.length : 0, + genePoolSize: genesList.length, }); var useDrift = driftEnabled || driftIntensity > 0.15; var DISTILLED_PREFIX = 'gene_distilled_'; var DISTILLED_SCORE_FACTOR = 0.8; - const scored = genes + const scored = genesList .map(g => { var s = scoreGene(g, signals); if (s > 0 && g.id && String(g.id).startsWith(DISTILLED_PREFIX)) s *= DISTILLED_SCORE_FACTOR; diff --git a/skills/capability-evolver/src/gep/signals.js b/skills/capability-evolver/src/gep/signals.js index 0df85bd..95268d6 100644 --- a/skills/capability-evolver/src/gep/signals.js +++ b/skills/capability-evolver/src/gep/signals.js @@ -282,14 +282,14 @@ function extractSignals({ recentSessionTranscript, todayLog, memorySnippet, user // --- Tool Usage Analytics --- var toolUsage = {}; - var toolMatches = corpus.match(/\[TOOL:\s*(\w+)\]/g) || []; + var toolMatches = corpus.match(/\[TOOL:\s*([\w-]+)\]/g) || []; // Extract exec commands to identify benign loops (like watchdog checks) var execCommands = corpus.match(/exec: (node\s+[\w\/\.-]+\.js\s+ensure)/g) || []; var benignExecCount = execCommands.length; for (var i = 0; i < toolMatches.length; i++) { - var toolName = toolMatches[i].match(/\[TOOL:\s*(\w+)\]/)[1]; + var toolName = toolMatches[i].match(/\[TOOL:\s*([\w-]+)\]/)[1]; toolUsage[toolName] = (toolUsage[toolName] || 0) + 1; } diff --git a/skills/capability-evolver/src/gep/skillDistiller.js b/skills/capability-evolver/src/gep/skillDistiller.js index 7f5b575..be704a3 100644 --- a/skills/capability-evolver/src/gep/skillDistiller.js +++ b/skills/capability-evolver/src/gep/skillDistiller.js @@ -223,7 +223,7 @@ function buildDistillationPrompt(analysis, existingGenes, sampleCapsules) { }); return [ - 'You are a Gene synthesis engine for the GEP (Gene Expression Protocol).', + 'You are a Gene synthesis engine for the GEP (Genome Evolution Protocol).', '', 'Analyze the following successful evolution capsules and extract a reusable Gene.', '', diff --git a/skills/capability-evolver/src/gep/solidify.js b/skills/capability-evolver/src/gep/solidify.js index 1b9f9da..1b95054 100644 --- a/skills/capability-evolver/src/gep/solidify.js +++ b/skills/capability-evolver/src/gep/solidify.js @@ -17,6 +17,9 @@ const { const { computeAssetId, SCHEMA_VERSION } = require('./contentHash'); const { captureEnvFingerprint } = require('./envFingerprint'); const { buildValidationReport } = require('./validationReport'); +const { logAssetCall } = require('./assetCallLog'); +const { recordNarrative } = require('./narrativeMemory'); +const { isLlmReviewEnabled, runLlmReview } = require('./llmReview'); function nowIso() { return new Date().toISOString(); @@ -701,10 +704,14 @@ function rollbackNewUntrackedFiles({ repoRoot, baselineUntracked }) { // This prevents "ghost skill directories" where mkdir succeeded but // file creation failed/was rolled back. Without this, empty dirs like // skills/anima/, skills/oblivion/ etc. accumulate after failed innovations. + // SAFETY: never remove top-level structural directories (skills/, src/, etc.) + // or critical protected directories. Only remove leaf subdirectories. var dirsToCheck = new Set(); for (var di = 0; di < deleted.length; di++) { var dir = path.dirname(deleted[di]); while (dir && dir !== '.' && dir !== '/') { + var normalized = dir.replace(/\\/g, '/'); + if (!normalized.includes('/')) break; dirsToCheck.add(dir); dir = path.dirname(dir); } @@ -713,6 +720,7 @@ function rollbackNewUntrackedFiles({ repoRoot, baselineUntracked }) { var sortedDirs = Array.from(dirsToCheck).sort(function (a, b) { return b.length - a.length; }); var removedDirs = []; for (var si = 0; si < sortedDirs.length; si++) { + if (isCriticalProtectedPath(sortedDirs[si] + '/')) continue; var dirAbs = path.join(repoRoot, sortedDirs[si]); try { var entries = fs.readdirSync(dirAbs); @@ -957,8 +965,32 @@ function readRecentSessionInputs() { return { recentSessionTranscript, todayLog: todayLogContent, memorySnippet, userSnippet }; } +function isGitRepo(dir) { + try { + execSync('git rev-parse --git-dir', { + cwd: dir, encoding: 'utf8', + stdio: ['ignore', 'pipe', 'pipe'], timeout: 5000, + }); + return true; + } catch (_) { + return false; + } +} + function solidify({ intent, summary, dryRun = false, rollbackOnFailure = true } = {}) { const repoRoot = getRepoRoot(); + + if (!isGitRepo(repoRoot)) { + console.error('[Solidify] FATAL: Not a git repository (' + repoRoot + ').'); + console.error('[Solidify] Solidify requires git for rollback, diff capture, and blast radius.'); + console.error('[Solidify] Run "git init && git add -A && git commit -m init" first.'); + return { + ok: false, + status: 'failed', + failure_reason: 'not_a_git_repository', + event: null, + }; + } const state = readStateForSolidify(); const lastRun = state && state.last_run ? state.last_run : null; const genes = loadGenes(); @@ -1053,6 +1085,29 @@ function solidify({ intent, summary, dryRun = false, rollbackOnFailure = true } console.error(`[Solidify] CANARY FAILED: ${canary.err}`); } + // Optional LLM review: when EVOLVER_LLM_REVIEW=true, submit diff for review. + let llmReviewResult = null; + if (constraintCheck.ok && validation.ok && protocolViolations.length === 0 && isLlmReviewEnabled()) { + try { + const reviewDiff = captureDiffSnapshot(repoRoot); + llmReviewResult = runLlmReview({ + diff: reviewDiff, + gene: geneUsed, + signals, + mutation, + }); + if (llmReviewResult && llmReviewResult.approved === false) { + constraintCheck.violations.push('llm_review_rejected: ' + (llmReviewResult.summary || 'no reason')); + constraintCheck.ok = false; + console.log('[LLMReview] Change REJECTED: ' + (llmReviewResult.summary || '')); + } else if (llmReviewResult) { + console.log('[LLMReview] Change approved (confidence: ' + (llmReviewResult.confidence || '?') + ')'); + } + } catch (e) { + console.log('[LLMReview] Failed (non-fatal): ' + (e && e.message ? e.message : e)); + } + } + // Build standardized ValidationReport (machine-readable, interoperable). const validationReport = buildValidationReport({ geneId: geneUsed && geneUsed.id ? geneUsed.id : null, @@ -1212,7 +1267,12 @@ function solidify({ intent, summary, dryRun = false, rollbackOnFailure = true } if (!dryRun && !success && rollbackOnFailure) { rollbackTracked(repoRoot); - rollbackNewUntrackedFiles({ repoRoot, baselineUntracked: lastRun && lastRun.baseline_untracked ? lastRun.baseline_untracked : [] }); + // Only clean up new untracked files when a valid baseline exists. + // Without a baseline, we cannot distinguish pre-existing untracked files + // from AI-generated ones, so deleting would be destructive. + if (lastRun && Array.isArray(lastRun.baseline_untracked)) { + rollbackNewUntrackedFiles({ repoRoot, baselineUntracked: lastRun.baseline_untracked }); + } } // Apply epigenetic marks to the gene based on outcome and environment @@ -1254,6 +1314,21 @@ function solidify({ intent, summary, dryRun = false, rollbackOnFailure = true } }; if (!dryRun) writeStateForSolidify(state); + if (!dryRun) { + try { + recordNarrative({ + gene: geneUsed, + signals, + mutation, + outcome: event.outcome, + blast, + capsule, + }); + } catch (e) { + console.log('[Narrative] Record failed (non-fatal): ' + (e && e.message ? e.message : e)); + } + } + // Search-First Evolution: auto-publish eligible capsules to the Hub (as Gene+Capsule bundle). let publishResult = null; if (!dryRun && capsule && capsule.a2a && capsule.a2a.eligible_to_broadcast) { @@ -1327,6 +1402,21 @@ function solidify({ intent, summary, dryRun = false, rollbackOnFailure = true } }); } publishResult = { attempted: true, asset_id: capsule.asset_id || capsule.id, bundle: true }; + logAssetCall({ + run_id: lastRun && lastRun.run_id ? lastRun.run_id : null, + action: 'asset_publish', + asset_id: capsule.asset_id || capsule.id, + asset_type: 'Capsule', + source_node_id: null, + chain_id: publishChainId || null, + signals: Array.isArray(capsule.trigger) ? capsule.trigger : [], + extra: { + source_type: sourceType, + reused_asset_id: reusedAssetId, + gene_id: publishGene && publishGene.id ? publishGene.id : null, + parent: parentRef || null, + }, + }); } else { publishResult = { attempted: false, reason: 'no_hub_url' }; } @@ -1340,6 +1430,14 @@ function solidify({ intent, summary, dryRun = false, rollbackOnFailure = true } : sourceType === 'reused' ? 'skip_direct_reused_asset' : 'below_min_score'; publishResult = { attempted: false, reason }; + logAssetCall({ + run_id: lastRun && lastRun.run_id ? lastRun.run_id : null, + action: 'asset_publish_skip', + asset_id: capsule.asset_id || capsule.id, + asset_type: 'Capsule', + reason, + signals: Array.isArray(capsule.trigger) ? capsule.trigger : [], + }); } } @@ -1452,6 +1550,7 @@ function solidify({ intent, summary, dryRun = false, rollbackOnFailure = true } module.exports = { solidify, + isGitRepo, readStateForSolidify, writeStateForSolidify, isValidationCommandAllowed, diff --git a/skills/capability-evolver/src/gep/taskReceiver.js b/skills/capability-evolver/src/gep/taskReceiver.js index 743a132..4e9e4de 100644 --- a/skills/capability-evolver/src/gep/taskReceiver.js +++ b/skills/capability-evolver/src/gep/taskReceiver.js @@ -82,7 +82,8 @@ async function fetchTasks(opts) { } return result; - } catch { + } catch (err) { + console.warn("[TaskReceiver] fetchTasks failed:", err && err.message ? err.message : err); return { tasks: [] }; } } @@ -150,7 +151,7 @@ function estimateCapabilityMatch(task, memoryEvents) { var weightSum = 0; for (var sk in totalBySignalKey) { // Reconstruct signals from the key for comparison - var skParts = sk.split(':').map(function(s) { return s.trim().toLowerCase(); }).filter(Boolean); + var skParts = sk.split('|').map(function(s) { return s.trim().toLowerCase(); }).filter(Boolean); var sim = jaccard(taskSignals, skParts); if (sim < 0.15) continue; diff --git a/skills/capability-evolver/src/ops/cleanup.js b/skills/capability-evolver/src/ops/cleanup.js index 48e0770..71cd4fa 100644 --- a/skills/capability-evolver/src/ops/cleanup.js +++ b/skills/capability-evolver/src/ops/cleanup.js @@ -9,6 +9,14 @@ const { getEvolutionDir } = require('../gep/paths'); var MAX_AGE_MS = 24 * 60 * 60 * 1000; // 24 hours var MIN_KEEP = 10; +function safeBatchDelete(batch) { + var deleted = 0; + for (var i = 0; i < batch.length; i++) { + try { fs.unlinkSync(batch[i]); deleted++; } catch (_) {} + } + return deleted; +} + function run() { var evoDir = getEvolutionDir(); if (!fs.existsSync(evoDir)) return; @@ -26,36 +34,18 @@ function run() { var deleted = 0; // Phase 1: Age-based cleanup (keep at least MIN_KEEP) - // [OPTIMIZATION] Batch deletion for age-based cleanup as well - const filesToDelete = []; + var filesToDelete = []; for (var i = MIN_KEEP; i < files.length; i++) { if (now - files[i].mtime > MAX_AGE_MS) { filesToDelete.push(files[i].path); } } - + if (filesToDelete.length > 0) { - const BATCH_SIZE = 50; - for (let i = 0; i < filesToDelete.length; i += BATCH_SIZE) { - const batch = filesToDelete.slice(i, i + BATCH_SIZE); - try { - // Remove package-lock.json if it exists (not relevant here but good practice in other contexts) - // Use rm -f with quotes to handle paths safely - // Phase 1 optimization update: mirroring phase 2 logic - const args = batch.map(function(p) { return '"' + p + '"'; }).join(' '); - require('child_process').execSync('rm -f ' + args, { stdio: 'ignore' }); - deleted += batch.length; - } catch (e) { - // Fallback to serial deletion if batch fails - batch.forEach(function(p) { - try { fs.unlinkSync(p); deleted++; } catch (_) {} - }); - } - } + deleted += safeBatchDelete(filesToDelete); } - // Phase 2: Size-based safety cap (keep max 10 files total to drastically reduce bloat) - // Re-scan remaining files after age cleanup + // Phase 2: Size-based safety cap (keep max 10 files total) try { var remainingFiles = fs.readdirSync(evoDir) .filter(function(f) { return /^gep_prompt_.*\.(json|txt)$/.test(f); }) @@ -66,29 +56,10 @@ function run() { }) .sort(function(a, b) { return b.mtime - a.mtime; }); // newest first - // [OPTIMIZATION] Batch deletion using execSync('rm') for speed and robustness var MAX_FILES = 10; if (remainingFiles.length > MAX_FILES) { - const toDelete = remainingFiles.slice(MAX_FILES).map(function(f) { return f.path; }); - - // Chunking into batches of 50 to avoid E2BIG on some systems, - // though with MAX_FILES=10 and typical usage, list won't be huge. - const BATCH_SIZE = 50; - for (let i = 0; i < toDelete.length; i += BATCH_SIZE) { - const batch = toDelete.slice(i, i + BATCH_SIZE); - try { - // Safe bulk delete via shell, faster than serial unlinkSync - // Using "rm -f" to ignore non-existent files - const args = batch.map(function(p) { return '"' + p + '"'; }).join(' '); - require('child_process').execSync('rm -f ' + args, { stdio: 'ignore' }); - deleted += batch.length; - } catch (e) { - // Fallback to serial if batch fails - batch.forEach(function(p) { - try { fs.unlinkSync(p); deleted++; } catch (_) {} - }); - } - } + var toDelete = remainingFiles.slice(MAX_FILES).map(function(f) { return f.path; }); + deleted += safeBatchDelete(toDelete); } } catch (e) { console.warn('[Cleanup] Phase 2 failed:', e.message); diff --git a/workspace/.learnings/ERRORS.md b/workspace/.learnings/ERRORS.md new file mode 100644 index 0000000..ee77a45 --- /dev/null +++ b/workspace/.learnings/ERRORS.md @@ -0,0 +1,49 @@ +# Errors + +Command failures, exceptions, and issues captured during development. + +**Areas**: frontend | backend | infra | tests | docs | config +**Statuses**: pending | in_progress | resolved | wont_fix + +## Status Definitions + +| Status | Meaning | +|--------|---------| +| `pending` | Not yet addressed | +| `in_progress` | Actively being worked on | +| `resolved` | Issue fixed | +| `wont_fix` | Decided not to address (reason in Resolution) | + +## Entry Format + +```markdown +## [ERR-YYYYMMDD-XXX] title + +**Logged**: ISO-8601 timestamp +**Priority**: low | medium | high | critical +**Status**: pending +**Area**: frontend | backend | infra | tests | docs | config + +### Summary +Brief description of what failed + +### Error +``` +Actual error message +``` + +### Context +- What was attempted +- Input/parameters used +- Environment details + +### Suggested Fix +How this could be resolved + +### Metadata +- Reproducible: yes | no | unknown +- Related Files: path/to/file.ext +- See Also: ERR-20250110-001 + +--- +``` diff --git a/workspace/.learnings/FEATURE_REQUESTS.md b/workspace/.learnings/FEATURE_REQUESTS.md new file mode 100644 index 0000000..80fa8f3 --- /dev/null +++ b/workspace/.learnings/FEATURE_REQUESTS.md @@ -0,0 +1,44 @@ +# Feature Requests + +User-requested capabilities that don't exist yet. + +**Areas**: frontend | backend | infra | tests | docs | config +**Statuses**: pending | in_progress | resolved | wont_fix + +## Status Definitions + +| Status | Meaning | +|--------|---------| +| `pending` | Not yet addressed | +| `in_progress` | Actively being worked on | +| `resolved` | Feature implemented | +| `wont_fix` | Decided not to implement (reason in Resolution) | + +## Entry Format + +```markdown +## [FEAT-YYYYMMDD-XXX] title + +**Logged**: ISO-8601 timestamp +**Priority**: low | medium | high +**Status**: pending +**Area**: frontend | backend | infra | tests | docs | config + +### Requested Capability +What the user wanted to do + +### User Context +Why they needed it + +### Complexity Estimate +simple | medium | complex + +### Suggested Implementation +How this could be built + +### Metadata +- Frequency: first_time | recurring +- Related Features: existing_feature_name + +--- +``` diff --git a/workspace/.learnings/LEARNINGS.md b/workspace/.learnings/LEARNINGS.md new file mode 100644 index 0000000..6993f9b --- /dev/null +++ b/workspace/.learnings/LEARNINGS.md @@ -0,0 +1,45 @@ +# Learnings + +Corrections, insights, and knowledge gaps captured during development. + +**Categories**: correction | insight | knowledge_gap | best_practice +**Areas**: frontend | backend | infra | tests | docs | config +**Statuses**: pending | in_progress | resolved | wont_fix | promoted | promoted_to_skill + +## Status Definitions + +| Status | Meaning | +|--------|---------| +| `pending` | Not yet addressed | +| `in_progress` | Actively being worked on | +| `resolved` | Issue fixed or knowledge integrated | +| `wont_fix` | Decided not to address (reason in Resolution) | +| `promoted` | Elevated to CLAUDE.md, AGENTS.md, or copilot-instructions.md | +| `promoted_to_skill` | Extracted as a reusable skill | + +## Skill Extraction Fields + +When a learning is promoted to a skill, add these fields: + +```markdown +**Status**: promoted_to_skill +**Skill-Path**: skills/skill-name +``` + +Example: +```markdown +## [LRN-20250115-001] best_practice + +**Logged**: 2025-01-15T10:00:00Z +**Priority**: high +**Status**: promoted_to_skill +**Skill-Path**: skills/docker-m1-fixes +**Area**: infra + +### Summary +Docker build fails on Apple Silicon due to platform mismatch +... +``` + +--- +