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

Constructors

UseChatController({required LlmProvider provider, AiConversation? initial, List<ToolDefinition> tools = const [], AiRequestOptions? options, Future<List<ToolResultPart>> onToolCalls(List<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 AiBranch with 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 null if none did. Feed an AiContextMeter or 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 results as an AiRole.tool message and streams the model's continuation — call this after executing the tool calls the model requested. A no-op if results is 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 text and 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 messageId to text — keeping any non-text parts such as attachments — discards every message after it, and re-runs the model from that point. A no-op if messageId is 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 text and optional attachments.
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 userMessage optimistically and streams the model's response.
toString() String
A string representation of this object.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited