引入了一个新的插件组件类型 `BasePrompt`,允许插件动态地向核心Prompt模板中注入额外的上下文信息。该系统旨在提高Prompt的可扩展性和可定制性,使得开发者可以在不修改核心代码的情况下,通过插件来丰富和调整模型的行为。 主要变更包括: - **`BasePrompt` 基类**: 定义了Prompt组件的标准接口,包括 `execute` 方法用于生成注入内容,以及 `injection_point` 属性用于指定目标Prompt。 - **`PromptComponentManager`**: 一个新的管理器,负责注册、分类和执行所有 `BasePrompt` 组件。它会在构建核心Prompt时,自动查找并执行相关组件,将其输出拼接到主Prompt内容之前。 - **核心Prompt逻辑更新**: `src.chat.utils.prompt.Prompt` 类现在会调用 `PromptComponentManager` 来获取并注入组件内容。 - **插件系统集成**: `ComponentRegistry` 和 `PluginManager` 已更新,以支持 `BasePrompt` 组件的注册、管理和统计。 - **示例插件更新**: `hello_world_plugin` 中增加了一个 `WeatherPrompt` 示例,演示了如何创建和注册一个新的Prompt组件。 - **代码重构**: 将 `PromptParameters` 类从 `prompt.py` 移动到独立的 `prompt_params.py` 文件中,以改善模块化和解决循环依赖问题。
162 lines
5.7 KiB
Python
162 lines
5.7 KiB
Python
from abc import abstractmethod
|
||
|
||
from src.common.logger import get_logger
|
||
from src.plugin_system.base.component_types import (
|
||
ActionInfo,
|
||
CommandInfo,
|
||
ComponentType,
|
||
EventHandlerInfo,
|
||
InterestCalculatorInfo,
|
||
PlusCommandInfo,
|
||
PromptInfo,
|
||
ToolInfo,
|
||
)
|
||
|
||
from .base_action import BaseAction
|
||
from .base_command import BaseCommand
|
||
from .base_events_handler import BaseEventHandler
|
||
from .base_interest_calculator import BaseInterestCalculator
|
||
from .base_prompt import BasePrompt
|
||
from .base_tool import BaseTool
|
||
from .plugin_base import PluginBase
|
||
from .plus_command import PlusCommand
|
||
|
||
logger = get_logger("base_plugin")
|
||
|
||
|
||
class BasePlugin(PluginBase):
|
||
"""基于Action和Command的插件基类
|
||
|
||
所有上述类型的插件都应该继承这个基类,一个插件可以包含多种组件:
|
||
- Action组件:处理聊天中的动作
|
||
- Command组件:处理命令请求
|
||
- 未来可扩展:Scheduler、Listener等
|
||
"""
|
||
|
||
@classmethod
|
||
def _get_component_info_from_class(cls, component_class: type, component_type: ComponentType):
|
||
"""从组件类自动生成组件信息
|
||
|
||
Args:
|
||
component_class: 组件类
|
||
component_type: 组件类型
|
||
|
||
Returns:
|
||
对应类型的ComponentInfo对象
|
||
"""
|
||
if component_type == ComponentType.COMMAND:
|
||
if hasattr(component_class, "get_command_info"):
|
||
return component_class.get_command_info()
|
||
else:
|
||
logger.warning(f"Command类 {component_class.__name__} 缺少 get_command_info 方法")
|
||
return None
|
||
|
||
elif component_type == ComponentType.ACTION:
|
||
if hasattr(component_class, "get_action_info"):
|
||
return component_class.get_action_info()
|
||
else:
|
||
logger.warning(f"Action类 {component_class.__name__} 缺少 get_action_info 方法")
|
||
return None
|
||
|
||
elif component_type == ComponentType.INTEREST_CALCULATOR:
|
||
if hasattr(component_class, "get_interest_calculator_info"):
|
||
return component_class.get_interest_calculator_info()
|
||
else:
|
||
logger.warning(
|
||
f"InterestCalculator类 {component_class.__name__} 缺少 get_interest_calculator_info 方法"
|
||
)
|
||
return None
|
||
|
||
elif component_type == ComponentType.PLUS_COMMAND:
|
||
# PlusCommand的get_info逻辑可以在这里实现
|
||
logger.warning("PlusCommand的get_info逻辑尚未实现")
|
||
return None
|
||
|
||
elif component_type == ComponentType.TOOL:
|
||
# Tool的get_info逻辑可以在这里实现
|
||
logger.warning("Tool的get_info逻辑尚未实现")
|
||
return None
|
||
|
||
elif component_type == ComponentType.EVENT_HANDLER:
|
||
# EventHandler的get_info逻辑可以在这里实现
|
||
logger.warning("EventHandler的get_info逻辑尚未实现")
|
||
return None
|
||
|
||
elif component_type == ComponentType.PROMPT:
|
||
if hasattr(component_class, "get_prompt_info"):
|
||
return component_class.get_prompt_info()
|
||
else:
|
||
logger.warning(f"Prompt类 {component_class.__name__} 缺少 get_prompt_info 方法")
|
||
return None
|
||
|
||
else:
|
||
logger.error(f"不支持的组件类型: {component_type}")
|
||
return None
|
||
|
||
@classmethod
|
||
def get_component_info(cls, component_class: type, component_type: ComponentType):
|
||
"""获取组件信息的通用方法
|
||
|
||
这是一个便捷方法,内部调用_get_component_info_from_class
|
||
|
||
Args:
|
||
component_class: 组件类
|
||
component_type: 组件类型
|
||
|
||
Returns:
|
||
对应类型的ComponentInfo对象
|
||
"""
|
||
return cls._get_component_info_from_class(component_class, component_type)
|
||
|
||
@abstractmethod
|
||
def get_plugin_components(
|
||
self,
|
||
) -> list[
|
||
tuple[ActionInfo, type[BaseAction]]
|
||
| tuple[CommandInfo, type[BaseCommand]]
|
||
| tuple[PlusCommandInfo, type[PlusCommand]]
|
||
| tuple[EventHandlerInfo, type[BaseEventHandler]]
|
||
| tuple[ToolInfo, type[BaseTool]]
|
||
| tuple[InterestCalculatorInfo, type[BaseInterestCalculator]]
|
||
| tuple[PromptInfo, type[BasePrompt]]
|
||
]:
|
||
"""获取插件包含的组件列表
|
||
|
||
子类必须实现此方法,返回组件信息和组件类的列表
|
||
|
||
Returns:
|
||
List[tuple[ComponentInfo, Type]]: [(组件信息, 组件类), ...]
|
||
"""
|
||
...
|
||
|
||
def register_plugin(self) -> bool:
|
||
"""注册插件及其所有组件"""
|
||
from src.plugin_system.core.component_registry import component_registry
|
||
|
||
components = self.get_plugin_components()
|
||
|
||
# 检查依赖
|
||
if not self._check_dependencies():
|
||
logger.error(f"{self.log_prefix} 依赖检查失败,跳过注册")
|
||
return False
|
||
|
||
# 注册所有组件
|
||
registered_components = []
|
||
for component_info, component_class in components:
|
||
component_info.plugin_name = self.plugin_name
|
||
if component_registry.register_component(component_info, component_class):
|
||
registered_components.append(component_info)
|
||
else:
|
||
logger.warning(f"{self.log_prefix} 组件 {component_info.name} 注册失败")
|
||
|
||
# 更新插件信息中的组件列表
|
||
self.plugin_info.components = registered_components
|
||
|
||
# 注册插件
|
||
if component_registry.register_plugin(self.plugin_info):
|
||
logger.debug(f"{self.log_prefix} 插件注册成功,包含 {len(registered_components)} 个组件")
|
||
return True
|
||
else:
|
||
logger.error(f"{self.log_prefix} 插件注册失败")
|
||
return False
|