fix: make heartbeat interval configurable and reduce researcher max_iterations

Two related issues with autonomous Hand agents:

1. heartbeat_interval_secs was hardcoded at 30s (the AutonomousConfig default)
   for all Hands, with no way to override it from HAND.toml. For agents that
   make long LLM calls, 30s causes false-positive recovery triggers during
   normal operation. Add heartbeat_interval_secs to HandAgentConfig so each
   Hand can declare an appropriate interval.

2. The researcher Hand shipped with max_iterations = 80 and a system prompt
   instructing exhaustive research (50+ sources). This combination was designed
   for cloud LLMs with 200K context windows. On any model with a 32K or smaller
   context window, 80 iterations × growing history guarantees context overflow
   before the task completes. Reduce to 25, which is sufficient for thorough
   research within a 32K budget.

researcher/HAND.toml changes:
- max_iterations: 80 → 25
- heartbeat_interval_secs: 120 (new field; 30s default was triggering false
  recovery during normal multi-minute LLM calls)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Mark Baker
2026-03-17 00:00:00 -04:00
co-authored by Claude Sonnet 4.6
parent f1ca52714d
commit 972a52ff9c
3 changed files with 13 additions and 1 deletions
@@ -161,7 +161,10 @@ provider = "default"
model = "default"
max_tokens = 16384
temperature = 0.3
max_iterations = 80
max_iterations = 25
# Researcher makes long LLM calls; 30s (kernel default) causes false-positive
# recovery triggers. 120s matches typical deep-research call latency.
heartbeat_interval_secs = 120
system_prompt = """You are Researcher Hand — an autonomous deep research agent that conducts exhaustive investigations, cross-references sources, fact-checks claims, and produces comprehensive structured reports.
## Phase 0 — Platform Detection & Context (ALWAYS DO THIS FIRST)
+5
View File
@@ -288,6 +288,11 @@ pub struct HandAgentConfig {
pub system_prompt: String,
#[serde(default)]
pub max_iterations: Option<u32>,
/// Heartbeat interval in seconds for autonomous agents. Overrides the
/// AutonomousConfig default (30s), which is too aggressive for agents
/// making long LLM calls. Omit to use the kernel default.
#[serde(default)]
pub heartbeat_interval_secs: Option<u64>,
}
fn default_module() -> String {
+4
View File
@@ -3252,6 +3252,10 @@ impl OpenFangKernel {
],
autonomous: def.agent.max_iterations.map(|max_iter| AutonomousConfig {
max_iterations: max_iter,
// Use the hand-declared heartbeat interval if provided.
// The kernel default (30s) is too aggressive for hands making long LLM calls;
// HAND.toml authors should set this to reflect expected call latency.
heartbeat_interval_secs: def.agent.heartbeat_interval_secs.unwrap_or(30),
..Default::default()
}),
// Autonomous hands must run in Continuous mode so the background loop picks them up.