From 87241bc4ffa3b25091e7c4b53d498268a246f297 Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Sun, 13 Sep 2026 14:40:35 +0800 Subject: [PATCH] =?UTF-8?q?docs(sdk):=20=E5=90=8C=E6=AD=A5=201.3.0=20?= =?UTF-8?q?=E8=83=BD=E5=8A=9B=E8=AF=B4=E6=98=8E=E4=B8=8E=E5=8F=91=E7=89=88?= =?UTF-8?q?=E5=8F=A3=E5=BE=84=E5=88=B0=E5=8F=91=E5=B8=83=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 发布线是 SDK 1.3.0 的产物来源,README 停在内核 1.2.0 的口径会让插件作者 按过期说明写代码。只捡文档,不动本线 meta.Version(这里必须恒为 1.3.0)。 --- README.md | 42 ++++++++++++++++++++++++++++++++++++++++-- README_EN.md | 24 ++++++++++++++++++++++-- 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e0ed1ee..b583aab 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ HomeAgent 插件开发 SDK,用于构建与 HomeAgent 平台交互的智能插 ## 版本与兼容性 -当前:**SDK 1.2.0**(需内核 **1.2.0+**)。 +当前:**SDK 1.3.0**(需内核 **1.3.0+**)。 **版本号跟随内核的中版本,patch 位恒为 `.0`**: @@ -12,11 +12,15 @@ HomeAgent 插件开发 SDK,用于构建与 HomeAgent 平台交互的智能插 |---|---| | 1.0.0 / 1.0.1 / … / 1.0.4 | 1.0.0 | | 1.1.0 / 1.1.1 / … / 1.1.N | **1.1.0** | -| 1.2.0 起 | 1.2.0 | +| 1.2.0 / 1.2.1 / … / 1.2.N | **1.2.0** | +| 1.3.0 起 | **1.3.0** | 内核的 patch 位专用于 bugfix 与漏洞修复,不碰公开接口,所以 SDK 版本号不跟着动—— 否则你要么被迫跟版、要么怀疑自己版本过时,而接口其实一个字都没变。 +因此 **SDK 仓在一个中版本里只发一次**(`vX.Y.0`),核心的 `v1.3.1`/`v1.3.2`/… 不伴随 SDK 发版。 +(2026-09-13 曾误发过 `v1.3.1`,已撤回 —— patch 位带非零数字的 SDK tag 都是错误的。) + **1.0.x 插件升到 1.1.x:不需要改代码,也不需要重编。** 1.1.0 的新增全部是 「插件调用、内核实现」方向,不调就不受影响(已用 SDK 0.9.2 编的旧 `plugin.bin` 实测验证:在新内核上直接建链通过,因为握手校验的是 `ProtocolVersion`、不是 SDK 版本)。 @@ -28,6 +32,40 @@ HomeAgent 插件开发 SDK,用于构建与 HomeAgent 平台交互的智能插 所以 `plugin.bin` 必须用配套的 `hmapdev` 重编后与内核**同批**安装——否则握手时协议版本 不匹配会被拒绝(错误信息会明确提示用配套 hmapdev 重编,不会静默降级)。 +## 1.3.0 新增:注入优先级与动态输出通道 + +### 注入优先级(`InjectOptions.Priority`) + +插件可以声明**自己这次注入的中断级别**,内核按四级阶梯调度: + +| 级别 | 常量 | 谁用 | +|---|---|---| +| L1–L3 | `PriorityL1` / `PriorityL2` / `PriorityL3` | 插件按紧急程度自选(L1 最低) | +| L4 | `PriorityL4` | **保留给内核与内核级插件**(内核自身事件、内核级通道) | + +- 零值(不声明)与旧的注入调用**完全等价**:按排队处理,不抢占任何正在执行的回合 + ⇒ 存量插件不需要改一行、也不需要重编。 +- 高优先级中断可以**抢占**低优先级正在跑的回合;被抢占的回合挂起、之后恢复继续 + (现场保存/恢复对插件透明)。 +- 排队输入**没有级别**:排队就是排队,任何中断都能插到它前面。 + +### 动态输出通道(`UnregisterOutputChannel`) + +`RegisterOutputChannel` 注册的通道此前只增不减。对**随资源生灭**的通道(典型:远程设备 +一台设备一个输出通道),设备掉线后通道还在,模型会继续对一个死通道发消息并以为发成功了。 + +1.3.0 起成对提供: + +| API | 用途 | +|---|---| +| `UnregisterOutputChannel(name)` | 注销输出通道(含能力表与工具) | +| `OutputChannelUnregistrar` / `SetOutputChannelUnregistrar` | 插件侧拿到注销句柄(内核注入) | + +⚠️ 通道名要**由插件派生得又合法又唯一**(外部 id 不能直接当通道名)—— +设备 id 这类外部输入可能带 `/` 等字符,而通道名会拼进 LLM 函数名 `output_send__`, +违规会让**整条 LLM 请求**被上游拒绝(2026-09-13 生产事故:`device/` 导致全量对话 403)。 +派生规则与约束见下方「输出通道」一节。 + ## 注入行为与上下文裁剪(1.2.0) 「记不记入记忆」与「要不要据此裁剪上下文」这两件事,原先只有 `ToolDef` 能声明; diff --git a/README_EN.md b/README_EN.md index 222f034..d717c70 100644 --- a/README_EN.md +++ b/README_EN.md @@ -4,7 +4,7 @@ Plugin development SDK for building intelligent plugins that interact with the H ## Version and Compatibility -Current: **SDK 1.2.0** (requires kernel **1.2.0+**). +Current: **SDK 1.3.0** (requires kernel **1.3.0+**). **The version tracks the kernel's minor version, with the patch position pinned at `.0`**: @@ -12,13 +12,33 @@ Current: **SDK 1.2.0** (requires kernel **1.2.0+**). |---|---| | 1.0.0 / 1.0.1 / … / 1.0.4 | 1.0.0 | | 1.1.0 / 1.1.1 / … / 1.1.N | **1.1.0** | -| 1.2.0 onward | 1.2.0 | +| 1.2.0 / 1.2.1 / … / 1.2.N | **1.2.0** | +| 1.3.0 onward | **1.3.0** | The kernel's patch position is reserved for bugfixes and vulnerability fixes, which never touch the public interface, so the SDK version has no reason to move with it — otherwise you would either be forced to chase releases or suspect your version is stale, when not one character of the interface has changed. +The SDK repository therefore publishes **exactly once per minor version** (`vX.Y.0`); kernel patches +such as `v1.3.1` do not trigger an SDK release. (A `v1.3.1` tag was mistakenly cut on 2026-09-13 and +has been withdrawn — any SDK tag with a non-zero patch position is wrong.) + +## New in 1.3.0: Injection Priority and Dynamic Output Channels + +- **`InjectOptions.Priority` / `PriorityL1`–`PriorityL4`** — a plugin declares the interrupt level of + its own injection; the kernel schedules L1–L4, where **L4 is reserved for the kernel and + kernel-level plugins**. The zero value is fully equivalent to the old three-argument call + (queued, never preempting), so existing plugins need neither a code change nor a rebuild. + Queued input has no level: anything can jump ahead of it. +- **`UnregisterOutputChannel` / `OutputChannelUnregistrar` / `SetOutputChannelUnregistrar`** — + channels that die with their resource (one channel per remote device) can now be unregistered; + previously they lingered and the model kept "successfully" sending into a dead channel. +- **Channel names must be legal and unique.** The name is spliced into the LLM function name + `output_send__`, so it may only contain `[A-Za-z0-9_-]`. A real production incident + (2026-09-13): `device/` made every LLM request fail with 403. Derive channel names from + external IDs — never use the raw ID. + **Upgrading a 1.0.x plugin to 1.1.x: no code changes, no rebuild.** Everything added in 1.1.0 is in the "plugin calls, kernel implements" direction, so not calling it means not being affected (verified with an old `plugin.bin` built against SDK 0.9.2: it handshakes fine on the new kernel,