Files
beaver_project/app-instance/backend/beaver/tools/registry/tool_registry.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

80 lines
2.5 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 工具注册表。
这层只做三件事:
1. 注册工具
2. 按名称查找工具
3. 导出 provider 可消费的 tool schemas
不要把执行逻辑塞进这里。
执行属于 runtime/executor那样边界更清晰。
"""
from __future__ import annotations
from collections.abc import Sequence
from typing import Iterable
from beaver.tools.base import BaseTool, ToolSpec
class ToolRegistry:
"""统一维护当前 runtime 可用的工具集合。"""
def __init__(self) -> None:
self._tools: dict[str, BaseTool] = {}
def register(self, tool: BaseTool, *, replace: bool = False) -> None:
"""注册一个工具。
默认不允许重名覆盖,避免 loader/runtime 不小心把同名工具静默冲掉。
"""
name = tool.spec.name
if not replace and name in self._tools:
raise ValueError(f"Tool '{name}' is already registered")
self._tools[name] = tool
def register_many(self, tools: Iterable[BaseTool], *, replace: bool = False) -> None:
for tool in tools:
self.register(tool, replace=replace)
def get(self, name: str) -> BaseTool | None:
return self._tools.get(name)
def require(self, name: str) -> BaseTool:
tool = self.get(name)
if tool is None:
raise KeyError(f"Unknown tool '{name}'")
return tool
def list_specs(self) -> list[ToolSpec]:
return [tool.spec for tool in self._tools.values()]
def list_always_specs(self) -> list[ToolSpec]:
"""列出每轮 run 都应该暴露给模型的基础工具。"""
return [spec for spec in self.list_specs() if spec.always_available]
def get_specs(self, names: Sequence[str]) -> list[ToolSpec]:
"""按名称顺序返回已注册工具 spec忽略未知工具。"""
specs: list[ToolSpec] = []
seen: set[str] = set()
for name in names:
tool = self.get(name)
if tool is None or name in seen:
continue
specs.append(tool.spec)
seen.add(name)
return specs
def export_provider_schemas(self) -> list[dict]:
"""导出给 provider 的函数工具 schema 列表。"""
return [spec.to_provider_schema() for spec in self.list_specs()]
def export_selected_provider_schemas(self, specs: Sequence[ToolSpec]) -> list[dict]:
"""导出一组已选择工具的 provider schema。"""
return [spec.to_provider_schema() for spec in specs]