Feat/replan after trigger#25
Merged
Merged
Conversation
…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.
92f92ca to
7a06285
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.