agentgui 1.0.221 → 1.0.223

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/lib/speech.js CHANGED
@@ -27,6 +27,12 @@ const POCKET_TTS_VOICES = [
27
27
  ];
28
28
 
29
29
  const PREDEFINED_IDS = new Set(POCKET_TTS_VOICES.filter(v => v.id !== 'default').map(v => v.id));
30
+ const FALLBACK_VOICE = 'cosette';
31
+
32
+ function isVoiceCloningError(err) {
33
+ const msg = (err.message || err.stderr || String(err)).toLowerCase();
34
+ return msg.includes('voice cloning') || msg.includes('could not download the weights');
35
+ }
30
36
  const POCKET_PORT = 8787;
31
37
 
32
38
  const needsPatch = !serverTTS.getVoices(EXTRA_VOICE_DIRS).some(v => v.id === 'alba' && !v.isCustom);
@@ -79,11 +85,19 @@ function getSTT() {
79
85
  return serverSTT.getSTT();
80
86
  }
81
87
 
82
- function synthesize(text, voiceId) {
83
- if (needsPatch && voiceId && PREDEFINED_IDS.has(voiceId)) {
84
- return synthesizeDirect(text, voiceId);
88
+ async function synthesize(text, voiceId) {
89
+ try {
90
+ if (needsPatch && voiceId && PREDEFINED_IDS.has(voiceId)) {
91
+ return await synthesizeDirect(text, voiceId);
92
+ }
93
+ return await serverTTS.synthesize(text, voiceId, EXTRA_VOICE_DIRS);
94
+ } catch (err) {
95
+ if (isVoiceCloningError(err) && voiceId && !PREDEFINED_IDS.has(voiceId)) {
96
+ console.log(`[TTS] Voice cloning failed for "${voiceId}", falling back to ${FALLBACK_VOICE}`);
97
+ return synthesize(text, FALLBACK_VOICE);
98
+ }
99
+ throw err;
85
100
  }
86
- return serverTTS.synthesize(text, voiceId, EXTRA_VOICE_DIRS);
87
101
  }
88
102
 
89
103
  function synthesizeStream(text, voiceId) {
@@ -95,7 +109,27 @@ function synthesizeStream(text, voiceId) {
95
109
  }
96
110
  })();
97
111
  }
98
- return serverTTS.synthesizeStream(text, voiceId, EXTRA_VOICE_DIRS);
112
+ return synthesizeStreamWithFallback(text, voiceId);
113
+ }
114
+
115
+ function synthesizeStreamWithFallback(text, voiceId) {
116
+ let fellBack = false;
117
+ const upstream = serverTTS.synthesizeStream(text, voiceId, EXTRA_VOICE_DIRS);
118
+ return (async function* () {
119
+ try {
120
+ for await (const chunk of upstream) {
121
+ yield chunk;
122
+ }
123
+ } catch (err) {
124
+ if (!fellBack && isVoiceCloningError(err) && voiceId && !PREDEFINED_IDS.has(voiceId)) {
125
+ fellBack = true;
126
+ console.log(`[TTS] Voice cloning failed for "${voiceId}", falling back to ${FALLBACK_VOICE}`);
127
+ yield* synthesizeStream(text, FALLBACK_VOICE);
128
+ } else {
129
+ throw err;
130
+ }
131
+ }
132
+ })();
99
133
  }
100
134
 
101
135
  function getVoices() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentgui",
3
- "version": "1.0.221",
3
+ "version": "1.0.223",
4
4
  "description": "Multi-agent ACP client with real-time communication",
5
5
  "type": "module",
6
6
  "main": "server.js",
@@ -1117,7 +1117,8 @@ class AgentGUIClient {
1117
1117
  async startExecution() {
1118
1118
  const prompt = this.ui.messageInput?.value || '';
1119
1119
  const conv = this.state.currentConversation;
1120
- const agentId = conv?.agentType || this.ui.agentSelector?.value || 'claude-code';
1120
+ const isNewConversation = conv && !conv.messageCount && !this.state.streamingConversations.has(conv.id);
1121
+ const agentId = (isNewConversation ? this.ui.agentSelector?.value : null) || conv?.agentType || this.ui.agentSelector?.value || 'claude-code';
1121
1122
  const model = this.ui.modelSelector?.value || null;
1122
1123
 
1123
1124
  if (!prompt.trim()) {
@@ -1137,6 +1138,7 @@ class AgentGUIClient {
1137
1138
 
1138
1139
  try {
1139
1140
  if (conv?.id) {
1141
+ this.lockAgentAndModel(agentId, model);
1140
1142
  await this.streamToConversation(conv.id, savedPrompt, agentId, model);
1141
1143
  this._confirmOptimisticMessage(pendingId);
1142
1144
  } else {
@@ -1942,7 +1944,6 @@ class AgentGUIClient {
1942
1944
  }
1943
1945
 
1944
1946
  const { conversation } = await response.json();
1945
- this.lockAgentAndModel(agentId, model);
1946
1947
 
1947
1948
  await this.loadConversations();
1948
1949
 
@@ -2018,7 +2019,14 @@ class AgentGUIClient {
2018
2019
  outputEl.appendChild(cached.dom.firstChild);
2019
2020
  }
2020
2021
  this.state.currentConversation = cached.conversation;
2021
- this.lockAgentAndModel(cached.conversation.agentType || 'claude-code', cached.conversation.model || null);
2022
+ const cachedHasActivity = cached.conversation.messageCount > 0 || this.state.streamingConversations.has(conversationId);
2023
+ if (cachedHasActivity) {
2024
+ this.lockAgentAndModel(cached.conversation.agentType || 'claude-code', cached.conversation.model || null);
2025
+ } else {
2026
+ this.unlockAgentAndModel();
2027
+ if (this.ui.agentSelector && cached.conversation.agentType) this.ui.agentSelector.value = cached.conversation.agentType;
2028
+ if (cached.conversation.agentType) this.loadModelsForAgent(cached.conversation.agentType);
2029
+ }
2022
2030
  this.conversationCache.delete(conversationId);
2023
2031
  this.restoreScrollPosition(conversationId);
2024
2032
  this.enableControls();
@@ -2046,7 +2054,14 @@ class AgentGUIClient {
2046
2054
  const { conversation, isActivelyStreaming, latestSession, chunks: rawChunks, totalChunks, messages: allMessages } = await resp.json();
2047
2055
 
2048
2056
  this.state.currentConversation = conversation;
2049
- this.lockAgentAndModel(conversation.agentType || 'claude-code', conversation.model || null);
2057
+ const hasActivity = (allMessages && allMessages.length > 0) || isActivelyStreaming || latestSession || this.state.streamingConversations.has(conversationId);
2058
+ if (hasActivity) {
2059
+ this.lockAgentAndModel(conversation.agentType || 'claude-code', conversation.model || null);
2060
+ } else {
2061
+ this.unlockAgentAndModel();
2062
+ if (this.ui.agentSelector && conversation.agentType) this.ui.agentSelector.value = conversation.agentType;
2063
+ if (conversation.agentType) this.loadModelsForAgent(conversation.agentType);
2064
+ }
2050
2065
 
2051
2066
  const chunks = (rawChunks || []).map(chunk => ({
2052
2067
  ...chunk,