test(agents): cover configured bundle MCP request timeouts (#127529)

Adopted from Microsoft's Lobster patch 0042 via the
giodl73-repo/lobster-plugins-and-patches upstream candidate
(source commit e9f84234ebdf, blob 8e753747babe).
This commit is contained in:
Peter Steinberger
2026-08-21 13:48:36 -07:00
committed by GitHub
parent 3bb1433b78
commit 33a0bea6d0
+75 -1
View File
@@ -339,7 +339,8 @@ function handle(message) {
}
void (async () => {
await waitForPath(callToolReleasePath);
setTimeout(() => {
log("delay tools/call " + callToolDelayMs);
pendingTimer = setTimeout(() => {
send({
jsonrpc: "2.0",
id: message.id,
@@ -1189,6 +1190,79 @@ describe("session MCP runtime", () => {
}
});
it("uses the configured request timeout instead of the connection timeout for delayed MCP tools/list", async () => {
const tempDir = tempDirTracker.make("bundle-mcp-configured-listtools-");
const serverPath = path.join(tempDir, "configured-list-tools.mjs");
const logPath = path.join(tempDir, "server.log");
await writeListToolsMcpServer({
filePath: serverPath,
logPath,
delayMs: 2_000,
});
const runtime = await getOrCreateSessionMcpRuntime({
sessionId: "session-configured-listtools-timeout",
sessionKey: "agent:test:session-configured-listtools-timeout",
workspaceDir: "/workspace",
cfg: {
mcp: {
servers: {
configuredListTools: {
command: process.execPath,
args: [serverPath],
connectionTimeoutMs: 1_000,
requestTimeoutMs: 4_000,
},
},
},
},
});
try {
const catalog = await runtime.getCatalog();
expect(catalog.tools.map((tool) => tool.toolName)).toEqual(["slow_tool"]);
await expect(fs.readFile(logPath, "utf8")).resolves.toContain("delay tools/list 2000");
} finally {
await runtime.dispose();
}
});
it("rejects delayed MCP tools/call responses that exceed the configured request timeout", async () => {
const tempDir = tempDirTracker.make("bundle-mcp-call-timeout-");
const serverPath = path.join(tempDir, "slow-tool-call.mjs");
const logPath = path.join(tempDir, "server.log");
await writeListToolsMcpServer({
filePath: serverPath,
logPath,
callToolDelayMs: 1_500,
});
const runtime = await getOrCreateSessionMcpRuntime({
sessionId: "session-tool-call-timeout",
sessionKey: "agent:test:session-tool-call-timeout",
workspaceDir: "/workspace",
cfg: {
mcp: {
servers: {
slowToolCall: {
command: process.execPath,
args: [serverPath],
requestTimeoutMs: 250,
},
},
},
},
});
try {
await runtime.getCatalog();
await expect(runtime.callTool("slowToolCall", "slow_tool", {})).rejects.toThrow(/timed out/i);
await waitForFileText(logPath, "delay tools/call 1500", LIST_TOOLS_SERVER_LOG_TIMEOUT_MS);
} finally {
await runtime.dispose();
}
});
it("times out default-config hung bundle MCP tools/list using the internal catalog timeout", async () => {
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "bundle-mcp-listtools-timeout-"));
const serverPath = path.join(tempDir, "hanging-list-tools.mjs");