Streaming Messages

StreamingText renders a reply as the agent writes it: Markdown, code with syntax highlighting, tables, images and charts, revealed word by word, as ChatGPT does. AIConversation shows every reply with it, and you can use it on its own in a composable of yours:

StreamingText(
    text = reply.text,
    animate = reply.isGenerating,
)

Type the reply out

While animate is true, the view reveals the text that's new since the last update, word by word and whitespace by whitespace. When the new text continues the old one, it goes on from where it is. When it doesn't, such as when the agent rewrites its answer, it starts again from the beginning. Once animate is false, the view shows the full text at once. That's why a stored reply doesn't type itself out again when the user scrolls back to it. When animate turns false in the middle of the reveal, as it does with the final update, the view finishes revealing the rest instead of jumping to the end.

chunkDelayMs sets the speed of the reveal, in milliseconds per chunk. The default is 30 ms.

With Stream Chat, a reply is generating while its message's generating field is true. What your backend sends covers how to set it.

By default, the view renders the revealed text as Markdown. To render it your own way, pass content, which receives the text revealed so far:

StreamingText(text = reply.text, animate = reply.isGenerating) { displayedText ->
    Text(text = displayedText, style = MaterialTheme.typography.bodyLarge)
}

Code and charts

Code blocks render with syntax highlighting, under a header with the code's language and a button that copies the code. A code block whose language is chartjs, and whose content is a Chart.js configuration, renders as an interactive chart instead, once the block is complete. Chart.js reads line, bar, pie, doughnut, radar, polarArea, bubble and scatter charts, which is handy to describe in your agent's instructions:

```chartjs
{
  "type": "bar",
  "data": {
    "labels": ["Jan", "Feb", "Mar"],
    "datasets": [{ "label": "Signups", "data": [120, 180, 240] }]
  },
  "options": { "plugins": { "title": { "display": true, "text": "Signups per month" } } }
}
```

The chart draws in a WebView with the Chart.js library bundled in the SDK, so it needs no network, and the chart's page can't connect anywhere. A configuration Chart.js can't read shows the error in place of the chart.

Show what the agent is doing

Before the first word of a reply arrives, the agent may spend a while thinking or calling tools. AITypingIndicator shows what it's doing: a label of your choice, followed by three animated dots:

AITypingIndicator(
    label = { Text("Checking external sources") },
)

Pass indicator to replace the dots, for example with a CircularProgressIndicator(). The dots use the current LocalContentColor.

Show what the agent is doing and errors shows where the agent says what it's doing. While the agent only thinks, AIConversation shows "Thinking... 4s" by itself, as described in Show the agent thinking.

Appearance

StreamingText renders Markdown, code blocks included, with the colors and text styles of the current MaterialTheme. To give every AITypingIndicator the same label or dots, override the AITypingIndicatorLabel and AITypingIndicatorIndicator slots of ChatAiComponentFactory, as in Customize the composer.