mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-09-21 17:38:10 +00:00
feat: add plgreload tool for atomic plugin reload
- Agent can now call plgreload to reload plugins/ directory - Atomic swap: new devices Start → routes swapped → old devices Stop - Output channel capability validation on output_send - output_list_channels tool for channel discovery - OneBot V11 protocol implementation (Reverse WebSocket) - Plugin = container with embedded IO channel (composition) - Unified ToolDef type (agentIO.ToolDef = plugin.ToolDef)
This commit is contained in:
@ -251,6 +251,8 @@ func main() {
|
|||||||
DocStore: docStore,
|
DocStore: docStore,
|
||||||
Knowledge: ks,
|
Knowledge: ks,
|
||||||
Personality: personality,
|
Personality: personality,
|
||||||
|
PluginReg: pluginReg,
|
||||||
|
PluginDir: filepath.Join(cfg.Daemon.DataDir, "plugins"),
|
||||||
})
|
})
|
||||||
agent.Start()
|
agent.Start()
|
||||||
defer agent.Stop()
|
defer agent.Stop()
|
||||||
@ -292,12 +294,4 @@ func main() {
|
|||||||
log.Printf("[homed] stopped")
|
log.Printf("[homed] stopped")
|
||||||
}
|
}
|
||||||
|
|
||||||
func countIOPlugins(r *plugin.Registry) int {
|
|
||||||
n := 0
|
|
||||||
for _, p := range r.List() {
|
|
||||||
if p.IOConfig() != nil {
|
|
||||||
n++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|||||||
@ -49,6 +49,7 @@ type Agent struct {
|
|||||||
|
|
||||||
// 插件注册表(用于 plgreload)
|
// 插件注册表(用于 plgreload)
|
||||||
pluginReg *plugin.Registry
|
pluginReg *plugin.Registry
|
||||||
|
pluginDir string
|
||||||
|
|
||||||
// 定期心跳蒸馏
|
// 定期心跳蒸馏
|
||||||
distillInterval time.Duration
|
distillInterval time.Duration
|
||||||
@ -108,6 +109,7 @@ func New(cfg AgentConfig) *Agent {
|
|||||||
knowledge: cfg.Knowledge,
|
knowledge: cfg.Knowledge,
|
||||||
personality: cfg.Personality,
|
personality: cfg.Personality,
|
||||||
pluginReg: cfg.PluginReg,
|
pluginReg: cfg.PluginReg,
|
||||||
|
pluginDir: cfg.PluginDir,
|
||||||
distillInterval: cfg.DistillInterval,
|
distillInterval: cfg.DistillInterval,
|
||||||
maxContextSize: cfg.MaxContextSize,
|
maxContextSize: cfg.MaxContextSize,
|
||||||
}
|
}
|
||||||
@ -318,6 +320,8 @@ func (a *Agent) executeToolCall(tc agentAPI.ToolCall) string {
|
|||||||
return a.executeOutputSendTool(tc)
|
return a.executeOutputSendTool(tc)
|
||||||
case tc.Name == "output_list_channels":
|
case tc.Name == "output_list_channels":
|
||||||
return a.executeOutputListChannels()
|
return a.executeOutputListChannels()
|
||||||
|
case tc.Name == "plgreload":
|
||||||
|
return a.executePluginReload()
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.tracker != nil {
|
if a.tracker != nil {
|
||||||
@ -690,6 +694,21 @@ func (a *Agent) buildToolDefs() []interface{} {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 插件重载工具
|
||||||
|
if a.pluginReg != nil && a.pluginDir != "" {
|
||||||
|
tools = append(tools, map[string]interface{}{
|
||||||
|
"type": "function",
|
||||||
|
"function": map[string]interface{}{
|
||||||
|
"name": "plgreload",
|
||||||
|
"description": "重载 plugins/ 目录的所有插件。扫描目录变更,原子化替换 IO 设备。",
|
||||||
|
"parameters": map[string]interface{}{
|
||||||
|
"type": "object",
|
||||||
|
"properties": map[string]interface{}{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// 输出通道工具
|
// 输出通道工具
|
||||||
tools = append(tools, map[string]interface{}{
|
tools = append(tools, map[string]interface{}{
|
||||||
"type": "function",
|
"type": "function",
|
||||||
@ -1045,6 +1064,18 @@ func getString(m map[string]interface{}, key string) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// executePluginReload — 重载所有插件(原子替换 IO 设备)
|
||||||
|
func (a *Agent) executePluginReload() string {
|
||||||
|
if a.pluginReg == nil {
|
||||||
|
return "插件系统未启用"
|
||||||
|
}
|
||||||
|
msg, err := a.pluginReg.Reload(a.pluginDir)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Sprintf("插件重载失败: %v", err)
|
||||||
|
}
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
func getFloat(m map[string]interface{}, key string) float64 {
|
func getFloat(m map[string]interface{}, key string) float64 {
|
||||||
if v, ok := m[key]; ok {
|
if v, ok := m[key]; ok {
|
||||||
switch n := v.(type) {
|
switch n := v.(type) {
|
||||||
|
|||||||
Reference in New Issue
Block a user