osborn 0.9.79 ā 0.9.81
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/dist/index.js +43 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1237,6 +1237,8 @@ async function main() {
|
|
|
1237
1237
|
// Track state
|
|
1238
1238
|
let pendingSessionClose = null; // Tracks async session close for reconnect safety
|
|
1239
1239
|
let currentSession = null;
|
|
1240
|
+
// 0.9.81: callable handler reference ā see registration site for why.
|
|
1241
|
+
let participantConnectedHandler = null;
|
|
1240
1242
|
let currentAgent = null; // For updateChatCtx() context injection
|
|
1241
1243
|
let currentLLM = null;
|
|
1242
1244
|
// Agent-side "alone in room" leave timer (see Room-presence lifecycle note up
|
|
@@ -1361,6 +1363,36 @@ async function main() {
|
|
|
1361
1363
|
console.error('š§ [ZOMBIE-WATCHDOG] poll error:', err instanceof Error ? err.message : err);
|
|
1362
1364
|
}
|
|
1363
1365
|
}, WATCHDOG_POLL_MS);
|
|
1366
|
+
// āā 0.9.80: Event-loss adopter (poll-based) āā
|
|
1367
|
+
// After a leave/rejoin cycle the same Room instance can stop delivering
|
|
1368
|
+
// ParticipantConnected entirely ā observed 2026-07-28: the leave-room guard
|
|
1369
|
+
// saw "1 participant(s) still in room" while the agent sat at "Waiting for
|
|
1370
|
+
// user to connect" (state knew, events never fired; user stuck on
|
|
1371
|
+
// "Connecting..." forever). Same blind-spot family as the zombie watchdog:
|
|
1372
|
+
// never trust the event stream alone. Every 5s: participant present but no
|
|
1373
|
+
// voice session ā re-emit ParticipantConnected (60s per-identity cooldown
|
|
1374
|
+
// so a slow in-flight session creation isn't double-fired).
|
|
1375
|
+
const adoptAttempts = new Map();
|
|
1376
|
+
setInterval(() => {
|
|
1377
|
+
try {
|
|
1378
|
+
if (livekitState.status !== 'connected')
|
|
1379
|
+
return;
|
|
1380
|
+
if (currentSession)
|
|
1381
|
+
return;
|
|
1382
|
+
const p = room.remoteParticipants.values().next().value;
|
|
1383
|
+
if (!p)
|
|
1384
|
+
return;
|
|
1385
|
+
const last = adoptAttempts.get(p.identity) ?? 0;
|
|
1386
|
+
if (Date.now() - last < 60_000)
|
|
1387
|
+
return;
|
|
1388
|
+
adoptAttempts.set(p.identity, Date.now());
|
|
1389
|
+
console.log(`š„ [ADOPT-POLL] ${p.identity} present with no session ā invoking ParticipantConnected handler directly`);
|
|
1390
|
+
participantConnectedHandler?.(p).catch((e) => console.error('š„ [ADOPT-POLL] handler error:', e instanceof Error ? e.message : e));
|
|
1391
|
+
}
|
|
1392
|
+
catch (err) {
|
|
1393
|
+
console.error('š„ [ADOPT-POLL] error:', err instanceof Error ? err.message : err);
|
|
1394
|
+
}
|
|
1395
|
+
}, 5_000);
|
|
1364
1396
|
/**
|
|
1365
1397
|
* Hard-kill the in-flight Claude SDK query AND the persistent subprocess.
|
|
1366
1398
|
*
|
|
@@ -3037,7 +3069,13 @@ async function main() {
|
|
|
3037
3069
|
console.error('ā Reconnect attempt threw (should not happen ā connectWithRetry loops):', err);
|
|
3038
3070
|
});
|
|
3039
3071
|
});
|
|
3040
|
-
|
|
3072
|
+
// 0.9.81: handler extracted to a named reference so the adopt-poll and
|
|
3073
|
+
// /connect-room adopt can CALL it directly. Synthetic `room.emit(...)` does
|
|
3074
|
+
// NOT reach listeners on rtc-node's Room (observed 2026-07-28: ADOPT-POLL
|
|
3075
|
+
// re-emitted for three successive participants, zero sessions created) ā
|
|
3076
|
+
// the event dispatch is internal, so direct invocation is the only
|
|
3077
|
+
// reliable path for state-driven adoption.
|
|
3078
|
+
participantConnectedHandler = async (participant) => {
|
|
3041
3079
|
console.log(`\nš¤ User joined: ${participant.identity}`);
|
|
3042
3080
|
// A user is present ā cancel any pending agent-side "alone" leave.
|
|
3043
3081
|
if (aloneTimer) {
|
|
@@ -3899,7 +3937,8 @@ async function main() {
|
|
|
3899
3937
|
catch (err) {
|
|
3900
3938
|
console.error('ā Failed to start session:', err);
|
|
3901
3939
|
}
|
|
3902
|
-
}
|
|
3940
|
+
};
|
|
3941
|
+
room.on(RoomEvent.ParticipantConnected, (p) => { participantConnectedHandler?.(p); });
|
|
3903
3942
|
room.on(RoomEvent.ParticipantDisconnected, (participant) => {
|
|
3904
3943
|
console.log(`š User left: ${participant.identity}`);
|
|
3905
3944
|
// Full cleanup ā stop all background work to avoid accumulating API usage
|
|
@@ -4780,8 +4819,8 @@ async function main() {
|
|
|
4780
4819
|
// Re-emit the event for every pre-existing participant so the session is
|
|
4781
4820
|
// created exactly as if they had joined after us.
|
|
4782
4821
|
for (const p of room.remoteParticipants.values()) {
|
|
4783
|
-
console.log(`š„ Participant already in room at join: ${p.identity} ā adopting (
|
|
4784
|
-
|
|
4822
|
+
console.log(`š„ Participant already in room at join: ${p.identity} ā adopting (invoking handler directly)`);
|
|
4823
|
+
participantConnectedHandler?.(p).catch((e) => console.error('š„ adopt handler error:', e instanceof Error ? e.message : e));
|
|
4785
4824
|
}
|
|
4786
4825
|
};
|
|
4787
4826
|
// 0.9.73: explicit frontend leave should also start the idle-exit countdown ā
|