Components.AI built-in UIs
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 281
Description
**Scope:** the UI layer of `Microsoft.AspNetCore.Components.AI` (PR [#67673](https://github.com/dotnet/aspnetcore/pull/67673), branch `javiercn/components-ai-full`).
**Target:** an out-of-box experience comparable to the GitHub Copilot app and the Microsoft Copilot website.
**Not in scope:** Blocks, RichText AST, Pipeline, Engine internals and the `[ToolBlock]` source generator — the low-level layers are in good shape and are not revisited here.
**Status:** requirements and discovery only. Nothing here has been implemented.
This document is the output of a full pass over the library's UI surface: every component was read, the resulting gaps were written down as requirements, and the requirements were then justified against fifteen user journeys and three structural sketches. It is long because it is meant to be the single reference for the work, not a summary of it.
### How to read it
The document has four parts, and they answer four different questions.
1. **Decisions and findings** — what has already been settled, and what reading the current code turned up. Everything else is constrained by these.
2. **Structural sketches** — deliberately crude pictures of what the composer, the message list, and tool calls are *made of*. They are **non-normative**: they encode structure and state, never colour, type, spacing or layout. They exist because several requirements below are almost impossible to state unambiguously in prose.
3. **User journeys** — fifteen journeys covering who uses this and how. Each one is the justification for a cluster of requirements; where a journey and a requirement disagree, the journey is right and the requirement needs fixing.
4. **The requirements backlog** — the actual work, in thirteen sections, each item sized and prioritised.
Because the whole thing is well past GitHub's 65k limit for a single body, **each part is posted as its own comment below** and indexed in the table of contents. This body holds the framing: the character we are designing for, the personas, and the journey index.
Priority: **P0** ship-blocking for a credible out-of-box experience · **P1** important · **P2** later. Size: **S/M/L**.
---
## Contents
| # | Section | What it covers |
|---|---|---|
| 1 | [Decisions and findings](https://github.com/dotnet/aspnetcore/issues/68227#issuecomment-5190997252) | The 15 decisions that constrain everything, and 7 findings from reading the code |
| 2 | [Sketch — the composer](https://github.com/dotnet/aspnetcore/issues/68227#issuecomment-5190997749) | Three bands, button states, attachments, narrow/touch |
| 3 | [Sketch — the message list](https://github.com/dotnet/aspnetcore/issues/68227#issuecomment-5190998252) | Turns vs. messages, the two decorator seams, streaming, rich text, media |
| 4 | [Sketch — tool calls and approval](https://github.com/dotnet/aspnetcore/issues/68227#issuecomment-5190998767) | Three rendering modes; approval wrapping the call |
| 5 | [Journeys 1–5](https://github.com/dotnet/aspnetcore/issues/68227#issuecomment-5190999267) | Ask & stream · stop & retry · attach · act on an answer · long conversations |
| 6 | [Journeys 6–10](https://github.com/dotnet/aspnetcore/issues/68227#issuecomment-5190999755) | Keyboard & screen reader · approvals · voice · edit & resubmit · switching |
| 7 | [Journeys 11–15](https://github.com/dotnet/aspnetcore/issues/68227#issuecomment-5191000253) | Suggestions · media · model & mode · error recovery · phone |
| 8 | [Backlog A–F](https://github.com/dotnet/aspnetcore/issues/68227#issuecomment-5191000705) | Foundations · virtualization · composer · attachments · media · decorators |
| 9 | [Backlog G–M](https://github.com/dotnet/aspnetcore/issues/68227#issuecomment-5191001248) | Interaction state · keyboard · a11y · rich text · suggestions · shells · gates |
| 10 | [Open design decisions](https://github.com/dotnet/aspnetcore/issues/68227#issuecomment-5191001777) | The 8 things still genuinely undecided |
| 11 | [Appendix — image manifest](https://github.com/dotnet/aspnetcore/issues/68227#issuecomment-5191002346) | Where the sketch images come from and how to regenerate them |
---
## App character
Everything below is conditioned by how this is supposed to feel. The library is not an app, but it ships enough default behaviour to set a tone, and these are the attributes we want that default to carry.
It should feel **calm**. A conversation with an assistant is a reading experience punctuated by typing, and the single biggest way a chat UI fails is by moving things around while someone is trying to read them. Nothing should jump, reflow, or scroll out from under the reader unless they asked for it. This is why auto-follow is opt-in rather than the default, why decorators reserve their space before they are revealed, and why media reserves its dimensions before it loads.
It should feel **honest about what it is doing**. The system is frequently busy, sometimes for a long time, occasionally on the user's behalf in ways that matter (a tool that deletes things). Every one of those states should be visible and truthful: busy looks busy, stopped looks stopped rather than finished, failed says so where the answer would have been, and an action that needs consent asks for it with enough context to answer.
It should feel **unobtrusive**. The library's job is to get out of the way of the app built on top of it. Defaults are quiet — tool calls do not render, chrome does not accumulate, nothing is decorated that was not asked for — and every default is replaceable without reimplementing the thing it replaced.
It should feel **trustworthy and predictable**. The same gesture does the same thing everywhere; a control that is disabled says why; a destructive action says what it will destroy before it does it; nothing the user typed is ever silently lost.
Its **voice** is plain and unfussy. Interface text states what happened and what can be done about it, in the user's language, without apology or personality. The library ships no cute copy — and, since every string is currently hardcoded English, it does not really ship copy anyone else can use either (see A4).
**Context of use** spans a full-page app, a drawer alongside other content, and a floating bubble, on a desktop with a keyboard, on a phone with a thumb, and through a screen reader. None of these is the primary case that the others degrade from.
---
## Personas
Four kinds of people travel these journeys. They are not market segments; they are the four sets of constraints the UI has to satisfy simultaneously.
**The daily driver** uses the assistant many times a day for real work, mostly with a keyboard and a large screen, interleaved with everything else they are doing. They ask a question, skim the answer while it is still arriving, and act on it — copying a snippet, retrying a bad answer, attaching a log file. They are fast and slightly impatient, they have long conversations they come back to, and they notice immediately when the UI wastes their time or loses their place. Most of the journeys below are theirs.
**The power user** pushes the thing harder. They run several conversations at once and switch between them, they care which model answered, they edit a badly worded question rather than asking again, and they will approve or reject tool actions that touch real systems. They want control surfaced, not hidden, and they are the persona most likely to be failed by state that silently resets.
**The keyboard and screen reader user** never touches a pointer. Everything has to be reachable in a sensible order, everything interactive has to say what it is, and the parts of the experience that are purely visual — an answer streaming in, a control becoming available, a request for approval appearing — have to be announced, at the right time and without flooding. This persona is not an accessibility checklist bolted on at the end; they are one of the four people the design has to work for, and several requirements exist only because of them.
**The mobile user** is on a phone or tablet, one-handed, with an on-screen keyboard eating half the viewport and no hover at all. Every affordance that reveals itself on hover has to have a tap equivalent, every target has to be finger-sized, and the composer has to stay reachable and visible while the keyboard is up. Today the library has zero media queries, so this persona is currently unserved.
---
## The journeys at a glance
| # | Journey | Persona | Priority |
|---|---|---|---|
| 1 | [Ask a question and read the answer](#journey-1--ask-a-question-and-read-the-answer) | Daily driver | Must |
| 2 | [Stop a bad answer and try again](#journey-2--stop-a-bad-answer-and-try-again) | Daily driver | Must |
| 3 | [Attach a file and ask about it](#journey-3--attach-a-file-and-ask-about-it) | Daily driver | Must |
| 4 | [Act on an answer](#journey-4--act-on-an-answer) | Daily driver | Must |
| 5 | [Review a long conversation](#journey-5--review-a-long-conversation) | Daily driver | Must |
| 6 | [Work by keyboard and screen reader](#journey-6--work-by-keyboard-and-screen-reader) | Keyboard and screen reader user | Must |
| 7 | [Approve a tool action](#journey-7--approve-a-tool-action) | Daily driver | Must |
| 8 | [Ask by voice](#journey-8--ask-by-voice) | Daily driver | Should |
| 9 | [Edit a question and run it again](#journey-9--edit-a-question-and-run-it-again) | Power user | Should |
| 10 | [Move between conversations](#journey-10--move-between-conversations) | Power user | Should |
| 11 | [Begin from a suggestion](#journey-11--begin-from-a-suggestion) | Daily driver | Should |
| 12 | [Read an answer containing media](#journey-12--read-an-answer-containing-media) | Daily driver | Should |
| 13 | [Change the model or mode](#journey-13--change-the-model-or-mode) | Power user | Should |
| 14 | [Recover when the request fails](#journey-14--recover-when-the-request-fails) | Daily driver | Should |
| 15 | [Use it on a phone](#journey-15--use-it-on-a-phone) | Mobile user | Must |
All fifteen are also playable as a low-fidelity sketch — `docs/user-journeys/sketch/`, run with `dotnet run preview.cs`. The sketch is a journey-confirmation tool, not a design: it is intentionally style-free and says nothing about how any of this should look.
---
Contributor guide
Research direction
Start with the linked PR and the requirement sections in the issue comments, then run `docs/user-journeys/sketch/` with `dotnet run preview.cs` to understand the intended journeys. This issue is a broad discovery and design backlog with open decisions, so a contributor would need a separately scoped requirement before implementation can be considered done.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100