agentgui 1.0.241 → 1.0.242
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/package.json +1 -1
- package/static/index.html +170 -19
- package/static/js/client.js +47 -12
- package/static/js/streaming-renderer.js +31 -25
package/package.json
CHANGED
package/static/index.html
CHANGED
|
@@ -1883,33 +1883,15 @@
|
|
|
1883
1883
|
padding: 0.3rem 0.625rem;
|
|
1884
1884
|
font-size: 0.75rem;
|
|
1885
1885
|
line-height: 1.3;
|
|
1886
|
-
cursor:
|
|
1886
|
+
cursor: default;
|
|
1887
1887
|
user-select: none;
|
|
1888
|
-
list-style: none;
|
|
1889
1888
|
}
|
|
1890
1889
|
.tool-result-status::-webkit-details-marker { display: none; }
|
|
1891
1890
|
.tool-result-status::marker { display: none; content: ''; }
|
|
1892
|
-
.tool-result-status::before {
|
|
1893
|
-
content: '\25b6';
|
|
1894
|
-
font-size: 0.5rem;
|
|
1895
|
-
margin-right: 0.125rem;
|
|
1896
|
-
display: inline-block;
|
|
1897
|
-
transition: transform 0.15s;
|
|
1898
|
-
color: #16a34a;
|
|
1899
|
-
flex-shrink: 0;
|
|
1900
|
-
}
|
|
1901
|
-
html.dark .tool-result-status::before { color: #4ade80; }
|
|
1902
|
-
.tool-result-inline[open] > .tool-result-status::before { transform: rotate(90deg); }
|
|
1903
|
-
.tool-result-status:hover { background: #bbf7d0; }
|
|
1904
|
-
html.dark .tool-result-status:hover { background: #14532d; }
|
|
1905
1891
|
.tool-result-inline > .folded-tool-body { border-top: 1px solid #bbf7d0; }
|
|
1906
1892
|
html.dark .tool-result-inline > .folded-tool-body { border-top-color: #166534; }
|
|
1907
1893
|
.tool-result-error { background: #fef2f2; border-top-color: #fecaca; }
|
|
1908
1894
|
html.dark .tool-result-error { background: #1f0a0a; border-top-color: #991b1b; }
|
|
1909
|
-
.tool-result-error > .tool-result-status:hover { background: #fecaca; }
|
|
1910
|
-
html.dark .tool-result-error > .tool-result-status:hover { background: #2d0f0f; }
|
|
1911
|
-
.tool-result-error .tool-result-status::before { color: #dc2626; }
|
|
1912
|
-
html.dark .tool-result-error .tool-result-status::before { color: #f87171; }
|
|
1913
1895
|
.tool-result-error .folded-tool-icon { color: #dc2626; }
|
|
1914
1896
|
html.dark .tool-result-error .folded-tool-icon { color: #f87171; }
|
|
1915
1897
|
.tool-result-error .folded-tool-name { color: #991b1b; }
|
|
@@ -2390,6 +2372,174 @@
|
|
|
2390
2372
|
animation: pulse 1s ease-in-out infinite;
|
|
2391
2373
|
background-color: var(--color-warning) !important;
|
|
2392
2374
|
}
|
|
2375
|
+
|
|
2376
|
+
/* ===== IN-UI DIALOGS ===== */
|
|
2377
|
+
.dialog-overlay {
|
|
2378
|
+
position: fixed;
|
|
2379
|
+
top: 0;
|
|
2380
|
+
left: 0;
|
|
2381
|
+
right: 0;
|
|
2382
|
+
bottom: 0;
|
|
2383
|
+
z-index: 10000;
|
|
2384
|
+
display: flex;
|
|
2385
|
+
align-items: center;
|
|
2386
|
+
justify-content: center;
|
|
2387
|
+
opacity: 0;
|
|
2388
|
+
transition: opacity 0.2s ease;
|
|
2389
|
+
}
|
|
2390
|
+
.dialog-overlay.visible { opacity: 1; }
|
|
2391
|
+
.dialog-backdrop {
|
|
2392
|
+
position: absolute;
|
|
2393
|
+
top: 0;
|
|
2394
|
+
left: 0;
|
|
2395
|
+
right: 0;
|
|
2396
|
+
bottom: 0;
|
|
2397
|
+
background: rgba(0, 0, 0, 0.5);
|
|
2398
|
+
backdrop-filter: blur(2px);
|
|
2399
|
+
}
|
|
2400
|
+
.dialog-container {
|
|
2401
|
+
position: fixed;
|
|
2402
|
+
top: 0;
|
|
2403
|
+
left: 0;
|
|
2404
|
+
right: 0;
|
|
2405
|
+
bottom: 0;
|
|
2406
|
+
display: flex;
|
|
2407
|
+
align-items: center;
|
|
2408
|
+
justify-content: center;
|
|
2409
|
+
z-index: 10001;
|
|
2410
|
+
opacity: 0;
|
|
2411
|
+
transition: opacity 0.2s ease;
|
|
2412
|
+
}
|
|
2413
|
+
.dialog-container.visible { opacity: 1; }
|
|
2414
|
+
.dialog-box {
|
|
2415
|
+
background: var(--color-bg-primary);
|
|
2416
|
+
border-radius: 0.75rem;
|
|
2417
|
+
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
|
2418
|
+
max-width: 90vw;
|
|
2419
|
+
width: 400px;
|
|
2420
|
+
overflow: hidden;
|
|
2421
|
+
transform: scale(0.95) translateY(-10px);
|
|
2422
|
+
transition: transform 0.2s ease;
|
|
2423
|
+
}
|
|
2424
|
+
.dialog-container.visible .dialog-box {
|
|
2425
|
+
transform: scale(1) translateY(0);
|
|
2426
|
+
}
|
|
2427
|
+
.dialog-box-progress { width: 450px; }
|
|
2428
|
+
.dialog-header {
|
|
2429
|
+
padding: 1rem 1.25rem;
|
|
2430
|
+
border-bottom: 1px solid var(--color-border);
|
|
2431
|
+
}
|
|
2432
|
+
.dialog-title {
|
|
2433
|
+
margin: 0;
|
|
2434
|
+
font-size: 1.1rem;
|
|
2435
|
+
font-weight: 600;
|
|
2436
|
+
}
|
|
2437
|
+
.dialog-body {
|
|
2438
|
+
padding: 1.25rem;
|
|
2439
|
+
}
|
|
2440
|
+
.dialog-message {
|
|
2441
|
+
margin: 0;
|
|
2442
|
+
font-size: 0.9rem;
|
|
2443
|
+
line-height: 1.5;
|
|
2444
|
+
color: var(--color-text-primary);
|
|
2445
|
+
}
|
|
2446
|
+
.dialog-label {
|
|
2447
|
+
display: block;
|
|
2448
|
+
margin-bottom: 0.5rem;
|
|
2449
|
+
font-size: 0.9rem;
|
|
2450
|
+
color: var(--color-text-primary);
|
|
2451
|
+
}
|
|
2452
|
+
.dialog-input {
|
|
2453
|
+
width: 100%;
|
|
2454
|
+
padding: 0.625rem 0.875rem;
|
|
2455
|
+
border: 1px solid var(--color-border);
|
|
2456
|
+
border-radius: 0.5rem;
|
|
2457
|
+
background: var(--color-bg-secondary);
|
|
2458
|
+
color: var(--color-text-primary);
|
|
2459
|
+
font-size: 0.9rem;
|
|
2460
|
+
outline: none;
|
|
2461
|
+
transition: border-color 0.15s, box-shadow 0.15s;
|
|
2462
|
+
}
|
|
2463
|
+
.dialog-input:focus {
|
|
2464
|
+
border-color: var(--color-primary);
|
|
2465
|
+
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);
|
|
2466
|
+
}
|
|
2467
|
+
.dialog-footer {
|
|
2468
|
+
padding: 0.75rem 1.25rem;
|
|
2469
|
+
display: flex;
|
|
2470
|
+
justify-content: flex-end;
|
|
2471
|
+
gap: 0.5rem;
|
|
2472
|
+
border-top: 1px solid var(--color-border);
|
|
2473
|
+
background: var(--color-bg-secondary);
|
|
2474
|
+
}
|
|
2475
|
+
.dialog-btn {
|
|
2476
|
+
padding: 0.5rem 1.25rem;
|
|
2477
|
+
border: none;
|
|
2478
|
+
border-radius: 0.5rem;
|
|
2479
|
+
font-size: 0.875rem;
|
|
2480
|
+
font-weight: 500;
|
|
2481
|
+
cursor: pointer;
|
|
2482
|
+
transition: all 0.15s;
|
|
2483
|
+
}
|
|
2484
|
+
.dialog-btn-primary {
|
|
2485
|
+
background: var(--color-primary);
|
|
2486
|
+
color: white;
|
|
2487
|
+
}
|
|
2488
|
+
.dialog-btn-primary:hover { background: var(--color-primary-dark); }
|
|
2489
|
+
.dialog-btn-secondary {
|
|
2490
|
+
background: var(--color-bg-primary);
|
|
2491
|
+
color: var(--color-text-primary);
|
|
2492
|
+
border: 1px solid var(--color-border);
|
|
2493
|
+
}
|
|
2494
|
+
.dialog-btn-secondary:hover { background: var(--color-bg-secondary); }
|
|
2495
|
+
.dialog-btn-danger { background: var(--color-error); }
|
|
2496
|
+
.dialog-btn-danger:hover { background: #dc2626; }
|
|
2497
|
+
.dialog-progress-bar {
|
|
2498
|
+
height: 8px;
|
|
2499
|
+
background: var(--color-bg-secondary);
|
|
2500
|
+
border-radius: 4px;
|
|
2501
|
+
overflow: hidden;
|
|
2502
|
+
margin: 1rem 0 0.5rem;
|
|
2503
|
+
}
|
|
2504
|
+
.dialog-progress-fill {
|
|
2505
|
+
height: 100%;
|
|
2506
|
+
background: var(--color-primary);
|
|
2507
|
+
border-radius: 4px;
|
|
2508
|
+
transition: width 0.3s ease;
|
|
2509
|
+
}
|
|
2510
|
+
.dialog-progress-percent {
|
|
2511
|
+
margin: 0;
|
|
2512
|
+
text-align: center;
|
|
2513
|
+
font-size: 0.8rem;
|
|
2514
|
+
color: var(--color-text-secondary);
|
|
2515
|
+
}
|
|
2516
|
+
|
|
2517
|
+
/* ===== TOAST NOTIFICATIONS ===== */
|
|
2518
|
+
.toast-notification {
|
|
2519
|
+
position: fixed;
|
|
2520
|
+
bottom: 100px;
|
|
2521
|
+
left: 50%;
|
|
2522
|
+
transform: translateX(-50%) translateY(20px);
|
|
2523
|
+
padding: 0.75rem 1.5rem;
|
|
2524
|
+
border-radius: 0.5rem;
|
|
2525
|
+
font-size: 0.875rem;
|
|
2526
|
+
font-weight: 500;
|
|
2527
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
2528
|
+
z-index: 20000;
|
|
2529
|
+
opacity: 0;
|
|
2530
|
+
transition: all 0.3s ease;
|
|
2531
|
+
display: flex;
|
|
2532
|
+
align-items: center;
|
|
2533
|
+
gap: 0.5rem;
|
|
2534
|
+
}
|
|
2535
|
+
.toast-notification.visible {
|
|
2536
|
+
opacity: 1;
|
|
2537
|
+
transform: translateX(-50%) translateY(0);
|
|
2538
|
+
}
|
|
2539
|
+
.toast-info { background: var(--color-primary); color: white; }
|
|
2540
|
+
.toast-success { background: var(--color-success); color: white; }
|
|
2541
|
+
.toast-error { background: var(--color-error); color: white; }
|
|
2542
|
+
.toast-warning { background: var(--color-warning); color: white; }
|
|
2393
2543
|
</style>
|
|
2394
2544
|
</head>
|
|
2395
2545
|
<body>
|
|
@@ -2597,6 +2747,7 @@
|
|
|
2597
2747
|
<script defer src="/gm/js/websocket-manager.js"></script>
|
|
2598
2748
|
<script defer src="/gm/js/event-filter.js"></script>
|
|
2599
2749
|
<script defer src="/gm/js/syntax-highlighter.js"></script>
|
|
2750
|
+
<script defer src="/gm/js/dialogs.js"></script>
|
|
2600
2751
|
<script defer src="/gm/js/ui-components.js"></script>
|
|
2601
2752
|
<script defer src="/gm/js/conversations.js"></script>
|
|
2602
2753
|
<script defer src="/gm/js/client.js"></script>
|
package/static/js/client.js
CHANGED
|
@@ -282,10 +282,12 @@ class AgentGUIClient {
|
|
|
282
282
|
|
|
283
283
|
try {
|
|
284
284
|
const position = localStorage.getItem(`scroll_${conversationId}`);
|
|
285
|
+
const scrollContainer = document.getElementById(this.config.scrollContainerId);
|
|
286
|
+
if (!scrollContainer) return;
|
|
287
|
+
|
|
285
288
|
if (position !== null) {
|
|
286
289
|
const scrollTop = parseInt(position, 10);
|
|
287
|
-
|
|
288
|
-
if (scrollContainer && !isNaN(scrollTop)) {
|
|
290
|
+
if (!isNaN(scrollTop)) {
|
|
289
291
|
requestAnimationFrame(() => {
|
|
290
292
|
requestAnimationFrame(() => {
|
|
291
293
|
const maxScroll = scrollContainer.scrollHeight - scrollContainer.clientHeight;
|
|
@@ -293,6 +295,12 @@ class AgentGUIClient {
|
|
|
293
295
|
});
|
|
294
296
|
});
|
|
295
297
|
}
|
|
298
|
+
} else {
|
|
299
|
+
requestAnimationFrame(() => {
|
|
300
|
+
requestAnimationFrame(() => {
|
|
301
|
+
scrollContainer.scrollTop = 0;
|
|
302
|
+
});
|
|
303
|
+
});
|
|
296
304
|
}
|
|
297
305
|
} catch (e) {
|
|
298
306
|
console.warn('Failed to restore scroll position:', e);
|
|
@@ -368,7 +376,7 @@ class AgentGUIClient {
|
|
|
368
376
|
if (this.ui.injectButton) {
|
|
369
377
|
this.ui.injectButton.addEventListener('click', async () => {
|
|
370
378
|
if (!this.state.currentConversation) return;
|
|
371
|
-
const instructions = prompt('Enter instructions to inject into the running agent:');
|
|
379
|
+
const instructions = await window.UIDialog.prompt('Enter instructions to inject into the running agent:', '', 'Inject Instructions');
|
|
372
380
|
if (!instructions) return;
|
|
373
381
|
try {
|
|
374
382
|
const resp = await fetch(`${window.__BASE_URL}/api/conversations/${this.state.currentConversation.id}/inject`, {
|
|
@@ -981,17 +989,17 @@ class AgentGUIClient {
|
|
|
981
989
|
btn.addEventListener('click', async (e) => {
|
|
982
990
|
const index = parseInt(e.target.dataset.index);
|
|
983
991
|
const msgId = queue[index].messageId;
|
|
984
|
-
if (confirm('Delete this queued message?')) {
|
|
992
|
+
if (await window.UIDialog.confirm('Delete this queued message?', 'Delete Message')) {
|
|
985
993
|
await fetch(window.__BASE_URL + `/api/conversations/${conversationId}/queue/${msgId}`, { method: 'DELETE' });
|
|
986
994
|
}
|
|
987
995
|
});
|
|
988
996
|
});
|
|
989
997
|
|
|
990
998
|
queueEl.querySelectorAll('.queue-edit-btn').forEach(btn => {
|
|
991
|
-
btn.addEventListener('click', (e) => {
|
|
999
|
+
btn.addEventListener('click', async (e) => {
|
|
992
1000
|
const index = parseInt(e.target.dataset.index);
|
|
993
1001
|
const q = queue[index];
|
|
994
|
-
const newContent = prompt('Edit message:', q.content);
|
|
1002
|
+
const newContent = await window.UIDialog.prompt('Edit message:', q.content, 'Edit Queued Message');
|
|
995
1003
|
if (newContent !== null && newContent !== q.content) {
|
|
996
1004
|
fetch(window.__BASE_URL + `/api/conversations/${conversationId}/queue/${q.messageId}`, {
|
|
997
1005
|
method: 'PATCH',
|
|
@@ -1176,7 +1184,8 @@ class AgentGUIClient {
|
|
|
1176
1184
|
const dName = hasRenderer ? StreamingRenderer.getToolDisplayName(tn) : tn;
|
|
1177
1185
|
const tTitle = hasRenderer && block.input ? StreamingRenderer.getToolTitle(tn, block.input) : '';
|
|
1178
1186
|
const iconHtml = hasRenderer && this.renderer ? `<span class="folded-tool-icon">${this.renderer.getToolIcon(tn)}</span>` : '';
|
|
1179
|
-
|
|
1187
|
+
const colorIdx = hasRenderer && this.renderer ? this.renderer._getBlockColorIndex('tool_use') : 1;
|
|
1188
|
+
html += `<details class="block-tool-use folded-tool" open style="border-left:3px solid var(--block-color-${colorIdx})"><summary class="folded-tool-bar">${iconHtml}<span class="folded-tool-name">${this.escapeHtml(dName)}</span>${tTitle ? `<span class="folded-tool-desc">${this.escapeHtml(tTitle)}</span>` : ''}</summary>${inputHtml}`;
|
|
1180
1189
|
pendingToolUseClose = true;
|
|
1181
1190
|
} else if (block.type === 'tool_result') {
|
|
1182
1191
|
const content = typeof block.content === 'string' ? block.content : JSON.stringify(block.content);
|
|
@@ -1185,7 +1194,8 @@ class AgentGUIClient {
|
|
|
1185
1194
|
const resultIcon = block.is_error
|
|
1186
1195
|
? '<svg viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/></svg>'
|
|
1187
1196
|
: '<svg viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/></svg>';
|
|
1188
|
-
const
|
|
1197
|
+
const colorIdx = hasRenderer && this.renderer ? this.renderer._getBlockColorIndex('tool_result') : 2;
|
|
1198
|
+
const resultHtml = `<div class="tool-result-inline${block.is_error ? ' tool-result-error' : ''}" style="border-left:3px solid var(--block-color-${colorIdx})"><div class="tool-result-status"><span class="folded-tool-icon">${resultIcon}</span><span class="folded-tool-name">${block.is_error ? 'Error' : 'Success'}</span><span class="folded-tool-desc">${this.escapeHtml(resultPreview)}</span></div><div class="folded-tool-body">${smartHtml}</div></div>`;
|
|
1189
1199
|
if (pendingToolUseClose) {
|
|
1190
1200
|
html += resultHtml + '</details>';
|
|
1191
1201
|
pendingToolUseClose = false;
|
|
@@ -1996,6 +2006,13 @@ class AgentGUIClient {
|
|
|
1996
2006
|
this._modelDownloadInProgress = false;
|
|
1997
2007
|
console.error('[Models] Download error:', progress.error);
|
|
1998
2008
|
this._updateConnectionIndicator(this.wsManager?.latency?.quality || 'unknown');
|
|
2009
|
+
if (window._voiceProgressDialog) {
|
|
2010
|
+
window._voiceProgressDialog.close();
|
|
2011
|
+
window._voiceProgressDialog = null;
|
|
2012
|
+
}
|
|
2013
|
+
if (window.UIDialog) {
|
|
2014
|
+
window.UIDialog.alert('Failed to download voice models: ' + progress.error, 'Download Error');
|
|
2015
|
+
}
|
|
1999
2016
|
return;
|
|
2000
2017
|
}
|
|
2001
2018
|
|
|
@@ -2004,12 +2021,30 @@ class AgentGUIClient {
|
|
|
2004
2021
|
console.log('[Models] Download complete');
|
|
2005
2022
|
this._updateConnectionIndicator(this.wsManager?.latency?.quality || 'unknown');
|
|
2006
2023
|
this._updateVoiceTabState();
|
|
2024
|
+
if (window._voiceProgressDialog) {
|
|
2025
|
+
window._voiceProgressDialog.update(100, 'Voice models ready!');
|
|
2026
|
+
setTimeout(function() {
|
|
2027
|
+
if (window._voiceProgressDialog) {
|
|
2028
|
+
window._voiceProgressDialog.close();
|
|
2029
|
+
window._voiceProgressDialog = null;
|
|
2030
|
+
}
|
|
2031
|
+
}, 500);
|
|
2032
|
+
}
|
|
2007
2033
|
return;
|
|
2008
2034
|
}
|
|
2009
2035
|
|
|
2010
2036
|
if (progress.started || progress.downloading) {
|
|
2011
2037
|
this._modelDownloadInProgress = true;
|
|
2012
2038
|
this._updateConnectionIndicator(this.wsManager?.latency?.quality || 'unknown');
|
|
2039
|
+
|
|
2040
|
+
if (window._voiceProgressDialog && progress.totalBytes > 0) {
|
|
2041
|
+
var pct = Math.round((progress.totalDownloaded / progress.totalBytes) * 100);
|
|
2042
|
+
var mb = Math.round(progress.totalBytes / 1024 / 1024);
|
|
2043
|
+
var downloaded = Math.round((progress.totalDownloaded || 0) / 1024 / 1024);
|
|
2044
|
+
window._voiceProgressDialog.update(pct, 'Downloading ' + downloaded + 'MB / ' + mb + 'MB');
|
|
2045
|
+
} else if (window._voiceProgressDialog && progress.file) {
|
|
2046
|
+
window._voiceProgressDialog.update(0, 'Loading ' + progress.file + '...');
|
|
2047
|
+
}
|
|
2013
2048
|
}
|
|
2014
2049
|
}
|
|
2015
2050
|
|
|
@@ -2018,8 +2053,7 @@ class AgentGUIClient {
|
|
|
2018
2053
|
if (voiceBtn) {
|
|
2019
2054
|
var isReady = this._modelDownloadProgress?.done === true ||
|
|
2020
2055
|
this._modelDownloadProgress?.complete === true;
|
|
2021
|
-
voiceBtn.
|
|
2022
|
-
voiceBtn.title = isReady ? 'Voice' : 'Downloading voice models...';
|
|
2056
|
+
voiceBtn.title = isReady ? 'Voice' : 'Voice (click to download models)';
|
|
2023
2057
|
}
|
|
2024
2058
|
}
|
|
2025
2059
|
|
|
@@ -2438,8 +2472,9 @@ class AgentGUIClient {
|
|
|
2438
2472
|
*/
|
|
2439
2473
|
showError(message) {
|
|
2440
2474
|
console.error(message);
|
|
2441
|
-
|
|
2442
|
-
|
|
2475
|
+
if (window.UIDialog) {
|
|
2476
|
+
window.UIDialog.alert(message, 'Error');
|
|
2477
|
+
}
|
|
2443
2478
|
}
|
|
2444
2479
|
|
|
2445
2480
|
/**
|
|
@@ -399,23 +399,25 @@ class StreamingRenderer {
|
|
|
399
399
|
div.className = 'block-text';
|
|
400
400
|
if (isHtml) div.classList.add('html-content');
|
|
401
401
|
div.innerHTML = html;
|
|
402
|
-
const colorIndex = this.
|
|
402
|
+
const colorIndex = this._getBlockColorIndex('text');
|
|
403
403
|
div.style.borderLeft = `3px solid var(--block-color-${colorIndex})`;
|
|
404
404
|
return div;
|
|
405
405
|
}
|
|
406
406
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
407
|
+
_getBlockColorIndex(blockType) {
|
|
408
|
+
const typeColors = {
|
|
409
|
+
'text': 0,
|
|
410
|
+
'tool_use': 1,
|
|
411
|
+
'tool_result': 2,
|
|
412
|
+
'code': 3,
|
|
413
|
+
'thinking': 4,
|
|
414
|
+
'bash': 5,
|
|
415
|
+
'system': 6,
|
|
416
|
+
'result': 7,
|
|
417
|
+
'error': 8,
|
|
418
|
+
'image': 9
|
|
419
|
+
};
|
|
420
|
+
return typeColors[blockType] !== undefined ? typeColors[blockType] : 0;
|
|
419
421
|
}
|
|
420
422
|
|
|
421
423
|
containsHtmlTags(text) {
|
|
@@ -733,7 +735,10 @@ class StreamingRenderer {
|
|
|
733
735
|
|
|
734
736
|
const details = document.createElement('details');
|
|
735
737
|
details.className = 'block-tool-use folded-tool';
|
|
738
|
+
details.setAttribute('open', '');
|
|
736
739
|
if (block.id) details.dataset.toolUseId = block.id;
|
|
740
|
+
const colorIndex = this._getBlockColorIndex('tool_use');
|
|
741
|
+
details.style.borderLeft = `3px solid var(--block-color-${colorIndex})`;
|
|
737
742
|
const summary = document.createElement('summary');
|
|
738
743
|
summary.className = 'folded-tool-bar';
|
|
739
744
|
const displayName = this.getToolUseDisplayName(toolName);
|
|
@@ -1199,33 +1204,34 @@ class StreamingRenderer {
|
|
|
1199
1204
|
const isError = block.is_error || false;
|
|
1200
1205
|
const content = block.content || '';
|
|
1201
1206
|
const contentStr = typeof content === 'string' ? content : JSON.stringify(content, null, 2);
|
|
1202
|
-
const preview = contentStr.length > 80 ? contentStr.substring(0, 77).replace(/\n/g, ' ') + '...' : contentStr.replace(/\n/g, ' ');
|
|
1203
1207
|
|
|
1204
|
-
const
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
if (block.tool_use_id)
|
|
1208
|
+
const wrapper = document.createElement('div');
|
|
1209
|
+
wrapper.className = 'tool-result-inline' + (isError ? ' tool-result-error' : '');
|
|
1210
|
+
wrapper.dataset.eventType = 'tool_result';
|
|
1211
|
+
if (block.tool_use_id) wrapper.dataset.toolUseId = block.tool_use_id;
|
|
1212
|
+
const colorIndex = this._getBlockColorIndex('tool_result');
|
|
1213
|
+
wrapper.style.borderLeft = `3px solid var(--block-color-${colorIndex})`;
|
|
1208
1214
|
|
|
1215
|
+
const header = document.createElement('div');
|
|
1216
|
+
header.className = 'tool-result-status';
|
|
1209
1217
|
const iconSvg = isError
|
|
1210
1218
|
? '<svg viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/></svg>'
|
|
1211
1219
|
: '<svg viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/></svg>';
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
summary.className = 'tool-result-status';
|
|
1215
|
-
summary.innerHTML = `
|
|
1220
|
+
const preview = contentStr.length > 80 ? contentStr.substring(0, 77).replace(/\n/g, ' ') + '...' : contentStr.replace(/\n/g, ' ');
|
|
1221
|
+
header.innerHTML = `
|
|
1216
1222
|
<span class="folded-tool-icon">${iconSvg}</span>
|
|
1217
1223
|
<span class="folded-tool-name">${isError ? 'Error' : 'Success'}</span>
|
|
1218
1224
|
<span class="folded-tool-desc">${this.escapeHtml(preview)}</span>
|
|
1219
1225
|
`;
|
|
1220
|
-
|
|
1226
|
+
wrapper.appendChild(header);
|
|
1221
1227
|
|
|
1222
1228
|
const renderedContent = StreamingRenderer.renderSmartContentHTML(contentStr, this.escapeHtml.bind(this));
|
|
1223
1229
|
const body = document.createElement('div');
|
|
1224
1230
|
body.className = 'folded-tool-body';
|
|
1225
1231
|
body.innerHTML = renderedContent;
|
|
1226
|
-
|
|
1232
|
+
wrapper.appendChild(body);
|
|
1227
1233
|
|
|
1228
|
-
return
|
|
1234
|
+
return wrapper;
|
|
1229
1235
|
}
|
|
1230
1236
|
|
|
1231
1237
|
/**
|