agentgui 1.0.248 → 1.0.250

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.248",
3
+ "version": "1.0.250",
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
@@ -2753,6 +2753,7 @@
2753
2753
  <script defer src="/gm/js/syntax-highlighter.js"></script>
2754
2754
  <script defer src="/gm/js/dialogs.js"></script>
2755
2755
  <script defer src="/gm/js/ui-components.js"></script>
2756
+ <script defer src="/gm/js/progress-dialog.js"></script>
2756
2757
  <script defer src="/gm/js/conversations.js"></script>
2757
2758
  <script defer src="/gm/js/client.js"></script>
2758
2759
  <script type="module" src="/gm/js/voice.js"></script>
@@ -2044,8 +2044,11 @@ class AgentGUIClient {
2044
2044
  window._voiceProgressDialog.close();
2045
2045
  window._voiceProgressDialog = null;
2046
2046
  }
2047
+ const errorMsg = 'Failed to download voice models: ' + progress.error;
2047
2048
  if (window.UIDialog) {
2048
- window.UIDialog.alert('Failed to download voice models: ' + progress.error, 'Download Error');
2049
+ window.UIDialog.alert(errorMsg, 'Download Error');
2050
+ } else {
2051
+ alert(errorMsg);
2049
2052
  }
2050
2053
  return;
2051
2054
  }
@@ -208,10 +208,22 @@
208
208
  function triggerVoiceModelDownload() {
209
209
  var client = window.agentGUIClient;
210
210
  if (client && client._modelDownloadInProgress) {
211
+ if (window._voiceProgressDialog) {
212
+ return;
213
+ }
211
214
  showToast('Voice models downloading... please wait', 'info');
212
215
  return;
213
216
  }
214
- showToast('Starting voice model download...', 'info');
217
+
218
+ if (!window._voiceProgressDialog) {
219
+ window._voiceProgressDialog = new ProgressDialog({
220
+ title: 'Voice Models',
221
+ message: 'Preparing to download voice models...',
222
+ percentage: 0,
223
+ cancellable: false
224
+ });
225
+ }
226
+
215
227
  fetch((window.__BASE_URL || '') + '/api/speech-status', {
216
228
  method: 'POST',
217
229
  headers: { 'Content-Type': 'application/json' },
@@ -219,12 +231,22 @@
219
231
  }).then(function(res) { return res.json(); })
220
232
  .then(function(data) {
221
233
  if (data.ok) {
222
- showToast('Downloading voice models... will auto-open when ready', 'info');
223
234
  window._voiceTabPendingOpen = true;
235
+ if (window._voiceProgressDialog) {
236
+ window._voiceProgressDialog.update(0, 'Starting download...');
237
+ }
224
238
  } else {
239
+ if (window._voiceProgressDialog) {
240
+ window._voiceProgressDialog.close();
241
+ window._voiceProgressDialog = null;
242
+ }
225
243
  showToast('Failed to start download: ' + (data.error || 'unknown'), 'error');
226
244
  }
227
245
  }).catch(function(err) {
246
+ if (window._voiceProgressDialog) {
247
+ window._voiceProgressDialog.close();
248
+ window._voiceProgressDialog = null;
249
+ }
228
250
  showToast('Download request failed: ' + err.message, 'error');
229
251
  });
230
252
  }
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Progress Dialog
3
+ * Modal dialog for displaying download/upload progress
4
+ */
5
+
6
+ class ProgressDialog {
7
+ constructor(config = {}) {
8
+ this.title = config.title || 'Progress';
9
+ this.message = config.message || 'Processing...';
10
+ this.percentage = config.percentage || 0;
11
+ this.cancellable = config.cancellable || false;
12
+ this.onCancel = config.onCancel || null;
13
+ this.overlay = null;
14
+ this.progressBar = null;
15
+ this.progressText = null;
16
+ this.messageEl = null;
17
+ this._create();
18
+ }
19
+
20
+ _create() {
21
+ this.overlay = document.createElement('div');
22
+ this.overlay.className = 'folder-modal-overlay visible';
23
+ this.overlay.style.zIndex = '3000';
24
+
25
+ const modal = document.createElement('div');
26
+ modal.className = 'folder-modal';
27
+ modal.style.width = '400px';
28
+
29
+ const header = document.createElement('div');
30
+ header.className = 'folder-modal-header';
31
+ header.innerHTML = `
32
+ <h3>${this._escapeHtml(this.title)}</h3>
33
+ ${this.cancellable ? '<button class="folder-modal-close" aria-label="Cancel">&times;</button>' : ''}
34
+ `;
35
+
36
+ const body = document.createElement('div');
37
+ body.style.padding = '1.5rem 1rem';
38
+
39
+ this.messageEl = document.createElement('div');
40
+ this.messageEl.style.marginBottom = '1rem';
41
+ this.messageEl.style.fontSize = '0.875rem';
42
+ this.messageEl.style.color = 'var(--color-text-primary)';
43
+ this.messageEl.textContent = this.message;
44
+
45
+ const progressContainer = document.createElement('div');
46
+ progressContainer.style.marginBottom = '0.5rem';
47
+
48
+ this.progressBar = document.createElement('div');
49
+ this.progressBar.style.width = '100%';
50
+ this.progressBar.style.height = '8px';
51
+ this.progressBar.style.backgroundColor = 'var(--color-bg-secondary)';
52
+ this.progressBar.style.borderRadius = '4px';
53
+ this.progressBar.style.overflow = 'hidden';
54
+
55
+ const progressFill = document.createElement('div');
56
+ progressFill.className = 'progress-fill';
57
+ progressFill.style.height = '100%';
58
+ progressFill.style.backgroundColor = 'var(--color-primary)';
59
+ progressFill.style.width = this.percentage + '%';
60
+ progressFill.style.transition = 'width 0.3s ease';
61
+
62
+ this.progressBar.appendChild(progressFill);
63
+ progressContainer.appendChild(this.progressBar);
64
+
65
+ this.progressText = document.createElement('div');
66
+ this.progressText.style.fontSize = '0.75rem';
67
+ this.progressText.style.color = 'var(--color-text-secondary)';
68
+ this.progressText.style.textAlign = 'right';
69
+ this.progressText.style.marginTop = '0.25rem';
70
+ this.progressText.textContent = Math.round(this.percentage) + '%';
71
+
72
+ body.appendChild(this.messageEl);
73
+ body.appendChild(progressContainer);
74
+ body.appendChild(this.progressText);
75
+
76
+ modal.appendChild(header);
77
+ modal.appendChild(body);
78
+ this.overlay.appendChild(modal);
79
+
80
+ if (this.cancellable) {
81
+ const closeBtn = header.querySelector('.folder-modal-close');
82
+ closeBtn.addEventListener('click', () => this._handleCancel());
83
+ }
84
+
85
+ document.body.appendChild(this.overlay);
86
+ }
87
+
88
+ update(percentage, message) {
89
+ if (message !== undefined) {
90
+ this.message = message;
91
+ if (this.messageEl) {
92
+ this.messageEl.textContent = message;
93
+ }
94
+ }
95
+
96
+ if (percentage !== undefined) {
97
+ this.percentage = Math.min(100, Math.max(0, percentage));
98
+ const fill = this.progressBar?.querySelector('.progress-fill');
99
+ if (fill) {
100
+ fill.style.width = this.percentage + '%';
101
+ }
102
+ if (this.progressText) {
103
+ this.progressText.textContent = Math.round(this.percentage) + '%';
104
+ }
105
+ }
106
+ }
107
+
108
+ close() {
109
+ if (this.overlay && this.overlay.parentNode) {
110
+ this.overlay.remove();
111
+ }
112
+ }
113
+
114
+ _handleCancel() {
115
+ if (this.onCancel) {
116
+ this.onCancel();
117
+ }
118
+ this.close();
119
+ }
120
+
121
+ _escapeHtml(text) {
122
+ const div = document.createElement('div');
123
+ div.textContent = text;
124
+ return div.innerHTML;
125
+ }
126
+ }
127
+
128
+ if (typeof module !== 'undefined' && module.exports) {
129
+ module.exports = ProgressDialog;
130
+ }
@@ -424,7 +424,9 @@ class StreamingRenderer {
424
424
  'image': 9,
425
425
  'plan': 10,
426
426
  'usage': 11,
427
- 'premature': 8
427
+ 'premature': 8,
428
+ 'tool_status': 7,
429
+ 'generic': 0
428
430
  };
429
431
  return typeColors[blockType] !== undefined ? typeColors[blockType] : 0;
430
432
  }
@@ -1501,6 +1503,8 @@ class StreamingRenderer {
1501
1503
  renderBlockGeneric(block, context) {
1502
1504
  const div = document.createElement('div');
1503
1505
  div.className = 'block-generic';
1506
+ const colorIndex = this._getBlockColorIndex('generic');
1507
+ div.style.borderLeft = `3px solid var(--block-color-${colorIndex})`;
1504
1508
 
1505
1509
  // Show key-value pairs instead of raw JSON
1506
1510
  const fieldsHtml = Object.entries(block)
@@ -1532,6 +1536,8 @@ class StreamingRenderer {
1532
1536
  renderBlockError(block, error) {
1533
1537
  const div = document.createElement('div');
1534
1538
  div.className = 'block-error';
1539
+ const colorIndex = this._getBlockColorIndex('error');
1540
+ div.style.borderLeft = `3px solid var(--block-color-${colorIndex})`;
1535
1541
 
1536
1542
  div.innerHTML = `
1537
1543
  <div style="display:flex;align-items:flex-start;gap:0.625rem">