feat(plugins): add managed runtime SDK and release 2.4.5
This commit is contained in:
1 parent
506e3bf1c5
commit
2a3bbaa3fb
45 files changed
+3348
-98
No files matched your search
@@ -1,6 +1,6 @@
|
||||
# 插件开发 SDK 与证据协议(ARTEMIS 2.3.0)
|
||||
# 插件开发 SDK 与证据协议(ARTEMIS 2.4.5)
|
||||
|
||||
新插件必须适配本文规则,再通过实测进入市场。旧 `schema_version: 1` 仍可读取;执行插件使用版本 2,并声明 `capabilities`。需要回放面板、人工表单和报告字段时使用版本 3,见[工作区插件接口](workspace-plugins.md)。模型执行、任务队列、资源锁、超时和报告由 ARTEMIS 管理,插件不另建任务调度器,也不替用户决定用例通过。
|
||||
新插件必须适配本文规则,再通过实测进入市场。旧 `schema_version: 1` 仍可读取;执行插件使用版本 2,并声明 `capabilities`。需要回放面板、人工表单和报告字段时使用版本 3,见[工作区插件接口](workspace-plugins.md)。模型执行、任务队列、资源锁、整体调用预算和报告由 ARTEMIS 管理;插件负责内部工具的超时、取消与子进程收尾,不另建任务调度器,也不替用户决定用例通过。
|
||||
|
||||
## 从可运行模板开始
|
||||
|
||||
@@ -23,6 +23,8 @@ uv run python -c "import shutil; shutil.make_archive('evidence-demo', 'zip', 'ex
|
||||
|
||||
静态检查通过不等于市场准入,也不表示业务测试通过。需按下面清单提交实际验证记录。
|
||||
|
||||
涉及外部程序或已批准文件输入时,从 [managed-tool-demo](../examples/plugins/managed-tool-demo/README.md) 开始;它提供真实 MCP 离线回归。通用接口、故障自测和独立 `--market` 检查见[运行辅助接口与市场材料](plugin-sdk.md)。SDK 自测在临时目录运行,不访问真实设备。
|
||||
|
||||
## 清单与工具能力
|
||||
|
||||
`plugin.json` 的安装、版本约束、资源、权限设置沿用 [插件说明](plugins.md)。版本 2 增加:
|
||||
@@ -87,3 +89,5 @@ stdio 宿主注入 `ARTEMIS_ARTIFACTS_DIR`,插件默认把生成文件写入
|
||||
- 视觉:截图来源、遮挡、DPI、窗口切换、坐标一致、无图时拒绝盲点;录屏启动/结束/暂停恢复、编码回退、磁盘不足、时间缺口、关键节点、播放状态、中文可读性及长程体积。
|
||||
- 文件:中文文件名、覆盖保护、校验失败;终端/API:退出码、业务结果和不确定副作用。
|
||||
- Skill 必须只描述真实存在且已适配的能力,不绕过权限、调度和证据协议。保留来源和必要许可证,版本与实测范围明确;未测平台/场景不能写成已通过。
|
||||
- 外部程序验证正常退出、内部超时、取消和输出超限后的整个进程树回收;不能只确认 MCP/直接子进程退出。写操作消费文件时,批准摘要必须绑定实际消费的不可变内容,覆盖校验后替换、截断与增长。
|
||||
- 市场提交须附 [MARKET.json](plugin-sdk.md#marketjson),绑定候选内容、组件分发授权和验收证据;对最终 ZIP 运行 `--market`。本地开发检查不强制公开许可,市场材料检查不替代源码和业务审查。
|
||||
@@ -0,0 +1,121 @@
|
||||
# 插件运行辅助接口与市场检查
|
||||
|
||||
这些接口从 ARTEMIS **2.4.5** 开始提供,位于 `artemis.plugins.sdk`;使用 ARTEMIS 2.4.5 或更新版本的 Python,并在插件清单中声明 `artemis_version: ">=2.4.5,<3.0.0"`。它们不属于远程薄客户端 `artemis-client`,不启动后台、模型或第二套任务队列。现有不依赖这些辅助接口的插件仍按自身清单兼容旧宿主;采用这些接口才需要提高最低版本。
|
||||
|
||||
## 已批准文件必须绑定实际使用的字节
|
||||
|
||||
```python
|
||||
from artemis.plugins.sdk import snapshot_file
|
||||
|
||||
snapshot = snapshot_file(authorized_path, approved_sha256)
|
||||
# 此后只消费快照。连接建立、预检或等待期间原文件发生变化,也不会改变快照。
|
||||
for chunk in snapshot.chunks():
|
||||
transport.sendall(chunk)
|
||||
```
|
||||
|
||||
`approved_sha256` 必须来自已批准的内容身份,不能在执行时把新文件的摘要自动当作新的批准。制作快照、验证设备身份和写入授权都应在真正写操作前完成。使用 `.data` 或只读的 `.chunks()`,不要校验之后重新打开原路径;传输后才发现摘要不符不能撤销已经发生的写入。
|
||||
|
||||
`snapshot_file` 一次读取授权的普通文件并核对 SHA256,拒绝链接、特殊文件、大小超限和摘要不符。默认上限 64 MiB,副本是不可变内存 bytes;参数 `max_bytes` 仅作用于本次调用,选择更大上限须评估内存。它不负责用户授权或路径沙箱,插件仍要限制允许读取的范围。大文件如采用磁盘快照或流式方案,应提供等价的防修改保证并另行验证,不能恢复到“检查后重开路径”。
|
||||
|
||||
`VerifiedFile.size`、`.sha256` 对应快照本身。原路径同长度覆盖、替换、增长或截断后,快照仍保持原内容。对写入端到端的回归必须检查实际发送字节,不能只断言预检函数被调用。
|
||||
|
||||
## 外部工具的生命周期
|
||||
|
||||
```python
|
||||
from artemis.plugins.sdk import ManagedProcessError, run_process
|
||||
|
||||
try:
|
||||
result = await run_process(
|
||||
fixed_argv,
|
||||
cwd=authorized_directory,
|
||||
timeout=20,
|
||||
input_data=snapshot.data,
|
||||
)
|
||||
except ManagedProcessError as exc:
|
||||
# 用稳定的 error_code 返回部分执行/未知;不回显命令或原始敏感输出,不自动重试。
|
||||
...
|
||||
```
|
||||
|
||||
`fixed_argv` 必须是业务层构造的固定参数列表,不能向模型暴露任意 shell;`cwd` 为明确的现有目录。可通过 `env` 提供所需的环境白名单;未提供时继承当前插件环境,插件应自行排除不需要的密钥和工具日志变量。宿主的凭据管理不会自动证明外部程序的输出安全。
|
||||
|
||||
`timeout` 必须为有限正数,作用于本次工具运行;标准输入最多 64 MiB。stdout、stderr 分别返回 bytes,共用默认 4 MiB 上限,可通过本次调用的 `max_output_bytes` 调整。输出超限立即停止;部分输出不作有效结果返回。`ProcessResult.returncode` 保留非零退出码,不据此生成业务用例通过结论。
|
||||
|
||||
运行器在 Windows 先将等待启动的引导进程加入不可继承的 Job Object,再允许启动实际工具,防止快速派生后代漏出归属;父进程退出时 Job Object 同样回收其树。POSIX 使用独立会话,正常退出、超时、取消和输出超限均回收所属进程组。它是生命周期辅助,不是恶意程序沙箱,不能承诺回收主动逃离会话的程序。
|
||||
|
||||
调用结束后不保留后台子进程。需要常驻驱动的插件应实现会话级归属、关闭与验证,不借本接口后台化工具。取消在清理后继续传播,不能吞掉 `CancelledError`。清理另有固定的有界等待;未确认完成时抛出 `process_cleanup_unconfirmed`,插件必须返回未知状态并核对资源,不声明已全部停止。
|
||||
|
||||
常见错误码:`process_timeout`、`process_output_limit`、`process_launch_failed`、`process_ownership_failed`、`process_worker_interrupted`、`process_invalid_status`、`process_cleanup_unconfirmed`。`may_have_started=false` 只表示已知工具尚未启动;其余情况不能授权重发写操作。运行器从不重试。原始输出可能包含密钥,返回给模型前按业务字段白名单处理。
|
||||
|
||||
宿主负责整体任务与 MCP 调用预算,插件负责内部操作及其后代。内部超时先发生时,必须在向宿主返回前收尾;宿主未超时、或只关闭 MCP 连接,都不能替代这一步。
|
||||
|
||||
## 可运行回归
|
||||
|
||||
```sh
|
||||
<ARTEMIS_PYTHON> -B -m artemis.plugins.sdk_checks --json-output sdk-faults.json
|
||||
<ARTEMIS_PYTHON> -B <受管工具模板目录>/test_contract.py
|
||||
```
|
||||
|
||||
模板目录在源码仓库的 `examples/plugins/managed-tool-demo`,或本 Skill 的 `assets/managed-tool-demo`;先复制到用户指定开发目录。以下检查均使用 ARTEMIS 2.4.5 或更新版本的 Python。
|
||||
|
||||
第一条只在临时目录创建合成文件和自己的测试进程,覆盖文件同长度覆盖、截断/增长、错误摘要、二进制 stdin、非零退出码、正常结束/超时/取消后的后代回收、输出超限、附件摘要与路径拒绝,以及部分/未知执行不能授权重试。它不连接设备、不调用模型、不修改现有任务或配置。结果明确标为 `sdk_faults_only`。
|
||||
|
||||
第二条额外通过真实 stdio MCP 调用模板工具,核对有效输入、错误摘要、目录穿越拒绝及宿主附件回读,结果标为 `template_offline_contract`。模板见插件开发文档的受管工具示例。
|
||||
|
||||
改写插件后,必须扩展模板测试到自己的实际入口:在最后一次预检与真正消费文件之间替换输入、让实际工具创建后代再超时/取消,并检查实际传输和进程存活。SDK 自测通过不能证明插件调用正确。还需覆盖错误/部分执行、证据丢失或摘要不符、权限、资源互斥以及真实任务时间线。
|
||||
|
||||
## 开发检查与市场材料检查
|
||||
|
||||
统一入口为仓库/Skill 的 `check_plugin.py`,也可执行 `python -m artemis.plugins.validation`。两处脚本调用同一个实现,不单独维护规则。
|
||||
|
||||
```sh
|
||||
# 日常本地开发,无需公开分发许可;--live 只握手,不派发工具。
|
||||
<ARTEMIS_PYTHON> <检查脚本> <插件目录或ZIP> --live --values '{"python":"ARTEMIS解释器绝对路径"}'
|
||||
|
||||
# 在清洁候选目录生成草稿;所有结论未验证、许可未知,不覆盖已有 MARKET.json。
|
||||
<ARTEMIS_PYTHON> <检查脚本> <插件目录> --prepare-market
|
||||
|
||||
# 对最终候选 ZIP 检查市场材料;包含只读 MCP 声明握手,不调用业务工具。
|
||||
<ARTEMIS_PYTHON> <检查脚本> <最终ZIP> --market --values '{"python":"ARTEMIS解释器绝对路径"}' --json-output market-check.json
|
||||
```
|
||||
|
||||
路径与 JSON 按当前 Shell 引用;密钥不放进 `--values`。`--json-output` 必须在候选目录外,不能覆盖输入 ZIP。ZIP 沿用宿主的安全解压和大小限制,检查不向已有插件库安装。`--market` 先核对材料,再握手,普通开发检查仍保持轻量。
|
||||
|
||||
市场检查拒绝缓存、`.pyc`、虚拟环境、版本库目录、个人 `.env` 配置、链接和冲突路径。环境样例可保留 `.env.example`。不要为通过检查而清理用户运行目录;从可分发输入构建独立候选。
|
||||
|
||||
## MARKET.json
|
||||
|
||||
此文件随包提交,版本固定为 1,不增加 `plugin.json` 字段,旧宿主仍可安装符合其能力的插件。草稿由检查脚本生成,包含:
|
||||
|
||||
| 字段 | 要求 |
|
||||
| --- | --- |
|
||||
| `plugin_id`、`plugin_version` | 与候选清单完全一致 |
|
||||
| `content_sha256` | 全部包内文件路径及 SHA256 的确定性摘要,只排除根层 `MARKET.json` 自身 |
|
||||
| `traits.uses_subprocesses` | 明确 true/false,不能保留 null |
|
||||
| `traits.file_inputs_for_writes` | 是否消费文件执行写操作,明确 true/false |
|
||||
| `components` | 分开列原始实现、适配层、第三方依赖/参考资料的许可和来源 |
|
||||
| `checks` | 下表全部验收项目,保留实际范围和证据 |
|
||||
|
||||
每个组件包含 `name`、`paths`、`license`、`permission`、`license_file`、`source_file`。`paths` 为精确包内相对路径或目录前缀,`.` 表示整个包;全部可分发文件须被覆盖。只有明确的 `permission: "permitted"` 才接受,`local_only` 和 `unknown` 均阻止市场提交。许可和来源文件必须实际在包内;适配层开源许可不会重新许可原始代码、用例、协议或内部资料。可使用合适的 LicenseRef,不强制统一开源,但具体分发授权必须可审查。
|
||||
|
||||
每条验收记录包含 `status`、`evidence_file`、`evidence_sha256`、`notes`。`passed` 必须指向真实的非空包内文档及其正确摘要,notes 说明验证环境、范围与结果;缺失、失败和未验证均拒绝。不能把历史记录、SDK 自测或模拟设备改写为本次真实业务通过。
|
||||
|
||||
| 验收项目 | 要记录的内容 |
|
||||
| --- | --- |
|
||||
| `installation` | 安装、升级、平台和依赖兼容 |
|
||||
| `tool_contract` | 实际 MCP Schema、能力和参数限制 |
|
||||
| `failure_partial` | 错误、部分执行、未知副作用与不盲目重试 |
|
||||
| `timeout_cancel` | 实际工具入口超时与取消 |
|
||||
| `process_tree` | 工具创建后代后,正常/超时/取消的回收验证 |
|
||||
| `file_binding` | 已批准文件被替换、截断、增长时的实际消费字节 |
|
||||
| `resource_conflicts` | 同设备/桌面资源互斥 |
|
||||
| `evidence_export` | 导出索引、中文路径、摘要不符与缺失附件 |
|
||||
| `history_uninstall` | 卸载/升级后历史仍可读 |
|
||||
| `secret_redaction` | 配置、命令、输出和回执脱敏 |
|
||||
| `real_task` | 经宿主正常任务的操作、时间线、暂停/恢复、证据和报告 |
|
||||
| `source_review` | 对本次包的源码审查、来源与分发授权核对 |
|
||||
|
||||
仅在声明无相应行为时,`process_tree`、`file_binding` 可 `not_applicable`;无 MCP 时 `tool_contract`、`timeout_cancel` 可不适用;无声明资源时 `resource_conflicts` 可不适用。仍须在 notes 中给出理由,不能把未测写成不适用。其他项目须有真实通过记录。
|
||||
|
||||
更新任何文件后,旧材料会失效。先重跑受影响验证,再用 `--fingerprint` 查看新的内容摘要,并更新记录;不要只刷新摘要来沿用过期结论。握手结束后重新核对内容与市场记录,检查期间改动会使检查失败。最终 ZIP 检查结果另包含实际解压检查的同一份字节的 SHA256,不重新打开原路径来记录替换文件;公开发布时仍需核对固定附件、市场索引与无认证下载字节。
|
||||
|
||||
市场材料检查验证字段、覆盖范围、摘要和证据存在性,不证明声明真实、不替作者确认权利归属,也不自动发布。源码审查和实际业务验收仍由发布方核对;文档、静态检查、握手、SDK 故障自测与真实业务结论分别记录。
|
||||
@@ -0,0 +1,29 @@
|
||||
# ARTEMIS 2.4.5
|
||||
|
||||
本版基于 2.4.4,补齐插件作者管理外部工具、已批准文件与市场审查材料的公共能力。远程客户端 `artemis-client`、市场插件及第三方依赖独立版本化,本次不升版。
|
||||
|
||||
## 更新
|
||||
|
||||
- 新增 `artemis.plugins.sdk.snapshot_file`:按明确批准的 SHA256 读取不可变快照,实际工具消费快照字节,避免校验后原文件被替换、覆盖或截断;默认输入上限 64 MiB。
|
||||
- 新增 `run_process`:固定 argv、工作目录和超时,限制 stdout/stderr 总量,在正常结束、超时与取消后回收自己启动的后代。Windows 先取得 Job Object 归属再启动实际工具;提供稳定错误码,执行结果不明时不声称尚未执行,也不自动重试。
|
||||
- 新增可独立运行的 SDK 故障检查,以及受管工具模板。模板覆盖真实 stdio MCP 调用和宿主附件回读,随源码与官方 Skill 同步分发。
|
||||
- 开发与市场检查共用一份实现。`check_plugin.py --prepare-market` 生成未验证的 `MARKET.json` 草稿;`--market` 检查来源许可、验收材料、候选内容指纹和 MCP 工具声明,并拒绝缓存、私密环境文件及握手期间包内容变化。
|
||||
- 补充模板的 LICENSE、SOURCE.md 和开发说明。市场材料检查仍需结合源码、分发权利与真实业务审查;检查命令通过不会自动发布插件。
|
||||
|
||||
这些辅助接口管理工具生命周期和文件内容绑定;插件仍负责权限范围、业务验收、写操作状态及敏感信息处理。POSIX 使用独立进程组,不将运行器作为恶意程序沙箱。
|
||||
|
||||
## 兼容性
|
||||
|
||||
采用新增 SDK 的插件须声明 `artemis_version: ">=2.4.5,<3.0.0"`,并使用 ARTEMIS 2.4.5 或更新版本的 Python。正式 2.4.4 包不包含该 SDK。
|
||||
|
||||
插件清单和证据协议保持兼容,`MARKET.json` 是独立的审查材料。未使用新增 SDK 的现有插件继续按自身最低版本运行。已独立发布的设备测试插件 `0.5.0+artemis.6` 将修复包含在插件自身,仍可用于正式 ARTEMIS 2.4.4;主程序升级不会自动更新或授权插件。
|
||||
|
||||
## 验证
|
||||
|
||||
Python 默认确定性回归、Ruff 格式与静态检查、质量基线、核心类型检查,以及最终源码 ZIP 的官方源和国内镜像全新安装、生产构建结果,随发布附件 `INSTALL-VERIFICATION.md` 提供。验证记录注明实际 Python、Node/npm、源码提交及 ZIP SHA256。
|
||||
|
||||
SDK 故障检查与模板契约使用合成文件及测试进程,不替代设备、固件升级或用户业务验收。Windows 为本次实际验证环境,POSIX 分支未实测。
|
||||
|
||||
## 升级
|
||||
|
||||
已有安装请等待任务结束,运行 `update-cn.bat` 或 `update.bat` 后重启。新安装下载 `artemis-2.4.5-source.zip`,按 `SHA256SUMS.txt` 校验后启动。请勿直接覆盖旧安装目录。
|
||||
Reference in new issue
Block a user