Summary
runLocal has a MAX_ADVANCES = 1000 guard against infinite loops, but when the limit is hit the function silently returns outcome: "running". The caller cannot distinguish "hit the safety limit" from "execution genuinely still in flight".
Root Cause
packages/agent-core/src/local/run-local.ts:
const MAX_ADVANCES = 1000;
let guard = 0;
while (guard++ < MAX_ADVANCES) {
await core.advance(executionId, max);
// ...
}
// If limit exhausted → falls through, final.status is still "running"
const outcome = final?.status ?? "running"; // → "running" with no indication why
Fix
Return a distinct outcome (or add a stubWarning) when the guard fires:
let limitExceeded = false;
while (guard++ < MAX_ADVANCES) { ... }
if (guard > MAX_ADVANCES) limitExceeded = true;
// expose in result:
unusedStubs // or add a top-level limitExceeded: boolean field
At minimum, document that outcome: "running" can mean "advance limit reached".
Summary
runLocalhas aMAX_ADVANCES = 1000guard against infinite loops, but when the limit is hit the function silently returnsoutcome: "running". The caller cannot distinguish "hit the safety limit" from "execution genuinely still in flight".Root Cause
packages/agent-core/src/local/run-local.ts:Fix
Return a distinct outcome (or add a
stubWarning) when the guard fires:At minimum, document that
outcome: "running"can mean "advance limit reached".