Skip to content

feat(studio): switch a plan's scope choices and a reading's chips - #73

Merged
jm-rivera merged 14 commits into
devfrom
feat/plan-scope-switch
Oct 27, 2026
Merged

jm-rivera merged 14 commits into
devfrom
feat/plan-scope-switch

Conversation

@jm-rivera

@jm-rivera jm-rivera commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Studio's plan card shows each scope choice the harness reports (sector, region, provider, measure basis) with its options, the reason an option is unavailable, and a control to switch it. A switch posts interrupt.response with decision: "switch", the choice, the option and the plan revision the user saw, and the card re-renders from the re-offered plan with what moved. A stale switch or approve gets the current card back from the harness's 409 and replaces the one shown; approve now sends plan_revision.

After an answer, Studio renders the harness's apply_choice chips beside the follow-up prompts on the latest turn. A click sends a turn carrying the chosen option and no message, shows the chip label as the user's side, and streams the answer like any turn; a refused chip shows the reason and is removed.

The wire mirror lives in src/lib/studio/wire.ts, the card logic in plan.ts and chips.ts, and the UI in PlanModal.tsx, PlanCard.tsx, ChatMessage.tsx and useChat.ts. Deploy this before the dfo-ai scope-choices and composite PRs (#88 and #89), which serve these frames: the current site draws their chips as empty buttons (the chips row below).

Testing: tsc --noEmit and eslint are clean; the 518 Studio wire, plan, chips, prompt allowance and client tests pass, including the harness's own request and frame fixtures.

Screenshots

Before is dev and after is this branch, both against the same local harness and Search, at 1440 by 900.

Change Before After
Plan card: each choice offers its options before 01 after 01
Switching the basis to net after 02
The card offered again on net after 03
Chips under an answer before 04 after 04
A clicked chip starts a turn after 05
The switched answer and its chips after 06

Decision rows that carry a scope choice list its options: the active one
marked, available ones selectable, partial ones with their years and
unavailable ones disabled with their reason. A pick sends a switch with
the plan revision through the interrupt stream, keeps the card until the
re-offered plan arrives, and shows what moved. A stale revision or an
unavailable option leaves the card with a notice. The wire mirror gains
the plan revision, requirements, operations and asks it lagged on.
A stale-revision refusal stops further switches on that card and says
why; options in flight keep focus; the moved note and notice stay
mounted so screen readers announce them; a plain detail body reaches
the notice.
A switch or approve refused as plan_revision_stale now takes the
current_plan the harness returns and shows it with the refusal's
detail, so switching and approving continue on the plan actually
pending. Approve sends the plan revision the user saw.
Studio shows the harness's apply_choice chips beside the follow-up
prompts on the latest answer. A click sends a turn carrying the chosen
option and no message, shows the chip label as the user's side, and
streams the answer like any turn; a refused chip shows the reason and
is removed.
A chip carries the turn whose answer offered it and the spec_id of the
reading it switches, and the click sends both in apply_choice, so the
harness can refuse a chip whose answer or reading is no longer current.
…nds in one place

A switch refused as stale keeps the card's revision, so an approve is
refused, and only the harness's switch refusals count as refused
switches; any other failure ends the turn. stream() guards every refusal
against a stopped or superseded turn, send and applyChoice open a turn
through one startTurn, a chip clicked mid-request queues, a forked
conversation shows no chips, and the card shows its notice.
A chip passes the guest prompt limit and is tracked as studio.prompt
with intent apply_choice, through the one wrapper typed prompts use.
@jm-rivera
jm-rivera marked this pull request as ready for review October 27, 2026 10:46
@jm-rivera
jm-rivera merged commit 107e12e into dev Oct 27, 2026
2 checks passed
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