feat: add noInterruptOnUserMessage and noContinueWhileChildrenActive options - #53
Open
harryzhou2000 wants to merge 2 commits into
Open
feat: add noInterruptOnUserMessage and noContinueWhileChildrenActive options#53harryzhou2000 wants to merge 2 commits into
harryzhou2000 wants to merge 2 commits into
Conversation
…ad of pausing) When enabled, a new human message no longer pauses an active goal with stopReason 'user intervention'. The goal loop keeps running and the message steers the next continuation, matching Codex-style steering. Gates the three pause sites (chat.message, auto-continue claim guard, and the idle continuation driver); plugin-owned command/continuation messages are never interventions either way. Default remains false. Adds option docs to README, index.d.ts, and CHANGELOG, plus tests: a chat.message + idle steering test and a normalizeOptions boolean test.
Author
|
Hi @willytop8 — this PR now adds two goal-loop options (defaults unchanged): noInterruptOnUserMessage (human messages steer instead of pausing the goal) and noContinueWhileChildrenActive (defer auto-continue while subagent/background children are active). CI runs are still waiting on workflow approval (action_required) — could you approve them to start the pipeline? The full CI matrix (npm run check on Node 18/20/22/24) passes locally at the final commit (356/356), plus coverage, type contracts, and smoke. Open to review feedback on either option. |
…hile subagents run) When enabled, auto-continue is deferred while the session has active child sessions (subagents, background tasks): the goal stays running but the goal loop does not prompt the orchestrator over work a child is already doing. The gate lives in claimContinuationSource, which covers both continuation paths (normal continue and budget wrapup). It checks opencode's children and status endpoints through the existing shape adapter (children/status are replay-safe read-only operations); hosts that cannot report children/status fail open and continue as before. Default remains false. Adds adapter coverage (children/status shape probing) and behavioral tests (deferral while a child is busy, continuation once children are idle, and unchanged default behavior).
harryzhou2000
added a commit
to harryzhou2000/cfd_solver_agentic_benchmark_workspace_template
that referenced
this pull request
Aug 4, 2026
…age patch) Pin the willytop8 goal-plugin fork at 03c493c (feat/no-interrupt-user-message): a no-interrupt config option so human messages steer an active goal instead of pausing it. PR: willytop8/OpenCode-goal-plugin#53.
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.
What changed
Adds two plugin-level options (both default
false, so existing behavior is unchanged):noInterruptOnUserMessage— whentrue, a new human message no longer pauses an active goal withstopReason: "user intervention":chat.messagehook skips the immediate pause/abort;newHumanMessage/userInterventionDetected;userInterventionDetected.The goal loop keeps running and the human message is included in the next continuation, so the message steers the loop (Codex-style) instead of stopping for
/goal resume. Plugin-owned command and continuation messages were already excluded from intervention detection and remain so.noContinueWhileChildrenActive— whentrue, auto-continue is deferred while the session has active child sessions (subagents, background tasks): the goal stays running, but the goal loop does not prompt the orchestrator over work a child is already doing. The gate lives inclaimContinuationSource, which covers both continuation paths (normal continue and budget wrapup), and checks opencode'schildren+statusendpoints through the existing shape adapter (children/statusare replay-safe read-only operations). Hosts that cannot report children/status fail open and continue as before.Why
For long-running autonomous goal loops, any user-role message currently stops the goal and requires an explicit
/goal resume. That includes messages that are not real human steering, e.g. synthetic background-task result messages injected by some hosts, which can pause a goal seconds after it starts (observed in practice: a goal paused 55s in by a background-task completion notification). With the option enabled, such messages leave the loop untouched while real user input steers the next continuation.In particular, OpenCode's experimental background subagents may interrupt an active goal: when a background-task result is delivered into the session as a synthetic user-role message (
type: text,synthetic: true, no plugin metadata), the currentchat.messagepath treats it as human intervention and pauses the goal. WithnoInterruptOnUserMessage: truethose synthetic results no longer pause the loop; real human messages keep steering the next continuation instead of stopping the goal.Conversely, while a background subagent is still running, the goal loop currently has no way to know it: the plugin's auto-continue fires on the orchestrator's own idle even though a child is doing the work, risking overlapping edits on the same files.
noContinueWhileChildrenActive: truedefers the continuation until the children are idle (matching the guard omo-slim applies to its own continuation nudge).Checks run
node-compatibility(npm run check) — passed locally on official Node 18.20.8, 20.20.2, 22.23.2, and 24.19.0 at the final commit (356/356 tests on each).quality-contracts:npm run test:coverage— passed (Node 22)npm run type:check— passed (NodeNext + Bundler)npm run smoke— passednpm run checkon official Node 22 — 356/356 pass (the four new tests included)npm run test:mutation,npm run benchmark:behavior,npm run smoke:packed-host,npm run smoke:packed-tools,npm audit --omit=dev --audit-level=high,npm run pack:check— not completed locally (mutation alone exceeds 15 minutes on this machine and the run was interrupted); these are exercised by the GitHub pipeline once the workflow run is approved.test/goal-plugin.test.js):noInterruptOnUserMessage:true keeps the goal running and steers the loop(chat.message + idle driver)normalizeOptions defaults noInterruptOnUserMessage to false and keeps it booleannoContinueWhileChildrenActive:true defers continuation while a child is active(defers, then continues once the child is idle)active children do not block auto-continue by defaultnormalizeOptions defaults noContinueWhileChildrenActive to false and keeps it booleantest/opencode-session-api.test.js):children/statusshape-adapter and replay-safety coverage.test/persistence-lease.test.jsandtest/session-concurrency.test.jsfail independently of this change (reproduced identically on pristinemain); both pass on the official Node builds used by CI.Manual OpenCode smoke testing
None against a live OpenCode host in this environment; the hook-level behavior is covered by the tests above.
Config