AI scenarios
Long conversations
Bit.BlazorUI.AI Scripted transportFive hundred messages with code, tables, tool calls, and citations, rendered through a virtualized list.
Live demo
Scroll to the top and back, then send something: new content follows the view only while you are already at the bottom.
Five hundred messages
Answer 221. The cost is dominated by rendering, not by parsing. Coalescing updates removes most of it, and virtualization removes the rest.
Here is the shape of it:
var budget = TimeSpan.FromMilliseconds(18);
scheduler.Request();The interval is the only dial that matters.
- Render modes 94%
- Circuit lifetime 81%
Two passages matched, and they say the same thing.
| Messages | Rendered | Notes |
|---|---|---|
| 60 | all | below the threshold |
| 500 | visible only | virtualized |
Answer 225. The cost is dominated by rendering, not by parsing. Coalescing updates removes most of it, and virtualization removes the rest.
Here is the shape of it:
var budget = TimeSpan.FromMilliseconds(26);
scheduler.Request();The interval is the only dial that matters.
- Render modes 94%
- Circuit lifetime 81%
Two passages matched, and they say the same thing.
| Messages | Rendered | Notes |
|---|---|---|
| 60 | all | below the threshold |
| 500 | visible only | virtualized |
Answer 229. The cost is dominated by rendering, not by parsing. Coalescing updates removes most of it, and virtualization removes the rest.
Here is the shape of it:
var budget = TimeSpan.FromMilliseconds(34);
scheduler.Request();The interval is the only dial that matters.
- Render modes 94%
- Circuit lifetime 81%
Two passages matched, and they say the same thing.
| Messages | Rendered | Notes |
|---|---|---|
| 60 | all | below the threshold |
| 500 | visible only | virtualized |
Answer 233. The cost is dominated by rendering, not by parsing. Coalescing updates removes most of it, and virtualization removes the rest.
Here is the shape of it:
var budget = TimeSpan.FromMilliseconds(42);
scheduler.Request();The interval is the only dial that matters.
- Render modes 94%
- Circuit lifetime 81%
Two passages matched, and they say the same thing.
| Messages | Rendered | Notes |
|---|---|---|
| 60 | all | below the threshold |
| 500 | visible only | virtualized |
Answer 237. The cost is dominated by rendering, not by parsing. Coalescing updates removes most of it, and virtualization removes the rest.
Here is the shape of it:
var budget = TimeSpan.FromMilliseconds(50);
scheduler.Request();The interval is the only dial that matters.
- Render modes 94%
- Circuit lifetime 81%
Two passages matched, and they say the same thing.
| Messages | Rendered | Notes |
|---|---|---|
| 60 | all | below the threshold |
| 500 | visible only | virtualized |
Answer 241. The cost is dominated by rendering, not by parsing. Coalescing updates removes most of it, and virtualization removes the rest.
Here is the shape of it:
var budget = TimeSpan.FromMilliseconds(18);
scheduler.Request();The interval is the only dial that matters.
- Render modes 94%
- Circuit lifetime 81%
Two passages matched, and they say the same thing.
| Messages | Rendered | Notes |
|---|---|---|
| 60 | all | below the threshold |
| 500 | visible only | virtualized |
Answer 245. The cost is dominated by rendering, not by parsing. Coalescing updates removes most of it, and virtualization removes the rest.
Here is the shape of it:
var budget = TimeSpan.FromMilliseconds(26);
scheduler.Request();The interval is the only dial that matters.
- Render modes 94%
- Circuit lifetime 81%
Two passages matched, and they say the same thing.
| Messages | Rendered | Notes |
|---|---|---|
| 60 | all | below the threshold |
| 500 | visible only | virtualized |
Answer 249. The cost is dominated by rendering, not by parsing. Coalescing updates removes most of it, and virtualization removes the rest.
Here is the shape of it:
var budget = TimeSpan.FromMilliseconds(34);
scheduler.Request();The interval is the only dial that matters.
How it works
Up to a threshold every message is rendered, which is both simpler and faster. Past it
(BitAiUiOptions.VirtualizeThreshold, sixty messages here) only the newest sixty are: scroll up
and the older ones come in thirty at a time above what you are reading, which stays where it is, and once you
are back at the newest message they are let go of again. Nothing is estimated - every message drawn is drawn
at its own height - so the content never jumps and the view never goes blank. The conversation is
deliberately varied - a thousand identical paragraphs would prove nothing; the hard case is mixed content
with wildly different heights.
The five hundred messages are built in code (AiDemoConversations.Long) - a
BitAiConversation filled with AddMessage, each answer a
BitAiMessage of parts: text, Markdown, a tool call with its result, a table with a citation - and
handed to the session factory (SessionFactory.Create(conversation)), so new messages go to the
transport registered for the site, which echoes them. A conversation restored from storage is handed over
the same way (see Conversations).
Where the render budget goes:
- A part subscribes to itself, so a token re-renders the part it went into - not its message, nor the transcript. The chat around it renders as a turn starts and as it ends.
-
Each of those views renders at most once per 50 ms
(
BitAiUiOptions.RenderInterval), however many tokens arrive in that time - coalesced by aBitAiRenderScheduler, which an app's own component listening to a stream can use too (see Streaming). -
Bursts of text are evened out before they reach the conversation: the session paces the deltas
(
BitAiChatSessionOptions.Pacing), so a paragraph arriving at once is drawn over a few frames rather than in one. - Text accumulates in a builder, so appending stays linear.
- Markdown before the last block boundary is parsed once and reused.
Components used
BitAiMessageList- the transcript, drawing only its newest messages past the threshold, with auto-scroll that follows only a reader at the newest message.BitAiScrollToLatest- the way back down once the reader has scrolled away.BitAiMessagePartView- one part, re-rendered only when it changes.
Feedback
Found a mistake, a gap, or something that could be clearer? Every page and every component is one click from its source.