fix(agent): merge abort signals instead of overriding caller's signal
When both timeoutMs and a caller-provided abortSignal were set, the timeout signal silently replaced the caller's signal. Now they are combined via mergeAbortSignals() so either source can cancel the run. Also removes dead array-handling branch in text-tool-extractor.ts (extractJSONObjects only returns objects, never arrays).
This commit is contained in:
parent
bc31008f4e
commit
a4a1add8ca
|
|
@ -50,6 +50,19 @@ import {
|
|||
|
||||
const ZERO_USAGE: TokenUsage = { input_tokens: 0, output_tokens: 0 }
|
||||
|
||||
/**
|
||||
* Combine two {@link AbortSignal}s so that aborting either one cancels the
|
||||
* returned signal. Works on Node 18+ (no `AbortSignal.any` required).
|
||||
*/
|
||||
function mergeAbortSignals(a: AbortSignal, b: AbortSignal): AbortSignal {
|
||||
const controller = new AbortController()
|
||||
if (a.aborted || b.aborted) { controller.abort(); return controller.signal }
|
||||
const abort = () => controller.abort()
|
||||
a.addEventListener('abort', abort, { once: true })
|
||||
b.addEventListener('abort', abort, { once: true })
|
||||
return controller.signal
|
||||
}
|
||||
|
||||
function addUsage(a: TokenUsage, b: TokenUsage): TokenUsage {
|
||||
return {
|
||||
input_tokens: a.input_tokens + b.input_tokens,
|
||||
|
|
@ -298,11 +311,17 @@ export class Agent {
|
|||
const timeoutSignal = this.config.timeoutMs !== undefined && this.config.timeoutMs > 0
|
||||
? AbortSignal.timeout(this.config.timeoutMs)
|
||||
: undefined
|
||||
// Merge caller-provided abortSignal with the timeout signal so that
|
||||
// either cancellation source is respected.
|
||||
const callerAbort = callerOptions?.abortSignal
|
||||
const effectiveAbort = timeoutSignal && callerAbort
|
||||
? mergeAbortSignals(timeoutSignal, callerAbort)
|
||||
: timeoutSignal ?? callerAbort
|
||||
const runOptions: RunOptions = {
|
||||
...callerOptions,
|
||||
onMessage: internalOnMessage,
|
||||
...(needsRunId ? { runId: generateRunId() } : undefined),
|
||||
...(timeoutSignal ? { abortSignal: timeoutSignal } : undefined),
|
||||
...(effectiveAbort ? { abortSignal: effectiveAbort } : undefined),
|
||||
}
|
||||
|
||||
const result = await runner.run(messages, runOptions)
|
||||
|
|
|
|||
|
|
@ -211,15 +211,6 @@ export function extractToolCallsFromText(
|
|||
|
||||
const results: ToolUseBlock[] = []
|
||||
for (const obj of jsonObjects) {
|
||||
// Handle array of tool calls
|
||||
if (Array.isArray(obj)) {
|
||||
for (const item of obj) {
|
||||
const block = parseToolCallJSON(item, nameSet)
|
||||
if (block !== null) results.push(block)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
const block = parseToolCallJSON(obj, nameSet)
|
||||
if (block !== null) results.push(block)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue