Package-level declarations

Types

Link copied to clipboard

Where AgentComputerScaffold shows the agent's computer.

Link copied to clipboard
@Stable
class AgentComputerState

What the agent's computer view shows (Manus-style): which reply, which step, whether it follows the live run, and a replay in progress. Create with rememberAgentComputerState; Chat and Conversation make one when none is provided.

Link copied to clipboard
@Immutable
data class AgentProgress(val phase: AgentProgress.Phase, val tool: ToolPart? = null, val steps: Int = 0, val plan: List<WorkflowStep> = emptyList(), val reply: String = "", val error: String? = null)

Where the agent's run stands, for surfaces outside the chat (notifications, widgets, a watch): derived from the conversation's model alone, whatever protocol produced it.

Link copied to clipboard
@Immutable
data class AgentStep(val tool: ToolPart, val files: List<FilePart>)

One step of an agent run: a tool call and the files (screenshots) it produced, in message order.

Link copied to clipboard
@Immutable
data class AgentToolSpec(val name: String, val description: String? = null, val schema: String? = null)

A tool an agent can call; schema is its JSON input schema, if shown.

Link copied to clipboard
class AiElementsFileProvider : FileProvider

The library's own FileProvider, so opening a file never collides with the app's provider.

Link copied to clipboard
@Immutable
class AiElementsRenderers(val tools: Map<String, ToolRenderer> = emptyMap(), val data: Map<String, DataRenderer> = emptyMap(), val tool: (ToolPart) -> ToolRenderer?? = null, val codeBlocks: Map<String, CodeBlockRenderer> = emptyMap())

App-wide overrides for how parts render — the extension point for customising the chat without forking Conversation or the message rows. Provide it with CompositionLocalProvider(LocalAiElementsRenderers provides AiElementsRenderers(...)).

Link copied to clipboard
fun interface CodeBlockRenderer

Renders a fenced code block of one language (``` ```lang ```) in place of the code view. */

Link copied to clipboard
fun interface DataRenderer

Renders one data part in place of the built-in DataPartView shapes.

Link copied to clipboard
fun interface FileLoader

Loads the bytes behind a file URL for attachment previews (data: URLs are decoded without it). Replace it to use your app's HTTP stack, cache or authentication.

Link copied to clipboard

What a model can do; shown as small tags.

Link copied to clipboard
@Immutable
data class ModelOption(val id: String, val name: String = id, val provider: String? = null, val description: String? = null, val capabilities: Set<ModelCapability> = emptySet(), val contextWindow: Int? = null)

A model offered by ModelSelector; provider groups the list, contextWindow is in tokens.

Link copied to clipboard
data class OpenInTarget(val label: String, val urlTemplate: String)

A destination for OpenInChat; {q} in urlTemplate is replaced by the encoded prompt.

Link copied to clipboard
@Immutable
data class QuestionAnswer(val selected: List<String>, val text: String? = null)

What the user answered: chosen option ids and/or their own text.

Link copied to clipboard
@Immutable
data class QuestionOption(val id: String, val label: String, val description: String? = null)

A choice in a Question; id is what QuestionAnswer.selected reports.

Link copied to clipboard
fun interface RunReplay

Plays a reply's run back from its recorded events, at their original pace, when a recording exists — e.g. AG-UI's event log (AgUiEventLog.replayOf in ai-elements-core). The flow's events are folded into a fresh reply as they arrive, exactly as a live run is.

Link copied to clipboard

Progress of a plan / task / chain-of-thought step.

Link copied to clipboard
@Stable
class StickToBottomState

"Stick to bottom" for a chat list (the idea behind AI Elements' use-stick-to-bottom), for a normal top-to-bottom LazyListState:

Link copied to clipboard
fun interface ToolRenderer

Renders one tool call in place of the built-in ToolCall / Subagent. The decision callback carries approval, denial reason, edited arguments and remember choice. A null callback means read-only rendering: do not show approval actions. Respect ToolPart.approvalAnswers when offering edits or a reason.

Link copied to clipboard
data class WorkflowStep(val label: String, val description: String? = null, val status: StepStatus = StepStatus.PENDING, val badges: List<String> = emptyList())

One step of a plan, task or chain of thought; badges are short tags such as files or URLs.

Properties

Link copied to clipboard

The chat apps OpenInChat offers by default; pass your own list to change them.

Link copied to clipboard
Link copied to clipboard

Whether a tool call is a delegation to a sub-agent (render it with Subagent).

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
val LocalAgentComputer: ProvidableCompositionLocal<AgentComputerState?>

The agent's computer view of the enclosing AgentComputerScaffold.

Link copied to clipboard
val LocalAiElementsRenderers: ProvidableCompositionLocal<AiElementsRenderers>
Link copied to clipboard
val LocalFileLoader: ProvidableCompositionLocal<FileLoader>

Functions

Link copied to clipboard
fun ToolPart.activityLabel(resources: Resources): String

What this call is doing, for people ("Running command · ls -la"), for surfaces outside composition (notifications, widgets).

Link copied to clipboard
@Composable
fun Agent(name: String, modifier: Modifier = Modifier, model: String? = null, instructions: String? = null, tools: List<AgentToolSpec> = emptyList(), outputSchema: String? = null, description: String? = null, toolsTitle: String? = null)

An agent's definition (AI Elements <Agent>): name and model, its instructions, the tools it may call (each expands to its schema) and the shape of its output. Also renders a remote agent's card (e.g. A2A): pass its description and its skills as tools with toolsTitle.

Link copied to clipboard
@Composable
fun AgentComputerPanel(state: AgentComputerState, message: Message, modifier: Modifier = Modifier)

The agent's computer: the selected step as the agent saw it — its screenshot, a terminal for a command, the diff of an edit, the file it read, the page it fetched (ToolPart.category) — with a timeline to scrub, step or play through, "back to live" while the reply streams, and a replay of the recorded run when there is one (RunReplay).

Link copied to clipboard
@Composable
fun AgentComputerScaffold(state: AgentComputerState, messages: List<Message>, modifier: Modifier = Modifier, layout: AgentComputerLayout = AgentComputerLayout.Auto, content: @Composable () -> Unit)

Lays out content (a conversation) with the agent's computer view of state: by default (AgentComputerLayout.Auto) a side pane next to it when there is room (at least 720dp, as Material 3's supporting pane on expanded widths), a bottom sheet otherwise. The width is the scaffold's own, so it adapts inside a list–detail layout too; an app that has an adaptive scaffold of its own hosts the panel there (AgentComputerLayout.Hosted).

Link copied to clipboard
@Composable
fun AgentRunDialog(message: Message, prompt: String?, onDismiss: () -> Unit)

Full-screen WorkflowCanvas of one agent run.

Link copied to clipboard

The steps of message: each tool call with the image files that follow it (a screenshot of what the call did — AI SDK file parts, AG-UI media tool results, on-device tools' files), whatever protocol produced them.

Link copied to clipboard
@Composable
fun AssistantAvatar(active: Boolean, modifier: Modifier = Modifier)

The assistant's expressive "sparkle" avatar; spins while streaming.

Link copied to clipboard
@Composable
fun AssistantMessage(message: Message, modifier: Modifier = Modifier, prompt: String? = null, onRegenerate: () -> Unit? = null, onToolApproval: (toolCallId: String, approved: Boolean) -> Unit? = null, onSelectVersion: (index: Int) -> Unit? = null, onToolDecision: (toolCallId: String, decision: ToolDecision) -> Unit? = null)

A whole assistant message in one composable (for non-virtualized lists); Conversation renders replies block by block instead.

Link copied to clipboard
@Composable
fun AttachmentStrip(attachments: List<FilePart>, onRemove: (FilePart) -> Unit, modifier: Modifier = Modifier, thumbSize: Dp = 64.dp)

Pending attachments above the composer (AI Elements <PromptInputAttachments>), each removable.

Link copied to clipboard
@Composable
fun BranchSelector(index: Int, count: Int, onSelect: (Int) -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true)

Switch between versions of a reply (AI Elements <Branch>): ‹ 2 / 3 ›. Hidden when there is only one version.

Link copied to clipboard
@Composable
fun ChainOfThought(steps: List<WorkflowStep>, modifier: Modifier = Modifier, title: String = stringResource(R.string.ai_chain_of_thought))

A multi-step reasoning trace (AI Elements <ChainOfThought>): a vertical timeline of steps with status, descriptions and result badges.

Link copied to clipboard
@Composable
fun Chat(controller: ChatController, modifier: Modifier = Modifier, placeholder: String? = null, voiceMode: Boolean = true, toolbar: @Composable RowScope.() -> Unit = {}, replay: RunReplay? = null)

A complete chat screen body: the Conversation (streaming Markdown, tools and approvals, sub-agents, plans, branches, checkpoints) above a PromptInput with stop and queueing, all wired to controller. With voiceMode (and speech recognition on the device), the send button of an empty input starts a VoiceMode conversation. Wrap it in AiElementsTheme; add your own buttons to the input with toolbar.

Link copied to clipboard
@Composable
fun ChatEmptyState(title: String, subtitle: String? = null, suggestions: List<Suggestion>, onSelect: (Suggestion) -> Unit, modifier: Modifier = Modifier, showHero: Boolean = true)

Empty-conversation hero: a slowly turning expressive shape, a greeting and suggestions. Pass showHero = false on short windows (phone landscape).

Link copied to clipboard
@Composable
fun Checkpoint(onRestore: () -> Unit, modifier: Modifier = Modifier, label: String = stringResource(R.string.ai_checkpoint))

A restore point between turns (AI Elements <Checkpoint>): a divider with a "Restore" action that rewinds the conversation to here, after confirming.

Link copied to clipboard
@Composable
fun CitationSheet(sources: List<SourcePart>, onDismiss: () -> Unit)

Bottom sheet listing cited sources, each opening in the browser.

Link copied to clipboard
@Composable
fun Confirmation(title: String, description: String, onApprove: () -> Unit?, onDeny: () -> Unit?, modifier: Modifier = Modifier, input: String? = null, onDecide: (ToolDecision) -> Unit? = null, withReason: Boolean = true)

Human-in-the-loop approval (AI Elements <Confirmation>): what the agent wants to do, with approve / deny actions. Null callbacks render read-only. With onDecide the user can also deny with a reason or edit the call's JSON input before approving (AG-UI approve-with-edits, AI SDK reason); pass a null input or withReason = false where the backend cannot carry them.

Link copied to clipboard
@Composable
fun ContextUsage(usage: Usage, modifier: Modifier = Modifier, contextWindow: Int? = null)

Token / context-window usage (AI Elements <Context>): a compact chip that opens a breakdown. With contextWindow it shows how full the window is.

Link copied to clipboard
@Composable
fun Conversation(state: ChatState, modifier: Modifier = Modifier, listState: LazyListState = rememberLazyListState(), maxContentWidth: Dp = 840.dp, contentPadding: PaddingValues = PaddingValues(16.dp), onRegenerate: () -> Unit = {}, onRetry: () -> Unit = onRegenerate, onDismissError: () -> Unit = {}, onToolApproval: (toolCallId: String, approved: Boolean) -> Unit? = null, onSelectVersion: (messageId: String, index: Int) -> Unit? = null, onRestoreCheckpoint: (messageId: String) -> Unit? = null, onToolDecision: (toolCallId: String, decision: ToolDecision) -> Unit? = null, onInputResponse: (requestId: String, response: InputResponse) -> Unit? = null)

The scrolling message list (AI Elements <Conversation>).

Link copied to clipboard
@Composable
fun DataPartView(part: DataPart, modifier: Modifier = Modifier, renderers: Map<String, @Composable (DataPart) -> Unit> = emptyMap())

Renders an agent-streamed data-* part. Built-in shapes:

Link copied to clipboard
@Composable
fun DocumentAttachment(file: FilePart, modifier: Modifier = Modifier)

A document in a message (an artifact the agent made or a file it read): its type and name, with the first page and page count for a PDF. Tapping a PDF opens PdfViewerDialog; other formats (Word, Excel, PowerPoint, …) open in an app that can show them.

Link copied to clipboard
@Composable
fun FileAttachment(file: FilePart, modifier: Modifier = Modifier, imageHeight: Dp = 220.dp)

A file part inside a message: images, videos and audio inline; documents (PDF preview, others open in an app).

Link copied to clipboard
@Composable
fun FileImage(file: FilePart, modifier: Modifier = Modifier, contentScale: ContentScale = ContentScale.Crop, fitToImage: Boolean = false, maxDecodePx: Int = 1600)

An image from a FilePart (AI Elements <Image>): decodes data: URLs and fetches http(s) URLs off the main thread, downsampled to maxDecodePx.

Link copied to clipboard
@Composable
fun ImageViewer(file: FilePart, onDismiss: () -> Unit)

An image full screen, on black: pinch to zoom, drag to pan, double-tap to zoom in or back, and rotate a quarter turn at a time (for images whose orientation is wrong at the source).

Link copied to clipboard
@Composable
fun InlineCitation(sources: List<SourcePart>, modifier: Modifier = Modifier)

An inline citation badge (AI Elements <InlineCitation>): the first source's host plus "+N" for the rest; tapping opens the cited sources.

Link copied to clipboard
@Composable
fun InputRequestCard(request: InputRequest, onRespond: (InputResponse) -> Unit, modifier: Modifier = Modifier)

The agent (or a tool's server) asks the user for something: a form built from the request's JSON Schema, a link to complete out of band, or a plain confirmation. Protocol-neutral — the same card answers an AG-UI interrupt and an MCP elicitation.

Link copied to clipboard
suspend fun localFile(context: Context, file: FilePart, loader: FileLoader): File?

file as a file in the app's cache: data: URLs decoded, http(s) and content: URLs loaded (through loader, the app's LocalFileLoader); file: URLs as they are.

Link copied to clipboard
@Composable
fun MessageItem(message: Message, modifier: Modifier = Modifier, prompt: String? = null, onRegenerate: () -> Unit? = null, onToolApproval: (toolCallId: String, approved: Boolean) -> Unit? = null, onSelectVersion: (index: Int) -> Unit? = null, onToolDecision: (toolCallId: String, decision: ToolDecision) -> Unit? = null)

Renders any Message: a bubble for the user, a full-width part list for the assistant.

Link copied to clipboard
@Composable
fun ModelSelector(models: List<ModelOption>, selectedId: String?, onSelect: (ModelOption) -> Unit, modifier: Modifier = Modifier)

Pick a model (AI Elements <ModelSelector>): a chip showing the current model opens a searchable sheet grouped by provider, with capability tags and context window per model.

Link copied to clipboard
suspend fun openExternally(context: Context, file: FilePart, loader: FileLoader): Boolean

Opens file in an app that can view it (the user's PDF reader, WPS / Office for documents, …), the mobile way to show formats without an in-app renderer. Returns false when no app can.

Link copied to clipboard
@Composable
fun OpenInChat(prompt: String, modifier: Modifier = Modifier, targets: List<OpenInTarget> = DefaultOpenInTargets)

Continue a prompt in another assistant (AI Elements <OpenIn>), or hand it to any app through the Android share sheet.

Link copied to clipboard
@Composable
fun PdfViewerDialog(file: FilePart, onDismiss: () -> Unit)

A PDF full screen: every page, pinch to zoom, and "Open with" for a full reader.

Link copied to clipboard
@Composable
fun Plan(title: String, description: String, steps: List<WorkflowStep>, modifier: Modifier = Modifier, streaming: Boolean = false)

An agent's plan (AI Elements <Plan>): title, summary and the planned steps; shimmers while it is still being written.

Link copied to clipboard
suspend fun playableUri(context: Context, file: FilePart): Uri

A URI the platform media stack can open for file: http(s), content: and file: URLs as they are; a data: URL is written to the app's cache once (media players cannot read it).

Link copied to clipboard
@Composable
fun PromptInput(value: String, onValueChange: (String) -> Unit, onSubmit: () -> Unit, onStop: () -> Unit, busy: Boolean, modifier: Modifier = Modifier, placeholder: String = stringResource(R.string.ai_prompt_placeholder), attachments: List<FilePart> = emptyList(), onAddAttachment: () -> Unit? = null, onRemoveAttachment: (FilePart) -> Unit = {}, allowQueue: Boolean = false, onVoiceMode: () -> Unit? = null, toolbar: @Composable RowScope.() -> Unit = {})

The composer (AI Elements <PromptInput>): a roomy rounded field with a toolbar row. The submit button morphs into a spinning cookie-shaped stop button while a reply is streaming.

Link copied to clipboard
@Composable
fun Question(prompt: String, options: List<QuestionOption>, onSubmit: (QuestionAnswer) -> Unit, modifier: Modifier = Modifier, description: String? = null, multiple: Boolean = false, allowOther: Boolean = true, answered: QuestionAnswer? = null)

The agent asks the user something (AI Elements <Question>): one or several of options, and/or a free-text answer when allowOther. Once answered, the card shows the answer read-only.

Link copied to clipboard
@Composable
fun Queue(items: List<QueuedMessage>, paused: Boolean, onRemove: (QueuedMessage) -> Unit, onSendNow: (QueuedMessage) -> Unit, modifier: Modifier = Modifier)

Prompts waiting for the agent (AI Elements <Queue>). Each can be removed; when the queue is paused (after stop or an error) each can be sent now.

Link copied to clipboard
@Composable
fun Reasoning(part: ReasoningPart, modifier: Modifier = Modifier)

Collapsible "thinking" block. Opens automatically while the model reasons and collapses to "Thought for Ns" when it's done — like AI Elements' <Reasoning>.

Link copied to clipboard
Link copied to clipboard
@Composable
fun rememberChat(backend: (ToolApprover) -> ChatBackend): ChatController

A ChatController kept for as long as this composition: for prototypes and previews. In an app, create the controller in a ViewModel (with viewModelScope) so the conversation survives configuration changes, and pass it to Chat.

Link copied to clipboard
@Composable
fun rememberStickToBottomState(listState: LazyListState): StickToBottomState

Remembers a StickToBottomState for listState; install its connection with Modifier.nestedScroll.

Link copied to clipboard
@Composable
fun SchemaForm(schema: JsonObject, onSubmit: (JsonObject) -> Unit, onDecline: () -> Unit, modifier: Modifier = Modifier)

A form for a flat JSON Schema object (MCP elicitation's restricted schema, AG-UI responseSchema): text (with format email / uri / date), numbers with minimum / maximum, booleans, single choices (enum, oneOf / anyOf of {const, title, description}) and multiple choices (arrays of those, minItems / maxItems). A choice whose anyOf also allows a plain {"type": "string"} offers the user's own answer ("Other"), as Pydantic AI Harness AskUser questions do. Choices with descriptions or an own answer show as a list, others as chips. Defaults pre-fill; required fields must be set before submitting.

Link copied to clipboard
@Composable
fun ShimmerText(text: String, modifier: Modifier = Modifier, style: TextStyle = LocalTextStyle.current, active: Boolean = true)

Text with a sweeping highlight, used for in-progress labels ("Thinking…").

Link copied to clipboard
@Composable
fun Sources(sources: List<SourcePart>, modifier: Modifier = Modifier)

"Used N sources" with a row of link chips (AI Elements <Sources>).

Link copied to clipboard
@Composable
fun StepView(step: AgentStep, modifier: Modifier = Modifier)

One step as the agent saw it, by what the call did: its screenshot (in a browser frame when it acted on a web page), a terminal for a command, a diff for an edit, the file or matches it read, the page text it fetched, else its output.

Link copied to clipboard
@Composable
fun Subagent(part: ToolPart, modifier: Modifier = Modifier, onToolApproval: (toolCallId: String, approved: Boolean) -> Unit? = null)

A delegated agent run (the sub-agent pattern): who was asked, what they were asked to do, and their live work — reasoning, tool calls (approvable in place) and answer — nested under the delegating tool call.

Link copied to clipboard
@Composable
fun Suggestions(suggestions: List<Suggestion>, onSelect: (Suggestion) -> Unit, modifier: Modifier = Modifier)

Prompt suggestion chips (AI Elements <Suggestions>), wrapping across lines.

Link copied to clipboard
@Composable
fun Task(title: String, items: List<WorkflowStep>, modifier: Modifier = Modifier)

A unit of agent work (AI Elements <Task>): a collapsible title with the items done so far; file names render as monospace chips.

Link copied to clipboard
@Composable
fun ToolCall(part: ToolPart, modifier: Modifier = Modifier, onApproval: (Boolean) -> Unit? = null, onDecision: (ToolDecision) -> Unit? = LocalToolDecision.current?.let { cb -> { decision -> cb(part.id, decision) } })

A tool invocation card (AI Elements <Tool>): tool name, a status pill, and an expandable section with the JSON input and the output / error. While the call awaits approval it shows a Confirmation with approve / deny actions.

Link copied to clipboard
@Composable
fun ToolPartView(part: ToolPart, modifier: Modifier = Modifier, onToolApproval: (toolCallId: String, approved: Boolean) -> Unit? = null, onToolDecision: (toolCallId: String, decision: ToolDecision) -> Unit? = LocalToolDecision.current)

A tool call rendered by the element that fits it: Subagent for delegations, ToolCall otherwise.

Link copied to clipboard
@Composable
fun UserMessage(message: Message, modifier: Modifier = Modifier)

A user message: attachments above a right-aligned bubble.

Link copied to clipboard
@Composable
fun VideoAttachment(file: FilePart, modifier: Modifier = Modifier)

A video in a message: its first frame, duration and a play button; tapping plays it full screen (platform VideoView, with the system media controls).

Link copied to clipboard
@Composable
fun VideoPlayerDialog(file: FilePart, onDismiss: () -> Unit)

Plays file full screen with the platform player and media controls.