osborn 0.9.85 → 0.9.86
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 +6 -0
- package/dist/recall-client.js +21 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -303,6 +303,12 @@ function startApiServer(workingDir, port) {
|
|
|
303
303
|
req.on('end', () => {
|
|
304
304
|
try {
|
|
305
305
|
const payload = JSON.parse(body);
|
|
306
|
+
// 0.9.86: log every receipt so we can SEE what Recall streams
|
|
307
|
+
// (event type + word count) — the handler was silent, making it
|
|
308
|
+
// impossible to tell whether webhooks arrive or are just filtered.
|
|
309
|
+
const evt = payload?.event ?? 'unknown';
|
|
310
|
+
const wc = (payload?.data?.data?.words ?? []).length;
|
|
311
|
+
console.log(`📨 Recall webhook: event=${evt} words=${wc}`);
|
|
306
312
|
const recall = getRecallClient();
|
|
307
313
|
if (recall)
|
|
308
314
|
recall.handleWebhook(payload);
|
package/dist/recall-client.js
CHANGED
|
@@ -149,9 +149,19 @@ export class RecallClient extends EventEmitter {
|
|
|
149
149
|
const bot = (await res.json());
|
|
150
150
|
return bot.status_changes?.at(-1)?.code ?? 'unknown';
|
|
151
151
|
}
|
|
152
|
+
// 0.9.86: track the last text we emitted per speaker so partials don't
|
|
153
|
+
// spam the LLM with every incremental word — only emit when the utterance
|
|
154
|
+
// grows meaningfully or finalizes.
|
|
155
|
+
#lastEmitted = new Map();
|
|
152
156
|
handleWebhook(payload) {
|
|
153
|
-
//
|
|
154
|
-
|
|
157
|
+
// Accept BOTH finals (transcript.data) AND partials (transcript.partial_data).
|
|
158
|
+
// recallai_streaming in prioritize_low_latency mode emits partials DURING
|
|
159
|
+
// the call and finals lag — ignoring partials (the old behavior) meant no
|
|
160
|
+
// live transcript at all (confirmed 2026-07-29: 0 webhook-processed turns
|
|
161
|
+
// mid-call). We emit partials for liveness, deduped against the last text.
|
|
162
|
+
const isFinal = payload.event === 'transcript.data';
|
|
163
|
+
const isPartial = payload.event === 'transcript.partial_data';
|
|
164
|
+
if (!isFinal && !isPartial)
|
|
155
165
|
return;
|
|
156
166
|
const words = payload.data?.data?.words ?? [];
|
|
157
167
|
const text = words.map(w => w.text).join(' ').trim();
|
|
@@ -159,7 +169,15 @@ export class RecallClient extends EventEmitter {
|
|
|
159
169
|
return;
|
|
160
170
|
const speaker = payload.data?.data?.participant?.name ?? 'Unknown';
|
|
161
171
|
const botId = payload.data?.bot?.id ?? 'unknown';
|
|
162
|
-
|
|
172
|
+
const key = `${botId}:${speaker}`;
|
|
173
|
+
// Dedup: skip a partial that just repeats/prefixes what we already sent.
|
|
174
|
+
const prev = this.#lastEmitted.get(key) ?? '';
|
|
175
|
+
if (!isFinal && (text === prev || (prev && text.startsWith(prev) && text.length - prev.length < 8)))
|
|
176
|
+
return;
|
|
177
|
+
this.#lastEmitted.set(key, text);
|
|
178
|
+
if (isFinal)
|
|
179
|
+
this.#lastEmitted.delete(key); // reset for the next utterance
|
|
180
|
+
this.emit('transcript', { botId, speaker, text, partial: !isFinal });
|
|
163
181
|
}
|
|
164
182
|
registerBot(botId, sessionId) {
|
|
165
183
|
this.#activeBots.set(botId, sessionId);
|