agentgui 1.0.258 → 1.0.260
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 +52 -17
- package/static/js/client.js +12 -2
- package/static/js/voice.js +12 -3
package/package.json
CHANGED
package/static/index.html
CHANGED
|
@@ -1715,15 +1715,15 @@
|
|
|
1715
1715
|
text-align: center;
|
|
1716
1716
|
}
|
|
1717
1717
|
|
|
1718
|
-
/* --- Folded Tool Use (
|
|
1718
|
+
/* --- Folded Tool Use (neutral base, colored by block-type-* classes) --- */
|
|
1719
1719
|
.folded-tool {
|
|
1720
1720
|
margin: 0;
|
|
1721
1721
|
border-radius: 0.375rem;
|
|
1722
1722
|
overflow: hidden;
|
|
1723
|
-
background: #
|
|
1723
|
+
background: #f3f4f6;
|
|
1724
1724
|
}
|
|
1725
1725
|
html.dark .folded-tool {
|
|
1726
|
-
background: #
|
|
1726
|
+
background: #1f2937;
|
|
1727
1727
|
}
|
|
1728
1728
|
.folded-tool-bar {
|
|
1729
1729
|
display: flex;
|
|
@@ -1735,11 +1735,11 @@
|
|
|
1735
1735
|
list-style: none;
|
|
1736
1736
|
font-size: 0.85rem;
|
|
1737
1737
|
line-height: 1.3;
|
|
1738
|
-
background: #
|
|
1738
|
+
background: #e5e7eb;
|
|
1739
1739
|
transition: background 0.15s;
|
|
1740
1740
|
}
|
|
1741
1741
|
html.dark .folded-tool-bar {
|
|
1742
|
-
background: #
|
|
1742
|
+
background: #374151;
|
|
1743
1743
|
}
|
|
1744
1744
|
.folded-tool-bar::-webkit-details-marker { display: none; }
|
|
1745
1745
|
.folded-tool-bar::marker { display: none; content: ''; }
|
|
@@ -1749,33 +1749,33 @@
|
|
|
1749
1749
|
margin-right: 0.125rem;
|
|
1750
1750
|
display: inline-block;
|
|
1751
1751
|
transition: transform 0.15s;
|
|
1752
|
-
color: #
|
|
1752
|
+
color: #6b7280;
|
|
1753
1753
|
flex-shrink: 0;
|
|
1754
1754
|
}
|
|
1755
|
-
html.dark .folded-tool-bar::before { color: #
|
|
1755
|
+
html.dark .folded-tool-bar::before { color: #9ca3af; }
|
|
1756
1756
|
.folded-tool[open] > .folded-tool-bar::before { transform: rotate(90deg); }
|
|
1757
|
-
.folded-tool-bar:hover { background: #
|
|
1758
|
-
html.dark .folded-tool-bar:hover { background: #
|
|
1757
|
+
.folded-tool-bar:hover { background: #d1d5db; }
|
|
1758
|
+
html.dark .folded-tool-bar:hover { background: #4b5563; }
|
|
1759
1759
|
.folded-tool-icon {
|
|
1760
1760
|
display: flex;
|
|
1761
1761
|
align-items: center;
|
|
1762
|
-
color: #
|
|
1762
|
+
color: #6b7280;
|
|
1763
1763
|
width: 1rem;
|
|
1764
1764
|
height: 1rem;
|
|
1765
1765
|
flex-shrink: 0;
|
|
1766
1766
|
}
|
|
1767
|
-
html.dark .folded-tool-icon { color: #
|
|
1767
|
+
html.dark .folded-tool-icon { color: #9ca3af; }
|
|
1768
1768
|
.folded-tool-icon svg { width: 1rem; height: 1rem; }
|
|
1769
1769
|
.folded-tool-name {
|
|
1770
1770
|
font-weight: 600;
|
|
1771
|
-
color: #
|
|
1771
|
+
color: #374151;
|
|
1772
1772
|
font-family: 'Monaco','Menlo','Ubuntu Mono', monospace;
|
|
1773
1773
|
font-size: 0.8rem;
|
|
1774
1774
|
flex-shrink: 0;
|
|
1775
1775
|
}
|
|
1776
|
-
html.dark .folded-tool-name { color: #
|
|
1776
|
+
html.dark .folded-tool-name { color: #d1d5db; }
|
|
1777
1777
|
.folded-tool-desc {
|
|
1778
|
-
color: #
|
|
1778
|
+
color: #6b7280;
|
|
1779
1779
|
font-family: 'Monaco','Menlo','Ubuntu Mono', monospace;
|
|
1780
1780
|
font-size: 0.8rem;
|
|
1781
1781
|
overflow: hidden;
|
|
@@ -1785,13 +1785,13 @@
|
|
|
1785
1785
|
min-width: 0;
|
|
1786
1786
|
opacity: 0.8;
|
|
1787
1787
|
}
|
|
1788
|
-
html.dark .folded-tool-desc { color: #
|
|
1788
|
+
html.dark .folded-tool-desc { color: #9ca3af; }
|
|
1789
1789
|
.folded-tool-body {
|
|
1790
1790
|
padding: 0.5rem 0.75rem;
|
|
1791
1791
|
font-size: 0.75rem;
|
|
1792
|
-
border-top: 1px solid #
|
|
1792
|
+
border-top: 1px solid #d1d5db;
|
|
1793
1793
|
}
|
|
1794
|
-
html.dark .folded-tool-body { border-top-color: #
|
|
1794
|
+
html.dark .folded-tool-body { border-top-color: #4b5563; }
|
|
1795
1795
|
.folded-tool-body .tool-input-pre {
|
|
1796
1796
|
margin: 0;
|
|
1797
1797
|
padding: 0.375rem 0.5rem;
|
|
@@ -2007,6 +2007,41 @@
|
|
|
2007
2007
|
.tool-result-success .folded-tool-name { color: #166534; font-weight: 600; }
|
|
2008
2008
|
html.dark .tool-result-success .folded-tool-name { color: #86efac; }
|
|
2009
2009
|
|
|
2010
|
+
/* --- Tool_use parent: has-success / has-error indicators on header --- */
|
|
2011
|
+
.folded-tool.has-success { background: #f0fdf4; }
|
|
2012
|
+
html.dark .folded-tool.has-success { background: #0a1f0f; }
|
|
2013
|
+
.folded-tool.has-success > .folded-tool-bar { background: #dcfce7; }
|
|
2014
|
+
html.dark .folded-tool.has-success > .folded-tool-bar { background: #0f2b1a; }
|
|
2015
|
+
.folded-tool.has-success > .folded-tool-bar:hover { background: #bbf7d0; }
|
|
2016
|
+
html.dark .folded-tool.has-success > .folded-tool-bar:hover { background: #14532d; }
|
|
2017
|
+
.folded-tool.has-success > .folded-tool-bar::before { color: #16a34a; }
|
|
2018
|
+
html.dark .folded-tool.has-success > .folded-tool-bar::before { color: #4ade80; }
|
|
2019
|
+
.folded-tool.has-success .folded-tool-icon { color: #16a34a; }
|
|
2020
|
+
html.dark .folded-tool.has-success .folded-tool-icon { color: #4ade80; }
|
|
2021
|
+
.folded-tool.has-success .folded-tool-name { color: #166534; }
|
|
2022
|
+
html.dark .folded-tool.has-success .folded-tool-name { color: #86efac; }
|
|
2023
|
+
.folded-tool.has-success .folded-tool-desc { color: #15803d; }
|
|
2024
|
+
html.dark .folded-tool.has-success .folded-tool-desc { color: #4ade80; }
|
|
2025
|
+
.folded-tool.has-success > .folded-tool-body { border-top-color: #bbf7d0; }
|
|
2026
|
+
html.dark .folded-tool.has-success > .folded-tool-body { border-top-color: #166534; }
|
|
2027
|
+
|
|
2028
|
+
.folded-tool.has-error { background: #fef2f2; }
|
|
2029
|
+
html.dark .folded-tool.has-error { background: #1c0f0f; }
|
|
2030
|
+
.folded-tool.has-error > .folded-tool-bar { background: #fee2e2; }
|
|
2031
|
+
html.dark .folded-tool.has-error > .folded-tool-bar { background: #2c1010; }
|
|
2032
|
+
.folded-tool.has-error > .folded-tool-bar:hover { background: #fecaca; }
|
|
2033
|
+
html.dark .folded-tool.has-error > .folded-tool-bar:hover { background: #451a1a; }
|
|
2034
|
+
.folded-tool.has-error > .folded-tool-bar::before { color: #ef4444; }
|
|
2035
|
+
html.dark .folded-tool.has-error > .folded-tool-bar::before { color: #f87171; }
|
|
2036
|
+
.folded-tool.has-error .folded-tool-icon { color: #ef4444; }
|
|
2037
|
+
html.dark .folded-tool.has-error .folded-tool-icon { color: #f87171; }
|
|
2038
|
+
.folded-tool.has-error .folded-tool-name { color: #991b1b; }
|
|
2039
|
+
html.dark .folded-tool.has-error .folded-tool-name { color: #fca5a5; }
|
|
2040
|
+
.folded-tool.has-error .folded-tool-desc { color: #b91c1c; }
|
|
2041
|
+
html.dark .folded-tool.has-error .folded-tool-desc { color: #f87171; }
|
|
2042
|
+
.folded-tool.has-error > .folded-tool-body { border-top-color: #fecaca; }
|
|
2043
|
+
html.dark .folded-tool.has-error > .folded-tool-body { border-top-color: #7f1d1d; }
|
|
2044
|
+
|
|
2010
2045
|
/* --- Consecutive block joining --- */
|
|
2011
2046
|
.folded-tool + .folded-tool,
|
|
2012
2047
|
.block-tool-use + .block-tool-use {
|
package/static/js/client.js
CHANGED
|
@@ -611,6 +611,8 @@ class AgentGUIClient {
|
|
|
611
611
|
if (chunk.block.type === 'tool_result') {
|
|
612
612
|
const lastInFrag = bFrag.lastElementChild;
|
|
613
613
|
if (lastInFrag?.classList?.contains('block-tool-use')) {
|
|
614
|
+
lastInFrag.classList.remove('has-success', 'has-error');
|
|
615
|
+
lastInFrag.classList.add(chunk.block.is_error ? 'has-error' : 'has-success');
|
|
614
616
|
const parentIsOpen = lastInFrag.hasAttribute('open');
|
|
615
617
|
const contextWithParent = { ...chunk, parentIsOpen };
|
|
616
618
|
const el = this.renderer.renderBlock(chunk.block, contextWithParent, bFrag);
|
|
@@ -1141,7 +1143,7 @@ class AgentGUIClient {
|
|
|
1141
1143
|
let html = '<div class="message-blocks">';
|
|
1142
1144
|
if (content.blocks && Array.isArray(content.blocks)) {
|
|
1143
1145
|
let pendingToolUseClose = false;
|
|
1144
|
-
content.blocks.forEach(block => {
|
|
1146
|
+
content.blocks.forEach((block, blockIdx, blocks) => {
|
|
1145
1147
|
if (block.type !== 'tool_result' && pendingToolUseClose) {
|
|
1146
1148
|
html += '</details>';
|
|
1147
1149
|
pendingToolUseClose = false;
|
|
@@ -1186,7 +1188,9 @@ class AgentGUIClient {
|
|
|
1186
1188
|
const tTitle = hasRenderer && block.input ? StreamingRenderer.getToolTitle(tn, block.input) : '';
|
|
1187
1189
|
const iconHtml = hasRenderer && this.renderer ? `<span class="folded-tool-icon">${this.renderer.getToolIcon(tn)}</span>` : '';
|
|
1188
1190
|
const typeClass = hasRenderer && this.renderer ? this.renderer._getBlockTypeClass('tool_use') : 'block-type-tool_use';
|
|
1189
|
-
|
|
1191
|
+
const nextBlock = blocks[blockIdx + 1];
|
|
1192
|
+
const resultClass = nextBlock?.type === 'tool_result' ? (nextBlock.is_error ? 'has-error' : 'has-success') : '';
|
|
1193
|
+
html += `<details class="block-tool-use folded-tool ${typeClass} ${resultClass}"><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}`;
|
|
1190
1194
|
pendingToolUseClose = true;
|
|
1191
1195
|
} else if (block.type === 'tool_result') {
|
|
1192
1196
|
const content = typeof block.content === 'string' ? block.content : JSON.stringify(block.content);
|
|
@@ -1751,6 +1755,8 @@ class AgentGUIClient {
|
|
|
1751
1755
|
const lastEl = blocksEl.lastElementChild;
|
|
1752
1756
|
const toolUseEl = matchById || (lastEl?.classList?.contains('block-tool-use') ? lastEl : null);
|
|
1753
1757
|
if (toolUseEl) {
|
|
1758
|
+
toolUseEl.classList.remove('has-success', 'has-error');
|
|
1759
|
+
toolUseEl.classList.add(chunk.block.is_error ? 'has-error' : 'has-success');
|
|
1754
1760
|
const parentIsOpen = toolUseEl.hasAttribute('open');
|
|
1755
1761
|
const contextWithParent = { ...chunk, parentIsOpen };
|
|
1756
1762
|
const element = this.renderer.renderBlock(chunk.block, contextWithParent, blocksEl);
|
|
@@ -1811,6 +1817,8 @@ class AgentGUIClient {
|
|
|
1811
1817
|
const lastEl = blocksEl.lastElementChild;
|
|
1812
1818
|
const toolUseEl = matchById || (lastEl?.classList?.contains('block-tool-use') ? lastEl : null);
|
|
1813
1819
|
if (toolUseEl) {
|
|
1820
|
+
toolUseEl.classList.remove('has-success', 'has-error');
|
|
1821
|
+
toolUseEl.classList.add(chunk.block.is_error ? 'has-error' : 'has-success');
|
|
1814
1822
|
const parentIsOpen = toolUseEl.hasAttribute('open');
|
|
1815
1823
|
const contextWithParent = { ...chunk, parentIsOpen };
|
|
1816
1824
|
const el = this.renderer.renderBlock(chunk.block, contextWithParent, blocksEl);
|
|
@@ -2390,6 +2398,8 @@ class AgentGUIClient {
|
|
|
2390
2398
|
if (chunk.block.type === 'tool_result') {
|
|
2391
2399
|
const lastInFrag = blockFrag.lastElementChild;
|
|
2392
2400
|
if (lastInFrag?.classList?.contains('block-tool-use')) {
|
|
2401
|
+
lastInFrag.classList.remove('has-success', 'has-error');
|
|
2402
|
+
lastInFrag.classList.add(chunk.block.is_error ? 'has-error' : 'has-success');
|
|
2393
2403
|
const parentIsOpen = lastInFrag.hasAttribute('open');
|
|
2394
2404
|
const contextWithParent = { ...chunk, parentIsOpen };
|
|
2395
2405
|
const element = this.renderer.renderBlock(chunk.block, contextWithParent, blockFrag);
|
package/static/js/voice.js
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
var isLoadingHistory = false;
|
|
18
18
|
var _lastVoiceBlockText = null;
|
|
19
19
|
var _lastVoiceBlockTime = 0;
|
|
20
|
+
var _voiceBreakNext = false;
|
|
20
21
|
var selectedVoiceId = localStorage.getItem('voice-selected-id') || 'default';
|
|
21
22
|
var ttsAudioCache = new Map();
|
|
22
23
|
var TTS_CLIENT_CACHE_MAX = 50;
|
|
@@ -549,7 +550,7 @@
|
|
|
549
550
|
var emptyMsg = container.querySelector('.voice-empty');
|
|
550
551
|
if (emptyMsg) emptyMsg.remove();
|
|
551
552
|
var lastChild = container.lastElementChild;
|
|
552
|
-
if (!isUser && lastChild && lastChild.classList.contains('voice-block') && !lastChild.classList.contains('voice-block-user')) {
|
|
553
|
+
if (!isUser && !_voiceBreakNext && lastChild && lastChild.classList.contains('voice-block') && !lastChild.classList.contains('voice-block-user')) {
|
|
553
554
|
var contentSpan = lastChild.querySelector('.voice-block-content');
|
|
554
555
|
if (contentSpan) {
|
|
555
556
|
contentSpan.textContent += '\n' + stripHtml(text);
|
|
@@ -558,6 +559,7 @@
|
|
|
558
559
|
return lastChild;
|
|
559
560
|
}
|
|
560
561
|
}
|
|
562
|
+
_voiceBreakNext = false;
|
|
561
563
|
var div = document.createElement('div');
|
|
562
564
|
div.className = 'voice-block' + (isUser ? ' voice-block-user' : '');
|
|
563
565
|
if (isUser) {
|
|
@@ -666,6 +668,7 @@
|
|
|
666
668
|
if (data.conversationId && data.conversationId !== currentConversationId) return;
|
|
667
669
|
spokenChunks = new Set();
|
|
668
670
|
renderedSeqs = new Set();
|
|
671
|
+
_voiceBreakNext = false;
|
|
669
672
|
}
|
|
670
673
|
});
|
|
671
674
|
window.addEventListener('conversation-selected', function(e) {
|
|
@@ -682,7 +685,6 @@
|
|
|
682
685
|
function handleVoiceBlock(block, isNew) {
|
|
683
686
|
if (!block || !block.type) return;
|
|
684
687
|
if (block.type === 'text' && block.text) {
|
|
685
|
-
// Deduplicate: prevent rendering the same text block twice within 500ms
|
|
686
688
|
var now = Date.now();
|
|
687
689
|
if (_lastVoiceBlockText === block.text && (now - _lastVoiceBlockTime) < 500) {
|
|
688
690
|
return;
|
|
@@ -697,7 +699,10 @@
|
|
|
697
699
|
setTimeout(function() { div.classList.remove('speaking'); }, 2000);
|
|
698
700
|
}
|
|
699
701
|
} else if (block.type === 'result') {
|
|
702
|
+
_voiceBreakNext = true;
|
|
700
703
|
addVoiceResultBlock(block, isNew);
|
|
704
|
+
} else {
|
|
705
|
+
_voiceBreakNext = true;
|
|
701
706
|
}
|
|
702
707
|
}
|
|
703
708
|
|
|
@@ -705,9 +710,9 @@
|
|
|
705
710
|
var container = document.getElementById('voiceMessages');
|
|
706
711
|
if (!container) return;
|
|
707
712
|
container.innerHTML = '';
|
|
708
|
-
// Reset dedup state when loading a new conversation
|
|
709
713
|
_lastVoiceBlockText = null;
|
|
710
714
|
_lastVoiceBlockTime = 0;
|
|
715
|
+
_voiceBreakNext = false;
|
|
711
716
|
if (!conversationId) {
|
|
712
717
|
showVoiceEmpty(container);
|
|
713
718
|
return;
|
|
@@ -722,6 +727,7 @@
|
|
|
722
727
|
return;
|
|
723
728
|
}
|
|
724
729
|
var hasContent = false;
|
|
730
|
+
_voiceBreakNext = false;
|
|
725
731
|
data.chunks.forEach(function(chunk) {
|
|
726
732
|
if (chunk.sequence !== undefined) renderedSeqs.add(chunk.sequence);
|
|
727
733
|
var block = typeof chunk.data === 'string' ? JSON.parse(chunk.data) : chunk.data;
|
|
@@ -730,8 +736,11 @@
|
|
|
730
736
|
addVoiceBlock(block.text, false);
|
|
731
737
|
hasContent = true;
|
|
732
738
|
} else if (block.type === 'result') {
|
|
739
|
+
_voiceBreakNext = true;
|
|
733
740
|
addVoiceResultBlock(block, false);
|
|
734
741
|
hasContent = true;
|
|
742
|
+
} else {
|
|
743
|
+
_voiceBreakNext = true;
|
|
735
744
|
}
|
|
736
745
|
});
|
|
737
746
|
if (!hasContent) showVoiceEmpty(container);
|