8cd884027f
docs: 项目状态与 plan 同步到 v1.1.1,vendored SDK meta 注释对齐 SDK 仓
...
三处失同步,都会让读者拿到错的现状:
## README / README_EN
「项目状态」段的最新条目还停在 v1.0.0,而 1.1.0 与 1.1.1 都已发布。补上两条,
并把顶部特性摘要与下载段的 Windows 安装器版本号一起更新(那里写死了
`HomeAgent_v1.0.0_*_win64.exe`,照着它去 release 页面找是找不到文件的)。
## plan.md §12.1
标题还是「待用户决策后执行」,而四个决策点早已全部落定并执行完毕。改为已完成,
并记下实际演进已超出当初设想的地方(这些后来都写进了 docs/git-branching.md):
发布分支改为一个中版本一条、三级通道由 tag 区分、SDK 版本跟随核心中版本且
patch 位恒为 .0、beta 阶段不发 SDK、main 永不作发版分支。
同时修掉一处会误导追溯的陈述:§12.1 原文说 `v1.0.0` tag 指向 feature 分支中间点
`670efcd` 需要重打——那件事早已做完,现在指向 `release/v1.0.x` 上的 `9b92a04`。
## plan.md §12.5
「无 Windows 真机验证」这条仍然成立,但补一句区分:Windows NSIS 安装器从 v1.0.0
起就随每个正式版作为 release 资产发布了。**能打出包 ≠ 包里的共享内存/事件对象在
真机上能跑通**,混为一谈会让人以为这项已经关闭。
## vendored SDK meta
主仓跟踪 `third_party/homeagent-sdk/meta/meta.go`,而该文件在 SDK 仓 main 上刚补了
版本路牌的说明注释。两仓这份文件必须逐字一致——否则下次谁改了哪边说不清,
而它正是「两仓中版本对齐」这条纪律的载体。仅注释差异,无行为变化。
2026-09-06 10:56:42 +08:00
e4be9667ec
chore(meta): main 的版本路牌推到 1.2.0
...
按 docs/git-branching.md §2.1,main 的 meta.Version 始终是**下一个未发布中版本**。
1.1.x 线正在发布中(release/v1.1.x 承载 v1.1.0 / v1.1.1),所以 main 指向 1.2.0。
它标记「main 正在积攒 1.2 的东西」,不表示 1.2.0 已经存在——1.2.0 没有任何 tag。
已发布的版本号一律看对应的 release/vX.Y.x 分支与 tag。
两仓同步:SDK 仓 main 也是 1.2.0(SDK 版本跟随核心中版本,见 §七.1),
而 release/v1.1.x 上 SDK 定版 1.1.0。
**此 commit 不 cherry-pick 到发布分支**(§五:版本号 bump 不跨分支搬)。
2026-09-06 09:54:55 +08:00
687e5655bc
feat(sdk): 多模态贯通插件边界——公开接口、内核桥接与统一输入主干
...
记忆系统在 1.1.0 支持了二进制多媒体节点,但那条链路只对**内核自己**开放:
用户在 qq 发图能落进 CAS、能被记忆引用,而插件调 Commit / DocMemory().Insert
交进来的媒体一律无处安放。原因是三层都断着,且**每一层都不报错**。
## 一、公开 SDK:补上媒体的表达能力(全部新增,无签名变更)
- `Triple` += `SentenceText`、`MediaDigests`
- `Doc` += `MediaDigests`、`Attachments`;新增 `MediaAttachment`
- `TextEvent` += `Attachments`
- `DocMemoryAPI` += `InsertWithMedia`
- `IOInjector` += `InjectInputMedia` / `InjectInputMediaSync` / `InjectInterruptMedia`
- `PluginSDK` 补上一直缺失的 `SetToolBlocks` 包装(接口里有、便捷方法里没有)
`MediaAttachment` 一个类型服务两个方向:给 `Data`+`MIME` 是新内容(CAS 按字节
去重),只给 `Digest` 是引用已有内容。读路径**只回元数据不回字节**——一次检索
可能命中几十份媒体,全塞回去会把跨进程消息撑爆。
媒体注入不能搭 `SetToolBlocks` 的车:那个方法只在工具处理函数内部可用,且媒体
要等下一条 tool message 才到模型手上。插件主动发起一轮带媒体的对话、以及中断
注入,需要自己的签名,且媒体在**本轮**就送到模型。
## 二、内核桥接层:原先在静默裁字段
`internal/sdk/memory_impl.go` 此前只搬自己认识的几个字段,其余丢弃且返回 nil:
- 图记忆丢 `Confidence`/`SubjectType`/`ObjectType`/`SentenceText`,又走 `Commit`
而非 `CommitWithMedia`(不回 sentenceIDs)→ 媒体绑定链 `SentenceText → sentences
→ sentence_id → media_refs` 一步都走不通,插件即便按格式写好标记也永远挂不上;
- 知识库 `Query` 只回 ID/Title/Content,`Insert` 只写这三个;`Remove` 不解引用,
于是那些媒体永久处于「被引用」状态,GC 收不掉、磁盘只增不减
(内核的归档路径 `releaseDocMedia` 做了这一步,插件路径漏了同一步)。
规则改为:**内部结构有的字段一律透传**。标记格式处理作为包级私有辅助留在桥接
层自己手里,但必须与内核 `mediaSummaryForEvent` 字节兼容——两边要能互读对方
写下的标记。
标记插入必须在 `ds.Insert` **之前**(向量索引取 `Summary + " " + Content`,
之后补的标记检索不到),引用绑定必须在**之后**(owner_id 是 Insert 生成的 ID)。
## 三、跨进程链路:不接线就是全体外部插件编译失败
`go test` 直接把这一层拍出来了——`procIO does not implement sdk.IOInjector`。
公开接口加方法后,生成模板不跟上,**每个外部插件都编不过**,是硬失败不是软降级。
六处接线:`protocol.go` 四个 method 常量、`capability.go` 能力归属、
`corehandler.go` 四个分派分支、`proc_core.go` 委托、`proc_main.go.tmpl` 模板侧
实现、以及三个测试替身。
## 四、统一输入主干:把模态从「函数选择」降级为「字段」
`processTextInput` / `processMediaInput` 合并为 `processInput`。这个分叉是历史
产物而非设计:`processTextInput` 本来就处理媒体(`bindEventMedia` +
`mediaSummaryForEvent`,与媒体路径尾部完全相同),`process()` 只看
`stageCtx.Extra["media_blocks"]`、根本不认识 `evt.Type`。模态是输入的**属性**,
不是输入的**种类**。
媒体路径由此获得它一直缺的六项:去重、`no_memory`、通道 `Cleaner`、中断语义、
`_consolidation_` 路由、正确的 `EventRawInput`。
最后一项是个真 bug:媒体路径发布 `"content": evt.Payload`(一个 map),而
`webui/handler.go` 断言 `.(string)` → 断言失败、`content == ""`、提前返回。
**用户发的图从来没出现在 WebUI 聊天记录里。**
`media_blocks` 同时接受 `[]agentAPI.ContentBlock` 与 `[]pubsdk.ContentBlock`:
字段一致但 Go 不自动转换,只认一种的后果是另一种被静默丢弃。
## 五、模型可调用的三个工具
`memory_commit` 的 `sentence_text` **从未暴露给模型**,而它是绑定链上的必经环节;
连同 `media_digests` 一起补进 JSON schema 与工具文档。`doc_commit` 加
`media_digests`。`doc_query` 把关联媒体单独一行附在结果末尾(正文按 2000 字截断,
标记通常就在尾部)。
标记由**内核**生成而非插件/模型拼装:要求调用方知道格式,等于让一个拼写错误
静默切断引用绑定,而全链路无人报错。
## 六、WebUI 上传走真实媒体链路
图片/音频读回字节拼 data URL 注入 `media_blocks`(8MB 上限,超限退回按路径处理)。
此前只注入一句「文件已保存到 <路径>」,指望模型自己调 `files_read`——但那返回
文本,图片字节对模型永远不可见。附件类型识别扩展到 audio 并在缺 Content-Type
时按扩展名兜底(判错不只是卡片样式问题,图片被当普通文件就进不了视觉链路)。
## 测试
- `internal/sdk/memory_impl_test.go`(12 例,此前该包**没有任何测试文件**)
- `internal/agent/core/inputunify_test.go`(统一主干 + 双静态类型 + 三工具媒体)
- `third_party/homeagent-sdk/sdk/stress_test.go`(13 例并发压测)
压测抓到两处**真**竞态(不是理论风险):`PluginSDK` 的 API 字段与 `autoRestart`
无锁,而写方(内核注入 API、插件 `SetAutoRestart`)与读方(插件后台 goroutine
注入、内核 registry 读 `AutoRestart`)天然跨 goroutine。加 `apiMu` 修掉;约定
只在持锁期间取字段值,取完即释放再调用——持锁调用会把 `InjectInputSync` 这类
阻塞到 agent 回复(可达数分钟)的方法与 `SetIOInjector` 串起来,让插件重载卡死。
测试还抓出两个自身缺陷:`bindDocMedia` 把同一份媒体数两次(`AddRef` 幂等所以表
是对的,但日志说「绑定 2 个」而实际 1 条——误导后续排查),以及用单字符实体名
时 `validEntityName` 静默跳过、`Commit` 返回 nil 却什么都没写。
存量插件不需要改一行也不需要重编:新增方法由插件调用、内核实现,不调就不受影响。
17 个 example 插件源码零改动通过类型检查。
2026-09-06 09:51:31 +08:00
670efcd426
sdk: 同步 SDK 仓 meta 到 1.0.0(vendored 侧)
...
SDK 仓的 5ed8d65 在主仓这边的对应提交。主仓经 replace 引用
third_party/homeagent-sdk,其 sdk/ 与 meta/ 由主仓一并跟踪
(只有 example/ 与 tools/ 被 .gitignore 忽略)。
2026-09-02 23:02:26 +08:00
14f3605f6e
chore: sdk v0.9.2 vendored副本同步 + go.mod 依赖更新
...
- third_party/homeagent-sdk/meta/meta.go: 0.9.1 → 0.9.2
- go.mod: require v0.9.2(replace 保留,指向本地 vendored 目录确保可编译性)
- CoreVersion 同步更新
2026-08-27 09:36:49 +08:00
ae42e486de
feat(pluginmgr): 插件更新接口(upgrade/downgrade 保留配置)+ skill_install overwrite
...
内核 Registry 拆出 StopAndUnload:
- 停止并从注册表移除插件但保留 config_<name> 表
- 不触发 onRemove 回调(那是删除专用语义)
- RemovePlugin 改为追加清理配置表示清除,更新场景调 StopAndUnload
pluginmgr:
- installFromData/installFromURL/installFromPath 加 overwrite 参数
- 已存在+overwrite=true:StopAndUnload→备份旧目录→解压新包→失败回滚→
返回 action=upgraded/downgraded/reinstalled+previous_version+config_kept
- 已存在+overwrite=false:返回 error+hint(指向 overwrite 用法)
- cmpVersion 点分版本号数字比较(非字典序)
- 测试覆盖:首次安装→重装拒绝→升级保留配置→降级→失败回滚
skill_install 加 overwrite 参数:
- 同名技能存在时先卸载旧实例+删除目录再安装新包
SDK PluginMgr 接口同步加 StopAndUnload(name string) error
工具链 plugindev 已重建到 /usr/local/bin(7/29→8/25 版本)
QQ 插件诊断日志版(webhook recv 到达+isAtBot 失败日志)已打包并
通过 upgrade 接口热更新部署,配置保留验证通过。
2026-08-25 22:02:17 +08:00
2089d41c0f
sync: 同步 SDK PluginMgr API 与 dispatch 48/49/50 (vendored 副本)
2026-08-16 18:44:28 +08:00
0d963ed86f
sync: 同步 SDK meta.go CABINumMin 兼容修复(与 SDK 仓一致)
2026-08-15 17:26:33 +08:00
710b1afdf9
C ABI v2: invoke_stage 写回 + ABI 版本对齐核心版本号 (v0.9.0)
...
- C ABI invoke_stage 增加 result 输出参数,外部插件 stage 回调可将修改后的
StageContext(RawMessage/LLMText/FinalText/Response/ToolResults) 写回内核
- ABI 标识版本改为字符串 semver 与核心 Version 对齐(ABIVersion="0.9.0"),
C 层协商用派生整数 CABINum=900(major*100+minor),不再使用独立数字编码
- version_min 保证 v0.8.x(800) 旧插件向后兼容可加载
- 修复工具循环 zen 兼容补位误伤首轮 system 上下文(仅尾部为 assistant/tool 时补位)
- 更新 README 项目状态说明
2026-08-15 15:38:57 +08:00
3a5a16c916
bump version to v0.8.0
2026-07-29 15:45:24 +08:00
a899d777c3
sdk: embed non-toolchain SDK in third_party, add NoMemory/Cleaner support
...
- Embed sdk/, example/, meta/, go.mod from homeagent-sdk (no .git)
- Core .gitignore excludes SDK toolchain: bin/, tools/, package/
- RegisterInputChannel + ChannelDef(NoMemory, Cleaner) in SDK
- IOManager input channel registry with GetInputChannelDef
- eventloop: apply channel Cleaner/NoMemory to interrupt text
- context engine: channelDefLookup applied in textForVector
- document store: ChannelCleaner param for archive functions
- All callers/adapters updated with ChannelDef{} default
2026-07-29 14:48:23 +08:00