neoagent 2.3.1-beta.43 → 2.3.1-beta.44

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": "neoagent",
3
- "version": "2.3.1-beta.43",
3
+ "version": "2.3.1-beta.44",
4
4
  "description": "Proactive personal AI agent with no limits",
5
5
  "license": "MIT",
6
6
  "main": "server/index.js",
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"42d3d75a56efe1a2e9902f52dc8006099c45d9
37
37
 
38
38
  _flutter.loader.load({
39
39
  serviceWorkerSettings: {
40
- serviceWorkerVersion: "555509852" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
40
+ serviceWorkerVersion: "705842576" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
41
41
  }
42
42
  });
@@ -468,8 +468,6 @@ class VoiceRuntimeManager {
468
468
  provider: session.voiceSettings?.liveProvider,
469
469
  model: session.voiceSettings?.liveTtsModel,
470
470
  voice: session.voiceSettings?.liveVoice,
471
- transport: 'wearable',
472
- responseFormat: 'wav',
473
471
  });
474
472
  const spokenContent = sanitizeSpeechText(content);
475
473
 
@@ -481,6 +479,7 @@ class VoiceRuntimeManager {
481
479
  for (const attempt of ttsAttempts) {
482
480
  index = 0;
483
481
  streamError = null;
482
+ let attemptChunks = 0;
484
483
  try {
485
484
  await synthesizeVoiceReplyStream(
486
485
  spokenContent,
@@ -494,13 +493,21 @@ class VoiceRuntimeManager {
494
493
  audioBase64: audioBytes.toString('base64'),
495
494
  mimeType,
496
495
  });
496
+ attemptChunks += 1;
497
497
  index += 1;
498
498
  },
499
499
  );
500
+ if (attemptChunks === 0) {
501
+ throw new Error(`${attempt.provider} TTS produced no audio chunks.`);
502
+ }
500
503
  streamError = null;
501
504
  break;
502
505
  } catch (error) {
503
506
  streamError = String(error?.message || error || 'Voice playback failed.');
507
+ console.warn(`[VoiceRuntime] ${attempt.provider} TTS failed for flutter session ${sessionId}: ${streamError}`);
508
+ if (attemptChunks > 0) {
509
+ break;
510
+ }
504
511
  }
505
512
  }
506
513
  } catch (error) {
@@ -559,6 +566,7 @@ class VoiceRuntimeManager {
559
566
  for (const attempt of ttsAttempts) {
560
567
  index = 0;
561
568
  streamError = null;
569
+ let attemptChunks = 0;
562
570
  try {
563
571
  await synthesizeVoiceReplyStream(
564
572
  spokenContent,
@@ -573,12 +581,20 @@ class VoiceRuntimeManager {
573
581
  audioBase64: audioBytes.toString('base64'),
574
582
  mimeType,
575
583
  }));
584
+ attemptChunks += 1;
576
585
  index += 1;
577
586
  },
578
587
  );
588
+ if (attemptChunks === 0) {
589
+ throw new Error(`${attempt.provider} TTS produced no audio chunks.`);
590
+ }
579
591
  break;
580
592
  } catch (error) {
581
593
  streamError = String(error?.message || error || 'Voice playback failed.');
594
+ console.warn(`[VoiceRuntime] ${attempt.provider} TTS failed for wearable session ${sessionId}: ${streamError}`);
595
+ if (attemptChunks > 0) {
596
+ break;
597
+ }
582
598
  }
583
599
  }
584
600
  } catch (error) {
@@ -64,10 +64,17 @@ function toBoolean(value, fallback = false) {
64
64
  return fallback;
65
65
  }
66
66
 
67
- function selectGithubRelease(releases, channel) {
67
+ function releaseHasAsset(release, assetName) {
68
+ return Boolean(selectReleaseAsset(release, assetName));
69
+ }
70
+
71
+ function selectGithubRelease(releases, channel, assetName = null) {
68
72
  const normalizedChannel = normalizeChannel(channel);
69
73
  if (normalizedChannel === 'stable') {
70
- return Array.isArray(releases) ? releases.find((release) => release && release.prerelease === false && release.draft === false) || null : null;
74
+ const candidates = Array.isArray(releases)
75
+ ? releases.filter((release) => release && release.prerelease === false && release.draft === false)
76
+ : [];
77
+ return candidates.find((release) => !assetName || releaseHasAsset(release, assetName)) || candidates[0] || null;
71
78
  }
72
79
 
73
80
  const betaPattern = /-beta(?:\.\d+)?$/i;
@@ -79,7 +86,7 @@ function selectGithubRelease(releases, channel) {
79
86
  const leftPublished = Date.parse(left?.published_at ?? left?.created_at ?? '') || 0;
80
87
  return rightPublished - leftPublished;
81
88
  });
82
- return candidates[0] || null;
89
+ return candidates.find((release) => !assetName || releaseHasAsset(release, assetName)) || candidates[0] || null;
83
90
  }
84
91
 
85
92
  function selectReleaseAsset(release, assetName) {
@@ -161,13 +168,10 @@ function parseChecksumBody(body, assetName) {
161
168
  return null;
162
169
  }
163
170
 
164
- async function fetchGithubRelease(fetchImpl, repository, channel, token) {
171
+ async function fetchGithubRelease(fetchImpl, repository, channel, token, assetName = null) {
165
172
  const normalizedChannel = normalizeChannel(channel);
166
- if (normalizedChannel === 'stable') {
167
- return fetchGithubJson(fetchImpl, `https://api.github.com/repos/${repository}/releases/latest`, token);
168
- }
169
173
  const releases = await fetchGithubJson(fetchImpl, `https://api.github.com/repos/${repository}/releases?per_page=100`, token);
170
- const release = selectGithubRelease(releases, normalizedChannel);
174
+ const release = selectGithubRelease(releases, normalizedChannel, assetName);
171
175
  if (!release) {
172
176
  const error = new Error(`No ${normalizedChannel} firmware release found for ${repository}`);
173
177
  error.status = 404;
@@ -260,7 +264,7 @@ async function resolveFirmwareManifest({
260
264
 
261
265
  try {
262
266
  const token = getGithubToken();
263
- const release = await fetchGithubRelease(fetchImpl, repository, normalizedChannel, token);
267
+ const release = await fetchGithubRelease(fetchImpl, repository, normalizedChannel, token, assetName);
264
268
  const asset = selectReleaseAsset(release, assetName);
265
269
  if (!asset || !asset.browser_download_url) {
266
270
  return {