@@ -68,35 +68,68 @@ var response = client.prompt(new PromptRequest(
6868client. close();
6969```
7070
71- ### 2. Hello World Agent
71+ ### 2. Hello World Agent (Sync)
7272
73- Create a minimal ACP agent:
73+ Create a minimal ACP agent using the sync API (recommended for simplicity) :
7474
7575``` java
7676import com.agentclientprotocol.sdk.agent.* ;
7777import com.agentclientprotocol.sdk.agent.transport.* ;
7878import com.agentclientprotocol.sdk.spec.AcpSchema.* ;
79- import reactor.core.publisher.Mono ;
8079import java.util.List ;
80+ import java.util.UUID ;
8181
8282// Create stdio transport
8383var transport = new StdioAcpAgentTransport ();
8484
85- // Build agent with handlers
85+ // Build sync agent - handlers use plain return values (no Mono!)
86+ AcpSyncAgent agent = AcpAgent . sync(transport)
87+ .initializeHandler(req - >
88+ new InitializeResponse (1 , new AgentCapabilities (), List . of()))
89+ .newSessionHandler(req - >
90+ new NewSessionResponse (UUID . randomUUID(). toString(), null , null ))
91+ .promptHandler((req, updater) - > {
92+ // Send updates using blocking void method
93+ updater. sendUpdate(req. sessionId(),
94+ new AgentMessageChunk (" agent_message_chunk" ,
95+ new TextContent (" Hello from the agent!" )));
96+ // Return response directly (no Mono!)
97+ return new PromptResponse (StopReason . END_TURN );
98+ })
99+ .build();
100+
101+ // Run agent (blocks until client disconnects)
102+ agent. run();
103+ ```
104+
105+ ### 2b. Hello World Agent (Async)
106+
107+ For reactive applications, use the async API:
108+
109+ ``` java
110+ import com.agentclientprotocol.sdk.agent.* ;
111+ import com.agentclientprotocol.sdk.agent.transport.* ;
112+ import com.agentclientprotocol.sdk.spec.AcpSchema.* ;
113+ import reactor.core.publisher.Mono ;
114+ import java.util.List ;
115+ import java.util.UUID ;
116+
117+ var transport = new StdioAcpAgentTransport ();
118+
86119AcpAsyncAgent agent = AcpAgent . async(transport)
87120 .initializeHandler(req - > Mono . just(
88- new InitializeResponse (1 , new AgentCapabilities (), List . of())
89- ))
121+ new InitializeResponse (1 , new AgentCapabilities (), List . of())))
90122 .newSessionHandler(req - > Mono . just(
91- new NewSessionResponse (java.util. UUID . randomUUID(). toString(), null , null )
92- ))
93- .promptHandler((req, updater) - > Mono . just(
94- new PromptResponse (StopReason . END_TURN )
95- ))
123+ new NewSessionResponse (UUID . randomUUID(). toString(), null , null )))
124+ .promptHandler((req, updater) - >
125+ updater. sendUpdate(req. sessionId(),
126+ new AgentMessageChunk (" agent_message_chunk" ,
127+ new TextContent (" Hello from the agent!" )))
128+ .then(Mono . just(new PromptResponse (StopReason . END_TURN ))))
96129 .build();
97130
98- // Start and run
99- agent. start(). block();
131+ // Start and await termination
132+ agent. start(). then(agent . awaitTermination()) . block();
100133```
101134
102135---
@@ -105,8 +138,23 @@ agent.start().block();
105138
106139### 3. Streaming Updates
107140
108- Send real-time updates to the client during prompt processing:
141+ Send real-time updates to the client during prompt processing.
142+
143+ ** Agent (Sync) - recommended:**
144+ ``` java
145+ .promptHandler((req, updater) - > {
146+ // Blocking void calls - simple and straightforward
147+ updater. sendUpdate(req. sessionId(),
148+ new AgentThoughtChunk (" agent_thought_chunk" ,
149+ new TextContent (" Thinking..." )));
150+ updater. sendUpdate(req. sessionId(),
151+ new AgentMessageChunk (" agent_message_chunk" ,
152+ new TextContent (" Here's my response." )));
153+ return new PromptResponse (StopReason . END_TURN );
154+ })
155+ ```
109156
157+ ** Agent (Async):**
110158``` java
111159.promptHandler((request, updater) - > {
112160 return updater. sendUpdate(request. sessionId(),
@@ -119,43 +167,59 @@ Send real-time updates to the client during prompt processing:
119167})
120168```
121169
122- Clients receive updates via the session update consumer:
123-
170+ ** Client - receiving updates:**
124171``` java
125- AcpAsyncClient client = AcpClient . async (transport)
172+ AcpSyncClient client = AcpClient . sync (transport)
126173 .sessionUpdateConsumer(notification - > {
127- System . out. println(" Update: " + notification. update());
128- return Mono . empty();
174+ var update = notification. update();
175+ if (update instanceof AgentMessageChunk msg) {
176+ System . out. print(((TextContent ) msg. content()). text());
177+ }
129178 })
130179 .build();
131180```
132181
133182### 4. Agent-to-Client Requests
134183
135- Agents can request file operations from the client:
184+ Agents can request file operations from the client.
136185
186+ ** Agent (Sync) - reading files:**
137187``` java
138- .promptHandler((request, updater) - > {
139- // Read a file from the client's filesystem
140- return agent. readTextFile(new ReadTextFileRequest (
141- request. sessionId(), " /src/Main.java" , null , null ))
142- .flatMap(file - > {
143- String content = file. content();
144- // Process content...
145- return Mono . just(new PromptResponse (StopReason . END_TURN ));
146- });
147- })
148- ```
188+ // Store agent reference for use in prompt handler
189+ AtomicReference<AcpSyncAgent > agentRef = new AtomicReference<> ();
149190
150- Clients must register handlers for agent requests:
191+ AcpSyncAgent agent = AcpAgent . sync(transport)
192+ .promptHandler((req, updater) - > {
193+ AcpSyncAgent agentInstance = agentRef. get();
151194
195+ // Read a file from the client's filesystem
196+ var fileResponse = agentInstance. readTextFile(
197+ new ReadTextFileRequest (req. sessionId(), " pom.xml" , null , 10 ));
198+ String content = fileResponse. content();
199+
200+ // Write a file
201+ agentInstance. writeTextFile(
202+ new WriteTextFileRequest (req. sessionId(), " output.txt" , " Hello!" ));
203+
204+ return new PromptResponse (StopReason . END_TURN );
205+ })
206+ .build();
207+
208+ agentRef. set(agent); // Store reference before running
209+ agent. run();
210+ ```
211+
212+ ** Client - registering file handlers:**
152213``` java
153- AcpAsyncClient client = AcpClient . async(transport)
154- .readTextFileHandler(params - > {
155- // Read file and return content
156- ReadTextFileRequest req = /* unmarshal params */ ;
214+ AcpSyncClient client = AcpClient . sync(transport)
215+ .readTextFileHandler((ReadTextFileRequest req) - > {
216+ // Handlers receive typed requests directly
157217 String content = Files . readString(Path . of(req. path()));
158- return Mono . just(new ReadTextFileResponse (content));
218+ return new ReadTextFileResponse (content);
219+ })
220+ .writeTextFileHandler((WriteTextFileRequest req) - > {
221+ Files . writeString(Path . of(req. path()), req. content());
222+ return new WriteTextFileResponse ();
159223 })
160224 .build();
161225```
@@ -166,7 +230,7 @@ Check what features the peer supports before using them:
166230
167231``` java
168232// Client: check agent capabilities after initialize
169- client. initialize(new InitializeRequest (1 , clientCaps)). block() ;
233+ client. initialize(new InitializeRequest (1 , clientCaps));
170234
171235NegotiatedCapabilities agentCaps = client. getAgentCapabilities();
172236if (agentCaps. supportsLoadSession()) {
0 commit comments