From 2aab90c508c222678d5b360cda64918e9775a581 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 19 Oct 2026 22:09:09 +0800 Subject: [PATCH] =?UTF-8?q?fix(plugins):=20=E5=86=85=E7=BD=AE=E6=B8=85?= =?UTF-8?q?=E5=8D=95=E7=BB=88=E5=AE=A1=2015=20=E2=86=92=2013=20=E2=80=94?= =?UTF-8?q?=E2=80=94=20kbtree/multimodal=20=E7=BF=BB=E6=A1=88=E5=8A=A0?= =?UTF-8?q?=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 翻案依据(逐方法对照公开 SDK,非方法名 grep) 初判把 kbtree/multimodal 归入"只用公开 SDK",错了。两边的 s.Knowledge() / s.LLM() **同名但接口面不同**: - kbtree 需要 KnowledgeAPI.Subtree/CategoryCounts/SearchIn/Categories 与 KnowledgeTreeView/KnowledgeCategoryCount 类型 —— 公开 KnowledgeAPI 只有 Search/Add/List,树视图类型公开面根本没有 - multimodal 需要 LLMAPI.Chat + LLMMessage/LLMContentBlock —— 公开 LLMAPI 只有 ListSources/SetSource/CurrentSource,没有 Chat 外置它们 = OCR/看图/转写、知识树浏览静默失效。 ## 最终内置 13 个 cli webui agentcli healthcheck pluginmgr seq remotedevice clawhubadapter kbtree multimodal cfgmgr skillmgr seemedia 外置 5 个(SDK 仓 example/ 已提供工程并已部署验证): cmd localuse mcp(本轮)+ ai_image files(此前)+ timer(更早) ## 文档同步(中英 6 份) 数量 11 → 13;判定标准小节补「终审翻案」与教训: **判外置与否必须逐方法对照公开接口,同名方法不等于同面。** 验证:go build/vet/test 全绿;生产实例已部署新内核 + 新插件包, 四个按需插件经 plugin_start 拉起、工具全部注册(cmd_run / local_screensee / mcp_* / files_edit_line 实核)。 --- README.md | 4 ++-- README_EN.md | 4 ++-- assets/docs/en/ARCHITECTURE.md | 20 ++++++++++++++++---- assets/docs/en/OVERVIEW.md | 2 +- assets/docs/zh/ARCHITECTURE.md | 17 +++++++++++++---- assets/docs/zh/OVERVIEW.md | 2 +- internal/plugins/all.go | 18 +++++++++++++++--- 7 files changed, 50 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 2d19543a..e448cd91 100644 --- a/README.md +++ b/README.md @@ -235,7 +235,7 @@ internal/ ├── memory/ 三层记忆:Graph(SQLite) / Document(JSON+TF-IDF) / Text(JSONL) + StaticEmbedder(预训练词嵌入/TF-IDF回退) + CleanTemplateText(去模版) ├── knowledge/ 知识库(文件系统 + TF-IDF) ├── plugin/ 插件注册表 + 子进程加载器(stdio RPC + 共享内存段 + 事件环) -├── plugins/ 内置 11 个插件(webui/cli/agentcli/cfgmgr/healthcheck/pluginmgr/clawhubadapter/remotedevice/skillmgr/seemedia/seq)—— 判定标准见 ARCHITECTURE「内置插件的判定标准」 +├── plugins/ 内置 13 个插件(webui/cli/agentcli/cfgmgr/healthcheck/kbtree/multimodal/pluginmgr/clawhubadapter/remotedevice/skillmgr/seemedia/seq)—— 判定标准见 ARCHITECTURE「内置插件的判定标准」 ├── sdk/ PluginSDK(Tool/Stage/Event 三通道) ├── config/ SQLite 配置中心 ├── events/ 事件总线 @@ -390,7 +390,7 @@ make install # 安装到系统 本项目的 AGPL。因此**外部插件不是本项目的衍生作品**,作者可自行选择许可(含闭源、商业、私有), 既不必同许可、也不受 §13 网络条款约束。第三方插件生态的安全与活跃正建立在这条之上。 -边界很清楚:**AGPL 覆盖内核与随包内置插件**(`homed`、`internal/`、`internal/plugins/` 下 11 个内置插件); +边界很清楚:**AGPL 覆盖内核与随包内置插件**(`homed`、`internal/`、`internal/plugins/` 下 13 个内置插件); **MIT 覆盖公开 SDK**(`sdk/`,`go.mod` 零外部依赖、只依赖 Go 标准库,不引用内核任何代码)。 子进程隔离在这里不重要了——决定许可的是被链接的 SDK 代码本身,而它是 MIT。 diff --git a/README_EN.md b/README_EN.md index d9d285e7..0d208769 100644 --- a/README_EN.md +++ b/README_EN.md @@ -216,7 +216,7 @@ internal/ ├── memory/ Three-layer memory: Graph(SQLite) / Document(JSON+TF-IDF) / Text(JSONL) + StaticEmbedder(pretrained word embedding/TF-IDF fallback) + CleanTemplateText(de-template) ├── knowledge/ Knowledge base (filesystem + TF-IDF) ├── plugin/ Plugin registry + subprocess loader (stdio RPC + shared memory segment + event ring) -├── plugins/ 11 built-in plugins (webui/cli/agentcli/cfgmgr/healthcheck/pluginmgr/clawhubadapter/remotedevice/skillmgr/seemedia/seq) — see ARCHITECTURE "which plugins stay built-in" +├── plugins/ 13 built-in plugins (webui/cli/agentcli/cfgmgr/healthcheck/kbtree/multimodal/pluginmgr/clawhubadapter/remotedevice/skillmgr/seemedia/seq) — see ARCHITECTURE "Which Plugins Stay Built-in" ├── sdk/ PluginSDK (Tool/Stage/Event three channels) ├── config/ SQLite config center ├── events/ Event bus @@ -416,7 +416,7 @@ private included), with no same-license obligation and no §13 network clause. T vitality of the third-party plugin ecosystem rest on this. The boundary is clean: **AGPL covers the kernel and the bundled plugins** (`homed`, `internal/`, -the 11 built-in plugins under `internal/plugins/`); **MIT covers the public SDK** (`sdk/`, whose +the 13 built-in plugins under `internal/plugins/`); **MIT covers the public SDK** (`sdk/`, whose `go.mod` has zero external dependencies and imports only the Go standard library — it never references any kernel code). Process isolation is beside the point here — what decides the license is the linked SDK code itself, and that code is MIT. diff --git a/assets/docs/en/ARCHITECTURE.md b/assets/docs/en/ARCHITECTURE.md index 8f1c3a82..ca2daa35 100644 --- a/assets/docs/en/ARCHITECTURE.md +++ b/assets/docs/en/ARCHITECTURE.md @@ -318,7 +318,7 @@ VM built-ins: `json.encode` / `json.decode` / `log` / `http_get` / `http_post`. | Method | Registration Mechanism | Compilation | Usage | |--------|----------------------|-------------|-------| -| Built-in | `init()` → `RegisterFactory` | `internal/plugins/` compiled into kernel | webui/cli/agentcli etc. (11 total; see the criteria section below) | +| Built-in | `init()` → `RegisterFactory` | `internal/plugins/` compiled into kernel | webui/cli/agentcli etc. (13 total; see the criteria section below) | | External subprocess plugin | Handshake + stdio JSON-RPC reverse registration | `hmapdev build` → `plugin.bin` (ordinary Go binary) | qq/browser/files etc. | | Lua script plugin | Execute `main.lua` to register tools | No compilation, takes effect after restart/reload | luademo etc. | | SKILL plugin | Parse `SKILL.md` | Markdown definition | Loaded via clawhubadapter | @@ -372,7 +372,19 @@ Counter-examples (externalized, because public capabilities suffice): | Plugin | Actual dependencies | |---|---| | timer | RegisterTool + Settings + InjectText (public) | -| ai_image / files / cmd / kbtree / localuse / mcp / multimodal | RegisterTool + Settings (+ public APIs such as s.Knowledge()) | +| ai_image / files / cmd / localuse / mcp | RegisterTool + Settings (+ public RegisterStage) | + +> ★ Reversal on final review (2026-10-19, method-by-method comparison against +> the public SDK brought two back): **kbtree** needs +> `KnowledgeAPI.Subtree/CategoryCounts/SearchIn/Categories` — the public +> `KnowledgeAPI` only has `Search/Add/List`, and the public SDK lacks the +> `KnowledgeTreeView`/`KnowledgeCategoryCount` types. **multimodal** needs +> `LLMAPI.Chat` + `LLMMessage`/`LLMContentBlock` — the public `LLMAPI` only +> has `ListSources/SetSource/CurrentSource`. Both were initially misjudged as +> "public-only" because `s.Knowledge()`/`s.LLM()` exist on both sides **with +> the same names but different surfaces**. Lesson: externalization decisions +> require method-by-method comparison against the public interface, not name +> matching. > ⚠️ Both copies existing at once is forbidden: `loadOne` checks the built-in > factory table first and never looks at the external `plugin.bin` if it hits @@ -641,7 +653,7 @@ internal/ │ ├── registry.go — Registry + lifecycle │ ├── dynamic.go — Load-channel dispatch (proc / lua / skill); .so only remains to error loudly │ └── manifest.go — plugin.json metadata -├── plugins/ — Built-in plugin implementations (11; see "Which Plugins Stay Built-in") +├── plugins/ — Built-in plugin implementations (13; see "Which Plugins Stay Built-in") │ ├── all.go — Blank imports (**the single authoritative list**; edit only this) │ ├── webui/ — HTTP server + embedded SPA │ ├── cli/ — Unix socket CLI @@ -655,7 +667,7 @@ internal/ │ ├── seemedia/ — Direct media view │ ├── seq/ — Sequence orchestration │ ├── data/ plugin_data/ — Plugin static assets (non-Go, shipped with the kernel) -│ ├── kbtree/ cmd/ localuse/ mcp/ multimodal/ ai_image/ files/ +│ ├── cmd/ localuse/ mcp/ ai_image/ files/ │ │ — Source remains but **not listed in all.go**: externalized │ │ on 2026-10-19 as .hmap packages (projects in the SDK repo's │ │ example/); directories to be removed once external projects stabilize diff --git a/assets/docs/en/OVERVIEW.md b/assets/docs/en/OVERVIEW.md index 2be88956..2ccfa145 100644 --- a/assets/docs/en/OVERVIEW.md +++ b/assets/docs/en/OVERVIEW.md @@ -100,7 +100,7 @@ Code is in the project root, implemented in Go. Core functionality is operational. Plugin system and SDK are ready for independent external plugin development. -- Built-in plugins (11): webui / cli / agentcli / cfgmgr / healthcheck / pluginmgr / clawhubadapter / remotedevice / skillmgr / seemedia / seq +- Built-in plugins (13): webui / cli / agentcli / cfgmgr / healthcheck / kbtree / multimodal / pluginmgr / clawhubadapter / remotedevice / skillmgr / seemedia / seq - Criterion: **a plugin stays built-in only if it requires internal-SDK-only capabilities**; everything else ships as an .hmap external plugin (see ARCHITECTURE) - External plugin examples ([homeagent-sdk](https://github.com/JianFeeeee/homeagentsdk) repo `example/`, both Go and Lua types): qq / files / a2a / ai_image / bili / browser / calendar / editdoc / memo / music / ocr / rss / sanitizer / weather / luademo - Distribution: `.hmap` plugin package format, installable via WebUI diff --git a/assets/docs/zh/ARCHITECTURE.md b/assets/docs/zh/ARCHITECTURE.md index 08670992..5604b072 100644 --- a/assets/docs/zh/ARCHITECTURE.md +++ b/assets/docs/zh/ARCHITECTURE.md @@ -307,7 +307,7 @@ VM 内置 `json.encode` / `json.decode` / `log` / `http_get` / `http_post`。 | 方式 | 注册机制 | 编译 | 用途 | |------|----------|------|------| -| 内置插件 | `init()` → `RegisterFactory` | `internal/plugins/` 编译进内核 | webui/cli/agentcli 等 11 个(判定标准见下) | +| 内置插件 | `init()` → `RegisterFactory` | `internal/plugins/` 编译进内核 | webui/cli/agentcli 等 13 个(判定标准见下) | | 外部子进程插件 | 握手 + stdio JSON-RPC 反向注册 | `hmapdev build` → `plugin.bin`(普通 Go 二进制) | qq/browser/files 等 | | Lua 脚本插件 | 执行 `main.lua` 注册工具 | 无需编译,重启/重载生效 | luademo 等 | | SKILL 插件 | 解析 `SKILL.md` | Markdown 定义 | clawhubadapter 兼容加载 | @@ -356,7 +356,16 @@ Lua 脚本插件加载:`internal/plugin/` → gopher-lua 解释器执行 `main | 插件 | 实际依赖 | |---|---| | timer | RegisterTool + Settings + InjectText(公开) | -| ai_image / files / cmd / kbtree / localuse / mcp / multimodal | RegisterTool + Settings(+ s.Knowledge() 等公开 API) | +| ai_image / files / cmd / localuse / mcp | RegisterTool + Settings(+ 公开 RegisterStage) | + +> ★ 终审翻案(2026-10-19,逐方法对照公开 SDK 后加回两个): +> **kbtree** 依赖 `KnowledgeAPI.Subtree/CategoryCounts/SearchIn/Categories` +> ——公开 `KnowledgeAPI` 只有 `Search/Add/List`,且公开 SDK 没有 +> `KnowledgeTreeView`/`KnowledgeCategoryCount` 类型; +> **multimodal** 依赖 `LLMAPI.Chat` + `LLMMessage`/`LLMContentBlock` +> ——公开 `LLMAPI` 只有 `ListSources/SetSource/CurrentSource`。 +> 两者最初被误判为"只用公开能力",因为 `s.Knowledge()`/`s.LLM()` 两边 +> **同名不同面**。教训:判外置与否必须逐方法对照公开接口,不能只看方法名。 > ⚠️ 两份并存是禁止的:`loadOne` 先查内置工厂表,命中就不再看外部 `plugin.bin` > ⇒ 内置版永远赢,外部版**装了也不生效**。外置一个插件时,必须同时把它从 @@ -613,7 +622,7 @@ internal/ │ ├── registry.go — 注册表 + 生命周期 │ ├── dynamic.go — 加载通道分派(proc / lua / skill);.so 仅剩给明确报错 │ └── manifest.go — plugin.json 元数据 -├── plugins/ — 内置插件实现(11 个,判定标准见「内置插件的判定标准」) +├── plugins/ — 内置插件实现(13 个,判定标准见「内置插件的判定标准」) │ ├── all.go — 空白导入(**唯一权威清单**,增删内置插件只改这里) │ ├── webui/ — HTTP 服务器 + 嵌入式 SPA │ ├── cli/ — Unix socket CLI @@ -627,7 +636,7 @@ internal/ │ ├── seemedia/ — 直看媒体 │ ├── seq/ — 序列编排 │ ├── data/ plugin_data/ — 插件静态资源(非 Go,随内核打包) -│ ├── kbtree/ cmd/ localuse/ mcp/ multimodal/ ai_image/ files/ +│ ├── cmd/ localuse/ mcp/ ai_image/ files/ │ │ — 源码仍在但**未列入 all.go**:2026-10-19 起外置, │ │ 以 .hmap 形式安装(SDK 仓 example/ 提供工程); │ │ 目录待外置工程稳定后删除 diff --git a/assets/docs/zh/OVERVIEW.md b/assets/docs/zh/OVERVIEW.md index ed7d2a43..70b853c0 100644 --- a/assets/docs/zh/OVERVIEW.md +++ b/assets/docs/zh/OVERVIEW.md @@ -93,7 +93,7 @@ HomeAgent 是一个持续运行的个人智能 Agent 框架。 核心功能已可运行。插件系统和 SDK 已就绪,可独立开发外部插件。 -- 内置插件(11 个):webui / cli / agentcli / cfgmgr / healthcheck / pluginmgr / clawhubadapter / remotedevice / skillmgr / seemedia / seq +- 内置插件(13 个):webui / cli / agentcli / cfgmgr / healthcheck / kbtree / multimodal / pluginmgr / clawhubadapter / remotedevice / skillmgr / seemedia / seq - 判定标准:**只有必须使用内部 SDK 能力(公开 SDK 没有的接口面)的插件才内置**,其余一律外置为 .hmap 插件(详见 ARCHITECTURE「内置插件的判定标准」) - 外部插件示例([homeagent-sdk](https://github.com/JianFeeeee/homeagentsdk) 仓库 `example/`,含 Go 和 Lua 两种类型):qq / files / a2a / ai_image / bili / browser / calendar / editdoc / memo / music / ocr / rss / sanitizer / weather / luademo - 打包分发:`.hmap` 插件包格式,通过 WebUI 安装 diff --git a/internal/plugins/all.go b/internal/plugins/all.go index c3625b8c..88d0a8dd 100644 --- a/internal/plugins/all.go +++ b/internal/plugins/all.go @@ -43,10 +43,20 @@ package plugins // // 反例(已外置,因为它们只要公开能力): // cmd 仅 internal/plugin 的 RegisterFactory → 换成 NewPluginFactory 即可 -// kbtree 仅 s.Knowledge() + s.Settings() // localuse 仅 RegisterTool + Settings -// mcp 仅 RegisterTool + Settings -// multimodal 仅 RegisterTool + Settings +// mcp 仅 RegisterTool + Settings + RegisterStage +// +// ★ 终审翻案(2026-10-19,逐方法对照公开 SDK 后加回两个): +// kbtree KnowledgeAPI.Subtree/CategoryCounts/SearchIn/Categories —— +// 公开 KnowledgeAPI 只有 Search/Add/List,且公开 SDK 没有 +// KnowledgeTreeView/KnowledgeCategoryCount 类型 ⇒ 必须内置 +// multimodal LLMAPI.Chat + LLMMessage/LLMContentBlock(多模态消息)—— +// 公开 LLMAPI 只有 ListSources/SetSource/CurrentSource, +// 没有 Chat,也没有消息类型 ⇒ 必须内置 +// (agentcli 的 EventPublish 同理,见上) +// +// 教训:判「只用公开 SDK」不能只 grep 方法名前缀,要**逐方法对照公开接口**。 +// s.Knowledge() / s.LLM() 两边同名,但接口面不同;粗看就会误判成可外置。 // // ## ★ agentcli 为什么不能外置(2026-10-19 核实) // @@ -87,6 +97,8 @@ import ( _ "github.com/JianFeeeee/HomeAgent/internal/plugins/clawhubadapter" _ "github.com/JianFeeeee/HomeAgent/internal/plugins/cli" _ "github.com/JianFeeeee/HomeAgent/internal/plugins/healthcheck" + _ "github.com/JianFeeeee/HomeAgent/internal/plugins/kbtree" + _ "github.com/JianFeeeee/HomeAgent/internal/plugins/multimodal" _ "github.com/JianFeeeee/HomeAgent/internal/plugins/pluginmgr" _ "github.com/JianFeeeee/HomeAgent/internal/plugins/remotedevice" _ "github.com/JianFeeeee/HomeAgent/internal/plugins/seemedia"