@burdenoff/fe-libs 2026.1004.3 → 2026.1004.5
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/chrome/mobileTabBar/useVisibleNavItems.d.ts +9 -0
- package/dist/chrome/mobileTabBar/useVisibleNavItems.d.ts.map +1 -1
- package/dist/chrome/mobileTabBar/useVisibleNavItems.js +3 -1
- package/dist/shared/assistant/api.d.ts +6 -0
- package/dist/shared/assistant/api.d.ts.map +1 -1
- package/dist/shared/assistant/api.js +5 -3
- package/dist/shared/assistant/i18nManifest.d.ts +13 -0
- package/dist/shared/assistant/i18nManifest.d.ts.map +1 -1
- package/dist/shared/assistant/i18nManifest.js +25 -12
- package/dist/shared/assistant/index.d.ts +11 -0
- package/dist/shared/assistant/index.d.ts.map +1 -1
- package/dist/shared/assistant/localUiCommandCopy.d.ts +18 -0
- package/dist/shared/assistant/localUiCommandCopy.d.ts.map +1 -1
- package/dist/shared/assistant/localUiCommandCopy.js +22 -2
- package/dist/shared/assistant/localUiCommands.d.ts +63 -26
- package/dist/shared/assistant/localUiCommands.d.ts.map +1 -1
- package/dist/shared/assistant/localUiCommands.js +128 -59
- package/dist/shared/assistant/store.d.ts +10 -0
- package/dist/shared/assistant/store.d.ts.map +1 -1
- package/dist/shared/assistant/store.js +52 -44
- package/dist/shared/assistant/ui/AssistantChatArea.d.ts.map +1 -1
- package/dist/shared/assistant/ui/AssistantChatArea.js +1023 -874
- package/dist/shared/assistant/ui/AssistantMarkdownRenderer.d.ts +3 -34
- package/dist/shared/assistant/ui/AssistantMarkdownRenderer.d.ts.map +1 -1
- package/dist/shared/assistant/ui/AssistantMarkdownRenderer.js +83 -119
- package/dist/shared/assistant/ui/AssistantMoreMenu.d.ts.map +1 -1
- package/dist/shared/assistant/ui/AssistantMoreMenu.js +58 -56
- package/dist/shared/assistant/ui/AssistantSpeechProvider.d.ts.map +1 -1
- package/dist/shared/assistant/ui/AssistantSpeechProvider.js +106 -105
- package/dist/shared/assistant/ui/composer/AssistantConnectSourceItem.js +2 -1
- package/dist/shared/assistant/ui/composer/AssistantVoiceGraceSelector.d.ts +20 -0
- package/dist/shared/assistant/ui/composer/AssistantVoiceGraceSelector.d.ts.map +1 -0
- package/dist/shared/assistant/ui/composer/AssistantVoiceGraceSelector.js +39 -0
- package/dist/shared/assistant/ui/composer/connectSource.js +2 -1
- package/dist/shared/assistant/ui/useVoiceSession.d.ts +35 -2
- package/dist/shared/assistant/ui/useVoiceSession.d.ts.map +1 -1
- package/dist/shared/assistant/ui/useVoiceSession.js +232 -171
- package/dist/shared/assistant/ui/voice/AssistantVoiceSession.d.ts +15 -1
- package/dist/shared/assistant/ui/voice/AssistantVoiceSession.d.ts.map +1 -1
- package/dist/shared/assistant/ui/voice/AssistantVoiceSession.js +121 -101
- package/dist/shared/assistant/uiActions/assistantHref.d.ts +36 -0
- package/dist/shared/assistant/uiActions/assistantHref.d.ts.map +1 -0
- package/dist/shared/assistant/uiActions/assistantHref.js +46 -0
- package/dist/shared/assistant/uiActions/deixis.d.ts +29 -0
- package/dist/shared/assistant/uiActions/deixis.d.ts.map +1 -0
- package/dist/shared/assistant/uiActions/deixis.js +54 -0
- package/dist/shared/assistant/uiActions/entityRoutes.d.ts +49 -0
- package/dist/shared/assistant/uiActions/entityRoutes.d.ts.map +1 -0
- package/dist/shared/assistant/uiActions/entityRoutes.js +53 -0
- package/dist/shared/assistant/uiActions/inAppLinks.d.ts +28 -0
- package/dist/shared/assistant/uiActions/inAppLinks.d.ts.map +1 -0
- package/dist/shared/assistant/uiActions/inAppLinks.js +51 -0
- package/dist/shared/assistant/uiActions/linkContext.d.ts +52 -0
- package/dist/shared/assistant/uiActions/linkContext.d.ts.map +1 -0
- package/dist/shared/assistant/uiActions/linkContext.js +60 -0
- package/dist/shared/assistant/uiActions/recordNames.d.ts +73 -0
- package/dist/shared/assistant/uiActions/recordNames.d.ts.map +1 -0
- package/dist/shared/assistant/uiActions/recordNames.js +75 -0
- package/dist/shared/assistant/uiActions/resolveTarget.d.ts +43 -0
- package/dist/shared/assistant/uiActions/resolveTarget.d.ts.map +1 -0
- package/dist/shared/assistant/uiActions/resolveTarget.js +49 -0
- package/dist/shared/assistant/uiActions/uiCatalogue.d.ts +30 -0
- package/dist/shared/assistant/uiActions/uiCatalogue.d.ts.map +1 -0
- package/dist/shared/assistant/uiActions/uiCatalogue.js +22 -0
- package/dist/shared/assistant/voice/handsFree.d.ts +160 -0
- package/dist/shared/assistant/voice/handsFree.d.ts.map +1 -0
- package/dist/shared/assistant/voice/handsFree.js +104 -0
- package/dist/shared/assistant/voice/supersededTurns.d.ts +29 -0
- package/dist/shared/assistant/voice/supersededTurns.d.ts.map +1 -0
- package/dist/shared/assistant/voice/supersededTurns.js +17 -0
- package/dist/shared/assistant/voice/useVoiceInput.d.ts +7 -0
- package/dist/shared/assistant/voice/useVoiceInput.d.ts.map +1 -1
- package/dist/shared/assistant/voice/useVoiceInput.js +13 -10
- package/dist/shared/assistant/voice/voiceSession.d.ts +64 -20
- package/dist/shared/assistant/voice/voiceSession.d.ts.map +1 -1
- package/dist/shared/assistant/voice/voiceSession.js +120 -67
- package/dist/shared/components/assistantWidget/MessageContent.js +4 -3
- package/dist/shared-assistant.js +206 -195
- package/package.json +3 -1
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hands-free voice, steps H1 and H2 — the pure rules (BOFF hands-free slice).
|
|
3
|
+
*
|
|
4
|
+
* Everything here is data in, decision out: no DOM, no timers, no React, for
|
|
5
|
+
* the reason `voiceSession.ts` gives (this repo's unit runner has no browser).
|
|
6
|
+
* The hook (`useVoiceSession`) owns the clock and the recogniser; this file
|
|
7
|
+
* owns what the words and the preference MEAN.
|
|
8
|
+
*
|
|
9
|
+
* ★ H1 — the end-of-speech grace is a USER PREFERENCE (2 s default, 3 s, 5 s),
|
|
10
|
+
* and there is exactly ONE timing owner: `planSubmitTimer`. The old
|
|
11
|
+
* `SILENCE_SUBMIT_MS` constant is gone; the value the timer waits is the
|
|
12
|
+
* preference, resolved by `resolveVoiceGraceMs`. Nothing else in the package
|
|
13
|
+
* waits before submitting a spoken turn (`ENDPOINT_GRACE_MS` only decides when
|
|
14
|
+
* the stage SHOWS the pause, and is clamped inside the grace).
|
|
15
|
+
*
|
|
16
|
+
* ★ H2 — corrections while the assistant is still PREPARING an answer. The
|
|
17
|
+
* microphone stays open in `thinking`, so a recogniser can deliver three kinds
|
|
18
|
+
* of result there, and telling them apart is the whole difficulty:
|
|
19
|
+
* 1. a trailing result of the turn JUST submitted (Chrome finalises late;
|
|
20
|
+
* Chrome Android re-sends the whole utterance, sometimes revised) — must
|
|
21
|
+
* be ignored, or every spoken question is aborted and sent twice;
|
|
22
|
+
* 2. noise and fillers ("uh", "hmm") — must not abort a model turn;
|
|
23
|
+
* 3. a person speaking — a correction: the turn is superseded.
|
|
24
|
+
* `planThinkingSpeech` is that classification.
|
|
25
|
+
*
|
|
26
|
+
* A spoken "yes" never commits a business write. In `thinking` a bare
|
|
27
|
+
* affirmation is therefore NOT a correction at all: it neither aborts the turn
|
|
28
|
+
* nor withdraws anything (`classifyWriteReply` is the same classifier the 5a
|
|
29
|
+
* binder uses). The binder, and the card's button, stay the only way a change
|
|
30
|
+
* is confirmed.
|
|
31
|
+
*/
|
|
32
|
+
/** The choices offered in the voice settings, shortest first. */
|
|
33
|
+
export declare const VOICE_GRACE_CHOICES_MS: readonly [2000, 3000, 5000];
|
|
34
|
+
export type VoiceGraceMs = (typeof VOICE_GRACE_CHOICES_MS)[number];
|
|
35
|
+
/**
|
|
36
|
+
* How long the user must stop talking before the turn is submitted, until they
|
|
37
|
+
* choose otherwise.
|
|
38
|
+
*
|
|
39
|
+
* ★ 2000, not 1200: 1.2 s does not survive an ordinary pause. Once a turn is
|
|
40
|
+
* submitted the reducer discards the rest of the sentence, so cutting someone
|
|
41
|
+
* off costs the whole round trip AND makes them repeat themselves — waiting
|
|
42
|
+
* 800 ms longer costs only a moment of silence. The asymmetry is what settled
|
|
43
|
+
* the number, and it is why the longer choices exist for people who pause more.
|
|
44
|
+
*/
|
|
45
|
+
export declare const DEFAULT_VOICE_GRACE_MS: VoiceGraceMs;
|
|
46
|
+
/**
|
|
47
|
+
* Read a stored or passed value as one of the offered choices.
|
|
48
|
+
*
|
|
49
|
+
* Anything else — a stale number from an older build, a string, `null`, a value
|
|
50
|
+
* hand-edited into storage — is the default, never a nearby choice: a grace of
|
|
51
|
+
* 0 or 600000 ms read back from storage would either submit mid-word or never
|
|
52
|
+
* submit at all.
|
|
53
|
+
*/
|
|
54
|
+
export declare function resolveVoiceGraceMs(value: unknown): VoiceGraceMs;
|
|
55
|
+
/**
|
|
56
|
+
* The ONE decision about the submit timer.
|
|
57
|
+
*
|
|
58
|
+
* `arm` is true only for a listening, unmuted session with something worth
|
|
59
|
+
* sending, and NOT while the person asked to finish in their own time
|
|
60
|
+
* ("Let me finish", `holding`). `delayMs` is the preference. The hook re-asks
|
|
61
|
+
* on every change of the session, so new speech cancels a pending submit and
|
|
62
|
+
* the turn continues — there is no second timer to forget.
|
|
63
|
+
*/
|
|
64
|
+
export declare function planSubmitTimer(input: {
|
|
65
|
+
phase: string;
|
|
66
|
+
muted: boolean;
|
|
67
|
+
/** Everything heard this turn (`spokenSoFar`). */
|
|
68
|
+
spoken: string;
|
|
69
|
+
/** "Let me finish" is on: nothing is submitted until the person says done. */
|
|
70
|
+
holding: boolean;
|
|
71
|
+
/** The preference, in ms. */
|
|
72
|
+
graceMs: number;
|
|
73
|
+
}): {
|
|
74
|
+
arm: boolean;
|
|
75
|
+
delayMs: number;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* The comparable words of a transcript: letters, marks and digits only (marks
|
|
79
|
+
* kept — Tamil and Hindi vowel signs are marks), lower-cased. Punctuation and
|
|
80
|
+
* capitals a final adds are not speech.
|
|
81
|
+
*/
|
|
82
|
+
export declare function speechWords(text: string): string[];
|
|
83
|
+
/**
|
|
84
|
+
* Add a newly finalised phrase to the turn heard so far.
|
|
85
|
+
*
|
|
86
|
+
* ★ Chrome Android duplicates finals. With `continuous` on, a restarted
|
|
87
|
+
* recogniser can re-send the phrase it just finalised, and it often re-sends
|
|
88
|
+
* the WHOLE utterance so far with a few words added. Plain concatenation turned
|
|
89
|
+
* "when should I sow" into "when should I sow when should I sow ragi" and sent
|
|
90
|
+
* that. So:
|
|
91
|
+
* - a phrase that STARTS WITH everything heard is the same utterance, longer
|
|
92
|
+
* or equal: it replaces what was heard;
|
|
93
|
+
* - a phrase of two or more words that the turn already ENDS with is a
|
|
94
|
+
* repeat: dropped;
|
|
95
|
+
* - anything else is new speech: appended.
|
|
96
|
+
* A single repeated word is kept unless it is the whole turn — "no no" is
|
|
97
|
+
* emphasis, but a lone "hello" arriving twice is the recogniser.
|
|
98
|
+
*/
|
|
99
|
+
export declare function mergeFinalPhrase(pending: string, phrase: string): string;
|
|
100
|
+
/**
|
|
101
|
+
* A transcript without the words of the turn it follows, when it starts with
|
|
102
|
+
* them (a cumulative result: "when should I sow ragi" after "when should I
|
|
103
|
+
* sow"). Anything else is returned unchanged.
|
|
104
|
+
*/
|
|
105
|
+
export declare function stripSubmittedPrefix(transcript: string, submitted: string): string;
|
|
106
|
+
/**
|
|
107
|
+
* How long after a turn is submitted its OWN trailing results may still arrive.
|
|
108
|
+
*
|
|
109
|
+
* The person was silent for the whole grace (2 s at least), so anything
|
|
110
|
+
* arriving this soon after the submit and resembling what was sent is the
|
|
111
|
+
* recogniser finishing the sentence, not a correction. Past it, only an exact
|
|
112
|
+
* repeat is ignored — a person correcting "plant ragi in June" with "no plant
|
|
113
|
+
* ragi in July" is speaking, however alike the words are.
|
|
114
|
+
*/
|
|
115
|
+
export declare const TRAILING_RESULT_WINDOW_MS = 1500;
|
|
116
|
+
/**
|
|
117
|
+
* Is this transcript the recogniser finishing, repeating or revising the turn
|
|
118
|
+
* that was just submitted?
|
|
119
|
+
*
|
|
120
|
+
* `sinceSubmitMs` is null when unknown (no clock): then only an exact repeat
|
|
121
|
+
* counts, which can only ever err towards treating speech as speech.
|
|
122
|
+
*/
|
|
123
|
+
export declare function isTrailingResultOfSubmitted(transcript: string, submitted: string, sinceSubmitMs: number | null): boolean;
|
|
124
|
+
/**
|
|
125
|
+
* Is this a person speaking, rather than noise?
|
|
126
|
+
*
|
|
127
|
+
* Aborting a model turn costs the turn, so the bar is two letters or digits
|
|
128
|
+
* that are not all filler. "no" and "ok" pass; "a", "uh" and "hmm" do not. A
|
|
129
|
+
* single Han, kana or Hangul character passes — "不" is a whole word.
|
|
130
|
+
*/
|
|
131
|
+
export declare function isGenuineUserSpeech(text: string): boolean;
|
|
132
|
+
/** What a result heard while the answer is being prepared amounts to. */
|
|
133
|
+
export type ThinkingSpeechPlan = {
|
|
134
|
+
kind: "ignore";
|
|
135
|
+
reason: "empty" | "trailing" | "noise" | "affirmation";
|
|
136
|
+
} | {
|
|
137
|
+
kind: "supersede";
|
|
138
|
+
/** What the person said, without the words of the turn it corrects. */
|
|
139
|
+
text: string;
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* Classify a result that arrives while the assistant is PREPARING an answer.
|
|
143
|
+
*
|
|
144
|
+
* Ignored: nothing; the recogniser finishing, repeating or revising the turn
|
|
145
|
+
* just submitted; noise; and a bare affirmation (a spoken "yes" is never a
|
|
146
|
+
* correction, and never commits a write — see the header). Everything else is
|
|
147
|
+
* a correction.
|
|
148
|
+
*
|
|
149
|
+
* Echo is not checked here: nothing plays during `thinking`. The caller still
|
|
150
|
+
* passes the previous reply through `isEcho` first, because its tail can sound
|
|
151
|
+
* for a moment after playback ends.
|
|
152
|
+
*/
|
|
153
|
+
export declare function planThinkingSpeech(input: {
|
|
154
|
+
transcript: string;
|
|
155
|
+
/** The turn in flight, as it was sent. */
|
|
156
|
+
submitted: string;
|
|
157
|
+
/** Milliseconds since it was sent, or null when no clock was given. */
|
|
158
|
+
sinceSubmitMs: number | null;
|
|
159
|
+
}): ThinkingSpeechPlan;
|
|
160
|
+
//# sourceMappingURL=handsFree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handsFree.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/voice/handsFree.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAQH,iEAAiE;AACjE,eAAO,MAAM,sBAAsB,6BAA8B,CAAC;AAElE,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnE;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,EAAE,YAAmB,CAAC;AAEzD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAEhE;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,OAAO,EAAE,OAAO,CAAC;IACjB,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAIpC;AAMD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAMlD;AA6BD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAQxE;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAelF;AAMD;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAK9C;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GAAG,IAAI,GAC3B,OAAO,CAYT;AAyBD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOzD;AAED,yEAAyE;AACzE,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,aAAa,CAAA;CAAE,GAC1E;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEN;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B,GAAG,kBAAkB,CASrB"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { classifyWriteReply as e } from "../writeReplyBinder.js";
|
|
2
|
+
//#region src/shared/assistant/voice/handsFree.ts
|
|
3
|
+
var t = [
|
|
4
|
+
2e3,
|
|
5
|
+
3e3,
|
|
6
|
+
5e3
|
|
7
|
+
], n = 2e3;
|
|
8
|
+
function r(e) {
|
|
9
|
+
return t.find((t) => t === e) ?? 2e3;
|
|
10
|
+
}
|
|
11
|
+
function i(e) {
|
|
12
|
+
let t = r(e.graceMs);
|
|
13
|
+
return {
|
|
14
|
+
arm: e.phase === "listening" && !e.muted && !e.holding && e.spoken.trim().length > 0,
|
|
15
|
+
delayMs: t
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function a(e) {
|
|
19
|
+
let t = e.toLowerCase().replace(/[^\p{L}\p{M}\p{N}]+/gu, " ").trim();
|
|
20
|
+
return t ? t.split(" ") : [];
|
|
21
|
+
}
|
|
22
|
+
var o = (e, t) => t.length <= e.length && t.every((t, n) => e[n] === t), s = (e, t) => t.length <= e.length && t.every((n, r) => e[e.length - t.length + r] === n), c = (e, t) => {
|
|
23
|
+
if (t.length === 0) return !0;
|
|
24
|
+
for (let n = 0; n + t.length <= e.length; n += 1) if (t.every((t, r) => e[n + r] === t)) return !0;
|
|
25
|
+
return !1;
|
|
26
|
+
};
|
|
27
|
+
function l(e, t) {
|
|
28
|
+
let n = Array(t.length + 1).fill(0);
|
|
29
|
+
for (let r of e) {
|
|
30
|
+
let e = Array(t.length + 1).fill(0);
|
|
31
|
+
for (let i = 1; i <= t.length; i += 1) e[i] = r === t[i - 1] ? (n[i - 1] ?? 0) + 1 : Math.max(n[i] ?? 0, e[i - 1] ?? 0);
|
|
32
|
+
n = e;
|
|
33
|
+
}
|
|
34
|
+
return n[t.length] ?? 0;
|
|
35
|
+
}
|
|
36
|
+
function u(e, t) {
|
|
37
|
+
let n = a(e), r = a(t);
|
|
38
|
+
return r.length === 0 ? e : n.length === 0 || o(r, n) ? t.replace(/\s+/g, " ").trim() : r.length >= 2 && s(n, r) ? e : `${e} ${t}`.replace(/\s+/g, " ").trim();
|
|
39
|
+
}
|
|
40
|
+
function d(e, t) {
|
|
41
|
+
let n = a(t);
|
|
42
|
+
if (n.length === 0) return e.replace(/\s+/g, " ").trim();
|
|
43
|
+
let r = e.split(/\s+/).filter(Boolean), i = 0;
|
|
44
|
+
for (let t = 0; t < r.length; t += 1) {
|
|
45
|
+
let o = a(r[t] ?? "");
|
|
46
|
+
if (o.length !== 0) for (let a of o) {
|
|
47
|
+
if (a !== n[i]) return e.replace(/\s+/g, " ").trim();
|
|
48
|
+
if (i += 1, i === n.length) return r.slice(t + 1).join(" ").trim();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return e.replace(/\s+/g, " ").trim();
|
|
52
|
+
}
|
|
53
|
+
var f = 1500, p = .6;
|
|
54
|
+
function m(e, t, n) {
|
|
55
|
+
let r = a(e), i = a(t);
|
|
56
|
+
return r.length === 0 ? !0 : i.length === 0 ? !1 : r.length === i.length && r.every((e, t) => e === i[t]) ? !0 : n === null || n >= 1500 ? !1 : c(i, r) ? !0 : o(r, i) && r.length - i.length >= 2 ? !1 : l(r, i) / Math.max(r.length, i.length) >= p;
|
|
57
|
+
}
|
|
58
|
+
var h = new Set([
|
|
59
|
+
"uh",
|
|
60
|
+
"um",
|
|
61
|
+
"uhm",
|
|
62
|
+
"umm",
|
|
63
|
+
"er",
|
|
64
|
+
"erm",
|
|
65
|
+
"eh",
|
|
66
|
+
"ah",
|
|
67
|
+
"hm",
|
|
68
|
+
"hmm",
|
|
69
|
+
"hmmm",
|
|
70
|
+
"mm",
|
|
71
|
+
"mmm",
|
|
72
|
+
"mhm",
|
|
73
|
+
"huh",
|
|
74
|
+
"oh"
|
|
75
|
+
]), g = /[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}]/u;
|
|
76
|
+
function _(e) {
|
|
77
|
+
let t = a(e);
|
|
78
|
+
if (t.length === 0 || t.every((e) => h.has(e))) return !1;
|
|
79
|
+
let n = [...t.join("")];
|
|
80
|
+
return n.length >= 2 ? !0 : n.length === 1 && g.test(n[0] ?? "");
|
|
81
|
+
}
|
|
82
|
+
function v(t) {
|
|
83
|
+
if (a(t.transcript).length === 0) return {
|
|
84
|
+
kind: "ignore",
|
|
85
|
+
reason: "empty"
|
|
86
|
+
};
|
|
87
|
+
if (m(t.transcript, t.submitted, t.sinceSubmitMs)) return {
|
|
88
|
+
kind: "ignore",
|
|
89
|
+
reason: "trailing"
|
|
90
|
+
};
|
|
91
|
+
let n = d(t.transcript, t.submitted);
|
|
92
|
+
return _(n) ? e(n, "en") === "affirm" ? {
|
|
93
|
+
kind: "ignore",
|
|
94
|
+
reason: "affirmation"
|
|
95
|
+
} : {
|
|
96
|
+
kind: "supersede",
|
|
97
|
+
text: n
|
|
98
|
+
} : {
|
|
99
|
+
kind: "ignore",
|
|
100
|
+
reason: "noise"
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
//#endregion
|
|
104
|
+
export { n as DEFAULT_VOICE_GRACE_MS, f as TRAILING_RESULT_WINDOW_MS, t as VOICE_GRACE_CHOICES_MS, _ as isGenuineUserSpeech, m as isTrailingResultOfSubmitted, u as mergeFinalPhrase, i as planSubmitTimer, v as planThinkingSpeech, r as resolveVoiceGraceMs, a as speechWords, d as stripSubmittedPrefix };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The turns a person has superseded — the stale-turn guard of hands-free
|
|
3
|
+
* corrections (H2).
|
|
4
|
+
*
|
|
5
|
+
* When someone speaks a correction while the assistant is still PREPARING an
|
|
6
|
+
* answer, the in-flight turn is aborted (`POST /sessions/:id/abort`) and then
|
|
7
|
+
* recorded here. Aborting is best-effort and asynchronous, so the old turn can
|
|
8
|
+
* still deliver something afterwards: its reply landing, its speech starting
|
|
9
|
+
* from the speech feed, its text becoming the "latest reply" the caption and
|
|
10
|
+
* the echo reference are built from. Every one of those paths asks THIS module
|
|
11
|
+
* whether the message belongs to a turn that was superseded, and refuses if so:
|
|
12
|
+
* the late answer never restarts audio, never replaces a caption and never
|
|
13
|
+
* advances the next turn.
|
|
14
|
+
*
|
|
15
|
+
* ★ Module scope on purpose, like `speechFeed`: the publisher (the chat area),
|
|
16
|
+
* the speaker (the speech provider) and the voice session are three components
|
|
17
|
+
* that do not know each other, and the guard has to hold across a remount.
|
|
18
|
+
*
|
|
19
|
+
* ★ Bounded. A session is a handful of turns; the oldest ids are dropped first
|
|
20
|
+
* so a long-lived page cannot grow this without limit, and an id this old can
|
|
21
|
+
* no longer be in flight.
|
|
22
|
+
*/
|
|
23
|
+
/** Record that the turn that produced assistant message `messageId` was superseded. */
|
|
24
|
+
export declare function markTurnSuperseded(messageId: string): void;
|
|
25
|
+
/** Was the turn behind `messageId` superseded? Null and undefined never were. */
|
|
26
|
+
export declare function isTurnSuperseded(messageId: string | null | undefined): boolean;
|
|
27
|
+
/** Tests only. */
|
|
28
|
+
export declare function resetSupersededTurnsForTest(): void;
|
|
29
|
+
//# sourceMappingURL=supersededTurns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supersededTurns.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/voice/supersededTurns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAOH,uFAAuF;AACvF,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAQ1D;AAED,iFAAiF;AACjF,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAE9E;AAED,kBAAkB;AAClB,wBAAgB,2BAA2B,IAAI,IAAI,CAElD"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/shared/assistant/voice/supersededTurns.ts
|
|
2
|
+
var e = 64, t = /* @__PURE__ */ new Set();
|
|
3
|
+
function n(n) {
|
|
4
|
+
for (t.delete(n), t.add(n); t.size > e;) {
|
|
5
|
+
let e = t.values().next();
|
|
6
|
+
if (e.done) break;
|
|
7
|
+
t.delete(e.value);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function r(e) {
|
|
11
|
+
return typeof e == "string" && t.has(e);
|
|
12
|
+
}
|
|
13
|
+
function i() {
|
|
14
|
+
t.clear();
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { r as isTurnSuperseded, n as markTurnSuperseded, i as resetSupersededTurnsForTest };
|
|
@@ -31,6 +31,13 @@
|
|
|
31
31
|
* - **`stop()` resolves the final transcript** through `onFinalize`, so the
|
|
32
32
|
* composer can commit exactly once when the user stops.
|
|
33
33
|
*/
|
|
34
|
+
/**
|
|
35
|
+
* Can this browser recognise speech at all? The same test `useVoiceInput`
|
|
36
|
+
* reports as `isSupported`, for surfaces that must decide whether to OFFER a
|
|
37
|
+
* voice setting without mounting the hook (a settings row for a recogniser
|
|
38
|
+
* that does not exist is a control that cannot do anything).
|
|
39
|
+
*/
|
|
40
|
+
export declare function isSpeechRecognitionSupported(): boolean;
|
|
34
41
|
/**
|
|
35
42
|
* How long to refuse a restart after `recognition.start()` THREW.
|
|
36
43
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useVoiceInput.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/voice/useVoiceInput.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AA+DH;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAW5C;;;;;;;;;;GAUG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAE9E;AAED,MAAM,MAAM,eAAe,GACzB,aAAa,GAAG,WAAW,GAAG,eAAe,GAAG,SAAS,GAAG,wBAAwB,GAAG,SAAS,CAAC;AA+BnG,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,8EAA8E;IAC9E,UAAU,EAAE,OAAO,CAAC;IACpB;;;;;;OAMG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,IAAI,CAAC;IACtC,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,uEAAuE;IACvE,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB;AAED,wBAAgB,aAAa,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,oBAAoB,GAAG,mBAAmB,CAmO5G"}
|
|
1
|
+
{"version":3,"file":"useVoiceInput.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/voice/useVoiceInput.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AA+DH;;;;;GAKG;AACH,wBAAgB,4BAA4B,IAAI,OAAO,CAEtD;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAW5C;;;;;;;;;;GAUG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAE9E;AAED,MAAM,MAAM,eAAe,GACzB,aAAa,GAAG,WAAW,GAAG,eAAe,GAAG,SAAS,GAAG,wBAAwB,GAAG,SAAS,CAAC;AA+BnG,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,8EAA8E;IAC9E,UAAU,EAAE,OAAO,CAAC;IACpB;;;;;;OAMG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,KAAK,IAAI,CAAC;IACtC,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,uEAAuE;IACvE,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB;AAED,wBAAgB,aAAa,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,oBAAoB,GAAG,mBAAmB,CAmO5G"}
|
|
@@ -17,11 +17,14 @@ function o() {
|
|
|
17
17
|
let e = window;
|
|
18
18
|
return e.SpeechRecognition ?? e.webkitSpeechRecognition ?? null;
|
|
19
19
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return t - e < s;
|
|
20
|
+
function s() {
|
|
21
|
+
return o() !== null;
|
|
23
22
|
}
|
|
24
|
-
|
|
23
|
+
var c = 2e3, l = 2;
|
|
24
|
+
function u(e, t) {
|
|
25
|
+
return t - e < c;
|
|
26
|
+
}
|
|
27
|
+
function d(e) {
|
|
25
28
|
switch (e) {
|
|
26
29
|
case "not-allowed":
|
|
27
30
|
case "service-not-allowed": return "not-allowed";
|
|
@@ -32,18 +35,18 @@ function u(e) {
|
|
|
32
35
|
default: return "unknown";
|
|
33
36
|
}
|
|
34
37
|
}
|
|
35
|
-
function
|
|
38
|
+
function f({ onFinalize: s, language: c }) {
|
|
36
39
|
let { locale: f } = e(), [p, m] = i(!1), [h, g] = i(!1), [_, v] = i(""), [y, b] = i(null), x = r(null), S = r(0), C = r(-Infinity), w = r(0), T = r(s);
|
|
37
40
|
n(() => {
|
|
38
41
|
T.current = s;
|
|
39
42
|
}, [s]);
|
|
40
|
-
let E = o() !== null, D =
|
|
43
|
+
let E = o() !== null, D = c ?? a[f] ?? "en-US";
|
|
41
44
|
n(() => () => {
|
|
42
45
|
x.current?.abort(), x.current = null;
|
|
43
46
|
}, []);
|
|
44
47
|
let O = t((e = "manual") => {
|
|
45
48
|
let t = o();
|
|
46
|
-
if (!t || x.current || e === "auto" &&
|
|
49
|
+
if (!t || x.current || e === "auto" && u(C.current, performance.now())) return;
|
|
47
50
|
let n = new t();
|
|
48
51
|
n.continuous = !0, n.interimResults = !0, n.lang = D;
|
|
49
52
|
let r = S.current;
|
|
@@ -57,7 +60,7 @@ function d({ onFinalize: s, language: d }) {
|
|
|
57
60
|
t.trim() && T.current(t.trim()), v(n.trim());
|
|
58
61
|
}, n.onerror = (e) => {
|
|
59
62
|
if (r !== S.current) return;
|
|
60
|
-
let t =
|
|
63
|
+
let t = d(e.error);
|
|
61
64
|
t !== "no-speech" && b(t);
|
|
62
65
|
}, n.onend = () => {
|
|
63
66
|
r === S.current && (x.current = null, g(!1), m(!1), v(""));
|
|
@@ -67,7 +70,7 @@ function d({ onFinalize: s, language: d }) {
|
|
|
67
70
|
try {
|
|
68
71
|
n.start();
|
|
69
72
|
} catch {
|
|
70
|
-
C.current = performance.now(), w.current += 1, w.current >=
|
|
73
|
+
C.current = performance.now(), w.current += 1, w.current >= l && b("unknown"), x.current = null, g(!1), m(!1);
|
|
71
74
|
return;
|
|
72
75
|
}
|
|
73
76
|
x.current = n, w.current = 0, b(null), v("");
|
|
@@ -101,4 +104,4 @@ function d({ onFinalize: s, language: d }) {
|
|
|
101
104
|
};
|
|
102
105
|
}
|
|
103
106
|
//#endregion
|
|
104
|
-
export {
|
|
107
|
+
export { c as START_RETRY_COOLDOWN_MS, s as isSpeechRecognitionSupported, u as startIsCoolingDown, f as useVoiceInput };
|
|
@@ -46,6 +46,28 @@ export interface VoiceSessionSnapshot {
|
|
|
46
46
|
interim: string;
|
|
47
47
|
/** Why the session stopped, when it stopped abnormally. */
|
|
48
48
|
error: VoiceSessionError | null;
|
|
49
|
+
/**
|
|
50
|
+
* H2: what the turn in flight was sent as, while there is one ('' otherwise).
|
|
51
|
+
* Kept so a result that is only the recogniser finishing, repeating or
|
|
52
|
+
* revising it is not mistaken for a correction, and so a cumulative result
|
|
53
|
+
* ("<sent words> <new words>") contributes only the new words.
|
|
54
|
+
*/
|
|
55
|
+
submitted: string;
|
|
56
|
+
/** H2: when `submitted` was sent (the `at` of the `silence` that sent it). */
|
|
57
|
+
submittedAt: number | null;
|
|
58
|
+
/**
|
|
59
|
+
* H2: the words being collected, or the turn in flight, are a CORRECTION of
|
|
60
|
+
* a turn that was superseded. Cleared when the corrected turn is answered,
|
|
61
|
+
* interrupted or the session ends.
|
|
62
|
+
*/
|
|
63
|
+
correcting: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* H2: how many times an in-flight turn has been superseded this session.
|
|
66
|
+
* A counter, not a flag, so the hook can act exactly once per supersession
|
|
67
|
+
* (abort the model turn, withdraw outdated proposals) without the reducer
|
|
68
|
+
* doing anything impure. Reset by `start`.
|
|
69
|
+
*/
|
|
70
|
+
superseded: number;
|
|
49
71
|
}
|
|
50
72
|
/**
|
|
51
73
|
* Deliberately does NOT include a "playback blocked" variant. Nothing can
|
|
@@ -63,10 +85,13 @@ export type VoiceSessionEvent =
|
|
|
63
85
|
type: 'speech';
|
|
64
86
|
transcript: string;
|
|
65
87
|
final: boolean;
|
|
88
|
+
/** Wall-clock ms when it was heard — what the H2 trailing-result window is measured with. */
|
|
89
|
+
at?: number;
|
|
66
90
|
}
|
|
67
|
-
/** Nothing heard for `
|
|
91
|
+
/** Nothing heard for the person's grace (`resolveVoiceGraceMs`). */
|
|
68
92
|
| {
|
|
69
93
|
type: 'silence';
|
|
94
|
+
at?: number;
|
|
70
95
|
} | {
|
|
71
96
|
type: 'reply';
|
|
72
97
|
text: string;
|
|
@@ -116,24 +141,19 @@ export type VoiceSessionEvent =
|
|
|
116
141
|
type: 'end';
|
|
117
142
|
};
|
|
118
143
|
/**
|
|
119
|
-
* How long the user must stop talking before the turn is submitted
|
|
144
|
+
* How long the user must stop talking before the turn is submitted is a USER
|
|
145
|
+
* PREFERENCE (H1): `DEFAULT_VOICE_GRACE_MS` (2 s), 3 s or 5 s, resolved by
|
|
146
|
+
* `resolveVoiceGraceMs` and applied by `planSubmitTimer` in `./handsFree` —
|
|
147
|
+
* the only place that waits. (`SILENCE_SUBMIT_MS`, which used to live here, is
|
|
148
|
+
* gone: a second constant was a second owner.)
|
|
120
149
|
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
* operator reported being cut off mid-sentence, and the cost is worse than a
|
|
128
|
-
* truncated prompt — once the turn is submitted the reducer discards every
|
|
129
|
-
* `speech` event outside `listening`, so the rest of the sentence is not
|
|
130
|
-
* queued, it is thrown away, and the assistant answers half a question.
|
|
131
|
-
*
|
|
132
|
-
* The asymmetry is what settles the number: waiting 800ms longer costs a moment
|
|
133
|
-
* of silence, while cutting someone off costs the whole round trip AND makes
|
|
134
|
-
* them repeat themselves.
|
|
150
|
+
* Why the default is 2 s and not the 1.2 s it started at: 1.2 s does not
|
|
151
|
+
* survive an ordinary pause — once the turn is submitted the reducer discards
|
|
152
|
+
* every `speech` event outside `listening`, so the rest of the sentence is not
|
|
153
|
+
* queued, it is thrown away, and the assistant answers half a question. Waiting
|
|
154
|
+
* 800ms longer costs a moment of silence; cutting someone off costs the whole
|
|
155
|
+
* round trip AND makes them repeat themselves.
|
|
135
156
|
*/
|
|
136
|
-
export declare const SILENCE_SUBMIT_MS = 2000;
|
|
137
157
|
/**
|
|
138
158
|
* Quiet needed before the pause is SHOWN as a pause.
|
|
139
159
|
*
|
|
@@ -145,7 +165,7 @@ export declare const SILENCE_SUBMIT_MS = 2000;
|
|
|
145
165
|
*
|
|
146
166
|
* Short enough to be seen, long enough that an ordinary breath between words
|
|
147
167
|
* does not flicker the stage. ★800, not 400: this file already records that
|
|
148
|
-
*
|
|
168
|
+
* the grace had to go 1200 -> 2000 because ordinary pauses ran longer
|
|
149
169
|
* than expected, so a 400ms threshold sits inside normal inter-clause silence
|
|
150
170
|
* and would oscillate the stage mid-sentence. Still leaves ~1.2s visible.
|
|
151
171
|
*/
|
|
@@ -213,7 +233,14 @@ export declare function isEcho(transcript: string, spokenText: string | null): b
|
|
|
213
233
|
* while the phase is `listening`. Leaving it unclaimed meant the NEXT question
|
|
214
234
|
* found it waiting and spoke the answer to the question the user had cut off.
|
|
215
235
|
*/
|
|
216
|
-
export declare function planReplyConsumption(replyId: string | null | undefined, phase: VoiceSessionPhase, consumedReplyId: string | null
|
|
236
|
+
export declare function planReplyConsumption(replyId: string | null | undefined, phase: VoiceSessionPhase, consumedReplyId: string | null,
|
|
237
|
+
/**
|
|
238
|
+
* H2: the reply belongs to a turn the person superseded (`isTurnSuperseded`).
|
|
239
|
+
* It is claimed and never advances the session, whatever the phase — a late
|
|
240
|
+
* answer to a question the person has since corrected must not move the
|
|
241
|
+
* turn that REPLACED it out of `thinking`.
|
|
242
|
+
*/
|
|
243
|
+
supersededReply?: boolean): {
|
|
217
244
|
claim: boolean;
|
|
218
245
|
advance: boolean;
|
|
219
246
|
};
|
|
@@ -265,13 +292,30 @@ export declare function planListeningHold(input: {
|
|
|
265
292
|
held: boolean;
|
|
266
293
|
};
|
|
267
294
|
/**
|
|
268
|
-
* Is the microphone capturing right now?
|
|
295
|
+
* Is the microphone capturing right now — in the sense the AUDIO guards mean?
|
|
269
296
|
*
|
|
270
297
|
* False while the assistant speaks, which is the whole point: an open
|
|
271
298
|
* microphone during playback is what created the feedback loop. False whenever
|
|
272
299
|
* muted, whatever the phase.
|
|
300
|
+
*
|
|
301
|
+
* ★ Deliberately still `listening` only, though the recogniser now also runs in
|
|
302
|
+
* `thinking` (see `shouldRecognise`). This is what the speech provider is told
|
|
303
|
+
* ("the microphone is open: refuse to auto-speak a reply into it"), and the
|
|
304
|
+
* not-capturing notice is judged by. A correction heard in `thinking` supersedes
|
|
305
|
+
* the turn and returns the phase to `listening`, so a late reply is then refused
|
|
306
|
+
* by exactly this guard — it is not weakened by listening for corrections.
|
|
273
307
|
*/
|
|
274
308
|
export declare function isCapturing(snapshot: VoiceSessionSnapshot): boolean;
|
|
309
|
+
/**
|
|
310
|
+
* Should the recogniser be RUNNING right now (H2)?
|
|
311
|
+
*
|
|
312
|
+
* While `listening`, and also while the assistant is `thinking`: nothing plays
|
|
313
|
+
* then, so there is no echo to fear, and keeping the microphone open is what
|
|
314
|
+
* lets a person correct themselves without tapping. Closed for the whole of
|
|
315
|
+
* `speaking`, and whenever muted. Barge-in while SPEAKING is a separate step
|
|
316
|
+
* (H3) and is NOT enabled here.
|
|
317
|
+
*/
|
|
318
|
+
export declare function shouldRecognise(snapshot: VoiceSessionSnapshot): boolean;
|
|
275
319
|
/** The orb's visual mode. Kept here so the UI has no state logic of its own. */
|
|
276
320
|
export declare function orbMode(snapshot: VoiceSessionSnapshot): 'idle' | 'listening' | 'thinking' | 'speaking';
|
|
277
321
|
//# sourceMappingURL=voiceSession.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voiceSession.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/voice/voiceSession.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;
|
|
1
|
+
{"version":3,"file":"voiceSession.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/voice/voiceSession.ts"],"names":[],"mappings":"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"}
|