UseChatController class
Drives a chat conversation against any LlmProvider, exposing state as a Listenable (this class is a ChangeNotifier).
This is the Dart analogue of the web useChat hook. It is deliberately
un-opinionated about state management: bind it with ListenableBuilder,
or adapt it to Bloc / Riverpod / Provider — the controller imposes nothing.
The raw events stream is available as an escape hatch for custom state
layers.
Streaming performance
Incoming events are folded by an internal MessageProcessor, and
notifyListeners is coalesced: many events arriving in one turn trigger
a single notification. The coalescing strategy is injectable via scheduler
(defaulting to scheduleMicrotask); combined with Flutter's per-frame
rebuild pipeline this keeps high token rates from dropping frames. A host
that wants strict frame alignment can pass a scheduler backed by
SchedulerBinding.addPostFrameCallback.
History
The full message history is retained so the user can scroll the whole session; trimming for token budgets is a provider/server concern, not the controller's.
- Inheritance
-
- Object
- ChangeNotifier
- UseChatController
Constructors
-
UseChatController({required LlmProvider provider, AiConversation? initial, List<
ToolDefinition> tools = const [], AiRequestOptions? options, Future<List< onToolCalls(List<ToolResultPart> >ToolCallPart> calls, AiToolCallSignal signal)?, int maxSteps = 8, int maxBranches = 20, int? tokenBudget, int maxIdenticalToolCalls = 0, bool validateToolArgs = true, ChatObserver? observer, AiConversation trimHistory(AiConversation conversation)?, void scheduler(VoidCallback callback)?, String idGenerator()?}) -
Creates a controller bound to
provider.
Properties
- branchCount → int
-
How many regenerated versions exist for the latest turn (1 = no
alternatives). Drive an
AiBranchwith this and branchIndex.no setter - branchIndex → int
-
The 0-based index of the version currently shown for the latest turn.
no setter
- conversation → AiConversation
-
The full conversation transcript.
no setter
- error → Object?
-
The error from the last failed turn, or
null.no setter -
events
→ Stream<
AiStreamEvent> -
A broadcast stream of every event applied to the conversation.
no setter
- hashCode → int
-
The hash code for this object.
no setterinherited
- hasListeners → bool
-
Whether any listeners are currently registered.
no setterinherited
-
messages
→ List<
AiMessage> -
The messages in the conversation.
no setter
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
- stackTrace → StackTrace?
-
The stack trace captured alongside error, or
null.no setter - status → ChatStatus
-
The current turn status.
no setter
- totalUsage → AiUsage?
-
The summed token usage across every message in the conversation that
reported it, or
nullif none did. Feed anAiContextMeteror estimate cost with AiUsage.estimateCost.no setter
Methods
-
addListener(
VoidCallback listener) → void -
Register a closure to be called when the object changes.
inherited
-
addToolResults(
List< ToolResultPart> results) → Future<void> -
Appends tool
resultsas an AiRole.tool message and streams the model's continuation — call this after executing the tool calls the model requested. A no-op ifresultsis empty. -
clear(
) → void - Clears the conversation and cancels any in-flight turn.
-
dispose(
) → void -
Discards any resources used by the object.
override
-
editLastUserMessage(
String text) → Future< void> -
Edits the most recent user message to
textand re-runs from it. A no-op if there is no user message. See editMessage. -
editMessage(
String messageId, String text) → Future< void> -
Edits the user message
messageIdtotext— keeping any non-text parts such as attachments — discards every message after it, and re-runs the model from that point. A no-op ifmessageIdis not a user message in the transcript, or if the edit would leave the message empty. -
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
notifyListeners(
) → void -
Call all the registered listeners.
inherited
-
regenerate(
) → Future< void> - Re-runs the model from the most recent user message, discarding everything after it. A no-op if there is no user message.
-
removeListener(
VoidCallback listener) → void -
Remove a previously registered closure from the list of closures that are
notified when the object changes.
inherited
-
selectBranch(
int index) → void -
Switches the latest turn to regenerated version
index(0-based). A no-op out of range, while a turn is in flight, or if already showing it. -
sendText(
String text, {List< AiPart> attachments = const []}) → Future<void> -
Sends a user message composed of
textand optionalattachments. -
setOptions(
AiRequestOptions? options) → void - Replaces the request options applied to subsequent turns (for example, to change the model).
-
setProvider(
LlmProvider provider) → void - Switches the active provider. Does not affect the current transcript or interrupt an in-flight turn.
-
setTools(
List< ToolDefinition> tools) → void - Replaces the tools advertised to the provider on subsequent turns.
-
stop(
) → void - Cancels the in-flight turn, finalizing the streaming message as stopped.
-
submit(
AiMessage userMessage) → Future< void> -
Appends
userMessageoptimistically and streams the model's response. -
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited