diff --git a/README.md b/README.md index e37aa8a21..848774a82 100644 --- a/README.md +++ b/README.md @@ -17,47 +17,58 @@ Build AI agents with Go. Multi-provider, multi-model, one API. > Fantasy is currently a preview. Expect API changes. ```go -import "charm.land/fantasy" -import "charm.land/fantasy/providers/openrouter" - -// Choose your fave provider. -provider, err := openrouter.New(openrouter.WithAPIKey(myHotKey)) -if err != nil { - fmt.Fprintln(os.Stderr, "Whoops:", err) - os.Exit(1) -} - -ctx := context.Background() - -// Pick your fave model. -model, err := provider.LanguageModel(ctx, "moonshotai/kimi-k2") -if err != nil { - fmt.Fprintln(os.Stderr, "Dang:", err) - os.Exit(1) -} +package woof -// Make your own tools. -cuteDogTool := fantasy.NewAgentTool( - "cute_dog_tool", - "Provide up-to-date info on cute dogs.", - fetchCuteDogInfoFunc, +import ( + "charm.land/fantasy" + "charm.land/fantasy/providers/openrouter" ) -// Equip your agent. -agent := fantasy.NewAgent( - model, - fantasy.WithSystemPrompt("You are a moderately helpful, dog-centric assistant."), - fantasy.WithTools(cuteDogTool), +const ( + apiKey = "sike" + modelId = "moonshotai/kimi-k2" ) -// Put that agent to work! -const prompt = "Find all the cute dogs in Silver Lake, Los Angeles." -result, err := agent.Generate(ctx, fantasy.AgentCall{Prompt: prompt}) -if err != nil { +func processWoof() { + // Choose your fave provider. + provider, err := openrouter.New(openrouter.WithAPIKey(apiKey)) + if err != nil { + fmt.Fprintln(os.Stderr, "Whoops:", err) + os.Exit(1) + } + + ctx := context.Background() + + // Pick your fave model. + model, err := provider.LanguageModel(ctx, modelId) + if err != nil { + fmt.Fprintln(os.Stderr, "Dang:", err) + os.Exit(1) + } + + // Make your own tools. + cuteDogTool := fantasy.NewAgentTool( + "cute_dog_tool", + "Provide up-to-date info on cute dogs.", + fetchCuteDogInfoFunc, + ) + + // Equip your agent. + agent := fantasy.NewAgent( + model, + fantasy.WithSystemPrompt("You are a moderately helpful, dog-centric assistant."), + fantasy.WithTools(cuteDogTool), + ) + + // Put that agent to work! + const prompt = "Find all the cute dogs in Silver Lake, Los Angeles." + result, err := agent.Generate(ctx, fantasy.AgentCall{Prompt: prompt}) + if err != nil { fmt.Fprintln(os.Stderr, "Oof:", err) os.Exit(1) + } + fmt.Println(result.Response.Content.Text()) } -fmt.Println(result.Response.Content.Text()) ``` 🍔 For the full implementation and more [see the examples directory](https://github.com/charmbracelet/fantasy/tree/main/examples). diff --git a/examples/simple/main.go b/examples/simple/main.go index cc6b0f583..28f35916f 100644 --- a/examples/simple/main.go +++ b/examples/simple/main.go @@ -12,9 +12,19 @@ import ( "charm.land/fantasy/providers/openrouter" ) +const ( + apiKey = "sike" + modelId = "moonshotai/kimi-k2" +) + +// Schema for the tool input +type cuteDogQuery struct { + Location string `json:"location" description:"The location to search for cute dogs."` +} + func main() { // Choose your fave provider. - provider, err := openrouter.New(openrouter.WithAPIKey(os.Getenv("OPENROUTER_API_KEY"))) + provider, err := openrouter.New(openrouter.WithAPIKey(os.Getenv(apiKey))) if err != nil { fmt.Fprintln(os.Stderr, "Whoops:", err) os.Exit(1) @@ -23,19 +33,13 @@ func main() { ctx := context.Background() // Pick your fave model. - model, err := provider.LanguageModel(ctx, "moonshotai/kimi-k2") + model, err := provider.LanguageModel(ctx, modelId) if err != nil { fmt.Fprintln(os.Stderr, "Dang:", err) os.Exit(1) } - // Let's make a tool that fetches info about cute dogs. Here's a schema - // for the tool's input. - type cuteDogQuery struct { - Location string `json:"location" description:"The location to search for cute dogs."` - } - - // And here's the implementation of that tool. + // Let's make a tool that fetches info about cute dogs fetchCuteDogInfo := func(ctx context.Context, input cuteDogQuery, _ fantasy.ToolCall) (fantasy.ToolResponse, error) { if input.Location == "Silver Lake, Los Angeles" { return fantasy.NewTextResponse("Cute dogs are everywhere!"), nil diff --git a/examples/stream/main.go b/examples/stream/main.go index ee426205d..6ceb48beb 100644 --- a/examples/stream/main.go +++ b/examples/stream/main.go @@ -14,6 +14,10 @@ import ( "charm.land/fantasy/providers/openai" ) +const ( + modelId = "gpt-5" +) + const systemPrompt = ` You are moderately helpful assistant with a new puppy named Chuck. Chuck is moody and ranges from very happy to very annoyed. He's pretty happy-go-lucky, @@ -33,17 +37,6 @@ type dogInteraction struct { OtherDogName string `json:"dogName" description:"Name of the other dog. Just make something up. All the dogs are named after Japanese cars from the 80s."` } -// Here's a tool call. In this case it's a set of random barks. -func letsBark(ctx context.Context, i dogInteraction, _ fantasy.ToolCall) (fantasy.ToolResponse, error) { - var r fantasy.ToolResponse - if rand.Float64() >= 0.5 { - r.Content = randomBarks(1, 3) - } else { - r.Content = randomBarks(5, 10) - } - return r, nil -} - func main() { // We're going to use OpenAI. apiKey := os.Getenv("OPENAI_API_KEY") @@ -62,7 +55,7 @@ func main() { ctx := context.Background() // Choose the model. - model, err := provider.LanguageModel(ctx, "gpt-5") + model, err := provider.LanguageModel(ctx, modelId) if err != nil { fmt.Println(err) os.Exit(1) @@ -127,6 +120,17 @@ func main() { } } +// Here's a tool call. In this case it's a set of random barks. +func letsBark(_ context.Context, _ dogInteraction, _ fantasy.ToolCall) (fantasy.ToolResponse, error) { + var r fantasy.ToolResponse + if rand.Float64() >= 0.5 { + r.Content = randomBarks(1, 3) + } else { + r.Content = randomBarks(5, 10) + } + return r, nil +} + // Return a random number of barks between low and high. func randomBarks(low, high int) string { const bark = "ruff"