test: add test with tool

Andrey Nering created

Change summary

providertests/provider_test.go                               | 45 ++++
providertests/testdata/TestTool/anthropic-claude-sonnet.yaml | 63 ++++++
providertests/testdata/TestTool/openai-gpt-4o.yaml           | 26 ++
3 files changed, 134 insertions(+)

Detailed changes

providertests/provider_test.go 🔗

@@ -1,6 +1,7 @@
 package providertests
 
 import (
+	"context"
 	"strings"
 	"testing"
 
@@ -37,3 +38,47 @@ func TestSimple(t *testing.T) {
 		})
 	}
 }
+
+func TestTool(t *testing.T) {
+	for _, pair := range languageModelBuilders {
+		t.Run(pair.name, func(t *testing.T) {
+			r := newRecorder(t)
+
+			languageModel, err := pair.builder(r)
+			if err != nil {
+				t.Fatalf("failed to build language model: %v", err)
+			}
+
+			type WeatherInput struct {
+				Location string `json:"location" description:"the city"`
+			}
+
+			weatherTool := ai.NewAgentTool(
+				"weather",
+				"Get weather information for a location",
+				func(ctx context.Context, input WeatherInput, _ ai.ToolCall) (ai.ToolResponse, error) {
+					return ai.NewTextResponse("40 C"), nil
+				},
+			)
+
+			agent := ai.NewAgent(
+				languageModel,
+				ai.WithSystemPrompt("You are a helpful assistant"),
+				ai.WithTools(weatherTool),
+			)
+			result, err := agent.Generate(t.Context(), ai.AgentCall{
+				Prompt: "What's the weather in Florence?",
+			})
+			if err != nil {
+				t.Fatalf("failed to generate: %v", err)
+			}
+
+			want1 := "Florence"
+			want2 := "40"
+			got := result.Response.Content.Text()
+			if !strings.Contains(got, want1) || !strings.Contains(got, want2) {
+				t.Fatalf("unexpected response: got %q, want %q %q", got, want1, want2)
+			}
+		})
+	}
+}

providertests/testdata/TestTool/anthropic-claude-sonnet.yaml 🔗

@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+  request:
+    proto: HTTP/1.1
+    proto_major: 1
+    proto_minor: 1
+    content_length: 490
+    host: ""
+    body: "{\"max_tokens\":4096,\"messages\":[{\"content\":[{\"text\":\"What's the weather in Florence?\",\"type\":\"text\"}],\"role\":\"user\"}],\"model\":\"claude-sonnet-4-20250514\",\"system\":[{\"text\":\"You are a helpful assistant\",\"type\":\"text\"}],\"tool_choice\":{\"disable_parallel_tool_use\":false,\"type\":\"auto\"},\"tools\":[{\"input_schema\":{\"properties\":{\"location\":{\"description\":\"the city\",\"type\":\"string\"}},\"required\":[\"location\"],\"type\":\"object\"},\"name\":\"weather\",\"description\":\"Get weather information for a location\"}]}"
+    headers:
+      Accept:
+      - application/json
+      Content-Type:
+      - application/json
+      User-Agent:
+      - Anthropic/Go 1.10.0
+    url: https://api.anthropic.com/v1/messages
+    method: POST
+  response:
+    proto: HTTP/2.0
+    proto_major: 2
+    proto_minor: 0
+    content_length: -1
+    uncompressed: true
+    body: "{\"id\":\"msg_01EnEXYvvJsZqCkmy6JSJbmZ\",\"type\":\"message\",\"role\":\"assistant\",\"model\":\"claude-sonnet-4-20250514\",\"content\":[{\"type\":\"text\",\"text\":\"I'll get the weather information for Florence for you.\"},{\"type\":\"tool_use\",\"id\":\"toolu_01DuHpbePNYnbErjgBf5iHsF\",\"name\":\"weather\",\"input\":{\"location\":\"Florence\"}}],\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"usage\":{\"input_tokens\":392,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":63,\"service_tier\":\"standard\"}}"
+    headers:
+      Content-Type:
+      - application/json
+    status: 200 OK
+    code: 200
+    duration: 2.213104625s
+- id: 1
+  request:
+    proto: HTTP/1.1
+    proto_major: 1
+    proto_minor: 1
+    content_length: 850
+    host: ""
+    body: "{\"max_tokens\":4096,\"messages\":[{\"content\":[{\"text\":\"What's the weather in Florence?\",\"type\":\"text\"}],\"role\":\"user\"},{\"content\":[{\"text\":\"I'll get the weather information for Florence for you.\",\"type\":\"text\"},{\"id\":\"toolu_01DuHpbePNYnbErjgBf5iHsF\",\"input\":{\"location\":\"Florence\"},\"name\":\"weather\",\"type\":\"tool_use\"}],\"role\":\"assistant\"},{\"content\":[{\"tool_use_id\":\"toolu_01DuHpbePNYnbErjgBf5iHsF\",\"content\":[{\"text\":\"40 C\",\"type\":\"text\"}],\"type\":\"tool_result\"}],\"role\":\"user\"}],\"model\":\"claude-sonnet-4-20250514\",\"system\":[{\"text\":\"You are a helpful assistant\",\"type\":\"text\"}],\"tool_choice\":{\"disable_parallel_tool_use\":false,\"type\":\"auto\"},\"tools\":[{\"input_schema\":{\"properties\":{\"location\":{\"description\":\"the city\",\"type\":\"string\"}},\"required\":[\"location\"],\"type\":\"object\"},\"name\":\"weather\",\"description\":\"Get weather information for a location\"}]}"
+    headers:
+      Accept:
+      - application/json
+      Content-Type:
+      - application/json
+      User-Agent:
+      - Anthropic/Go 1.10.0
+    url: https://api.anthropic.com/v1/messages
+    method: POST
+  response:
+    proto: HTTP/2.0
+    proto_major: 2
+    proto_minor: 0
+    content_length: -1
+    uncompressed: true
+    body: "{\"id\":\"msg_01HyNDRGB4Vs42jfUPPcBaak\",\"type\":\"message\",\"role\":\"assistant\",\"model\":\"claude-sonnet-4-20250514\",\"content\":[{\"type\":\"text\",\"text\":\"The current temperature in Florence is 40°C (104°F). That's quite hot! Make sure to stay hydrated and seek shade or air conditioning if you're in the area.\"}],\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"usage\":{\"input_tokens\":470,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":42,\"service_tier\":\"standard\"}}"
+    headers:
+      Content-Type:
+      - application/json
+    status: 200 OK
+    code: 200
+    duration: 2.306400542s

providertests/testdata/TestTool/openai-gpt-4o.yaml 🔗

@@ -0,0 +1,63 @@
+---
+version: 2
+interactions:
+- id: 0
+  request:
+    proto: HTTP/1.1
+    proto_major: 1
+    proto_minor: 1
+    content_length: 424
+    host: ""
+    body: "{\"messages\":[{\"content\":\"You are a helpful assistant\",\"role\":\"system\"},{\"content\":\"What's the weather in Florence?\",\"role\":\"user\"}],\"model\":\"gpt-4o\",\"tool_choice\":\"auto\",\"tools\":[{\"function\":{\"name\":\"weather\",\"strict\":false,\"description\":\"Get weather information for a location\",\"parameters\":{\"properties\":{\"location\":{\"description\":\"the city\",\"type\":\"string\"}},\"required\":[\"location\"],\"type\":\"object\"}},\"type\":\"function\"}]}"
+    headers:
+      Accept:
+      - application/json
+      Content-Type:
+      - application/json
+      User-Agent:
+      - OpenAI/Go 2.3.0
+    url: https://api.openai.com/v1/chat/completions
+    method: POST
+  response:
+    proto: HTTP/2.0
+    proto_major: 2
+    proto_minor: 0
+    content_length: -1
+    uncompressed: true