diff --git a/internal/agent/core/agent_tools_test.go b/internal/agent/core/agent_tools_test.go index 4d8a403..e84d28d 100644 --- a/internal/agent/core/agent_tools_test.go +++ b/internal/agent/core/agent_tools_test.go @@ -62,7 +62,8 @@ func TestExecuteOutputSendTool(t *testing.T) { a := &Agent{io: io} tc := agentAPI.ToolCall{Name: "output_send__screen", Arguments: map[string]interface{}{ - "content": `{"content":"hello world"}`, + "payload": "hello world", + "type": "text", }} result := a.executeOutputSendTool(tc) if !strings.Contains(result, "screen") { @@ -84,7 +85,8 @@ func TestExecuteOutputSendToolChannelNotExist(t *testing.T) { io := agentIO.NewIOManager() a := &Agent{io: io} tc := agentAPI.ToolCall{Name: "output_send__nonexistent", Arguments: map[string]interface{}{ - "content": "hello", + "payload": "hello", + "type": "text", }} result := a.executeOutputSendTool(tc) if !strings.Contains(result, "不存在") && !strings.Contains(result, "不可用") { @@ -101,7 +103,8 @@ func TestExecuteOutputSendToolNoTextCap(t *testing.T) { a := &Agent{io: io} tc := agentAPI.ToolCall{Name: "output_send__camera", Arguments: map[string]interface{}{ - "content": "hello", + "payload": "hello", + "type": "text", }} result := a.executeOutputSendTool(tc) if strings.Contains(result, "已通过") { diff --git a/internal/agent/core/context.go b/internal/agent/core/context.go index d1e312c..1ed0568 100644 --- a/internal/agent/core/context.go +++ b/internal/agent/core/context.go @@ -139,6 +139,23 @@ func (c *RelevanceContext) Append(evt ContextEvent) { c.save() } +func (c *RelevanceContext) InsertByTimestamp(evt ContextEvent) { + c.mu.Lock() + defer c.mu.Unlock() + + evt.Vector = c.computeVector(&evt) + + idx := sort.Search(len(c.events), func(i int) bool { + return c.events[i].Timestamp.After(evt.Timestamp) + }) + + c.events = append(c.events, nil) + copy(c.events[idx+1:], c.events[idx:]) + c.events[idx] = &evt + + c.save() +} + func (c *RelevanceContext) save() error { if c.savePath == "" { return nil diff --git a/internal/agent/core/toolcall.go b/internal/agent/core/toolcall.go index e1f3525..3834a01 100644 --- a/internal/agent/core/toolcall.go +++ b/internal/agent/core/toolcall.go @@ -503,7 +503,7 @@ func (a *Agent) executeDocTool(tc agentAPI.ToolCall) string { if len(content) > 2000 { content = content[:2000] + "..." } - a.context.Append(ContextEvent{ + a.context.InsertByTimestamp(ContextEvent{ Timestamp: d.CreatedAt, Source: "cold_storage", Input: fmt.Sprintf("加载文档记忆: %s", query), diff --git a/internal/plugins/cli/plugin.go b/internal/plugins/cli/plugin.go index 7c5577b..6e389d5 100644 --- a/internal/plugins/cli/plugin.go +++ b/internal/plugins/cli/plugin.go @@ -71,6 +71,15 @@ func (p *Plugin) Name() string { return p.name } func (p *Plugin) Start(s *sdk.PluginSDK) error { s.SetAutoRestart(true) + + s.RegisterOutputChannel("cli", 1, "CLI 终端", func(args map[string]interface{}) (interface{}, error) { + payload, _ := args["payload"].(string) + if payload != "" { + fmt.Println(payload) + } + return map[string]interface{}{"status": "ok"}, nil + }) + s.Settings().RegisterDef(sdk.ConfigDef{ Key: "api_key", Type: "password", DisplayName: "CLI API 密钥", Description: "CLI 客户端连接时需提供的认证密钥(留空则使用 WebUI 密钥)", diff --git a/internal/plugins/webui/plugin.go b/internal/plugins/webui/plugin.go index c292d86..3bdca64 100644 --- a/internal/plugins/webui/plugin.go +++ b/internal/plugins/webui/plugin.go @@ -156,6 +156,21 @@ func (p *Plugin) Name() string { return p.name } func (p *Plugin) Start(s *sdk.PluginSDK) error { s.SetAutoRestart(true) + + s.RegisterOutputChannel("webui", 1, "Web 控制台", func(args map[string]interface{}) (interface{}, error) { + payload, _ := args["payload"].(string) + if payload != "" { + p.evBus.Publish(&events.Event{ + Type: events.EventAgentOutput, + Payload: map[string]interface{}{ + "content": payload, + "channel": "webui", + }, + }) + } + return map[string]interface{}{"status": "ok"}, nil + }) + s.Settings().RegisterDef(sdk.ConfigDef{Key: "api_key", Default: "", Type: "password", DisplayName: "API 密钥", Description: "访问 API 时需要的密钥", Category: "webui"}) s.Settings().RegisterDef(sdk.ConfigDef{Key: "username", Default: "admin", Type: "string", DisplayName: "登录用户名", Description: "Web 控制台登录用户名", Category: "webui"}) s.Settings().RegisterDef(sdk.ConfigDef{Key: "password", Default: "", Type: "password", DisplayName: "Web 控制台登录密码", Description: "Web 控制台登录密码", Category: "webui"})