AI scenarios
Structured output
Bit.BlazorUI.AI Scripted transportA 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
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
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
BitAiStructuredDataView- the structured part: a registered renderer, else a default that reads the shape.BitAiDataTable- an array of objects as a table.BitAiJsonView- any other value, as a collapsible tree.BitAiMarkdownView- the table the second demo writes as text when no format is asked for.
Feedback
Found a mistake, a gap, or something that could be clearer? Every page and every component is one click from its source.