Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 2 additions & 10 deletions core/http/static/chat.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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,
Expand Down
94 changes: 94 additions & 0 deletions core/http/static/general.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
18 changes: 4 additions & 14 deletions core/http/views/chat.html
Original file line number Diff line number Diff line change
Expand Up @@ -324,17 +324,11 @@
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
Expand Down Expand Up @@ -366,11 +360,7 @@
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,
Expand Down Expand Up @@ -1332,7 +1322,7 @@ <h1 class="text-lg font-semibold text-[var(--color-text-primary)]">
<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>
Expand Down