refactor(agent): 按需加载 Agent 运行时 (#6336)

This commit is contained in:
InfinityPacer
2026-08-16 19:25:24 +08:00
committed by GitHub
parent e5f0c53069
commit 5b367011c5
56 changed files with 5059 additions and 628 deletions
+76 -45
View File
@@ -1,26 +1,46 @@
"""Agent 编排服务门面。
chain 层需要触发 Agent 后台任务、渲染提示词、查询模型能力时统一经本模块调用。
具体实现由 app.agent 在启动时注册,形成依赖倒置:
具体实现由 startup 组合根注册,形成依赖倒置:
chain -> application.agent <- agentstartup 在导入期注册)
chain -> application.agent <- startup -> agent
静态依赖图上 application 不依赖 agentagent 作为入口层向 application
注册实现,从而拆除 chain <-> agent 的互指环
注意:本模块禁止静态导入 app.agent 下的任何模块(含函数内导入),
否则会形成 agent -> chain -> application -> agent 的新环。
未注册时的兜底注册由 startup/agent_initializer 在导入期完成。
门面保存 provider 而非重量级实现对象,注册本身不会物化 Agent、LLM 或工具树。
本模块禁止静态或函数内导入 app.agent,否则会重新形成跨层循环依赖
"""
from typing import Any, Callable, Optional
# 注册表:启动期由 startup/agent_initializer 填充。
_agent_manager: Any = None
_prompt_manager: Any = None
_agent_capability_manager: Any = None
_llm_helper: Any = None
_manual_redo_prompt_builder: Optional[Callable[[Any], str]] = None
Provider = Callable[[], Any]
# provider 注册表由 startup/agent_initializer 在组合根装配。
_agent_manager_provider: Optional[Provider] = None
_running_agent_manager_provider: Optional[Provider] = None
_prompt_manager_provider: Optional[Provider] = None
_agent_capability_manager_provider: Optional[Provider] = None
_llm_helper_provider: Optional[Provider] = None
_manual_redo_prompt_builder_provider: Optional[Provider] = None
def register_agent_service_providers(
*,
agent_manager_provider: Provider,
running_agent_manager_provider: Provider,
prompt_manager_provider: Provider,
capability_manager_provider: Provider,
llm_helper_provider: Provider,
manual_redo_prompt_builder_provider: Provider,
) -> None:
"""注册 Agent 服务 provider,保持组合根装配阶段零重量实现导入。"""
global _agent_manager_provider, _running_agent_manager_provider
global _prompt_manager_provider, _agent_capability_manager_provider
global _llm_helper_provider, _manual_redo_prompt_builder_provider
_agent_manager_provider = agent_manager_provider
_running_agent_manager_provider = running_agent_manager_provider
_prompt_manager_provider = prompt_manager_provider
_agent_capability_manager_provider = capability_manager_provider
_llm_helper_provider = llm_helper_provider
_manual_redo_prompt_builder_provider = manual_redo_prompt_builder_provider
def register_agent_services(
@@ -30,38 +50,40 @@ def register_agent_services(
llm_helper: Any,
manual_redo_prompt_builder: Optional[Callable[[Any], str]] = None,
) -> None:
"""注册 Agent 服务实现(由 startup 组合根在导入期调用)"""
global _agent_manager, _prompt_manager, _agent_capability_manager, _llm_helper
global _manual_redo_prompt_builder
_agent_manager = agent_manager
_prompt_manager = prompt_manager
_agent_capability_manager = capability_manager
_llm_helper = llm_helper
_manual_redo_prompt_builder = manual_redo_prompt_builder
"""兼容直接对象注入;生产组合根应注册惰性 provider"""
register_agent_service_providers(
agent_manager_provider=lambda: agent_manager,
running_agent_manager_provider=lambda: agent_manager,
prompt_manager_provider=lambda: prompt_manager,
capability_manager_provider=lambda: capability_manager,
llm_helper_provider=lambda: llm_helper,
manual_redo_prompt_builder_provider=lambda: manual_redo_prompt_builder,
)
def _ensure_registered() -> None:
"""校验 Agent 服务已注册。
正常启动路径由 startup/agent_initializer 在导入期注册;未注册时
直接抛出带指引的错误,避免在此处静态导入 app.agent 破坏依赖方向。
"""
if _agent_manager is None:
def _resolve(provider: Optional[Provider], service_name: str) -> Any:
"""解析已注册服务;缺少组合根装配时给出稳定错误。"""
if provider is None:
raise RuntimeError(
"Agent 服务未注册:请先导入 app.startup.agent_initializer 完成组合根装配"
f"Agent 服务 {service_name} 未注册:"
"请先导入 app.startup.agent_initializer 完成组合根装配"
)
return provider()
def get_agent_manager() -> Any:
"""返回 AgentManager 单例"""
_ensure_registered()
return _agent_manager
"""返回 canonical AgentManager;调用可能触发实现物化"""
return _resolve(_agent_manager_provider, "agent_manager")
def get_running_agent_manager() -> Any | None:
"""返回已进入 RUNNING 的 AgentManager,不触发实现物化。"""
return _resolve(_running_agent_manager_provider, "running_agent_manager")
def get_prompt_manager() -> Any:
"""返回提示词管理器。"""
_ensure_registered()
return _prompt_manager
"""按需返回提示词管理器。"""
return _resolve(_prompt_manager_provider, "prompt_manager")
def supports_image_input(
@@ -71,8 +93,8 @@ def supports_image_input(
base_url_preset: Optional[str] = None,
) -> bool:
"""判断当前模型是否启用了图片输入能力。"""
_ensure_registered()
return _llm_helper.supports_image_input(
llm_helper = _resolve(_llm_helper_provider, "llm_helper")
return llm_helper.supports_image_input(
provider=provider,
model=model,
base_url=base_url,
@@ -82,19 +104,28 @@ def supports_image_input(
def is_audio_input_available() -> bool:
"""判断语音输入能力是否可用。"""
_ensure_registered()
return _agent_capability_manager.is_audio_input_available()
capability_manager = _resolve(
_agent_capability_manager_provider,
"agent_capability_manager",
)
return capability_manager.is_audio_input_available()
def transcribe_audio(content: bytes, filename: str = "input.ogg") -> Optional[str]:
"""把音频内容转写为文本。"""
_ensure_registered()
return _agent_capability_manager.transcribe_audio(content, filename=filename)
capability_manager = _resolve(
_agent_capability_manager_provider,
"agent_capability_manager",
)
return capability_manager.transcribe_audio(content, filename=filename)
def build_manual_redo_prompt(history: Any) -> str:
"""构造整理记录 AI 重新整理提示词(builder 由 agent 层注册)。"""
_ensure_registered()
if _manual_redo_prompt_builder is None:
builder = _resolve(
_manual_redo_prompt_builder_provider,
"manual_redo_prompt_builder",
)
if builder is None:
raise RuntimeError("整理记录重新整理提示词构建器未注册")
return _manual_redo_prompt_builder(history)
return builder(history)