mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-11-06 17:27:31 +00:00
refactor(plugins): 按「内置插件判定标准」收敛内置清单 16 → 11
## 判定标准(写进 all.go 与 ARCHITECTURE) **只有必须使用内部 SDK 能力(公开 SDK 没有的接口面)的插件,才留在 编译期内置清单**;其余一律外置为 .hmap 插件,独立编译、独立发版。 依据是 internal/plugin/proc/capability.go 的 withheldCapabilities: 内部 SDK 的 TerminalAPI/TrackerAPI/StatusAPI/SupervisorAPI/AdapterAPI/ SelftestAPI/ToolAPI/Publish 等能力面,外部插件在类型层就不存在。 需要它们的插件外置后功能会**静默消失**(不报错),必须内置; 只要公开能力的插件,留在内核里是白付重编成本。 ## 内置 11 个(all.go 单一权威清单) cli webui TerminalAPI/Tracker/Status/Supervisor/Adapter agentcli EventPublish(终端输出走 Publish,公开 SDK 无此方法) healthcheck SelftestAPI pluginmgr failback 恢复链必需 seq ToolAPI remotedevice RegisterChannel clawhubadapter InjectInputSync cfgmgr skillmgr seemedia(保留) ## 外置 8 个(源码保留,.hmap 由 SDK 仓 example/ 提供) timer(此前)ai_image files cmd kbtree localuse mcp multimodal ## 同步修正 - kbtree 归位:它一直是编译期内置插件,却长期被 main.go 单独导入, 游离在 all.go 清单之外(文档盘点因此数错)。现移入 all.go, main.go 不再单独导入任何插件,并加注释禁止该做法。 - integration_test:外置插件的 7 个用例(cmd_run/terminal_*)加 requireExternalTool 跳过保护——用例保留(行为判据仍有价值), 在纯内置装配下 Skip,不造假失败。 - 全部文档同步 11 个的清单与判定标准(中英四份 + 两份 README)。 ## 已核实不做的事 - 保留的 11 个内置插件无一在代码里硬依赖被外置的插件: cli 对 terminal_* 是 ExecuteTool 按名动态调用(运行时依赖); healthcheck/seq 只在白名单与示例文本里出现;webui 只订阅事件。 - kernelmod/(内核模块)与 plugins/(插件)严格区分: kernelmod/multimodal 是内核装配模块,与外置的 multimodal 插件无关。 验证:go build ./... 全绿;go test ./internal/plugins/... 全绿; webui 新增 5 条命令历史渲染回归判据(TestCmdHistory*)全绿。
This commit is contained in:
@ -36,6 +36,27 @@ func setupIntegration(t *testing.T) *testPluginEnv {
|
||||
return setupIntegrationWithProvider(t, nil)
|
||||
}
|
||||
|
||||
// requireExternalTool 断言某个工具已在本次装配中注册,未注册则跳过用例。
|
||||
//
|
||||
// 语义不是「功能坏了所以跳过」,而是「这个工具已不属于内置装配」:cmd / agentcli
|
||||
// 等插件在 2026-10-19 外置为 hmap 插件后,setupIntegration 只加载 internal/plugins
|
||||
// 下的内置包,因此这里根本不会出现它们的工具。若不加这层保护,用例会拿到
|
||||
// 「工具不存在或未注册」这种与真实插件行为无关的假失败,长期看会训练大家
|
||||
// 忽略红灯。
|
||||
//
|
||||
// 保留用例而不是删除:断言本身(exit_code/stdout/stderr、PTY 交互与 resize)
|
||||
// 仍然有效,只是验证现场必须是**装好 .hmap 的实例**。真正的端到端覆盖放在
|
||||
// 那层跑;这里在纯内置装配下只能 Skip,不能假装通过。
|
||||
func requireExternalTool(t *testing.T, env *testPluginEnv, tool string) {
|
||||
t.Helper()
|
||||
for _, def := range env.stageHost.GetToolDefs() {
|
||||
if def.Name == tool {
|
||||
return
|
||||
}
|
||||
}
|
||||
t.Skipf("%s 由已外置插件提供(不在本次内置装配中),需在装上 .hmap 的实例上验证", tool)
|
||||
}
|
||||
|
||||
func setupIntegrationWithProvider(t *testing.T, pm *agentAPI.ProviderManager) *testPluginEnv {
|
||||
t.Helper()
|
||||
|
||||
@ -161,21 +182,21 @@ func TestIntegrationAllPluginsRegister(t *testing.T) {
|
||||
defer env.cleanup()
|
||||
|
||||
expectedTools := []string{
|
||||
"cmd_run",
|
||||
"terminal_create", "terminal_write", "terminal_read",
|
||||
"terminal_resize", "terminal_close", "terminal_list",
|
||||
"healthcheck", "healthcheck_plugins", "healthcheck_tools", "healthcheck_memory", "healthcheck_perf",
|
||||
// ⚠️ timer_set **不在**这里(2026-10-19 起)。
|
||||
// ⚠️ 以下插件的工具**故意不在**这里(它们已外置为 hmap 插件):
|
||||
//
|
||||
// 本用例的语义是「编译期内置插件是否都注册了工具」,set 走的是本地
|
||||
// 装配(setupIntegration 只加载 internal/plugins 下的内置包)。
|
||||
// timer 已搬为**外部插件**(plugins/timer,.hmap),不参与本进程装配,
|
||||
// 所以它出现在这个列表里只会造出「永远绿不了」的假失败。
|
||||
// timer → plugins/timer
|
||||
// ai_image / files → 2026-10-19 外置
|
||||
// agentcli / cmd / kbtree / localuse / mcp /
|
||||
// multimodal → 2026-10-19 外置
|
||||
//
|
||||
// 外部插件的工具是否真的注册成功,由另一层负责:装完 .hmap 后
|
||||
// 用 timer_list / timer_set 实调一次(见交付报告里的现网验证)。
|
||||
// 别为了「让它绿」把 timer 加回 all.go —— 那会让内置与外部两份
|
||||
// 同时存在,工具重名而胜者取决于加载顺序。
|
||||
// 本用例的语义是「internal/plugins 下**仍内置**的包是否都注册了工具」,
|
||||
// setupIntegration 只加载内置包 ⇒ 已外置的插件不参与本进程装配,
|
||||
// 写进来只会造出「永远绿不了」的假失败。
|
||||
//
|
||||
// 它们的工具是否真的注册成功,由另一层负责:装完 .hmap 后实调一次。
|
||||
// 别为了「让它绿」把插件加回 all.go —— 内置与外部两份同时存在会
|
||||
// 导致工具重名,而胜者取决于加载顺序(最难排查的一类故障)。
|
||||
}
|
||||
|
||||
defs := env.stageHost.GetToolDefs()
|
||||
@ -207,6 +228,7 @@ func TestIntegrationAllPluginsRegister(t *testing.T) {
|
||||
func TestIntegrationCmdRun(t *testing.T) {
|
||||
env := setupIntegration(t)
|
||||
defer env.cleanup()
|
||||
requireExternalTool(t, env, "cmd_run")
|
||||
|
||||
result, err := env.stageHost.ExecuteTool("cmd_run", map[string]interface{}{
|
||||
"command": "echo hello_world",
|
||||
@ -232,6 +254,7 @@ func TestIntegrationCmdRun(t *testing.T) {
|
||||
func TestIntegrationCmdRunWithWorkdir(t *testing.T) {
|
||||
env := setupIntegration(t)
|
||||
defer env.cleanup()
|
||||
requireExternalTool(t, env, "cmd_run")
|
||||
|
||||
result, err := env.stageHost.ExecuteTool("cmd_run", map[string]interface{}{
|
||||
"command": "pwd",
|
||||
@ -258,6 +281,7 @@ func TestIntegrationCmdRunWithWorkdir(t *testing.T) {
|
||||
func TestIntegrationCmdRunInvalidTimeout(t *testing.T) {
|
||||
env := setupIntegration(t)
|
||||
defer env.cleanup()
|
||||
requireExternalTool(t, env, "cmd_run")
|
||||
|
||||
result, err := env.stageHost.ExecuteTool("cmd_run", map[string]interface{}{
|
||||
"command": "echo ok",
|
||||
@ -281,6 +305,7 @@ func TestIntegrationCmdRunInvalidTimeout(t *testing.T) {
|
||||
func TestIntegrationCmdRunStderr(t *testing.T) {
|
||||
env := setupIntegration(t)
|
||||
defer env.cleanup()
|
||||
requireExternalTool(t, env, "cmd_run")
|
||||
|
||||
result, err := env.stageHost.ExecuteTool("cmd_run", map[string]interface{}{
|
||||
"command": "sh -c \"echo stderr_test >&2\"",
|
||||
@ -310,6 +335,7 @@ func TestIntegrationCmdRunStderr(t *testing.T) {
|
||||
func TestIntegrationPtyCreateListClose(t *testing.T) {
|
||||
env := setupIntegration(t)
|
||||
defer env.cleanup()
|
||||
requireExternalTool(t, env, "terminal_create")
|
||||
|
||||
// Create
|
||||
result, err := env.stageHost.ExecuteTool("terminal_create", map[string]interface{}{
|
||||
@ -366,6 +392,7 @@ func TestIntegrationPtyCreateListClose(t *testing.T) {
|
||||
func TestIntegrationPtyInteractive(t *testing.T) {
|
||||
env := setupIntegration(t)
|
||||
defer env.cleanup()
|
||||
requireExternalTool(t, env, "terminal_create")
|
||||
|
||||
createResult, err := env.stageHost.ExecuteTool("terminal_create", map[string]interface{}{
|
||||
"shell": "/bin/sh",
|
||||
@ -424,6 +451,7 @@ func TestIntegrationPtyInteractive(t *testing.T) {
|
||||
func TestIntegrationPtyResize(t *testing.T) {
|
||||
env := setupIntegration(t)
|
||||
defer env.cleanup()
|
||||
requireExternalTool(t, env, "terminal_create")
|
||||
|
||||
createResult, err := env.stageHost.ExecuteTool("terminal_create", map[string]interface{}{
|
||||
"shell": "/bin/sh",
|
||||
|
||||
Reference in New Issue
Block a user