Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions go/internal/e2e/tools_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,80 @@ func TestToolsE2E(t *testing.T) {
}
})

t.Run("low_level_tool_definition", func(t *testing.T) {
ctx.ConfigureForTest(t)

type PhaseArgs struct {
Phase string `json:"phase" jsonschema:"Current phase,enum=searching,enum=analyzing,enum=done"`
}
type SearchArgs struct {
Keyword string `json:"keyword" jsonschema:"Search keyword"`
}

currentPhase := ""

setCurrentPhaseTool := copilot.DefineTool("set_current_phase", "Sets the current phase of the agent",
func(params PhaseArgs, inv copilot.ToolInvocation) (string, error) {
currentPhase = params.Phase
return "Phase set to " + params.Phase, nil
})

searchItemsTool := copilot.DefineTool("search_items", "Search for items by keyword",
func(params SearchArgs, inv copilot.ToolInvocation) (string, error) {
if params.Keyword != "copilot" {
t.Fatalf("Expected keyword to be 'copilot', got %q", params.Keyword)
}
return "Found: item_alpha, item_beta", nil
})
Comment on lines +98 to +115

session, err := client.CreateSession(t.Context(), &copilot.SessionConfig{
OnPermissionRequest: copilot.PermissionHandler.ApproveAll,
AvailableTools: copilot.NewToolSet().AddCustom("*").AddBuiltIn("web_fetch").ToSlice(),
Tools: []copilot.Tool{
setCurrentPhaseTool,
searchItemsTool,
},
})
if err != nil {
t.Fatalf("Failed to create session: %v", err)
}

_, err = session.Send(t.Context(), copilot.MessageOptions{
Prompt: "First, set the current phase to 'analyzing'. Then search for items with keyword 'copilot'. Report the phase and search results.",
})
if err != nil {
t.Fatalf("Failed to send message: %v", err)
}

answer, err := testharness.GetFinalAssistantMessage(t.Context(), session)
if err != nil {
t.Fatalf("Failed to get assistant message: %v", err)
}

if answer == nil {
t.Fatalf("Expected non-nil assistant message")
}
ad, ok := answer.Data.(*copilot.AssistantMessageData)
if !ok {
t.Fatalf("Expected AssistantMessageData")
}

content := ad.Content
if content == "" {
t.Fatalf("Expected non-empty response")
}
lower := strings.ToLower(content)
if !strings.Contains(lower, "analyzing") {
t.Errorf("Expected response to contain 'analyzing', got %q", content)
}
if !strings.Contains(lower, "item_alpha") && !strings.Contains(lower, "item_beta") {
t.Errorf("Expected response to contain 'item_alpha' or 'item_beta', got %q", content)
}
if currentPhase != "analyzing" {
t.Errorf("Expected currentPhase to be 'analyzing', got %q", currentPhase)
}
})

t.Run("handles tool calling errors", func(t *testing.T) {
ctx.ConfigureForTest(t)

Expand Down
Loading