#1897·agent-zero

[错误] 插件加载将插件目录插入 sys.path[0] 中 — 具有 api/ 目录的插件覆盖了核心 API 包(在懒加载处理器上出现 500 错误)

作者: pabloalgo创建于 2026年9月11日更新于 2026年9月11日

摘要: [错误] 插件加载将插件目录插入到 sys.path[0] 中 — 任何带有 api/ 目录的插件都会遮蔽核心的 api 包,并破坏延迟加载的 API 处理程序(500) ** 版本**: v2.12(也影响 v2.11+ 插件加载)## 概要新的插件加载(v2.11+)将每个插件的目录插入到 sys.path 的 **前面**(sys.path[0])。如果一个插件提供了名为 api/ 的目录(这是一个插件暴露 API 处理程序的自然名称),它 **遮蔽了核心的 api 包**,从而导致随后解析的所有绝对导入失败。延迟加载的核心 API 处理程序随后会崩溃,出现 ModuleNotFoundError 错误并返回 HTTP 500。## 重现(确定性)1. 安装任何插件,其目录中包含 api/(例如,具有空的 api/__init__.py — 即使是一个命名空间包形状的空目录也会触发此问题)。2. 重启 UI(run_ui.py)。3. POST /api/message_async(未授权 — 失败发生在授权之前):ModuleNotFoundError: No module named 'api.message'api/message_async.py 行 3:from api.message import Message — 将 api 解析为插件的 api/ 目录(sys.path[0]),该目录中没有 message.py。## 我如何调试它(可能帮助维护者的方法)删除临时调试处理程序 api/debug_syspath.py,其中暴露 sys.path — 它是由导致失败的同一分发程序加载的,因此它返回了具体失败上下文的 sys.path:{ "syspath": [ "<repo>/usr/plugins/<offending-plugin>", "<repo>", ...], "cwd": "/root", ... } sys.path[0] 是插件目录 → 遮蔽是直接可见的。## 证据表明这是插件加载(而不是过时状态)- 从具有 cwd=repo 的 shell 中导入 api.message: ** 正常工作- 从运行中的应用程序分发程序中导入相同的内容: ** 失败- 删除插件目录 → 端点返回到健康状态(302 到登录);重新添加它 → 又出现 500- 重启无法帮助(插件在每次启动时都重新插入其目录)- 相同的处理程序代码(from api.message import Message)存在于 v2.10 中,并且在那里工作 — v2.10 的插件加载没有将插件目录预先插入到 sys.path 中## 影响任何用户插件都包含一个 api/ 目录(对于通过文档中定义的 plugins/<name>/api/<handler>.py 约定添加 API 处理程序的插件来说,这是一个非常自然的布局!),将 ** 所有 ** 核心 API 处理程序都破坏了,这些处理程序在延迟分发路径中使用了绝对的 api.* 导入。失败模式令人困惑:磁盘上的树结构完好无损,从 shell 中导入正常工作,只有在进程中延迟导入才会失败。## 建议的方向- 不改变 sys.path 就加载插件处理程序(分发程序已经通过文件位置通过 spec_from_file_location 加载 — 将插件目录预先插入到 sys.path 中似乎只用于插件自身的导入;加载后移除的作用域插入将有效)- 或者:隔离插件导入(importlib.metadata / 根据插件命名空间)以便插件目录永远不会遮蔽核心包- 或者(最小):将 api 保留为受保护的顶级名称,并在插件加载时对插件目录遮蔽 api 进行大声警告欢迎提供…

内容来源: agent0ai/agent-zero