@@ -861,7 +861,6 @@ export class AgentLoop {
861
861
throw error ;
862
862
}
863
863
}
864
- turnInput = [ ] ; // clear turn input, prepare for function call results
865
864
866
865
// If the user requested cancellation while we were awaiting the network
867
866
// request, abort immediately before we start handling the stream.
@@ -894,6 +893,8 @@ export class AgentLoop {
894
893
// eslint-disable-next-line no-constant-condition
895
894
while ( true ) {
896
895
try {
896
+ let newTurnInput : Array < ResponseInputItem > = [ ] ;
897
+
897
898
// eslint-disable-next-line no-await-in-loop
898
899
for await ( const event of stream as AsyncIterable < ResponseEvent > ) {
899
900
log ( `AgentLoop.run(): response event ${ event . type } ` ) ;
@@ -935,7 +936,7 @@ export class AgentLoop {
935
936
"requires_action"
936
937
) {
937
938
// TODO: remove this once we can depend on streaming events
938
- const newTurnInput = await this . processEventsWithoutStreaming (
939
+ newTurnInput = await this . processEventsWithoutStreaming (
939
940
event . response . output ,
940
941
stageItem ,
941
942
) ;
@@ -970,24 +971,30 @@ export class AgentLoop {
970
971
971
972
if ( delta . length === 0 ) {
972
973
// No new input => end conversation.
973
- turnInput = [ ] ;
974
+ newTurnInput = [ ] ;
974
975
} else {
975
976
// Re‑send full transcript *plus* the new delta so the
976
977
// stateless backend receives complete context.
977
- turnInput = [ ...this . transcript , ...delta ] ;
978
+ newTurnInput = [ ...this . transcript , ...delta ] ;
978
979
// The prefix ends at the current transcript length –
979
980
// everything after this index is new for the next
980
981
// iteration.
981
982
transcriptPrefixLen = this . transcript . length ;
982
983
}
983
- } else {
984
- turnInput = newTurnInput ;
985
984
}
986
985
}
987
986
lastResponseId = event . response . id ;
988
987
this . onLastResponseId ( event . response . id ) ;
989
988
}
990
989
}
990
+
991
+ // Set after we have consumed all stream events in case the stream wasn't
992
+ // complete or we missed events for whatever reason. That way, we will set
993
+ // the next turn to an empty array to prevent an infinite loop.
994
+ // And don't update the turn input too early otherwise we won't have the
995
+ // current turn inputs available for retries.
996
+ turnInput = newTurnInput ;
997
+
991
998
// Stream finished successfully – leave the retry loop.
992
999
break ;
993
1000
} catch ( err : unknown ) {
0 commit comments