Merge PR #4271: fix(task): abort underlying MCP call when proxy tool timeout fires (@metaphorics)
This commit is contained in:
@@ -215,7 +215,12 @@ function renderIrcPeerRoster(selfId: string): string {
|
||||
return lines.join("\n");
|
||||
}
|
||||
|
||||
function withAbortTimeout<T>(promise: Promise<T>, timeoutMs: number, signal?: AbortSignal): Promise<T> {
|
||||
function withAbortTimeout<T>(
|
||||
promise: Promise<T>,
|
||||
timeoutMs: number,
|
||||
signal?: AbortSignal,
|
||||
timeoutController?: AbortController,
|
||||
): Promise<T> {
|
||||
if (signal?.aborted) {
|
||||
return Promise.reject(new ToolAbortError());
|
||||
}
|
||||
@@ -225,6 +230,7 @@ function withAbortTimeout<T>(promise: Promise<T>, timeoutMs: number, signal?: Ab
|
||||
const timeoutId = setTimeout(() => {
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
timeoutController?.abort(new DOMException(`MCP tool call timed out after ${timeoutMs}ms`, "TimeoutError"));
|
||||
reject(new Error(`MCP tool call timed out after ${timeoutMs}ms`));
|
||||
}, timeoutMs);
|
||||
|
||||
@@ -232,6 +238,7 @@ function withAbortTimeout<T>(promise: Promise<T>, timeoutMs: number, signal?: Ab
|
||||
if (settled) return;
|
||||
settled = true;
|
||||
clearTimeout(timeoutId);
|
||||
timeoutController?.abort();
|
||||
reject(new ToolAbortError());
|
||||
};
|
||||
|
||||
@@ -708,13 +715,21 @@ export function createMCPProxyTools(mcpManager: MCPManager): CustomTool[] {
|
||||
const serverName = mcpTool.mcpServerName ?? "";
|
||||
const mcpToolName = mcpTool.mcpToolName ?? "";
|
||||
try {
|
||||
const timeoutController = new AbortController();
|
||||
const timeoutSignal = timeoutController.signal;
|
||||
const combinedSignal = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;
|
||||
const result = await withAbortTimeout(
|
||||
(async () => {
|
||||
const connection = await mcpManager.waitForConnection(serverName);
|
||||
return callTool(connection, mcpToolName, params as Record<string, unknown>, { signal });
|
||||
const connection = await untilAborted(combinedSignal, () =>
|
||||
mcpManager.waitForConnection(serverName),
|
||||
);
|
||||
return callTool(connection, mcpToolName, params as Record<string, unknown>, {
|
||||
signal: combinedSignal,
|
||||
});
|
||||
})(),
|
||||
MCP_CALL_TIMEOUT_MS,
|
||||
signal,
|
||||
timeoutController,
|
||||
);
|
||||
return {
|
||||
content: (result.content ?? []).map(item =>
|
||||
|
||||
Reference in New Issue
Block a user