Files
Agent-System-Backend/internal/tools/search_test.go
T
weichen f1302ed5b3 Enable canonical versioned Go module consumption
Why: Allow consumers to download an immutable module revision without nested source checkouts or local path replacements.

Evidence: SELF package tests and the prior canonical-path rejection are recorded in the Dev dependency-workspace task card; remote consumption is replayed against the committed candidate.

Impact: Change the module identity and its Go imports while preserving API behavior. Existing historical submodule revisions remain buildable.

Refs: Versioned dependencies U1/U3; feature/dependency-workspace
2026-10-13 15:47:16 +00:00

86 lines
2.6 KiB
Go

package tools
import (
"context"
"encoding/json"
"errors"
"strings"
"testing"
agenttools "git-ssh.u1680832.nyat.app/weichen/Agent-Native.git/runtime/tools"
core "git-ssh.u1680832.nyat.app/weichen/Agent-System-Core.git"
)
type fakeProvider struct {
resp agenttools.SearchResponse
err error
}
func (f *fakeProvider) Search(ctx context.Context, req agenttools.SearchRequest) (agenttools.SearchResponse, error) {
return f.resp, f.err
}
func newSearchRegistry(t *testing.T, p agenttools.SearchProvider) *Registry {
t.Helper()
reg := NewRegistry()
if err := reg.RegisterBuiltin(); err != nil {
t.Fatal(err)
}
if err := RegisterSearchTools(reg, p); err != nil {
t.Fatal(err)
}
return reg
}
func TestSearchToolsRegistered(t *testing.T) {
reg := newSearchRegistry(t, &fakeProvider{})
for _, name := range []string{"tavily_search", "web_search"} {
if _, _, ok := reg.Get(name); !ok {
t.Errorf("tool %s not registered", name)
}
}
}
func execSearchTool(t *testing.T, reg *Registry, name, args string) core.ToolCallResult {
t.Helper()
return reg.Execute(nil, core.ToolCallRequest{CallID: "c1", Name: name, Arguments: json.RawMessage(args)})
}
func TestSearchExecuteFormatsResults(t *testing.T) {
reg := newSearchRegistry(t, &fakeProvider{resp: agenttools.SearchResponse{
Answer: "概要答案",
Results: []agenttools.SearchResult{
{Title: "结果一", Content: "内容甲", Score: 0.9},
{Title: "结果二", Content: "内容乙", Score: 0.8},
},
}})
res := execSearchTool(t, reg, "tavily_search", `{"query":"超声 法规","search_depth":"basic","max_results":5}`)
if res.Status != "ok" {
t.Fatalf("status=%s output=%q", res.Status, res.Output)
}
for _, want := range []string{"Tavily 实时网络搜索结果", "概要答案", "结果一", "内容乙"} {
if !strings.Contains(res.Output, want) {
t.Errorf("output missing %q:\n%s", want, res.Output)
}
}
}
func TestSearchEmptyQuery(t *testing.T) {
reg := newSearchRegistry(t, &fakeProvider{})
res := execSearchTool(t, reg, "web_search", `{"query":" "}`)
if res.Status == "ok" || !strings.Contains(res.Output, "query cannot be empty") {
t.Errorf("empty query: status=%s out=%q", res.Status, res.Output)
}
}
func TestSearchFailureFallback(t *testing.T) {
reg := newSearchRegistry(t, &fakeProvider{err: errors.New("all keys failed")})
res := execSearchTool(t, reg, "tavily_search", `{"query":"q"}`)
if res.Status == "ok" {
t.Error("provider failure should surface as tool error status")
}
if !strings.Contains(res.Output, "[Tavily Search Failed]") || !strings.Contains(res.Output, "fallback") {
t.Errorf("fallback copy missing: %q", res.Output)
}
}