Files
goclaw/internal/agent/loop_media_delivery_dedup_test.go

123 lines
3.4 KiB
Go

package agent
import (
"context"
"os"
"path/filepath"
"strings"
"testing"
"github.com/nextlevelbuilder/goclaw/internal/bus"
"github.com/nextlevelbuilder/goclaw/internal/providers"
"github.com/nextlevelbuilder/goclaw/internal/tools"
)
func TestProcessToolResultBlocksMessageSelfSendForQueuedMedia(t *testing.T) {
workspace := t.TempDir()
workspace, err := filepath.EvalSymlinks(workspace)
if err != nil {
t.Fatal(err)
}
mediaPath := filepath.Join(workspace, "generated-image.png")
if err := os.WriteFile(mediaPath, []byte("image"), 0o644); err != nil {
t.Fatal(err)
}
delivered := tools.NewDeliveredMedia()
ctx := context.Background()
ctx = tools.WithToolWorkspace(ctx, workspace)
ctx = tools.WithToolChannel(ctx, "lark-test")
ctx = tools.WithToolChatID(ctx, "chat-1")
ctx = tools.WithDeliveredMedia(ctx, delivered)
loop := &Loop{id: "test-agent"}
state := &runState{}
loop.processToolResult(
ctx,
state,
&RunRequest{RunID: "run-1"},
func(AgentEvent) {},
providers.ToolCall{ID: "create-1", Name: "create_image"},
"create_image",
&tools.Result{
ForLLM: "MEDIA:" + mediaPath,
Media: []bus.MediaFile{{
Path: mediaPath,
MimeType: "image/png",
}},
},
false,
)
if len(state.mediaResults) != 1 {
t.Fatalf("queued media = %d, want 1", len(state.mediaResults))
}
messageTool := tools.NewMessageTool(workspace, true)
messageTool.SetMessageBus(bus.New())
result := messageTool.Execute(ctx, map[string]any{
"action": "send",
"channel": "lark-test",
"target": "chat-1",
"message": "MEDIA:" + mediaPath,
})
if !result.IsError {
t.Fatal("message self-send succeeded for media already queued by the agent loop")
}
if !strings.Contains(result.ForLLM, "already queued for automatic delivery") {
t.Fatalf("message self-send blocked for the wrong reason: %q", result.ForLLM)
}
otherPath := filepath.Join(workspace, "manual-attachment.txt")
if err := os.WriteFile(otherPath, []byte("attachment"), 0o644); err != nil {
t.Fatal(err)
}
result = messageTool.Execute(ctx, map[string]any{
"action": "send",
"channel": "lark-test",
"target": "chat-1",
"message": "Attachments:\nMEDIA:" + mediaPath + "\nMEDIA:" + otherPath,
})
if !result.IsError {
t.Fatal("mixed message self-send included media already queued by the agent loop")
}
if !strings.Contains(result.ForLLM, "already queued for automatic delivery") {
t.Fatalf("mixed message self-send blocked for the wrong reason: %q", result.ForLLM)
}
}
func TestProcessToolResultMarksLegacyMediaAsQueued(t *testing.T) {
workspace := t.TempDir()
workspace, err := filepath.EvalSymlinks(workspace)
if err != nil {
t.Fatal(err)
}
mediaPath := filepath.Join(workspace, "legacy-output.pdf")
if err := os.WriteFile(mediaPath, []byte("pdf"), 0o644); err != nil {
t.Fatal(err)
}
delivered := tools.NewDeliveredMedia()
ctx := tools.WithToolWorkspace(context.Background(), workspace)
ctx = tools.WithDeliveredMedia(ctx, delivered)
state := &runState{}
(&Loop{id: "test-agent"}).processToolResult(
ctx,
state,
&RunRequest{RunID: "run-legacy"},
func(AgentEvent) {},
providers.ToolCall{ID: "exec-1", Name: "exec"},
"exec",
&tools.Result{ForLLM: "MEDIA:" + mediaPath},
false,
)
if len(state.mediaResults) != 1 {
t.Fatalf("queued legacy media = %d, want 1", len(state.mediaResults))
}
if !delivered.IsDelivered(mediaPath) {
t.Fatalf("legacy media %q was not marked for automatic delivery", mediaPath)
}
}