main.go

 1package main
 2
 3// This example demonstrates provider-defined web search tools.
 4// It auto-selects the provider based on which API key is set:
 5//
 6//	ANTHROPIC_API_KEY → Anthropic (Claude)
 7//	OPENAI_API_KEY    → OpenAI (GPT, Responses API)
 8//
 9// Provider tools are executed server-side by the model provider,
10// so there is no local tool implementation needed.
11
12import (
13	"context"
14	"fmt"
15	"os"
16	"strings"
17
18	"charm.land/fantasy"
19	"charm.land/fantasy/providers/anthropic"
20	"charm.land/fantasy/providers/openai"
21)
22
23func main() {
24	ctx := context.Background()
25
26	var (
27		model     fantasy.LanguageModel
28		webSearch fantasy.ProviderDefinedTool
29		err       error
30	)
31
32	switch {
33	case os.Getenv("ANTHROPIC_API_KEY") != "":
34		p, _ := anthropic.New(anthropic.WithAPIKey(os.Getenv("ANTHROPIC_API_KEY")))
35		model, err = p.LanguageModel(ctx, "claude-sonnet-4-20250514")
36		webSearch = anthropic.WebSearchTool(nil)
37
38	case os.Getenv("OPENAI_API_KEY") != "":
39		p, _ := openai.New(
40			openai.WithAPIKey(os.Getenv("OPENAI_API_KEY")),
41			openai.WithUseResponsesAPI(),
42		)
43		model, err = p.LanguageModel(ctx, "gpt-5.4")
44		webSearch = openai.WebSearchTool(nil)
45
46	default:
47		fmt.Fprintln(os.Stderr, "Set ANTHROPIC_API_KEY or OPENAI_API_KEY")
48		os.Exit(1)
49	}
50	if err != nil {
51		fmt.Fprintln(os.Stderr, err)
52		os.Exit(1)
53	}
54
55	agent := fantasy.NewAgent(model,
56		fantasy.WithProviderDefinedTools(webSearch),
57	)
58
59	result, err := agent.Generate(ctx, fantasy.AgentCall{
60		Prompt: "What is the population of Tokyo? Cite your source.",
61	})
62	if err != nil {
63		fmt.Fprintln(os.Stderr, err)
64		os.Exit(1)
65	}
66
67	var text strings.Builder
68	for _, c := range result.Response.Content {
69		if tc, ok := c.(fantasy.TextContent); ok {
70			text.WriteString(tc.Text)
71		}
72	}
73	fmt.Println(text.String())
74
75	for _, source := range result.Response.Content.Sources() {
76		fmt.Printf("Source: %s — %s\n", source.Title, source.URL)
77	}
78}