@@ -1379,6 +1379,77 @@ describe("runEmbeddedAgent incomplete-turn safety", () => {
13791379 ) . toBe ( true ) ;
13801380 } ) ;
13811381
1382+ it ( "uses currentAttemptAssistant over stale lastAssistant for incomplete-turn classification (#80918)" , ( ) => {
1383+ expect (
1384+ isIncompleteTerminalAssistantTurn ( {
1385+ hasAssistantVisibleText : true ,
1386+ lastAssistant : { stopReason : "stop" } as unknown as EmbeddedRunAttemptResult [ "currentAttemptAssistant" ] ,
1387+ } ) ,
1388+ ) . toBe ( false ) ;
1389+ expect (
1390+ isIncompleteTerminalAssistantTurn ( {
1391+ hasAssistantVisibleText : false ,
1392+ lastAssistant : { stopReason : "toolUse" } ,
1393+ } ) ,
1394+ ) . toBe ( true ) ;
1395+ } ) ;
1396+
1397+ it ( "does not flag stale lastAssistant=toolUse when currentAttemptAssistant=stop exists (#80918)" , ( ) => {
1398+ const incompleteTurnText = resolveIncompleteTurnPayloadText ( {
1399+ payloadCount : 1 ,
1400+ aborted : false ,
1401+ timedOut : false ,
1402+ attempt : makeAttemptResult ( {
1403+ assistantTexts : [ "Analysis..." , "Here is the final answer after update_plan." ] ,
1404+ toolMetas : [ { toolName : "update_plan" } ] ,
1405+ lastAssistant : {
1406+ role : "assistant" ,
1407+ stopReason : "toolUse" ,
1408+ provider : "openai" ,
1409+ model : "gpt-5.5" ,
1410+ content : [
1411+ { type : "text" , text : "Analysis..." } ,
1412+ { type : "tool_use" , id : "tool_1" , name : "update_plan" , input : { } } ,
1413+ ] ,
1414+ } as unknown as EmbeddedRunAttemptResult [ "lastAssistant" ] ,
1415+ currentAttemptAssistant : {
1416+ role : "assistant" ,
1417+ stopReason : "stop" ,
1418+ provider : "openai" ,
1419+ model : "gpt-5.5" ,
1420+ content : [ { type : "text" , text : "Here is the final answer after update_plan." } ] ,
1421+ } as unknown as EmbeddedRunAttemptResult [ "currentAttemptAssistant" ] ,
1422+ } ) ,
1423+ } ) ;
1424+
1425+ expect ( incompleteTurnText ) . toBeNull ( ) ;
1426+ } ) ;
1427+
1428+ it ( "still flags incomplete-turn when currentAttemptAssistant is absent and lastAssistant=toolUse (#76477 regression)" , ( ) => {
1429+ const incompleteTurnText = resolveIncompleteTurnPayloadText ( {
1430+ payloadCount : 1 ,
1431+ aborted : false ,
1432+ timedOut : false ,
1433+ attempt : makeAttemptResult ( {
1434+ assistantTexts : [ "Let me update the file..." ] ,
1435+ toolMetas : [ { toolName : "write" } ] ,
1436+ lastAssistant : {
1437+ role : "assistant" ,
1438+ stopReason : "toolUse" ,
1439+ provider : "openai" ,
1440+ model : "gpt-5.4" ,
1441+ content : [
1442+ { type : "text" , text : "Let me update the file..." } ,
1443+ { type : "tool_use" , id : "tool_1" , name : "write" , input : { } } ,
1444+ ] ,
1445+ } as unknown as EmbeddedRunAttemptResult [ "lastAssistant" ] ,
1446+ currentAttemptAssistant : undefined ,
1447+ } ) ,
1448+ } ) ;
1449+
1450+ expect ( incompleteTurnText ) . toContain ( "couldn't generate a response" ) ;
1451+ } ) ;
1452+
13821453 it ( "surfaces no-visible-answer recovery for app-server interrupted tool-only output" , ( ) => {
13831454 const interruptedToolOnlyAttempt = makeAttemptResult ( {
13841455 assistantTexts : [ ] ,
0 commit comments