agentgui 1.0.797 → 1.0.798

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.797",
3
+ "version": "1.0.798",
4
4
  "description": "Multi-agent ACP client with real-time communication",
5
5
  "type": "module",
6
6
  "main": "electron/main.js",
package/static/index.html CHANGED
@@ -290,6 +290,8 @@
290
290
  <script defer src="/gm/js/voice-machine.js"></script>
291
291
  <script defer src="/gm/js/conv-list-machine.js"></script>
292
292
  <script defer src="/gm/js/prompt-machine.js"></script>
293
+ <script defer src="/gm/js/recording-machine.js"></script>
294
+ <script defer src="/gm/js/terminal-machine.js"></script>
293
295
  <script defer src="/gm/js/conversations.js"></script>
294
296
  <script defer src="/gm/lib/msgpackr.min.js"></script>
295
297
  <script defer src="/gm/js/websocket-manager.js"></script>
@@ -0,0 +1,49 @@
1
+ (function() {
2
+ const { createMachine, createActor, assign } = XState;
3
+
4
+ const recordingMachine = createMachine({
5
+ id: 'recording',
6
+ initial: 'idle',
7
+ context: {
8
+ error: null,
9
+ },
10
+ states: {
11
+ idle: {
12
+ entry: assign({ error: null }),
13
+ on: {
14
+ START: { target: 'recording' },
15
+ },
16
+ },
17
+ recording: {
18
+ on: {
19
+ STOP: { target: 'processing' },
20
+ ERROR: {
21
+ target: 'idle',
22
+ actions: assign(({ event }) => ({ error: event.error || 'Recording failed' })),
23
+ },
24
+ },
25
+ },
26
+ processing: {
27
+ on: {
28
+ COMPLETE: { target: 'idle' },
29
+ ERROR: {
30
+ target: 'idle',
31
+ actions: assign(({ event }) => ({ error: event.error || 'Processing failed' })),
32
+ },
33
+ },
34
+ },
35
+ },
36
+ });
37
+
38
+ const actor = createActor(recordingMachine);
39
+ actor.start();
40
+
41
+ window.recordingMachineAPI = {
42
+ send: function(event) { actor.send(event); },
43
+ getState: function() { return actor.getSnapshot().value; },
44
+ isRecording: function() { return actor.getSnapshot().value === 'recording'; },
45
+ isProcessing: function() { return actor.getSnapshot().value === 'processing'; },
46
+ subscribe: function(fn) { return actor.subscribe(fn); },
47
+ };
48
+ window.__recordingMachine = actor;
49
+ })();
@@ -7,11 +7,13 @@
7
7
  var recordedChunks = [];
8
8
  var TARGET_SAMPLE_RATE = 16000;
9
9
 
10
+ function rmApi() { return window.recordingMachineAPI; }
11
+
10
12
  window.STTHandler = {
11
- isRecording: function() { return isRecording; },
13
+ isRecording: function() { return rmApi()?.isRecording() || isRecording; },
12
14
 
13
15
  startRecording: async function() {
14
- if (isRecording) return;
16
+ if (isRecording || rmApi()?.isRecording()) return;
15
17
  try {
16
18
  mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true });
17
19
  audioContext = new (window.AudioContext || window.webkitAudioContext)();
@@ -24,16 +26,19 @@
24
26
  };
25
27
  source.connect(workletNode);
26
28
  isRecording = true;
29
+ if (rmApi()) rmApi().send({ type: 'START' });
27
30
  return { success: true };
28
31
  } catch (e) {
29
32
  isRecording = false;
33
+ if (rmApi()) rmApi().send({ type: 'ERROR', error: e.message });
30
34
  return { success: false, error: e.message };
31
35
  }
32
36
  },
33
37
 
34
38
  stopRecording: async function() {
35
- if (!isRecording) return { success: false, error: 'Not recording' };
39
+ if (!isRecording && !rmApi()?.isRecording()) return { success: false, error: 'Not recording' };
36
40
  isRecording = false;
41
+ if (rmApi()) rmApi().send({ type: 'STOP' });
37
42
 
38
43
  if (workletNode) {
39
44
  workletNode.port.postMessage('stop');
@@ -77,13 +82,17 @@
77
82
  });
78
83
  var data = await resp.json();
79
84
  if (data.text) {
85
+ if (rmApi()) rmApi().send({ type: 'COMPLETE' });
80
86
  return { success: true, text: data.text };
81
87
  } else if (data.error) {
88
+ if (rmApi()) rmApi().send({ type: 'ERROR', error: data.error });
82
89
  return { success: false, error: data.error };
83
90
  } else {
91
+ if (rmApi()) rmApi().send({ type: 'ERROR', error: 'No transcription returned' });
84
92
  return { success: false, error: 'No transcription returned' };
85
93
  }
86
94
  } catch (e) {
95
+ if (rmApi()) rmApi().send({ type: 'ERROR', error: e.message });
87
96
  return { success: false, error: 'Transcription failed: ' + e.message };
88
97
  }
89
98
  }
@@ -0,0 +1,51 @@
1
+ (function() {
2
+ const { createMachine, createActor, assign } = XState;
3
+
4
+ const terminalMachine = createMachine({
5
+ id: 'terminal',
6
+ initial: 'inactive',
7
+ context: {
8
+ cwd: null,
9
+ },
10
+ states: {
11
+ inactive: {
12
+ on: {
13
+ START: { target: 'initializing' },
14
+ },
15
+ },
16
+ initializing: {
17
+ on: {
18
+ READY: { target: 'active' },
19
+ ERROR: { target: 'inactive' },
20
+ },
21
+ },
22
+ active: {
23
+ on: {
24
+ STOP: { target: 'inactive' },
25
+ SESSION_EXIT: { target: 'restarting' },
26
+ SET_CWD: {
27
+ actions: assign(({ event }) => ({ cwd: event.cwd })),
28
+ },
29
+ },
30
+ },
31
+ restarting: {
32
+ on: {
33
+ READY: { target: 'active' },
34
+ ERROR: { target: 'inactive' },
35
+ STOP: { target: 'inactive' },
36
+ },
37
+ },
38
+ },
39
+ });
40
+
41
+ const actor = createActor(terminalMachine);
42
+ actor.start();
43
+
44
+ window.terminalMachineAPI = {
45
+ send: function(event) { actor.send(event); },
46
+ getState: function() { return actor.getSnapshot().value; },
47
+ isActive: function() { var s = actor.getSnapshot().value; return s === 'active' || s === 'restarting'; },
48
+ subscribe: function(fn) { return actor.subscribe(fn); },
49
+ };
50
+ window.__terminalMachine = actor;
51
+ })();
@@ -101,10 +101,14 @@
101
101
  var cwd = getCwd();
102
102
  var dims = term ? { cols: term.cols, rows: term.rows } : { cols: 80, rows: 24 };
103
103
  wsSend({ type: 'terminal_start', cwd: cwd, cols: dims.cols, rows: dims.rows });
104
+ if (tmApi()) tmApi().send({ type: 'READY' });
104
105
  setTimeout(function() { if (term && term.focus) term.focus(); }, 100);
105
106
  }
106
107
 
108
+ function tmApi() { return window.terminalMachineAPI; }
109
+
107
110
  function startTerminal() {
111
+ if (tmApi()) tmApi().send({ type: 'START' });
108
112
  if (!ensureTerm()) {
109
113
  setTimeout(startTerminal, 200);
110
114
  return;
@@ -124,6 +128,7 @@
124
128
 
125
129
  function stopTerminal() {
126
130
  termActive = false;
131
+ if (tmApi()) tmApi().send({ type: 'STOP' });
127
132
  if (_wsListener && window.wsManager) { window.wsManager.off('message', _wsListener); _wsListener = null; }
128
133
  wsSend({ type: 'terminal_stop' });
129
134
  }