From 828ada12edb7a6e716d71f2f24e5b65aac9fb27e Mon Sep 17 00:00:00 2001
From: TevinClaw <510129976@qq.com>
Date: Mon, 16 Mar 2026 11:34:45 +0800
Subject: [PATCH] config: 更新配置文件和定时任务状态

---
 workspace/skills/memory-management/scripts/weekly_maintenance.py |  255 +++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 235 insertions(+), 20 deletions(-)

diff --git a/workspace/skills/memory-management/scripts/weekly_maintenance.py b/workspace/skills/memory-management/scripts/weekly_maintenance.py
index e4cee14..dbe8802 100755
--- a/workspace/skills/memory-management/scripts/weekly_maintenance.py
+++ b/workspace/skills/memory-management/scripts/weekly_maintenance.py
@@ -2,7 +2,7 @@
 """
 每周维护脚本
 周一早上9:30执行,负责:
-1. 运行memory-merger整理L2→L1
+1. 自动合并L2→L1(基于内容筛选策略)
 2. 检查L0大小
 3. 生成周报
 4. 发送报告(可选)
@@ -11,6 +11,7 @@
 import os
 import sys
 import subprocess
+import re
 from datetime import datetime, timedelta
 from pathlib import Path
 
@@ -20,28 +21,242 @@
     return Path.home() / ".openclaw" / "workspace"
 
 
-def run_memory_merger() -> tuple:
-    """运行memory-merger技能。"""
-    workspace = get_workspace_path()
-    merger_path = workspace / ".agents" / "skills" / "memory-merger"
+def should_merge_to_l1(content: str) -> tuple:
+    """
+    判断L2内容是否应该合并到L1
+    返回: (是否应该合并, 原因/类别)
+    """
+    content_lower = content.lower()
     
-    if not merger_path.exists():
-        return False, "memory-merger技能未安装"
+    # 策略1: 关键词匹配 - 重要决策类
+    decision_keywords = [
+        "决策", "决定", "结论", "方案", "选择",
+        "采用", "确定", "最终", "resolved", "解决",
+        "关键", "重要", "核心", "原则"
+    ]
     
-    # 运行memory-merger
+    # 策略2: 技术方案类
+    tech_keywords = [
+        "架构", "设计", "实现", "配置", "优化",
+        "部署", "迁移", "升级", "重构", "方案"
+    ]
+    
+    # 策略3: 经验教训类
+    lesson_keywords = [
+        "教训", "经验", "学习", "注意", "避免",
+        "问题", "bug", "错误", "失败原因"
+    ]
+    
+    # 策略4: 流程规范类
+    process_keywords = [
+        "流程", "规范", "规则", "约定", "标准",
+        "红线", "必须", "禁止", "要求"
+    ]
+    
+    # 检查匹配
+    matched_keywords = []
+    category = None
+    
+    for kw in decision_keywords:
+        if kw in content_lower:
+            matched_keywords.append(kw)
+            category = "决策记录"
+            break
+    
+    if not category:
+        for kw in tech_keywords:
+            if kw in content_lower:
+                matched_keywords.append(kw)
+                category = "技术方案"
+                break
+    
+    if not category:
+        for kw in lesson_keywords:
+            if kw in content_lower:
+                matched_keywords.append(kw)
+                category = "经验教训"
+                break
+    
+    if not category:
+        for kw in process_keywords:
+            if kw in content_lower:
+                matched_keywords.append(kw)
+                category = "流程规范"
+                break
+    
+    # 策略5: 内容长度检查(太短的内容不值得合并)
+    if len(content) < 200:
+        return False, "内容过短"
+    
+    # 策略6: 必须有结构化标记(有###标题的才算正式记录)
+    has_structure = bool(re.search(r'###\s+', content))
+    if not has_structure:
+        return False, "缺乏结构化标记"
+    
+    if category:
+        return True, category
+    
+    return False, "未匹配合并策略"
+
+
+def is_duplicate_in_l1(content: str, l1_file: Path) -> bool:
+    """检查内容是否已在L1中存在(简单去重)"""
+    if not l1_file.exists():
+        return False
+    
     try:
-        result = subprocess.run(
-            ["python", str(merger_path / "scripts" / "merge.py"), "memory-management"],
-            capture_output=True,
-            text=True,
-            timeout=60
-        )
-        if result.returncode == 0:
-            return True, result.stdout
-        else:
-            return False, result.stderr
-    except Exception as e:
-        return False, str(e)
+        l1_content = l1_file.read_text(encoding='utf-8')
+        # 提取内容前100字作为指纹
+        content_fingerprint = content[:100].strip()
+        # 检查L1中是否已有相似内容
+        return content_fingerprint in l1_content
+    except Exception:
+        return False
+
+
+def auto_merge_l2_to_l1() -> dict:
+    """
+    自动合并本周L2到L1
+    返回合并统计信息
+    """
+    workspace = get_workspace_path()
+    journal_dir = workspace / "memory" / "journal"
+    milestones_dir = workspace / "memory" / "milestones"
+    
+    if not journal_dir.exists():
+        return {"status": "no_journal", "merged": 0, "skipped": 0, "details": []}
+    
+    # 确保milestones目录存在
+    milestones_dir.mkdir(parents=True, exist_ok=True)
+    
+    # 获取本周日期范围
+    today = datetime.now()
+    start_of_week = today - timedelta(days=today.weekday())
+    
+    # 本周的L1文件
+    current_month = today.strftime("%Y-%m")
+    l1_file = milestones_dir / f"{current_month}-weekly.md"
+    
+    merged_count = 0
+    skipped_count = 0
+    details = []
+    
+    # 遍历本周L2文件
+    for l2_file in sorted(journal_dir.glob("*.md")):
+        try:
+            file_date = datetime.strptime(l2_file.stem, "%Y-%m-%d")
+            if not (start_of_week <= file_date <= today):
+                continue
+            
+            # 读取L2内容
+            l2_content = l2_file.read_text(encoding='utf-8')
+            
+            # 按事件分割(按##标题分割)
+            events = re.split(r'\n##\s+\[', l2_content)
+            
+            for event in events[1:]:  # 第一个通常是文件头
+                event = "## [" + event  # 恢复标题标记
+                
+                # 提取事件标题
+                title_match = re.search(r'##\s*\[.*?\]\s*(.+?)\n', event)
+                title = title_match.group(1).strip() if title_match else "未命名事件"
+                
+                # 判断是否应该合并
+                should_merge, reason = should_merge_to_l1(event)
+                
+                if not should_merge:
+                    skipped_count += 1
+                    details.append({
+                        "date": l2_file.stem,
+                        "title": title,
+                        "action": "跳过",
+                        "reason": reason
+                    })
+                    continue
+                
+                # 检查是否重复
+                if is_duplicate_in_l1(event, l1_file):
+                    skipped_count += 1
+                    details.append({
+                        "date": l2_file.stem,
+                        "title": title,
+                        "action": "跳过",
+                        "reason": "L1中已存在"
+                    })
+                    continue
+                
+                # 执行合并
+                try:
+                    # 准备L1格式内容
+                    l1_entry = f"""
+## [{l2_file.stem}] {title}
+**类别**: {reason}
+**来源**: [L2详情](./journal/{l2_file.name})
+
+### 摘要
+{event[:500]}...
+
+---
+"""
+                    
+                    # 追加到L1文件
+                    with open(l1_file, 'a', encoding='utf-8') as f:
+                        f.write(l1_entry)
+                    
+                    merged_count += 1
+                    details.append({
+                        "date": l2_file.stem,
+                        "title": title,
+                        "action": "已合并",
+                        "category": reason
+                    })
+                    
+                except Exception as e:
+                    details.append({
+                        "date": l2_file.stem,
+                        "title": title,
+                        "action": "失败",
+                        "reason": str(e)
+                    })
+                    
+        except ValueError:
+            continue  # 文件名格式不正确
+        except Exception as e:
+            details.append({
+                "date": l2_file.stem if 'l2_file' in locals() else "unknown",
+                "title": "读取失败",
+                "action": "错误",
+                "reason": str(e)
+            })
+    
+    return {
+        "status": "success" if merged_count > 0 else "no_merge",
+        "merged": merged_count,
+        "skipped": skipped_count,
+        "l1_file": str(l1_file) if merged_count > 0 else None,
+        "details": details
+    }
+
+
+def run_memory_merger() -> tuple:
+    """运行自动合并(替代原memory-merger调用)"""
+    result = auto_merge_l2_to_l1()
+    
+    if result["status"] == "no_journal":
+        return False, "未找到journal目录"
+    
+    if result["status"] == "success":
+        summary = f"✅ 合并完成: {result['merged']} 条 → {result['l1_file']}\n"
+        summary += f"⏭️  跳过: {result['skipped']} 条\n"
+        summary += "\n详细记录:\n"
+        for d in result['details'][-5:]:  # 只显示最后5条
+            summary += f"  - [{d['date']}] {d['title']}: {d['action']}"
+            if 'reason' in d:
+                summary += f" ({d['reason']})"
+            summary += "\n"
+        return True, summary
+    else:
+        return False, f"未找到可合并内容(本周共扫描 {result['skipped']} 条,均不符合合并条件)"
 
 
 def check_l0_size() -> dict:

--
Gitblit v1.9.1