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