Skip to content

Commit a1651fd

Browse files
edburnsCopilot
andcommitted
Add Node.js 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>
1 parent 0763c09 commit a1651fd

3 files changed

Lines changed: 50 additions & 4 deletions

File tree

nodejs/test/e2e/session_lifecycle.e2e.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ describe("Session Lifecycle", async () => {
3232

3333
// Sessions must have activity to be persisted to disk
3434
await session1.sendAndWait({ prompt: "Say hello" });
35-
await session2.sendAndWait({ prompt: "Say world" });
35+
await session2.sendAndWait({ prompt: "Say hi" });
3636

3737
// Poll until both sessions are visible on disk instead of a hard 500ms wait.
3838
await waitFor(async () => {

nodejs/test/e2e/tools.e2e.test.ts

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { writeFile } from "fs/promises";
66
import { join } from "path";
77
import { assert, describe, expect, it } from "vitest";
88
import { z } from "zod";
9-
import { defineTool, approveAll } from "../../src/index.js";
9+
import { defineTool, approveAll, ToolSet } from "../../src/index.js";
1010
import type { PermissionRequest } from "../../src/index.js";
1111
import { createSdkTestContext } from "./harness/sdkTestContext";
1212

@@ -45,6 +45,52 @@ describe("Custom tools", async () => {
4545
expect(assistantMessage?.data.content).toContain("HELLO");
4646
});
4747

48+
it("low_level_tool_definition", async () => {
49+
let currentPhase = "";
50+
const session = await client.createSession({
51+
onPermissionRequest: approveAll,
52+
availableTools: new ToolSet().addCustom("*").addBuiltIn("web_fetch"),
53+
tools: [
54+
defineTool("set_current_phase", {
55+
description: "Sets the current phase of the agent",
56+
parameters: z.object({
57+
phase: z.enum(["searching", "analyzing", "done"]),
58+
}),
59+
handler: ({ phase }) => {
60+
currentPhase = phase;
61+
return `Phase set to ${phase}`;
62+
},
63+
}),
64+
defineTool("search_items", {
65+
description: "Search for items by keyword",
66+
parameters: z.object({
67+
keyword: z.string(),
68+
}),
69+
handler: (_args, invocation) => {
70+
const args = invocation.arguments as Record<string, unknown>;
71+
if (args.keyword !== "copilot") {
72+
throw new Error(`Expected keyword to be 'copilot', got: ${String(args.keyword)}`);
73+
}
74+
return "Found: item_alpha, item_beta";
75+
},
76+
}),
77+
],
78+
});
79+
80+
const assistantMessage = await session.sendAndWait({
81+
prompt: "First, set the current phase to 'analyzing'. Then search for items with keyword 'copilot'. Report the phase and search results.",
82+
});
83+
84+
const content = assistantMessage?.data.content ?? "";
85+
expect(content.length).toBeGreaterThan(0);
86+
expect(content.toLowerCase()).toContain("analyzing");
87+
expect(
88+
content.toLowerCase().includes("item_alpha") ||
89+
content.toLowerCase().includes("item_beta")
90+
).toBe(true);
91+
expect(currentPhase).toBe("analyzing");
92+
});
93+
4894
it("handles tool calling errors", async () => {
4995
const session = await client.createSession({
5096
onPermissionRequest: approveAll,

test/snapshots/session_lifecycle/should_list_created_sessions_after_sending_a_message.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ conversations:
1313
- role: system
1414
content: ${system}
1515
- role: user
16-
content: Say world
16+
content: Say hi
1717
- role: assistant
18-
content: world
18+
content: Hi! I'm GitHub Copilot CLI, ready to help with your software engineering tasks. What would you like to work on?

0 commit comments

Comments
 (0)