33import java .util .List ;
44import java .util .Map ;
55import java .util .UUID ;
6+ import java .util .concurrent .atomic .AtomicBoolean ;
67
78import io .a2a .server .agentexecution .RequestContext ;
89import io .a2a .server .events .EventQueue ;
@@ -18,6 +19,8 @@ public class TaskUpdater {
1819 private final EventQueue eventQueue ;
1920 private final String taskId ;
2021 private final String contextId ;
22+ private final AtomicBoolean terminalStateReached = new AtomicBoolean (false );
23+ private final Object stateLock = new Object ();
2124
2225 public TaskUpdater (RequestContext context , EventQueue eventQueue ) {
2326 this .eventQueue = eventQueue ;
@@ -26,20 +29,41 @@ public TaskUpdater(RequestContext context, EventQueue eventQueue) {
2629 }
2730
2831 private void updateStatus (TaskState taskState ) {
29- updateStatus (taskState , null );
32+ updateStatus (taskState , null , taskState . isFinal () );
3033 }
3134
32- private void updateStatus (TaskState state , Message message ) {
33- TaskStatusUpdateEvent event = new TaskStatusUpdateEvent .Builder ()
34- .taskId (taskId )
35- .contextId (contextId )
36- .isFinal (state .isFinal ())
37- .status (new TaskStatus (state , message , null ))
38- .build ();
39- eventQueue .enqueueEvent (event );
35+ private void updateStatus (TaskState taskState , Message message ) {
36+ updateStatus (taskState , message , taskState .isFinal ());
37+ }
38+
39+ private void updateStatus (TaskState state , Message message , boolean isFinal ) {
40+ synchronized (stateLock ) {
41+ // Check if we're already in a terminal state
42+ if (terminalStateReached .get ()) {
43+ throw new IllegalStateException ("Cannot update task status - terminal state already reached" );
44+ }
45+
46+ // If this is a final state, set the flag
47+ if (isFinal ) {
48+ terminalStateReached .set (true );
49+ }
50+
51+ TaskStatusUpdateEvent event = new TaskStatusUpdateEvent .Builder ()
52+ .taskId (taskId )
53+ .contextId (contextId )
54+ .isFinal (isFinal )
55+ .status (new TaskStatus (state , message , null ))
56+ .build ();
57+ eventQueue .enqueueEvent (event );
58+ }
4059 }
4160
4261 public void addArtifact (List <Part <?>> parts , String artifactId , String name , Map <String , Object > metadata ) {
62+ addArtifact (parts , artifactId , name , metadata , null , null );
63+ }
64+
65+ public void addArtifact (List <Part <?>> parts , String artifactId , String name , Map <String , Object > metadata ,
66+ Boolean append , Boolean lastChunk ) {
4367 if (artifactId == null ) {
4468 artifactId = UUID .randomUUID ().toString ();
4569 }
@@ -54,6 +78,8 @@ public void addArtifact(List<Part<?>> parts, String artifactId, String name, Map
5478 .metadata (metadata )
5579 .build ()
5680 )
81+ .append (append )
82+ .lastChunk (lastChunk )
5783 .build ();
5884 eventQueue .enqueueEvent (event );
5985 }
@@ -98,6 +124,46 @@ public void cancel(Message message) {
98124 updateStatus (TaskState .CANCELED , message );
99125 }
100126
127+ public void reject () {
128+ reject (null );
129+ }
130+
131+ public void reject (Message message ) {
132+ updateStatus (TaskState .REJECTED , message );
133+ }
134+
135+ public void requiresInput () {
136+ requiresInput (null , false );
137+ }
138+
139+ public void requiresInput (Message message ) {
140+ requiresInput (message , false );
141+ }
142+
143+ public void requiresInput (boolean isFinal ) {
144+ requiresInput (null , isFinal );
145+ }
146+
147+ public void requiresInput (Message message , boolean isFinal ) {
148+ updateStatus (TaskState .INPUT_REQUIRED , message , isFinal );
149+ }
150+
151+ public void requiresAuth () {
152+ requiresAuth (null , false );
153+ }
154+
155+ public void requiresAuth (Message message ) {
156+ requiresAuth (message , false );
157+ }
158+
159+ public void requiresAuth (boolean isFinal ) {
160+ requiresAuth (null , isFinal );
161+ }
162+
163+ public void requiresAuth (Message message , boolean isFinal ) {
164+ updateStatus (TaskState .AUTH_REQUIRED , message , isFinal );
165+ }
166+
101167 public Message newAgentMessage (List <Part <?>> parts , Map <String , Object > metadata ) {
102168 return new Message .Builder ()
103169 .role (Message .Role .AGENT )
0 commit comments