Skip to content

fix(agents): cancel pending bundle LSP requests when the agent stops#104110

Merged
vincentkoc merged 5 commits into
openclaw:mainfrom
zhangguiping-xydt:fix/problem-bundle-lsp-cancel
Jul 11, 2026
Merged

fix(agents): cancel pending bundle LSP requests when the agent stops#104110
vincentkoc merged 5 commits into
openclaw:mainfrom
zhangguiping-xydt:fix/problem-bundle-lsp-cancel

Conversation

@zhangguiping-xydt

Copy link
Copy Markdown
Contributor

What Problem This Solves

Fixes an issue where users who stopped an agent while a bundle-provided LSP hover, definition, or references tool was pending could still leave the language server working for up to the request timeout and receive a late tool result after the run had been cancelled.

Why This Change Was Made

Bundle LSP tools now pass their per-call abort signal into the JSON-RPC request owner. Aborting removes that request from the pending map, clears its timer and listener, rejects the tool promise, and sends the LSP-standard $/cancelRequest notification for the same request id. The shared language-server process is intentionally kept alive for other calls.

User Impact

Stopping an agent now stops its pending bundle LSP tool calls promptly. The language server can cancel the corresponding work, late responses no longer resolve the cancelled tool call, and other tools can continue using the same server session.

Evidence

Reporter-provided pre-fix live proof used Claude bundle discovery, .lsp.json, a real stdio child process, and Content-Length JSON-RPC framing. The aborted hover call did not send cancellation and resolved 602 ms after abort:

{
  "lspCancelRequestReceived": false,
  "settledWithin100msAfterAbort": false,
  "toolResolved": true,
  "settledAfterAbortMs": 602,
  "serverRespondedAfterAbort": true
}

Post-fix local E2E live proof drives the same production surfaces and also verifies the shared server handles another request after cancellation:

{
  "realClaudeBundleLoaded": true,
  "materializedTool": "lsp_hover_prooflive",
  "runSignalAborted": true,
  "lspRequestReceivedBeforeAbort": true,
  "lspCancelRequestReceived": true,
  "settledWithin100msAfterAbort": true,
  "toolResolved": false,
  "settledAfterAbortMs": 1,
  "serverRespondedAfterAbort": true,
  "sharedSessionSurvived": true
}

Focused regression suite:

Test Files  1 passed (1)
Tests  11 passed (11)

Additional checks:

  • oxfmt --check passed for both touched files.
  • Repository run-oxlint.mjs passed for both touched files.

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: S labels Jul 11, 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. P2 Normal backlog priority with limited blast radius. labels Jul 11, 2026
@clawsweeper

clawsweeper Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 11, 2026, 10:00 AM ET / 14:00 UTC.

Summary
Propagates bundle LSP tool abort signals into pending JSON-RPC requests, cleans their local resources, sends $/cancelRequest, and preserves the shared language-server session.

PR surface: Source +46, Tests +64. Total +110 across 2 files.

Reproducibility: yes. at source level with high confidence. Current main does not consume the tool-call abort signal in its LSP request owner, and the PR provides matching real-process before-and-after protocol output.

Review metrics: none identified.

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

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

Next step before merge

  • No automated repair is needed; ordinary exact-head maintainer review and merge gating are the remaining actions.

Security
Cleared: The focused runtime-and-test change adds no dependency, workflow, permission, credential, package-resolution, publishing, downloaded-code, or other concrete supply-chain concern.

Review details

Best possible solution:

Land the exact-head request-scoped cancellation implementation after ordinary merge gating, keeping initialization, shutdown, late-response handling, and unrelated shared-session requests independent from a single tool abort.

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

Yes, at source level with high confidence. Current main does not consume the tool-call abort signal in its LSP request owner, and the PR provides matching real-process before-and-after protocol output.

Is this the best way to solve the issue?

Yes. Handling cancellation at the pending JSON-RPC request owner is the narrowest maintainable solution because it settles local resources once, notifies conforming servers, ignores late responses, and preserves unrelated shared-session work.

AGENTS.md: found and applied where relevant.

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

Label changes

Label justifications:

  • P2: This fixes a bounded but user-visible agent cancellation defect that can leave bundle LSP work running and produce a late tool result after the run stops.
  • rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body supplies after-fix live stdio LSP output through production bundle discovery, showing server cancellation receipt, prompt local rejection, ignored late completion, and successful shared-session reuse.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body supplies after-fix live stdio LSP output through production bundle discovery, showing server cancellation receipt, prompt local rejection, ignored late completion, and successful shared-session reuse.
Evidence reviewed

PR surface:

Source +46, Tests +64. Total +110 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 74 28 +46
Tests 1 66 2 +64
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 140 30 +110

What I checked:

  • Current-main defect: Current main forwards an abort signal to agent tool execution but sendRequest neither accepts nor consumes it, so a pending bundle LSP request remains active until response, timeout, process failure, or disposal. (src/agents/agent-bundle-lsp-runtime.ts:225, ba826be268a7)
  • Request-owner cancellation: The PR head checks already-aborted signals, registers per-request cleanup, removes the pending entry on abort, clears its timer and listener, sends the standard cancellation notification, and rejects the local promise. (src/agents/agent-bundle-lsp-runtime.ts:225, 3186e7a974cf)
  • Single terminal-path cleanup: Responses, timeouts, aborts, session failure, and disposal all use takePendingLspRequest, making pending-map deletion, timer clearing, and listener removal idempotent while ignoring late responses. (src/agents/agent-bundle-lsp-runtime.ts:119, 3186e7a974cf)
  • Regression coverage: Parameterized coverage exercises cancellation for hover, definition, and references requests and verifies the cancellation notification and continued use of the shared server session. (src/agents/agent-bundle-lsp-runtime.test.ts:257, 3186e7a974cf)
  • Protocol contract: The LSP 3.17 specification defines $/cancelRequest as a notification carrying the original request id and permits servers that cannot cancel work to ignore it, matching the PR's best-effort behavior.
  • Feature provenance: Git history shows the current bundle LSP runtime and its tests entered main in commit cce2d39, authored by Vincent Koc. (src/agents/agent-bundle-lsp-runtime.ts:1, cce2d39d0c6b)

Likely related people:

  • vincentkoc: Git history and blame attribute the current bundle LSP runtime, request lifecycle, and adjacent tests on main to Vincent Koc, making him the strongest routing candidate for this focused change. (role: feature introducer and recent area contributor; confidence: high; commits: cce2d39d0c6b; files: src/agents/agent-bundle-lsp-runtime.ts, src/agents/agent-bundle-lsp-runtime.test.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.
Review history (4 earlier review cycles)
  • reviewed 2026-07-11T03:22:17.847Z sha db34011 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-11T07:50:23.235Z sha 6528682 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-11T11:40:59.800Z sha cbf1ba6 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-11T12:25:49.209Z sha 880303e :: needs maintainer review before merge. :: none

@clawsweeper clawsweeper Bot added rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. labels Jul 11, 2026
@vincentkoc
vincentkoc merged commit f73c554 into openclaw:main Jul 11, 2026
100 checks passed
chengzhichao-xydt added a commit to chengzhichao-xydt/openclaw that referenced this pull request Jul 11, 2026
…rompt calls

Forward the per-call AbortSignal from materialized bundle MCP tools down
through SessionMcpRuntime and into the MCP SDK client request options.
This lets agent cancellation stop pending MCP work instead of leaving it
running after the caller has aborted, matching the LSP JSON-RPC cancel
behavior in openclaw#104110.

- Add optional signal parameters to SessionMcpRuntime request methods.
- Pass signal through materializeBundleMcpToolsForRun execute factories.
- Forward signal into client.callTool/listResources/readResource/listPrompts/getPrompt.
- Add regression test verifying signal reaches each runtime method.
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦞 diamond lobster Very strong PR readiness with only minor 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