mirror of
https://github.com/mudler/LocalAI.git
synced 2026-02-06 20:54:37 -05:00
Compare commits
2 Commits
feat/nemo
...
copilot/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a1e44c8ff | ||
|
|
bda40b266c |
@@ -2456,11 +2456,7 @@ document.addEventListener("alpine:init", () => {
|
|||||||
|
|
||||||
const N = chat.history.length - 1;
|
const N = chat.history.length - 1;
|
||||||
if (role === "thinking" || role === "reasoning") {
|
if (role === "thinking" || role === "reasoning") {
|
||||||
let c = "";
|
const c = DOMPurify.sanitize(marked.parse(content));
|
||||||
const lines = content.split("\n");
|
|
||||||
lines.forEach((line) => {
|
|
||||||
c += DOMPurify.sanitize(marked.parse(line));
|
|
||||||
});
|
|
||||||
chat.history.push({ role, content, html: c, image, audio });
|
chat.history.push({ role, content, html: c, image, audio });
|
||||||
}
|
}
|
||||||
else if (chat.history.length && chat.history[N].role === role) {
|
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];
|
chat.history[N].audio = [...(chat.history[N].audio || []), ...audio];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let c = "";
|
const c = DOMPurify.sanitize(marked.parse(content));
|
||||||
const lines = content.split("\n");
|
|
||||||
lines.forEach((line) => {
|
|
||||||
c += DOMPurify.sanitize(marked.parse(line));
|
|
||||||
});
|
|
||||||
chat.history.push({
|
chat.history.push({
|
||||||
role,
|
role,
|
||||||
content,
|
content,
|
||||||
|
|||||||
@@ -104,3 +104,97 @@ li:last-child {
|
|||||||
scrollbar-width: thin;
|
scrollbar-width: thin;
|
||||||
scrollbar-color: var(--color-bg-secondary) var(--color-bg-primary);
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -324,17 +324,11 @@ SOFTWARE.
|
|||||||
c = DOMPurify.sanitize('<pre><code class="language-json">' + formatted + '</code></pre>');
|
c = DOMPurify.sanitize('<pre><code class="language-json">' + formatted + '</code></pre>');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// If not JSON, treat as markdown
|
// If not JSON, treat as markdown
|
||||||
const lines = content.split("\n");
|
c = DOMPurify.sanitize(marked.parse(content));
|
||||||
lines.forEach((line) => {
|
|
||||||
c += DOMPurify.sanitize(marked.parse(line));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// For thinking and reasoning, format as markdown
|
// For thinking and reasoning, format as markdown
|
||||||
const lines = content.split("\n");
|
c = DOMPurify.sanitize(marked.parse(content));
|
||||||
lines.forEach((line) => {
|
|
||||||
c += DOMPurify.sanitize(marked.parse(line));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
// Set expanded state: thinking and reasoning are expanded by default in non-MCP mode, collapsed in MCP mode
|
// 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
|
// tool_call and tool_result are always collapsed by default
|
||||||
@@ -366,11 +360,7 @@ SOFTWARE.
|
|||||||
chat.history[N].model = messageModel;
|
chat.history[N].model = messageModel;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let c = "";
|
const c = DOMPurify.sanitize(marked.parse(content));
|
||||||
const lines = content.split("\n");
|
|
||||||
lines.forEach((line) => {
|
|
||||||
c += DOMPurify.sanitize(marked.parse(line));
|
|
||||||
});
|
|
||||||
chat.history.push({
|
chat.history.push({
|
||||||
role,
|
role,
|
||||||
content,
|
content,
|
||||||
@@ -1332,7 +1322,7 @@ SOFTWARE.
|
|||||||
<div class="flex flex-col flex-1">
|
<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>
|
<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="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">
|
<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>
|
<i class="fa-solid fa-copy"></i>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user