diff --git a/gui/chatblockmodel.cpp b/gui/chatblockmodel.cpp
index f71dd4a..2908651 100644
--- a/gui/chatblockmodel.cpp
+++ b/gui/chatblockmodel.cpp
@@ -61,6 +61,25 @@ QVariant ChatBlockModel::data(const QModelIndex &index, int role) const
block.cachedContent = block.content;
}
return block.cachedSubBlocks;
+ case FormattedContentRole: {
+ // For call blocks: always pretty-print JSON
+ // For tool blocks: detect JSON/diff, format accordingly
+ // For others: just escape HTML
+ QString content = block.content;
+ if (content.isEmpty()) return QString();
+ if (block.type == ChatBlock::Call) {
+ return prettyJson(content);
+ }
+ QString trimmed = content.trimmed();
+ if (trimmed.startsWith('{') || trimmed.startsWith('[')) {
+ return prettyJson(content);
+ }
+ if (trimmed.startsWith(QLatin1String("---")) || trimmed.startsWith(QLatin1String("diff "))) {
+ return highlightedHtml(content, QStringLiteral("Diff"));
+ }
+ // Plain text: escape and add line breaks
+ return content.toHtmlEscaped().replace('\n', QLatin1String("
"));
+ }
}
return {};
}
@@ -72,6 +91,7 @@ QHash ChatBlockModel::roleNames() const
{NameRole, "blockName"},
{ContentRole, "blockContent"},
{SubBlocksRole, "subBlocks"},
+ {FormattedContentRole, "formattedContent"},
};
}
diff --git a/gui/chatblockmodel.h b/gui/chatblockmodel.h
index 5bbb823..f5d660a 100644
--- a/gui/chatblockmodel.h
+++ b/gui/chatblockmodel.h
@@ -48,6 +48,7 @@ public:
NameRole,
ContentRole,
SubBlocksRole, // QVariantList of sub-block maps
+ FormattedContentRole, // pre-formatted HTML for call/tool expanded view
};
explicit ChatBlockModel(QObject *parent = nullptr);
diff --git a/gui/main.qml b/gui/main.qml
index 4d6e426..e74c8cc 100644
--- a/gui/main.qml
+++ b/gui/main.qml
@@ -624,7 +624,7 @@ ApplicationWindow {
Text {
id: callText
Layout.fillWidth: true
- text: visible ? chatModel.prettyJson(String(block.blockContent || "")) : ""
+ text: block.formattedContent || ""
textFormat: Text.RichText
wrapMode: Text.Wrap
font.family: "monospace"
@@ -653,17 +653,7 @@ ApplicationWindow {
Text {
id: toolText
Layout.fillWidth: true
- text: {
- if (!visible) return ""
- let content = String(block.blockContent || "")
- if (!content) return ""
- let trimmed = content.trim()
- if (trimmed.charAt(0) === '{' || trimmed.charAt(0) === '[')
- return chatModel.prettyJson(content)
- if (trimmed.indexOf("---") === 0 || trimmed.indexOf("diff ") === 0)
- return chatModel.highlightedHtml(content, "diff")
- return content.replace(/&/g, '&').replace(//g, '>').replace(/\n/g, '
')
- }
+ text: block.formattedContent || ""
textFormat: Text.RichText
wrapMode: Text.Wrap
font.family: "monospace"