Skip to content

Commit 0f22ce5

Browse files
edburnsCopilot
andauthored
Add Go low-level tool-definition E2E test [2/6] (#1724)
* Add Go low-level tool-definition E2E test Related to issue #1682 but does not fix #1682. Align low_level_tool_definition coverage with PR #1721 snapshot behavior by only defining tools exercised by the shared snapshot. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address Go PR review suggestions for low-level tool test Synchronize handler-updated state with a mutex and move keyword assertion to the main test goroutine to avoid calling t.Fatalf from a tool handler goroutine. Related to issue #1682 but does not fix #1682. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent cc7e5f3 commit 0f22ce5

1 file changed

Lines changed: 85 additions & 0 deletions

File tree

go/internal/e2e/tools_e2e_test.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,91 @@ func TestToolsE2E(t *testing.T) {
8484
}
8585
})
8686

87+
t.Run("low_level_tool_definition", func(t *testing.T) {
88+
ctx.ConfigureForTest(t)
89+
90+
type PhaseArgs struct {
91+
Phase string `json:"phase" jsonschema:"Current phase,enum=searching,enum=analyzing,enum=done"`
92+
}
93+
type SearchArgs struct {
94+
Keyword string `json:"keyword" jsonschema:"Search keyword"`
95+
}
96+
97+
var mu sync.Mutex
98+
currentPhase := ""
99+
searchKeyword := ""
100+
101+
setCurrentPhaseTool := copilot.DefineTool("set_current_phase", "Sets the current phase of the agent",
102+
func(params PhaseArgs, inv copilot.ToolInvocation) (string, error) {
103+
mu.Lock()
104+
currentPhase = params.Phase
105+
mu.Unlock()
106+
return "Phase set to " + params.Phase, nil
107+
})
108+
109+
searchItemsTool := copilot.DefineTool("search_items", "Search for items by keyword",
110+
func(params SearchArgs, inv copilot.ToolInvocation) (string, error) {
111+
mu.Lock()
112+
searchKeyword = params.Keyword
113+
mu.Unlock()
114+
return "Found: item_alpha, item_beta", nil
115+
})
116+
117+
session, err := client.CreateSession(t.Context(), &copilot.SessionConfig{
118+
OnPermissionRequest: copilot.PermissionHandler.ApproveAll,
119+
AvailableTools: copilot.NewToolSet().AddCustom("*").AddBuiltIn("web_fetch").ToSlice(),
120+
Tools: []copilot.Tool{
121+
setCurrentPhaseTool,
122+
searchItemsTool,
123+
},
124+
})
125+
if err != nil {
126+
t.Fatalf("Failed to create session: %v", err)
127+
}
128+
129+
_, err = session.Send(t.Context(), copilot.MessageOptions{
130+
Prompt: "First, set the current phase to 'analyzing'. Then search for items with keyword 'copilot'. Report the phase and search results.",
131+
})
132+
if err != nil {
133+
t.Fatalf("Failed to send message: %v", err)
134+
}
135+
136+
answer, err := testharness.GetFinalAssistantMessage(t.Context(), session)
137+
if err != nil {
138+
t.Fatalf("Failed to get assistant message: %v", err)
139+
}
140+
141+
if answer == nil {
142+
t.Fatalf("Expected non-nil assistant message")
143+
}
144+
ad, ok := answer.Data.(*copilot.AssistantMessageData)
145+
if !ok {
146+
t.Fatalf("Expected AssistantMessageData")
147+
}
148+
149+
content := ad.Content
150+
if content == "" {
151+
t.Fatalf("Expected non-empty response")
152+
}
153+
lower := strings.ToLower(content)
154+
if !strings.Contains(lower, "analyzing") {
155+
t.Errorf("Expected response to contain 'analyzing', got %q", content)
156+
}
157+
if !strings.Contains(lower, "item_alpha") && !strings.Contains(lower, "item_beta") {
158+
t.Errorf("Expected response to contain 'item_alpha' or 'item_beta', got %q", content)
159+
}
160+
mu.Lock()
161+
gotPhase := currentPhase
162+
gotKeyword := searchKeyword
163+
mu.Unlock()
164+
if gotKeyword != "copilot" {
165+
t.Errorf("Expected search keyword to be 'copilot', got %q", gotKeyword)
166+
}
167+
if gotPhase != "analyzing" {
168+
t.Errorf("Expected currentPhase to be 'analyzing', got %q", gotPhase)
169+
}
170+
})
171+
87172
t.Run("handles tool calling errors", func(t *testing.T) {
88173
ctx.ConfigureForTest(t)
89174

0 commit comments

Comments
 (0)