3a780384d0
refactor(memory): 裁剪与召回收敛到唯一入口 memoryPass
...
把「踢出去(prune)」与「取进来(recall)」从两处各写一遍,收敛为
memoryPass(query, trigger, prune, recall) 单一入口,统一:
- 同一份清洗后的 query(避免噪声带偏相关性打分);
- 同一次 token 预算与召回截断;
- 同一条带 trigger 的审计日志(谁、据什么触发了哪种操作)。
落地:
- 新增 memorypass.go:memoryPass + pruneByQuery(原 pruneOnInput 的执行体);
- pruneOnInput 只解析声明,执行委托 memoryPass;
- stepToolAfter 的裁剪/召回改为一次 memoryPass 调用(去掉重复的 topK 逻辑);
- 抽出 recallText,输入侧 buildTaskMemoryContext 与工具侧 recallTextFor 共用;
- 输入侧召回 query 改用 CleanInput(清洗文本),与裁剪侧同一语义;
- QQ qq_get_history 补齐声明 ContextPolicy=prune + RecallPolicy=auto
(内容类工具:真实聊天正文既当轮用完即裁,又据正文召回)。
测试:新增 memorypass_test.go,锁死 no-op / 两轴同时生效 / 正交不互相触发 /
输入侧用清洗 query。go build/vet 干净,internal/... 全绿,qq 插件模块测试通过。
2026-09-14 23:32:41 +08:00
b792a94b84
feat(memory): 新增可声明的召回轴 RecallPolicy(与 prune 正交)
...
问题:召回(把 L2/L3 相关记忆注入本轮)此前不可声明、也不受任何 SDK 字段
控制——它只在任务开始时对 f.Input 无条件跑一次。于是 qq_get_message 取回
真实正文后只触发 Prune(裁剪),从不触发召回;而中断通知的 meta 文本反而
会去召回(词不对题,命中一堆泛实体)。
改动:
- SDK 新增 RecallPolicy(none|auto) 轴,落在 InjectOptions / ChannelDef /
ToolDef 三个声明面,与 ContextPolicy 正交(裁剪 vs 召回)。默认值与
prune 刻意相反:输入/注入默认 auto(保持既有「每条输入都召回」),
工具默认 none(工具输出多为噪声,按需声明)。
- 内核:recallDeclared 按 注入点 > 通道 > 默认auto 解析;输入侧用它决定
是否注入记忆索引;工具侧 ContextPolicy/RecallPolicy 共用同一份清洗后
query,一次相关性过程分别 prune / recall;召回以 system 消息挂到消息
末尾(同任务内替换而非累加)。
- 管线:proc RPC(inject/register + 校验)、lua 键、io payload 全量透传。
- QQ 插件:中断与 qq 通道声明 RecallPolicy=none(meta 不是内容);
qq_get_message 声明 RecallPolicy=auto(取回正文后据正文召回)。
测试:新增 recallpolicy_test.go(core)与 proc 校验用例;
go build ./... 通过,go test ./internal/... 全通过,SDK 模块与 qq 插件测试通过。
2026-09-14 23:14:38 +08:00
5ea87a498a
chore(vendor): 同步 qq 插件权限身份绑帧修复(sdk cfa72df)
2026-09-14 16:45:17 +08:00
c252915083
feat(webui): 阶段管道改「循环 + 本轮轨迹」,区分工具/输出调用;再砍总览文字
...
jianf:阶段管道像无记忆的单向滑块,但一轮里会多次 toolcall、也可能多次输出;
且没区分 output_* 调用与普通工具调用;总览仍有一大坨文字。
- 阶段管道不再是单向滑块:#
画成 输入 → 行动 ⇄(工具↻) → 输出 → 结束 的循环结构,当前阶段高亮;
下面用一排 chip 记**本轮真实发生过的序列**(on_input 重置、before_toolcall 追加、
after_output 收尾,最多 24 条)。工具调用会反复出现,循环因此可见。
- 区分调用类型:普通工具 chip 前缀 ⚙(青),output_* 输出通道调用前缀 ⇥(accent 色),
两者配色与图标都不同。
- 文字再收缩:删掉「累计:入队/执行/抢占/挂起/背压」整行;队列标签由
「L4 内核独占…」压成 L4/L3/L2/L1/排队(原描述进 title);各段标题压成
「队列」「栈」「拓扑」;KPI 块标签压成 排队/中断/栈/子代理。
顺带(同类问题):CLI /stop 是人在终端当场下的指令,优先级由默认 L1 提到 L3。
2026-09-14 16:31:37 +08:00
7768168dd2
chore(sdk-vendor): 同步 qq 插件的消息合并改动(对应 SDK 仓 a01fe21)
...
本仓 vendored 了 SDK 的部分文件(third_party/homeagent-sdk,经 go.mod replace
引用),其中 example/qq/plugin.go 被跟踪。SDK 仓的 qq 消息合并提交同步过来,
保持 vendored 副本与 SDK 仓一致。
2026-09-14 16:11:22 +08:00
5160d8d4d1
chore(sdk-mirror): qq 插件 1.4.1(输出工具不再受当前会话身份限制)
...
镜像 SDK 仓的插件修复:被子的中断唤醒的一轮里,父带齐 meta 调 output_send__qq 也被
「可信 QQ 会话身份不完整」拒掉;输出改为先放行(目标由 meta 决定),读取类工具仍限当前会话。
2026-09-13 16:03:28 +08:00
cb32032f76
feat(scheduler)!: 中断/排队两类别模型 + 插件声明 L1-L3、L4 内核独占
...
用户澄清推翻了早期设计的三处前提,本提交按新模型重做调度核心(行为有意变化):
1) 类别由注入 API 决定,与通道名无关
- InjectInterrupt* -> TaskInterrupt(带级别,可被严格更高级中断打断)
- InjectText*/InjectInputSync*/内核自循环 -> TaskQueued(无级别,可被任何中断打断)
- 删除按通道名推断的 taskLevel():qq 走 InjectInterruptTextOpts,本就是中断
2) 级别只属于中断
- 插件在 InjectOptions.Priority 声明 L1-L3(空/非法降级 L1,声明 L4 夹到 L3)
- L4 内核独占:新增 raiseKernelInterrupt(panic / selfip);requestKernelPreempt 不夹取
- panic 现在产生一条带 kernel 标记的 L4 中断;L4 自身 panic 不再产生新 L4(防自我放大)
3) 选择结构:四容器固定次序,删除统一比较器
- immediate(抢占者立即运行)-> 中断队列 L4..L1 -> 栈顶(与队头比级别) -> 排队 FIFO
- 删除 pickTaskIndex/taskBefore 与“同级 pending 优先”补丁(根因是抢占者进了队列)
- 中断栈上界改为结构推论 = 4(= 中断级数);删除“超限转 pendingInterrupts”降级
公开 SDK(feature 分支有意新增,纯追加):InjectOptions.Priority + PriorityL1/2/3;
内核 io / proc 桥 / 插件模板同步透传。
设计稿 §2/§3/§4.1/§6.3/§9/§11/§12/§13/§15 按新模型重写。
验收:go build/vet 干净;go test ./... 37 包 ok 0 FAIL;-race 全绿;
e2e(抢占-挂起-恢复)+ 压力(200 排队 + 50 中断,L1/L2/L3 轮转)通过。
2026-09-13 07:00:51 +08:00
d1662e77cf
chore(sdk-mirror): 同步 vendored SDK 到 SDK main(qq 插件重写、browser 会话超时必填、路牌 1.3.0)
...
核心仓 `third_party/homeagent-sdk` 是 SDK 仓的 vendored 副本,内容以 SDK 仓 main 为准
(本仓 `.gitignore` 忽略 example/ 下的未跟踪文件,已跟踪的镜像文件用 `git add -u` 更新)。
本次把镜像追平到 SDK main(`8c10b7e`):
- qq 插件重写(+498 行):`output_send` 回声/自激路径的根因修复与去重;
- browser 示例:交互式会话 `timeout` 由默认 10m 改为**必填**(附参数校验与测试);
- `meta.Version` 1.2.0 → **1.3.0**(SDK v1.2.0 已定版,SDK main 按纪律推进到下一个中版本)。
2026-09-12 20:21:01 +08:00
eba300aec2
chore: 同步 vendored SDK(qq v1.2.0 + plugindev bridge 修复)
...
third_party/homeagent-sdk 同步至 SDK 仓 61f307b:
- fix(plugindev): bridge 模板补 dispatchIO.SetToolBlocks
SDK v0.9.2 给 IOInjector 加了该方法但 C ABI bridge 模板未同步,
导致任何外部插件编译失败(missing method SetToolBlocks)
- feat(qq) v1.2.0: msg_id→get_history 7 天兜底(不缓存正文)
+ qq_list_chats / qq_mark_read 会话列表(按最新消息排序 + 未读数)
+ 中断模板补 fallback 路径与私聊 user_id
.gitignore 补 HarmonyOS 构建工具链缓存(.hvigor-home/ .npm-cache/ .ohpm/),
这些由 HVIGOR_USER_HOME/ohpm 生成,非源码。
go build ./cmd/homed/ 通过。
2026-08-30 17:14:07 +08:00
75447aa7f8
fix(plugins): 全插件审查修复(qq/a2a/memo/calendar/rss/browser)
...
17 个生产插件全量审查:编译/vet 全过、无硬编码密钥、内核
executeToolCall 有 panic recover + 超时兜底。发现并修复:
P1 qq: downloadURL 裸 http.Get 无超时 → 120s client(挂起泄漏)
P2 a2a: inbound http.Server 无超时 → Read 30s/Write 120s/Idle 60s
(慢速连接占用 goroutine)
P5 memo/calendar/rss: 数据持久化直写 → atomicWriteJSON temp+rename
(崩溃截断 JSON 丢全部数据)
P6 qq: 3 处后台 goroutine(已读标记/rcon转发/下载任务)加 recover
(工具调用外 panic 会带崩 homed 进程)
P7 browser: dump-dom failback Kill 后补 wait 回收僵尸进程
已知可接受项:bili output_dir 用户可控(本机单用户)、recoverydiag
db_path 可读任意 sqlite(诊断工具固有权限,argv 传参无注入)。
全部经 plugindev 重打包 v+0.1 安装验证 config_kept=true。
2026-08-26 16:46:06 +08:00
c945eace1a
fix(webui): 附件死锁 + qq 插件文件发送收敛到 output 通道
...
1. webui 附件死锁修复(output_send__webui 发图 60s 超时根因)
EventAgentOutput 订阅者已持 chatMu,附件分支调 addChatMsg(内部
再次 Lock)——sync.Mutex 不可重入导致 Publish 永久阻塞,工具超时、
图片永远发不出来。改为持锁状态下直接操作 chatHistory+persist。
2. qq 插件 image/file 分支收敛到 output 通道
output_send__qq 的 type=image/file 此前只透传 payload 给 CQ 码,
发本地文件必须绕道 upload_group_file 独立工具。现在与 voice 分支
同模式:本地路径拷入 NapCat 共享目录转 file:///app/files/<name> URI,
http(s)/file:// URL 保持透传。upload_group_file 保留作为群文件柜
专用入口。
验证:工具链重编译 → qq.hmap 重打包 → pluginmgr overwrite 安装
(config_kept=true)→ agent 经 output_send__qq 用本地路径发图成功,
mascot.webp 已落共享目录。
2026-08-26 11:14:03 +08:00
1f1233b823
refactor: P0-P3 fixes, C1 cleanup, architecture diagrams, go.work upgrade
...
- P0-1: ProviderError type + ReportStatus for precise 401/403 detection
- P0-2: Remove -config flag from deploy/homeagent.service
- P2-1: 5s debounce on context.go Save()
- P2-2→C1: Delete output_set_channel entirely
- P2-3: Extract mediaDataURL/mediaChat helpers
- P2-4: Dedup defaultSources var
- P3: Delete dead packages (embed/tokenizer/container/snapshot)
- P3: Delete dead functions (messagesToMap, RunStageAll)
- CL: Update .gitignore, docs, Makefile, gojieba removal
- Config: Delete config/config.yaml, update docs
- Arch: Remove EmitOutputTo from emitResponse
- CL-1: go.work 1.19→1.21
- Docs: Add Mermaid architecture diagrams to README
- Docs: Add kernel-rebuild requires plugin-rebuild note to PLUGIN_DEV.md
2026-07-12 11:42:56 +08:00
dad62516a8
fix: openclaw translateAndRegister uses full tool name for LLM visibility
2026-07-10 13:55:03 +08:00
b55f1dcf0e
fix: cap distiller startup scan and switch to formal SDK module dependency
...
- replace vendored third_party/homeagent-sdk with formal module dependency
- keep canonical SDK via go.mod pinned commit
- optimize distiller startup loading to stream recent raw records only
- parse timestamps correctly and cap startup load to 5000 records
- remove quadratic string building in raw record parsing
- restore fast startup while preserving memory pipeline
2026-07-06 20:18:13 +08:00
50e5dec745
feat: converge dynamic plugins onto canonical homeagent-sdk
...
- Separate built-in plugin interface from external plugin interface
- Route dynamic plugin loading through homeagent-sdk/sdk using reflection
- Turn internal/sdk into an enhanced wrapper over canonical SDK types
- Vendor SDK repo snapshot under third_party/homeagent-sdk for stable builds
- Keep internal constructors/adapters for memory, knowledge, llm, settings
- Align dynamic QQ loading with canonical SDK chain
2026-07-06 19:27:51 +08:00