fix(agent): raise parallel delegation timeout to 300s for thinking models

This commit is contained in:
matevip 2026-05-11 17:23:26 +08:00
parent f25f910a82
commit e6fd39f6ba
2 changed files with 25 additions and 9 deletions

View File

@ -71,12 +71,20 @@ public class DelegateAgentTool {
static final int INHERITED_CONTEXT_MAX_MESSAGES = 10; static final int INHERITED_CONTEXT_MAX_MESSAGES = 10;
static final int INHERITED_CONTEXT_PER_MESSAGE_CHARS = 1000; static final int INHERITED_CONTEXT_PER_MESSAGE_CHARS = 1000;
/** /**
* Per-child timeout raised from 60 s to 120 s so that slow LLM models * Wall-clock budget for one delegateParallel batch applies to all children
* (kimi-code observed p99 91 s) can complete before the parent gives up. * together, not per child (they run concurrently on virtual threads).
* The previous 60 s limit was structurally impossible to satisfy once any *
* child called an LLM-backed tool. * <p>Configurable via {@code mateclaw.delegation.parallel-timeout-seconds};
* default 300 s (5 minutes). Earlier defaults (60 s 120 s) were
* structurally too tight for thinking models: a single LLM turn against
* Kimi / GLM / MiniMax routinely takes 90290 s when the child must
* produce multi-section structured output, so the parent gave up while the
* children were still happily streaming. 300 s matches the per-prompt
* ceiling used by ACP delegation and keeps headroom for one tool-call
* round trip on top of a single LLM turn.
*/ */
private static final int PARALLEL_TIMEOUT_SECONDS = 120; @Value("${mateclaw.delegation.parallel-timeout-seconds:300}")
private int parallelTimeoutSeconds;
/** /**
* Default deny list for child agents. Names are matched against the * Default deny list for child agents. Names are matched against the
@ -413,9 +421,9 @@ public class DelegateAgentTool {
List<ChildResult> results = new ArrayList<>(); List<ChildResult> results = new ArrayList<>();
try { try {
CompletableFuture.allOf(futures.values().toArray(new CompletableFuture[0])) CompletableFuture.allOf(futures.values().toArray(new CompletableFuture[0]))
.get(PARALLEL_TIMEOUT_SECONDS, TimeUnit.SECONDS); .get(parallelTimeoutSeconds, TimeUnit.SECONDS);
} catch (TimeoutException e) { } catch (TimeoutException e) {
log.warn("Parallel delegation timed out ({}s), collecting completed results", PARALLEL_TIMEOUT_SECONDS); log.warn("Parallel delegation timed out ({}s), collecting completed results", parallelTimeoutSeconds);
} catch (Exception e) { } catch (Exception e) {
log.error("Parallel delegation error: {}", e.getMessage()); log.error("Parallel delegation error: {}", e.getMessage());
} }
@ -444,7 +452,7 @@ public class DelegateAgentTool {
} }
f.cancel(true); f.cancel(true);
// Use ofTimeout so outcome="timeout" is explicit and distinct from "error". // Use ofTimeout so outcome="timeout" is explicit and distinct from "error".
results.add(ChildResult.ofTimeout(idx, agentName, PARALLEL_TIMEOUT_SECONDS)); results.add(ChildResult.ofTimeout(idx, agentName, parallelTimeoutSeconds));
} }
} }
@ -548,7 +556,7 @@ public class DelegateAgentTool {
.append("trim 后 0 字符)。请勿将此误报为超时或失败——子 Agent 已正常完成,只是本次无输出。\n"); .append("trim 后 0 字符)。请勿将此误报为超时或失败——子 Agent 已正常完成,只是本次无输出。\n");
} }
case "timeout" -> case "timeout" ->
sb.append("❌ 超时(").append(PARALLEL_TIMEOUT_SECONDS).append("s 内未返回)\n"); sb.append("❌ 超时(").append(parallelTimeoutSeconds).append("s 内未返回)\n");
default -> default ->
sb.append("❌ 失败:").append(r.error).append("\n"); sb.append("❌ 失败:").append(r.error).append("\n");
} }

View File

@ -171,6 +171,14 @@ mateclaw:
enabled: true enabled: true
failure-threshold: 3 failure-threshold: 3
cooldown-ms: 300000 cooldown-ms: 300000
# Multi-agent delegation (DelegateAgentTool).
delegation:
# Wall-clock budget for one delegateParallel batch (shared across all
# children — they run concurrently on virtual threads, so this is total
# latency, not per-child). 300 s headroom is needed because thinking
# models (Kimi / GLM / MiniMax) routinely take 90290 s per LLM turn
# when the child must produce multi-section structured output.
parallel-timeout-seconds: 300
# MateClaw Agent 配置 # MateClaw Agent 配置
mate: mate: