mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-10-12 10:47:30 +02:00
Add files via upload
This commit is contained in:
96 files changed
+11867
No files matched your search
@@ -0,0 +1,183 @@
|
||||
package multiagent
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/cloudwego/eino/adk"
|
||||
"github.com/cloudwego/eino/schema"
|
||||
)
|
||||
|
||||
func TestEinoToolResultProgressEmitterInfersPendingAndDedupes(t *testing.T) {
|
||||
var events []map[string]interface{}
|
||||
progress := func(eventType, _ string, data interface{}) {
|
||||
if eventType != "tool_result" {
|
||||
return
|
||||
}
|
||||
m, _ := data.(map[string]interface{})
|
||||
events = append(events, m)
|
||||
}
|
||||
pending := newEinoPendingToolCalls("conv-1", nil)
|
||||
pending.Mark(toolCallPendingInfo{
|
||||
ToolCallID: "call-1",
|
||||
ToolName: "execute",
|
||||
EinoAgent: "worker",
|
||||
EinoRole: "sub",
|
||||
})
|
||||
stdoutDup := newEinoExecuteStdoutSuppressor()
|
||||
emitter := newEinoToolResultProgressEmitter(einoToolResultProgressEmitterConfig{
|
||||
ConversationID: "conv-1",
|
||||
OrchestratorName: "lead",
|
||||
Progress: progress,
|
||||
EinoRoleTag: func(agent string) string {
|
||||
if agent == "worker" {
|
||||
return "sub"
|
||||
}
|
||||
return "orchestrator"
|
||||
},
|
||||
Pending: pending,
|
||||
ExecuteStdoutDup: stdoutDup,
|
||||
})
|
||||
|
||||
if !emitter.Emit(nil, "execute", "hello", "", false, "worker") {
|
||||
t.Fatal("first tool result should emit")
|
||||
}
|
||||
if !emitter.Emit(nil, "execute", "duplicate without id", "", false, "worker") {
|
||||
t.Fatal("id-less result should still emit after pending queue is empty")
|
||||
}
|
||||
if emitter.Emit(nil, "execute", "duplicate", "call-1", false, "worker") {
|
||||
t.Fatal("duplicate toolCallId should not emit")
|
||||
}
|
||||
|
||||
if len(events) != 2 {
|
||||
t.Fatalf("events = %#v, want two emitted results", events)
|
||||
}
|
||||
if events[0]["toolCallId"] != "call-1" || events[0]["einoRole"] != "sub" {
|
||||
t.Fatalf("first event data = %#v", events[0])
|
||||
}
|
||||
if _, ok := events[1]["toolCallId"]; ok {
|
||||
t.Fatalf("second event should not invent toolCallId: %#v", events[1])
|
||||
}
|
||||
if got := stdoutDup.Peek(); got != "duplicate without id" {
|
||||
t.Fatalf("execute stdout suppressor = %q, want last emitted execute stdout", got)
|
||||
}
|
||||
if pending.Count() != 0 {
|
||||
t.Fatalf("pending count = %d, want 0", pending.Count())
|
||||
}
|
||||
}
|
||||
|
||||
func TestEinoToolResultProgressEmitterBackgroundWaitDisplaysRunning(t *testing.T) {
|
||||
var data map[string]interface{}
|
||||
progress := func(eventType, _ string, raw interface{}) {
|
||||
if eventType == "tool_result" {
|
||||
data, _ = raw.(map[string]interface{})
|
||||
}
|
||||
}
|
||||
body := `工具已提交到后台执行,但本次等待已到达上限。
|
||||
|
||||
execution_id: 3eaaa391-050b-4be1-a870-48a855923cb7
|
||||
tool: exec
|
||||
status: running
|
||||
wait_timeout: 10s`
|
||||
emitter := newEinoToolResultProgressEmitter(einoToolResultProgressEmitterConfig{
|
||||
ConversationID: "conv-1",
|
||||
Progress: progress,
|
||||
})
|
||||
|
||||
if !emitter.Emit(nil, "exec", body, "call-1", true, "lead") {
|
||||
t.Fatal("background wait result should emit")
|
||||
}
|
||||
if data["success"] != true || data["isError"] != false || data["status"] != "background_running" {
|
||||
t.Fatalf("background display flags = %#v", data)
|
||||
}
|
||||
if data["modelFacingIsError"] != true {
|
||||
t.Fatalf("modelFacingIsError = %#v", data["modelFacingIsError"])
|
||||
}
|
||||
if data["executionId"] != "3eaaa391-050b-4be1-a870-48a855923cb7" {
|
||||
t.Fatalf("executionId = %#v", data["executionId"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestEinoToolResultProgressEmitterHidesModelOutputRejectedResult(t *testing.T) {
|
||||
called := false
|
||||
emitter := newEinoToolResultProgressEmitter(einoToolResultProgressEmitterConfig{
|
||||
ConversationID: "conv-1",
|
||||
Progress: func(eventType, _ string, _ interface{}) {
|
||||
if eventType == "tool_result" {
|
||||
called = true
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
if emitter.Emit(nil, "task", modelOutputRejectedResultPrefix+" Tool call was not executed.", "call-1", true, "lead") {
|
||||
t.Fatal("model output rejected result should not emit")
|
||||
}
|
||||
if called {
|
||||
t.Fatal("progress should not receive model output rejected tool_result")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEinoToolResultProgressEmitterTruncatesPreview(t *testing.T) {
|
||||
var data map[string]interface{}
|
||||
progress := func(eventType, _ string, raw interface{}) {
|
||||
if eventType == "tool_result" {
|
||||
data, _ = raw.(map[string]interface{})
|
||||
}
|
||||
}
|
||||
long := ""
|
||||
for i := 0; i < 205; i++ {
|
||||
long += "x"
|
||||
}
|
||||
emitter := newEinoToolResultProgressEmitter(einoToolResultProgressEmitterConfig{
|
||||
ConversationID: "conv-1",
|
||||
Progress: progress,
|
||||
})
|
||||
emitter.Emit(nil, "", long, "", false, "")
|
||||
|
||||
if data["toolName"] != "unknown" {
|
||||
t.Fatalf("tool name = %#v", data["toolName"])
|
||||
}
|
||||
if got, _ := data["resultPreview"].(string); len(got) != 203 || got[200:] != "..." {
|
||||
t.Fatalf("preview = %q len=%d", got, len(got))
|
||||
}
|
||||
}
|
||||
|
||||
func TestEinoToolResultProgressEmitterBackfillsArgumentsFromRunMessages(t *testing.T) {
|
||||
var data map[string]interface{}
|
||||
progress := func(eventType, _ string, raw interface{}) {
|
||||
if eventType == "tool_result" {
|
||||
data, _ = raw.(map[string]interface{})
|
||||
}
|
||||
}
|
||||
runMessages := newEinoRunMessageAccumulator([]adk.Message{
|
||||
&schema.Message{
|
||||
Role: schema.Assistant,
|
||||
ToolCalls: []schema.ToolCall{{
|
||||
ID: "call-read",
|
||||
Type: "function",
|
||||
Function: schema.FunctionCall{
|
||||
Name: "read_file",
|
||||
Arguments: `{"path":"/tmp/requirements.txt"}`,
|
||||
},
|
||||
}},
|
||||
},
|
||||
})
|
||||
emitter := newEinoToolResultProgressEmitter(einoToolResultProgressEmitterConfig{
|
||||
ConversationID: "conv-1",
|
||||
Progress: progress,
|
||||
RunMessages: runMessages,
|
||||
})
|
||||
|
||||
if !emitter.Emit(nil, "read_file", "ok", "call-read", false, "lead") {
|
||||
t.Fatal("expected tool result emit")
|
||||
}
|
||||
args, ok := data["argumentsObj"].(map[string]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("argumentsObj = %#v", data["argumentsObj"])
|
||||
}
|
||||
if args["path"] != "/tmp/requirements.txt" {
|
||||
t.Fatalf("path = %#v, want /tmp/requirements.txt", args["path"])
|
||||
}
|
||||
if data["arguments"] != `{"path":"/tmp/requirements.txt"}` {
|
||||
t.Fatalf("arguments = %#v", data["arguments"])
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user