Skip to content

AI scenarios

Structured output

Bit.BlazorUI.AI Scripted transport

A JSON array streamed a few characters at a time, rendered as a table that fills in row by row.

Live demo

Ask for a comparison: the rows appear while the JSON behind them is still incomplete.

A table from partial JSON

Ask for a comparison
Ask a question to get started.

How it works

The transport streams the value as BitAiStructuredDataDeltaEvents, and for most of a generation the payload is syntactically invalid JSON. BitAiPartialJson repairs the truncated document on every delta: open containers are closed, an incomplete trailing key is dropped, and a partially written string value is kept.

Nothing is invented: every value in the repaired document was present in the input, which is why it is safe to bind straight to a typed model - part.As(typeInfo), with the JsonTypeInfo of the app's own JsonSerializerContext, which keeps it safe to trim. With no renderer registered for its schema, an array of objects is drawn as a table, an object as a list of labelled values, and anything else as a tree.

// {"items":[{"name":"Ac  ->  {"items":[{"name":"Ac"}]}
var value = BitAiPartialJson.TryParse(part.RawJson);
var options = part.As(MyJsonContext.Default.ListOption);

The SchemaName of the deltas (options here) names the shape, which is what picks a renderer registered for it (renderers.RegisterStructured(name, ...), as the Forms scenario does). A transport whose provider returns the whole value at once sends one BitAiStructuredDataEvent(value) instead.

Asking for a shape

Ask for a comparison, then turn the response format off and ask again: the same transport answers with data matching the requested schema, or with text.

A response format in the request

Ask for a comparison
Ask a question to get started.

The model is constrained by the request, not by the UI. A session's RequestOptions (a BitAiRequestOptions, sent with every request) carry a ResponseFormat: BitAiResponseFormat.Text (free text, the default), BitAiResponseFormat.Json (any JSON), or BitAiResponseFormat.FromSchema(schema, name) (JSON matching a JSON Schema, the name some providers require) - its Kind, a BitAiResponseFormatKind, says which. The transport hands the format to its provider; this one, which plays the provider, answers with structured data named after the requested schema, and with a Markdown table when no format is asked for.

The toggle replaces the session's options (session.Options = session.Options with { ... }): they are an immutable record the session reads at the start of every request, so the next question goes out with the new format. The schema here is written by hand; BitAiTool.CreateSchema(MyJsonContext.Default.ListOption) derives one from the app's own type, the same one the value is read back into.

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.