Skip to content

AI scenarios

Custom tool UI

Bit.BlazorUI.AI Scripted transport

One tool rendered by an application component instead of the default card, everywhere that tool appears.

Live demo

Search the documentation: search_docs reports its progress, then its hits, in a card of this site's own.

A tool drawn by the app

Search the documentation
Ask a question to get started.

How it works

search_docs is rendered by SearchResultCard, an ordinary component of this site. BitAiRendererRegistry maps a tool name to a renderer (renderers.RegisterTool<SearchResultCard>("search_docs")), so the substitution applies wherever that tool is called without touching the message list. The component is handed the call as its Call parameter and re-renders as the call changes: its progress reports while the tool runs, its result once it has returned. RegisterTool(name, context => ...) takes a render fragment instead, handed a BitAiToolCallContext (the call, its message and the session).

The transport asks for search_docs as for any tool (see Tool calling), and the session runs it. The tool is declared with the BitAiTool.Create<TArgs>(name, description, argumentsTypeInfo, (args, invocation, token) => ...) overload (see Declaring a tool), whose handler is handed the BitAiToolInvocation and returns the whole outcome. It reports where it is through invocation.Progress - a BitAiToolProgress with a Fraction and a Message, which lands on the call as Call.Progress - and returns a full BitAiToolOutcome: the value the card reads (Call.Result.Value), the Text the model reads, and the Citations of what it searched, which the session adds to the reply's sources. The card reads the arguments through Call.DisplayArguments, which holds them while they still stream, and the time the call took through Call.Duration.

A custom renderer is handed data a model produced, so the shape it wants is a hope, not a guarantee: the card checks the payload before it reads it, and a renderer that throws anyway is contained by the boundary around it rather than taking the conversation down. The same registry takes renderers for message part kinds, artifact kinds, structured output schemas, code languages and citations.

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.