返回 DeepSeek-Reasonix
search_live_test.go
根目录 / internal / websearch / search_live_test.go
1 //go:build live
2
3 package websearch
4
5 import (
6 "context"
7 "encoding/json"
8 "os"
9 "testing"
10
11 "reasonix/internal/config"
12 "reasonix/internal/provider"
13 _ "reasonix/internal/provider/anthropic"
14 )
15
16 // Explicitly opt in: one bounded Flash search on the canonical official search wire.
17 // Credentials remain in memory; only result counts and usage are logged.
18 func TestLiveIndependentWebSearch(t *testing.T) {
19 if os.Getenv("REASONIX_LIVE_WEB_SEARCH") != "1" {
20 t.Skip("set REASONIX_LIVE_WEB_SEARCH=1 to run the bounded live probe")
21 }
22 key := os.Getenv("DEEPSEEK_API_KEY")
23 if key == "" {
24 t.Skip("no official DeepSeek credential available")
25 }
26 entry := &config.ProviderEntry{Name: "deepseek", Kind: "responses", BaseURL: "https://api.deepseek.com", Model: "deepseek-v4-flash", APIKeyEnv: "DEEPSEEK_API_KEY"}
27 entry.ResolveAPIKeyFromProcessEnvForProbe()
28 // Pin only this process credential; do not read or write global credentials.
29 route := (&config.Config{}).ResolveWebSearchProvider(entry)
30 if route == nil {
31 t.Fatal("official search route was not resolved")
32 }
33 if route.Kind != "anthropic" {
34 t.Fatalf("unexpected official search wire: %s", route.Kind)
35 }
36 tool := &Tool{Factory: func() (provider.Provider, error) {
37 return provider.New(route.Kind, provider.Config{Name: route.Name, BaseURL: route.BaseURL, Model: route.Model, APIKey: key, Extra: map[string]any{"web_search": true, "reject_redirects": true, "thinking": "enabled", "effort": "low"}})
38 }, ReportUsage: func(u *provider.Usage) {
39 t.Logf("prompt=%d completion=%d requests=%d", u.PromptTokens, u.CompletionTokens, u.RequestCount)
40 }}
41 output, err := tool.Execute(context.Background(), json.RawMessage(`{"query":"Find the official DeepSeek API thinking mode documentation and summarize its reasoning passback requirement with a source URL."}`))
42 if err != nil {
43 t.Fatal(err)
44 }
45 var result Result
46 if err := json.Unmarshal([]byte(output), &result); err != nil {
47 t.Fatal(err)
48 }
49 if len(result.Sources) == 0 || result.Summary == "" {
50 t.Fatal("search did not return a summary and structured sources")
51 }
52 t.Logf("sources=%d summary_bytes=%d", len(result.Sources), len(result.Summary))
53 }
54
54 lines GO