Fix duplicate replies after message tool sends from named agents
This commit is contained in:
parent
cf9e0496f7
commit
88d4a04e89
2 changed files with 78 additions and 6 deletions
|
|
@ -458,7 +458,7 @@ func (al *AgentLoop) Run(ctx context.Context) error {
|
||||||
if target == nil {
|
if target == nil {
|
||||||
cancelDrain()
|
cancelDrain()
|
||||||
if finalResponse != "" {
|
if finalResponse != "" {
|
||||||
al.publishResponseIfNeeded(ctx, msg.Channel, msg.ChatID, finalResponse)
|
al.publishResponseIfNeeded(ctx, msg.SessionKey, msg.Channel, msg.ChatID, finalResponse)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -518,7 +518,7 @@ func (al *AgentLoop) Run(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if finalResponse != "" {
|
if finalResponse != "" {
|
||||||
al.publishResponseIfNeeded(ctx, target.Channel, target.ChatID, finalResponse)
|
al.publishResponseIfNeeded(ctx, target.SessionKey, target.Channel, target.ChatID, finalResponse)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
default:
|
default:
|
||||||
|
|
@ -604,15 +604,17 @@ func (al *AgentLoop) Stop() {
|
||||||
al.running.Store(false)
|
al.running.Store(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (al *AgentLoop) publishResponseIfNeeded(ctx context.Context, channel, chatID, response string) {
|
func (al *AgentLoop) publishResponseIfNeeded(
|
||||||
|
ctx context.Context,
|
||||||
|
sessionKey, channel, chatID, response string,
|
||||||
|
) {
|
||||||
if response == "" {
|
if response == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
alreadySent := false
|
alreadySent := false
|
||||||
defaultAgent := al.GetRegistry().GetDefaultAgent()
|
if agent := al.agentForSession(sessionKey); agent != nil {
|
||||||
if defaultAgent != nil {
|
if tool, ok := agent.Tools.Get("message"); ok {
|
||||||
if tool, ok := defaultAgent.Tools.Get("message"); ok {
|
|
||||||
if mt, ok := tool.(*tools.MessageTool); ok {
|
if mt, ok := tool.(*tools.MessageTool); ok {
|
||||||
alreadySent = mt.HasSentInRound()
|
alreadySent = mt.HasSentInRound()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,76 @@ func TestProcessMessage_IncludesCurrentSenderInDynamicContext(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPublishResponseIfNeeded_UsesSessionAgentMessageState(t *testing.T) {
|
||||||
|
tmpDir, err := os.MkdirTemp("", "agent-test-*")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to create temp dir: %v", err)
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(tmpDir)
|
||||||
|
|
||||||
|
cfg := &config.Config{
|
||||||
|
Agents: config.AgentsConfig{
|
||||||
|
Defaults: config.AgentDefaults{
|
||||||
|
Workspace: tmpDir,
|
||||||
|
Model: "test-model",
|
||||||
|
MaxTokens: 4096,
|
||||||
|
MaxToolIterations: 10,
|
||||||
|
},
|
||||||
|
List: []config.AgentConfig{
|
||||||
|
{ID: "worker"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Tools: config.ToolsConfig{
|
||||||
|
Message: config.ToolConfig{Enabled: true},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
msgBus := bus.NewMessageBus()
|
||||||
|
al := NewAgentLoop(cfg, msgBus, &mockProvider{})
|
||||||
|
|
||||||
|
worker, ok := al.registry.GetAgent("worker")
|
||||||
|
if !ok {
|
||||||
|
t.Fatal("expected named agent to be registered")
|
||||||
|
}
|
||||||
|
|
||||||
|
tool, ok := worker.Tools.Get("message")
|
||||||
|
if !ok {
|
||||||
|
t.Fatal("expected message tool to be registered on named agent")
|
||||||
|
}
|
||||||
|
|
||||||
|
messageTool, ok := tool.(*tools.MessageTool)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("expected *tools.MessageTool, got %T", tool)
|
||||||
|
}
|
||||||
|
|
||||||
|
messageTool.ResetSentInRound()
|
||||||
|
result := messageTool.Execute(
|
||||||
|
tools.WithToolContext(context.Background(), "discord", "chat-1"),
|
||||||
|
map[string]any{"content": "tool message"},
|
||||||
|
)
|
||||||
|
if result == nil || result.Err != nil {
|
||||||
|
t.Fatalf("message tool execute failed: %+v", result)
|
||||||
|
}
|
||||||
|
|
||||||
|
sessionKey := routing.BuildAgentMainSessionKey(worker.ID)
|
||||||
|
al.publishResponseIfNeeded(context.Background(), sessionKey, "discord", "chat-1", "final response")
|
||||||
|
|
||||||
|
select {
|
||||||
|
case msg := <-msgBus.OutboundChan():
|
||||||
|
if msg.Content != "tool message" {
|
||||||
|
t.Fatalf("first outbound content = %q, want %q", msg.Content, "tool message")
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
t.Fatal("expected tool message to be published")
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case msg := <-msgBus.OutboundChan():
|
||||||
|
t.Fatalf("unexpected duplicate outbound message: %+v", msg)
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestProcessMessage_UseCommandLoadsRequestedSkill(t *testing.T) {
|
func TestProcessMessage_UseCommandLoadsRequestedSkill(t *testing.T) {
|
||||||
tmpDir := t.TempDir()
|
tmpDir := t.TempDir()
|
||||||
skillDir := filepath.Join(tmpDir, "skills", "shell")
|
skillDir := filepath.Join(tmpDir, "skills", "shell")
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue