| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- package tools
- import (
- "context"
- "encoding/json"
- "testing"
- "github.com/stretchr/testify/assert"
- )
- // MockTool is a simple tool implementation for testing
- type MockTool struct {
- name string
- description string
- response ToolResponse
- err error
- }
- func (m *MockTool) Info() ToolInfo {
- return ToolInfo{
- Name: m.name,
- Description: m.description,
- Parameters: map[string]any{},
- Required: []string{},
- }
- }
- func (m *MockTool) Run(ctx context.Context, call ToolCall) (ToolResponse, error) {
- return m.response, m.err
- }
- func TestBatchTool(t *testing.T) {
- t.Parallel()
- t.Run("successful batch execution", func(t *testing.T) {
- t.Parallel()
- // Create mock tools
- mockTools := map[string]BaseTool{
- "tool1": &MockTool{
- name: "tool1",
- description: "Mock Tool 1",
- response: NewTextResponse("Tool 1 Response"),
- err: nil,
- },
- "tool2": &MockTool{
- name: "tool2",
- description: "Mock Tool 2",
- response: NewTextResponse("Tool 2 Response"),
- err: nil,
- },
- }
- // Create batch tool
- batchTool := NewBatchTool(mockTools)
- // Create batch call
- input := `{
- "calls": [
- {
- "name": "tool1",
- "input": {}
- },
- {
- "name": "tool2",
- "input": {}
- }
- ]
- }`
- call := ToolCall{
- ID: "test-batch",
- Name: "batch",
- Input: input,
- }
- // Execute batch
- response, err := batchTool.Run(context.Background(), call)
- // Verify results
- assert.NoError(t, err)
- assert.Equal(t, ToolResponseTypeText, response.Type)
- assert.False(t, response.IsError)
- // Parse the response
- var batchResult BatchResult
- err = json.Unmarshal([]byte(response.Content), &batchResult)
- assert.NoError(t, err)
- // Verify batch results
- assert.Len(t, batchResult.Results, 2)
- assert.Empty(t, batchResult.Results[0].Error)
- assert.Empty(t, batchResult.Results[1].Error)
- assert.Empty(t, batchResult.Results[0].Separator)
- assert.NotEmpty(t, batchResult.Results[1].Separator)
- // Verify individual results
- var result1 ToolResponse
- err = json.Unmarshal(batchResult.Results[0].Result, &result1)
- assert.NoError(t, err)
- assert.Equal(t, "Tool 1 Response", result1.Content)
- var result2 ToolResponse
- err = json.Unmarshal(batchResult.Results[1].Result, &result2)
- assert.NoError(t, err)
- assert.Equal(t, "Tool 2 Response", result2.Content)
- })
- t.Run("tool not found", func(t *testing.T) {
- t.Parallel()
- // Create mock tools
- mockTools := map[string]BaseTool{
- "tool1": &MockTool{
- name: "tool1",
- description: "Mock Tool 1",
- response: NewTextResponse("Tool 1 Response"),
- err: nil,
- },
- }
- // Create batch tool
- batchTool := NewBatchTool(mockTools)
- // Create batch call with non-existent tool
- input := `{
- "calls": [
- {
- "name": "tool1",
- "input": {}
- },
- {
- "name": "nonexistent",
- "input": {}
- }
- ]
- }`
- call := ToolCall{
- ID: "test-batch",
- Name: "batch",
- Input: input,
- }
- // Execute batch
- response, err := batchTool.Run(context.Background(), call)
- // Verify results
- assert.NoError(t, err)
- assert.Equal(t, ToolResponseTypeText, response.Type)
- assert.False(t, response.IsError)
- // Parse the response
- var batchResult BatchResult
- err = json.Unmarshal([]byte(response.Content), &batchResult)
- assert.NoError(t, err)
- // Verify batch results
- assert.Len(t, batchResult.Results, 2)
- assert.Empty(t, batchResult.Results[0].Error)
- assert.Contains(t, batchResult.Results[1].Error, "tool not found: nonexistent")
- })
- t.Run("empty calls", func(t *testing.T) {
- t.Parallel()
- // Create batch tool with empty tools map
- batchTool := NewBatchTool(map[string]BaseTool{})
- // Create batch call with empty calls
- input := `{
- "calls": []
- }`
- call := ToolCall{
- ID: "test-batch",
- Name: "batch",
- Input: input,
- }
- // Execute batch
- response, err := batchTool.Run(context.Background(), call)
- // Verify results
- assert.NoError(t, err)
- assert.Equal(t, ToolResponseTypeText, response.Type)
- assert.True(t, response.IsError)
- assert.Contains(t, response.Content, "no tool calls provided")
- })
- t.Run("invalid input", func(t *testing.T) {
- t.Parallel()
- // Create batch tool with empty tools map
- batchTool := NewBatchTool(map[string]BaseTool{})
- // Create batch call with invalid JSON
- input := `{
- "calls": [
- {
- "name": "tool1",
- "input": {
- "invalid": json
- }
- }
- ]
- }`
- call := ToolCall{
- ID: "test-batch",
- Name: "batch",
- Input: input,
- }
- // Execute batch
- response, err := batchTool.Run(context.Background(), call)
- // Verify results
- assert.NoError(t, err)
- assert.Equal(t, ToolResponseTypeText, response.Type)
- assert.True(t, response.IsError)
- assert.Contains(t, response.Content, "error parsing parameters")
- })
- }
|