Repository navigation
Give each decision option a visual of its own, and let a Planner store the images it makes - #750
Merged
Merged
Conversation
…diagrams and tables A member who has to choose between two options should be able to compare them by looking, not by reading two paragraphs that differ in one clause. An option's `preview` is now its own field from the question a Planner asks to every card surface, and it is drawn as a framed Markdown block under the option's label and description. The field. `Question.Option` and the document's `Option` node carry an optional `preview`, at most 16,000 characters, kept verbatim for a host dialog and left out when empty. It round-trips through the document source as an `Option` attribute, indentation included, and through the stored definition, the projection into the plan, the backfill comparison and the definition shape the server compares before it publishes. Atomic's `ask_user_question` bridge no longer joins the preview onto the end of the description: it passes both, and the answer still echoes the chosen option's preview. The Planner's own `ask`, `open_decision` and `open_decisions` input takes it too. A card saved before this, whose preview was joined into its description, is untouched and looks the same. The rendering. `QuestionView` is the one place every surface reads an option from, so the Decisions tab, the inline card, the phone sheet, answered cards and the decision page all show the frame, and an answered card keeps every option's visual with the chosen one marked. The frame is the inset tone with a passive edge, in the option's own column. It holds whatever the card's Markdown renderer draws: a Mermaid fence through the document's renderer at a bounded height, the document's own images, code, and, in a preview only, GitHub pipe tables. A picture is held to the column and a third of a screen, less on a phone, and a loaded image opens large from its own button, in the editor's existing lightbox, without picking the option it sits in. An image that is not this document's shows its alt text, as before. Beside criteria an option shows a small thumbnail and leaves other content out of the row, so the matrix keeps its shape. Accessibility. An option with a visual is still one radio button named by its label and description, not by every word a diagram carries; the visual is a group of its own named "Preview of <label>", and every image keeps its alt text and a "View larger" name. A card without previews keeps the markup and the accessible names it had. Verification. A unit test covers the schema, the document round trip, the bridge and the rendering on every card surface. Decisions e2e covers a picture and a Mermaid preview on the inline card, the Decisions tab, the decision page, the phone sheet and an answered card, the large view and the keyboard, a legacy card, and a criteria row, with screenshots of each. Assistant-model: Claude Opus 5.5 (fast) Assistant-workflow: inline Assistant-verification: bun test on this commit alone passed: apps/server 3952, apps/web 858, packages/question 214, packages/dialect 173 Assistant-verification: bun run types passed on this commit alone; bun run ci passed with the whole change, including the design contract and the impeccable detector Assistant-verification: bun run e2e passed with the whole change: the new decision-option-previews spec and the other Decisions specs, 76 passed Co-authored-by: Alex Lavaee <lavaman131@github.com>
Decision options can carry an image, but a Planner that generates one, from codemode or any image model, had nowhere to put it: only MCP clients could upload to a document's images. This gives every Planner turn a tool to do that, tells the Planner how to use it, and lets a connected Planner learn whether the server supports all of it before it relies on it. `upload_plan_image`. A Planner turn can store a PNG, JPEG, WebP or GIF of at most 1 MiB in the document's own images, with required alt text of at most 200 characters, and gets back its path and the `` Markdown for a card body or an option's `preview`. The bytes get the same checks `upload_image` makes, the same bytes give the same path, and the image loads only for people who can read this document. The server never reads a path on the Planner's side: a remote Planner encodes its own file. The room stores it only during a live Planner turn, never for a background job, never in an archived document, and attributes it to the member the turn is for, or to the Planner's owner for a turn nobody asked for. It is a write tool, so the background job profiles exclude it. Capability. `decision-option-previews` joins `run-stage-deltas` as an agent connection feature: a client names it in `Chopin-Agent-Features`, and `attached.features` lists it when the server supports it. A turn's host tools include `upload_plan_image` only for a client that asked, so an older client is never offered a tool it cannot use. The package client asks for both features. A server from before the feature joins a preview onto the option's description and offers no tool, as before. Planner guidance. The Planner's `ask`, `open_decision` and `open_decisions` tools take `preview` per option, and its instructions tell it members decide by looking: give each option of a comparison a visual of the same kind, a small Mermaid diagram, a table or an image it made, and keep the description as the caption. Verification. Unit tests cover the tool's input checks, the room's upload access (live turn, archived document, background job, attribution), and the feature-gated tool list. The remote Planner e2e attaches a real agent, stores two images through the tool, asks a question whose options and body use them, sees them drawn, checks that only this document serves the bytes, and returns the chosen option's preview. Assistant-model: Claude Opus 5.5 (fast) Assistant-workflow: inline Assistant-verification: bun test apps/server (3961), apps/web (858), packages passed with the whole change Assistant-verification: bun run types and bun run ci passed with the whole change, including the design contract and the impeccable detector Assistant-verification: bun run e2e passed: planner-attachment with decision-option-previews, 11 tests, and ten other Decisions specs, 76 tests Co-authored-by: Alex Lavaee <lavaman131@github.com>
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.
Closes #749.
Decision options can now carry their own visual, so a member can compare the choices by looking at them, and a Planner can make the pictures.
What changed
An option's
previewis its own field, end to end.ask_user_question(Atomic), the input request of an attached Planner, and the Planner's ownask,open_decisionandopen_decisionstools keep an option'spreviewas a field of its own. It is Markdown, at most 16,000 characters, stored verbatim, and travels through the stored definition, the document source (anOptionattribute), the projection into the plan and the answer, which still echoes the chosen option's preview. The bridge no longer joins it onto the description. A card saved before this, whose preview was joined into its description, looks the same.Every surface frames it under the option, in the option's own column: the Decisions tab, the inline document card, the phone sheet, answered cards (which keep every option's visual, the chosen one marked) and the decision page. It holds whatever the card's Markdown draws: the document's own images, a Mermaid fence (bounded, "Show whole diagram"), code, and, in a preview only, GitHub pipe tables.
The Planner can make the pictures.
upload_plan_imagestores a PNG, JPEG, WebP or GIF (at most 1 MiB, required alt text) in the document's images and returns theMarkdown for a card body or an option'spreview. It reuses the image storage, theupload_imagechecks and the document-scoped image route. It works only during a live Planner turn, never for a background job or an archived document, and never reads a path on the Planner's side (a remote Planner sends base64). The Planner's instructions now say members decide by looking and to give each option of a comparison a visual of the same kind.A connected Planner can detect all of it.
decision-option-previewsis a new agent connection feature next torun-stage-deltas: a client names it inChopin-Agent-Features,attached.featureslists it when supported, andupload_plan_imageis in a turn'stoolsonly for a client that asked. The package client asks for both. A server without it joins a preview onto the description, as before. Documented indocs/agent-connection.md("Option previews") anddocs/decisions.md.Screenshots
From the e2e run (
CHOPIN_SHOTS):Inline card with picture previews
Decisions tab
Decision page
Answered card keeps every option's visual
Phone sheet
Opened large
Opened large on a phone
Mermaid diagram and table previews
Mermaid and table previews on a phone
Criteria row thumbnail
Tests
e2e/decision-option-previews.e2e.ts): picture and Mermaid previews on every surface, large view and keyboard, a legacy card, a criteria row.e2e/planner-attachment.e2e.ts): a real attached agent stores two images through the tool, asks a question using them in its options and body, sees them drawn, checks that only this document serves the bytes, and gets the chosen option's preview back.bun run types,bun run ci(design contract, impeccable detector),bun testin apps/server (3961), apps/web (858) and the packages, and 76 Decisions e2e tests plus the 11 above.Notes
question-view.tsx,questionnaire.tsx); no new exception.micromark-extension-gfm-tableandmdast-util-gfm-table, already in the lockfile through the editor), so existing card text renders as before.