1 Commits

Author SHA1 Message Date
4cb33193c9 feat(pluginmgr): plugin_install 支持本机 path(配合 plugindev_build 的产物)
背景:Agent 现在能自己构建插件了(plugindev 插件封装了 hmapdev),但安装只支持
http(s) URL —— 本地刚构建出来的 `dist/*.hmap` 装不上,链路断在最后一步。
pluginmgr 的 HTTP API 本来就接受 `{path}`(installFromPath),只是工具面没暴露。

改动:`plugin_install` 增加可选 `path`(本机 .hmap 路径),与 `url` 二选一,
同时给出时以 `path` 为准;`path` 必须存在且不是目录。描述里写明
「配合 plugindev_build 的产物用这个」。

于是 Agent 的完整闭环成立:
  plugindev_init → plugindev_build → plugin_install(path) → plgreload
2026-09-13 14:17:08 +08:00

View File

@ -138,28 +138,39 @@ func (p *Plugin) Stop() error {
func (p *Plugin) registerTools(s *sdk.PluginSDK) { func (p *Plugin) registerTools(s *sdk.PluginSDK) {
s.RegisterTool("plugin_install", sdk.ToolDef{ s.RegisterTool("plugin_install", sdk.ToolDef{
Name: "plugin_install", Name: "plugin_install",
Description: "从 URL 安装 HomeAgent 插件包(.hmap 文件)。插件已存在时传 overwrite=true 原地更新(升级/降级/重装,保留配置表,无需卸载重装)。更新后需调用 plgreload 或重启生效。", Description: "安装 HomeAgent 插件包(.hmap)。两种来源:url(http/https 下载)或 path(本机路径,配合 plugindev_build 的产物用这个)。插件已存在时传 overwrite=true 原地更新(升级/降级/重装,保留配置表,无需卸载重装)。更新后需调用 plgreload 或重启生效。",
Parameters: map[string]interface{}{ Parameters: map[string]interface{}{
"type": "object", "type": "object",
"properties": map[string]interface{}{ "properties": map[string]interface{}{
"url": map[string]interface{}{ "url": map[string]interface{}{
"type": "string", "type": "string",
"description": "插件包的下载 URL", "description": "插件包的下载 URL(http/https)",
},
"path": map[string]interface{}{
"type": "string",
"description": "插件包在**本机**的路径(.hmap)。与 url 二选一;同时给出时以 path 为准",
}, },
"overwrite": map[string]interface{}{ "overwrite": map[string]interface{}{
"type": "boolean", "type": "boolean",
"description": "已存在时原地更新(保留配置)。默认 false", "description": "已存在时原地更新(保留配置)。默认 false",
}, },
}, },
"required": []string{"url"},
}, },
}, func(args map[string]interface{}) (interface{}, error) { }, func(args map[string]interface{}) (interface{}, error) {
url, _ := args["url"].(string)
if url == "" {
return map[string]interface{}{"error": "url is required"}, nil
}
overwrite, _ := args["overwrite"].(bool) overwrite, _ := args["overwrite"].(bool)
return p.installFromURL(url, overwrite) // path 优先:它对应"agent 自己构建出产物再装"的场景(plugindev_build → plugin_install)。
if path, _ := args["path"].(string); strings.TrimSpace(path) != "" {
pth := strings.TrimSpace(path)
if st, err := os.Stat(pth); err != nil || st.IsDir() {
return map[string]interface{}{"error": fmt.Sprintf("path 无效(必须是存在的 .hmap 文件): %s", pth)}, nil
}
return p.installFromPath(pth, overwrite)
}
url, _ := args["url"].(string)
if strings.TrimSpace(url) == "" {
return map[string]interface{}{"error": "需要 url 或 path(二选一)"}, nil
}
return p.installFromURL(strings.TrimSpace(url), overwrite)
}) })
s.RegisterTool("plugin_list", sdk.ToolDef{ s.RegisterTool("plugin_list", sdk.ToolDef{