Skip to content

Add CancellationToken support to prompts - #404

Merged
shibayan merged 2 commits into
masterfrom
feature/cancellation-token
Sep 30, 2026
Merged

shibayan merged 2 commits into
masterfrom
feature/cancellation-token

Conversation

@shibayan

Copy link
Copy Markdown
Owner

Closes #208

Summary

Prompts can now be canceled from code with a CancellationToken, e.g. to close a pending prompt when the host hides its console, when a request arrives from a server, or on a timeout.

using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));

var name = Prompt.Input<string>(options => options.Message = "What's your name?", cts.Token);
var model = Prompt.Bind<MyFormModel>(cts.Token);

API (additive, no breaking changes)

  • New overloads taking CancellationToken for the options-object and configure-delegate forms of Input / Password / Confirm / Select / MultiSelect / List, plus Bind<T>(CancellationToken) and Bind<T>(T, CancellationToken).
  • Existing signatures are untouched, so this is binary compatible for 3.x. The simple parameter overloads (Input<T>(string message, ...)) were intentionally left alone: adding an optional token there would make the existing overloads ambiguous or break binary compatibility.
  • New ModelBinderRegistry.Register<T>(Action<T, CancellationToken>); the existing Register<T>(Action<T>) still works and ignores the token.

Behavior

  • When the token is canceled while waiting for input, the prompt is closed the same way as Ctrl+C and an OperationCanceledException (carrying the token) is thrown, independent of ThrowExceptionOnCancel.
  • An already-canceled token throws before anything is rendered.
  • Console.ReadKey cannot be interrupted, so only when a cancelable token is supplied the form polls KeyAvailable (waiting on the token's wait handle for 16 ms between checks). Without a token, the blocking ReadKey path is unchanged. IConsoleDriver is unchanged.

Source generator

The generated binders now register (model, cancellationToken) => ... and pass the token to each prompt call.

Docs

Added a "Canceling from code" section (en / ja) and a README snippet. Also corrected the existing text that said Ctrl+C returns the default value; it actually exits the process (via Environment.Exit(1)) unless ThrowExceptionOnCancel is set.

Tests

  • Form tests: already-canceled token (nothing rendered, no keys consumed), cancellation while waiting for input, and a cancelable but uncanceled token still returning input.
  • Registry / Bind tests: both Register overloads, null checks, and Bind passing the token to the binder.
  • xUnit1051 is suppressed in the test project: forms under test read from FakeConsoleDriver, which never blocks.
  • Full suite passes (682 tests, net8.0 / net10.0).
  • Manually verified with DefaultConsoleDriver in a real console window: cancellation fires within ~10 ms of the deadline across consecutive prompts, the next prompt renders below the canceled one, TreatControlCAsInput is restored, and the generated binder for a [PromptBindable] model receives the token.

🤖 Generated with Claude Code

- Add CancellationToken overloads for the options and configure based
  Input / Password / Confirm / Select / MultiSelect / List APIs and for
  Bind; existing signatures are unchanged
- While a cancelable token is supplied, poll for available keys instead
  of blocking in ReadKey, and close the prompt and throw
  OperationCanceledException once the token is canceled
- Pass the token through the binders emitted by the source generator
  via a new ModelBinderRegistry.Register overload
- Document cancellation from code and correct the Ctrl+C default
  behavior description

Closes #208

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings September 30, 2026 04:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The cancellation test relies on a short wall-clock delay and can fail under scheduling stalls.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Adds CancellationToken support throughout prompt execution and generated model binders.

Changes:

  • Adds cancelable prompt and binding overloads.
  • Polls console input while observing cancellation.
  • Adds tests and English/Japanese documentation.
File Description
README.md Adds cancellation example.
docs/​en/​configuration.md Documents cancellation behavior.
docs/​ja/​configuration.md Adds Japanese cancellation documentation.
src/​Sharprompt/​Forms/​FormBase.cs Implements cancellation-aware input polling.
src/​Sharprompt/​ModelBinderRegistry.cs Supports token-aware binders.
src/​Sharprompt/​Prompt.Basic.cs Adds token overloads for prompts.
src/​Sharprompt/​Prompt.Bind.cs Passes tokens to model binders.
src/​Sharprompt.SourceGenerator/​PromptBindableGenerator.cs Propagates tokens in generated binders.
tests/​Sharprompt.Tests/​Binding/​ModelBinderRegistryTests.cs Tests binder token propagation.
tests/​Sharprompt.Tests/​Forms/​FormInteractionTests.cs Tests form cancellation behavior.
tests/​Sharprompt.Tests/​Sharprompt.Tests.csproj Suppresses the cancellation-token analyzer warning.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tests/Sharprompt.Tests/Forms/FormInteractionTests.cs Outdated
Cancel the token from FakeConsoleDriver once every queued key has been
consumed instead of relying on a wall-clock delay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings September 30, 2026 04:40

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

Cancellation is consistently propagated, preserves existing behavior, and is covered by deterministic tests and documentation.

Review effort: Balanced
Findings: None

Resolved since last review (1)

@shibayan
shibayan merged commit 6755d7f into master Sep 30, 2026
6 checks passed
@shibayan
shibayan deleted the feature/cancellation-token branch September 30, 2026 04:53
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.

Manually cancel/reset open forms

2 participants