refactor(prompt): 优化Prompt组件注入逻辑并简化代码

将Prompt组件的注入逻辑从`Prompt.format`方法前置到`PromptManager.get_prompt_async`和`create_prompt_async`中。这使得注入时机更早,逻辑更清晰,并允许在获取Prompt时就能动态传入参数以影响注入内容。

主要变更:
- `PromptManager`: `get_prompt_async`现在负责处理组件注入,并接收可选的`parameters`参数。`format_prompt`相应地传递参数。
- `create_prompt_async`: 现在也支持在创建时进行动态注入。
- `Prompt.format`: 移除了原有的组件注入逻辑,简化了方法实现。
- `PromptComponentManager`: 重构为直接从全局`component_registry`获取组件,移除了自身的注册和存储逻辑,减少了状态管理的复杂性。
- `plan_filter.py`: 删除了大量冗余和重复的代码块,包括主动聊天模式的独立逻辑和旧的历史消息构建方式。
This commit is contained in:
minecraft1024a
2025-10-19 13:32:49 +08:00
parent 50a6c2de58
commit 73383f8246
3 changed files with 104 additions and 141 deletions

View File

@@ -1,11 +1,11 @@
import asyncio
from collections import defaultdict
from typing import Type
from src.chat.utils.prompt_params import PromptParameters
from src.common.logger import get_logger
from src.plugin_system.base.base_prompt import BasePrompt
from src.plugin_system.base.component_types import PromptInfo
from src.plugin_system.base.component_types import ComponentType, PromptInfo
from src.plugin_system.core.component_registry import component_registry
logger = get_logger("prompt_component_manager")
@@ -15,48 +15,11 @@ class PromptComponentManager:
管理所有 `BasePrompt` 组件的单例类。
该管理器负责:
1. 注册由插件定义的 `BasePrompt` 子类。
2. 根据注入点目标Prompt名称对它们进行分类存储
1. 从 `component_registry` 中查询 `BasePrompt` 子类。
2. 根据注入点目标Prompt名称对它们进行筛选
3. 提供一个接口以便在构建核心Prompt时能够获取并执行所有相关的组件。
"""
def __init__(self):
self._registry: dict[str, list[Type[BasePrompt]]] = defaultdict(list)
self._prompt_infos: dict[str, PromptInfo] = {}
def register(self, component_class: Type[BasePrompt]):
"""
注册一个 `BasePrompt` 组件类。
Args:
component_class: 要注册的 `BasePrompt` 子类。
"""
if not issubclass(component_class, BasePrompt):
logger.warning(f"尝试注册一个非 BasePrompt 的类: {component_class.__name__}")
return
try:
prompt_info = component_class.get_prompt_info()
if prompt_info.name in self._prompt_infos:
logger.warning(f"重复注册 Prompt 组件: {prompt_info.name}。将覆盖旧组件。")
injection_points = prompt_info.injection_point
if isinstance(injection_points, str):
injection_points = [injection_points]
if not injection_points or not all(injection_points):
logger.debug(f"Prompt 组件 '{prompt_info.name}' 未指定有效的 injection_point将不会被自动注入。")
return
for point in injection_points:
self._registry[point].append(component_class)
self._prompt_infos[prompt_info.name] = prompt_info
logger.info(f"成功注册 Prompt 组件 '{prompt_info.name}' 到注入点: {injection_points}")
except ValueError as e:
logger.error(f"注册 Prompt 组件失败 {component_class.__name__}: {e}")
def get_components_for(self, injection_point: str) -> list[Type[BasePrompt]]:
"""
获取指定注入点的所有已注册组件类。
@@ -67,7 +30,29 @@ class PromptComponentManager:
Returns:
list[Type[BasePrompt]]: 与该注入点关联的组件类列表。
"""
return self._registry.get(injection_point, [])
# 从组件注册中心获取所有启用的Prompt组件
enabled_prompts = component_registry.get_enabled_components_by_type(ComponentType.PROMPT)
matching_components: list[Type[BasePrompt]] = []
for prompt_name, prompt_info in enabled_prompts.items():
# 确保 prompt_info 是 PromptInfo 类型
if not isinstance(prompt_info, PromptInfo):
continue
# 获取注入点信息
injection_points = prompt_info.injection_point
if isinstance(injection_points, str):
injection_points = [injection_points]
# 检查当前注入点是否匹配
if injection_point in injection_points:
# 获取组件类
component_class = component_registry.get_component_class(prompt_name, ComponentType.PROMPT)
if component_class and issubclass(component_class, BasePrompt):
matching_components.append(component_class)
return matching_components
async def execute_components_for(self, injection_point: str, params: PromptParameters) -> str:
"""
@@ -85,12 +70,13 @@ class PromptComponentManager:
return ""
tasks = []
from src.plugin_system.core.component_registry import component_registry
for component_class in component_classes:
try:
prompt_info = self._prompt_infos.get(component_class.prompt_name)
if not prompt_info:
# 从注册中心获取组件信息
prompt_info = component_registry.get_component_info(
component_class.prompt_name, ComponentType.PROMPT
)
if not isinstance(prompt_info, PromptInfo):
logger.warning(f"找不到 Prompt 组件 '{component_class.prompt_name}' 的信息,无法获取插件配置")
plugin_config = {}
else: