agentgui 1.0.163 → 1.0.165
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 +49 -0
- package/static/js/client.js +52 -14
- package/static/js/streaming-renderer.js +5 -3
package/package.json
CHANGED
package/static/index.html
CHANGED
|
@@ -1614,6 +1614,55 @@
|
|
|
1614
1614
|
.folded-tool-info > .folded-tool-body { border-top-color: #c7d2fe; }
|
|
1615
1615
|
html.dark .folded-tool-info > .folded-tool-body { border-top-color: #3730a3; }
|
|
1616
1616
|
|
|
1617
|
+
/* --- Inline Tool Result (nested inside tool_use) --- */
|
|
1618
|
+
.tool-result-inline {
|
|
1619
|
+
border-top: 1px solid #bbf7d0;
|
|
1620
|
+
overflow: hidden;
|
|
1621
|
+
}
|
|
1622
|
+
html.dark .tool-result-inline { border-top-color: #166534; }
|
|
1623
|
+
.tool-result-status {
|
|
1624
|
+
display: flex;
|
|
1625
|
+
align-items: center;
|
|
1626
|
+
gap: 0.375rem;
|
|
1627
|
+
padding: 0.3rem 0.625rem;
|
|
1628
|
+
font-size: 0.75rem;
|
|
1629
|
+
line-height: 1.3;
|
|
1630
|
+
cursor: pointer;
|
|
1631
|
+
user-select: none;
|
|
1632
|
+
list-style: none;
|
|
1633
|
+
}
|
|
1634
|
+
.tool-result-status::-webkit-details-marker { display: none; }
|
|
1635
|
+
.tool-result-status::marker { display: none; content: ''; }
|
|
1636
|
+
.tool-result-status::before {
|
|
1637
|
+
content: '\25b6';
|
|
1638
|
+
font-size: 0.5rem;
|
|
1639
|
+
margin-right: 0.125rem;
|
|
1640
|
+
display: inline-block;
|
|
1641
|
+
transition: transform 0.15s;
|
|
1642
|
+
color: #16a34a;
|
|
1643
|
+
flex-shrink: 0;
|
|
1644
|
+
}
|
|
1645
|
+
html.dark .tool-result-status::before { color: #4ade80; }
|
|
1646
|
+
.tool-result-inline[open] > .tool-result-status::before { transform: rotate(90deg); }
|
|
1647
|
+
.tool-result-status:hover { background: #bbf7d0; }
|
|
1648
|
+
html.dark .tool-result-status:hover { background: #14532d; }
|
|
1649
|
+
.tool-result-inline > .folded-tool-body { border-top: 1px solid #bbf7d0; }
|
|
1650
|
+
html.dark .tool-result-inline > .folded-tool-body { border-top-color: #166534; }
|
|
1651
|
+
.tool-result-error { background: #fef2f2; border-top-color: #fecaca; }
|
|
1652
|
+
html.dark .tool-result-error { background: #1f0a0a; border-top-color: #991b1b; }
|
|
1653
|
+
.tool-result-error > .tool-result-status:hover { background: #fecaca; }
|
|
1654
|
+
html.dark .tool-result-error > .tool-result-status:hover { background: #2d0f0f; }
|
|
1655
|
+
.tool-result-error .tool-result-status::before { color: #dc2626; }
|
|
1656
|
+
html.dark .tool-result-error .tool-result-status::before { color: #f87171; }
|
|
1657
|
+
.tool-result-error .folded-tool-icon { color: #dc2626; }
|
|
1658
|
+
html.dark .tool-result-error .folded-tool-icon { color: #f87171; }
|
|
1659
|
+
.tool-result-error .folded-tool-name { color: #991b1b; }
|
|
1660
|
+
html.dark .tool-result-error .folded-tool-name { color: #fca5a5; }
|
|
1661
|
+
.tool-result-error .folded-tool-desc { color: #b91c1c; }
|
|
1662
|
+
html.dark .tool-result-error .folded-tool-desc { color: #f87171; }
|
|
1663
|
+
.tool-result-error > .folded-tool-body { border-top-color: #fecaca; }
|
|
1664
|
+
html.dark .tool-result-error > .folded-tool-body { border-top-color: #991b1b; }
|
|
1665
|
+
|
|
1617
1666
|
/* --- Collapsible Code Summary --- */
|
|
1618
1667
|
.collapsible-code {
|
|
1619
1668
|
margin: 0.125rem 0;
|
package/static/js/client.js
CHANGED
|
@@ -476,7 +476,16 @@ class AgentGUIClient {
|
|
|
476
476
|
mDiv.innerHTML = '<div class="message-role">Assistant</div><div class="message-blocks streaming-blocks"></div>';
|
|
477
477
|
const bEl = mDiv.querySelector('.message-blocks');
|
|
478
478
|
const bFrag = document.createDocumentFragment();
|
|
479
|
-
sList.forEach(chunk => {
|
|
479
|
+
sList.forEach(chunk => {
|
|
480
|
+
if (!chunk.block?.type) return;
|
|
481
|
+
const el = this.renderer.renderBlock(chunk.block, chunk);
|
|
482
|
+
if (!el) return;
|
|
483
|
+
if (chunk.block.type === 'tool_result') {
|
|
484
|
+
const lastInFrag = bFrag.lastElementChild;
|
|
485
|
+
if (lastInFrag?.classList?.contains('block-tool-use')) { lastInFrag.appendChild(el); return; }
|
|
486
|
+
}
|
|
487
|
+
bFrag.appendChild(el);
|
|
488
|
+
});
|
|
480
489
|
bEl.appendChild(bFrag);
|
|
481
490
|
const ts = document.createElement('div'); ts.className = 'message-timestamp'; ts.textContent = new Date(sList[sList.length - 1].created_at).toLocaleString();
|
|
482
491
|
mDiv.appendChild(ts);
|
|
@@ -833,7 +842,12 @@ class AgentGUIClient {
|
|
|
833
842
|
} else if (content && typeof content === 'object' && content.type === 'claude_execution') {
|
|
834
843
|
let html = '<div class="message-blocks">';
|
|
835
844
|
if (content.blocks && Array.isArray(content.blocks)) {
|
|
845
|
+
let pendingToolUseClose = false;
|
|
836
846
|
content.blocks.forEach(block => {
|
|
847
|
+
if (block.type !== 'tool_result' && pendingToolUseClose) {
|
|
848
|
+
html += '</details>';
|
|
849
|
+
pendingToolUseClose = false;
|
|
850
|
+
}
|
|
837
851
|
if (block.type === 'text') {
|
|
838
852
|
const parts = this.parseMarkdownCodeBlocks(block.text);
|
|
839
853
|
parts.forEach(part => {
|
|
@@ -873,7 +887,8 @@ class AgentGUIClient {
|
|
|
873
887
|
const dName = hasRenderer ? StreamingRenderer.getToolDisplayName(tn) : tn;
|
|
874
888
|
const tTitle = hasRenderer && block.input ? StreamingRenderer.getToolTitle(tn, block.input) : '';
|
|
875
889
|
const iconHtml = hasRenderer && this.renderer ? `<span class="folded-tool-icon">${this.renderer.getToolIcon(tn)}</span>` : '';
|
|
876
|
-
html += `<details class="folded-tool"><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}
|
|
890
|
+
html += `<details class="block-tool-use folded-tool"><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}`;
|
|
891
|
+
pendingToolUseClose = true;
|
|
877
892
|
} else if (block.type === 'tool_result') {
|
|
878
893
|
const content = typeof block.content === 'string' ? block.content : JSON.stringify(block.content);
|
|
879
894
|
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>`;
|
|
@@ -881,9 +896,16 @@ class AgentGUIClient {
|
|
|
881
896
|
const resultIcon = block.is_error
|
|
882
897
|
? '<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
898
|
: '<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
|
-
|
|
899
|
+
const resultHtml = `<details class="tool-result-inline${block.is_error ? ' tool-result-error' : ''}"><summary 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></summary><div class="folded-tool-body">${smartHtml}</div></details>`;
|
|
900
|
+
if (pendingToolUseClose) {
|
|
901
|
+
html += resultHtml + '</details>';
|
|
902
|
+
pendingToolUseClose = false;
|
|
903
|
+
} else {
|
|
904
|
+
html += resultHtml;
|
|
905
|
+
}
|
|
885
906
|
}
|
|
886
907
|
});
|
|
908
|
+
if (pendingToolUseClose) html += '</details>';
|
|
887
909
|
}
|
|
888
910
|
html += '</div>';
|
|
889
911
|
return html;
|
|
@@ -1116,10 +1138,15 @@ class AgentGUIClient {
|
|
|
1116
1138
|
const blocksEl = streamingEl.querySelector('.streaming-blocks');
|
|
1117
1139
|
if (!blocksEl) return;
|
|
1118
1140
|
const element = this.renderer.renderBlock(chunk.block, chunk);
|
|
1119
|
-
if (element)
|
|
1120
|
-
|
|
1121
|
-
|
|
1141
|
+
if (!element) return;
|
|
1142
|
+
if (chunk.block.type === 'tool_result') {
|
|
1143
|
+
const matchById = chunk.block.tool_use_id && blocksEl.querySelector(`.block-tool-use[data-tool-use-id="${chunk.block.tool_use_id}"]`);
|
|
1144
|
+
const lastEl = blocksEl.lastElementChild;
|
|
1145
|
+
const toolUseEl = matchById || (lastEl?.classList?.contains('block-tool-use') ? lastEl : null);
|
|
1146
|
+
if (toolUseEl) { toolUseEl.appendChild(element); this.scrollToBottom(); return; }
|
|
1122
1147
|
}
|
|
1148
|
+
blocksEl.appendChild(element);
|
|
1149
|
+
this.scrollToBottom();
|
|
1123
1150
|
}
|
|
1124
1151
|
|
|
1125
1152
|
renderChunkBatch(chunks) {
|
|
@@ -1136,13 +1163,20 @@ class AgentGUIClient {
|
|
|
1136
1163
|
if (!streamingEl) continue;
|
|
1137
1164
|
const blocksEl = streamingEl.querySelector('.streaming-blocks');
|
|
1138
1165
|
if (!blocksEl) continue;
|
|
1139
|
-
const frag = document.createDocumentFragment();
|
|
1140
1166
|
for (const chunk of groups[sid]) {
|
|
1141
1167
|
const el = this.renderer.renderBlock(chunk.block, chunk);
|
|
1142
|
-
if (el)
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1168
|
+
if (!el) continue;
|
|
1169
|
+
if (chunk.block.type === 'tool_result') {
|
|
1170
|
+
const matchById = chunk.block.tool_use_id && blocksEl.querySelector(`.block-tool-use[data-tool-use-id="${chunk.block.tool_use_id}"]`);
|
|
1171
|
+
const lastEl = blocksEl.lastElementChild;
|
|
1172
|
+
const toolUseEl = matchById || (lastEl?.classList?.contains('block-tool-use') ? lastEl : null);
|
|
1173
|
+
if (toolUseEl) {
|
|
1174
|
+
toolUseEl.appendChild(el);
|
|
1175
|
+
appended = true;
|
|
1176
|
+
continue;
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
blocksEl.appendChild(el);
|
|
1146
1180
|
appended = true;
|
|
1147
1181
|
}
|
|
1148
1182
|
}
|
|
@@ -1429,10 +1463,14 @@ class AgentGUIClient {
|
|
|
1429
1463
|
const blocksEl = messageDiv.querySelector('.message-blocks');
|
|
1430
1464
|
const blockFrag = document.createDocumentFragment();
|
|
1431
1465
|
sessionChunkList.forEach(chunk => {
|
|
1432
|
-
if (chunk.block
|
|
1433
|
-
|
|
1434
|
-
|
|
1466
|
+
if (!chunk.block?.type) return;
|
|
1467
|
+
const element = this.renderer.renderBlock(chunk.block, chunk);
|
|
1468
|
+
if (!element) return;
|
|
1469
|
+
if (chunk.block.type === 'tool_result') {
|
|
1470
|
+
const lastInFrag = blockFrag.lastElementChild;
|
|
1471
|
+
if (lastInFrag?.classList?.contains('block-tool-use')) { lastInFrag.appendChild(element); return; }
|
|
1435
1472
|
}
|
|
1473
|
+
blockFrag.appendChild(element);
|
|
1436
1474
|
});
|
|
1437
1475
|
blocksEl.appendChild(blockFrag);
|
|
1438
1476
|
|
|
@@ -703,6 +703,7 @@ class StreamingRenderer {
|
|
|
703
703
|
|
|
704
704
|
const details = document.createElement('details');
|
|
705
705
|
details.className = 'block-tool-use folded-tool';
|
|
706
|
+
if (block.id) details.dataset.toolUseId = block.id;
|
|
706
707
|
const summary = document.createElement('summary');
|
|
707
708
|
summary.className = 'folded-tool-bar';
|
|
708
709
|
const displayName = this.getToolUseDisplayName(toolName);
|
|
@@ -1154,7 +1155,7 @@ class StreamingRenderer {
|
|
|
1154
1155
|
}
|
|
1155
1156
|
|
|
1156
1157
|
/**
|
|
1157
|
-
* Render tool result
|
|
1158
|
+
* Render tool result as inline content to be merged into preceding tool_use block
|
|
1158
1159
|
*/
|
|
1159
1160
|
renderBlockToolResult(block, context) {
|
|
1160
1161
|
const isError = block.is_error || false;
|
|
@@ -1163,15 +1164,16 @@ class StreamingRenderer {
|
|
|
1163
1164
|
const preview = contentStr.length > 80 ? contentStr.substring(0, 77).replace(/\n/g, ' ') + '...' : contentStr.replace(/\n/g, ' ');
|
|
1164
1165
|
|
|
1165
1166
|
const details = document.createElement('details');
|
|
1166
|
-
details.className = isError ? '
|
|
1167
|
+
details.className = 'tool-result-inline' + (isError ? ' tool-result-error' : '');
|
|
1167
1168
|
details.dataset.eventType = 'tool_result';
|
|
1169
|
+
if (block.tool_use_id) details.dataset.toolUseId = block.tool_use_id;
|
|
1168
1170
|
|
|
1169
1171
|
const iconSvg = isError
|
|
1170
1172
|
? '<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>'
|
|
1171
1173
|
: '<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>';
|
|
1172
1174
|
|
|
1173
1175
|
const summary = document.createElement('summary');
|
|
1174
|
-
summary.className = '
|
|
1176
|
+
summary.className = 'tool-result-status';
|
|
1175
1177
|
summary.innerHTML = `
|
|
1176
1178
|
<span class="folded-tool-icon">${iconSvg}</span>
|
|
1177
1179
|
<span class="folded-tool-name">${isError ? 'Error' : 'Success'}</span>
|