diff --git a/agentscope-core/src/main/java/io/agentscope/core/tool/ToolMethodInvoker.java b/agentscope-core/src/main/java/io/agentscope/core/tool/ToolMethodInvoker.java index c0776541f..59a8ae737 100644 --- a/agentscope-core/src/main/java/io/agentscope/core/tool/ToolMethodInvoker.java +++ b/agentscope-core/src/main/java/io/agentscope/core/tool/ToolMethodInvoker.java @@ -336,11 +336,25 @@ private Object convertFromString(String stringValue, Class> targetType) { /** * Handle invocation errors with informative messages. * + *
Special handling for {@link ToolSuspendException}: if found in the exception chain,
+ * it will be re-thrown to allow proper suspension handling by {@link ToolExecutor}.
+ *
* @param e the exception
* @return ToolResultBlock with error message
+ * @throws ToolSuspendException if found in the exception chain
*/
private ToolResultBlock handleInvocationError(Exception e) {
+ // Check if the exception itself is ToolSuspendException
+ if (e instanceof ToolSuspendException) {
+ throw (ToolSuspendException) e;
+ }
+
Throwable cause = e.getCause();
+ // Check for ToolSuspendException in the exception chain
+ if (cause instanceof ToolSuspendException) {
+ throw (ToolSuspendException) cause;
+ }
+
String errorMsg =
cause != null
? ExceptionUtils.getErrorMessage(cause)
diff --git a/agentscope-core/src/test/java/io/agentscope/core/tool/ToolMethodInvokerTest.java b/agentscope-core/src/test/java/io/agentscope/core/tool/ToolMethodInvokerTest.java
index 73b5a2f4f..fcdd9838d 100644
--- a/agentscope-core/src/test/java/io/agentscope/core/tool/ToolMethodInvokerTest.java
+++ b/agentscope-core/src/test/java/io/agentscope/core/tool/ToolMethodInvokerTest.java
@@ -15,6 +15,8 @@
*/
package io.agentscope.core.tool;
+import static org.junit.Assert.assertThrows;
+
import io.agentscope.core.message.ToolResultBlock;
import io.agentscope.core.message.ToolUseBlock;
import io.agentscope.core.tool.test.ToolTestUtils;
@@ -121,6 +123,24 @@ public int parsableIntString(
@ToolParam(name = "value", description = "value") String value) {
return Integer.parseInt(value);
}
+
+ public String suspendTool(
+ @ToolParam(name = "reason", description = "reason") String reason) {
+ throw new ToolSuspendException(reason);
+ }
+
+ public java.util.concurrent.CompletableFuture