@@ -239,7 +239,6 @@ export interface ParserState {
239239 readonly reasoningDetails : Array < unknown >
240240 readonly reasoningDetailsObserved : boolean
241241 readonly reasoningEmitted : boolean
242- readonly latestToolIndex ?: number
243242 readonly nextToolIndex : number
244243}
245244
@@ -697,7 +696,6 @@ const step = (state: ParserState, event: OpenAIChatEvent) =>
697696 const toolDeltas = delta ?. tool_calls ?? [ ]
698697 let tools = state . tools
699698 let pendingTools = state . pendingTools
700- let latestToolIndex = state . latestToolIndex
701699 let nextToolIndex = state . nextToolIndex
702700
703701 let lifecycle = state . lifecycle
@@ -742,11 +740,15 @@ const step = (state: ParserState, event: OpenAIChatEvent) =>
742740 lifecycle = Lifecycle . textDelta ( lifecycle , events , "text-0" , delta . content )
743741 }
744742
745- // Compatible providers may omit indexes. Prefer durable identity, then use
746- // batch position for parallel deltas or the latest call for sparse chunks.
743+ // Compatible providers may omit indexes. Prefer durable identity, use batch
744+ // position for parallel deltas, and only infer a singleton continuation
745+ // when exactly one call is active.
747746 for ( const [ position , tool ] of toolDeltas . entries ( ) ) {
748747 const matched = toolIndexByID ( tools , pendingTools , tool . id || undefined )
749- const fallback = toolDeltas . length > 1 ? position : ( latestToolIndex ?? position )
748+ const active = Object . keys ( { ...pendingTools , ...tools } ) . map ( Number )
749+ if ( ( tool . index === undefined || tool . index === null ) && matched === undefined && ! tool . id && active . length > 1 )
750+ return yield * ProviderShared . eventError ( ADAPTER , "OpenAI Chat tool call delta has an ambiguous index" )
751+ const fallback = toolDeltas . length > 1 ? position : ( active [ 0 ] ?? position )
750752 const fallbackTool = tools [ fallback ] ?? pendingTools [ fallback ]
751753 const index =
752754 tool . index ?? matched ??
@@ -756,7 +758,6 @@ const step = (state: ParserState, event: OpenAIChatEvent) =>
756758 const id = current ?. id ?? pending ?. id ?? ( tool . id || undefined )
757759 const name = current ?. name ?? pending ?. name ?? ( tool . function ?. name || undefined )
758760 const text = `${ pending ?. input ?? "" } ${ tool . function ?. arguments ?? "" } `
759- latestToolIndex = index
760761 nextToolIndex = Math . max ( nextToolIndex , index + 1 )
761762 if ( ! current && ( ! id || ! name ) ) {
762763 pendingTools = {
@@ -804,7 +805,6 @@ const step = (state: ParserState, event: OpenAIChatEvent) =>
804805 reasoningDetails : state . reasoningDetails ,
805806 reasoningDetailsObserved,
806807 reasoningEmitted,
807- latestToolIndex,
808808 nextToolIndex,
809809 } ,
810810 events ,
0 commit comments