feat(app-instance): 集成Beaver后端并更新配置管理

集成新的Beaver后端服务到应用实例中,替换原有的nanobot实现。

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

此变更使应用实例能够使用统一的Beaver后端进行AI代理运行时管理。
This commit is contained in:
2026-04-27 17:37:40 +08:00
parent 36882a7d7b
commit 5ba5c7e4c1
47 changed files with 2821 additions and 462 deletions

View File

@ -1,6 +1,15 @@
"""Application services for Beaver."""
from .agent_service import AgentService
from .memory_service import MemoryService
__all__ = ["AgentService", "MemoryService"]
def __getattr__(name: str):
if name == "AgentService":
from .agent_service import AgentService
return AgentService
if name == "MemoryService":
from .memory_service import MemoryService
return MemoryService
raise AttributeError(name)

View File

@ -17,6 +17,7 @@ from pathlib import Path
from typing import Any
from beaver.engine import AgentLoop, AgentProfile, AgentRunResult, EngineLoader
from beaver.foundation.events import InboundMessage, OutboundMessage
class AgentService:
@ -36,11 +37,12 @@ class AgentService:
self,
*,
workspace: str | Path | None = None,
config_path: str | Path | None = None,
profile: AgentProfile | None = None,
loader: EngineLoader | None = None,
) -> None:
self.profile = profile or AgentProfile()
self.loader = loader or EngineLoader(workspace=workspace)
self.loader = loader or EngineLoader(workspace=workspace, config_path=config_path)
self._loop: AgentLoop | None = None
self._run_task: asyncio.Task[None] | None = None
@ -189,6 +191,60 @@ class AgentService:
loop = self.create_loop()
return await loop.submit_direct(message, **kwargs)
async def handle_inbound_message(self, inbound: InboundMessage) -> OutboundMessage:
"""把 bus inbound 映射成标准 runtime 调用,并返回结构化 outbound。"""
try:
result = await self.submit_direct(
inbound.content,
session_id=inbound.session_id,
source=f"gateway:{inbound.channel}",
user_id=inbound.user_id,
title=inbound.title,
execution_context=inbound.execution_context,
model=inbound.model,
provider_name=inbound.provider_name,
embedding_model=inbound.embedding_model,
)
except Exception as exc:
return self.build_outbound_error(inbound, detail=str(exc))
return self.build_outbound_message(inbound, result)
@staticmethod
def build_outbound_message(inbound: InboundMessage, result: AgentRunResult) -> OutboundMessage:
"""把一次 runtime 正常结果转成 bus outbound。"""
return OutboundMessage(
message_id=inbound.message_id,
channel=inbound.channel,
session_id=result.session_id,
run_id=result.run_id,
content=result.output_text,
finish_reason=result.finish_reason,
provider_name=result.provider_name,
model=result.model,
usage=dict(result.usage),
metadata={"inbound_metadata": dict(inbound.metadata)},
)
@staticmethod
def build_outbound_error(
inbound: InboundMessage,
*,
detail: str,
finish_reason: str = "error",
) -> OutboundMessage:
"""把 inbound 处理失败转换成结构化 outbound 错误消息。"""
return OutboundMessage(
message_id=inbound.message_id,
channel=inbound.channel,
session_id=inbound.session_id,
content=detail,
finish_reason=finish_reason,
metadata={"error": detail, "inbound_metadata": dict(inbound.metadata)},
)
def run_direct(
self,
message: str,