Files
beaver_project/app-instance/backend/beaver/tools/builtins/memory.py
steven_li 5ba5c7e4c1 feat(app-instance): 集成Beaver后端并更新配置管理
集成新的Beaver后端服务到应用实例中,替换原有的nanobot实现。

主要变更包括:
- 在Dockerfile和环境配置中添加Beaver相关路径和配置变量
- 更新工作目录结构从.nanobot到.beaver
- 实现Beaver引擎加载器,支持配置文件加载和工具组装
- 添加内置工具如ListDirectoryTool、ReadFileTool、SearchFilesTool
- 更新消息处理流程,支持通道适配器和网关模式
- 重构技能系统,支持显式工具提示和嵌入式检索
- 改进错误处理和生命周期管理

此变更使应用实例能够使用统一的Beaver后端进行AI代理运行时管理。
2026-04-27 17:37:40 +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:
"""分发 Hermes 风格的 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)