flutter_ai_client library

Provider-agnostic chat controller for the flutter_ai family.

Exposes UseChatController, a ChangeNotifier that wraps any LlmProvider from flutter_ai_core with optimistic send, cancellation, regeneration, model/provider switching, and frame-batched streaming — without imposing a state-management library.

Re-exports flutter_ai_core so consumers get the model and provider types from a single import.

Classes

AiConversation
An ordered, immutable transcript of AiMessages.
AiEmbedding
A single embedding vector produced by an EmbeddingProvider.
AiMessage
A single turn in a conversation, authored by one AiRole.
AiPart
A single typed segment of an AiMessage.
AiRequestOptions
Provider-neutral knobs for a generation request.
AiResponseFormat
Requests structured output constrained to a JSON schema.
AiStreamEvent
A single incremental update emitted by an LlmProvider during generation.
AiToolCallSignal
A cancellation signal handed to an onToolCalls executor as its second argument.
AiUsage
Token usage for a model turn, with an optional cost estimate.
ChatObserver
Observes the agent lifecycle of a UseChatController for tracing, metrics, and logging.
ChatStore
Persists and restores AiConversations so a chat survives app restarts.
ChatThread
A lightweight summary of a stored conversation, for a thread list / sidebar.
ChatThreadStore
A ChatStore that can also enumerate and delete threads — enough to drive a conversation list / sidebar.
DataPart
A structured data payload that drives generative UI.
EmbeddingProvider
An optional capability a provider MAY implement to turn text into embedding vectors (for semantic search, clustering, and RAG retrieval).
FilePart
A file attachment: an image, document, or audio clip.
InMemoryChatThreadStore
An in-memory ChatThreadStore — handy for demos, tests, and prototyping before wiring real storage. Titles are derived via autoTitle on save.
JsonAccumulator
Accumulates a JSON document that arrives in fragments and parses it tolerantly while still incomplete.
LlmProvider
The contract every model backend implements: turn a conversation into a stream of incremental AiStreamEvents.
MessageFinished
Marks message messageId complete, carrying the reason generation ended.
MessageProcessor
Folds a stream of AiStreamEvents into evolving AiConversation state.
MessageStarted
Announces a new message and its author, before any content arrives.
MutationResult
The outcome of applying one stream event to a MessageProcessor.
PartReceived
Appends a fully-formed part (a file, source, or data payload) to message messageId.
ReasoningDelta
Appends delta to the reasoning of message messageId.
ReasoningPart
The model's intermediate reasoning ("chain of thought").
SourcePart
A citation or source referenced by the model, rendered as a link or chip.
StreamErrorEvent
Reports an error during generation.
TextDelta
Appends delta to the prose of message messageId.
TextPart
Human- or model-authored prose, typically rendered as Markdown.
TextRenderer<T>
A strategy for turning message text into a rendered representation.
TokenCounter
An optional capability a provider MAY implement to count the tokens a request would consume before sending it.
ToolCallDelta
Appends a fragment of argument JSON to tool call toolCallId.
ToolCallPart
A request from the model to invoke a tool.
ToolCallReady
Signals that tool call toolCallId has received all its arguments.
ToolCallStarted
Opens a tool call within message messageId.
ToolDefinition
A declaration of a tool the model may call: its name, purpose, and the JSON Schema describing its arguments.
ToolResultPart
The output of a tool, fed back to the model and shown to the user.
ToolResultReceived
Delivers the output of tool call toolCallId into message messageId.
UseChatController
Drives a chat conversation against any LlmProvider, exposing state as a Listenable (this class is a ChangeNotifier).

Enums

AiMessageStatus
The delivery state of an AiMessage.
AiRole
The author of a message in a conversation.
ChatStatus
The lifecycle state of a chat turn driven by a controller.
FinishReason
Why the model stopped generating a message.
ReasoningEffort
How much effort a reasoning-capable model should spend on internal thinking before answering.
ToolCallState
The lifecycle stage of a single tool call.

Extensions

GenerateObject on LlmProvider
Structured-output helpers layered on top of any LlmProvider.

Functions

attachStore(UseChatController controller, ChatStore store, String id, {Duration debounce = const Duration(milliseconds: 400)}) VoidCallback
Auto-saves controller's conversation to store under id whenever it changes and the turn has settled, coalescing rapid changes over debounce.
autoTitle(AiConversation conversation, {String fallback = 'New chat', int maxLength = 40}) String
Derives a short title from a conversation's first user message, falling back to fallback. Trims to maxLength characters.
keepLastMessages(int count) AiConversation Function(AiConversation)
History-trimming strategies for UseChatController.trimHistory.
keepLastWithSummary({required String summary(), required int count, String summaryLabel = 'Summary of earlier conversation:'}) AiConversation Function(AiConversation)
Keeps the system prefix plus a rolling summary of older turns, plus the most recent count non-system messages.
llmExceptionFor(int status, String body, {Duration? retryAfter}) LlmException
Maps an HTTP status to the matching LlmException subtype.
trimToApproxTokenBudget(int maxTokens, {int charsPerToken = 4}) AiConversation Function(AiConversation)
Keeps the system prefix plus as many of the most recent non-system messages as fit within maxTokens, estimated from text length.
validateJsonSchema(Object? value, Map<String, Object?> schema, {String path = 'args'}) List<String>
Validates value against schema, returning a list of violation messages (empty when valid). path names the root in messages (defaults to args).

Exceptions / Errors

AgentLoopException
Surfaced on UseChatController.error when the agent loop is halted because the model requested the same tool call (identical name + args) more than the controller's maxIdenticalToolCalls limit — a runaway-loop guard that stops the turn instead of looping (and spending tokens) up to maxSteps.
AiToolCallCancelled
Thrown by AiToolCallSignal.throwIfCancelled when the turn was cancelled.
LlmAuthException
Authentication/authorization failure (HTTP 401/403) — usually a bad or missing API key.
LlmException
A failed provider HTTP request, surfaced on StreamErrorEvent.error so hosts can branch on the type (auth vs. rate-limit vs. server) instead of string-matching a message.
LlmRateLimitException
Rate limited (HTTP 429). Honor retryAfter before retrying.
LlmRequestException
A non-retryable client error (other 4xx) — e.g. a malformed request.
LlmServerException
Server-side failure (HTTP 5xx, incl. Anthropic 529 overloaded).