mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-15 17:30:13 +08:00
重命名
This commit is contained in:
@@ -81,7 +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,
|
||||
"extra_user_content_parts": self.req.extra_user_content_parts,
|
||||
}
|
||||
|
||||
if self.streaming:
|
||||
|
||||
@@ -14,6 +14,7 @@ import astrbot.core.message.components as Comp
|
||||
from astrbot import logger
|
||||
from astrbot.core.agent.message import (
|
||||
AssistantMessageSegment,
|
||||
ContentPart,
|
||||
ToolCall,
|
||||
ToolCallMessageSegment,
|
||||
)
|
||||
@@ -92,8 +93,10 @@ class ProviderRequest:
|
||||
"""会话 ID"""
|
||||
image_urls: list[str] = field(default_factory=list)
|
||||
"""图片 URL 列表"""
|
||||
extra_content_blocks: list[dict] = field(default_factory=list)
|
||||
"""额外的内容块列表,用于在用户消息后添加额外的文本块(如系统提醒、指令等)"""
|
||||
extra_user_content_parts: list[dict] | list[ContentPart] = field(
|
||||
default_factory=list
|
||||
)
|
||||
"""额外的用户消息内容部分列表,用于在用户消息后添加额外的内容块(如系统提醒、指令等)。支持 dict 或 ContentPart 对象"""
|
||||
func_tool: ToolSet | None = None
|
||||
"""可用的函数工具"""
|
||||
contexts: list[dict] = field(default_factory=list)
|
||||
@@ -179,7 +182,14 @@ class ProviderRequest:
|
||||
content_blocks.append({"type": "text", "text": "[图片]"})
|
||||
|
||||
# 2. 额外的内容块(系统提醒、指令等)
|
||||
content_blocks.extend(self.extra_content_blocks)
|
||||
if self.extra_user_content_parts:
|
||||
for part in self.extra_user_content_parts:
|
||||
if hasattr(part, "model_dump"):
|
||||
# ContentPart 对象,需要 model_dump
|
||||
content_blocks.append(part.model_dump())
|
||||
else:
|
||||
# 已经是 dict
|
||||
content_blocks.append(part)
|
||||
|
||||
# 3. 图片内容
|
||||
if self.image_urls:
|
||||
@@ -203,7 +213,7 @@ class ProviderRequest:
|
||||
if (
|
||||
len(content_blocks) == 1
|
||||
and content_blocks[0]["type"] == "text"
|
||||
and not self.extra_content_blocks
|
||||
and not self.extra_user_content_parts
|
||||
and not self.image_urls
|
||||
):
|
||||
return {"role": "user", "content": content_blocks[0]["text"]}
|
||||
|
||||
@@ -103,7 +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,
|
||||
extra_user_content_parts: list[dict] | None = None,
|
||||
**kwargs,
|
||||
) -> LLMResponse:
|
||||
"""获得 LLM 的文本对话结果。会使用当前的模型进行对话。
|
||||
@@ -115,7 +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: 额外的内容块列表,用于在用户消息后添加额外的文本块(如系统提醒、指令等)
|
||||
extra_user_content_parts: 额外的内容块列表,用于在用户消息后添加额外的文本块(如系统提醒、指令等)
|
||||
kwargs: 其他参数
|
||||
|
||||
Notes:
|
||||
|
||||
@@ -296,7 +296,7 @@ class ProviderAnthropic(Provider):
|
||||
system_prompt=None,
|
||||
tool_calls_result=None,
|
||||
model=None,
|
||||
extra_content_blocks=None,
|
||||
extra_user_content_parts=None,
|
||||
**kwargs,
|
||||
) -> LLMResponse:
|
||||
if contexts is None:
|
||||
@@ -304,7 +304,7 @@ class ProviderAnthropic(Provider):
|
||||
new_record = None
|
||||
if prompt is not None:
|
||||
new_record = await self.assemble_context(
|
||||
prompt, image_urls, extra_content_blocks
|
||||
prompt, image_urls, extra_user_content_parts
|
||||
)
|
||||
context_query = self._ensure_message_to_dicts(contexts)
|
||||
if new_record:
|
||||
@@ -353,7 +353,7 @@ class ProviderAnthropic(Provider):
|
||||
system_prompt=None,
|
||||
tool_calls_result=None,
|
||||
model=None,
|
||||
extra_content_blocks=None,
|
||||
extra_user_content_parts=None,
|
||||
**kwargs,
|
||||
):
|
||||
if contexts is None:
|
||||
@@ -361,7 +361,7 @@ class ProviderAnthropic(Provider):
|
||||
new_record = None
|
||||
if prompt is not None:
|
||||
new_record = await self.assemble_context(
|
||||
prompt, image_urls, extra_content_blocks
|
||||
prompt, image_urls, extra_user_content_parts
|
||||
)
|
||||
context_query = self._ensure_message_to_dicts(contexts)
|
||||
if new_record:
|
||||
@@ -398,7 +398,7 @@ class ProviderAnthropic(Provider):
|
||||
self,
|
||||
text: str,
|
||||
image_urls: list[str] | None = None,
|
||||
extra_content_blocks: list[dict] | None = None,
|
||||
extra_user_content_parts: list[dict] | None = None,
|
||||
):
|
||||
"""组装上下文,支持文本和图片"""
|
||||
content = []
|
||||
@@ -409,15 +409,17 @@ class ProviderAnthropic(Provider):
|
||||
elif image_urls:
|
||||
# 如果没有文本但有图片,添加占位文本
|
||||
content.append({"type": "text", "text": "[图片]"})
|
||||
elif extra_content_blocks:
|
||||
elif extra_user_content_parts:
|
||||
# 如果只有额外内容块,也需要添加占位文本
|
||||
content.append({"type": "text", "text": " "})
|
||||
|
||||
# 2. 额外的内容块(系统提醒、指令等)
|
||||
if extra_content_blocks:
|
||||
if extra_user_content_parts:
|
||||
# 过滤出文本块,因为 Anthropic 主要支持文本和图片
|
||||
text_blocks = [
|
||||
block for block in extra_content_blocks if block.get("type") == "text"
|
||||
block
|
||||
for block in extra_user_content_parts
|
||||
if block.get("type") == "text"
|
||||
]
|
||||
content.extend(text_blocks)
|
||||
|
||||
@@ -460,7 +462,7 @@ class ProviderAnthropic(Provider):
|
||||
# 如果只有主文本且没有额外内容块和图片,返回简单格式以保持向后兼容
|
||||
if (
|
||||
text
|
||||
and not extra_content_blocks
|
||||
and not extra_user_content_parts
|
||||
and not image_urls
|
||||
and len(content) == 1
|
||||
and content[0]["type"] == "text"
|
||||
|
||||
@@ -680,7 +680,7 @@ class ProviderGoogleGenAI(Provider):
|
||||
system_prompt=None,
|
||||
tool_calls_result=None,
|
||||
model=None,
|
||||
extra_content_blocks=None,
|
||||
extra_user_content_parts=None,
|
||||
**kwargs,
|
||||
) -> LLMResponse:
|
||||
if contexts is None:
|
||||
@@ -688,7 +688,7 @@ class ProviderGoogleGenAI(Provider):
|
||||
new_record = None
|
||||
if prompt is not None:
|
||||
new_record = await self.assemble_context(
|
||||
prompt, image_urls, extra_content_blocks
|
||||
prompt, image_urls, extra_user_content_parts
|
||||
)
|
||||
context_query = self._ensure_message_to_dicts(contexts)
|
||||
if new_record:
|
||||
@@ -735,7 +735,7 @@ class ProviderGoogleGenAI(Provider):
|
||||
system_prompt=None,
|
||||
tool_calls_result=None,
|
||||
model=None,
|
||||
extra_content_blocks=None,
|
||||
extra_user_content_parts=None,
|
||||
**kwargs,
|
||||
) -> AsyncGenerator[LLMResponse, None]:
|
||||
if contexts is None:
|
||||
@@ -743,7 +743,7 @@ class ProviderGoogleGenAI(Provider):
|
||||
new_record = None
|
||||
if prompt is not None:
|
||||
new_record = await self.assemble_context(
|
||||
prompt, image_urls, extra_content_blocks
|
||||
prompt, image_urls, extra_user_content_parts
|
||||
)
|
||||
context_query = self._ensure_message_to_dicts(contexts)
|
||||
if new_record:
|
||||
@@ -807,7 +807,7 @@ class ProviderGoogleGenAI(Provider):
|
||||
self,
|
||||
text: str,
|
||||
image_urls: list[str] | None = None,
|
||||
extra_content_blocks: list[dict] | None = None,
|
||||
extra_user_content_parts: list[dict] | None = None,
|
||||
):
|
||||
"""组装上下文。"""
|
||||
# 构建内容块列表
|
||||
@@ -819,13 +819,13 @@ class ProviderGoogleGenAI(Provider):
|
||||
elif image_urls:
|
||||
# 如果没有文本但有图片,添加占位文本
|
||||
content_blocks.append({"type": "text", "text": "[图片]"})
|
||||
elif extra_content_blocks:
|
||||
elif extra_user_content_parts:
|
||||
# 如果只有额外内容块,也需要添加占位文本
|
||||
content_blocks.append({"type": "text", "text": " "})
|
||||
|
||||
# 2. 额外的内容块(系统提醒、指令等)
|
||||
if extra_content_blocks:
|
||||
content_blocks.extend(extra_content_blocks)
|
||||
if extra_user_content_parts:
|
||||
content_blocks.extend(extra_user_content_parts)
|
||||
|
||||
# 3. 图片内容
|
||||
if image_urls:
|
||||
@@ -851,7 +851,7 @@ class ProviderGoogleGenAI(Provider):
|
||||
# 如果只有主文本且没有额外内容块和图片,返回简单格式以保持向后兼容
|
||||
if (
|
||||
text
|
||||
and not extra_content_blocks
|
||||
and not extra_user_content_parts
|
||||
and not image_urls
|
||||
and len(content_blocks) == 1
|
||||
and content_blocks[0]["type"] == "text"
|
||||
|
||||
@@ -348,7 +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,
|
||||
extra_user_content_parts: list[dict] | None = None,
|
||||
**kwargs,
|
||||
) -> tuple:
|
||||
"""准备聊天所需的有效载荷和上下文"""
|
||||
@@ -357,7 +357,7 @@ class ProviderOpenAIOfficial(Provider):
|
||||
new_record = None
|
||||
if prompt is not None:
|
||||
new_record = await self.assemble_context(
|
||||
prompt, image_urls, extra_content_blocks
|
||||
prompt, image_urls, extra_user_content_parts
|
||||
)
|
||||
context_query = self._ensure_message_to_dicts(contexts)
|
||||
if new_record:
|
||||
@@ -479,7 +479,7 @@ class ProviderOpenAIOfficial(Provider):
|
||||
system_prompt=None,
|
||||
tool_calls_result=None,
|
||||
model=None,
|
||||
extra_content_blocks=None,
|
||||
extra_user_content_parts=None,
|
||||
**kwargs,
|
||||
) -> LLMResponse:
|
||||
payloads, context_query = await self._prepare_chat_payload(
|
||||
@@ -489,7 +489,7 @@ class ProviderOpenAIOfficial(Provider):
|
||||
system_prompt,
|
||||
tool_calls_result,
|
||||
model=model,
|
||||
extra_content_blocks=extra_content_blocks,
|
||||
extra_user_content_parts=extra_user_content_parts,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
@@ -629,7 +629,7 @@ class ProviderOpenAIOfficial(Provider):
|
||||
self,
|
||||
text: str,
|
||||
image_urls: list[str] | None = None,
|
||||
extra_content_blocks: list[dict] | None = None,
|
||||
extra_user_content_parts: list[dict] | None = None,
|
||||
) -> dict:
|
||||
"""组装成符合 OpenAI 格式的 role 为 user 的消息段"""
|
||||
# 构建内容块列表
|
||||
@@ -641,13 +641,13 @@ class ProviderOpenAIOfficial(Provider):
|
||||
elif image_urls:
|
||||
# 如果没有文本但有图片,添加占位文本
|
||||
content_blocks.append({"type": "text", "text": "[图片]"})
|
||||
elif extra_content_blocks:
|
||||
elif extra_user_content_parts:
|
||||
# 如果只有额外内容块,也需要添加占位文本
|
||||
content_blocks.append({"type": "text", "text": " "})
|
||||
|
||||
# 2. 额外的内容块(系统提醒、指令等)
|
||||
if extra_content_blocks:
|
||||
content_blocks.extend(extra_content_blocks)
|
||||
if extra_user_content_parts:
|
||||
content_blocks.extend(extra_user_content_parts)
|
||||
|
||||
# 3. 图片内容
|
||||
if image_urls:
|
||||
@@ -673,7 +673,7 @@ class ProviderOpenAIOfficial(Provider):
|
||||
# 如果只有主文本且没有额外内容块和图片,返回简单格式以保持向后兼容
|
||||
if (
|
||||
text
|
||||
and not extra_content_blocks
|
||||
and not extra_user_content_parts
|
||||
and not image_urls
|
||||
and len(content_blocks) == 1
|
||||
and content_blocks[0]["type"] == "text"
|
||||
|
||||
@@ -7,6 +7,7 @@ from astrbot.api import logger, sp, star
|
||||
from astrbot.api.event import AstrMessageEvent
|
||||
from astrbot.api.message_components import Image, Reply
|
||||
from astrbot.api.provider import Provider, ProviderRequest
|
||||
from astrbot.core.agent.message import TextPart
|
||||
from astrbot.core.provider.func_tool_manager import ToolSet
|
||||
|
||||
|
||||
@@ -85,11 +86,8 @@ class ProcessLLMRequest:
|
||||
req.image_urls,
|
||||
)
|
||||
if caption:
|
||||
req.extra_content_blocks.append(
|
||||
{
|
||||
"type": "text",
|
||||
"text": f"<image_caption>{caption}</image_caption>",
|
||||
}
|
||||
req.extra_user_content_parts.append(
|
||||
TextPart(text=f"<image_caption>{caption}</image_caption>")
|
||||
)
|
||||
req.image_urls = []
|
||||
except Exception as e:
|
||||
@@ -231,17 +229,17 @@ class ProcessLLMRequest:
|
||||
except BaseException as e:
|
||||
logger.error(f"处理引用图片失败: {e}")
|
||||
|
||||
# 3. 将所有部分组合成文本并添加到 extra_content_blocks 中
|
||||
# 3. 将所有部分组合成文本并添加到 extra_user_content_parts 中
|
||||
# 确保引用内容被正确的标签包裹
|
||||
quoted_content = "\n".join(content_parts)
|
||||
# 确保所有内容都在<Quoted Message>标签内
|
||||
quoted_text = f"<Quoted Message>\n{quoted_content}\n</Quoted Message>"
|
||||
|
||||
req.extra_content_blocks.append({"type": "text", "text": quoted_text})
|
||||
req.extra_user_content_parts.append(TextPart(text=quoted_text))
|
||||
|
||||
# 统一包裹所有系统提醒
|
||||
if system_parts:
|
||||
system_content = (
|
||||
"<system_reminder>" + "\n".join(system_parts) + "</system_reminder>"
|
||||
)
|
||||
req.extra_content_blocks.append({"type": "text", "text": system_content})
|
||||
req.extra_user_content_parts.append(TextPart(text=system_content))
|
||||
|
||||
Reference in New Issue
Block a user