Skip to content

Feat/replan after trigger#25

Merged
siarheidudko merged 1 commit into
mainfrom
feat/replan-after-trigger
Jul 6, 2026
Merged

Feat/replan after trigger#25
siarheidudko merged 1 commit into
mainfrom
feat/replan-after-trigger

Conversation

@siarheidudko

@siarheidudko siarheidudko commented Jul 6, 2026

Copy link
Copy Markdown
Member

feat: configurable replan trigger (replanAfter) + self-corrected failure rule
Summary
Makes the replanner trigger host-configurable and fixes a spurious-replan case where a tool call that failed and then recovered within the same step still forced a replan.

What changed
New replanAfter config option (ReplanTrigger) controls when the LLM replanner is consulted after a step:

'failure' (default) — the step was blocked, or a tool call failed and stayed failed.
'always' — run the replanner after every step (useful when the host surfaces problems through systemPrompt / domain context). Costs one extra LLM call per step.
(stepResult) => boolean | Promise — a predicate that decides per step result. It may be async and close over host state.
Self-corrected failure rule. The default trigger no longer fires when a tool call fails but a later successful call to the same tool within the same step recovers it. The executor's multi-step loop already handled it, so forcing a replan was wasteful noise.

Safety guarantees for predicates. A predicate that throws, rejects, or outlives llmTimeoutMs / the run signal transparently falls back to the 'failure' rule. A buggy or hung predicate can never stall the run; the fallback is logged as a warning.

Release workflow. Improved npm publishing logic with NPM_TOKEN fallback handling in release.yml.

API surface
Adds replanAfter?: ReplanTrigger to IAgentConfig.
Exports the new ReplanTrigger type from the package root.
Exports replanTriggered() alongside the existing shouldCallReplanner() for direct unit testing.
Compatibility
Fully backward-compatible. replanAfter defaults to 'failure', which preserves the previous behavior (aside from the self-corrected-failure fix, which strictly reduces unnecessary replans).

Tests
Extends tests/runner.test.ts with coverage for 'always', predicate triggers, async/throwing/timing-out predicates, and the self-corrected failure path.

…ure rule

Add `replanAfter` (ReplanTrigger): 'failure' (default) | 'always' | predicate,
controlling when the LLM replanner runs after a step. The default no longer
forces a replan for a tool failure that a later successful call to the same
tool recovered within the step (self-corrected).

Predicate triggers are bounded by a ref'd-timer watchdog and fall back to the
'failure' rule on throw / reject / timeout / abort, so a buggy or hung predicate
can never stall the run - nor let an idle event loop exit before the fallback
lands. A ref'd setTimeout keeps the loop alive until it fires (an unref'd
AbortSignal.timeout let node:test on Node 22 tear the loop down early and
cancel the test).

Also: NPM_TOKEN fallback in the release publish step; bump 0.0.16 -> 0.0.17.
@siarheidudko siarheidudko force-pushed the feat/replan-after-trigger branch from 92f92ca to 7a06285 Compare July 6, 2026 13:01
@siarheidudko siarheidudko merged commit 3aba6f3 into main Jul 6, 2026
8 checks passed
@siarheidudko siarheidudko deleted the feat/replan-after-trigger branch July 6, 2026 13:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant