Skip to content

feat: honor $/cancelRequest by cancelling the in-flight task#30

Merged
Garulf merged 1 commit into
mainfrom
feat/cancel-request
Jul 13, 2026
Merged

feat: honor $/cancelRequest by cancelling the in-flight task#30
Garulf merged 1 commit into
mainfrom
feat/cancel-request

Conversation

@Garulf

@Garulf Garulf commented Jul 13, 2026

Copy link
Copy Markdown
Owner

Summary

Flow Launcher fires a query per keystroke and cancels the superseded one with a $/cancelRequest notification (StreamJsonRpc's cancellation protocol, params {"id": <request id>}). The V2 launcher previously skipped the notification along with all other $/ methods — protocol-safe, but stale queries kept running to completion. For plugins whose query does real async work (HTTP calls, disk scans), typing "weather" meant seven queries with six of them burning effort and rate limit on results nobody will see.

Changes

  • FlowLauncherV2.run tracks in-flight tasks by request id; $/cancelRequest cancels the matching task. Unknown ids, already-finished requests, and malformed params are ignored silently, as before.
  • A cancelled request is answered with the JSON-RPC RequestCanceled error (-32800), which StreamJsonRpc recognizes and discards — every request still gets exactly one response.
  • Other $/ notifications remain silently skipped; $/cancelRequest is still never dispatched to plugin methods (existing test unchanged and passing).

Caveat

task.cancel() interrupts at await points, so this benefits async plugin methods — exactly the slow ones. A synchronous method that blocks the event loop still runs to completion.

Verification

tox -e lint,type,py38,py312 all green — 137 tests, including three new ones: a slow async query is actually cancelled (asserted via a completion flag and the -32800 response; the suite finishes in ~1s despite the test's 5s sleep, proving the cancel), unknown-id cancels are no-ops, and malformed params don't crash the loop.

Flow Launcher (via StreamJsonRpc) fires a query per keystroke and
cancels the superseded one with a $/cancelRequest notification.
Previously the launcher skipped the notification and let stale queries
run to completion, wasting work for async plugins doing HTTP calls or
other slow I/O.

Track in-flight tasks by request id; on $/cancelRequest cancel the
matching task and answer it with the JSON-RPC RequestCanceled error
(-32800), which the host understands and discards. Notifications with
unknown ids or malformed params are still ignored silently, as are all
other $/ methods.

Note task.cancel() interrupts only at await points, so this benefits
async plugin methods; synchronous ones still run to completion.

Claude-Session: https://claude.ai/code/session_016BXjCFiQ5jaCjkaFmCZGyF
@Garulf
Garulf force-pushed the feat/cancel-request branch from cd01383 to 87545b2 Compare July 13, 2026 08:51
@Garulf
Garulf merged commit 2cdbbfd into main Jul 13, 2026
5 checks passed
@Garulf
Garulf deleted the feat/cancel-request branch July 13, 2026 08:54
Garulf added a commit that referenced this pull request Jul 13, 2026
Flow Launcher (via StreamJsonRpc) fires a query per keystroke and
cancels the superseded one with a $/cancelRequest notification.
Previously the launcher skipped the notification and let stale queries
run to completion, wasting work for async plugins doing HTTP calls or
other slow I/O.

Track in-flight tasks by request id; on $/cancelRequest cancel the
matching task and answer it with the JSON-RPC RequestCanceled error
(-32800), which the host understands and discards. Notifications with
unknown ids or malformed params are still ignored silently, as are all
other $/ methods.

Note task.cancel() interrupts only at await points, so this benefits
async plugin methods; synchronous ones still run to completion.
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