diff --git a/nanochat/ui.html b/nanochat/ui.html
index b2b4605..e742a31 100644
--- a/nanochat/ui.html
+++ b/nanochat/ui.html
@@ -5,6 +5,8 @@
NanoChat
+
+
@@ -282,6 +355,39 @@
let currentTemperature = 0.8;
let currentTopK = 50;
+ // Configure marked.js for better rendering
+ if (typeof marked !== 'undefined') {
+ marked.setOptions({
+ breaks: true, // Convert line breaks to
+ gfm: true, // GitHub Flavored Markdown
+ sanitize: false, // We'll use DOMPurify instead
+ smartypants: false // Disable smart quotes for simplicity
+ });
+ }
+
+ // Markdown rendering function
+ function renderMarkdown(content) {
+ try {
+ if (typeof marked !== 'undefined' && typeof DOMPurify !== 'undefined') {
+ const rawHtml = marked.parse(content);
+ return DOMPurify.sanitize(rawHtml);
+ } else {
+ console.warn('Markdown libraries not loaded, falling back to plain text');
+ return escapeHtml(content);
+ }
+ } catch (error) {
+ console.error('Markdown rendering failed:', error);
+ return escapeHtml(content);
+ }
+ }
+
+ // HTML escape fallback function
+ function escapeHtml(text) {
+ const div = document.createElement('div');
+ div.textContent = text;
+ return div.innerHTML;
+ }
+
chatInput.addEventListener('input', function() {
this.style.height = 'auto';
this.style.height = Math.min(this.scrollHeight, 200) + 'px';
@@ -321,7 +427,13 @@
const contentDiv = document.createElement('div');
contentDiv.className = 'message-content';
- contentDiv.textContent = content;
+
+ // Render markdown for assistant messages, plain text for others
+ if (role === 'assistant' && content) {
+ contentDiv.innerHTML = renderMarkdown(content);
+ } else {
+ contentDiv.textContent = content;
+ }
// Add click handler for user messages to enable editing
if (role === 'user' && messageIndex !== null) {
@@ -395,7 +507,7 @@
messages: messages,
temperature: currentTemperature,
top_k: currentTopK,
- max_tokens: 512
+ max_tokens: 64
}),
});
@@ -421,7 +533,8 @@
const data = JSON.parse(line.slice(6));
if (data.token) {
fullResponse += data.token;
- assistantContent.textContent = fullResponse;
+ // Render markdown in real-time as tokens arrive
+ assistantContent.innerHTML = renderMarkdown(fullResponse);
chatContainer.scrollTop = chatContainer.scrollHeight;
}
} catch (e) {