fix(wizard-ask): return an explicit cancellation outcome, not a sentinel - #1218
Open
Gilbert09 wants to merge 1 commit into
Open
fix(wizard-ask): return an explicit cancellation outcome, not a sentinel#1218Gilbert09 wants to merge 1 commit into
Gilbert09 wants to merge 1 commit into
Conversation
A cancelled or timed-out `wizard_ask` came back as `{ answers: { host:
"__cancelled__" } }` and nothing else. The sentinel is not named anywhere in
the tool schema, and a prompt the user dismissed is byte-identical to one
nobody answered before it timed out.
Both facades now return a `cancelled` envelope alongside `answers`: the
question ids that were not collected, whether the user dismissed the prompt
or it timed out, and what to do next. The bridge reports `timedOut` — the one
fact only it holds — and the shared descriptor builds the envelope, so the MCP
server and the pi-native tool cannot drift.
Generated-By: PostHog Desktop
Task-Id: 2e6fcdd3-5969-4b4d-ab93-a70ef50ce512
🧙 Wizard CIRun the Wizard CI and test your changes against wizard-workbench example apps by replying with a GitHub comment using one of the following commands: Test all apps:
Test all apps in a directory:
Test an individual app:
Show more apps
Test against a Context Mill branch:
Add Results will be posted here when complete. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
wizard_askis how the seeded warehouse task collects a source's credentials,one call per detected source. When a call collects nothing, the result the
agent reads is:
{ "answers": { "host": "__cancelled__", "password": "__cancelled__" } }Two things are missing from that.
The cancellation is encoded, not stated.
__cancelled__appears nowhere inthe tool's schema or description — an agent can only act on it if it already
knows the sentinel. The tool description tells it to "treat a cancelled or
timed-out response as the user declined" without saying how to recognise one.
A task agent on this flow asked for exactly this: an explicit decline
indicator, separate from the cancelled answer values, so it can report its own
completion state honestly. That report is what feeds the skip reason we added
in #1195, so the input to it being guesswork undermines the measurement too.
A dismissal and a timeout are indistinguishable. The bridge already knows
which happened — it stamps
timed_outon the analytics event — but throws thedistinction away before the agent sees it. They call for different behaviour.
A dismissal is one decline: fall back for that source, carry on with the next.
A timeout means nobody is reading the terminal, and every later prompt in the
run will end the same way after the same 20-minute wait. Cancelled prompts
are the dominant in-task loss in this flow, and timeouts are a real slice of
them, including runs that timed out more than once — each one a full wait
spent on a prompt that could not be answered.
Why: users who accept the offer to connect their data sources and then
walk away lose the whole step, and the agent cannot tell that case from a
deliberate "not this one".
Changes
WizardAskBridge.requestresolves to{ answers, timedOut }.timedOutisthe one fact only the bridge holds; the flag also replaces the
duration >= timeoutinference the analytics event was using.describeAskCancellation()inwizard-tools/tools.tsbuilds acancelledenvelope —reason(user-cancelled/timed-out), theuncollected
questionIds, and anoteon what to do next. Shared by bothharness facades, the same discipline
HANDOFF_FIELDSapplies to the handoffschema, so the MCP server and the pi-native tool cannot drift.
answersis unchanged, so theskill text that reads it (a context-mill artifact) keeps working as-is.
values.
The notes stay about the ask itself and say nothing about task queues or
complete_task—wizard_askserves programs that have neither.Not touched: the cap accounting and the refund (a cancelled ask is still
free), the sentinel itself, the timeouts, and the offer.
Test plan
pnpm build && pnpm test && pnpm lint— 2647 tests pass, 0 lint errors.New cases: the bridge reports a dismissal and a timeout distinctly; the
descriptor names the uncollected ids, separates the two reasons, handles a
partly answered ask, and never counts a vaulted
{secretRef}answer ascancelled; the pi tool emits the envelope, distinguishes a timeout, and omits
it entirely when every question was answered.
Created with PostHog Desktop