feat(prompt): 为提示词组件提供注入目标上下文

为了让单个提示词组件在注入到不同目标时能够有不同的行为,现在向组件的执行上下文中传递当前注入的目标提示词名称 (`target_prompt_name`)。

这使得组件可以根据注入点动态调整其生成的内容。例如,一个工具列表组件在注入到 planner prompt 和 reflection prompt 时可以提供不同详尽程度的列表。

主要变更:
- `BasePrompt` 初始化时接收 `target_prompt_name`。
- `PromptComponentManager` 在应用注入规则时会传递此参数。
- `add_injection_rule` 方法现在支持批量添加规则,以简化注册流程。

BREAKING CHANGE: `PromptComponentManager.add_injection_rule` 中 `content_provider` 的函数签名已更改,现在需要接受第二个参数 `target_prompt_name: str`。

旧签名: `async def provider(params: PromptParameters) -> str`
新签名: `async def provider(params: PromptParameters, target_prompt_name: str) -> str
This commit is contained in:
minecraft1024a
2025-11-13 18:18:15 +08:00
committed by Windpicker-owo
parent a72bf27ad6
commit c3e4091bc2
3 changed files with 23 additions and 16 deletions

View File

@@ -194,6 +194,7 @@ class WeatherPrompt(BasePrompt):
async def execute(self) -> str:
# 在实际应用中这里可以调用天气API
# 为了演示,我们返回一个固定的天气信息
logger.info(self.target_prompt_name)
return "当前天气晴朗温度25°C。"
@@ -202,7 +203,7 @@ class HelloWorldPlugin(BasePlugin):
"""一个包含四大核心组件和高级配置功能的入门示例插件。"""
plugin_name = "hello_world_plugin"
enable_plugin = False
enable_plugin = True
dependencies: ClassVar = []
python_dependencies: ClassVar = []
config_file_name = "config.toml"

View File

@@ -2,6 +2,7 @@ import asyncio
import copy
import re
from collections.abc import Awaitable, Callable
from typing import List
from src.chat.utils.prompt_params import PromptParameters
from src.common.logger import get_logger
@@ -68,7 +69,9 @@ class PromptComponentManager:
logger.warning(f"无法为 '{prompt_name}' 加载静态规则,因为它不是一个有效的 Prompt 组件。")
continue
def create_provider(cls: type[BasePrompt]) -> Callable[[PromptParameters], Awaitable[str]]:
def create_provider(
cls: type[BasePrompt],
) -> Callable[[PromptParameters, str], Awaitable[str]]:
"""
为静态组件创建一个内容提供者闭包 (Content Provider Closure)。
@@ -80,10 +83,10 @@ class PromptComponentManager:
cls (type[BasePrompt]): 需要为其创建提供者的 Prompt 组件类。
Returns:
Callable[[PromptParameters], Awaitable[str]]: 一个符合管理器标准的异步内容提供者。
Callable[[PromptParameters, str], Awaitable[str]]: 一个符合管理器标准的异步内容提供者。
"""
async def content_provider(params: PromptParameters) -> str:
async def content_provider(params: PromptParameters, target_prompt_name: str) -> str:
"""实际执行内容生成的异步函数。"""
try:
# 从注册表获取最新的组件信息,包括插件配置
@@ -92,8 +95,8 @@ class PromptComponentManager:
if isinstance(p_info, PromptInfo):
plugin_config = component_registry.get_plugin_config(p_info.plugin_name)
# 实例化组件并执行
instance = cls(params=params, plugin_config=plugin_config)
# 实例化组件并执行,传入 target_prompt_name
instance = cls(params=params, plugin_config=plugin_config, target_prompt_name=target_prompt_name)
result = await instance.execute()
return str(result) if result is not None else ""
except Exception as e:
@@ -116,28 +119,29 @@ class PromptComponentManager:
async def add_injection_rule(
self,
prompt_name: str,
rule: InjectionRule,
rules: List[InjectionRule],
content_provider: Callable[..., Awaitable[str]],
source: str = "runtime",
) -> bool:
"""
动态添加或更新一条注入规则。
动态添加或更新注入规则。
此方法允许在系统运行时,由外部逻辑(如插件、命令)向管理器中添加新的注入行为。
如果已存在同名组件针对同一目标的规则,此方法会覆盖旧规则。
Args:
prompt_name (str): 动态注入组件的唯一名称。
rule (InjectionRule): 描述注入行为的规则对象。
rules (List[InjectionRule]): 描述注入行为的规则对象列表
content_provider (Callable[..., Awaitable[str]]):
一个异步函数,用于在应用注入时动态生成内容。
函数签名应为: `async def provider(params: "PromptParameters") -> str`
函数签名应为: `async def provider(params: "PromptParameters", target_prompt_name: str) -> str`
source (str, optional): 规则的来源标识,默认为 "runtime"
Returns:
bool: 如果成功添加或更新,则返回 True。
"""
async with self._lock:
for rule in rules:
target_rules = self._dynamic_rules.setdefault(rule.target_prompt, {})
target_rules[prompt_name] = (rule, content_provider, source)
logger.info(f"成功添加/更新注入规则: '{prompt_name}' -> '{rule.target_prompt}' (来源: {source})")
@@ -207,7 +211,7 @@ class PromptComponentManager:
# 对于非 REMOVE 类型的注入,需要先获取内容
if rule.injection_type != InjectionType.REMOVE:
try:
content = await provider(params)
content = await provider(params, target_prompt_name)
except Exception as e:
logger.error(f"执行规则 '{rule}' (来源: {source}) 的内容提供者时失败: {e}", exc_info=True)
continue # 跳过失败的 provider不中断整个流程

View File

@@ -27,22 +27,24 @@ class BasePrompt(ABC):
# 定义此组件希望如何注入到核心Prompt中
# 这是一个 InjectionRule 对象的列表,可以实现复杂的注入逻辑
# 例如: [InjectionRule(target_prompt="planner_prompt", injection_type=InjectionType.APPEND, priority=50)]
injection_rules: ClassVar[list[InjectionRule] ] = []
injection_rules: ClassVar[list[InjectionRule]] = []
"""定义注入规则的列表"""
# 旧的注入点定义,用于向后兼容。如果定义了这个,它将被自动转换为 injection_rules。
injection_point: str | list[str] | None = None
"""[已废弃] 要注入的目标Prompt名称或列表请使用 injection_rules"""
def __init__(self, params: PromptParameters, plugin_config: dict | None = None):
def __init__(self, params: PromptParameters, plugin_config: dict | None = None, target_prompt_name: str | None = None):
"""初始化Prompt组件
Args:
params: 统一提示词参数,包含所有构建提示词所需的上下文信息。
plugin_config: 插件配置字典。
target_prompt_name: 在应用注入时,当前注入的目标提示词名称。
"""
self.params = params
self.plugin_config = plugin_config or {}
self.target_prompt_name = target_prompt_name
self.log_prefix = "[PromptComponent]"
logger.debug(f"{self.log_prefix} Prompt组件 '{self.prompt_name}' 初始化完成")