mirror of
https://github.com/zhayujie/chatgpt-on-wechat.git
synced 2026-07-17 19:27:11 +08:00
Add a self-evolution subsystem that reviews idle conversations in an isolated agent and durably learns from them — patching/creating skills, finishing unfinished tasks, and backfilling missed memory. - Trigger: background idle scan, fires when a session is idle >= N min AND (>= N turns OR context usage > 80%). In-memory cursor reviews only new messages so a session never re-learns old content. - Isolated review agent: same model, restricted toolset, hard write-guard confining edits to the workspace (built-in skills are protected). - Safety: file-level backup before edits + evolution_undo tool; notify the user ONLY when a workspace file actually changed (no-nag rule); capped concurrency. - Records to memory/evolution/<date>.md, surfaced in the memory UI's renamed "Self-Evolution" tab (merged with dream diaries). - Hide internal [SCHEDULED]/[EVOLUTION]/backup_id markers from chat history display (also fixes scheduler marker leakage) while keeping them in stored content for undo. - Flat config: self_evolution_enabled (default off until release), self_evolution_idle_minutes (15), self_evolution_min_turns (6). - Tests: tests/test_evolution.py (stub + real model modes, 7 scenarios).
59 lines
2.3 KiB
Python
59 lines
2.3 KiB
Python
"""Evolution undo tool.
|
|
|
|
Lets the main chat agent roll back a previous self-evolution when the user asks
|
|
("undo the last learning"). The rollback itself is a deterministic FILE RESTORE
|
|
from the snapshot taken before the evolution — the model only supplies the
|
|
backup_id it reads from the [EVOLUTION] record in the conversation. No LLM-driven
|
|
re-editing is involved, so a restore can never make things worse.
|
|
"""
|
|
|
|
from agent.tools.base_tool import BaseTool, ToolResult
|
|
|
|
|
|
class EvolutionUndoTool(BaseTool):
|
|
"""Restore memory/skill files to the state before a self-evolution."""
|
|
|
|
name: str = "evolution_undo"
|
|
description: str = (
|
|
"Undo a previous self-evolution (self-learning) by restoring the "
|
|
"memory/skill files to their state before that learning. Use this when "
|
|
"the user asks to undo / revert / roll back the last self-learning. "
|
|
"Find the backup_id in the most recent [EVOLUTION] record in the "
|
|
"conversation and pass it here."
|
|
)
|
|
params: dict = {
|
|
"type": "object",
|
|
"properties": {
|
|
"backup_id": {
|
|
"type": "string",
|
|
"description": (
|
|
"The backup_id from the [EVOLUTION] record to restore "
|
|
"(e.g. '20260607-155551-850')."
|
|
),
|
|
}
|
|
},
|
|
"required": ["backup_id"],
|
|
}
|
|
|
|
def execute(self, args: dict):
|
|
backup_id = (args.get("backup_id") or "").strip()
|
|
if not backup_id:
|
|
return ToolResult.fail("Error: backup_id is required")
|
|
try:
|
|
from agent.memory.config import get_default_memory_config
|
|
from agent.evolution.backup import restore_backup
|
|
|
|
workspace_dir = get_default_memory_config().get_workspace()
|
|
ok = restore_backup(workspace_dir, backup_id)
|
|
if ok:
|
|
return ToolResult.success(
|
|
f"Restored memory/skills to the state before evolution "
|
|
f"{backup_id}. The previous self-learning has been undone."
|
|
)
|
|
return ToolResult.fail(
|
|
f"Could not find or restore backup {backup_id}. It may have "
|
|
f"expired or already been rolled back."
|
|
)
|
|
except Exception as e:
|
|
return ToolResult.fail(f"Error during undo: {e}")
|