@@ -439,6 +439,72 @@ public void process_statefulAggregation_tracksArtifactIdAndAppendForAuthor() {
439439 assertThat (ev3 .getArtifact ().artifactId ()).isEqualTo (firstArtifactId );
440440 }
441441
442+ @ Test
443+ public void execute_withDefaultArtifactPerRun_emitsMessageAndLastChunk () {
444+ Event partialEvent =
445+ Event .builder ()
446+ .partial (true )
447+ .author ("agent" )
448+ .content (
449+ Content .builder ()
450+ .parts (ImmutableList .of (Part .builder ().text ("chunk1" ).build ()))
451+ .build ())
452+ .build ();
453+ Event finalEvent =
454+ Event .builder ()
455+ .partial (false )
456+ .author ("agent" )
457+ .content (
458+ Content .builder ()
459+ .parts (ImmutableList .of (Part .builder ().text ("chunk1chunk2" ).build ()))
460+ .build ())
461+ .build ();
462+
463+ testAgent .setEventsToEmit (Flowable .just (partialEvent , finalEvent ));
464+ AgentExecutor executor =
465+ new AgentExecutor .Builder ()
466+ .app (App .builder ().name ("test_app" ).rootAgent (testAgent ).build ())
467+ .sessionService (new InMemorySessionService ())
468+ .artifactService (new InMemoryArtifactService ())
469+ .agentExecutorConfig (
470+ AgentExecutorConfig .builder ()
471+ .outputMode (AgentExecutorConfig .OutputMode .ARTIFACT_PER_RUN )
472+ .build ())
473+ .build ();
474+
475+ RequestContext requestContext = createRequestContext ();
476+ executor .execute (requestContext , eventQueue );
477+
478+ // Verify events were correctly formed.
479+ ImmutableList <TaskArtifactUpdateEvent > artifactEvents =
480+ enqueuedEvents .stream ()
481+ .filter (e -> e instanceof TaskArtifactUpdateEvent )
482+ .map (e -> (TaskArtifactUpdateEvent ) e )
483+ .collect (toImmutableList ());
484+
485+ assertThat (artifactEvents ).hasSize (2 );
486+ // Partial event has lastChunk = false
487+ assertThat (artifactEvents .get (0 ).isLastChunk ()).isFalse ();
488+ // Final event has lastChunk = true
489+ assertThat (artifactEvents .get (1 ).isLastChunk ()).isTrue ();
490+
491+ // First chunk appends=false, subsequent chunks append=true
492+ assertThat (artifactEvents .get (0 ).isAppend ()).isFalse ();
493+ assertThat (artifactEvents .get (1 ).isAppend ()).isTrue ();
494+
495+ // Now verify the final TaskStatusUpdateEvent has a null message as expected
496+ Optional <TaskStatusUpdateEvent > statusEvent =
497+ enqueuedEvents .stream ()
498+ .filter (e -> e instanceof TaskStatusUpdateEvent )
499+ .map (e -> (TaskStatusUpdateEvent ) e )
500+ .filter (TaskStatusUpdateEvent ::isFinal )
501+ .findFirst ();
502+
503+ assertThat (statusEvent ).isPresent ();
504+ Message finalMessage = statusEvent .get ().getStatus ().message ();
505+ assertThat (finalMessage ).isNull ();
506+ }
507+
442508 private static final class TestAgent extends BaseAgent {
443509 private Flowable <Event > eventsToEmit ;
444510
0 commit comments