1package main
2
3// This example shows how to use provider-defined tools like Anthropic's
4// built-in web search. Provider tools are executed server-side by the model
5// provider, so there's no local tool implementation needed.
6
7import (
8 "context"
9 "fmt"
10 "os"
11 "strings"
12
13 "charm.land/fantasy"
14 "charm.land/fantasy/providers/anthropic"
15)
16
17func main() {
18 opts := []anthropic.Option{
19 anthropic.WithAPIKey(os.Getenv("ANTHROPIC_API_KEY")),
20 }
21 if baseURL := os.Getenv("ANTHROPIC_BASE_URL"); baseURL != "" {
22 opts = append(opts, anthropic.WithBaseURL(baseURL))
23 }
24
25 provider, err := anthropic.New(opts...)
26 if err != nil {
27 fmt.Fprintln(os.Stderr, "Error creating provider:", err)
28 os.Exit(1)
29 }
30
31 ctx := context.Background()
32
33 model, err := provider.LanguageModel(ctx, "claude-sonnet-4-20250514")
34 if err != nil {
35 fmt.Fprintln(os.Stderr, "Error creating model:", err)
36 os.Exit(1)
37 }
38
39 // Use the web search tool helper. Pass nil for defaults, or configure
40 // with options like MaxUses, AllowedDomains, and UserLocation.
41 webSearch := anthropic.WebSearchTool(nil)
42
43 agent := fantasy.NewAgent(model,
44 fantasy.WithProviderDefinedTools(webSearch),
45 )
46
47 result, err := agent.Generate(ctx, fantasy.AgentCall{
48 Prompt: "What is the current weather in San Francisco?",
49 })
50 if err != nil {
51 fmt.Fprintln(os.Stderr, "Error:", err)
52 os.Exit(1)
53 }
54
55 // Collect all text parts. With web search the model interleaves
56 // text around tool calls, producing multiple TextContent parts.
57 var text strings.Builder
58 for _, c := range result.Response.Content {
59 if tc, ok := c.(fantasy.TextContent); ok {
60 text.WriteString(tc.Text)
61 }
62 }
63 fmt.Println(text.String())
64
65 // Print any web sources the model cited.
66 for _, source := range result.Response.Content.Sources() {
67 fmt.Printf("Source: %s — %s\n", source.Title, source.URL)
68 }
69}