2727 * Asynchronous tool callback interface that supports non-blocking tool execution.
2828 *
2929 * <p>
30- * Unlike traditional {@link ToolCallback}, async tools don't block threads and are suitable
31- * for scenarios involving external API calls, database operations, and other I/O operations.
30+ * Unlike traditional {@link ToolCallback}, async tools don't block threads and are
31+ * suitable for scenarios involving external API calls, database operations, and other I/O
32+ * operations.
3233 *
3334 * <p>
3435 * <strong>Using async tools can significantly improve concurrency performance and prevent
3536 * thread pool exhaustion.</strong>
3637 *
37- * <h2>Basic Usage</h2>
38- * <pre>{@code
39- * @Component
38+ * <h2>Basic Usage</h2> <pre>{@code
39+ * @Component
4040 * public class AsyncWeatherTool implements AsyncToolCallback {
4141 *
4242 * private final WebClient webClient;
4545 * this.webClient = builder.baseUrl("https://api.weather.com").build();
4646 * }
4747 *
48- * @Override
48+
49+ * @Override
4950 * public Mono<String> callAsync(String toolInput, ToolContext context) {
5051 * WeatherRequest request = parseInput(toolInput);
5152 * return webClient.get()
5556 * .timeout(Duration.ofSeconds(5));
5657 * }
5758 *
58- * @Override
59+ *
60+ @Override
5961 * public ToolDefinition getToolDefinition() {
6062 * return ToolDefinition.builder()
6163 * .name("get_weather")
6870 *
6971 * <h2>Backward Compatibility</h2>
7072 * <p>
71- * If only the async method is implemented, the synchronous {@link #call(String, ToolContext)}
72- * method will automatically call {@link #callAsync(String, ToolContext)} and block for the result.
73+ * If only the async method is implemented, the synchronous
74+ * {@link #call(String, ToolContext)} method will automatically call
75+ * {@link #callAsync(String, ToolContext)} and block for the result.
7376 *
7477 * <h2>Performance Benefits</h2>
7578 * <table border="1">
@@ -109,15 +112,15 @@ public interface AsyncToolCallback extends ToolCallback {
109112 *
110113 * <h3>Best Practices</h3>
111114 * <ul>
112- * <li>Use {@link Mono#timeout(java.time.Duration)} to set timeout and avoid infinite waiting</li>
115+ * <li>Use {@link Mono#timeout(java.time.Duration)} to set timeout and avoid infinite
116+ * waiting</li>
113117 * <li>Use {@link Mono#retry(long)} to handle temporary failures</li>
114118 * <li>Use {@link Mono#onErrorResume(Function)} to handle errors gracefully</li>
115119 * <li>Avoid blocking calls (like {@code Thread.sleep}) in async methods</li>
116120 * </ul>
117121 *
118- * <h3>Example</h3>
119- * <pre>{@code
120- * @Override
122+ * <h3>Example</h3> <pre>{@code
123+ * @Override
121124 * public Mono<String> callAsync(String toolInput, ToolContext context) {
122125 * return webClient.get()
123126 * .uri("/api/data")
@@ -131,22 +134,24 @@ public interface AsyncToolCallback extends ToolCallback {
131134 * @param toolInput the tool input arguments (JSON format)
132135 * @param context the tool execution context, may be null
133136 * @return a Mono that asynchronously returns the tool execution result
134- * @throws org.springframework.ai.tool.execution.ToolExecutionException if tool execution fails
137+ * @throws org.springframework.ai.tool.execution.ToolExecutionException if tool
138+ * execution fails
135139 */
136140 Mono <String > callAsync (String toolInput , @ Nullable ToolContext context );
137141
138142 /**
139143 * Check if async execution is supported.
140144 *
141145 * <p>
142- * Returns {@code true} by default. If a subclass overrides this method and returns {@code false},
143- * the framework will use synchronous call {@link #call(String, ToolContext)} and execute it
144- * in a separate thread pool (boundedElastic).
146+ * Returns {@code true} by default. If a subclass overrides this method and returns
147+ * {@code false}, the framework will use synchronous call
148+ * {@link #call(String, ToolContext)} and execute it in a separate thread pool
149+ * (boundedElastic).
145150 *
146151 * <p>
147152 * Can dynamically decide whether to use async based on runtime conditions:
148153 * <pre>{@code
149- * @ Override
154+ * @ Override
150155 * public boolean supportsAsync() {
151156 * // Use async only in production environment
152157 * return "production".equals(environment.getActiveProfiles()[0]);
@@ -159,13 +164,16 @@ default boolean supportsAsync() {
159164 }
160165
161166 /**
162- * Execute tool call synchronously (backward compatibility - single parameter version).
167+ * Execute tool call synchronously (backward compatibility - single parameter
168+ * version).
163169 *
164170 * <p>
165- * Default implementation delegates to the two-parameter version {@link #call(String, ToolContext)}.
171+ * Default implementation delegates to the two-parameter version
172+ * {@link #call(String, ToolContext)}.
166173 * @param toolInput the tool input arguments (JSON format)
167174 * @return the tool execution result
168- * @throws org.springframework.ai.tool.execution.ToolExecutionException if tool execution fails
175+ * @throws org.springframework.ai.tool.execution.ToolExecutionException if tool
176+ * execution fails
169177 */
170178 @ Override
171179 default String call (String toolInput ) {
@@ -176,20 +184,22 @@ default String call(String toolInput) {
176184 * Execute tool call synchronously (backward compatibility).
177185 *
178186 * <p>
179- * Default implementation calls {@link #callAsync(String, ToolContext)} and blocks for the result.
180- * This ensures backward compatibility but loses the performance benefits of async execution.
187+ * Default implementation calls {@link #callAsync(String, ToolContext)} and blocks for
188+ * the result. This ensures backward compatibility but loses the performance benefits
189+ * of async execution.
181190 *
182191 * <p>
183- * <strong>Note</strong>: If your tool needs to support both sync and async calls,
184- * you can override this method to provide an optimized synchronous implementation.
192+ * <strong>Note</strong>: If your tool needs to support both sync and async calls, you
193+ * can override this method to provide an optimized synchronous implementation.
185194 *
186195 * <p>
187- * <strong>Warning</strong>: This method blocks the current thread until the async operation completes.
188- * Avoid calling this method directly in reactive contexts.
196+ * <strong>Warning</strong>: This method blocks the current thread until the async
197+ * operation completes. Avoid calling this method directly in reactive contexts.
189198 * @param toolInput the tool input arguments (JSON format)
190199 * @param context the tool execution context, may be null
191200 * @return the tool execution result
192- * @throws org.springframework.ai.tool.execution.ToolExecutionException if tool execution fails
201+ * @throws org.springframework.ai.tool.execution.ToolExecutionException if tool
202+ * execution fails
193203 */
194204 @ Override
195205 default String call (String toolInput , @ Nullable ToolContext context ) {
0 commit comments