mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-13 20:14:50 +00:00
123 lines
3.4 KiB
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)
|
|
}
|
|
}
|