feat: 集成 AstrBot SDK vendored runtime 与 bridge 运行时#6810
Open
whatevertogo wants to merge 497 commits intoAstrBotDevs:masterfrom
Open
feat: 集成 AstrBot SDK vendored runtime 与 bridge 运行时#6810whatevertogo wants to merge 497 commits intoAstrBotDevs:masterfrom
whatevertogo wants to merge 497 commits intoAstrBotDevs:masterfrom
Conversation
fix(testing): use public session waiter probe in PluginHarness
…BotDevs#33) * fix(testing): route session waiter followups through dispatcher * fix(testing): preserve waiter context and completion state * fix(runtime): preserve session waiter plugin identity * fix(runtime): scope session waiters by plugin * fix(testing): isolate waiter replacement and followup drains * fix(runtime): normalize waiter routing inputs
- Updated MEMORY_SEARCH_INPUT_SCHEMA to include `namespace` and `include_descendants`. - Modified MEMORY_SEARCH_OUTPUT_SCHEMA to allow nullable `namespace`. - Added `namespace` to MEMORY_GET_INPUT_SCHEMA, MEMORY_DELETE_INPUT_SCHEMA, MEMORY_SAVE_WITH_TTL_INPUT_SCHEMA, MEMORY_GET_MANY_INPUT_SCHEMA, and MEMORY_DELETE_MANY_INPUT_SCHEMA. - Enhanced MEMORY_STATS_INPUT_SCHEMA to support `namespace` and `include_descendants`. - Updated MEMORY_GET_OUTPUT_SCHEMA and MEMORY_STATS_OUTPUT_SCHEMA to include `namespace` and `namespace_count`. - Introduced `_memory_backends` in CapabilityRouterHost and CapabilityRouterBridgeBase for better memory management. - Refactored MemoryCapabilityMixin to utilize memory backends for plugin-specific memory operations. - Improved memory search functionality to respect namespaces and include descendants based on input parameters. - Added tests to validate memory operations across different namespaces and ensure persistence across restarts. - Implemented error handling in the handler dispatcher to manage exceptions gracefully.
…rbot-sdk into sdk/whatevertogo
feat(cli): improve astr init defaults
- Implemented `validate_plugin_id` to ensure safe plugin identifiers. - Added `resolve_plugin_data_dir` to resolve plugin data directories securely. - Updated memory and system capabilities to utilize new plugin ID validation. - Refactored session waiter management to simplify plugin ID handling. - Enhanced tests for plugin ID validation and data directory resolution.
feat(memory): 增强内存功能并修复测试与注入问题
fix(cli): exit cleanly on init abort
…tion-review fix(runtime): resolve issue AstrBotDevs#24 review regressions and add coverage
- Moved message result and session classes to internal modules while preserving legacy import paths for compatibility. - Updated imports across the SDK to reflect the new internal structure. - Enhanced session waiter management to support multiple plugins and improve error handling. - Added tests to ensure LLM tool registration and session waiter functionality align with dispatcher expectations. - Cleaned up code and improved documentation for clarity and maintainability.
# Conflicts: # src/astrbot_sdk/context.py # src/astrbot_sdk/runtime/handler_dispatcher.py # src/astrbot_sdk/session_waiter.py # src/astrbot_sdk/testing.py
refactor(sdk): reorganize internals and harden runtime regressions
955470aee chore: refresh vendor snapshot [skip ci] 6da1db9a7 Merge pull request AstrBotDevs#98 from united-pooh:dev 4e6d9590d fix: 更新 set_extra 和 get_extra 方法的文档,增加关于数据序列化的说明 fix: 修改 HandlerDispatcher 中的事件类型判断,支持 streaming_delta REVERT: f23721f24 chore: refresh vendor snapshot [skip ci] git-subtree-dir: astrbot-sdk git-subtree-split: 955470aeef93f2fd8c6354c001777c46e9d98835
…d runtime_store - Added SdkRegistryManager for managing SDK plugins, including listing, registering, and unregistering skills and HTTP APIs. - Introduced SdkRequestRuntime to handle request overlays, dispatch tokens, and event results. - Created runtime_store to maintain the state of SDK plugins, request contexts, and HTTP routes. - Implemented data classes for structured management of plugin records, request overlays, and dynamic command routes. - Enhanced error handling and logging for better debugging and operational visibility.
b817715b9 chore: refresh vendor snapshot [skip ci] 231bd5da2 Merge pull request AstrBotDevs#99 from united-pooh:dev 2637cbbdb feat: 添加 register_file_url 方法以支持文件 URL 注册,并更新相关文档 bb4a57aec fix: 更新 MessageEvent 类中的方法文档,增加中文说明以提升可读性 REVERT: 955470aee chore: refresh vendor snapshot [skip ci] git-subtree-dir: astrbot-sdk git-subtree-split: b817715b9179b359ea1a1ea5a7d1bf198f0be798
378257db7 chore: refresh vendor snapshot [skip ci] f8dab1de5 Merge pull request AstrBotDevs#100 from united-pooh:dev 5492735cd feat: 添加 repo 字段到插件元数据,增强插件信息的完整性 REVERT: b817715b9 chore: refresh vendor snapshot [skip ci] git-subtree-dir: astrbot-sdk git-subtree-split: 378257db7da5e75fb99449ab1266f33e101a6922
feat: 更新认证中间件以支持 SDK 插件的自定义认证流程 test: 增加测试以验证插件重载操作的串行化 test: 添加测试以确保无效处理程序类型在插件加载时失败
9724f6230 chore: refresh vendor snapshot [skip ci] 87dd4d31f Merge pull request AstrBotDevs#103 from united-pooh:dev 816732c52 Merge branch 'dev' of https://github.com/united-pooh/astrbot-sdk into dev 740f497fb feat: 引入线程安全机制,优化插件加载和组件实例化过程 1c2c451b9 Merge pull request AstrBotDevs#102 from united-pooh/docs/72 dad29d656 docs: 翻译预期外的英文注释 0688d335f Merge pull request AstrBotDevs#101 from united-pooh/fix-96-init-gitignore-template b7b3e6bc5 feat: generate plugin gitignore during init REVERT: 378257db7 chore: refresh vendor snapshot [skip ci] git-subtree-dir: astrbot-sdk git-subtree-split: 9724f6230147d6101cc4c6493d3d6b7b8e1d4f33
56943300b chore: refresh vendor snapshot [skip ci] 215e06572 Merge pull request AstrBotDevs#104 from united-pooh:dev ea10d593d feat: 增强插件导入机制,支持命名空间和动态导入 REVERT: 9724f6230 chore: refresh vendor snapshot [skip ci] git-subtree-dir: astrbot-sdk git-subtree-split: 56943300b29038e57ab859d19d900e2e967a3a8a
0a9c86345 chore: refresh vendor snapshot [skip ci] b5d9b934b Merge pull request AstrBotDevs#105 from united-pooh:dev c07f04e63 feat: 更新多个客户端和模块,增强类型注解和文档说明 REVERT: 56943300b chore: refresh vendor snapshot [skip ci] git-subtree-dir: astrbot-sdk git-subtree-split: 0a9c86345ea2192154580d0ef054b72b99892b9e
- Added validation to ensure HTTP routes and handler capabilities belong to the current plugin namespace in the SDK. - Updated tests to reflect changes in API registration routes, ensuring they include the plugin ID as a prefix. - Introduced new error handling for invalid route and capability registrations. - Refactored existing tests to accommodate the new route structure and added tests for new validation logic. - Improved the structure of SDK record creation for better readability and maintainability.
SDK 装饰器层(decorators.py)为所有装饰器增加 callable 检查和参数归一化/校验, 防止插件作者传入非法类型后在运行时才崩溃。conversation.py 修复 ConversationState 反序列化兼容。events.py 新增 has_admin_permission() 别名。 runtime/loader.py 引入 MetaPathFinder 替代纯 builtin __import__ hook, 解决插件 import alias 泄漏到 sys.modules 的问题;新增 _restore_plugin_import_hook() 用于测试 teardown。runtime/peer.py 防止 stop() 并发重入、入站消息超限拒绝(8MB), _handle_raw_message 不再向上抛异常。runtime/transport.py 所有读循环改为帧级容错: 单帧 ValueError/UnicodeDecodeError 只跳过该帧,不中断整个连接。runtime/supervisor.py 为 worker 初始化增加 60s 超时。 core/command_compatibility.py 将 build_cross_system_conflicts 从 O(n*m) 暴力比较 优化为前缀索引查找,大幅减少命令冲突检测耗时。 core/platform/astr_message_event.py 新增语义清晰的 LLM/发送状态 API (set_default_llm_blocked/should_call_default_llm/mark_send_operation 等), 旧 call_llm/_has_send_oper 字段保留但标记为内部实现。 core/sdk_bridge/request_runtime.py 对所有 overlay/context 字典操作加 threading.RLock,消除并发调度时的竞态条件;close_request_overlay 拆为锁内原子移除 + 锁外 event 回写两阶段。plugin_bridge.py 新增 _snapshot_records 系列方法统一 遍历入口、Windows 平台 MCP 进程终止改用 taskkill、调度 handler 后 finally 关闭 overlay 防泄漏。dispatch_engine.py 全面使用新的 event API 替代直接写字段。 runtime_store.py 新增 mutation_lock 和 snapshot 方法。tests 覆盖 dispatch engine、 loader 隔离、transport 帧容错、bridge runtime capabilities、MCP/provider tool、 native command、vnext author experience 等场景。
新增 _internal/sdk_logger.py 作为 SDK 唯一日志出口,通过 logger.patch()
注入 plugin_tag、short_levelname、版本号等上下文字段,替换 12 个模块中
原有的 from loguru import logger 和 loader.py 里的 stdlib logging。
- decorator_lifecycle/cli/context/peer/supervisor/transport/worker/session_waiter/star: 改为从 sdk_logger 导入
- handler_dispatcher: 含方法内延迟导入也一并迁移
- loader: 移除 _LOGGER (logging.getLogger),全部改用 loguru + {} 格式串
- test_sdk_plugin_config_bridge: caplog 改为 monkeypatch 适配 loguru
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
动机 / Motivation
这个 PR 的目标,不是简单"把一个新 SDK 目录拷进主仓库",而是把 AstrBot SDK v4 的运行时能力 以一种可以在主仓库长期维护、逐步落地、并且不破坏旧插件生态的方式接入 AstrBot。
与其说他是sdk,不如说他是为了新旧插件都兼容的新插件扩展平台
要解决的核心问题有 4 类:
插件运行边界不清晰
旧插件路径与主进程深度耦合,插件直接共享宿主进程内对象,插件异常、运行时污染、依赖冲突都更容易放大到整个系统。
插件开发接口过于依赖宿主内部实现
旧接口里很多能力是"直接拿宿主对象调用"的风格,虽然能用,但边界不稳定、类型约束弱、难以做清晰的能力声明,也不利于长期演进。
主仓库和 SDK 仓库的职责边界需要明确
独立的
astrbot-sdk仓库需要作为 SDK 的 source of truth 持续演进;AstrBot 主仓库需要的是一个可消费、可同步、可测试的 vendored 运行时快照,而不是把整个 SDK 源仓库原样搬进来。迁移必须渐进,不能推翻现有插件体系
AstrBot 现有大量逻辑仍然基于 legacy Star 插件体系。SDK 的接入必须保证:
因此,这个 PR 的真实定位是:
sdk_bridge宿主桥接层变更规模 / Change Statistics
按模块统计:
astrbot-sdk/astrbot/core/sdk_bridge/tests/astrbot/core/astrbot/dashboard/astrbot/core/pipeline/astrbot/core/platform/sources/scripts/这次 PR 实际做了什么
1. 在主仓库中引入
astrbot-sdk/的 vendored snapshot这个 PR 在主仓库下新增了
astrbot-sdk/目录,但这里必须明确:astrbot-sdk/是 给 AstrBot 主仓库消费的 vendored subtree snapshotastrbot-sdk源仓库的完整镜像这里保留的主要内容包括:
src/astrbot_sdk/:SDK 运行时包主体pyproject.toml:让主仓库可以按本地 path dependency 使用 SDKREADME.md/VENDORED.md/LICENSE:说明 vendoring 约定与快照边界templates/project_notes/AGENTS.md/CLAUDE.md:因为astr init仍然会生成这些模板testing.py、_testing_support.py、_internal/testing_support.py等最小测试辅助:因为主仓库与模板仍然依赖这些约定同时,很多内容是 刻意不 vendoring 进主仓库的:
这样设计的原因是:
主仓库要消费稳定快照,不是承载 SDK 全量研发现场
AstrBot 主仓库关注的是"可运行、可集成、可回归"的 SDK 版本,而不是承接 SDK 仓库的所有开发噪音。
source of truth 必须单一
SDK 行为、文档、测试体系的第一来源仍然应该是独立
astrbot-sdk仓库。主仓库里的astrbot-sdk/只是同步产物,不应该再被误解为主要开发位置。便于后续同步与审查
scripts/sync-sdk.ps1/scripts/sync-sdk.sh明确要求:这保证了变更路径清晰,减少"主仓库偷偷改 SDK vendored 文件"的维护风险。
2. 把 SDK 的运行时模型正式接入 AstrBot 主仓库
主仓库引入的不只是一个 Python package,而是一整套 SDK 运行时入口:
protocol/:协议消息模型与描述符runtime/:loader / peer / transport / supervisor / handler_dispatcher / capability_router 等运行时骨架clients/:ctx.llm、ctx.memory、ctx.db、ctx.platform等高层客户端decorators.py:声明式 handler/capability 注册入口(20+ 装饰器,涵盖 on_command、on_message、on_event、on_schedule、on_provider_change、validate_config、http_api、mcp_server、register_skill、background_task 等)context.py/events.py/message/*:插件作者直接面对的主要 APISDK 本身的设计是比较清晰的一条链路:
也就是说,SDK 不是让插件"直接摸宿主对象",而是让插件通过 显式能力调用 与宿主通信。
这套设计的核心思想有三点:
协议优先(protocol-first)
先定义清楚消息模型、调用边界、错误结构,再谈功能。
能力优先(capability-first)
宿主暴露什么能力,要通过 capability 名称和 payload schema 明确表达,而不是让插件到处拿宿主内部对象直接调用。
声明式优先(descriptor-first)
handler、trigger、capability 都先变成可序列化描述符,再进入运行时分发。这让跨进程、热重载、命令面板、平台命令注册这些事情都更可控。
3. SDK CLI 工具链
SDK 包含完整的命令行工具(
astr命令),为插件开发者提供端到端的工作流支持:astr init--agents claude,codex自动生成 AI 编程助手 skill 模板astr validateastr buildastr dev --local--watch文件变更热重载、--interactive交互调试astr runastr worker4. 插件持久化记忆系统
SDK 内置
PluginMemoryBackend,提供插件级别的持久化键值记忆后端:save_with_ttl()支持带过期时间的记忆条目include_descendants递归查询5. SDK 客户端面(Capability Surface)
SDK 通过
Context暴露 15+ 类型化客户端,每个客户端背后是 capability proxy:LLMClientchat,chat_raw,stream_chatMemoryClientsearch,save,get,delete,list_keysDBClientget,set,delete,list,get_many,set_many,watchPlatformClientsend,send_stream,get_member_info,get_group_member_listProviderClientchat_for_provider,get_llm_profileProviderManagerClientlist_providers,get_providerPersonaManagerClientlist,create,update,deleteConversationManagerClientlist,create,update,delete,set_activeKnowledgeBaseManagerClientlist,create,update,delete,upload,retrieveMessageHistoryManagerClientlist,get_pageMCPManagerClientlist_servers,register_global_server,enable_server,session_callPermissionClientcheckPermissionManagerClientlist,add,removeSkillClientregister_skill,unregister_skillHTTPClientregister_api,unregister_apiMetadataClientget_plugin_config,get_plugin_metadataFileServiceClientregister_file,handle_fileSessionServiceManager6. SDK 测试基础设施
SDK 提供完善的测试辅助(
astrbot_sdk.testing),支持插件作者编写单元测试和集成测试:MockContext:完整 mock 的 Context,内置 InMemoryDB、InMemoryMemory、MockCapabilityRouterMockMessageEvent:可配置 user_id / group_id / platform / session 的 mock 事件MockLLMClient:支持预设响应(mock_response/mock_stream_response)MockPlatformClient:记录发送历史,支持assert_sent断言PluginHarness:从 plugin.yaml 加载插件并执行完整 dispatch 流程StdoutPlatformSink:将平台输出捕获到内存或 stdoutSDK 为什么这样设计
1. 为什么要做 Worker / Supervisor 运行时边界
SDK 的核心架构是把插件执行从主进程逻辑里抽出来,形成更明确的执行边界:
Supervisor管理 Worker 生命周期WorkerSession代表一个被宿主管理的插件运行单元Peer + Transport负责协议收发HandlerDispatcher/CapabilityDispatcher负责把协议调用分发到真实 Python 对象这样做的原因是:
隔离故障域
插件执行失败、卡死、局部污染时,不必直接把主进程也拖下水。
隔离依赖与环境
SDK 运行时天然更适合做环境分组、虚拟环境规划和后续多运行边界扩展。
让宿主和插件关系从"对象耦合"变成"协议耦合"
这会让系统更难写一点,但长期维护成本更低,因为边界明确以后,兼容性和演进策略才可控。
2. 为什么是 Capability Router,而不是直接暴露宿主 API
Context下的llm/memory/db/platform/provider/permission/kb/mcp等客户端,本质上都是 capability 的 typed facade。这样做的好处是:
调用边界稳定
插件只需要知道 capability 名称和参数,不需要知道宿主内部对象结构。
更适合做 schema 验证与错误治理
Capability 本身就是"一个命名的、结构化的远程调用点",天然适合做 JSON Schema、错误码、重试语义和 docs_url。
便于宿主分层实现
主仓库里真正干活的代码仍然可以分散在 ProviderManager、PlatformManager、ConversationManager、DB、KB 等各处,但对 SDK 来说只看见统一 capability surface。
3. 为什么 handler / trigger 要走描述符,而不是靠反射硬猜
HandlerDescriptor、CommandTrigger、MessageTrigger、EventTrigger、ScheduleTrigger这一层是 SDK 的一个重要设计点。它解决的是:
如果没有这一层,宿主要做的事情会很混乱:
描述符层的意义,本质上是把"运行时行为"先降维成"静态声明",这样宿主侧才有机会在真正执行前做规划、注册、展示和校验。
为什么 AstrBot 主仓库还需要一层
sdk_bridge如果 SDK 已经有 protocol、peer、capability_router,为什么主仓库还要额外实现
astrbot/core/sdk_bridge/?因为 SDK 是通用插件运行时,AstrBot Core 则是一个已经存在多年、已有完整 legacy 体系、已有平台适配器、已有消息流水线和 Dashboard 的具体宿主。两者之间不可能无缝直接拼上,必须有一层宿主适配桥。
sdk_bridge做的事情,本质上是把:做一次明确的对接。
可以把它理解为:
sdk_bridge决定"在 AstrBot 这个具体宿主里,这些事情到底接到哪里去、怎么兼容现有流水线"sdk_bridge的设计与职责1.
SdkPluginBridge:宿主侧总入口(3,793 行)astrbot/core/sdk_bridge/plugin_bridge.py是这一层的核心。它承担了几类关键职责:
插件发现与运行管理
WorkerSessionhandler 匹配与分发
请求级状态管理
_RequestOverlayState跟踪单次消息分发的 overlay 状态sent_message/stop/call_llm宿主侧面板与管理接口
宿主事件桥接
decorating_result、agent_begin、agent_done等这样设计的原因是:
SdkPluginBridge里,能够避免这种适配逻辑散落到全项目2.
CoreCapabilityBridge:把 AstrBot Core 能力整理成 SDK capability surfaceastrbot/core/sdk_bridge/capability_bridge.py和其 mixins 负责把 AstrBot Core 已有能力重新整理成 SDK 世界可理解的 capability 集合。这里不是重新实现业务,而是把宿主现有能力做一层 协议化、能力化、结构化暴露。
当前拆分出的能力组包括(对应
sdk_bridge/capabilities/下的 mixin 文件):_host.pybasic.pyllm.pyprovider.pyplatform.pysession.pypersona.pyconversation.pyknowledgebase.py/kb.pymessage_history.pypermission.pymcp.pyskill.pysystem.py这么拆的原因是:
按领域拆分,比按技术层拆更稳定
对插件作者来说,最稳定的心智模型不是"这个函数在宿主的哪个 manager 里",而是"这是 provider 能力、platform 能力、kb 能力还是 session 能力"。
便于逐步扩展 capability 面
后续某个领域能力增长时,只需要扩对应 mixin,而不是把一个巨型 bridge 类继续堆大。
更利于测试
主仓库当前新增的大量
tests/test_sdk/unit/测试,本质上就是在回归这些 capability contract 是否稳定。3.
TriggerConverter:trigger/filter/permission 的宿主侧匹配TriggerConverter的职责看似简单,但实际上很关键:HandlerDescriptor中声明的 trigger/filter/permission 规则映射到 AstrBot 当前消息事件模型上normalize_message_type()统一规范化(group/private/other)它存在的原因是:
SDK 描述符与 AstrBot 当前事件模型不是同一套类型系统
需要一层稳定的 host-side matcher。
命令与消息匹配逻辑必须宿主可控
这样 Dashboard 命令展示、平台原生命令注册、运行时触发行为才会保持一致。
本地 filter ref 必须 fail-open 处理
某些 filter 指向插件进程内 callable,宿主不能直接执行,所以桥接层要明确知道哪些规则能在 host 侧判断,哪些不能。
4.
event_payload.py:payload 归一化层AstrBot Core 事件对象和 SDK 侧
MessageEvent不是同一个对象体系。event_payload.py的设计目标是:AstrMessageEvent的关键信息抽成InboundEventSnapshot为什么这层必要:
5.
_RequestOverlayState:请求覆盖层这是这次 bridge 设计里最容易被忽略、但实际上非常关键的部分。
AstrBot 原有流水线不是为"SDK 插件在另一套 runtime 里执行,并返回 stop/call_llm/result 覆盖行为"而设计的。为了在不重写整个流水线的前提下把 SDK 接进去,必须引入一层 请求级 overlay state。
它解决的核心问题是:
SDK handler 返回的结果要能影响宿主后续流水线
比如:
这些影响必须是"本次请求级"的,而不是全局状态
否则不同消息请求会互相污染。
宿主现有 stage 必须能读取"effective result"而不是只读
event.get_result()所以你会看到 pipeline 的多个 stage 被改造成:
换句话说,overlay 设计是在尽量少改动旧流水线的前提下,把 SDK 的"跨进程 handler 决策"投影回宿主当前请求上下文里。
这是一个很典型的增量架构设计:
这个 bridge 是如何嵌入 AstrBot 现有生命周期的
1. Core Lifecycle 接入
astrbot/core/core_lifecycle.py里,这个 PR 增加了:SdkPluginBridgestar_contextplatform_managerstart()它这样做的原因是:
2. Pipeline 接入(9 文件,243 行变更)
改动点主要在:
astrbot/core/pipeline/process_stage/stage.pyastrbot/core/pipeline/respond/stage.pyastrbot/core/pipeline/result_decorate/stage.py这些改动的核心不是"重写 pipeline",而是让 pipeline 在关键节点具备以下能力:
call_llm的最终决策不能再只看 legacy event 状态,还要看 SDK overlay 决策decorating_result这类宿主事件也需要反向派发给 SDK这里的设计重点是 共存而非替换。
也就是说,当前实现不是把旧 pipeline 砍掉换成 SDK pipeline,而是让:
这也是为什么这个 PR 的迁移风险可控得多。
3. Dashboard 接入(10 文件,547 行变更)
Dashboard 相关改动主要在:
astrbot/dashboard/routes/command.pyastrbot/dashboard/routes/tools.pyastrbot/dashboard/routes/plugin.pyastrbot/dashboard/routes/config.pyastrbot/dashboard/routes/skills.pyastrbot/dashboard/routes/session_management.pyastrbot/dashboard/routes/stat.pyastrbot/dashboard/server.py这里的设计策略也很明确:
SDK 命令要可见,但不一定要全量可编辑
当前
command.py明确把 SDK commands 标记为只读。这是合理的,因为 SDK command 的 source of truth 在插件描述符,不在 Dashboard 本地手工改表单。SDK tools 可以纳入统一工具面板
只要 tool 是桥接层能管理的,就应该与 legacy tools 一样出现在工具视图里,并支持激活/停用。
配置 schema 通过 bridge 获取,而不是复制一份配置逻辑
这样 Dashboard 能显示 SDK 插件的配置,又不会把 plugin config contract 分裂成两套。
这种设计说明 Dashboard 的目标不是"自己管理一套 SDK 元数据",而是作为 bridge 的展示和操作前端。
4. 平台原生命令接入
在 Telegram / Discord 适配器里,这个 PR 增加了从 bridge 读取 native command candidates 的逻辑。
这背后的设计原因是:
这再次体现了"声明式描述符"的价值:
同一份元数据既能驱动运行时触发,也能驱动 Dashboard 展示,还能驱动平台命令注册。
除了 bridge,本 PR 还做了哪些必要配套
这个 PR 里还有一些配套改动,单看可能不显眼,但它们其实都是 SDK integration 能落地的必要条件。
1. 配置、技能、工具、MCP、权限等周边能力统一纳入 capability 面
CoreCapabilityBridge不只是桥一下llm.chat这么简单,它把:都整理进了 capability world。
这说明这个 PR 做的不是"给 SDK 开两个测试用接口",而是认真地把 AstrBot Core 能力重新投影成 SDK 的宿主契约。
2. Star / Skill 管理器增强
star_manager.py(+269 行):增强插件发现、加载、重载逻辑,支持 SDK 插件与 legacy Star 共存skill_manager.py(+435 行):增强技能安装、注册、同步逻辑,支持 SDK 技能纳入统一管理3. 新增工具函数
media_utils.py(94 行):媒体处理工具storage_cleaner.py(271 行):存储清理工具4. 同步脚本与 vendoring 约束
scripts/sync-sdk.ps1/scripts/sync-sdk.sh的价值不只是方便同步,而是把维护约束落到了脚本里:这相当于把"vendored SDK 不该坏掉"的约束做成了工具化的 guardrail。
5. SDK 事件分发钩子
新增
agent_begin和agent_done系统事件分发支持,允许 SDK 插件监听 Agent 执行生命周期。测试覆盖
本 PR 新增 17,926 行测试代码,分布在以下区域:
tests/test_sdk/unit/tests/test_sdk/tests/test_db_backward_compat.pytests/test_dashboard.pytests/test_plugin_manager.pytests/test_platform_register.pytests/test_computer_config.pytests/unit/test_astr_agent_hooks.pytests/unit/test_astr_agent_tool_exec.pytests/unit/test_tool_conflict_resolution.pytests/unit/test_tool_google_schema.pytests/unit/test_faiss_vec_db.py兼容性与迁移结论
Breaking Changes
预期兼容策略是:
换句话说,这个 PR 更像是一次 宿主能力扩展与架构铺路,而不是一次激进替换。
从迁移角度看,它建立的是一个可逐步迁移的双轨体系:
验证方式 / Verification
Checklist / 检查清单
astrbot-sdk/在主仓库中是 vendored snapshot,而不是完整 SDK 源仓库sdk_bridge在 AstrBot 宿主中的职责、边界和存在必要性