@@ -308,6 +308,49 @@ void shouldIgnoreUnknownRpcResponses() {
308308 assertFalse (turn .future ().isDone ());
309309 }
310310
311+
312+ @ Test
313+ void shouldStreamRealAgentMessageDeltas () {
314+ List <String > deltas = new ArrayList <>();
315+ CodexAppServerTurn turn = newTurn (
316+ AppServerTurnRequest .builder ().prompt ("hi" ).onDelta (deltas ::add ).build (),
317+ new ThreadMappingCache (10 ));
318+
319+ handshake (turn );
320+ turn .handleFrame ("{\" jsonrpc\" :\" 2.0\" ,\" id\" :2,\" result\" :{\" thread\" :{\" id\" :\" th_1\" }}}" );
321+ turn .handleFrame ("{\" method\" :\" item/agentMessage/delta\" ,\" params\" :{\" threadId\" :\" th_1\" ,"
322+ + "\" turnId\" :\" turn_1\" ,\" itemId\" :\" item_1\" ,\" delta\" :\" 你\" }}" );
323+ turn .handleFrame ("{\" method\" :\" item/agentMessage/delta\" ,\" params\" :{\" threadId\" :\" th_1\" ,"
324+ + "\" turnId\" :\" turn_1\" ,\" itemId\" :\" item_1\" ,\" delta\" :\" 好\" }}" );
325+ turn .handleFrame ("{\" method\" :\" turn/completed\" ,\" params\" :{}}" );
326+
327+ assertEquals (List .of ("你" , "好" ), deltas );
328+ assertEquals ("你好" , turn .future ().join ().getContent ());
329+ }
330+
331+ @ Test
332+ void shouldNotDuplicateCompletedMessageAfterStreamingDeltas () {
333+ List <String > deltas = new ArrayList <>();
334+ CodexAppServerTurn turn = newTurn (
335+ AppServerTurnRequest .builder ().prompt ("hi" ).onDelta (deltas ::add ).build (),
336+ new ThreadMappingCache (10 ));
337+
338+ handshake (turn );
339+ turn .handleFrame ("{\" jsonrpc\" :\" 2.0\" ,\" id\" :2,\" result\" :{\" thread\" :{\" id\" :\" th_1\" }}}" );
340+ turn .handleFrame ("{\" method\" :\" item/agentMessage/delta\" ,\" params\" :{\" threadId\" :\" th_1\" ,"
341+ + "\" turnId\" :\" turn_1\" ,\" itemId\" :\" item_1\" ,\" delta\" :\" 你\" }}" );
342+ turn .handleFrame ("{\" method\" :\" item/agentMessage/delta\" ,\" params\" :{\" threadId\" :\" th_1\" ,"
343+ + "\" turnId\" :\" turn_1\" ,\" itemId\" :\" item_1\" ,\" delta\" :\" 好\" }}" );
344+ turn .handleFrame ("{\" method\" :\" item/completed\" ,\" params\" :{\" item\" :{\" id\" :\" item_1\" ,"
345+ + "\" type\" :\" agentMessage\" ,\" text\" :\" 你好\" }}}" );
346+ turn .handleFrame ("{\" method\" :\" turn/completed\" ,\" params\" :{}}" );
347+
348+ assertEquals (List .of ("你" , "好" ), deltas ,
349+ "item/completed must not re-emit text that already arrived as real deltas" );
350+ assertEquals ("你好" , turn .future ().join ().getContent (),
351+ "completed item must not duplicate already-streamed content" );
352+ }
353+
311354 @ Test
312355 void shouldCollectAgentMessageItemsAndIgnoreOthers () {
313356 List <String > deltas = new ArrayList <>();
0 commit comments