diff --git a/astrbot/core/agent/runners/tool_loop_agent_runner.py b/astrbot/core/agent/runners/tool_loop_agent_runner.py index 7eb90f3fc..1e04001e4 100644 --- a/astrbot/core/agent/runners/tool_loop_agent_runner.py +++ b/astrbot/core/agent/runners/tool_loop_agent_runner.py @@ -81,6 +81,7 @@ class ToolLoopAgentRunner(BaseAgentRunner[TContext]): "func_tool": self.req.func_tool, "model": self.req.model, # NOTE: in fact, this arg is None in most cases "session_id": self.req.session_id, + "extra_content_blocks": self.req.extra_content_blocks, } if self.streaming: diff --git a/astrbot/core/provider/provider.py b/astrbot/core/provider/provider.py index 7f21a2ee1..b81e24da6 100644 --- a/astrbot/core/provider/provider.py +++ b/astrbot/core/provider/provider.py @@ -103,6 +103,7 @@ class Provider(AbstractProvider): system_prompt: str | None = None, tool_calls_result: ToolCallsResult | list[ToolCallsResult] | None = None, model: str | None = None, + extra_content_blocks: list[dict] | None = None, **kwargs, ) -> LLMResponse: """获得 LLM 的文本对话结果。会使用当前的模型进行对话。 @@ -114,6 +115,7 @@ class Provider(AbstractProvider): tools: tool set contexts: 上下文,和 prompt 二选一使用 tool_calls_result: 回传给 LLM 的工具调用结果。参考: https://platform.openai.com/docs/guides/function-calling + extra_content_blocks: 额外的内容块列表,用于在用户消息后添加额外的文本块(如系统提醒、指令等) kwargs: 其他参数 Notes: diff --git a/astrbot/core/provider/sources/anthropic_source.py b/astrbot/core/provider/sources/anthropic_source.py index a55a3a0a1..788047375 100644 --- a/astrbot/core/provider/sources/anthropic_source.py +++ b/astrbot/core/provider/sources/anthropic_source.py @@ -296,13 +296,16 @@ class ProviderAnthropic(Provider): system_prompt=None, tool_calls_result=None, model=None, + extra_content_blocks=None, **kwargs, ) -> LLMResponse: if contexts is None: contexts = [] new_record = None if prompt is not None: - new_record = await self.assemble_context(prompt, image_urls) + new_record = await self.assemble_context( + prompt, image_urls, extra_content_blocks + ) context_query = self._ensure_message_to_dicts(contexts) if new_record: context_query.append(new_record) @@ -350,13 +353,16 @@ class ProviderAnthropic(Provider): system_prompt=None, tool_calls_result=None, model=None, + extra_content_blocks=None, **kwargs, ): if contexts is None: contexts = [] new_record = None if prompt is not None: - new_record = await self.assemble_context(prompt, image_urls) + new_record = await self.assemble_context( + prompt, image_urls, extra_content_blocks + ) context_query = self._ensure_message_to_dicts(contexts) if new_record: context_query.append(new_record) @@ -403,6 +409,9 @@ class ProviderAnthropic(Provider): elif image_urls: # 如果没有文本但有图片,添加占位文本 content.append({"type": "text", "text": "[图片]"}) + elif extra_content_blocks: + # 如果只有额外内容块,也需要添加占位文本 + content.append({"type": "text", "text": " "}) # 2. 额外的内容块(系统提醒、指令等) if extra_content_blocks: diff --git a/astrbot/core/provider/sources/gemini_source.py b/astrbot/core/provider/sources/gemini_source.py index 614c83aad..918bb1f87 100644 --- a/astrbot/core/provider/sources/gemini_source.py +++ b/astrbot/core/provider/sources/gemini_source.py @@ -680,13 +680,16 @@ class ProviderGoogleGenAI(Provider): system_prompt=None, tool_calls_result=None, model=None, + extra_content_blocks=None, **kwargs, ) -> LLMResponse: if contexts is None: contexts = [] new_record = None if prompt is not None: - new_record = await self.assemble_context(prompt, image_urls) + new_record = await self.assemble_context( + prompt, image_urls, extra_content_blocks + ) context_query = self._ensure_message_to_dicts(contexts) if new_record: context_query.append(new_record) @@ -732,13 +735,16 @@ class ProviderGoogleGenAI(Provider): system_prompt=None, tool_calls_result=None, model=None, + extra_content_blocks=None, **kwargs, ) -> AsyncGenerator[LLMResponse, None]: if contexts is None: contexts = [] new_record = None if prompt is not None: - new_record = await self.assemble_context(prompt, image_urls) + new_record = await self.assemble_context( + prompt, image_urls, extra_content_blocks + ) context_query = self._ensure_message_to_dicts(contexts) if new_record: context_query.append(new_record) @@ -813,6 +819,9 @@ class ProviderGoogleGenAI(Provider): elif image_urls: # 如果没有文本但有图片,添加占位文本 content_blocks.append({"type": "text", "text": "[图片]"}) + elif extra_content_blocks: + # 如果只有额外内容块,也需要添加占位文本 + content_blocks.append({"type": "text", "text": " "}) # 2. 额外的内容块(系统提醒、指令等) if extra_content_blocks: diff --git a/astrbot/core/provider/sources/openai_source.py b/astrbot/core/provider/sources/openai_source.py index fcd2e0e32..8a9346cef 100644 --- a/astrbot/core/provider/sources/openai_source.py +++ b/astrbot/core/provider/sources/openai_source.py @@ -348,6 +348,7 @@ class ProviderOpenAIOfficial(Provider): system_prompt: str | None = None, tool_calls_result: ToolCallsResult | list[ToolCallsResult] | None = None, model: str | None = None, + extra_content_blocks: list[dict] | None = None, **kwargs, ) -> tuple: """准备聊天所需的有效载荷和上下文""" @@ -355,7 +356,9 @@ class ProviderOpenAIOfficial(Provider): contexts = [] new_record = None if prompt is not None: - new_record = await self.assemble_context(prompt, image_urls) + new_record = await self.assemble_context( + prompt, image_urls, extra_content_blocks + ) context_query = self._ensure_message_to_dicts(contexts) if new_record: context_query.append(new_record) @@ -476,6 +479,7 @@ class ProviderOpenAIOfficial(Provider): system_prompt=None, tool_calls_result=None, model=None, + extra_content_blocks=None, **kwargs, ) -> LLMResponse: payloads, context_query = await self._prepare_chat_payload( @@ -485,6 +489,7 @@ class ProviderOpenAIOfficial(Provider): system_prompt, tool_calls_result, model=model, + extra_content_blocks=extra_content_blocks, **kwargs, ) @@ -636,6 +641,9 @@ class ProviderOpenAIOfficial(Provider): elif image_urls: # 如果没有文本但有图片,添加占位文本 content_blocks.append({"type": "text", "text": "[图片]"}) + elif extra_content_blocks: + # 如果只有额外内容块,也需要添加占位文本 + content_blocks.append({"type": "text", "text": " "}) # 2. 额外的内容块(系统提醒、指令等) if extra_content_blocks: