omnius 1.0.27 → 1.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +206 -97
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -610964,7 +610964,7 @@ body { display:flex; flex-direction:column; height:100vh; margin:0; overflow:hid
|
|
|
610964
610964
|
color: var(--color-fg);
|
|
610965
610965
|
}
|
|
610966
610966
|
.msg.assistant::before {
|
|
610967
|
-
content: '
|
|
610967
|
+
content: 'O' !important;
|
|
610968
610968
|
position: absolute;
|
|
610969
610969
|
top: 14px;
|
|
610970
610970
|
left: 0;
|
|
@@ -612301,6 +612301,36 @@ const $sidebarWidth = writable(260);
|
|
|
612301
612301
|
const $config = writable(null); // {endpoint, model, ...}
|
|
612302
612302
|
const $activeTab = writable('chat');
|
|
612303
612303
|
|
|
612304
|
+
function parseInitialGuiRoute() {
|
|
612305
|
+
const path = (location.pathname || '/').replace(//+$/, '') || '/';
|
|
612306
|
+
const pathToTab = {
|
|
612307
|
+
'/chat': 'chat',
|
|
612308
|
+
'/agent': 'agent',
|
|
612309
|
+
'/voice': 'voice',
|
|
612310
|
+
'/projects': 'projects',
|
|
612311
|
+
'/dashboard': 'jobs',
|
|
612312
|
+
'/jobs': 'jobs',
|
|
612313
|
+
'/activity': 'activity',
|
|
612314
|
+
'/settings': 'config',
|
|
612315
|
+
'/config': 'config',
|
|
612316
|
+
};
|
|
612317
|
+
const tab = pathToTab[path] || null;
|
|
612318
|
+
let chatSession = null;
|
|
612319
|
+
if (tab === 'chat') {
|
|
612320
|
+
const qs = location.search.replace(/^?/, '').trim();
|
|
612321
|
+
if (qs) {
|
|
612322
|
+
try {
|
|
612323
|
+
const params = new URLSearchParams(location.search);
|
|
612324
|
+
chatSession = params.get('session') || params.get('id') || params.get('s') || decodeURIComponent(qs.split('&')[0] || '');
|
|
612325
|
+
} catch {
|
|
612326
|
+
chatSession = qs;
|
|
612327
|
+
}
|
|
612328
|
+
}
|
|
612329
|
+
}
|
|
612330
|
+
return { tab, chatSession };
|
|
612331
|
+
}
|
|
612332
|
+
const initialGuiRoute = parseInitialGuiRoute();
|
|
612333
|
+
|
|
612304
612334
|
// Global writes (not project-scoped)
|
|
612305
612335
|
$apiKey.subscribe(v => {
|
|
612306
612336
|
try { v ? localStorage.setItem('omnius-api-key', v) : localStorage.removeItem('omnius-api-key'); } catch {}
|
|
@@ -612350,11 +612380,12 @@ $currentProject.subscribe(async (proj) => {
|
|
|
612350
612380
|
// Server hydrate (overrides local on first load — server is cross-device truth)
|
|
612351
612381
|
const server = await loadServerPrefs();
|
|
612352
612382
|
$selectedModel.set(server?.selectedModel ?? localModel);
|
|
612353
|
-
$chatSessionId.set(server?.currentChatSessionId
|
|
612383
|
+
$chatSessionId.set(initialGuiRoute.chatSession || server?.currentChatSessionId || localChat || null);
|
|
612354
612384
|
$agentRunId.set(server?.currentAgentRunId ?? (localAgent || null));
|
|
612355
612385
|
$sidebarWidth.set(server?.sidebarWidth ?? localWidth);
|
|
612356
612386
|
if (server?.theme && server.theme !== $theme.get()) $theme.set(server.theme);
|
|
612357
|
-
if (
|
|
612387
|
+
if (initialGuiRoute.tab) $activeTab.set(initialGuiRoute.tab);
|
|
612388
|
+
else if (server?.activeTab) $activeTab.set(server.activeTab);
|
|
612358
612389
|
else if (localTab) $activeTab.set(localTab);
|
|
612359
612390
|
});
|
|
612360
612391
|
|
|
@@ -612657,6 +612688,42 @@ function persistSelectedModel() {
|
|
|
612657
612688
|
}).catch(() => { /* offline / read-only — store still saved */ });
|
|
612658
612689
|
}
|
|
612659
612690
|
|
|
612691
|
+
function appendAssistantActions(div, textProvider) {
|
|
612692
|
+
const actions = document.createElement('div');
|
|
612693
|
+
actions.className = 'msg-actions';
|
|
612694
|
+
const mkBtn = (label, title, fn) => {
|
|
612695
|
+
const b = document.createElement('button');
|
|
612696
|
+
b.textContent = label;
|
|
612697
|
+
b.title = title;
|
|
612698
|
+
b.onclick = fn;
|
|
612699
|
+
return b;
|
|
612700
|
+
};
|
|
612701
|
+
actions.appendChild(mkBtn('copy', 'Copy message', () => {
|
|
612702
|
+
const txt = (typeof textProvider === 'function' ? textProvider() : '') || '';
|
|
612703
|
+
try { navigator.clipboard.writeText(txt); } catch {}
|
|
612704
|
+
const first = actions.querySelector('button');
|
|
612705
|
+
if (!first) return;
|
|
612706
|
+
const orig = first.textContent;
|
|
612707
|
+
first.textContent = 'copied';
|
|
612708
|
+
setTimeout(() => { first.textContent = orig; }, 1500);
|
|
612709
|
+
}));
|
|
612710
|
+
actions.appendChild(mkBtn('regen', 'Regenerate this response', () => {
|
|
612711
|
+
try { regenerateAssistantMessage(div); } catch (e) { console.warn('regen failed', e); }
|
|
612712
|
+
}));
|
|
612713
|
+
actions.appendChild(mkBtn('del', 'Delete this message', () => {
|
|
612714
|
+
try { deleteMessageDiv(div); } catch (e) { console.warn('del failed', e); }
|
|
612715
|
+
}));
|
|
612716
|
+
div.appendChild(actions);
|
|
612717
|
+
return actions;
|
|
612718
|
+
}
|
|
612719
|
+
|
|
612720
|
+
function removeAssistantActions(div) {
|
|
612721
|
+
if (!div) return;
|
|
612722
|
+
Array.from(div.children || []).forEach(ch => {
|
|
612723
|
+
if (ch && ch.classList && ch.classList.contains('msg-actions')) ch.remove();
|
|
612724
|
+
});
|
|
612725
|
+
}
|
|
612726
|
+
|
|
612660
612727
|
function addMessage(role, content) {
|
|
612661
612728
|
const div = document.createElement('div');
|
|
612662
612729
|
div.className = 'msg ' + role;
|
|
@@ -612678,32 +612745,7 @@ function addMessage(role, content) {
|
|
|
612678
612745
|
}
|
|
612679
612746
|
// OWUI-3: rich per-message action row on assistant messages.
|
|
612680
612747
|
if (role === 'assistant') {
|
|
612681
|
-
|
|
612682
|
-
actions.className = 'msg-actions';
|
|
612683
|
-
const mkBtn = (label, title, fn) => {
|
|
612684
|
-
const b = document.createElement('button');
|
|
612685
|
-
b.textContent = label;
|
|
612686
|
-
b.title = title;
|
|
612687
|
-
b.onclick = fn;
|
|
612688
|
-
return b;
|
|
612689
|
-
};
|
|
612690
|
-
actions.appendChild(mkBtn('copy', 'Copy message', () => {
|
|
612691
|
-
// Copy what's actually visible (post-render text), not the raw arg —
|
|
612692
|
-
// the closure-captured "content" may be empty when this message was
|
|
612693
|
-
// built incrementally during streaming.
|
|
612694
|
-
const txt = host.innerText || host.textContent || content || '';
|
|
612695
|
-
try { navigator.clipboard.writeText(txt); } catch {}
|
|
612696
|
-
const orig = actions.querySelector('button').textContent;
|
|
612697
|
-
actions.querySelector('button').textContent = 'copied';
|
|
612698
|
-
setTimeout(() => { actions.querySelector('button').textContent = orig; }, 1500);
|
|
612699
|
-
}));
|
|
612700
|
-
actions.appendChild(mkBtn('regen', 'Regenerate this response', () => {
|
|
612701
|
-
try { regenerateAssistantMessage(div); } catch (e) { console.warn('regen failed', e); }
|
|
612702
|
-
}));
|
|
612703
|
-
actions.appendChild(mkBtn('del', 'Delete this message', () => {
|
|
612704
|
-
try { deleteMessageDiv(div); } catch (e) { console.warn('del failed', e); }
|
|
612705
|
-
}));
|
|
612706
|
-
div.appendChild(actions);
|
|
612748
|
+
appendAssistantActions(div, () => host.innerText || host.textContent || content || '');
|
|
612707
612749
|
}
|
|
612708
612750
|
conv.appendChild(div);
|
|
612709
612751
|
// OWUI-3: schedule syntax highlight for any new code blocks.
|
|
@@ -612894,6 +612936,12 @@ function appendExpandableContent(parent, fullText, opts) {
|
|
|
612894
612936
|
return wrapper;
|
|
612895
612937
|
}
|
|
612896
612938
|
|
|
612939
|
+
function isInternalChatTool(toolName) {
|
|
612940
|
+
return toolName === 'task_complete'
|
|
612941
|
+
|| toolName === 'todo_write'
|
|
612942
|
+
|| toolName === 'todo_read';
|
|
612943
|
+
}
|
|
612944
|
+
|
|
612897
612945
|
// WO-CHAT-RESUME-TOOLS — render a single tool_call event into a parent
|
|
612898
612946
|
// container. Used by BOTH the live SSE handler AND the chat history
|
|
612899
612947
|
// restore path so reloads see the same intermediate-state dropdowns
|
|
@@ -612901,12 +612949,13 @@ function appendExpandableContent(parent, fullText, opts) {
|
|
|
612901
612949
|
// SSE chunk shape ({type:'tool_call', tool, args}) OR the persisted
|
|
612902
612950
|
// session message shape ({role:'tool_call', tool, args}).
|
|
612903
612951
|
function renderToolCallEvent(parent, chunkLike) {
|
|
612952
|
+
const toolName = chunkLike.tool || 'tool';
|
|
612953
|
+
if (isInternalChatTool(toolName)) return null;
|
|
612904
612954
|
const details = document.createElement('details');
|
|
612905
612955
|
details.style.cssText = 'background:var(--color-bg-elevated);border-left:2px solid var(--color-brand);margin:2px 0;font-size:0.7rem';
|
|
612906
612956
|
const summary = document.createElement('summary');
|
|
612907
612957
|
summary.style.cssText = 'padding:4px 8px;color:var(--color-brand);cursor:pointer';
|
|
612908
612958
|
|
|
612909
|
-
const toolName = chunkLike.tool || 'tool';
|
|
612910
612959
|
let a = (chunkLike.args && typeof chunkLike.args === 'object') ? chunkLike.args : {};
|
|
612911
612960
|
if (typeof chunkLike.args === 'string') {
|
|
612912
612961
|
try { a = JSON.parse(chunkLike.args); } catch { a = { _raw: chunkLike.args }; }
|
|
@@ -612995,6 +613044,7 @@ function renderToolCallEvent(parent, chunkLike) {
|
|
|
612995
613044
|
// WO-CHAT-RESUME-TOOLS — render a single tool_result event with the
|
|
612996
613045
|
// show-more/hide expandable helper. Used by both live SSE and restore.
|
|
612997
613046
|
function renderToolResultEvent(parent, chunkLike) {
|
|
613047
|
+
if (isInternalChatTool(chunkLike.tool)) return null;
|
|
612998
613048
|
const resultEl = document.createElement('div');
|
|
612999
613049
|
const errStyle = chunkLike.success === false
|
|
613000
613050
|
? 'background:#2a1e1e;border-left:2px solid var(--color-error);color:var(--color-error);'
|
|
@@ -613304,6 +613354,7 @@ async function sendMessage() {
|
|
|
613304
613354
|
// $chatSessionId.set(...) — the subscriber persists to project-
|
|
613305
613355
|
// scoped localStorage AND server prefs. Setting it here is enough.
|
|
613306
613356
|
chatSessionId = sid;
|
|
613357
|
+
syncRouteForTab('chat', true);
|
|
613307
613358
|
// WO-TASK-02: Surface the session ID globally so refreshTodos works
|
|
613308
613359
|
window.currentSessionId = sid;
|
|
613309
613360
|
// Initial refresh in case the agent set todos before the SSE stream
|
|
@@ -613343,16 +613394,20 @@ async function sendMessage() {
|
|
|
613343
613394
|
|| (typeof ta.result === 'string' && ta.result)
|
|
613344
613395
|
|| '';
|
|
613345
613396
|
if (summaryText) {
|
|
613346
|
-
if (fullContent
|
|
613347
|
-
|
|
613397
|
+
if (fullContent.trim() !== summaryText.trim()) {
|
|
613398
|
+
if (fullContent && !fullContent.endsWith('\\n')) fullContent += '\\n\\n';
|
|
613399
|
+
fullContent += summaryText;
|
|
613400
|
+
}
|
|
613348
613401
|
contentDiv.innerHTML = renderMarkdown(fullContent);
|
|
613402
|
+
hideStreamingIndicator(msgDiv);
|
|
613349
613403
|
maybeAutoScroll();
|
|
613350
613404
|
}
|
|
613351
|
-
|
|
613405
|
+
continue;
|
|
613352
613406
|
}
|
|
613353
613407
|
|
|
613354
613408
|
// Tool call event — show live as expandable section
|
|
613355
613409
|
if (chunk.type === 'tool_call') {
|
|
613410
|
+
if (isInternalChatTool(chunk.tool || '')) continue;
|
|
613356
613411
|
chatTools.push(chunk);
|
|
613357
613412
|
const details = document.createElement('details');
|
|
613358
613413
|
details.style.cssText = 'background:var(--color-bg-elevated);border-left:2px solid var(--color-brand);margin:2px 0;font-size:0.7rem';
|
|
@@ -613466,6 +613521,7 @@ async function sendMessage() {
|
|
|
613466
613521
|
// expand to see the FULL output instead of being capped at
|
|
613467
613522
|
// 150 chars. The button sits underneath the result block.
|
|
613468
613523
|
if (chunk.type === 'tool_result') {
|
|
613524
|
+
if (isInternalChatTool(chunk.tool || '')) continue;
|
|
613469
613525
|
const resultEl = document.createElement('div');
|
|
613470
613526
|
resultEl.style.cssText = 'background:var(--color-bg-elevated);padding:4px 8px 4px 18px;margin:0 0 2px 0;color:var(--color-fg-muted);font-size:0.65rem';
|
|
613471
613527
|
appendExpandableContent(resultEl, chunk.output || '', { truncateAt: 150, baseStyle: 'color:var(--color-fg-muted);' });
|
|
@@ -613482,12 +613538,7 @@ async function sendMessage() {
|
|
|
613482
613538
|
// Content delta
|
|
613483
613539
|
const delta = chunk.choices?.[0]?.delta?.content || '';
|
|
613484
613540
|
if (delta) {
|
|
613485
|
-
|
|
613486
|
-
// first delta, and remove on subsequent deltas (it lives at
|
|
613487
|
-
// the bottom of the message, below content).
|
|
613488
|
-
if (!fullContent) {
|
|
613489
|
-
showStreamingIndicator(msgDiv, 'writing');
|
|
613490
|
-
}
|
|
613541
|
+
hideStreamingIndicator(msgDiv);
|
|
613491
613542
|
fullContent += delta;
|
|
613492
613543
|
contentDiv.innerHTML = renderMarkdown(fullContent);
|
|
613493
613544
|
try { _highlightCodeBlocks(contentDiv); } catch {}
|
|
@@ -613502,6 +613553,7 @@ async function sendMessage() {
|
|
|
613502
613553
|
// extract it here so the next message uses the same session.
|
|
613503
613554
|
if (!chatSessionId && metaInfo && metaInfo.session_id) {
|
|
613504
613555
|
chatSessionId = metaInfo.session_id;
|
|
613556
|
+
syncRouteForTab('chat', true);
|
|
613505
613557
|
}
|
|
613506
613558
|
|
|
613507
613559
|
// Save with metadata for session recall
|
|
@@ -613541,14 +613593,8 @@ async function sendMessage() {
|
|
|
613541
613593
|
toolsContainer.appendChild(details);
|
|
613542
613594
|
}
|
|
613543
613595
|
|
|
613544
|
-
|
|
613545
|
-
|
|
613546
|
-
actions.className = 'msg-actions';
|
|
613547
|
-
const copyBtn = document.createElement('button');
|
|
613548
|
-
copyBtn.textContent = 'copy';
|
|
613549
|
-
copyBtn.onclick = () => { navigator.clipboard.writeText(fullContent); copyBtn.textContent = 'copied'; setTimeout(() => copyBtn.textContent = 'copy', 1500); };
|
|
613550
|
-
actions.appendChild(copyBtn);
|
|
613551
|
-
msgDiv.appendChild(actions);
|
|
613596
|
+
removeAssistantActions(msgDiv);
|
|
613597
|
+
appendAssistantActions(msgDiv, () => fullContent);
|
|
613552
613598
|
} catch (err) {
|
|
613553
613599
|
// Match the red left-border styling used by failed tool_result
|
|
613554
613600
|
// and the stop-button. Sits inside the assistant bubble so it
|
|
@@ -614398,9 +614444,56 @@ window.closeRemoteConnection = closeRemoteConnection;
|
|
|
614398
614444
|
} catch {}
|
|
614399
614445
|
})();
|
|
614400
614446
|
|
|
614401
|
-
// Tab switching
|
|
614447
|
+
// Tab switching + browser route sync
|
|
614402
614448
|
const allPanels = ['chat-container','agent-panel','jobs-panel','config-panel','activity-panel','projects-panel','voice-panel'];
|
|
614403
|
-
function
|
|
614449
|
+
function routePathForTab(tab) {
|
|
614450
|
+
const map = {
|
|
614451
|
+
chat: '/chat',
|
|
614452
|
+
agent: '/agent',
|
|
614453
|
+
voice: '/voice',
|
|
614454
|
+
projects: '/projects',
|
|
614455
|
+
jobs: '/dashboard',
|
|
614456
|
+
activity: '/activity',
|
|
614457
|
+
config: '/settings',
|
|
614458
|
+
};
|
|
614459
|
+
return map[tab] || '/chat';
|
|
614460
|
+
}
|
|
614461
|
+
function tabForRoutePath(pathname) {
|
|
614462
|
+
const path = (pathname || '/').replace(//+$/, '') || '/';
|
|
614463
|
+
const map = {
|
|
614464
|
+
'/': 'chat',
|
|
614465
|
+
'/chat': 'chat',
|
|
614466
|
+
'/agent': 'agent',
|
|
614467
|
+
'/voice': 'voice',
|
|
614468
|
+
'/projects': 'projects',
|
|
614469
|
+
'/dashboard': 'jobs',
|
|
614470
|
+
'/jobs': 'jobs',
|
|
614471
|
+
'/activity': 'activity',
|
|
614472
|
+
'/settings': 'config',
|
|
614473
|
+
'/config': 'config',
|
|
614474
|
+
};
|
|
614475
|
+
return map[path] || 'chat';
|
|
614476
|
+
}
|
|
614477
|
+
function chatSessionFromRouteSearch(search) {
|
|
614478
|
+
const qs = String(search || '').replace(/^?/, '').trim();
|
|
614479
|
+
if (!qs) return null;
|
|
614480
|
+
try {
|
|
614481
|
+
const params = new URLSearchParams(search);
|
|
614482
|
+
return params.get('session') || params.get('id') || params.get('s') || decodeURIComponent(qs.split('&')[0] || '');
|
|
614483
|
+
} catch {
|
|
614484
|
+
return qs;
|
|
614485
|
+
}
|
|
614486
|
+
}
|
|
614487
|
+
function syncRouteForTab(tab, replace) {
|
|
614488
|
+
const path = routePathForTab(tab);
|
|
614489
|
+
const query = tab === 'chat' && chatSessionId ? '?' + encodeURIComponent(chatSessionId) : '';
|
|
614490
|
+
const next = path + query;
|
|
614491
|
+
if ((location.pathname + location.search) === next) return;
|
|
614492
|
+
const method = replace ? 'replaceState' : 'pushState';
|
|
614493
|
+
try { history[method]({}, '', next); } catch {}
|
|
614494
|
+
}
|
|
614495
|
+
function switchTab(tab, opts) {
|
|
614496
|
+
opts = opts || {};
|
|
614404
614497
|
const panelMap = {chat:'chat-container',agent:'agent-panel',jobs:'jobs-panel',config:'config-panel',activity:'activity-panel',projects:'projects-panel',voice:'voice-panel'};
|
|
614405
614498
|
allPanels.forEach(id => { const el = document.getElementById(id); if(el) el.style.display = 'none'; });
|
|
614406
614499
|
const panel = document.getElementById(panelMap[tab]);
|
|
@@ -614417,6 +614510,8 @@ function switchTab(tab) {
|
|
|
614417
614510
|
document.querySelectorAll('#omnius-sidebar .sb-nav').forEach(b => {
|
|
614418
614511
|
b.classList.toggle('active', b.getAttribute('data-tab') === tab);
|
|
614419
614512
|
});
|
|
614513
|
+
if ($activeTab.get && $activeTab.get() !== tab) $activeTab.set(tab);
|
|
614514
|
+
if (!opts.fromRoute) syncRouteForTab(tab, !!opts.replaceRoute);
|
|
614420
614515
|
if (tab === 'jobs') loadJobs();
|
|
614421
614516
|
if (tab === 'agent') {
|
|
614422
614517
|
loadProfiles();
|
|
@@ -614432,6 +614527,14 @@ function switchTab(tab) {
|
|
|
614432
614527
|
try { loadVoiceTab(); } catch {}
|
|
614433
614528
|
}
|
|
614434
614529
|
}
|
|
614530
|
+
window.addEventListener('popstate', () => {
|
|
614531
|
+
const tab = tabForRoutePath(location.pathname);
|
|
614532
|
+
if (tab === 'chat') {
|
|
614533
|
+
const sid = chatSessionFromRouteSearch(location.search);
|
|
614534
|
+
if (sid && sid !== chatSessionId) switchSession(sid);
|
|
614535
|
+
}
|
|
614536
|
+
switchTab(tab, { fromRoute: true });
|
|
614537
|
+
});
|
|
614435
614538
|
|
|
614436
614539
|
// Projects tab — list all workspaces the user has run 'omnius' in, and let them
|
|
614437
614540
|
// switch the active workspace. A switch is a server-side state change; the
|
|
@@ -615125,6 +615228,7 @@ function updateSessionSelect() {
|
|
|
615125
615228
|
// still works exactly as before.
|
|
615126
615229
|
function switchChatSession(id) {
|
|
615127
615230
|
switchSession(id);
|
|
615231
|
+
switchTab('chat', { replaceRoute: true });
|
|
615128
615232
|
}
|
|
615129
615233
|
function newChatSession() {
|
|
615130
615234
|
switchSession('');
|
|
@@ -615294,6 +615398,7 @@ function switchSession(id) {
|
|
|
615294
615398
|
chatSessionId = null;
|
|
615295
615399
|
messages = [];
|
|
615296
615400
|
document.getElementById('conversation').innerHTML = '';
|
|
615401
|
+
syncRouteForTab('chat', true);
|
|
615297
615402
|
return;
|
|
615298
615403
|
}
|
|
615299
615404
|
const saved = loadScopedSessions();
|
|
@@ -615345,6 +615450,7 @@ function switchSession(id) {
|
|
|
615345
615450
|
div.appendChild(outerDetails);
|
|
615346
615451
|
}
|
|
615347
615452
|
}
|
|
615453
|
+
syncRouteForTab('chat', true);
|
|
615348
615454
|
}
|
|
615349
615455
|
}
|
|
615350
615456
|
|
|
@@ -616354,32 +616460,14 @@ async function refreshTodos(sessionId) {
|
|
|
616354
616460
|
}
|
|
616355
616461
|
const j = await r.json();
|
|
616356
616462
|
const todos = (j && Array.isArray(j.todos)) ? j.todos : [];
|
|
616357
|
-
// 1)
|
|
616463
|
+
// 1) Keep the full checklist out of the chat transcript. The compact
|
|
616464
|
+
// tasks strip below is the visible progress surface.
|
|
616358
616465
|
if (todoChecklistEl && todoListEl) {
|
|
616359
|
-
|
|
616360
|
-
|
|
616361
|
-
|
|
616362
|
-
|
|
616363
|
-
|
|
616364
|
-
for (const t of todos) {
|
|
616365
|
-
const li = document.createElement('li');
|
|
616366
|
-
li.style.cssText = 'padding:2px 0;display:flex;gap:8px;align-items:flex-start';
|
|
616367
|
-
const mark = document.createElement('span');
|
|
616368
|
-
mark.style.cssText = 'color:var(--color-brand);font-family:monospace;flex-shrink:0';
|
|
616369
|
-
mark.textContent = statusMark(t.status);
|
|
616370
|
-
li.appendChild(mark);
|
|
616371
|
-
const content = document.createElement('span');
|
|
616372
|
-
content.style.cssText = t.status === 'completed'
|
|
616373
|
-
? 'color:var(--color-fg-subtle);text-decoration:line-through'
|
|
616374
|
-
: 'color:var(--color-fg)';
|
|
616375
|
-
content.textContent = t.content + (t.blocker ? ' (blocked: ' + t.blocker + ')' : '');
|
|
616376
|
-
li.appendChild(content);
|
|
616377
|
-
todoListEl.appendChild(li);
|
|
616378
|
-
}
|
|
616379
|
-
}
|
|
616380
|
-
}
|
|
616381
|
-
// 2) Update the compact tasks-row strip in the footer
|
|
616382
|
-
renderTasksRow(todos);
|
|
616466
|
+
todoChecklistEl.style.display = 'none';
|
|
616467
|
+
todoListEl.innerHTML = '';
|
|
616468
|
+
}
|
|
616469
|
+
// 2) Chat mode should not surface transient planning todos in the UI.
|
|
616470
|
+
renderTasksRow([]);
|
|
616383
616471
|
} catch { /* network or parse failure — leave panel as-is */ }
|
|
616384
616472
|
}
|
|
616385
616473
|
|
|
@@ -616456,9 +616544,11 @@ async function restoreChatSession() {
|
|
|
616456
616544
|
currentAssistantTools.style.cssText = 'margin:4px 0;font-size:0.7rem';
|
|
616457
616545
|
msgDiv.appendChild(currentAssistantTools);
|
|
616458
616546
|
} else if (m.role === 'tool_call') {
|
|
616547
|
+
if (isInternalChatTool(m.tool)) continue;
|
|
616459
616548
|
renderToolCallEvent(ensureTools(), { tool: m.tool, args: m.args });
|
|
616460
616549
|
} else if (m.role === 'tool_result') {
|
|
616461
|
-
|
|
616550
|
+
if (isInternalChatTool(m.tool)) continue;
|
|
616551
|
+
renderToolResultEvent(ensureTools(), { tool: m.tool, output: m.output, success: m.success });
|
|
616462
616552
|
} else if (m.role === 'user_checkin') {
|
|
616463
616553
|
// WO-CHAT-CHECKIN — replay the teal user check-in entry
|
|
616464
616554
|
renderCheckinEvent(ensureTools(), m.content);
|
|
@@ -616527,11 +616617,13 @@ function attachInFlightPoller(sessionId, initialJob) {
|
|
|
616527
616617
|
curTools.style.cssText = 'margin:4px 0;font-size:0.7rem';
|
|
616528
616618
|
md.appendChild(curTools);
|
|
616529
616619
|
} else if (m.role === 'tool_call') {
|
|
616620
|
+
if (isInternalChatTool(m.tool)) continue;
|
|
616530
616621
|
if (!curTools) { const md = addMessage('assistant', ''); curTools = document.createElement('div'); curTools.style.cssText = 'margin:4px 0;font-size:0.7rem'; md.appendChild(curTools); }
|
|
616531
616622
|
renderToolCallEvent(curTools, { tool: m.tool, args: m.args });
|
|
616532
616623
|
} else if (m.role === 'tool_result') {
|
|
616624
|
+
if (isInternalChatTool(m.tool)) continue;
|
|
616533
616625
|
if (!curTools) { const md = addMessage('assistant', ''); curTools = document.createElement('div'); curTools.style.cssText = 'margin:4px 0;font-size:0.7rem'; md.appendChild(curTools); }
|
|
616534
|
-
renderToolResultEvent(curTools, { output: m.output, success: m.success });
|
|
616626
|
+
renderToolResultEvent(curTools, { tool: m.tool, output: m.output, success: m.success });
|
|
616535
616627
|
}
|
|
616536
616628
|
}
|
|
616537
616629
|
}
|
|
@@ -616565,11 +616657,13 @@ function attachInFlightPoller(sessionId, initialJob) {
|
|
|
616565
616657
|
curTools.style.cssText = 'margin:4px 0;font-size:0.7rem';
|
|
616566
616658
|
md.appendChild(curTools);
|
|
616567
616659
|
} else if (m.role === 'tool_call') {
|
|
616660
|
+
if (isInternalChatTool(m.tool)) continue;
|
|
616568
616661
|
if (!curTools) { const md = addMessage('assistant', ''); curTools = document.createElement('div'); curTools.style.cssText = 'margin:4px 0;font-size:0.7rem'; md.appendChild(curTools); }
|
|
616569
616662
|
renderToolCallEvent(curTools, { tool: m.tool, args: m.args });
|
|
616570
616663
|
} else if (m.role === 'tool_result') {
|
|
616664
|
+
if (isInternalChatTool(m.tool)) continue;
|
|
616571
616665
|
if (!curTools) { const md = addMessage('assistant', ''); curTools = document.createElement('div'); curTools.style.cssText = 'margin:4px 0;font-size:0.7rem'; md.appendChild(curTools); }
|
|
616572
|
-
renderToolResultEvent(curTools, { output: m.output, success: m.success });
|
|
616666
|
+
renderToolResultEvent(curTools, { tool: m.tool, output: m.output, success: m.success });
|
|
616573
616667
|
}
|
|
616574
616668
|
}
|
|
616575
616669
|
}
|
|
@@ -617003,9 +617097,9 @@ $activeTab.subscribe((tab) => {
|
|
|
617003
617097
|
if (!tab || typeof switchTab !== 'function') return;
|
|
617004
617098
|
// Avoid recursion: switchTab is called by user click and writes back
|
|
617005
617099
|
// via window.switchTab('chat') style; we only DOM-update if needed.
|
|
617006
|
-
const
|
|
617007
|
-
if (
|
|
617008
|
-
try { switchTab(tab); } catch {}
|
|
617100
|
+
const navBtn = document.querySelector('#omnius-sidebar .sb-nav[data-tab="' + tab + '"]');
|
|
617101
|
+
if (!navBtn || !navBtn.classList.contains('active')) {
|
|
617102
|
+
try { switchTab(tab, { replaceRoute: true }); } catch {}
|
|
617009
617103
|
}
|
|
617010
617104
|
});
|
|
617011
617105
|
|
|
@@ -617504,7 +617598,7 @@ function _renderSidebarChats(filter) {
|
|
|
617504
617598
|
const cls = 'sb-chat' + (id === activeId ? ' active' : '');
|
|
617505
617599
|
const safeId = String(id).replace(/'/g, "\\\\'");
|
|
617506
617600
|
const safeTitle = title.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
617507
|
-
return '<div class="' + cls + '" draggable="true" ondragstart="_onChatDragStart(event,\\'' + safeId + '\\')" onclick="
|
|
617601
|
+
return '<div class="' + cls + '" draggable="true" ondragstart="_onChatDragStart(event,\\'' + safeId + '\\')" onclick="switchSession(\\'' + safeId + '\\'); switchTab(\\'chat\\', { replaceRoute: true })" title="' + safeTitle + '">' +
|
|
617508
617602
|
'<span class="sb-chat-title">' + safeTitle + '</span>' +
|
|
617509
617603
|
'<button class="sb-chat-menu" onclick="_showChatRowMenu(event,\\'' + safeId + '\\')" title="More">⋮</button>' +
|
|
617510
617604
|
'</div>';
|
|
@@ -623749,7 +623843,19 @@ async function handleRequest(req2, res, ollamaUrl, verbose) {
|
|
|
623749
623843
|
res.end(svg);
|
|
623750
623844
|
return;
|
|
623751
623845
|
}
|
|
623752
|
-
|
|
623846
|
+
const guiRoutes = /* @__PURE__ */ new Set([
|
|
623847
|
+
"/",
|
|
623848
|
+
"/chat",
|
|
623849
|
+
"/agent",
|
|
623850
|
+
"/voice",
|
|
623851
|
+
"/projects",
|
|
623852
|
+
"/dashboard",
|
|
623853
|
+
"/jobs",
|
|
623854
|
+
"/activity",
|
|
623855
|
+
"/settings",
|
|
623856
|
+
"/config"
|
|
623857
|
+
]);
|
|
623858
|
+
if (guiRoutes.has(pathname) && method === "GET" && req2.headers.accept?.includes("text/html")) {
|
|
623753
623859
|
res.writeHead(200, {
|
|
623754
623860
|
"Content-Type": "text/html; charset=utf-8",
|
|
623755
623861
|
"Cache-Control": "no-cache, no-store, must-revalidate, max-age=0",
|
|
@@ -624901,8 +625007,9 @@ data: ${JSON.stringify(data)}
|
|
|
624901
625007
|
session.id,
|
|
624902
625008
|
5
|
|
624903
625009
|
);
|
|
624904
|
-
|
|
624905
|
-
|
|
625010
|
+
const chatTodosEnabled = chatBody["todos"] === true || chatBody["enable_todos"] === true || chatBody["todo_injection"] === true;
|
|
625011
|
+
let currentTodos = chatTodosEnabled ? readTodos(session.id) : [];
|
|
625012
|
+
if (chatTodosEnabled && currentTodos.length === 0) {
|
|
624906
625013
|
const seeded = autoSeedTodosFromPrompt(chatBody.message);
|
|
624907
625014
|
if (seeded.length >= 2) {
|
|
624908
625015
|
try {
|
|
@@ -624915,7 +625022,7 @@ data: ${JSON.stringify(data)}
|
|
|
624915
625022
|
}
|
|
624916
625023
|
}
|
|
624917
625024
|
}
|
|
624918
|
-
const todoBlock = currentTodos.length > 0 ? "CURRENT TODO LIST:\n" + currentTodos.map((t2) => {
|
|
625025
|
+
const todoBlock = chatTodosEnabled && currentTodos.length > 0 ? "CURRENT TODO LIST:\n" + currentTodos.map((t2) => {
|
|
624919
625026
|
const mark = t2.status === "completed" ? "◉" : t2.status === "in_progress" ? "◐" : t2.status === "blocked" ? "◍" : "○";
|
|
624920
625027
|
return `${mark} ${t2.content}` + (t2.blocker ? ` (blocked: ${t2.blocker})` : "");
|
|
624921
625028
|
}).join("\n") + "\n\nUse the todo_write tool to update this list as you complete steps. Mark each item completed once you finish it.\n\n" : "";
|
|
@@ -625227,19 +625334,21 @@ ${historyLines}
|
|
|
625227
625334
|
finishInFlightChat(session.id, "completed", content.trim());
|
|
625228
625335
|
} catch {
|
|
625229
625336
|
}
|
|
625230
|
-
|
|
625231
|
-
|
|
625232
|
-
|
|
625233
|
-
|
|
625234
|
-
|
|
625235
|
-
|
|
625236
|
-
|
|
625237
|
-
|
|
625238
|
-
|
|
625239
|
-
|
|
625240
|
-
|
|
625337
|
+
if (chatTodosEnabled) {
|
|
625338
|
+
try {
|
|
625339
|
+
const finalTodos = readTodos(session.id);
|
|
625340
|
+
if (finalTodos.length > 0 && finalTodos.some((t2) => t2.status !== "completed" && t2.status !== "blocked")) {
|
|
625341
|
+
const updated = finalTodos.map((t2) => ({
|
|
625342
|
+
id: t2.id,
|
|
625343
|
+
content: t2.content,
|
|
625344
|
+
status: t2.status === "blocked" ? "blocked" : "completed",
|
|
625345
|
+
parentId: t2.parentId,
|
|
625346
|
+
blocker: t2.blocker
|
|
625347
|
+
}));
|
|
625348
|
+
writeTodos(session.id, updated);
|
|
625349
|
+
}
|
|
625350
|
+
} catch {
|
|
625241
625351
|
}
|
|
625242
|
-
} catch {
|
|
625243
625352
|
}
|
|
625244
625353
|
writeMemoryEpisodes(session.id, chatBody.message, content.trim(), toolCallCount).catch(() => {
|
|
625245
625354
|
});
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.28",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "omnius",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.28",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
package/package.json
CHANGED