Feature request: Plumb AbortSignal through ToolInvocation so session.abort() can cancel in-flight tool handlers
Summary
session.abort() cancels the agentic loop (no further tool calls scheduled) but does not propagate cancellation into a currently-executing tool handler. The handler runs to completion regardless. This forces SDK consumers building wedge-recovery to implement OS-level process tree kills at their own layer, when the cooperative cancellation primitive could live in the SDK.
Verified state at @github/copilot-sdk (dist/)
1. ToolInvocation interface (types.d.ts:224-233):
export interface ToolInvocation {
sessionId: string;
toolCallId: string;
toolName: string;
arguments: unknown;
/** W3C Trace Context traceparent from the CLI's execute_tool span. */
traceparent?: string;
/** W3C Trace Context tracestate from the CLI's execute_tool span. */
tracestate?: string;
}
No signal, no abortSignal, no cancellation handle.
2. _executeToolAndRespond (session.js:278-309):
async _executeToolAndRespond(requestId, toolName, toolCallId, args, handler, traceparent, tracestate) {
try {
const rawResult = await handler(args, { sessionId, toolCallId, toolName, arguments: args, traceparent, tracestate });
...
} catch (error) { ... }
}
Handler is awaited synchronously; no signal threaded through; no race against an abort source.
3. session.abort() (session.js:765-769):
async abort() {
await this.connection.sendRequest("session.abort", { sessionId: this.sessionId });
}
JSDoc: "and can continue to be used for new messages" + "resolves when the abort request is acknowledged." Confirms scope is the agentic loop, not the handler.
4. Searched node_modules/@github/copilot-sdk/dist/ for AbortSignal|AbortController|signal:|cancel\(|cancellation: zero matches.
Proposed API
Add an optional AbortSignal to ToolInvocation that aborts when session.abort() (or a new session.cancelToolCall(toolCallId)) is called:
export interface ToolInvocation {
sessionId: string;
toolCallId: string;
toolName: string;
arguments: unknown;
/** Aborts when session.abort() or session.cancelToolCall(toolCallId) is invoked. */
signal: AbortSignal;
traceparent?: string;
tracestate?: string;
}
Optional addition: a more granular session.cancelToolCall(toolCallId) that cancels a specific in-flight handler without aborting the broader agentic loop.
Why it matters
Without handler-level cancellation, consumers building wedge-recovery (long-running shell handlers, network calls, file I/O on large files) must:
- Track child PIDs at handler-spawn or via shell tool event streams,
- Issue OS-level kills (Windows
taskkill /F /T /PID, POSIX SIGKILL fan-out across descendant tree),
- Re-probe survivors with bounded wait,
- Manage orphan-leak edge cases.
That's ~125 lines of code per consumer plus cross-platform paths. A cooperative AbortSignal in the SDK lets handlers self-terminate cleanly — fetch(url, { signal }), await sleep(ms, { signal }), child_process.spawn(...).on(signal.aborted, kill) — which is the well-trodden Node.js cancellation idiom.
Backwards compatibility
AbortSignal is non-required for handlers that don't consume it (existing handlers continue to work). Handlers that opt in get cooperative cancellation; the SDK keeps its existing process-isolation guarantees.
Concrete consumer evidence
Parley (multi-agent orchestration system built on @github/copilot-sdk) ships at present a 313-line wedge-kill primitive in our orchestrator (Windows taskkill /F /T /PID + POSIX SIGKILL fan-out + bounded post-kill verify + tracker reset) that exists specifically because session.abort() doesn't propagate. With this feature, that primitive would be ~30 lines of if (signal.aborted) cleanup() in the consumer's tool handlers.
Workaround until landed
OS-level process tree kill via tracked child PIDs from tool start events, gated by a bounded post-kill verify. Functional but not durable. Issue tracks the durable layer.
Affected versions
Verified against @github/copilot-sdk shipped in current Parley node_modules snapshot (May 2026). Please confirm whether the proposed API has been considered or is on the roadmap.
Feature request: Plumb AbortSignal through ToolInvocation so session.abort() can cancel in-flight tool handlers
Summary
session.abort()cancels the agentic loop (no further tool calls scheduled) but does not propagate cancellation into a currently-executing tool handler. The handler runs to completion regardless. This forces SDK consumers building wedge-recovery to implement OS-level process tree kills at their own layer, when the cooperative cancellation primitive could live in the SDK.Verified state at
@github/copilot-sdk(dist/)1.
ToolInvocationinterface (types.d.ts:224-233):No
signal, noabortSignal, no cancellation handle.2.
_executeToolAndRespond(session.js:278-309):Handler is awaited synchronously; no signal threaded through; no race against an abort source.
3.
session.abort()(session.js:765-769):JSDoc: "and can continue to be used for new messages" + "resolves when the abort request is acknowledged." Confirms scope is the agentic loop, not the handler.
4. Searched
node_modules/@github/copilot-sdk/dist/forAbortSignal|AbortController|signal:|cancel\(|cancellation: zero matches.Proposed API
Add an optional
AbortSignaltoToolInvocationthat aborts whensession.abort()(or a newsession.cancelToolCall(toolCallId)) is called:Optional addition: a more granular
session.cancelToolCall(toolCallId)that cancels a specific in-flight handler without aborting the broader agentic loop.Why it matters
Without handler-level cancellation, consumers building wedge-recovery (long-running shell handlers, network calls, file I/O on large files) must:
taskkill /F /T /PID, POSIXSIGKILLfan-out across descendant tree),That's ~125 lines of code per consumer plus cross-platform paths. A cooperative
AbortSignalin the SDK lets handlers self-terminate cleanly —fetch(url, { signal }),await sleep(ms, { signal }),child_process.spawn(...).on(signal.aborted, kill)— which is the well-trodden Node.js cancellation idiom.Backwards compatibility
AbortSignalis non-required for handlers that don't consume it (existing handlers continue to work). Handlers that opt in get cooperative cancellation; the SDK keeps its existing process-isolation guarantees.Concrete consumer evidence
Parley (multi-agent orchestration system built on
@github/copilot-sdk) ships at present a 313-line wedge-kill primitive in our orchestrator (Windowstaskkill /F /T /PID+ POSIX SIGKILL fan-out + bounded post-kill verify + tracker reset) that exists specifically becausesession.abort()doesn't propagate. With this feature, that primitive would be ~30 lines ofif (signal.aborted) cleanup()in the consumer's tool handlers.Workaround until landed
OS-level process tree kill via tracked child PIDs from tool start events, gated by a bounded post-kill verify. Functional but not durable. Issue tracks the durable layer.
Affected versions
Verified against
@github/copilot-sdkshipped in current Parleynode_modulessnapshot (May 2026). Please confirm whether the proposed API has been considered or is on the roadmap.