Skip to content

fix(agent-core): stop loop after aborted tool run#94412

Merged
vincentkoc merged 6 commits into
openclaw:mainfrom
szsip239:codex/fix-abort-tool-lock-release
Jun 22, 2026
Merged

fix(agent-core): stop loop after aborted tool run#94412
vincentkoc merged 6 commits into
openclaw:mainfrom
szsip239:codex/fix-abort-tool-lock-release

Conversation

@szsip239

@szsip239 szsip239 commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Stop the agent loop after an in-flight tool aborts the run, once the existing tool result and turn_end have been emitted.
  • Avoid requesting another model turn with an already-aborted signal.
  • Add a regression test that fails if a tool-triggered abort calls the model a second time.

Real behavior proof

Behavior addressed: When a tool aborts the active run during tool execution, current origin/main still starts another model turn with the already-aborted signal. That extra turn can keep the caller/session path open after the user-visible abort, which matches the observed session-lock symptom after switching away from an in-flight OpenClaw run. This PR ends the agent loop immediately after the aborted tool result and turn_end have been emitted.

Real environment tested: Local OpenClaw source checkout on macOS, Node v26.3.0, pnpm 11.2.2. I ran the same inline reproduction against current origin/main at 0cae5b3672 and this PR branch codex/fix-abort-tool-lock-release at 1096846d2f. The reproduction imports the real OpenClaw packages/agent-core/src/agent-loop.ts through tsx and exercises runAgentLoop with a model stream, an actual OpenClaw tool object, and an AbortController signal; no mocked unit-test runner is involved in this proof.

Exact steps or command run after this patch: On the PR branch, I ran an inline node --import tsx --input-type=module reproduction that creates a first assistant toolCall, executes an abort_tool whose execute calls controller.abort(new Error("user aborted")), then fails if streamFn is called more than once. I also ran node scripts/run-vitest.mjs packages/agent-core/src/agent-loop.test.ts -t "does not request another model turn after a tool aborts the run".

Evidence after fix: The same reproduction fails on origin/main and passes on this PR branch. On origin/main (0cae5b3672) it printed:

{
  "commit": "0cae5b3672",
  "streamCalls": 2,
  "aborted": true,
  "roles": ["user", "assistant", "toolResult", "assistant"],
  "finalEvent": "agent_end"
}

and then threw Error: BUG: model turn continued after abort. On this PR branch (1096846d2f) it printed:

{
  "commit": "1096846d2f",
  "streamCalls": 1,
  "aborted": true,
  "roles": ["user", "assistant", "toolResult"],
  "finalEvent": "agent_end"
}

The targeted regression test output was:

Test Files  1 passed (1)
Tests  1 passed | 13 skipped (14)
Duration  619ms

Observed result after fix: After the tool aborts the run, OpenClaw emits the tool result and agent_end without issuing a second model request. The returned messages stop at user, assistant, and toolResult; there is no extra assistant message from an aborted follow-up turn.

What was not tested: I did not rerun a full packaged gateway/CLI release build with a live external model provider for this PR-body refresh. The proof above isolates the real OpenClaw agent-loop path locally; full-suite and broader gateway checks remain supplemental CI/maintainer validation.

Verification

  • node scripts/run-vitest.mjs packages/agent-core/src/agent-loop.test.ts -t "does not request another model turn after a tool aborts the run"
  • node scripts/run-vitest.mjs packages/agent-core/src/agent-loop.test.ts
  • node scripts/run-vitest.mjs src/agents/embedded-agent-runner/run/attempt.subscription-cleanup.test.ts src/agents/embedded-agent-runner/run/attempt.session-lock.test.ts
  • pnpm tsgo:test:packages
  • pnpm tsgo:core

@openclaw-barnacle openclaw-barnacle Bot added size: S triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels Jun 18, 2026
@clawsweeper

clawsweeper Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed June 22, 2026, 5:00 AM ET / 09:00 UTC.

Summary
The PR adds a shared abort-stop helper in packages/agent-core/src/agent-loop.ts and regression tests for tool-triggered and next-turn-hook-triggered aborts.

PR surface: Source +43, Tests +148. Total +191 across 2 files.

Reproducibility: yes. Current source shows the missing post-tool abort check before prepareNextTurn, and the PR body supplies a before/after terminal reproduction showing the extra model call on main and one stream call on the PR branch.

Review metrics: 1 noteworthy metric.

  • Terminal abort outcome: 1 synthesized assistant terminal message added. Maintainers should notice that the latest patch intentionally changes the abort transcript from ending on a tool result to ending on an aborted assistant outcome.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Refresh or investigate the failed checks-node-core-runtime-infra-process shard before landing.

Risk before merge

  • [P1] Current PR head still has one failing CI shard outside the changed files, so maintainers need a CI refresh or scoped failure review before landing.
  • [P1] The PR body's role-list proof predates the later terminal-aborted-message commits; the current tests and diff, not that older role list, reflect the latest terminal transcript behavior.

Maintainer options:

  1. Decide the mitigation before merge
    Land the focused shared agent-core abort boundary after current-head CI is clean or the remaining unrelated shard failure is explicitly scoped by maintainers.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P2] The remaining action is maintainer review plus CI refresh/scoping, not a concrete ClawSweeper repair job on the patch.

Security
Cleared: The diff only changes agent-core loop control flow and colocated tests, with no dependency, workflow, secret, install, publishing, or supply-chain surface.

Review details

Best possible solution:

Land the focused shared agent-core abort boundary after current-head CI is clean or the remaining unrelated shard failure is explicitly scoped by maintainers.

Do we have a high-confidence way to reproduce the issue?

Yes. Current source shows the missing post-tool abort check before prepareNextTurn, and the PR body supplies a before/after terminal reproduction showing the extra model call on main and one stream call on the PR branch.

Is this the best way to solve the issue?

Yes. The shared agent-core loop boundary is the right layer because both the plain Agent and harness paths consume runAgentLoop, and session consumers already key terminal handling off message and turn events.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against e20edd753bd7.

Label changes

Label justifications:

  • P1: The PR targets a broken agent abort/session workflow where a tool-triggered abort can continue into an extra model turn instead of releasing the run promptly.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body includes terminal before/after output from a real source checkout showing current main makes a second stream call after abort while the PR branch stops at one call; current tests cover the later terminal assistant refinement.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes terminal before/after output from a real source checkout showing current main makes a second stream call after abort while the PR branch stops at one call; current tests cover the later terminal assistant refinement.
Evidence reviewed

PR surface:

Source +43, Tests +148. Total +191 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 43 0 +43
Tests 1 148 0 +148
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 191 0 +191

What I checked:

Likely related people:

  • steipete: GitHub path history shows the agent-core package extraction and later terminal lifecycle work on agent-loop.ts, agent.ts, types.ts, and related tests. (role: package extraction and terminal lifecycle contributor; confidence: high; commits: bb46b79d3c14, aa0d6e1bca55, 0314819f918a; files: packages/agent-core/src/agent-loop.ts, packages/agent-core/src/agent.ts, packages/agent-core/src/types.ts)
  • fuller-stack-dev: GitHub path history shows deferred tool hydration and co-authored terminal lifecycle work on the same agent-loop/type surfaces involved in tool continuation behavior. (role: recent agent-loop feature contributor; confidence: medium; commits: 965fa05df38b, 0314819f918a; files: packages/agent-core/src/agent-loop.ts, packages/agent-core/src/agent.ts, packages/agent-core/src/types.ts)
  • vincentkoc: Local blame and GitHub history show recent agent-loop and harness maintenance, including text-delta loop behavior and harness API cleanup near this runtime surface. (role: recent adjacent loop contributor; confidence: medium; commits: 6fcc9457020e, 464adfe5e544, f05fd56d666a; files: packages/agent-core/src/agent-loop.ts, packages/agent-core/src/harness/agent-harness.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 High-priority user-facing bug, regression, or broken workflow. labels Jun 18, 2026
@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels Jun 18, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. labels Jun 18, 2026
@vincentkoc
vincentkoc force-pushed the codex/fix-abort-tool-lock-release branch 2 times, most recently from 0308d98 to 468234a Compare June 22, 2026 05:31
@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. and removed rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. labels Jun 22, 2026
@vincentkoc
vincentkoc force-pushed the codex/fix-abort-tool-lock-release branch 9 times, most recently from fa08a2d to 530e68f Compare June 22, 2026 09:47
@vincentkoc
vincentkoc force-pushed the codex/fix-abort-tool-lock-release branch from 530e68f to e11d971 Compare June 22, 2026 09:53
@vincentkoc
vincentkoc merged commit 7fe287b into openclaw:main Jun 22, 2026
75 checks passed
@vincentkoc

Copy link
Copy Markdown
Member

Merged via squash.

Thanks @szsip239!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P1 High-priority user-facing bug, regression, or broken workflow. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants