| 1 | package control |
| 2 | |
| 3 | import ( |
| 4 | "strings" |
| 5 | "testing" |
| 6 | |
| 7 | "reasonix/internal/event" |
| 8 | "reasonix/internal/provider" |
| 9 | ) |
| 10 | |
| 11 | func TestCompletionLogSourcesUseStableLocalMessageIdentity(t *testing.T) { |
| 12 | receipt := &event.CompletionReceipt{Verifications: []event.ReceiptVerification{{ToolCallID: "call"}}} |
| 13 | messages := []provider.Message{{Role: provider.RoleTool, ID: "entry-one", ToolCallID: "call", Content: "first log"}} |
| 14 | bound := bindCompletionLogSources(receipt, messages) |
| 15 | if bound.Verifications[0].ToolResultID != "entry-one" || receipt.Verifications[0].ToolResultID != "" { |
| 16 | t.Fatal("source missing or executor receipt mutated") |
| 17 | } |
| 18 | messages = append(messages, provider.Message{Role: provider.RoleTool, ID: "entry-two", ToolCallID: "call", Content: "later log"}) |
| 19 | if got := bindCompletionLogSources(receipt, messages); got.Verifications[0].ToolResultID != "" { |
| 20 | t.Fatal("ambiguous provider call ID accepted") |
| 21 | } |
| 22 | if bound.Verifications[0].ToolResultID != "entry-one" { |
| 23 | t.Fatal("later call changed the previously frozen source") |
| 24 | } |
| 25 | } |
| 26 | |
| 27 | func TestLookupToolResultFindsServerSearch(t *testing.T) { |
| 28 | msgs := []provider.Message{{ |
| 29 | Role: provider.RoleAssistant, |
| 30 | Content: "answer only", |
| 31 | ServerSearch: []provider.ServerSearchCall{{ |
| 32 | ID: "s1", |
| 33 | Query: "bitcoin", |
| 34 | Results: []provider.ServerSearchHit{{Title: "新闻本文", URL: "https://example.com/a"}}, |
| 35 | }}, |
| 36 | }} |
| 37 | got := lookupToolResult(msgs, "s1") |
| 38 | if got == nil || got.Args != `{"query":"bitcoin"}` || !strings.Contains(got.Output, "新闻本文") { |
| 39 | t.Fatalf("lookup = %#v", got) |
| 40 | } |
| 41 | if lookupToolResult(msgs, "missing") != nil { |
| 42 | t.Fatal("unknown tool id should miss") |
| 43 | } |
| 44 | } |
| 45 | |
| 46 | func TestLookupSearchResultPreservesRecordedMissingSources(t *testing.T) { |
| 47 | for _, status := range []string{"", provider.SourcesNotProvided} { |
| 48 | messages := []provider.Message{{Role: provider.RoleAssistant, ServerSearch: []provider.ServerSearchCall{{ID: "s", SourcesStatus: status}}}} |
| 49 | got := lookupToolResult(messages, "s") |
| 50 | if got == nil || strings.Contains(got.Output, "not_provided") != (status != "") { |
| 51 | t.Fatalf("status %q: %+v", status, got) |
| 52 | } |
| 53 | } |
| 54 | } |
| 55 |