Console History vs Real-time: Code Analysis
Analysis of why history prompts are truncated and why rendering differs from real-time
Output
Console History vs Real-time: Code Analysis
🐛 ISSUE 1: Prompt Truncation
Root Cause: Hard-coded 100 character limit
The sanitizePrompt() function in console-history.ts:35 truncates all prompts:
return cleaned.slice(0, 100) + (cleaned.length > 100 ? '...' : '');
File: konui/src/console-history.ts:35
This truncation happens at 3 different call sites:
- Line 115: Kontext history loop
- Line 277: Working history in-progress
- Line 396: Fallback pending group
🐛 ISSUE 2: Different Rendering Code
Root Cause: Two completely separate code paths
| Aspect | Real-time | History Restore |
|---|---|---|
| Code file | console-websocket-client.ts | console-history.ts |
| Prompt display | Full prompt (no truncation) | Truncated to 100 chars |
| Prompt source | User's input directly | kontext.prompt (sanitized) |
| Rendering | appendLine() in console-ui.ts | Manual DOM creation inline |
| Event streaming | WebSocket events → handler | Pre-rendered from stored data |
| Tool results | Full content for short outputs | Only summary strings |
🔍 CODE PATH COMPARISON
REAL-TIME (console-websocket-client.ts:440-442)
// User types prompt, clicks Send → WebSocket sends → this code runs: appendLine('> ' + prompt, 'user-prompt'); // ↑ prompt is the RAW user input - FULL LENGTH
HISTORY RESTORE (console-history.ts:115-116)
// Page refresh → fetch /api/konsole/dashboard/history → this code runs: const origPrompt = sanitizePrompt(kontext.prompt); // ← 100 char TRUNCATION promptText.textContent = '> ' + origPrompt;
💡 WHY TWO CODE PATHS?
Historical reason: History restoration was added later and written as standalone inline script that gets embedded in the HTML. It duplicates much of the rendering logic instead of reusing the real-time handlers.
The inline script approach was needed for page-load execution before the main console modules initialize, but it created a maintenance burden where changes need to be made in multiple places.
✅ PROPOSED FIXES
Fix 1: Remove truncation from sanitizePrompt()
// BEFORE (line 35) return cleaned.slice(0, 100) + (cleaned.length > 100 ? '...' : ''); // AFTER - return full prompt return cleaned;
Fix 2: Add CSS text wrapping (optional)
/* In layout.ts CSS for .prompt-text */ .prompt-text { white-space: pre-wrap; /* Wrap long prompts */ word-break: break-word; }
Fix 3 (Future): Unify rendering code
Extract shared rendering functions that both real-time and history can use, eliminating duplication. This is more work but prevents future divergence.
📊 IMPACT SUMMARY
| Truncation fix | 1 line change | console-history.ts:35 |
| CSS wrapping | ~3 line change | views/layout.ts |
| Unified rendering | Larger refactor | Multiple files |
Files: konui/src/console-history.ts, konui/src/console-ui.ts, konui/src/console-websocket-client.ts
Quick Actions
Original Request
No layout configured
Details
📋 Claude's Context
ses_df705a8d...
Raw Data
{
"id": "a2f1fd0e-e101-45cf-97c7-bfbdcb189434",
"type": "general",
"status": "completed",
"title": "Console History vs Real-time: Code Analysis",
"description": "Analysis of why history prompts are truncated and why rendering differs from real-time",
"context": {
"output": "<div style=\"background:#1e1e1e;color:#e0e0e0;padding:20px;border-radius:8px;font-family:'Consolas','Monaco',monospace;\">\n<h2 style=\"font-family:sans-serif;color:#fff;margin:0 0 16px 0;\">Console History vs Real-time: Code Analysis</h2>\n\n<h3 style=\"color:#e06c75;margin:20px 0 12px 0;font-size:14px;\">🐛 ISSUE 1: Prompt Truncation</h3>\n<div style=\"background:#3d2d2d;padding:12px;border-radius:6px;margin-bottom:16px;border-left:4px solid #e06c75;\">\n<p style=\"margin:0 0 8px 0;color:#e06c75;font-weight:bold;\">Root Cause: Hard-coded 100 character limit</p>\n<p style=\"margin:0;color:#e0e0e0;\">The <code>sanitizePrompt()</code> function in console-history.ts:35 truncates all prompts:</p>\n<pre style=\"background:#252525;padding:8px;border-radius:4px;margin:8px 0 0 0;font-size:11px;overflow-x:auto;\"><span style=\"color:#e06c75;\">return cleaned.slice(0, 100) + (cleaned.length > 100 ? '...' : '');</span></pre>\n</div>\n\n<div style=\"background:#2d2d2d;padding:12px;border-radius:6px;margin-bottom:16px;\">\n<p style=\"margin:0 0 8px 0;color:#7f848e;font-size:12px;\">File: <code>konui/src/console-history.ts:35</code></p>\n<p style=\"margin:0;color:#e0e0e0;font-size:12px;\">This truncation happens at 3 different call sites:</p>\n<ul style=\"margin:8px 0 0 0;padding-left:20px;color:#e0e0e0;font-size:11px;\">\n<li>Line 115: Kontext history loop</li>\n<li>Line 277: Working history in-progress</li>\n<li>Line 396: Fallback pending group</li>\n</ul>\n</div>\n\n<h3 style=\"color:#e06c75;margin:20px 0 12px 0;font-size:14px;\">🐛 ISSUE 2: Different Rendering Code</h3>\n<div style=\"background:#3d2d2d;padding:12px;border-radius:6px;margin-bottom:16px;border-left:4px solid #e06c75;\">\n<p style=\"margin:0 0 8px 0;color:#e06c75;font-weight:bold;\">Root Cause: Two completely separate code paths</p>\n</div>\n\n<table style=\"width:100%;background:#2d2d2d;border-radius:6px;margin-bottom:16px;border-collapse:collapse;font-size:11px;\">\n<tr style=\"background:#353535;\"><th style=\"padding:8px;text-align:left;color:#7f848e;\">Aspect</th><th style=\"padding:8px;text-align:left;color:#98c379;\">Real-time</th><th style=\"padding:8px;text-align:left;color:#e06c75;\">History Restore</th></tr>\n<tr><td style=\"padding:8px;color:#e0e0e0;\">Code file</td><td style=\"padding:8px;color:#56b6c2;\">console-websocket-client.ts</td><td style=\"padding:8px;color:#56b6c2;\">console-history.ts</td></tr>\n<tr><td style=\"padding:8px;color:#e0e0e0;\">Prompt display</td><td style=\"padding:8px;color:#98c379;\">Full prompt (no truncation)</td><td style=\"padding:8px;color:#e06c75;\">Truncated to 100 chars</td></tr>\n<tr><td style=\"padding:8px;color:#e0e0e0;\">Prompt source</td><td style=\"padding:8px;color:#98c379;\">User's input directly</td><td style=\"padding:8px;color:#e06c75;\">kontext.prompt (sanitized)</td></tr>\n<tr><td style=\"padding:8px;color:#e0e0e0;\">Rendering</td><td style=\"padding:8px;color:#98c379;\">appendLine() in console-ui.ts</td><td style=\"padding:8px;color:#e06c75;\">Manual DOM creation inline</td></tr>\n<tr><td style=\"padding:8px;color:#e0e0e0;\">Event streaming</td><td style=\"padding:8px;color:#98c379;\">WebSocket events → handler</td><td style=\"padding:8px;color:#e06c75;\">Pre-rendered from stored data</td></tr>\n<tr><td style=\"padding:8px;color:#e0e0e0;\">Tool results</td><td style=\"padding:8px;color:#98c379;\">Full content for short outputs</td><td style=\"padding:8px;color:#e06c75;\">Only summary strings</td></tr>\n</table>\n\n<h3 style=\"color:#61afef;margin:20px 0 12px 0;font-size:14px;\">🔍 CODE PATH COMPARISON</h3>\n\n<div style=\"background:#2d2d2d;padding:12px;border-radius:6px;margin-bottom:16px;\">\n<h4 style=\"color:#98c379;margin:0 0 8px 0;font-size:12px;\">REAL-TIME (console-websocket-client.ts:440-442)</h4>\n<pre style=\"background:#252525;padding:8px;border-radius:4px;margin:0;font-size:10px;overflow-x:auto;\"><span style=\"color:#7f848e;\">// User types prompt, clicks Send → WebSocket sends → this code runs:</span>\n<span style=\"color:#61afef;\">appendLine</span>(<span style=\"color:#98c379;\">'> '</span> + <span style=\"color:#e5c07b;\">prompt</span>, <span style=\"color:#98c379;\">'user-prompt'</span>);\n<span style=\"color:#7f848e;\">// ↑ prompt is the RAW user input - FULL LENGTH</span></pre>\n</div>\n\n<div style=\"background:#2d2d2d;padding:12px;border-radius:6px;margin-bottom:16px;\">\n<h4 style=\"color:#e06c75;margin:0 0 8px 0;font-size:12px;\">HISTORY RESTORE (console-history.ts:115-116)</h4>\n<pre style=\"background:#252525;padding:8px;border-radius:4px;margin:0;font-size:10px;overflow-x:auto;\"><span style=\"color:#7f848e;\">// Page refresh → fetch /api/konsole/dashboard/history → this code runs:</span>\n<span style=\"color:#c678dd;\">const</span> origPrompt = <span style=\"color:#61afef;\">sanitizePrompt</span>(kontext.prompt); <span style=\"color:#7f848e;\">// ← 100 char TRUNCATION</span>\npromptText.textContent = <span style=\"color:#98c379;\">'> '</span> + origPrompt;</pre>\n</div>\n\n<h3 style=\"color:#c678dd;margin:20px 0 12px 0;font-size:14px;\">💡 WHY TWO CODE PATHS?</h3>\n<div style=\"background:#2d2d2d;padding:12px;border-radius:6px;margin-bottom:16px;\">\n<p style=\"margin:0 0 12px 0;color:#e0e0e0;font-size:12px;\"><strong>Historical reason:</strong> History restoration was added later and written as standalone inline script that gets embedded in the HTML. It duplicates much of the rendering logic instead of reusing the real-time handlers.</p>\n<p style=\"margin:0;color:#7f848e;font-size:11px;\">The inline script approach was needed for page-load execution before the main console modules initialize, but it created a maintenance burden where changes need to be made in multiple places.</p>\n</div>\n\n<h3 style=\"color:#98c379;margin:20px 0 12px 0;font-size:14px;\">✅ PROPOSED FIXES</h3>\n\n<div style=\"background:#2d3d2d;padding:12px;border-radius:6px;margin-bottom:12px;border-left:4px solid #98c379;\">\n<h4 style=\"color:#98c379;margin:0 0 8px 0;font-size:12px;\">Fix 1: Remove truncation from sanitizePrompt()</h4>\n<pre style=\"background:#252525;padding:8px;border-radius:4px;margin:0;font-size:10px;overflow-x:auto;\"><span style=\"color:#e06c75;\">// BEFORE (line 35)</span>\n<span style=\"color:#7f848e;\">return cleaned.slice(0, 100) + (cleaned.length > 100 ? '...' : '');</span>\n\n<span style=\"color:#98c379;\">// AFTER - return full prompt</span>\n<span style=\"color:#61afef;\">return cleaned;</span></pre>\n</div>\n\n<div style=\"background:#2d3d2d;padding:12px;border-radius:6px;margin-bottom:12px;border-left:4px solid #98c379;\">\n<h4 style=\"color:#98c379;margin:0 0 8px 0;font-size:12px;\">Fix 2: Add CSS text wrapping (optional)</h4>\n<pre style=\"background:#252525;padding:8px;border-radius:4px;margin:0;font-size:10px;overflow-x:auto;\"><span style=\"color:#7f848e;\">/* In layout.ts CSS for .prompt-text */</span>\n<span style=\"color:#61afef;\">.prompt-text</span> {\n <span style=\"color:#e5c07b;\">white-space</span>: <span style=\"color:#98c379;\">pre-wrap</span>; <span style=\"color:#7f848e;\">/* Wrap long prompts */</span>\n <span style=\"color:#e5c07b;\">word-break</span>: <span style=\"color:#98c379;\">break-word</span>;\n}</pre>\n</div>\n\n<div style=\"background:#2d3d2d;padding:12px;border-radius:6px;margin-bottom:16px;border-left:4px solid #98c379;\">\n<h4 style=\"color:#98c379;margin:0 0 8px 0;font-size:12px;\">Fix 3 (Future): Unify rendering code</h4>\n<p style=\"margin:0;color:#e0e0e0;font-size:11px;\">Extract shared rendering functions that both real-time and history can use, eliminating duplication. This is more work but prevents future divergence.</p>\n</div>\n\n<h3 style=\"color:#61afef;margin:20px 0 12px 0;font-size:14px;\">📊 IMPACT SUMMARY</h3>\n<table style=\"width:100%;background:#2d2d2d;border-radius:6px;margin-bottom:16px;border-collapse:collapse;font-size:11px;\">\n<tr><td style=\"padding:8px;color:#e0e0e0;\">Truncation fix</td><td style=\"padding:8px;color:#98c379;\">1 line change</td><td style=\"padding:8px;color:#7f848e;\">console-history.ts:35</td></tr>\n<tr><td style=\"padding:8px;color:#e0e0e0;\">CSS wrapping</td><td style=\"padding:8px;color:#98c379;\">~3 line change</td><td style=\"padding:8px;color:#7f848e;\">views/layout.ts</td></tr>\n<tr><td style=\"padding:8px;color:#e0e0e0;\">Unified rendering</td><td style=\"padding:8px;color:#e5c07b;\">Larger refactor</td><td style=\"padding:8px;color:#7f848e;\">Multiple files</td></tr>\n</table>\n\n<p style=\"color:#7f848e;margin:20px 0 0 0;font-size:11px;\">Files: konui/src/console-history.ts, konui/src/console-ui.ts, konui/src/console-websocket-client.ts</p>\n</div>",
"requestedAt": "2026-01-10T10:10:00.000Z",
"requestId": "e31f4119-a2cd-4b66-bd24-a1705775d94e",
"choices": [
{
"label": "Fix truncation",
"value": "Remove the 100 character truncation from sanitizePrompt() so full prompts are shown in history",
"primary": true
},
{
"label": "Add CSS wrapping",
"value": "Also add CSS text wrapping so long prompts display nicely",
"primary": false
},
{
"label": "Full refactor",
"value": "Do the larger refactor to unify the real-time and history rendering code paths",
"primary": false
}
],
"turnTiming": {
"totalMs": 84201,
"ttfeMs": 49,
"thinkingMs": 84152,
"toolExecutionMs": 0,
"toolCallCount": 0,
"thinkingPct": 100,
"toolsPct": 0,
"ttfePct": 0
}
},
"createdBy": "claude",
"createdAt": "2026-01-09T23:09:59.758Z",
"updatedAt": "2026-01-09T23:10:05.671Z",
"requestId": "e31f4119-a2cd-4b66-bd24-a1705775d94e",
"scope": "vibetools",
"tags": [
"console-history",
"analysis",
"ux"
],
"sessionId": "ses_df705a8d-ea1",
"flowId": "flow_01KEHQ5A7ZX7YDB8KG1NP2GE68",
"flowLinks": [
{
"flowId": "flow_01KEHQ5A7ZX7YDB8KG1NP2GE68",
"edgeType": "evidence",
"createdAt": "2026-01-09T23:09:59.758Z"
}
]
}