Files
beaver_project/app-instance/backend/beaver/tools/builtins/memory.py
steven_li 3b0af173cc refactor(beaver): 移除Hermes相关引用和迁移代码,完善Beaver后端主线实现
移除了所有Hermes相关的命名引用,包括:
- 从.gitignore中清理相关构建缓存文件
- 将README中的beaver-home路径配置更新
- 完善backend/README.md文档说明Beaver后端主线实现
- 移除Hermes风格的相关注释和兼容性代码
- 清理nanobot环境变量兼容性处理
- 删除技能迁移和服务迁移相关功能代码
- 更新测试用例中相关命名和函数名

BREAKING CHANGE: 移除了Hermes迁移相关API和CLI命令,不再支持nanobot环境变量兼容性
2026-05-14 17:20:32 +08:00

132 lines
4.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Beaver 内置 memory tool。
这个文件的职责很单纯:把 `MemoryStore` 暴露成一个 agent runtime 可以调用的统一工具。
设计边界:
1. `store.py` 负责底层数据与并发安全
2. 本文件负责工具接口、参数校验分发、JSON 响应
3. 更高层的 engine / loader 之后再决定如何把这个工具注册进 runtime
换句话说本文件是“memory 能力的工具化外壳”,不是记忆实现本身。
"""
from __future__ import annotations
import json
from dataclasses import dataclass, field
from typing import Any
from beaver.memory.curated.store import MemoryStore
MEMORY_TOOL_DESCRIPTION = (
"Save durable information to persistent memory that survives across sessions. "
"Use this proactively for user corrections, preferences, environment facts, "
"project conventions, and stable tool quirks. Do not store temporary task "
"progress or raw session logs here; use session search for historical detail."
)
MEMORY_TOOL_PARAMETERS: dict[str, Any] = {
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": ["add", "replace", "remove"],
"description": "The memory operation to perform.",
},
"target": {
"type": "string",
"enum": ["memory", "user"],
"description": "Which curated store to update.",
},
"content": {
"type": "string",
"description": "The new entry content. Required for add and replace.",
},
"old_text": {
"type": "string",
"description": "A short unique substring identifying the entry to replace or remove.",
},
},
"required": ["action", "target"],
}
def memory_tool(
*,
action: str,
target: str = "memory",
content: str | None = None,
old_text: str | None = None,
store: MemoryStore | None = None,
) -> str:
"""分发 CRUD memory API并返回 JSON 字符串。
这里统一采用 JSON 返回,是为了兼容常见 tool-calling 场景:
- LLM 更容易消费结构化结果
- Web/API/日志层也更容易透传和记录
"""
if store is None:
return json.dumps(
{
"success": False,
"error": "Memory store is not available for this runtime.",
},
ensure_ascii=False,
)
if target not in {"memory", "user"}:
return json.dumps(
{
"success": False,
"error": f"Invalid target '{target}'. Use 'memory' or 'user'.",
},
ensure_ascii=False,
)
if action == "add":
if not content:
result = {"success": False, "error": "content is required for add."}
else:
result = store.add(target, content)
elif action == "replace":
if not old_text:
result = {"success": False, "error": "old_text is required for replace."}
elif not content:
result = {"success": False, "error": "content is required for replace."}
else:
result = store.replace(target, old_text, content)
elif action == "remove":
if not old_text:
result = {"success": False, "error": "old_text is required for remove."}
else:
result = store.remove(target, old_text)
else:
result = {
"success": False,
"error": f"Unknown action '{action}'. Use add, replace, or remove.",
}
return json.dumps(result, ensure_ascii=False)
@dataclass(slots=True)
class MemoryTool:
"""面向 runtime 的轻量工具封装。
这里故意保持很薄:
1. 不重复实现业务逻辑
2. 不重复维护 schema
3. 只做 `execute()` 到 `memory_tool()` 的桥接
"""
store: MemoryStore
name: str = "memory"
description: str = MEMORY_TOOL_DESCRIPTION
toolset: str = "memory"
always_available: bool = True
parameters: dict[str, Any] = field(default_factory=lambda: dict(MEMORY_TOOL_PARAMETERS))
async def execute(self, **kwargs: Any) -> str:
return memory_tool(store=self.store, **kwargs)