fix(pico): avoid duplicate final websocket message

This commit is contained in:
lc6464 2026-04-09 22:59:36 +08:00
parent 2aeed8fb3a
commit 9982ee29a8
No known key found for this signature in database
GPG key ID: 53C61B42FEC71D6D
2 changed files with 25 additions and 15 deletions

View file

@ -2253,16 +2253,12 @@ turnLoop:
} }
logger.DebugCF("agent", "LLM response", llmResponseFields) logger.DebugCF("agent", "LLM response", llmResponseFields)
if al.bus != nil && ts.channel == "pico" { if al.bus != nil && ts.channel == "pico" && len(response.ToolCalls) > 0 {
liveContent := response.Content if strings.TrimSpace(response.Content) != "" {
if liveContent == "" && len(response.ToolCalls) == 0 && response.ReasoningContent != "" {
liveContent = response.ReasoningContent
}
if strings.TrimSpace(liveContent) != "" {
al.bus.PublishOutbound(turnCtx, bus.OutboundMessage{ al.bus.PublishOutbound(turnCtx, bus.OutboundMessage{
Channel: ts.channel, Channel: ts.channel,
ChatID: ts.chatID, ChatID: ts.chatID,
Content: liveContent, Content: response.Content,
}) })
} }
} }

View file

@ -2766,7 +2766,7 @@ func TestProcessMessage_PublishesToolFeedbackWhenEnabled(t *testing.T) {
} }
} }
func TestProcessMessage_PicoPublishesAssistantContentDuringToolCalls(t *testing.T) { func TestRun_PicoPublishesAssistantContentDuringToolCallsWithoutFinalDuplicate(t *testing.T) {
tmpDir := t.TempDir() tmpDir := t.TempDir()
cfg := &config.Config{ cfg := &config.Config{
@ -2790,17 +2790,21 @@ func TestProcessMessage_PicoPublishesAssistantContentDuringToolCalls(t *testing.
} }
agent.Tools.Register(&toolLimitTestTool{}) agent.Tools.Register(&toolLimitTestTool{})
response, err := al.processMessage(context.Background(), bus.InboundMessage{ runCtx, runCancel := context.WithCancel(context.Background())
defer runCancel()
runDone := make(chan error, 1)
go func() {
runDone <- al.Run(runCtx)
}()
if err := msgBus.PublishInbound(context.Background(), bus.InboundMessage{
Channel: "pico", Channel: "pico",
SenderID: "user-1", SenderID: "user-1",
ChatID: "session-1", ChatID: "session-1",
Content: "run with tools", Content: "run with tools",
}) }); err != nil {
if err != nil { t.Fatalf("PublishInbound() error = %v", err)
t.Fatalf("processMessage() error = %v", err)
}
if response != "final model text" {
t.Fatalf("processMessage() response = %q, want %q", response, "final model text")
} }
outputs := make([]string, 0, 2) outputs := make([]string, 0, 2)
@ -2821,6 +2825,16 @@ func TestProcessMessage_PicoPublishesAssistantContentDuringToolCalls(t *testing.
t.Fatalf("second outbound content = %q, want %q", outputs[1], "final model text") t.Fatalf("second outbound content = %q, want %q", outputs[1], "final model text")
} }
runCancel()
select {
case err := <-runDone:
if err != nil {
t.Fatalf("Run() error = %v", err)
}
case <-time.After(2 * time.Second):
t.Fatal("timed out waiting for Run() to exit")
}
select { select {
case outbound := <-msgBus.OutboundChan(): case outbound := <-msgBus.OutboundChan():
if outbound.Content == "final model text" { if outbound.Content == "final model text" {