@chatpanel/gateway 0.6.70 → 0.6.71
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 +1 -1
- package/src/server.js +1 -1
- package/src/stt-engine.js +13 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chatpanel/gateway",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.71",
|
|
4
4
|
"description": "Local privacy gateway \u2014 redacts PII out of OpenAI/Anthropic API traffic before it reaches a model, then restores it in the reply. Point opencode, codex, aider, Claude Code, etc. at it.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/server.js
CHANGED
|
@@ -56,7 +56,7 @@ import * as openai from './openai.js';
|
|
|
56
56
|
import * as responses from './responses.js';
|
|
57
57
|
import * as anthropic from './anthropic.js';
|
|
58
58
|
|
|
59
|
-
export const VERSION = '0.6.
|
|
59
|
+
export const VERSION = '0.6.71';
|
|
60
60
|
|
|
61
61
|
// WARM search tier — SQLite + FTS5 record store (falls back to an encrypted-JSON
|
|
62
62
|
// store if SQLite can't load), fed by the extension's ingest sync + backup-ingest.
|
package/src/stt-engine.js
CHANGED
|
@@ -422,6 +422,18 @@ async function decodeSession(s, { flush = false } = {}) {
|
|
|
422
422
|
const tooLong = audio.length >= MAX_SEGMENT_S * SAMPLE_RATE;
|
|
423
423
|
const overflow = audio.length >= MAX_BUFFER_S * SAMPLE_RATE;
|
|
424
424
|
if (flush || trailingQuiet || tooLong || overflow) {
|
|
425
|
+
// WHY THIS SEGMENT WAS COMMITTED — and it is not always because the speaker finished.
|
|
426
|
+
//
|
|
427
|
+
// Four situations produced an identical `final`, and a client could not tell them apart:
|
|
428
|
+
// the session ending and a trailing pause are the end of a TURN; the length and buffer
|
|
429
|
+
// caps are this engine cutting a segment it cannot hold any longer, mid-sentence, while
|
|
430
|
+
// the speaker is still going. In dictation the difference does not matter — either way
|
|
431
|
+
// the text is appended. In a voice CONVERSATION every final is SENT, so a long sentence
|
|
432
|
+
// was cut at twelve seconds and half of it asked as a question:
|
|
433
|
+
// "…you should just continuously listen to it and then" → sent, answered, lost.
|
|
434
|
+
// Both fields are ADDITIVE: an older client ignores them and behaves exactly as before.
|
|
435
|
+
const reason = flush ? 'flush' : trailingQuiet ? 'silence' : overflow ? 'overflow' : 'length';
|
|
436
|
+
const endOfTurn = reason === 'flush' || reason === 'silence';
|
|
425
437
|
// Commit: the open segment becomes a final; the buffer restarts empty.
|
|
426
438
|
s.chunks = []; s.samples = 0; s.lastInterim = '';
|
|
427
439
|
// Diarize this committed segment (opt-in): embed its audio, cluster → speaker.
|
|
@@ -433,7 +445,7 @@ async function decodeSession(s, { flush = false } = {}) {
|
|
|
433
445
|
speaker = s.diarizer.assign(vec, { pinnedLabel: s.speakerLabel });
|
|
434
446
|
} catch { /* diarization is additive — a failure never drops the transcript */ }
|
|
435
447
|
}
|
|
436
|
-
emit(s,
|
|
448
|
+
emit(s, { type: 'final', text, reason, endOfTurn, ...(speaker ? { speaker } : {}) });
|
|
437
449
|
} else if (text !== s.lastInterim) {
|
|
438
450
|
s.lastInterim = text;
|
|
439
451
|
emit(s, { type: 'interim', text });
|