package eino import ( "context" "testing" "github.com/sundynix/sundynix-dispatcher/internal/harness" "github.com/sundynix/sundynix-dispatcher/internal/llm" "github.com/sundynix/sundynix-shared/contract" ) // echoLLM 回显最后一条 user 消息内容(确定性),便于两条执行路径逐字对比。 func echoLLM() *fakeLLM { return &fakeLLM{ ready: true, stream: func(m []llm.ChatMessage) string { for i := len(m) - 1; i >= 0; i-- { if m[i].Role == "user" { return "ANS:" + m[i].Content } } return "ANS:" }, } } func runBoth(t *testing.T, graph string) (interp, comp string) { t.Helper() task := &contract.Task{ID: "t_eq", Graph: []byte(graph)} o1 := &Orchestrator{pool: echoLLM(), breaker: harness.NewCircuitBreaker(), sink: &fakeSink{}} a1, _, err := o1.runGraph(context.Background(), task, &execTracer{}) if err != nil { t.Fatalf("runGraph: %v", err) } o2 := &Orchestrator{pool: echoLLM(), breaker: harness.NewCircuitBreaker(), sink: &fakeSink{}} a2, err := o2.runComposeGraph(context.Background(), task, &execTracer{}) if err != nil { t.Fatalf("runComposeGraph: %v", err) } return a1, a2 } // TestComposeEquivalentLinear 多节点线性图:input→memory→agent→output,两路径成稿应逐字一致。 func TestComposeEquivalentLinear(t *testing.T) { graph := `{"version":"1","nodes":[ {"id":"in","kind":"input","config":{"text":"什么是图编排"}}, {"id":"m","kind":"memory","config":{}}, {"id":"a","kind":"agent","config":{"system":"你是助手"}}, {"id":"out","kind":"output","config":{}} ],"edges":[ {"source":"in","target":"m"},{"source":"m","target":"a"},{"source":"a","target":"out"} ]}` interp, comp := runBoth(t, graph) if interp == "" || interp != comp { t.Fatalf("线性图不等价: interp=%q compose=%q", interp, comp) } } // TestComposeEquivalentBranch 分支图:input→branch→(真)A/(假)B,条件恒真应都走 A,两路径一致。 func TestComposeEquivalentBranch(t *testing.T) { graph := `{"version":"1","nodes":[ {"id":"in","kind":"input","config":{"text":"hi"}}, {"id":"br","kind":"branch","config":{"condition":""}}, {"id":"a","kind":"agent","config":{"system":"A"}}, {"id":"b","kind":"agent","config":{"system":"B"}} ],"edges":[ {"source":"in","target":"br"}, {"source":"br","target":"a","sourceHandle":"true"}, {"source":"br","target":"b","sourceHandle":"false"} ]}` interp, comp := runBoth(t, graph) if interp == "" || interp != comp { t.Fatalf("分支图不等价: interp=%q compose=%q", interp, comp) } }