osborn 0.9.186 → 0.9.188

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.
Files changed (2) hide show
  1. package/dist/index.js +34 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4196,6 +4196,31 @@ async function main() {
4196
4196
  if (ev.newState === 'listening' && voiceQueue.length > 0) {
4197
4197
  setTimeout(() => processVoiceQueue(), 500);
4198
4198
  }
4199
+ // Suppressed-text replay: if TTS was suppressed while user was speaking
4200
+ // and no new user turn arrives within 1.2s, replay the suppressed text directly.
4201
+ // Without this, both sides go silent: agent has no transcript to react to,
4202
+ // user has no audio — deadlock.
4203
+ if (ev.newState === 'listening' && lastInterruption?.suppressedText) {
4204
+ const capturedInterruption = lastInterruption;
4205
+ const capturedText = lastInterruption.suppressedText;
4206
+ setTimeout(() => {
4207
+ if (lastInterruption === capturedInterruption &&
4208
+ lastInterruption.suppressedText === capturedText &&
4209
+ agentState === 'listening' &&
4210
+ userState === 'listening' &&
4211
+ currentSession) {
4212
+ console.log(`🔁 Replaying suppressed text (${capturedText.length} chars) — user returned to listening, no new turn arrived`);
4213
+ lastInterruption.suppressedText = '';
4214
+ try {
4215
+ ;
4216
+ currentSession.say(capturedText);
4217
+ }
4218
+ catch (err) {
4219
+ console.warn('⚠️ Suppressed text replay failed:', err instanceof Error ? err.message : err);
4220
+ }
4221
+ }
4222
+ }, 1200);
4223
+ }
4199
4224
  });
4200
4225
  // ============================================================
4201
4226
  // Interrupt-debug instrumentation (0.9.63) — log every SDK event
@@ -4532,6 +4557,7 @@ async function main() {
4532
4557
  let sessionsForFrontend = [];
4533
4558
  let recentSessionId = null;
4534
4559
  let hasRecentSession = false;
4560
+ let sessionsLoaded = false;
4535
4561
  const sendReady = async () => {
4536
4562
  if (readySent)
4537
4563
  return;
@@ -4542,6 +4568,7 @@ async function main() {
4542
4568
  hasRecentSession,
4543
4569
  recentSessionId,
4544
4570
  sessions: sessionsForFrontend,
4571
+ sessionsLoaded,
4545
4572
  preSelectedSessionId,
4546
4573
  mcpServers: getMcpServerStatusList(config),
4547
4574
  enabledMcpServers: enabledMcpNames,
@@ -4553,7 +4580,7 @@ async function main() {
4553
4580
  });
4554
4581
  };
4555
4582
  const readyInterval = setInterval(sendReady, 2000);
4556
- // Fire immediately (empty session list) so the frontend unblocks right away
4583
+ // Fire immediately (sessionsLoaded:false) so the frontend unblocks right away
4557
4584
  await sendReady();
4558
4585
  setTimeout(() => {
4559
4586
  clearInterval(readyInterval);
@@ -4573,8 +4600,13 @@ async function main() {
4573
4600
  messageCount: s.messageCount,
4574
4601
  fileSize: s.fileSize,
4575
4602
  }));
4603
+ sessionsLoaded = true;
4576
4604
  sendReady();
4577
- }).catch(err => console.warn('listAllClaudeSessions background load failed:', err));
4605
+ }).catch(err => {
4606
+ console.warn('listAllClaudeSessions background load failed:', err);
4607
+ sessionsLoaded = true; // unblock frontend even on error
4608
+ sendReady();
4609
+ });
4578
4610
  // Stop agent_ready retries on user speech
4579
4611
  session.on('input_speech_started', () => {
4580
4612
  readySent = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "osborn",
3
- "version": "0.9.186",
3
+ "version": "0.9.188",
4
4
  "description": "Voice AI coding assistant - local agent that connects to Osborn frontend",
5
5
  "type": "module",
6
6
  "bin": {