agentgui 1.0.138 → 1.0.140
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 +8 -1
- package/static/js/client.js +0 -5
- package/static/js/streaming-renderer.js +21 -58
- package/static/js/voice.js +22 -4
package/package.json
CHANGED
package/static/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
|
|
6
6
|
<meta name="description" content="AgentGUI - Real-time Claude Code Execution Visualization">
|
|
7
7
|
<title>AgentGUI</title>
|
|
8
|
-
<link rel="icon" type="image/svg+xml" href="/
|
|
8
|
+
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect width='100' height='100' rx='20' fill='%233b82f6'/%3E%3Ctext x='50' y='68' font-size='50' font-family='sans-serif' font-weight='bold' fill='white' text-anchor='middle'%3EG%3C/text%3E%3C/svg%3E">
|
|
9
9
|
|
|
10
10
|
<link href="https://cdn.jsdelivr.net/npm/rippleui@1.12.1/dist/css/styles.css" rel="stylesheet">
|
|
11
11
|
<link href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism-dark.css" rel="stylesheet">
|
|
@@ -1511,6 +1511,13 @@
|
|
|
1511
1511
|
html.dark .block-tool-result.result-success .result-body { color: #bbf7d0; }
|
|
1512
1512
|
html.dark .block-tool-result.result-error .result-body { color: #fecaca; }
|
|
1513
1513
|
|
|
1514
|
+
.result-collapsible { margin: 0; }
|
|
1515
|
+
.result-collapsible > summary { list-style: none; }
|
|
1516
|
+
.result-collapsible > summary::-webkit-details-marker { display: none; }
|
|
1517
|
+
.result-collapsible > summary::marker { display: none; content: ''; }
|
|
1518
|
+
.result-collapsible > summary .status-label::before { content: '\25b6'; font-size: 0.6rem; margin-right: 0.375rem; display: inline-block; transition: transform 0.15s; }
|
|
1519
|
+
.result-collapsible[open] > summary .status-label::before { transform: rotate(90deg); }
|
|
1520
|
+
|
|
1514
1521
|
.block-tool-result .result-body.collapsed { max-height: 150px; position: relative; }
|
|
1515
1522
|
.block-tool-result .result-body.collapsed::after {
|
|
1516
1523
|
content: '';
|
package/static/js/client.js
CHANGED
|
@@ -223,7 +223,6 @@ class AgentGUIClient {
|
|
|
223
223
|
const position = scrollContainer.scrollTop;
|
|
224
224
|
try {
|
|
225
225
|
localStorage.setItem(`scroll_${conversationId}`, position.toString());
|
|
226
|
-
console.log(`Saved scroll position for ${conversationId}: ${position}`);
|
|
227
226
|
} catch (e) {
|
|
228
227
|
console.warn('Failed to save scroll position:', e);
|
|
229
228
|
}
|
|
@@ -245,7 +244,6 @@ class AgentGUIClient {
|
|
|
245
244
|
if (scrollContainer && !isNaN(scrollTop)) {
|
|
246
245
|
requestAnimationFrame(() => {
|
|
247
246
|
scrollContainer.scrollTop = scrollTop;
|
|
248
|
-
console.log(`Restored scroll position for ${conversationId}: ${scrollTop}`);
|
|
249
247
|
});
|
|
250
248
|
}
|
|
251
249
|
}
|
|
@@ -985,7 +983,6 @@ class AgentGUIClient {
|
|
|
985
983
|
}
|
|
986
984
|
|
|
987
985
|
pollState.isPolling = false;
|
|
988
|
-
console.log('Stopped chunk polling');
|
|
989
986
|
}
|
|
990
987
|
|
|
991
988
|
/**
|
|
@@ -1073,7 +1070,6 @@ class AgentGUIClient {
|
|
|
1073
1070
|
*/
|
|
1074
1071
|
disableControls() {
|
|
1075
1072
|
if (this.ui.sendButton) this.ui.sendButton.disabled = true;
|
|
1076
|
-
if (this.ui.messageInput) this.ui.messageInput.disabled = true;
|
|
1077
1073
|
if (this.ui.agentSelector) this.ui.agentSelector.disabled = true;
|
|
1078
1074
|
}
|
|
1079
1075
|
|
|
@@ -1082,7 +1078,6 @@ class AgentGUIClient {
|
|
|
1082
1078
|
*/
|
|
1083
1079
|
enableControls() {
|
|
1084
1080
|
if (this.ui.sendButton) this.ui.sendButton.disabled = false;
|
|
1085
|
-
if (this.ui.messageInput) this.ui.messageInput.disabled = false;
|
|
1086
1081
|
if (this.ui.agentSelector) this.ui.agentSelector.disabled = false;
|
|
1087
1082
|
}
|
|
1088
1083
|
|
|
@@ -76,48 +76,18 @@ class StreamingRenderer {
|
|
|
76
76
|
* Setup DOM mutation observer for external changes
|
|
77
77
|
*/
|
|
78
78
|
setupDOMObserver() {
|
|
79
|
-
try {
|
|
80
|
-
this.observer = new MutationObserver(() => {
|
|
81
|
-
this.updateDOMNodeCount();
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
this.observer.observe(this.outputContainer, {
|
|
85
|
-
childList: true,
|
|
86
|
-
subtree: true,
|
|
87
|
-
characterData: false,
|
|
88
|
-
attributes: false
|
|
89
|
-
});
|
|
90
|
-
} catch (e) {
|
|
91
|
-
console.warn('DOM observer setup failed:', e.message);
|
|
92
|
-
}
|
|
93
79
|
}
|
|
94
80
|
|
|
95
81
|
/**
|
|
96
82
|
* Setup resize observer for viewport changes
|
|
97
83
|
*/
|
|
98
84
|
setupResizeObserver() {
|
|
99
|
-
try {
|
|
100
|
-
this.resizeObserver = new ResizeObserver(() => {
|
|
101
|
-
this.updateVirtualScroll();
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
if (this.scrollContainer) {
|
|
105
|
-
this.resizeObserver.observe(this.scrollContainer);
|
|
106
|
-
}
|
|
107
|
-
} catch (e) {
|
|
108
|
-
console.warn('Resize observer setup failed:', e.message);
|
|
109
|
-
}
|
|
110
85
|
}
|
|
111
86
|
|
|
112
87
|
/**
|
|
113
88
|
* Setup scroll optimization and auto-scroll
|
|
114
89
|
*/
|
|
115
90
|
setupScrollOptimization() {
|
|
116
|
-
if (this.scrollContainer) {
|
|
117
|
-
this.scrollContainer.addEventListener('scroll', () => {
|
|
118
|
-
this.updateVirtualScroll();
|
|
119
|
-
}, { passive: true });
|
|
120
|
-
}
|
|
121
91
|
}
|
|
122
92
|
|
|
123
93
|
/**
|
|
@@ -1076,13 +1046,27 @@ class StreamingRenderer {
|
|
|
1076
1046
|
? '<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>'
|
|
1077
1047
|
: '<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>';
|
|
1078
1048
|
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1049
|
+
const renderedContent = StreamingRenderer.renderSmartContentHTML(contentStr, this.escapeHtml.bind(this));
|
|
1050
|
+
|
|
1051
|
+
if (isError) {
|
|
1052
|
+
div.innerHTML = `
|
|
1053
|
+
<div class="result-header">
|
|
1054
|
+
<span class="status-label">${iconSvg} Error</span>
|
|
1055
|
+
${toolUseId ? `<span class="result-id">${this.escapeHtml(toolUseId)}</span>` : ''}
|
|
1056
|
+
</div>
|
|
1057
|
+
${renderedContent}
|
|
1058
|
+
`;
|
|
1059
|
+
} else {
|
|
1060
|
+
div.innerHTML = `
|
|
1061
|
+
<details class="result-collapsible">
|
|
1062
|
+
<summary class="result-header" style="cursor:pointer;list-style:none;user-select:none">
|
|
1063
|
+
<span class="status-label">${iconSvg} Success</span>
|
|
1064
|
+
${toolUseId ? `<span class="result-id">${this.escapeHtml(toolUseId)}</span>` : ''}
|
|
1065
|
+
</summary>
|
|
1066
|
+
<div class="result-collapsible-body">${renderedContent}</div>
|
|
1067
|
+
</details>
|
|
1068
|
+
`;
|
|
1069
|
+
}
|
|
1086
1070
|
|
|
1087
1071
|
return div;
|
|
1088
1072
|
}
|
|
@@ -1697,28 +1681,7 @@ class StreamingRenderer {
|
|
|
1697
1681
|
}
|
|
1698
1682
|
}
|
|
1699
1683
|
|
|
1700
|
-
/**
|
|
1701
|
-
* Update virtual scroll based on viewport
|
|
1702
|
-
*/
|
|
1703
1684
|
updateVirtualScroll() {
|
|
1704
|
-
if (!this.scrollContainer) return;
|
|
1705
|
-
|
|
1706
|
-
// Calculate visible items
|
|
1707
|
-
const scrollTop = this.scrollContainer.scrollTop;
|
|
1708
|
-
const viewportHeight = this.scrollContainer.clientHeight;
|
|
1709
|
-
const itemHeight = 80; // Approximate item height
|
|
1710
|
-
|
|
1711
|
-
const firstVisible = Math.floor(scrollTop / itemHeight);
|
|
1712
|
-
const lastVisible = Math.ceil((scrollTop + viewportHeight) / itemHeight);
|
|
1713
|
-
|
|
1714
|
-
// Update visibility of DOM nodes
|
|
1715
|
-
const items = this.outputContainer?.querySelectorAll('[data-event-id]');
|
|
1716
|
-
if (!items) return;
|
|
1717
|
-
|
|
1718
|
-
items.forEach((item, index) => {
|
|
1719
|
-
const isVisible = index >= firstVisible && index <= lastVisible;
|
|
1720
|
-
item.style.display = isVisible ? '' : 'none';
|
|
1721
|
-
});
|
|
1722
1685
|
}
|
|
1723
1686
|
|
|
1724
1687
|
/**
|
package/static/js/voice.js
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
|
-
import { STT, TTS } from 'webtalk-sdk';
|
|
2
|
-
|
|
3
1
|
(function() {
|
|
4
2
|
const BASE = window.__BASE_URL || '';
|
|
3
|
+
let STT = null;
|
|
4
|
+
let TTS = null;
|
|
5
|
+
|
|
6
|
+
async function loadSDK() {
|
|
7
|
+
try {
|
|
8
|
+
const mod = await import(BASE + '/webtalk/sdk.js');
|
|
9
|
+
STT = mod.STT;
|
|
10
|
+
TTS = mod.TTS;
|
|
11
|
+
return true;
|
|
12
|
+
} catch (e) {
|
|
13
|
+
console.warn('Webtalk SDK load failed:', e.message);
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
5
17
|
let stt = null;
|
|
6
18
|
let tts = null;
|
|
7
19
|
let isRecording = false;
|
|
@@ -19,8 +31,14 @@ import { STT, TTS } from 'webtalk-sdk';
|
|
|
19
31
|
setupUI();
|
|
20
32
|
setupStreamingListener();
|
|
21
33
|
setupAgentSelector();
|
|
22
|
-
|
|
23
|
-
|
|
34
|
+
var sdkLoaded = await loadSDK();
|
|
35
|
+
if (sdkLoaded) {
|
|
36
|
+
initSTT();
|
|
37
|
+
initTTS();
|
|
38
|
+
} else {
|
|
39
|
+
sttLoadPhase = 'failed';
|
|
40
|
+
updateMicState();
|
|
41
|
+
}
|
|
24
42
|
}
|
|
25
43
|
|
|
26
44
|
var sttLoadPhase = 'starting';
|