@@ -93,6 +93,14 @@ import {
9393 prepareSandboxInterruptedTurnResume ,
9494 type SandboxMemoryPersistenceContext ,
9595} from './runner/sandbox' ;
96+ import {
97+ buildAbortReconciliationInput ,
98+ createStreamAbortReconciliationState ,
99+ getAbortReconciliationPreviousResponseId ,
100+ markAbortReconciliationComplete ,
101+ recordStreamEventForAbortReconciliation ,
102+ shouldReconcileStreamAbort ,
103+ } from './runner/streamReconciliation' ;
96104
97105export type {
98106 CallModelInputFilter ,
@@ -1247,6 +1255,8 @@ export class Runner extends RunHooks<any, AgentOutputType<unknown>> {
12471255 guardrailTracker . throwIfError ( ) ;
12481256
12491257 let finalResponse : ModelResponse | undefined = undefined ;
1258+ const abortReconciliationState =
1259+ createStreamAbortReconciliationState ( ) ;
12501260 let inputMarked = false ;
12511261 const markInputOnce = ( ) => {
12521262 if ( inputMarked || ! serverConversationTracker ) {
@@ -1266,6 +1276,63 @@ export class Runner extends RunHooks<any, AgentOutputType<unknown>> {
12661276 ) ;
12671277 inputMarked = true ;
12681278 } ;
1279+ const reconcileStreamAbortIfNeeded = async ( ) => {
1280+ if (
1281+ ! serverConversationTracker ||
1282+ ! shouldReconcileStreamAbort ( abortReconciliationState )
1283+ ) {
1284+ return ;
1285+ }
1286+
1287+ const reconciliationInput = buildAbortReconciliationInput (
1288+ abortReconciliationState ,
1289+ ) ;
1290+ try {
1291+ const reconciliationResponse = await getResponseWithRetry (
1292+ preparedCall . model ,
1293+ {
1294+ systemInstructions : preparedCall . modelInput . instructions ,
1295+ prompt : preparedCall . prompt ,
1296+ ...( preparedCall . explictlyModelSet
1297+ ? { overridePromptModel : true }
1298+ : { } ) ,
1299+ input : reconciliationInput ,
1300+ previousResponseId : getAbortReconciliationPreviousResponseId (
1301+ abortReconciliationState ,
1302+ preparedCall ,
1303+ ) ,
1304+ conversationId : preparedCall . conversationId ,
1305+ modelSettings : preparedCall . modelSettings ,
1306+ tools : preparedCall . serializedTools ,
1307+ toolsExplicitlyProvided : preparedCall . toolsExplicitlyProvided ,
1308+ handoffs : preparedCall . serializedHandoffs ,
1309+ outputType : convertAgentOutputTypeToSerializable (
1310+ currentAgent . outputType ,
1311+ ) ,
1312+ tracing : getTracing (
1313+ this . config . tracingDisabled ,
1314+ this . config . traceIncludeSensitiveData ,
1315+ ) ,
1316+ } ,
1317+ ) ;
1318+ markAbortReconciliationComplete (
1319+ abortReconciliationState ,
1320+ reconciliationResponse ,
1321+ ) ;
1322+ serverConversationTracker . trackServerItems (
1323+ reconciliationResponse ,
1324+ ) ;
1325+ result . state . setConversationContext (
1326+ serverConversationTracker . conversationId ,
1327+ serverConversationTracker . previousResponseId ,
1328+ ) ;
1329+ } catch ( error ) {
1330+ logger . debug (
1331+ 'Failed to reconcile streamed function calls after abort.' ,
1332+ error ,
1333+ ) ;
1334+ }
1335+ } ;
12691336
12701337 sentInputToModel = true ;
12711338 if ( ! delayStreamInputPersistence ) {
@@ -1301,6 +1368,10 @@ export class Runner extends RunHooks<any, AgentOutputType<unknown>> {
13011368 ) ) {
13021369 guardrailTracker . throwIfError ( ) ;
13031370 markInputOnce ( ) ;
1371+ recordStreamEventForAbortReconciliation (
1372+ abortReconciliationState ,
1373+ event ,
1374+ ) ;
13041375 if ( event . type === 'response_done' ) {
13051376 const parsed = StreamEventResponseCompleted . parse ( event ) ;
13061377 finalResponse = {
@@ -1315,6 +1386,7 @@ export class Runner extends RunHooks<any, AgentOutputType<unknown>> {
13151386 // When the user's code exits a loop to consume the stream, we need to break
13161387 // this loop to prevent internal false errors and unnecessary processing
13171388 await awaitGuardrailsAndPersistInput ( ) ;
1389+ await reconcileStreamAbortIfNeeded ( ) ;
13181390 return ;
13191391 }
13201392 result . _addItem ( new RunRawModelStreamEvent ( event ) ) ;
@@ -1325,6 +1397,7 @@ export class Runner extends RunHooks<any, AgentOutputType<unknown>> {
13251397 markInputOnce ( ) ;
13261398 }
13271399 await awaitGuardrailsAndPersistInput ( ) ;
1400+ await reconcileStreamAbortIfNeeded ( ) ;
13281401 return ;
13291402 }
13301403 throw error ;
0 commit comments