集成新的Beaver后端服务到应用实例中,替换原有的nanobot实现。 主要变更包括: - 在Dockerfile和环境配置中添加Beaver相关路径和配置变量 - 更新工作目录结构从.nanobot到.beaver - 实现Beaver引擎加载器,支持配置文件加载和工具组装 - 添加内置工具如ListDirectoryTool、ReadFileTool、SearchFilesTool - 更新消息处理流程,支持通道适配器和网关模式 - 重构技能系统,支持显式工具提示和嵌入式检索 - 改进错误处理和生命周期管理 此变更使应用实例能够使用统一的Beaver后端进行AI代理运行时管理。
132 lines
4.1 KiB
Python
132 lines
4.1 KiB
Python
"""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)
|