Skip to content

Conversation

@Soulter
Copy link
Member

@Soulter Soulter commented Nov 1, 2025

更好地描述 LLM Message 模型。

Inspired by elegant https://github.com/MoonshotAI/kosong

在这个 PR 中,

  1. 我们基于 Pydantic 并且参考 MoonshotAI/kosong 引入了新的表示 LLM Message 的数据模型。由于 kosong 需要 Python 版本 >= 3.13,因此我们无法直接以库的形式引入 kosong。

    from astrbot.core.agent.message import (
        AssistantMessageSegment,
        UserMessageSegment,
        TextPart,
    )
    from astrbot.core.agent.tool import ToolSet
    
    provider = self.context.get_using_provider(event.unified_msg_origin)
    conv_mgr = self.context.conversation_manager
    curr_cid = await conv_mgr.get_curr_conversation_id(event.unified_msg_origin)
    if provider and curr_cid:
        user_msg = UserMessageSegment(content=[TextPart(text="hi")])
        llm_resp = await provider.text_chat(
            contexts=[user_msg],
            func_tool=ToolSet(tools=[HelloWorldTool()]),
        )
        await conv_mgr.add_message_pair(
            cid=curr_cid,
            user_message=user_msg,
            assistant_message=AssistantMessageSegment(
                content=[TextPart(text=llm_resp.completion_text)]
            ),
        )
        print(llm_resp.completion_text)
  2. 重构了以类的方式注册的 Tool 的 Tool 运行方法。现在我们将重载 call 来添加 Tool 的运行方法。

    from mcp.types import CallToolResult
    from pydantic import Field
    from pydantic.dataclasses import dataclass
    
    from astrbot.api import FunctionTool
    from astrbot.core.agent.run_context import ContextWrapper
    from astrbot.core.astr_agent_context import AstrAgentContext
    
    
    @dataclass
    class HelloWorldTool(FunctionTool):
        name: str = "hello_world"  # 工具名称
        description: str = "Say hello to the world."  # 工具描述
        parameters: dict = Field(
            default_factory=lambda: {
                "type": "object",
                "properties": {
                    "greeting": {
                        "type": "string",
                        "description": "The greeting message.",
                    },
                },
                "required": ["greeting"],
            }
        )  # 工具参数定义,见 OpenAI 官网或 https://json-schema.org/understanding-json-schema/
    
        async def call(
            self, context: ContextWrapper[AstrAgentContext], **kwargs
        ) -> str | CallToolResult:
            # event 在 context.context.event 中可用
            greeting = kwargs.get("greeting", "Hello")
            return f"{greeting}, World!"  # 也支持 mcp.types.CallToolResult 类型

    相比原来的 run 方法,call 方法将 event 实参改为了 ContextWrapper[AstrAgentContext] 类型的 context 方法。优点是更加标准化、独立。并且,我们引入了 Pydantic 进行数据校验,现在将会自动对 parameters 进行数据校验以符合 https://json-schema.org/draft/2020-12 。同时,run 方法我们仍然做了兼容,不过从此开始我们推荐使用 call 方法。

  3. 修复了以类注册 Tool 后,重载插件的 Bug。

  4. [Bug]插件主动发送的AI消息无法进入对话历史,导致上下文断裂 #3216 为插件开发引入了更好用的添加 LLM 消息上下文到对话历史记录的方法 add_message_pair。可以参考第一个代码片段。

  5. 为 Astr Agent SDK 做准备。

Compatibility & Breaking Changes / 兼容性与破坏性变更

  • 这是一个破坏性变更 (Breaking Change)。/ This is a breaking change.
  • 这不是一个破坏性变更。/ This is NOT a breaking change.

Checklist / 检查清单

  • 😊 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。/ If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
  • 👀 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”。/ My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
  • 🤓 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到了 requirements.txtpyproject.toml 文件相应位置。/ I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in requirements.txt and pyproject.toml.
  • 😮 我的更改没有引入恶意代码。/ My changes do not introduce malicious code.

@LIghtJUNction LIghtJUNction marked this pull request as ready for review November 1, 2025 16:46
@LIghtJUNction LIghtJUNction requested a review from Copilot November 1, 2025 16:47
@LIghtJUNction LIghtJUNction added the enhancement New feature or request label Nov 1, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors the agent tool system to improve type safety and modularity by introducing a new message model, restructuring tool abstractions, and consolidating context handling. The changes modernize type annotations using union syntax (| instead of Optional) and relocate message-related classes to a dedicated module.

Key changes include:

  • Introduction of astrbot/core/agent/message.py with Pydantic-based message models (Message, AssistantMessageSegment, ToolCallMessageSegment, etc.)
  • Refactored FunctionTool to use ToolSchema base class with proper JSON schema validation
  • Created MCPTool as a specialized subclass of FunctionTool for MCP service calls
  • Moved tool_call_timeout from AstrAgentContext to ContextWrapper for better encapsulation
  • Updated all provider sources to handle optional prompts and convert Message objects to dicts

Reviewed Changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
astrbot/core/utils/pip_installer.py Updated type hints to use modern union syntax (str | None)
astrbot/core/provider/sources/openai_source.py Added Message import, made prompt optional, added type guards for tool calls
astrbot/core/provider/sources/gemini_source.py Made prompt optional, added Message conversion logic, removed unreachable code
astrbot/core/provider/sources/coze_source.py Added Message-to-dict conversion before processing contexts
astrbot/core/provider/sources/anthropic_source.py Made prompt optional, added Message conversion logic
astrbot/core/provider/provider.py Updated abstract method signatures to support list[Message] contexts, added conversion helper
astrbot/core/provider/func_tool_manager.py Refactored MCP tool filtering to use isinstance(f, MCPTool) instead of origin field
astrbot/core/provider/entities.py Moved message segment classes to agent.message module, renamed Anthropic Message import to avoid collision
astrbot/core/pipeline/process_stage/method/llm_request.py Refactored tool execution logic to detect overridden call method, moved event to context
astrbot/core/pipeline/context_utils.py Added call_local_llm_tool helper function for executing local tools
astrbot/core/pipeline/context.py Exported call_local_llm_tool from context_utils
astrbot/core/conversation_mgr.py Added add_message_pair method for recording user-assistant conversations
astrbot/core/astr_agent_context.py Moved tool_call_timeout to ContextWrapper, added event field
astrbot/core/agent/tool.py Refactored to use ToolSchema base class, added JSON schema validation, introduced abstract call method
astrbot/core/agent/runners/tool_loop_agent_runner.py Updated to use new message classes, removed redundant event clearing
astrbot/core/agent/run_context.py Moved tool_call_timeout from AstrAgentContext, removed unused AstrMessageEvent import
astrbot/core/agent/message.py New file containing Pydantic message models with ContentPart registry system
astrbot/core/agent/mcp_client.py Added MCPTool class implementing the call method for MCP services
astrbot/core/agent/hooks.py Removed unused @dataclass decorator from BaseAgentRunHooks

LIghtJUNction and others added 5 commits November 2, 2025 01:33
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Member

@LIghtJUNction LIghtJUNction left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

一些细节修正

@LIghtJUNction LIghtJUNction requested a review from Copilot November 1, 2025 17:38
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated 11 comments.

Comments suppressed due to low confidence (2)

astrbot/core/pipeline/process_stage/method/llm_request.py:148

  • Corrected spelling of 'deligate' to 'delegate'.
                    text=f"error when deligate task to {tool.agent.name}",

astrbot/core/pipeline/process_stage/method/llm_request.py:170

  • Corrected spelling of 'deligate' to 'delegate'.
                text=f"error when deligate task to {tool.agent.name}",

@Soulter Soulter changed the title [WIP] refactor: llm message schema [WIP] refactor: revise LLM message schema and fix the reload logic when using dataclass-based LLM Tool registration Nov 2, 2025
@Soulter Soulter changed the title [WIP] refactor: revise LLM message schema and fix the reload logic when using dataclass-based LLM Tool registration refactor: revise LLM message schema and fix the reload logic when using dataclass-based LLM Tool registration Nov 2, 2025
@LIghtJUNction LIghtJUNction requested a review from Copilot November 2, 2025 10:05
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 7 comments.

@Soulter Soulter merged commit 50144dd into master Nov 2, 2025
11 checks passed
@Soulter Soulter mentioned this pull request Nov 5, 2025
2 tasks
@Soulter Soulter deleted the refactor/llm-message-schema branch November 21, 2025 10:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants