ChatController
Owns one conversation and drives a ChatBackend, the Kotlin counterpart of the AI SDK useChat() hook.
Beyond send/stop it supports a message queue (send while busy), reply versions (regenerate keeps the old answer as a branch) and checkpoints (rewind the conversation to an earlier turn).
Parameters
resolved on every turn, so switching provider/model applies to the next message without losing the conversation. It receives the controller's ToolApprover, which surfaces approval requests in the UI until respondToApproval is called. Threading: call it from one thread and give it a scope on a single-threaded dispatcher — viewModelScope (main thread) is the intended setup. The controller keeps its in-flight turn in plain fields, so a multi-threaded dispatcher such as Dispatchers.Default would race.
where turns run; collection happens on this scope's dispatcher (backends move their own I/O off the main thread).
streamed deltas are coalesced and published at most this often (one frame by default), so a model emitting hundreds of tokens per second never recomposes the UI per token. Structural events (tool calls, part ends, errors) publish immediately. 0 publishes every event.
Constructors
Functions
Ask again; the previous reply is kept as another version of the answer.
Answer a tool approval request with a reason or edited arguments.
Answer a tool approval request (AI Elements <Confirmation>).
Answer one of ChatState.inputRequests.
Rewind the conversation to just after messageId (AI Elements <Checkpoint>); later messages are dropped.
Show another version of an assistant reply (AI Elements <Branch>).
Send a user message (text and/or attachments, and data parts such as an A2UI action — DataPart.A2UI). While a reply is streaming the message is queued and sent when the turn finishes. Returns false only when there is nothing to send.
Send a queued prompt now (when idle), e.g. after the queue paused on stop/error.