Compare commits

...

2 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
6a1e44c8ff Fix markdown parsing to handle multi-line constructs correctly
Co-authored-by: mudler <2420543+mudler@users.noreply.github.com>
2026-02-03 11:42:51 +00:00
copilot-swe-agent[bot]
bda40b266c Initial plan 2026-02-03 11:40:19 +00:00
3 changed files with 100 additions and 24 deletions

View File

@@ -2456,11 +2456,7 @@ document.addEventListener("alpine:init", () => {
const N = chat.history.length - 1;
if (role === "thinking" || role === "reasoning") {
let c = "";
const lines = content.split("\n");
lines.forEach((line) => {
c += DOMPurify.sanitize(marked.parse(line));
});
const c = DOMPurify.sanitize(marked.parse(content));
chat.history.push({ role, content, html: c, image, audio });
}
else if (chat.history.length && chat.history[N].role === role) {
@@ -2475,11 +2471,7 @@ document.addEventListener("alpine:init", () => {
chat.history[N].audio = [...(chat.history[N].audio || []), ...audio];
}
} else {
let c = "";
const lines = content.split("\n");
lines.forEach((line) => {
c += DOMPurify.sanitize(marked.parse(line));
});
const c = DOMPurify.sanitize(marked.parse(content));
chat.history.push({
role,
content,

View File

@@ -104,3 +104,97 @@ li:last-child {
scrollbar-width: thin;
scrollbar-color: var(--color-bg-secondary) var(--color-bg-primary);
}
/* Chat message markdown content styles */
#messages pre {
background-color: var(--color-bg-primary);
border: 1px solid var(--color-border-subtle, rgba(255,255,255,0.1));
border-radius: 0.5rem;
padding: 1rem;
overflow-x: auto;
max-width: 100%;
margin: 0.5rem 0;
white-space: pre;
}
#messages pre code {
background: transparent;
padding: 0;
white-space: pre;
word-wrap: normal;
overflow-wrap: normal;
}
#messages code:not(pre code) {
background-color: var(--color-bg-primary);
padding: 0.2em 0.4em;
border-radius: 3px;
font-size: 0.875em;
}
#messages table {
width: 100%;
border-collapse: collapse;
margin: 0.5rem 0;
display: block;
overflow-x: auto;
}
#messages th,
#messages td {
border: 1px solid var(--color-border-subtle, rgba(255,255,255,0.1));
padding: 0.5rem;
text-align: left;
}
#messages th {
background-color: var(--color-bg-secondary);
}
#messages blockquote {
border-left: 4px solid var(--color-primary);
padding-left: 1rem;
margin: 0.5rem 0;
color: var(--color-text-secondary);
}
#messages h1, #messages h2, #messages h3, #messages h4, #messages h5, #messages h6 {
margin-top: 1rem;
margin-bottom: 0.5rem;
font-weight: 600;
line-height: 1.25;
}
#messages h1 { font-size: 1.5rem; }
#messages h2 { font-size: 1.25rem; }
#messages h3 { font-size: 1.125rem; }
#messages h4 { font-size: 1rem; }
#messages p {
margin: 0.5rem 0;
}
#messages ul, #messages ol {
margin: 0.5rem 0;
padding-left: 1.5rem;
}
#messages hr {
border: none;
border-top: 1px solid var(--color-border-subtle, rgba(255,255,255,0.1));
margin: 1rem 0;
}
/* Mobile responsiveness for chat */
@media (max-width: 768px) {
#messages {
max-width: 100%;
padding-left: 0.5rem;
padding-right: 0.5rem;
}
#messages pre {
max-width: calc(100vw - 3rem);
font-size: 0.8rem;
}
}

View File

@@ -324,17 +324,11 @@ SOFTWARE.
c = DOMPurify.sanitize('<pre><code class="language-json">' + formatted + '</code></pre>');
} catch (e) {
// If not JSON, treat as markdown
const lines = content.split("\n");
lines.forEach((line) => {
c += DOMPurify.sanitize(marked.parse(line));
});
c = DOMPurify.sanitize(marked.parse(content));
}
} else {
// For thinking and reasoning, format as markdown
const lines = content.split("\n");
lines.forEach((line) => {
c += DOMPurify.sanitize(marked.parse(line));
});
c = DOMPurify.sanitize(marked.parse(content));
}
// Set expanded state: thinking and reasoning are expanded by default in non-MCP mode, collapsed in MCP mode
// tool_call and tool_result are always collapsed by default
@@ -366,11 +360,7 @@ SOFTWARE.
chat.history[N].model = messageModel;
}
} else {
let c = "";
const lines = content.split("\n");
lines.forEach((line) => {
c += DOMPurify.sanitize(marked.parse(line));
});
const c = DOMPurify.sanitize(marked.parse(content));
chat.history.push({
role,
content,
@@ -1332,7 +1322,7 @@ SOFTWARE.
<div class="flex flex-col flex-1">
<span class="text-xs font-semibold text-[var(--color-text-secondary)] mb-1" x-text="message.model || $store.chat.activeChat()?.model || '{{if .Model}}{{.Model}}{{else}}Assistant{{end}}'"></span>
<div class="flex-1 text-[var(--color-text-primary)] flex items-center space-x-2 min-w-0">
<div class="p-3 rounded-lg bg-[var(--color-bg-secondary)] border border-[var(--color-accent-border)]/20 shadow-lg max-w-full overflow-x-auto overflow-wrap-anywhere" x-html="message.html"></div>
<div class="p-3 rounded-lg bg-[var(--color-bg-secondary)] border border-[var(--color-accent-border)]/20 shadow-lg max-w-full overflow-x-auto break-words" style="overflow-wrap: anywhere; word-break: break-word;" x-html="message.html"></div>
<button @click="copyToClipboard(message.html)" title="Copy to clipboard" class="text-[var(--color-text-secondary)] hover:text-[var(--color-primary)] transition-colors p-1 flex-shrink-0">
<i class="fa-solid fa-copy"></i>
</button>