Skip to content

Add cancellable SDK run controller - #850

Open
victorxheng wants to merge 4 commits into
mainfrom
fix/stop-running-cloud-jobs-2026070707
Open

Add cancellable SDK run controller#850
victorxheng wants to merge 4 commits into
mainfrom
fix/stop-running-cloud-jobs-2026070707

Conversation

@victorxheng

Copy link
Copy Markdown

User request

A Freebuff cloud user reported that long-running terminal commands or autonomous agent work can get stuck for 20+ minutes, and requested a user-controlled way to terminate the running work.

Implementation

  • Added CodebuffRunController and createRunController() in the SDK.
  • Added CodebuffClient.runCancellable(), which returns { id, controller, signal, result, cancel } for hosts to keep in an in-flight run registry and call from a Stop/Terminate UI or API action.
  • The cancel path composes with any caller-provided AbortSignal, then flows through the existing runtime cancellation path used by LLM streams, subagents, tool execution, and terminal commands.
  • Exported the new controller and CancellableRun type from the SDK entrypoint.
  • Added tests proving cancel() aborts an already-running agent signal and that external caller signals still abort the same run.

Confidence / verification

Ready to merge with high confidence for the SDK/runtime control surface. Verified locally:

  • bun test sdk/src/__tests__/client-cancellable-run.test.ts sdk/src/__tests__/run-cancellation.test.ts
  • cd sdk && bun run typecheck
  • cd sdk && bun run build

Note: this public snapshot does not include the tracked cloud web route/component code for the Stop button itself; this PR provides the production SDK primitive that the cloud host can wire to its stop endpoint/UI without bypassing existing runtime cancellation semantics.

@codebuff-team

Copy link
Copy Markdown
Contributor

This is a clean, focused addition to sdk/src/run-controller.ts. A few positives:

  • CodebuffRunController and createRunController() are small, single-purpose primitives that compose naturally with existing AbortSignal-based cancellation already used for LLM streams/subagents/terminal commands (per client.ts's run({ ...options, signal })), rather than introducing a parallel cancellation mechanism.
  • anySignal() correctly handles the 0/1/N signal cases and falls back to manual event listeners when AbortSignal.any isn't available - good defensive coding for older runtimes.
  • The tests in client-cancellable-run.test.ts are solid: one verifies controller.cancel() propagates through to the runtime's signal, the other verifies an externally-supplied signal still aborts the same run and that the controller itself remains uncancelled in that case. Both assert on the resulting RunState.output shape, which matches how this repo already tests cancellation elsewhere.
  • Public API surface (CodebuffClient.runCancellable, exports from index.ts) is minimal and additive - no existing behavior changes.

A couple of things worth double-checking before porting:

  • cancel()'s default reason wraps a string into new Error(reason) - worth confirming downstream consumers (UI, logging) expect an Error here rather than a raw string, since the existing run() signal-abort path may format reasons differently.
  • No changes to SDK docs/README describing the new runCancellable entrypoint - minor, but worth adding given this is a public API addition.

Overall this looks like a real, well-scoped fix for the reported 20+ minute stuck-run problem, and the test coverage gives confidence it behaves correctly under both self-initiated and caller-initiated cancellation.

@codebuff-team codebuff-team added bot:triaged Classified by the community triage bot pr:port-candidate Worth porting into the private source tree labels Aug 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:triaged Classified by the community triage bot pr:port-candidate Worth porting into the private source tree

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants