git.iko.soy/opencode-android
on 3e723a1 help sign in
40 lines 1.5 kB history raw
1package soy.iko.opencode.ui.chat
3import soy.iko.opencode.data.model.AssistantMessage
4import soy.iko.opencode.data.model.MessageWithParts
5import soy.iko.opencode.data.model.ReasoningPart
6import soy.iko.opencode.data.model.TextPart
7import soy.iko.opencode.data.model.UserMessage
9/**
10 * Render a conversation as Markdown for sharing/exporting. Each message becomes a
11 * role-prefixed section containing its text parts; reasoning and tool parts are
12 * omitted to keep the exported transcript readable. Pure (no Android deps) so it can
13 * be unit-tested directly.
14 */
15fun buildConversationMarkdown(messages: List<MessageWithParts>, title: String?): String {
16 val sb = StringBuilder()
17 if (!title.isNullOrBlank()) {
18 sb.append("# ").append(title.trim()).append("\n\n")
19 }
20 for (message in messages) {
21 val heading = when (message.info) {
22 is UserMessage -> "## You"
23 is AssistantMessage -> "## opencode"
24 else -> null
25 } ?: continue
26 val body = message.parts
27 .mapNotNull { part ->
28 when (part) {
29 is TextPart -> part.text.takeIf { it.isNotBlank() }
30 is ReasoningPart -> part.text.takeIf { it.isNotBlank() }?.let { "_${it}_" }
31 else -> null
32 }
33 }
34 .joinToString("\n\n")
35 .trim()
36 if (body.isEmpty()) continue
37 sb.append(heading).append("\n\n").append(body).append("\n\n")
38 }
39 return sb.toString().trimEnd()