agentgui 1.0.158 → 1.0.160
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 +28 -7
- package/static/js/client.js +8 -4
- package/static/js/streaming-renderer.js +73 -49
package/package.json
CHANGED
package/static/index.html
CHANGED
|
@@ -1586,6 +1586,34 @@
|
|
|
1586
1586
|
.folded-tool-error > .folded-tool-body { border-top-color: #fecaca; }
|
|
1587
1587
|
html.dark .folded-tool-error > .folded-tool-body { border-top-color: #7f1d1d; }
|
|
1588
1588
|
|
|
1589
|
+
/* --- Info variant of folded-tool (system blocks) --- */
|
|
1590
|
+
.folded-tool.folded-tool-info {
|
|
1591
|
+
background: #eef2ff;
|
|
1592
|
+
border-color: #c7d2fe;
|
|
1593
|
+
}
|
|
1594
|
+
html.dark .folded-tool.folded-tool-info {
|
|
1595
|
+
background: #15103a;
|
|
1596
|
+
border-color: #3730a3;
|
|
1597
|
+
}
|
|
1598
|
+
.folded-tool-info > .folded-tool-bar {
|
|
1599
|
+
background: #e0e7ff;
|
|
1600
|
+
}
|
|
1601
|
+
html.dark .folded-tool-info > .folded-tool-bar {
|
|
1602
|
+
background: #1e1b4b;
|
|
1603
|
+
}
|
|
1604
|
+
.folded-tool-info > .folded-tool-bar::before { color: #6366f1; }
|
|
1605
|
+
html.dark .folded-tool-info > .folded-tool-bar::before { color: #a5b4fc; }
|
|
1606
|
+
.folded-tool-info > .folded-tool-bar:hover { background: #c7d2fe; }
|
|
1607
|
+
html.dark .folded-tool-info > .folded-tool-bar:hover { background: #312e81; }
|
|
1608
|
+
.folded-tool-info .folded-tool-icon { color: #6366f1; }
|
|
1609
|
+
html.dark .folded-tool-info .folded-tool-icon { color: #a5b4fc; }
|
|
1610
|
+
.folded-tool-info .folded-tool-name { color: #3730a3; }
|
|
1611
|
+
html.dark .folded-tool-info .folded-tool-name { color: #c7d2fe; }
|
|
1612
|
+
.folded-tool-info .folded-tool-desc { color: #4f46e5; }
|
|
1613
|
+
html.dark .folded-tool-info .folded-tool-desc { color: #a5b4fc; }
|
|
1614
|
+
.folded-tool-info > .folded-tool-body { border-top-color: #c7d2fe; }
|
|
1615
|
+
html.dark .folded-tool-info > .folded-tool-body { border-top-color: #3730a3; }
|
|
1616
|
+
|
|
1589
1617
|
/* --- Collapsible Code Summary --- */
|
|
1590
1618
|
.collapsible-code {
|
|
1591
1619
|
margin: 0.25rem 0;
|
|
@@ -1695,13 +1723,6 @@
|
|
|
1695
1723
|
html.dark .block-tool-result.result-success .result-body { color: #bbf7d0; }
|
|
1696
1724
|
html.dark .block-tool-result.result-error .result-body { color: #fecaca; }
|
|
1697
1725
|
|
|
1698
|
-
.result-collapsible { margin: 0; }
|
|
1699
|
-
.result-collapsible > summary { list-style: none; }
|
|
1700
|
-
.result-collapsible > summary::-webkit-details-marker { display: none; }
|
|
1701
|
-
.result-collapsible > summary::marker { display: none; content: ''; }
|
|
1702
|
-
.result-collapsible > summary .status-label::before { content: '\25b6'; font-size: 0.6rem; margin-right: 0.375rem; display: inline-block; transition: transform 0.15s; }
|
|
1703
|
-
.result-collapsible[open] > summary .status-label::before { transform: rotate(90deg); }
|
|
1704
|
-
|
|
1705
1726
|
.block-tool-result .result-body.collapsed { max-height: 150px; position: relative; }
|
|
1706
1727
|
.block-tool-result .result-body.collapsed::after {
|
|
1707
1728
|
content: '';
|
package/static/js/client.js
CHANGED
|
@@ -60,13 +60,13 @@ class AgentGUIClient {
|
|
|
60
60
|
this.setupWebSocketListeners();
|
|
61
61
|
this.setupRendererListeners();
|
|
62
62
|
|
|
63
|
+
// Setup UI elements (must happen before loading data so DOM refs exist)
|
|
64
|
+
this.setupUI();
|
|
65
|
+
|
|
63
66
|
// Load initial data
|
|
64
67
|
await this.loadAgents();
|
|
65
68
|
await this.loadConversations();
|
|
66
69
|
|
|
67
|
-
// Setup UI elements
|
|
68
|
-
this.setupUI();
|
|
69
|
-
|
|
70
70
|
// Enable controls for initial interaction
|
|
71
71
|
this.enableControls();
|
|
72
72
|
|
|
@@ -877,7 +877,11 @@ class AgentGUIClient {
|
|
|
877
877
|
} else if (block.type === 'tool_result') {
|
|
878
878
|
const content = typeof block.content === 'string' ? block.content : JSON.stringify(block.content);
|
|
879
879
|
const smartHtml = typeof StreamingRenderer !== 'undefined' ? StreamingRenderer.renderSmartContentHTML(content, this.escapeHtml.bind(this)) : `<pre class="tool-result-pre">${this.escapeHtml(content.length > 2000 ? content.substring(0, 2000) + '\n... (truncated)' : content)}</pre>`;
|
|
880
|
-
|
|
880
|
+
const resultPreview = content.length > 80 ? content.substring(0, 77).replace(/\n/g, ' ') + '...' : content.replace(/\n/g, ' ');
|
|
881
|
+
const resultIcon = block.is_error
|
|
882
|
+
? '<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>'
|
|
883
|
+
: '<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>';
|
|
884
|
+
html += `<details class="folded-tool${block.is_error ? ' folded-tool-error' : ''}"><summary class="folded-tool-bar"><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></summary><div class="folded-tool-body">${smartHtml}</div></details>`;
|
|
881
885
|
}
|
|
882
886
|
});
|
|
883
887
|
}
|
|
@@ -1157,41 +1157,35 @@ class StreamingRenderer {
|
|
|
1157
1157
|
* Render tool result block with smart content display
|
|
1158
1158
|
*/
|
|
1159
1159
|
renderBlockToolResult(block, context) {
|
|
1160
|
-
const div = document.createElement('div');
|
|
1161
1160
|
const isError = block.is_error || false;
|
|
1162
|
-
div.className = `block-tool-result ${isError ? 'result-error' : 'result-success'}`;
|
|
1163
|
-
|
|
1164
1161
|
const content = block.content || '';
|
|
1165
1162
|
const contentStr = typeof content === 'string' ? content : JSON.stringify(content, null, 2);
|
|
1166
|
-
const
|
|
1163
|
+
const preview = contentStr.length > 80 ? contentStr.substring(0, 77).replace(/\n/g, ' ') + '...' : contentStr.replace(/\n/g, ' ');
|
|
1164
|
+
|
|
1165
|
+
const details = document.createElement('details');
|
|
1166
|
+
details.className = isError ? 'folded-tool folded-tool-error' : 'folded-tool';
|
|
1167
|
+
details.dataset.eventType = 'tool_result';
|
|
1167
1168
|
|
|
1168
1169
|
const iconSvg = isError
|
|
1169
1170
|
? '<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>'
|
|
1170
1171
|
: '<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>';
|
|
1171
1172
|
|
|
1172
|
-
const
|
|
1173
|
+
const summary = document.createElement('summary');
|
|
1174
|
+
summary.className = 'folded-tool-bar';
|
|
1175
|
+
summary.innerHTML = `
|
|
1176
|
+
<span class="folded-tool-icon">${iconSvg}</span>
|
|
1177
|
+
<span class="folded-tool-name">${isError ? 'Error' : 'Success'}</span>
|
|
1178
|
+
<span class="folded-tool-desc">${this.escapeHtml(preview)}</span>
|
|
1179
|
+
`;
|
|
1180
|
+
details.appendChild(summary);
|
|
1173
1181
|
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
</div>
|
|
1180
|
-
${renderedContent}
|
|
1181
|
-
`;
|
|
1182
|
-
} else {
|
|
1183
|
-
div.innerHTML = `
|
|
1184
|
-
<details class="result-collapsible">
|
|
1185
|
-
<summary class="result-header" style="cursor:pointer;list-style:none;user-select:none">
|
|
1186
|
-
<span class="status-label">${iconSvg} Success</span>
|
|
1187
|
-
${toolUseId ? `<span class="result-id">${this.escapeHtml(toolUseId)}</span>` : ''}
|
|
1188
|
-
</summary>
|
|
1189
|
-
<div class="result-collapsible-body">${renderedContent}</div>
|
|
1190
|
-
</details>
|
|
1191
|
-
`;
|
|
1192
|
-
}
|
|
1182
|
+
const renderedContent = StreamingRenderer.renderSmartContentHTML(contentStr, this.escapeHtml.bind(this));
|
|
1183
|
+
const body = document.createElement('div');
|
|
1184
|
+
body.className = 'folded-tool-body';
|
|
1185
|
+
body.innerHTML = renderedContent;
|
|
1186
|
+
details.appendChild(body);
|
|
1193
1187
|
|
|
1194
|
-
return
|
|
1188
|
+
return details;
|
|
1195
1189
|
}
|
|
1196
1190
|
|
|
1197
1191
|
/**
|
|
@@ -1247,11 +1241,21 @@ class StreamingRenderer {
|
|
|
1247
1241
|
* Render system event
|
|
1248
1242
|
*/
|
|
1249
1243
|
renderBlockSystem(block, context) {
|
|
1250
|
-
const
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1244
|
+
const details = document.createElement('details');
|
|
1245
|
+
details.className = 'folded-tool folded-tool-info';
|
|
1246
|
+
details.dataset.eventType = 'system';
|
|
1247
|
+
const desc = block.model ? this.escapeHtml(block.model) : 'Session';
|
|
1248
|
+
const summary = document.createElement('summary');
|
|
1249
|
+
summary.className = 'folded-tool-bar';
|
|
1250
|
+
summary.innerHTML = `
|
|
1251
|
+
<span class="folded-tool-icon"><svg viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd"/></svg></span>
|
|
1252
|
+
<span class="folded-tool-name">Session</span>
|
|
1253
|
+
<span class="folded-tool-desc">${desc}</span>
|
|
1254
|
+
`;
|
|
1255
|
+
details.appendChild(summary);
|
|
1256
|
+
const body = document.createElement('div');
|
|
1257
|
+
body.className = 'folded-tool-body block-system';
|
|
1258
|
+
body.innerHTML = `
|
|
1255
1259
|
<div class="system-body">
|
|
1256
1260
|
${block.model ? `<div class="sys-field"><span class="sys-label">Model</span><span class="sys-value"><code>${this.escapeHtml(block.model)}</code></span></div>` : ''}
|
|
1257
1261
|
${block.cwd ? `<div class="sys-field"><span class="sys-label">Directory</span><span class="sys-value"><code>${this.escapeHtml(block.cwd)}</code></span></div>` : ''}
|
|
@@ -1259,38 +1263,58 @@ class StreamingRenderer {
|
|
|
1259
1263
|
${block.tools && Array.isArray(block.tools) ? `<div class="sys-field" style="flex-direction:column;gap:0.375rem"><span class="sys-label">Tools (${block.tools.length})</span><div class="tools-list">${block.tools.map(t => `<span class="tool-badge">${this.escapeHtml(t)}</span>`).join('')}</div></div>` : ''}
|
|
1260
1264
|
</div>
|
|
1261
1265
|
`;
|
|
1262
|
-
|
|
1263
|
-
return
|
|
1266
|
+
details.appendChild(body);
|
|
1267
|
+
return details;
|
|
1264
1268
|
}
|
|
1265
1269
|
|
|
1266
1270
|
/**
|
|
1267
1271
|
* Render result block (execution summary)
|
|
1268
1272
|
*/
|
|
1269
1273
|
renderBlockResult(block, context) {
|
|
1270
|
-
const div = document.createElement('div');
|
|
1271
1274
|
const isError = block.is_error || false;
|
|
1272
|
-
div.className = `block-result ${isError ? 'result-err' : 'result-ok'}`;
|
|
1273
|
-
|
|
1274
1275
|
const duration = block.duration_ms ? (block.duration_ms / 1000).toFixed(1) + 's' : '';
|
|
1275
1276
|
const cost = block.total_cost_usd ? '$' + block.total_cost_usd.toFixed(4) : '';
|
|
1276
1277
|
const turns = block.num_turns || '';
|
|
1278
|
+
const statsDesc = [duration, cost, turns ? turns + ' turns' : ''].filter(Boolean).join(' / ');
|
|
1277
1279
|
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
</
|
|
1290
|
-
|
|
1280
|
+
const details = document.createElement('details');
|
|
1281
|
+
details.className = isError ? 'folded-tool folded-tool-error' : 'folded-tool';
|
|
1282
|
+
details.dataset.eventType = 'result';
|
|
1283
|
+
|
|
1284
|
+
const iconSvg = isError
|
|
1285
|
+
? '<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>'
|
|
1286
|
+
: '<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>';
|
|
1287
|
+
|
|
1288
|
+
const summary = document.createElement('summary');
|
|
1289
|
+
summary.className = 'folded-tool-bar';
|
|
1290
|
+
summary.innerHTML = `
|
|
1291
|
+
<span class="folded-tool-icon">${iconSvg}</span>
|
|
1292
|
+
<span class="folded-tool-name">${isError ? 'Failed' : 'Complete'}</span>
|
|
1293
|
+
<span class="folded-tool-desc">${this.escapeHtml(statsDesc)}</span>
|
|
1291
1294
|
`;
|
|
1295
|
+
details.appendChild(summary);
|
|
1292
1296
|
|
|
1293
|
-
|
|
1297
|
+
if (block.result || duration || cost || turns) {
|
|
1298
|
+
const body = document.createElement('div');
|
|
1299
|
+
body.className = 'folded-tool-body';
|
|
1300
|
+
let bodyHtml = '';
|
|
1301
|
+
if (duration || cost || turns) {
|
|
1302
|
+
bodyHtml += `<div class="block-result"><div class="result-stats">
|
|
1303
|
+
${duration ? `<div class="result-stat"><span class="stat-icon">⏲</span><span class="stat-value">${this.escapeHtml(duration)}</span><span class="stat-label">duration</span></div>` : ''}
|
|
1304
|
+
${cost ? `<div class="result-stat"><span class="stat-icon">💰</span><span class="stat-value">${this.escapeHtml(cost)}</span><span class="stat-label">cost</span></div>` : ''}
|
|
1305
|
+
${turns ? `<div class="result-stat"><span class="stat-icon">🔄</span><span class="stat-value">${this.escapeHtml(String(turns))}</span><span class="stat-label">turns</span></div>` : ''}
|
|
1306
|
+
</div></div>`;
|
|
1307
|
+
}
|
|
1308
|
+
if (block.result) {
|
|
1309
|
+
const r = typeof block.result === 'string' ? block.result : JSON.stringify(block.result, null, 2);
|
|
1310
|
+
const rendered = this.containsHtmlTags(r) ? '<div class="html-content">' + this.sanitizeHtml(r) + '</div>' : `<div style="font-size:0.8rem;white-space:pre-wrap;word-break:break-word;line-height:1.5">${this.escapeHtml(r)}</div>`;
|
|
1311
|
+
bodyHtml += rendered;
|
|
1312
|
+
}
|
|
1313
|
+
body.innerHTML = bodyHtml;
|
|
1314
|
+
details.appendChild(body);
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
return details;
|
|
1294
1318
|
}
|
|
1295
1319
|
|
|
1296
1320
|
/**
|