whatevertogo 6d60e0f66b feat: 添加 LLM 工具管理和会话级别状态管理能力
- 新增 llm/ 模块,包含 LLMToolSpec、ProviderRequest、AgentSpec 等实体
- 新增 LLMToolManager 用于管理 LLM 工具注册和激活状态
- 新增 SessionPluginManager 用于会话级别的插件启用状态管理
- 新增 SessionServiceManager 用于会话级别的 LLM/TTS 服务状态管理
- 新增 RegistryClient 用于查询 handler 元数据和设置白名单
- 扩展 CapabilityRouter 内置能力,支持 session.* 和 registry.* 命名空间
- 增强描述符和装饰器以支持新的 trigger 类型
2026-03-16 17:53:07 +08:00
2026-03-14 21:33:54 +08:00
2026-03-14 21:09:48 +08:00
2026-03-14 17:16:42 +08:00
2025-11-11 00:23:48 +08:00

AstrBot SDK

面向 AstrBot 插件作者的 v4 SDK。它提供三件核心能力

  • StarContextMessageEvent 编写插件
  • astrbot-sdk dev --local / --watch 做本地调试
  • astrbot_sdk.testing 写不依赖真实 Core 的插件测试

5 分钟跑通第一个插件

1. 创建插件骨架

astrbot-sdk init my_plugin
cd my_plugin

生成后的目录结构:

my_plugin/
├── README.md
├── plugin.yaml
├── requirements.txt
├── main.py
└── tests
    └── test_plugin.py

2. 校验插件

astrbot-sdk validate

3. 本地运行一次

astrbot-sdk dev --local --event-text hello

4. 开启热重载

astrbot-sdk dev --local --watch --event-text hello

保存 main.py 后,本地 harness 会自动重载并重新派发这条消息。

最小插件示例

from astrbot_sdk import Context, MessageEvent, Star, on_command


class MyPlugin(Star):
    @on_command("hello", description="发送问候")
    async def hello(self, event: MessageEvent, ctx: Context) -> None:
        await event.reply("Hello, World!")

对应 plugin.yaml

name: my_plugin
display_name: My Plugin
desc: 一个最小可运行的 AstrBot SDK 插件
author: your-name
version: 0.1.0
runtime:
  python: "3.12"
components:
  - class: main:MyPlugin

插件作者最常用的 API

事件和上下文

  • MessageEvent.text: 当前消息文本
  • MessageEvent.reply(text): 回复文本
  • MessageEvent.reply_image(image_url): 回复图片
  • MessageEvent.reply_chain(chain): 回复消息链
  • Context.plugin_id: 当前插件 ID
  • Context.logger: 已绑定插件 ID 的日志器

平台能力

  • ctx.platform.send(session, text)
  • ctx.platform.send_image(session, image_url)
  • ctx.platform.send_chain(session, chain)
  • ctx.platform.get_members(session)

LLM

  • ctx.llm.chat(prompt)
  • ctx.llm.chat_raw(prompt, ...)
  • ctx.llm.stream_chat(prompt, ...)

存储

  • ctx.db.get/set/delete/list
  • ctx.memory.save/get/delete/search

插件元数据和 HTTP

  • ctx.metadata.get_current_plugin()
  • ctx.metadata.get_plugin_config()
  • ctx.http.register_api(handler=self.http_handler)
  • ctx.http.unregister_api(...)
  • ctx.http.list_apis()

自定义 capability

  • @provide_capability(..., input_model=MyInput, output_model=MyOutput)
  • ctx.http.register_api(handler=self.http_handler) 可以直接复用上面的 capability 方法引用

本地调试

单次派发

astrbot-sdk dev --local --event-text hello

交互模式

astrbot-sdk dev --local --interactive

交互模式支持:

  • /session <id>
  • /user <id>
  • /platform <name>
  • /group <id>
  • /private
  • /event <type>
  • /exit

热重载

astrbot-sdk dev --local --watch --interactive

适合边改边测。代码变更后会自动重建插件运行时。

测试插件

最小测试示例:

import pytest

from astrbot_sdk.testing import MockContext, MockMessageEvent
from main import MyPlugin


@pytest.mark.asyncio
async def test_hello_handler():
    plugin = MyPlugin()
    ctx = MockContext(plugin_id="my_plugin")
    event = MockMessageEvent(text="/hello", context=ctx)

    await plugin.hello(event, ctx)

    assert event.replies == ["Hello, World!"]
    ctx.platform.assert_sent("Hello, World!")

运行:

python -m pytest tests/test_plugin.py -v

如果你想走真实 dispatch 链,而不是直接调用 handler

from pathlib import Path

from astrbot_sdk.testing import PluginHarness


async def test_dispatch():
    plugin_dir = Path(__file__).resolve().parents[1]
    async with PluginHarness.from_plugin_dir(plugin_dir) as harness:
        records = await harness.dispatch_text("hello")
    assert any(record.text == "Hello, World!" for record in records)

示例插件

面向插件作者的最小示例在:

仓库里的 test_plugin/new 是运行时/集成测试夹具,不是作者入门模板。

常见问题

1. validate 通过了,但 dev 还是失败

通常是组件导入或实例化阶段异常。现在错误信息会包含:

  • 插件名
  • plugin.yaml 路径
  • components[i].class
  • 原始异常原因

优先检查:

  • plugin.yamlcomponents
  • 导入路径是否真实存在
  • 组件类是否继承 astrbot_sdk.Star
  • __init__() 是否做了会抛异常的工作

2. handler 参数为什么无法注入

默认支持:

  • 按类型注入:MessageEventContext
  • 按名字注入:eventctxcontext
  • 命令参数字典中的同名字段

如果参数不在这几类里,请自己从 eventctx 取。

3. capability schema 校验失败怎么看

错误会明确指出:

  • 哪个 capability
  • 输入还是输出校验失败
  • 具体字段路径
  • 期望类型和实际类型

下一步

  1. 先跑通 examples/hello_plugin/README.md
  2. 再看 src-new/astrbot_sdk/testing.py 里的 PluginHarness / MockContext
  3. 需要更复杂的 capability、HTTP、metadata 示例时,再参考 test_plugin/new
Description
No description provided
Readme AGPL-3.0 141 MiB
Languages
Python 61.2%
Vue 19.5%
JavaScript 13.6%
TypeScript 4.8%
HTML 0.3%
Other 0.6%