docs(plan): 修正 §13.5 的错误判断,建账 §13.13 剩余内联路径

§13.5 之前写的「内核侧未接线」是方向性错误:我把分配方认错了。
实际是**插件侧** putInArena 做 arena.alloc + 写入 + 传 text_ref,内核侧
resolveText 读回。分配在插件侧并非缺口——§13.2 的模型就是「插件经 RPC
向内核申请/归还」,内核独占分配器;procCore.InjectText 拿到普通字符串
也是对的,因为共享内存是跨进程的内部实现、不对插件开发者暴露。

新增 §13.13,把「全量数据交互入共享内存」这个总目标的尾巴显式建账,
区分数据面(要入)与控制面(不该入,几十字节搬进去反而多两次 RPC):

已入:StageContext / 事件环 / tool.invoke / cleaner.invoke /
      output.invoke(本次 §13.6)/ io.injectText(§13.5)
未入:① 媒体块 io.injectMedia / injectMediaSync /
      injectInterruptMedia / setToolBlocks(本地大图 base64 可达数 MB,
      最大一条)② doc.insert / insertWithMedia ③ knowledge.add
      ④ 插件反向调内核读大结果仍内联
This commit is contained in:
JianFeeeee
2026-09-10 21:34:42 +08:00
parent e2672c56d6
commit b09f459aea

65
plan.md
View File

@ -1239,24 +1239,31 @@ SDK 仓 `v1.0.0` / `v1.1.0`。main 的版本路牌现为 `1.2.0`(尚无 tag
**目标**输入通道消息走共享内存
**现状(核实)**基础设施就位但内核侧未接线——
**现状(核实,已实现**
- `injectParams.TextRef SharedRef` `resolveText`corehandler.go:585
在插件内核方向可用内核插件方向的 `procCore.InjectText` 仍直接传
字符串给 `sdk.InjectText` `Alloc/Put` 构造 `TextRef`
- 即只做了半边插件回传文本内核注入还没走共享内存
- 插件侧 `putInArena`模板 `arena.alloc` RPC 写入 region
`SharedRef` `io.injectText` 回传内核 `coreHandler.resolveText`
corehandler.go:585 arena 读出
- **分配在插件侧是符合设计的**不是缺口:§13.2 的模型就是插件经 RPC
向内核申请/归还」,内核独占分配器`procCore.InjectText` 拿到的是普通
字符串因为共享内存是跨进程的内部实现不对插件开发者暴露
- 阈值 `inlinePayloadLimit = 512` 字节小于它走内联 JSON省一次 RPC
超过才 Alloc这是有意为之不是残留
**实施**
1. InputChannel Slotsource/channel/text/blocks 写入 arena
1. InputChannel Slotsource/channel/text/blocks 写入 arena
2. 插件消费后设 DONE
3. 同步注入 RPC + SharedRef 需要接线内核侧
3. 同步注入走 RPC + SharedRef`callWithText`
4. 异步注入改写 arena + eventfd
**验证**
- [ ] 真实 QQ 消息注入测试
- [ ] git commit -m "feat(shm): input channel lane" 未提交内核侧待接线
- [x] 模板 `callWithText` payload `text_ref` payload 走内联
- [ ] 真实 QQ 消息注入测试需生产部署后验证
- [x] git commit -m "feat(shm): input channel lane"2bc813b基础设施
**遗留(与 13.5 同类的未入内存路径)** §13.13
### 13.6 OutputChannel lane
@ -1360,3 +1367,43 @@ SSE Last-Event-ID → 超时 → api 状态码 → renderAll 增量 → XSS 消
- [ ] 图查询返回媒体节点
- [ ] git commit -m "feat(l3): native multimodal nodes/edges"
### 13.13 剩余内联大 payload 路径(「全量数据交互入共享内存」的尾巴)
**目标**所有**数据面**交换都走共享内存RPC 只传偏移描述符SharedRef)。
共享内存是跨进程的内部实现不对插件开发者暴露SDK 公开 API 仍是
string / map / slice)。
**已经走共享内存的**
| 通道 | 机制 |
| --- | --- |
| StageContext | 区内 segment + `WriteAll/ReadInto` |
| 事件环 | 区内 segment + eventfd 通知 |
| tool.invoke 参数/结果 | `Frame` / `ResultRef`(§13.3 |
| cleaner.invoke 输入/结果 | `Frame` / `TextRef`(§13.4 |
| output.invoke 参数 | `Frame`(§13.6 |
| io.injectText 系列 | 插件侧 `putInArena` `text_ref`(§13.5 |
**尚未入内存(按风险排序,都是数据面)**
1. **媒体块`io.injectMedia` / `injectMediaSync` / `injectInterruptMedia`
/ `io.setToolBlocks`**——`blocks` 内联在 RPC JSON
`ImageURL.URL` / `AudioURL.URL` 对本地生成的图/音频是 **base64 data URL**
本地大图 base64 后可达数 MB是目前最大的一条内联路径
待做blocks 序列化后 `putInArena` `blocks_ref`内核侧读回
2. **`doc.insert` / `doc.insertWithMedia`**——文档全文内联文档可达几十 KB
MB待做 1`doc_ref`
3. **`knowledge.add(name, content)`**——知识正文内联同上
4. **反向工具结果kernel → 插件)**目前只有正向插件内核
`ResultRef`插件反向调内核读大结果时仍是内联
不需入内存的控制面小报文`plugin.init.Config``tool.register` def
`settings.*``lifecycle.*``arena.alloc/free` 自身)——它们本身就只有
几十~几百字节搬进共享内存反而多两次 RPC
**验证**
- [ ] 媒体块走共享内存本地大图注入不再爆管道
- [ ] 文档/知识正文走共享内存
- [ ] git commit -m "feat(shm): remaining data-plane payloads via shared refs"