package eino import ( "context" "strings" "testing" "github.com/cloudwego/eino/schema" "github.com/sundynix/sundynix-shared/contract" ) // TestBuildMessagesShape 锁定 ChatTemplate 产出的消息序列与旧手拼逻辑等价: // [system(含画像+参考资料)] + [历史...] + [user(query)],且 JSON 花括号不被误解析。 func TestBuildMessagesShape(t *testing.T) { rc := &RunCtx{ System: "你是助手", Query: "今天几号", Profile: "称呼=Dexter", History: []*schema.Message{schema.UserMessage("上一句"), schema.AssistantMessage("上一答", nil)}, ToolOut: []string{`{"k":"v"}`}, // 含花括号,验证 FString 不误解析 } msgs, err := buildMessages(context.Background(), rc) if err != nil { t.Fatal(err) } if len(msgs) != 4 { t.Fatalf("应为 system+2历史+user=4 条,实际 %d", len(msgs)) } if msgs[0].Role != schema.System || !strings.Contains(msgs[0].Content, "你是助手") || !strings.Contains(msgs[0].Content, "称呼=Dexter") || !strings.Contains(msgs[0].Content, `{"k":"v"}`) { t.Fatalf("system 消息不对: %q", msgs[0].Content) } if msgs[3].Role != schema.User || msgs[3].Content != "今天几号" { t.Fatalf("user 消息不对: %q", msgs[3].Content) } } // fakeCaller 是 ToolCaller 测试替身,固定返回 kb_search 命中。 type fakeCaller struct{ content string } func (f *fakeCaller) CallTool(_ context.Context, _ string, _ *contract.ToolCall) (*contract.ToolResult, error) { return &contract.ToolResult{OK: true, Content: f.content}, nil } // TestRagRetrieverComponent 验证 Retriever 组件把 kb_search 命中转成 *schema.Document。 func TestRagRetrieverComponent(t *testing.T) { o := &Orchestrator{tools: &fakeCaller{content: `[{"text":"片段A","score":0.9},{"text":"片段B","score":0.8}]`}} docs, err := o.newRetriever("u/kb").Retrieve(context.Background(), "q") if err != nil { t.Fatal(err) } if len(docs) != 2 || docs[0].Content != "片段A" || docs[1].Content != "片段B" { t.Fatalf("文档解析不对: %+v", docs) } }