fix(security): stop delayed and additional tool callbacks after cancellation (#2430)
## Summary - Prevent `chat.completions.runTools()` from starting a privileged parsed tool callback after cancellation occurs during asynchronous argument parsing. - Prevent cancellation from starting the next sequential or later parallel tool callback, for both non-streaming and streaming runners and both external abort signals and `runner.abort()`. - Surface the existing public `APIUserAbortError`, wait for callbacks that were already running, and retain results/messages for callbacks that began before cancellation. - Preserve the SDK's documented completed-buffered-turn compatibility contract: when a completed response is already buffered as cancellation becomes visible, its **first immediate, non-parsing callback may still run**. This exception is consumed once, never permits an asynchronously parsed callback, and never permits a second callback. ## Regression-first proof Before the change, the new real-public-client suite produced **10 failing security cases and 6 passing compatibility controls**: synthetic privileged transfer callbacks ran with the runner signal already aborted. The final **20-case** suite covers non-streaming and streaming public clients, external abort signals and direct runner cancellation, delayed parsers, sequential callbacks, in-flight parallel callback completion, one-shot buffered-turn compatibility, context, parser feedback, and `afterCompletion`. ## Verification - Focused public runner coverage: **58 tests passed** (20 new security/compatibility cases plus all 38 existing runner cases). - Complete handwritten suite: **127 files / 4,064 tests passed**. - Complete generated suite against an isolated private-port Steady server: **82 suites / 559 tests passed**. - Repository formatting and all **415 lint rules** passed. - Strict source TypeScript checking and the complete CJS/ESM package build passed. - Published-source type checking passed with **TypeScript 4.9 and TypeScript 6**. - `publint` passed with only the pre-existing vendor-export warning. - Packed artifact checks passed across **1,216 source maps and 267 browser-safe mapped sources**. - Built-distribution public smoke checks passed for non-streaming and streaming runners, covering both delayed parsing and cancellation between sequential callbacks.
H
Hayden committed
c1685991da6dca1e0813ef25a3b584565278c621
Parent: 01a15bd
Committed by GitHub <noreply@github.com>
on 8/24/2026, 5:34:21 PM