Skip to content

AI scenarios

Basic chat

Bit.BlazorUI.AI Scripted transport

A working chat in three lines of markup. The session comes from the registered transport, and everything else is default behaviour.

Live demo

Send anything, or pick a starter prompt: the transport registered for the whole site echoes it back a few characters at a time.

A chat over the registered transport

Ask me anything
This demo echoes what you send, a few characters at a time.

How it works

BitAiChatSessionFactory creates a BitAiChatSession over the IBitAiTransport registered with AddBitBlazorUIAIServices, and the session drives a BitAiConversation. BitAiChat renders that conversation - the transcript, the composer, the empty state with its starter prompts and the scroll-to-latest button - and sends what the user writes through the session. The transport here is twenty lines of scripted C#; a real one wraps a provider's SDK, and nothing on the UI side changes.

Sending a message is one turn. The session appends the user message (BitAiChatSession.SubmitAsync), opens an empty assistant message, and calls the transport's one method, StreamAsync(BitAiRequest, CancellationToken). The BitAiRequest carries the conversation so far (Messages, oldest first, each an IBitAiMessage with its parts and attachments), its ConversationId, the session's generation settings (Options), the definitions of the tools the model may call (Tools) and the scoped Services. The transport answers with a stream of BitAiEvents, which the session applies to the assistant message as they arrive. This echo sends the smallest useful sequence:

  1. BitAiMessageStartedEvent - the reply has begun, so the thinking indicator can show at once.
  2. BitAiTextDeltaEvent, three characters at a time - each one appended to the reply's text part.
  3. BitAiUsageUpdatedEvent - the tokens it used, shown under the reply (the site turns ShowUsage on).
  4. BitAiMessageCompletedEvent - the reply is finished, and the message actions appear under it.

Only the text deltas are required: the session opens the message itself on the first one, and closes it when the stream ends. The stop button cancels the token the transport was handed, so a transport that honours it promptly stops at once and keeps what it had written; one that fails reports it with a BitAiErrorEvent rather than throwing (see Errors and retry). The AiScriptedTransport.cs tab holds the helpers every scenario's script is written with (AiScriptedTransport, AiScript); the EchoTransport.cs tab is the same echo as a class of its own, without them - the shape of the class an app writes.

Press Enter to send, Shift and Enter for a newline. The composer grows as you type and stops at twelve rows; while a reply streams, its send button becomes a stop button. The chat takes the height of its container, so give that container one.

Registration

AddBitBlazorUIAIServices registers the package (and the core services it builds on, so it replaces the AddBitBlazorUIServices line), then hands its callback a BitAiBuilder, which configures everything else in one statement:

  • UseTransport<TTransport>(), UseTransport(transport) or UseTransport(services => ...) - the transport the factory's sessions stream from: a scoped type, one shared instance, or one built from services.
  • AddTool(tool) and AddTool<TTool>() - the tools the model may call (Tool calling).
  • UseApprovalPolicy<TPolicy>() - which calls wait for a human decision (Tool approval).
  • AddModels(models, providers, defaultModelId) - the models the user can pick between (Models and usage).
  • UseConversationStore<TStore>() - where conversations are kept (Conversations).
  • ConfigureSessions(options => options with { ... }) - the BitAiChatSessionOptions every session of the factory starts with: the tool loop limit, text pacing, the timeout, the request options (Streaming, Parallel tools).
  • ConfigureUi(options => options with { ... }) - the presentation defaults of the components (Options & theming).
  • ConfigureRenderers(renderers => ...) - the app's own views for a tool, a structured schema, an artifact kind or a part kind (Custom tool UI, Forms).
  • ConfigureGenerativeUi(registry => ...) - the components model output may render (Generative UI).
  • Services - the service collection itself, for anything else the transport or the tools need.

Calling AddBitBlazorUIAIServices again with another callback adds to what an earlier call set up - a module of the app can register its own tools - since nothing is registered twice. Its trySingleton flag is for WebAssembly and Hybrid only: on Blazor Server the default approval policy remembers one user's "allow always", and a singleton would share it with every other user.

Components used

Feedback

Found a mistake, a gap, or something that could be clearer? Every page and every component is one click from its source.