Chat bubbles: preserve single newlines in agent messages too — the hard-break rule from user bubbles now applies to agent replies as well, so status lines and model-wrapped text render one line per field instead of collapsing into a wall of text; unit tests for preserveNewlinesAsHardBreaks

This commit is contained in:
ARIA committed 2026-08-21 10:26:35 +02:00
1 parent 1bcadcf950
commit ec53769325
3 files changed
+34 -8

No files matched your search

@@ -2137,8 +2137,11 @@ private fun MessageBubble(
// M8: render the agent's reply as markdown (bold / italic /
// underscore, tables, highlighted code blocks). Leading
// newlines are stripped so the text hugs the top of the
// bubble; the ▉ cursor is kept while streaming.
val displayText = msg.text.prepareForMarkdown() + if (msg.streaming) " ▉" else ""
// bubble; single newlines become hard breaks (models write
// status lines and wrapped text expecting a break per line,
// same as user input); the ▉ cursor is kept while streaming.
val displayText = msg.text.prepareForMarkdown().preserveNewlinesAsHardBreaks() +
if (msg.streaming) " ▉" else ""
MarkdownText(
text = displayText,
color = textColor,
@@ -14,12 +14,13 @@ fun String.prepareForMarkdown(): String {
}
/**
* Converts the single newlines a user typed into markdown hard breaks (two
* trailing spaces) so they render as line breaks instead of being collapsed
* into spaces by the parser (GFM treats a lone newline inside a paragraph as a
* space). Lines inside fenced code blocks (``` / ~~~) are left untouched so the
* code content is not altered; blank lines are kept as-is since they already
* produce paragraph breaks.
* Converts single newlines into markdown hard breaks (two trailing spaces) so
* they render as line breaks instead of being collapsed into spaces by the
* parser (GFM treats a lone newline inside a paragraph as a space). Applied to
* both user input (lazy line breaks) and agent replies (models write status
* lines and wrapped text expecting a break per line). Lines inside fenced code
* blocks (``` / ~~~) are left untouched so the code content is not altered;
* blank lines are kept as-is since they already produce paragraph breaks.
*/
fun String.preserveNewlinesAsHardBreaks(): String {
val lines = split("\n")