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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentgui",
3
- "version": "1.0.138",
3
+ "version": "1.0.140",
4
4
  "description": "Multi-agent ACP client with real-time communication",
5
5
  "type": "module",
6
6
  "main": "server.js",
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="/favicon.ico">
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: '';
@@ -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
- div.innerHTML = `
1080
- <div class="result-header">
1081
- <span class="status-label">${iconSvg} ${isError ? 'Error' : 'Success'}</span>
1082
- ${toolUseId ? `<span class="result-id">${this.escapeHtml(toolUseId)}</span>` : ''}
1083
- </div>
1084
- ${StreamingRenderer.renderSmartContentHTML(contentStr, this.escapeHtml.bind(this))}
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
  /**
@@ -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
- initSTT();
23
- initTTS();
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';