From 934eb4da7d6c96cdfa5a249edaa35c30830b091d Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Sun, 13 Sep 2026 07:18:03 +0800 Subject: [PATCH] =?UTF-8?q?feat(sdk):=20=E5=AF=BC=E5=87=BA=20PriorityL4=20?= =?UTF-8?q?=E2=80=94=E2=80=94=20=E5=86=85=E6=A0=B8=E7=BA=A7=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E7=9A=84=E2=80=9C=E7=AB=8B=E5=8D=B3=E6=89=93=E6=96=AD?= =?UTF-8?q?=E2=80=9D=E8=83=BD=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit L4 的归属此前写成“只有内核(panic/selfip)”,这是不完整的:**内核级插件** (编译期内置插件,如 webui/cli/timer)也需要它来实现中断能力——最典型的例子 就是 WebUI 的终止按钮:用户按下时必须有一条能立刻打断当前任务的中断。 - 新增 `PriorityL4 = "L4"`,注释写明“仅内核级(内置)插件可用”。 - `InjectOptions.Priority` 的注释同步更正:取值 L1..L4,L4 属内核级插件, 外部插件声明 L4 会被内核夹到 L3。 为什么不能给外部插件:否则任何第三方插件都能随时打断用户的一切工作。 夹取有**两道闸**(纵深防御): 1. proc 桥(外部进程唯一入口)一律把 L4 夹到 L3——在这里夹是因为 `source` 是插件自报字段、可以冒名; 2. 内核侧再按 `IsBuiltinPlugin(source)` 判一次。 `source` 约定为 `插件名` 或 `插件名/实例`(webui/),判据取第一段。 兼容性:纯追加,零值仍等价于 L1。 --- sdk/plugin.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sdk/plugin.go b/sdk/plugin.go index cf38db6..f66a789 100644 --- a/sdk/plugin.go +++ b/sdk/plugin.go @@ -81,19 +81,25 @@ type InjectOptions struct { // Priority 声明**中断注入**的优先级(仅 InjectInterrupt* 有意义)。 // - // 取值 "L1"/"L2"/"L3";空等同 L1。L4 由内核独占(panic / 内核事件 selfip), - // 插件声明 L4 会被内核夹到 L3——内核的调度内部属性不接受外部越权。 + // 取值 PriorityL1..PriorityL4;空等同 L1(默认级)。 + // L4 只有**内核级插件**能用(见 PriorityL4 注释);外部插件的 L4 会被夹到 L3。 // // 排队注入(InjectText*/InjectInputSync)没有级别:它们本就是“不需及时处理” // 的那一类,可被任何中断打断。 Priority string } -// 中断优先级取值(插件可用范围)。L4 不在其中:它由内核保留。 +// 中断优先级取值。 +// +// L1..L3 任何插件都可声明;**L4 只有内核级插件**(编译期内置插件, +// 如 cli/webui/timer)才能声明——它用于实现真正的“立即打断”能力, +// 例如 WebUI 的终止按钮。外部插件(走 proc 桥)声明 L4 会被内核夹到 L3。 const ( PriorityL1 = "L1" PriorityL2 = "L2" PriorityL3 = "L3" + // PriorityL4 仅内核级(内置)插件可用;外部插件声明会被夹到 L3。 + PriorityL4 = "L4" ) // ChannelDef 描述通道在记忆计算层的行为,与 ToolDef.NoMemory/Cleaner 语义一致。