agentgui 1.0.483 → 1.0.485

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.483",
3
+ "version": "1.0.485",
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
@@ -1199,13 +1199,21 @@
1199
1199
  overflow-y: auto;
1200
1200
  white-space: pre-wrap;
1201
1201
  word-break: break-word;
1202
+ font-family: inherit;
1203
+ border: 1px solid var(--color-border);
1204
+ resize: none;
1202
1205
  }
1203
1206
 
1204
- .voice-transcript:empty::before {
1205
- content: attr(data-placeholder);
1207
+ .voice-transcript::placeholder {
1206
1208
  color: var(--color-text-secondary);
1207
1209
  }
1208
1210
 
1211
+ .voice-transcript:focus {
1212
+ outline: none;
1213
+ border-color: var(--color-primary);
1214
+ background: var(--color-bg-primary);
1215
+ }
1216
+
1209
1217
  .voice-mic-btn {
1210
1218
  display: flex;
1211
1219
  align-items: center;
@@ -3169,10 +3177,10 @@
3169
3177
  </div>
3170
3178
  <div class="voice-input-section">
3171
3179
  <div class="voice-input-wrapper">
3172
- <select class="agent-selector voice-agent-selector" data-voice-agent-selector title="Select agent"></select>
3173
- <select class="agent-selector voice-cli-selector" data-voice-cli-selector title="Select CLI tool"></select>
3180
+ <select class="agent-selector voice-agent-selector" data-voice-agent-selector title="Select agent"></select>
3181
+ <select class="agent-selector voice-cli-selector" data-voice-cli-selector title="Select CLI tool"></select>
3174
3182
  <select class="agent-selector voice-model-selector" data-voice-model-selector title="Select model"></select>
3175
- <div class="voice-transcript" id="voiceTranscript" data-placeholder="Tap mic and speak..."></div>
3183
+ <textarea class="voice-transcript" id="voiceTranscript" placeholder="Type or tap mic and speak..." spellcheck="true"></textarea>
3176
3184
  <button class="voice-mic-btn" id="voiceMicBtn" title="Toggle recording" aria-label="Voice input">
3177
3185
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
3178
3186
  <path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/>
@@ -260,6 +260,15 @@
260
260
  if (sendBtn) {
261
261
  sendBtn.addEventListener('click', sendVoiceMessage);
262
262
  }
263
+ var transcript = document.getElementById('voiceTranscript');
264
+ if (transcript) {
265
+ transcript.addEventListener('keydown', function(e) {
266
+ if (e.ctrlKey && e.key === 'Enter' || e.metaKey && e.key === 'Enter') {
267
+ e.preventDefault();
268
+ sendVoiceMessage();
269
+ }
270
+ });
271
+ }
263
272
  }
264
273
 
265
274
  function resampleBuffer(inputBuffer, fromRate, toRate) {
@@ -310,8 +319,12 @@
310
319
  if (isRecording) return;
311
320
  var el = document.getElementById('voiceTranscript');
312
321
  if (el) {
313
- el.textContent = '';
314
- el.setAttribute('data-final', '');
322
+ if (el.value !== undefined) {
323
+ el.value = '';
324
+ } else {
325
+ el.textContent = '';
326
+ el.setAttribute('data-final', '');
327
+ }
315
328
  }
316
329
  try {
317
330
  mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });
@@ -357,7 +370,13 @@
357
370
  }
358
371
  recordedChunks = [];
359
372
  var resampled = resampleBuffer(merged, sourceSampleRate, TARGET_SAMPLE_RATE);
360
- if (el) el.textContent = 'Transcribing...';
373
+ if (el) {
374
+ if (el.value !== undefined) {
375
+ el.value = 'Transcribing...';
376
+ } else {
377
+ el.textContent = 'Transcribing...';
378
+ }
379
+ }
361
380
  try {
362
381
  var wavBuffer = encodeWav(resampled, TARGET_SAMPLE_RATE);
363
382
  var resp = await fetch(BASE + '/api/stt', {
@@ -368,27 +387,53 @@
368
387
  var data = await resp.json();
369
388
  if (data.text) {
370
389
  if (el) {
371
- el.textContent = data.text;
372
- el.setAttribute('data-final', data.text);
390
+ if (el.value !== undefined) {
391
+ el.value = data.text;
392
+ } else {
393
+ el.textContent = data.text;
394
+ el.setAttribute('data-final', data.text);
395
+ }
373
396
  }
374
397
  } else if (data.error) {
375
- if (el) el.textContent = 'Error: ' + data.error;
398
+ if (el) {
399
+ if (el.value !== undefined) {
400
+ el.value = 'Error: ' + data.error;
401
+ } else {
402
+ el.textContent = 'Error: ' + data.error;
403
+ }
404
+ }
376
405
  } else {
377
- if (el) el.textContent = '';
406
+ if (el) {
407
+ if (el.value !== undefined) {
408
+ el.value = '';
409
+ } else {
410
+ el.textContent = '';
411
+ }
412
+ }
378
413
  }
379
414
  } catch (e) {
380
- if (el) el.textContent = 'Transcription failed: ' + e.message;
415
+ if (el) {
416
+ if (el.value !== undefined) {
417
+ el.value = 'Transcription failed: ' + e.message;
418
+ } else {
419
+ el.textContent = 'Transcription failed: ' + e.message;
420
+ }
421
+ }
381
422
  }
382
423
  }
383
424
 
384
425
  function sendVoiceMessage() {
385
426
  var el = document.getElementById('voiceTranscript');
386
427
  if (!el) return;
387
- var text = el.textContent.trim();
428
+ var text = (el.value || el.textContent || '').trim();
388
429
  if (!text || text.startsWith('Transcribing') || text.startsWith('Error')) return;
389
430
  addVoiceBlock(text, true);
390
- el.textContent = '';
391
- el.setAttribute('data-final', '');
431
+ if (el.value !== undefined) {
432
+ el.value = '';
433
+ } else {
434
+ el.textContent = '';
435
+ el.setAttribute('data-final', '');
436
+ }
392
437
  if (typeof agentGUIClient !== 'undefined' && agentGUIClient) {
393
438
  var input = agentGUIClient.ui.messageInput;
394
439
  if (input) {
@@ -655,7 +700,7 @@
655
700
  var emptyMsg = container.querySelector('.voice-empty');
656
701
  if (emptyMsg) emptyMsg.remove();
657
702
  var lastChild = container.lastElementChild;
658
- if (!isUser && !_voiceBreakNext && lastChild && lastChild.classList.contains('voice-block') && !lastChild.classList.contains('voice-block-user')) {
703
+ if (!isUser && !_voiceBreakNext && !isLoadingHistory && lastChild && lastChild.classList.contains('voice-block') && !lastChild.classList.contains('voice-block-user')) {
659
704
  var contentSpan = lastChild.querySelector('.voice-block-content');
660
705
  if (contentSpan) {
661
706
  contentSpan.textContent += '\n' + stripHtml(text);
@@ -769,6 +814,13 @@
769
814
  if (data.seq !== undefined) renderedSeqs.add(data.seq);
770
815
  handleVoiceBlock(data.block, true, data.blockRole);
771
816
  }
817
+ if (data.type === 'message_created' && data.message) {
818
+ if (data.conversationId && data.conversationId !== currentConversationId) return;
819
+ var message = data.message;
820
+ if (message.role === 'user' && message.content) {
821
+ handleVoiceBlock({ type: 'text', text: message.content }, true, 'user');
822
+ }
823
+ }
772
824
  if (data.type === 'streaming_start') {
773
825
  if (data.conversationId && data.conversationId !== currentConversationId) return;
774
826
  spokenChunks = new Set();
@@ -830,8 +882,8 @@
830
882
  if (window.wsClient) {
831
883
  window.wsClient.rpc('conv.chunks', { id: conversationId })
832
884
  .then(function(data) {
833
- isLoadingHistory = false;
834
885
  if (!data.ok || !Array.isArray(data.chunks) || data.chunks.length === 0) {
886
+ isLoadingHistory = false;
835
887
  showVoiceEmpty(container);
836
888
  return;
837
889
  }
@@ -850,6 +902,7 @@
850
902
  }
851
903
  });
852
904
  if (!hasContent) showVoiceEmpty(container);
905
+ isLoadingHistory = false;
853
906
  })
854
907
  .catch(function() {
855
908
  isLoadingHistory = false;