对话组件¶
消息列表、单条消息、输入框及对话周边控件。
对话列表¶
展示消息列表:流式生成时跟随底部,向上滚动后暂停跟随。

| API | Conversation(state, onRegenerate, onToolApproval, …) |
| AI Elements | Conversation |
| 依赖模块 | ai-elements-ui |
| API 文档 | Conversation |
把 controller 放在 ViewModel 中。Conversation 只渲染消息列表;输入框由 PromptInput 提供,也可以直接用 Chat。审批和表单回答都需要接回 controller。
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import dev.ai.elements.core.chat.ChatController
import dev.ai.elements.ui.chat.Conversation
@Composable
fun ConversationExample(controller: ChatController) {
val state by controller.state.collectAsStateWithLifecycle()
Conversation(state, onToolDecision = controller::respondToApproval, onInputResponse = controller::respondToInput)
}
单条消息¶
渲染用户或助手消息,以及复制、朗读、重新生成等操作。

| API | MessageItem(message, onRegenerate) |
| AI Elements | Message |
| 依赖模块 | ai-elements-ui |
| API 文档 | MessageItem |
适合单条消息或非懒加载布局。较长的历史记录请使用 Conversation,它会按回复内容块进行懒加载。
import androidx.compose.runtime.Composable
import dev.ai.elements.core.chat.ChatController
import dev.ai.elements.core.model.Message
import dev.ai.elements.ui.chat.MessageItem
@Composable
fun MessagesExample(message: Message, controller: ChatController) {
MessageItem(message, onToolDecision = controller::respondToApproval)
}
消息输入框¶
支持文本、附件、语音输入、发送、停止与排队。

| API | PromptInput(value, onValueChange, onSubmit, onStop, busy) |
| AI Elements | PromptInput |
| 依赖模块 | ai-elements-ui |
| API 文档 | PromptInput |
文本和附件由调用方持有。只有 send 接受消息后才清空输入;controller 支持排队时可启用 allowQueue。
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import dev.ai.elements.core.chat.ChatController
import dev.ai.elements.ui.chat.PromptInput
@Composable
fun PromptInputExample(controller: ChatController) {
val state by controller.state.collectAsStateWithLifecycle()
var text by rememberSaveable { mutableStateOf("") }
PromptInput(text, { text = it }, { if (controller.send(text)) text = "" }, controller::stop, state.isBusy, allowQueue = true)
}
建议提问¶
让用户点击预设问题开始对话。

| API | Suggestions(suggestions, onSelect) |
| AI Elements | Suggestion |
| 依赖模块 | ai-elements-ui |
| API 文档 | Suggestions |
选择建议只会触发 onSelect,由应用决定填入输入框还是立即发送。
import androidx.compose.runtime.Composable
import dev.ai.elements.core.chat.ChatController
import dev.ai.elements.core.model.Suggestion
import dev.ai.elements.ui.chat.Suggestions
@Composable
fun SuggestionsExample(controller: ChatController) {
Suggestions(listOf(Suggestion("Explain this code")), onSelect = { controller.send(it.text) })
}
空对话欢迎页¶
用欢迎语和建议问题引导第一次对话。

| API | ChatEmptyState(title, subtitle, suggestions, onSelect) |
| 依赖模块 | ai-elements-ui |
| API 文档 | ChatEmptyState |
在消息历史为空时显示。窗口高度较小时可以设置 showHero=false。
import androidx.compose.runtime.Composable
import dev.ai.elements.core.chat.ChatController
import dev.ai.elements.core.model.Suggestion
import dev.ai.elements.ui.chat.ChatEmptyState
@Composable
fun EmptyStateExample(controller: ChatController) {
ChatEmptyState("How can I help?", suggestions = listOf(Suggestion("Make a plan")), onSelect = { controller.send(it.text) })
}
回复版本切换¶
在重新生成的多个回复版本之间切换。

| API | BranchSelector(index, count, onSelect) |
| AI Elements | Branch |
| 依赖模块 | ai-elements-ui |
| API 文档 | BranchSelector |
index 从 0 开始。调用方需要更新当前消息;这个控件本身不会修改历史。
import androidx.compose.runtime.Composable
import dev.ai.elements.core.chat.ChatController
import dev.ai.elements.core.model.Message
import dev.ai.elements.ui.chat.BranchSelector
@Composable
fun BranchExample(message: Message, controller: ChatController) {
BranchSelector(message.versionIndex, message.versions.size, onSelect = { controller.selectVersion(message.id, it) })
}
对话检查点¶
确认后恢复到之前的对话位置。

| API | Checkpoint(onRestore) |
| AI Elements | Checkpoint |
| 依赖模块 | ai-elements-ui |
| API 文档 | Checkpoint |
组件会先要求确认,再调用 onRestore。恢复 controller 的消息历史不会撤销工具已经修改的文件。
import androidx.compose.runtime.Composable
import dev.ai.elements.core.chat.ChatController
import dev.ai.elements.ui.chat.Checkpoint
@Composable
fun CheckpointExample(messageId: String, controller: ChatController) {
Checkpoint(onRestore = { controller.restoreCheckpoint(messageId) })
}
待发送队列¶
展示 Agent 忙碌期间等待发送的消息。

| API | Queue(items, paused, onRemove, onSendNow) |
| AI Elements | Queue |
| 依赖模块 | ai-elements-ui |
| API 文档 | Queue |
队列顺序由 controller 管理。停止或出错会暂停自动发送;将“立即发送”接到 sendQueuedNow。
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import dev.ai.elements.core.chat.ChatController
import dev.ai.elements.ui.chat.Queue
@Composable
fun QueueExample(controller: ChatController) {
val state by controller.state.collectAsStateWithLifecycle()
Queue(state.queue, paused = state.queuePaused, onRemove = { controller.removeQueued(it.id) }, onSendNow = { controller.sendQueuedNow(it.id) })
}
在其他聊天应用打开¶
把当前问题带到用户选择的聊天应用。

| API | OpenInChat(prompt) |
| AI Elements | OpenInChat |
| 依赖模块 | ai-elements-ui |
| API 文档 | OpenInChat |
问题会放入外部应用的 URL。让用户主动选择目标,不要传入隐藏上下文或凭据。
模型选择器¶
按提供方、能力与上下文窗口选择模型。

| API | ModelSelector(models, selectedId, onSelect) |
| AI Elements | ModelSelector |
| 依赖模块 | ai-elements-ui |
| API 文档 | ModelSelector |
选择器只更新界面状态。backend 工厂应在下一轮读取模型选择,并保留当前 controller 和消息历史。
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import dev.ai.elements.ui.chat.ModelOption
import dev.ai.elements.ui.chat.ModelSelector
@Composable
fun ModelSelectorExample() {
var selected by rememberSaveable { mutableStateOf("local") }
ModelSelector(listOf(ModelOption("local", "Local model", "My provider")), selected, onSelect = { selected = it.id })
}
Token 使用量¶
展示已用 token 与模型上下文窗口的关系。

| API | ContextUsage(usage, contextWindow) |
| AI Elements | Context |
| 依赖模块 | ai-elements-ui |
| API 文档 | ContextUsage |
传入实际统计和所选模型的窗口大小。该组件不负责分词或裁剪历史。
import androidx.compose.runtime.Composable
import dev.ai.elements.core.model.Usage
import dev.ai.elements.ui.chat.ContextUsage
@Composable
fun ContextExample() {
ContextUsage(Usage(inputTokens = 1200, outputTokens = 300), contextWindow = 32000)
}
加载指示器¶
等待首段输出时显示 Material 3 Expressive 加载动画。

| API | LoadingIndicator(), ContainedLoadingIndicator() |
| AI Elements | Loader |
| 依赖模块 | ai-elements-ui |
| API 文档 | LoadingIndicator |
这些组件来自 Material 3 依赖。调用时需要声明 ExperimentalMaterial3ExpressiveApi 的 opt-in。
@OptIn(androidx.compose.material3.ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun LoadingExample() {
androidx.compose.material3.LoadingIndicator()
}
流动高亮文字¶
用流动高亮提示任务仍在进行。

| API | ShimmerText(text, active) |
| AI Elements | Shimmer |
| 依赖模块 | ai-elements-ui |
| API 文档 | ShimmerText |
任务结束后将 active 设为 false。较长的内容更适合使用普通状态文字。