Add files via upload

This commit is contained in:
公明
2026-08-15 02:08:52 +08:00
committed by GitHub
parent 799282d0e7
commit bbc3395ac5
78 changed files with 10092 additions and 0 deletions
@@ -0,0 +1,152 @@
package multiagent
import (
"strings"
"testing"
"github.com/cloudwego/eino/schema"
)
func TestEinoStreamToolCallCompletionHandlerMergesEmitsAndPersistsToolCalls(t *testing.T) {
idx := 0
var eventTypes []string
var marked []toolCallPendingInfo
progress := func(eventType, _ string, _ interface{}) {
eventTypes = append(eventTypes, eventType)
}
runMessages := newEinoRunMessageAccumulator(nil)
runProgress := newEinoRunProgressTracker(
"deep", "lead", "conv-1", progress,
func(agent string) bool { return agent == "lead" },
nil,
)
handler := newEinoStreamToolCallCompletionHandler(einoStreamToolCallCompletionHandlerConfig{
ConversationID: "conv-1",
OrchMode: "deep",
Progress: progress,
RunProgress: runProgress,
RunMessages: runMessages,
MarkPending: func(info toolCallPendingInfo) {
marked = append(marked, info)
},
})
chunk := handler.Complete([]schema.ToolCall{
{
ID: "call-1",
Type: "function",
Index: &idx,
Function: schema.FunctionCall{
Name: "execute",
Arguments: `{"command":`,
},
},
{
Index: &idx,
Function: schema.FunctionCall{
Arguments: `"pwd"}`,
},
},
}, "lead")
if chunk == nil || len(chunk.ToolCalls) != 1 {
t.Fatalf("merged chunk = %#v, want one tool call", chunk)
}
if got := chunk.ToolCalls[0].Function.Arguments; got != `{"command":"pwd"}` {
t.Fatalf("arguments = %q", got)
}
msgs := runMessages.Messages()
if len(msgs) != 1 || len(msgs[0].ToolCalls) != 1 {
t.Fatalf("run messages = %#v, want persisted assistant tool call", msgs)
}
if len(marked) != 1 || marked[0].ToolCallID != "call-1" || marked[0].ToolName != "execute" {
t.Fatalf("marked pending = %#v", marked)
}
if !containsString(eventTypes, "tool_call") {
t.Fatalf("event types = %#v, want tool_call", eventTypes)
}
}
func TestEinoStreamToolCallCompletionHandlerPreservesStreamingToolArgumentsForToolLayerRecovery(t *testing.T) {
idx := 0
var eventTypes []string
var marked []toolCallPendingInfo
progress := func(eventType, _ string, _ interface{}) {
eventTypes = append(eventTypes, eventType)
}
runMessages := newEinoRunMessageAccumulator(nil)
runProgress := newEinoRunProgressTracker(
"deep", "lead", "conv-1", progress,
func(agent string) bool { return agent == "lead" },
nil,
)
handler := newEinoStreamToolCallCompletionHandler(einoStreamToolCallCompletionHandlerConfig{
ConversationID: "conv-1",
OrchMode: "deep",
Progress: progress,
RunProgress: runProgress,
RunMessages: runMessages,
MarkPending: func(info toolCallPendingInfo) {
marked = append(marked, info)
},
})
chunk := handler.Complete([]schema.ToolCall{
{
ID: "call-stream-unsafe",
Type: "function",
Index: &idx,
Function: schema.FunctionCall{
Name: "execute",
Arguments: `{"command":"`,
},
},
{
Index: &idx,
Function: schema.FunctionCall{
Arguments: strings.Repeat("x", 256) + `"}`,
},
},
}, "lead")
if chunk == nil || len(chunk.ToolCalls) != 1 {
t.Fatalf("chunk = %#v, want one tool call", chunk)
}
args := chunk.ToolCalls[0].Function.Arguments
if !strings.Contains(args, strings.Repeat("x", 32)) {
t.Fatalf("streaming arguments were unexpectedly rewritten: %q", args)
}
msgs := runMessages.Messages()
if len(msgs) != 1 || len(msgs[0].ToolCalls) != 1 {
t.Fatalf("run messages = %#v, want assistant tool call", msgs)
}
if got := msgs[0].ToolCalls[0].Function.Arguments; got != args {
t.Fatalf("persisted tool call arguments = %q, want %q", got, args)
}
if len(marked) != 1 || marked[0].ToolCallID != "call-stream-unsafe" || marked[0].ToolName != "execute" {
t.Fatalf("marked pending = %#v", marked)
}
if containsString(eventTypes, "model_output_rejected") || !containsString(eventTypes, "tool_call") {
t.Fatalf("event types = %#v, want real tool_call without model-output recovery", eventTypes)
}
}
func TestEinoStreamToolCallCompletionHandlerIgnoresEmptyFragments(t *testing.T) {
runMessages := newEinoRunMessageAccumulator(nil)
called := false
handler := newEinoStreamToolCallCompletionHandler(einoStreamToolCallCompletionHandlerConfig{
RunMessages: runMessages,
Progress: func(string, string, interface{}) {
called = true
},
})
if chunk := handler.Complete(nil, "lead"); chunk != nil {
t.Fatalf("chunk = %#v, want nil", chunk)
}
if len(runMessages.Messages()) != 0 {
t.Fatalf("run messages = %#v, want empty", runMessages.Messages())
}
if called {
t.Fatal("progress should not be called for empty fragments")
}
}