@burdenoff/fe-libs 2026.1028.2 → 2026.1028.4
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/shared/assistant/turnTimeline.d.ts +18 -6
- package/dist/shared/assistant/turnTimeline.js +57 -39
- package/dist/shared/assistant/turnTimingReport.d.ts +10 -1
- package/dist/shared/assistant/turnTimingReport.js +19 -6
- package/dist/shared/assistant/ui/AssistantSpeechProvider.js +239 -237
- package/dist/shared/assistant/ui/useVoiceSession.js +218 -202
- package/dist/shared/assistant/voice/handsfree/handsFreeController.d.ts +3 -0
- package/dist/shared/assistant/voice/handsfree/handsFreeController.js +5 -1
- package/dist/shared/assistant/voice/handsfree/useHandsFreeInterrupt.d.ts +1 -0
- package/dist/shared/assistant/voice/handsfree/useHandsFreeInterrupt.js +1 -0
- package/dist/shared/assistant/voice/useVoiceInput.d.ts +3 -1
- package/dist/shared/assistant/voice/useVoiceInput.js +49 -43
- package/dist/shared/config/gatewayUrls.d.ts +13 -0
- package/dist/shared/config/gatewayUrls.js +7 -3
- package/dist/shared/config/index.d.ts +1 -1
- package/dist/shared-assistant.js +206 -206
- package/dist/shared-config.js +16 -16
- package/dist/shared.js +140 -140
- package/package.json +1 -1
|
@@ -85,15 +85,15 @@
|
|
|
85
85
|
* window event: any script on the page can dispatch that event, so a listener
|
|
86
86
|
* on it can be fed invented timings. Only this module calls subscribers.
|
|
87
87
|
*/
|
|
88
|
-
export declare const TURN_MILESTONES: readonly ["speechEnded", "graceStarted", "graceEnded", "handedOver", "accepted", "cleared", "attemptStarted", "prewarmJoined", "bootAdopted", "provisionStarted", "createRequested", "sandboxRunning", "serviceReady", "runtimeReady", "promptSent", "lastQuietPoll", "streamOpen", "streamRemint", "firstDelta", "firstOutput", "firstText", "streamIdle", "answerDone", "complete", "speechQueued", "ttsStarted", "firstAudio", "audioEnded"];
|
|
88
|
+
export declare const TURN_MILESTONES: readonly ["speechEnded", "lastSpeechFrame", "recognizerSpeechEnded", "graceStarted", "graceEnded", "handedOver", "accepted", "cleared", "attemptStarted", "prewarmJoined", "bootAdopted", "provisionStarted", "createRequested", "sandboxRunning", "serviceReady", "runtimeReady", "promptSent", "lastQuietPoll", "streamOpen", "streamRemint", "firstDelta", "firstOutput", "firstText", "streamIdle", "answerDone", "complete", "speechQueued", "ttsStarted", "firstAudio", "audioEnded"];
|
|
89
89
|
export type TurnMilestone = (typeof TURN_MILESTONES)[number];
|
|
90
90
|
/**
|
|
91
91
|
* How the runtime was found:
|
|
92
92
|
* - `warm`: a remembered sandbox with a fresh readiness proof, session reused
|
|
93
93
|
* - `new-session`: that sandbox, but a new session
|
|
94
94
|
* - `preopened`: that sandbox, and a new session the first-keystroke warm had
|
|
95
|
-
* already opened (BOFF-8015). The
|
|
96
|
-
*
|
|
95
|
+
* already opened (BOFF-8015). The H2 collector gives it its own bounded
|
|
96
|
+
* class; older collectors count it as `warm`
|
|
97
97
|
* - `probed`: a RUNNING sandbox was reused only after a reachability probe
|
|
98
98
|
* - `adopted`: a boot was joined and waited out — the sandbox was listed
|
|
99
99
|
* PROVISIONING/PENDING, or its service answered "not up yet" during the
|
|
@@ -120,7 +120,7 @@ export type TurnRuntime = 'warm' | 'preopened' | 'new-session' | 'probed' | 'ado
|
|
|
120
120
|
*/
|
|
121
121
|
export type TurnTimelineOutcome = 'answered' | 'timedOut' | 'refused' | 'failed' | 'stopped';
|
|
122
122
|
export interface TurnDimensions {
|
|
123
|
-
channel: 'chat' | 'voice';
|
|
123
|
+
channel: 'chat' | 'voice' | 'listen';
|
|
124
124
|
mode: string;
|
|
125
125
|
product: string;
|
|
126
126
|
/** The reply language the turn asked for. */
|
|
@@ -170,6 +170,8 @@ export interface TurnAttempt extends TurnAttemptFacts {
|
|
|
170
170
|
}
|
|
171
171
|
export interface TurnTimeline extends TurnDimensions, TurnAttemptFacts {
|
|
172
172
|
turnId: string;
|
|
173
|
+
/** The selected preference, not the elapsed grace timer. */
|
|
174
|
+
selectedGraceMs?: number;
|
|
173
175
|
at: Partial<Record<TurnMilestone, number>>;
|
|
174
176
|
/** Earlier attempts of a retried turn, oldest first. */
|
|
175
177
|
attempts?: TurnAttempt[];
|
|
@@ -177,7 +179,7 @@ export interface TurnTimeline extends TurnDimensions, TurnAttemptFacts {
|
|
|
177
179
|
outcome?: TurnTimelineOutcome;
|
|
178
180
|
}
|
|
179
181
|
/** Marks a voice turn brings with it, taken before the panel has an id for it. */
|
|
180
|
-
export type VoiceTurnTiming = Partial<Record<'speechEnded' | 'graceStarted' | 'graceEnded' | 'handedOver', number>>;
|
|
182
|
+
export type VoiceTurnTiming = Partial<Record<'speechEnded' | 'lastSpeechFrame' | 'recognizerSpeechEnded' | 'graceStarted' | 'graceEnded' | 'handedOver' | 'selectedGraceMs', number>>;
|
|
181
183
|
/** Announced on `window` with a copy of the timeline each time it changes. */
|
|
182
184
|
export declare const TURN_TIMELINE_EVENT = "burdenoff:assistant-turn-timeline";
|
|
183
185
|
/** Receives a copy of a timeline each time it changes. */
|
|
@@ -204,7 +206,7 @@ export declare function beginTurn(turnId: string, dimensions: TurnDimensions, ca
|
|
|
204
206
|
/**
|
|
205
207
|
* Record a milestone. The FIRST time wins — the poll that first saw output is
|
|
206
208
|
* the one that counts, however many polls follow — and a turn that was never
|
|
207
|
-
* begun is ignored,
|
|
209
|
+
* begun is ignored, unclassified history cannot create a model-turn measurement.
|
|
208
210
|
*/
|
|
209
211
|
export declare function markTurn(turnId: string, milestone: TurnMilestone, at?: number): void;
|
|
210
212
|
/** Facts about the turn learnt along the way. The first answer to each stands. */
|
|
@@ -371,3 +373,13 @@ export declare function isComparableTurn(timeline: TurnTimeline): boolean;
|
|
|
371
373
|
* cold, tool / no tool, language, device, channel, or any combination.
|
|
372
374
|
*/
|
|
373
375
|
export declare function summariseTurnTimelines(timelines: readonly TurnTimeline[], groupOf: (timeline: TurnTimeline) => string, include?: (timeline: TurnTimeline) => boolean): Record<string, Partial<Record<TurnSegmentName, SegmentStats>>>;
|
|
376
|
+
/**
|
|
377
|
+
* Measure a manual Listen request through the existing timeline/report path.
|
|
378
|
+
* Only a confirmed useful answer in this page can seed it; notices, previews
|
|
379
|
+
* and unclassified history never become useful-audio samples. The new clock
|
|
380
|
+
* starts when playback is committed, not at the original model request (which
|
|
381
|
+
* may have finished hours ago). No message id is sent by the reporter.
|
|
382
|
+
*/
|
|
383
|
+
export declare function beginListenTurn(messageId: string, at?: number): string | undefined;
|
|
384
|
+
/** Finish a Listen startup once. Audio is marked only by the engine's onStart. */
|
|
385
|
+
export declare function finishListenTurn(id: string | undefined, outcome: 'answered' | 'failed' | 'stopped', at?: number): void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/shared/assistant/turnTimeline.ts
|
|
2
|
-
var e = /* @__PURE__ */ "speechEnded.graceStarted.graceEnded.handedOver.accepted.cleared.attemptStarted.prewarmJoined.bootAdopted.provisionStarted.createRequested.sandboxRunning.serviceReady.runtimeReady.promptSent.lastQuietPoll.streamOpen.streamRemint.firstDelta.firstOutput.firstText.streamIdle.answerDone.complete.speechQueued.ttsStarted.firstAudio.audioEnded".split("."), t = [
|
|
2
|
+
var e = /* @__PURE__ */ "speechEnded.lastSpeechFrame.recognizerSpeechEnded.graceStarted.graceEnded.handedOver.accepted.cleared.attemptStarted.prewarmJoined.bootAdopted.provisionStarted.createRequested.sandboxRunning.serviceReady.runtimeReady.promptSent.lastQuietPoll.streamOpen.streamRemint.firstDelta.firstOutput.firstText.streamIdle.answerDone.complete.speechQueued.ttsStarted.firstAudio.audioEnded".split("."), t = [
|
|
3
3
|
"attemptStarted",
|
|
4
4
|
"prewarmJoined",
|
|
5
5
|
"bootAdopted",
|
|
@@ -17,19 +17,19 @@ var e = /* @__PURE__ */ "speechEnded.graceStarted.graceEnded.handedOver.accepted
|
|
|
17
17
|
"firstText",
|
|
18
18
|
"streamIdle",
|
|
19
19
|
"answerDone"
|
|
20
|
-
], n = "burdenoff:assistant-turn-timeline", r = 50, i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set();
|
|
21
|
-
function
|
|
22
|
-
return
|
|
23
|
-
|
|
20
|
+
], n = "burdenoff:assistant-turn-timeline", r = 50, i = /* @__PURE__ */ new Map(), a = 0, o = /* @__PURE__ */ new Set();
|
|
21
|
+
function s(e) {
|
|
22
|
+
return o.add(e), () => {
|
|
23
|
+
o.delete(e);
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
|
-
function
|
|
26
|
+
function c() {
|
|
27
27
|
try {
|
|
28
28
|
if (typeof performance < "u" && typeof performance?.now == "function") return performance.now();
|
|
29
29
|
} catch {}
|
|
30
30
|
return Date.now();
|
|
31
31
|
}
|
|
32
|
-
function
|
|
32
|
+
function l() {
|
|
33
33
|
try {
|
|
34
34
|
let e = typeof window > "u" ? null : window;
|
|
35
35
|
return !e || typeof e.matchMedia != "function" ? "unknown" : e.matchMedia("(pointer: coarse)").matches ? "touch" : "pointer";
|
|
@@ -37,7 +37,7 @@ function c() {
|
|
|
37
37
|
return "unknown";
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
-
function
|
|
40
|
+
function u(e) {
|
|
41
41
|
return {
|
|
42
42
|
...e,
|
|
43
43
|
at: { ...e.at },
|
|
@@ -47,10 +47,10 @@ function l(e) {
|
|
|
47
47
|
})) } : {}
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
|
-
function
|
|
51
|
-
let t =
|
|
52
|
-
for (let e of [...
|
|
53
|
-
e(
|
|
50
|
+
function d(e) {
|
|
51
|
+
let t = u(e), r = () => {
|
|
52
|
+
for (let e of [...o]) try {
|
|
53
|
+
e(u(t));
|
|
54
54
|
} catch {}
|
|
55
55
|
try {
|
|
56
56
|
let e = typeof window > "u" ? null : window;
|
|
@@ -60,33 +60,33 @@ function u(e) {
|
|
|
60
60
|
};
|
|
61
61
|
typeof queueMicrotask == "function" ? queueMicrotask(r) : r();
|
|
62
62
|
}
|
|
63
|
-
function
|
|
63
|
+
function f(e, t, n) {
|
|
64
64
|
if (i.has(e)) return;
|
|
65
65
|
let a = {};
|
|
66
|
-
n?.speechEnded !== void 0 && (a.speechEnded = n.speechEnded), n?.graceStarted !== void 0 && (a.graceStarted = n.graceStarted), n?.graceEnded !== void 0 && (a.graceEnded = n.graceEnded), n?.handedOver !== void 0 && (a.handedOver = n.handedOver);
|
|
66
|
+
n?.speechEnded !== void 0 && (a.speechEnded = n.speechEnded), n?.lastSpeechFrame !== void 0 && (a.lastSpeechFrame = n.lastSpeechFrame), n?.recognizerSpeechEnded !== void 0 && (a.recognizerSpeechEnded = n.recognizerSpeechEnded), n?.graceStarted !== void 0 && (a.graceStarted = n.graceStarted), n?.graceEnded !== void 0 && (a.graceEnded = n.graceEnded), n?.handedOver !== void 0 && (a.handedOver = n.handedOver);
|
|
67
67
|
let o = {
|
|
68
68
|
turnId: e,
|
|
69
69
|
...t,
|
|
70
70
|
at: a
|
|
71
71
|
};
|
|
72
|
-
for (i.set(e, o); i.size > r;) {
|
|
72
|
+
for (n?.selectedGraceMs !== void 0 && (o.selectedGraceMs = n.selectedGraceMs), i.set(e, o); i.size > r;) {
|
|
73
73
|
let e = i.keys().next().value;
|
|
74
74
|
if (e === void 0) break;
|
|
75
75
|
i.delete(e);
|
|
76
76
|
}
|
|
77
|
-
|
|
77
|
+
d(o);
|
|
78
78
|
}
|
|
79
|
-
function
|
|
79
|
+
function p(e, t, n = c()) {
|
|
80
80
|
let r = i.get(e);
|
|
81
|
-
!r || r.at[t] !== void 0 || (r.at[t] = n,
|
|
81
|
+
!r || r.at[t] !== void 0 || (r.at[t] = n, d(r));
|
|
82
82
|
}
|
|
83
|
-
function
|
|
83
|
+
function m(e, t) {
|
|
84
84
|
let n = i.get(e);
|
|
85
85
|
if (!n) return;
|
|
86
86
|
let r = !1;
|
|
87
|
-
t.runtime !== void 0 && n.runtime === void 0 && (n.runtime = t.runtime, r = !0), t.usedTools !== void 0 && n.usedTools === void 0 && (n.usedTools = t.usedTools, r = !0), t.deadSandboxProbe !== void 0 && n.deadSandboxProbe === void 0 && (n.deadSandboxProbe = t.deadSandboxProbe, r = !0), t.cacheProofFailed !== void 0 && n.cacheProofFailed === void 0 && (n.cacheProofFailed = t.cacheProofFailed, r = !0), t.prewarm !== void 0 && n.prewarm === void 0 && (n.prewarm = t.prewarm, r = !0), t.transport !== void 0 && n.transport === void 0 && (n.transport = t.transport, r = !0), t.live !== void 0 && n.live === void 0 && (n.live = t.live, r = !0), t.session !== void 0 && n.session === void 0 && (n.session = t.session, r = !0), t.outcome !== void 0 && n.outcome === void 0 && (n.outcome = t.outcome, r = !0), r &&
|
|
87
|
+
t.runtime !== void 0 && n.runtime === void 0 && (n.runtime = t.runtime, r = !0), t.usedTools !== void 0 && n.usedTools === void 0 && (n.usedTools = t.usedTools, r = !0), t.deadSandboxProbe !== void 0 && n.deadSandboxProbe === void 0 && (n.deadSandboxProbe = t.deadSandboxProbe, r = !0), t.cacheProofFailed !== void 0 && n.cacheProofFailed === void 0 && (n.cacheProofFailed = t.cacheProofFailed, r = !0), t.prewarm !== void 0 && n.prewarm === void 0 && (n.prewarm = t.prewarm, r = !0), t.transport !== void 0 && n.transport === void 0 && (n.transport = t.transport, r = !0), t.live !== void 0 && n.live === void 0 && (n.live = t.live, r = !0), t.session !== void 0 && n.session === void 0 && (n.session = t.session, r = !0), t.outcome !== void 0 && n.outcome === void 0 && (n.outcome = t.outcome, r = !0), r && d(n);
|
|
88
88
|
}
|
|
89
|
-
function
|
|
89
|
+
function h(e, n = c()) {
|
|
90
90
|
let r = i.get(e);
|
|
91
91
|
if (!r) return;
|
|
92
92
|
let a = {
|
|
@@ -97,19 +97,19 @@ function m(e, n = s()) {
|
|
|
97
97
|
let t = r.at[e];
|
|
98
98
|
t !== void 0 && (a.at[e] = t, delete r.at[e]);
|
|
99
99
|
}
|
|
100
|
-
r.runtime !== void 0 && (a.runtime = r.runtime), r.usedTools !== void 0 && (a.usedTools = r.usedTools), r.deadSandboxProbe !== void 0 && (a.deadSandboxProbe = r.deadSandboxProbe), r.cacheProofFailed !== void 0 && (a.cacheProofFailed = r.cacheProofFailed), r.prewarm !== void 0 && (a.prewarm = r.prewarm), r.transport !== void 0 && (a.transport = r.transport), r.live !== void 0 && (a.live = r.live), r.session !== void 0 && (a.session = r.session), delete r.transport, delete r.live, delete r.session, delete r.runtime, delete r.usedTools, delete r.deadSandboxProbe, delete r.cacheProofFailed, delete r.prewarm, r.attempts = [...r.attempts ?? [], a], r.retried = !0,
|
|
100
|
+
r.runtime !== void 0 && (a.runtime = r.runtime), r.usedTools !== void 0 && (a.usedTools = r.usedTools), r.deadSandboxProbe !== void 0 && (a.deadSandboxProbe = r.deadSandboxProbe), r.cacheProofFailed !== void 0 && (a.cacheProofFailed = r.cacheProofFailed), r.prewarm !== void 0 && (a.prewarm = r.prewarm), r.transport !== void 0 && (a.transport = r.transport), r.live !== void 0 && (a.live = r.live), r.session !== void 0 && (a.session = r.session), delete r.transport, delete r.live, delete r.session, delete r.runtime, delete r.usedTools, delete r.deadSandboxProbe, delete r.cacheProofFailed, delete r.prewarm, r.attempts = [...r.attempts ?? [], a], r.retried = !0, d(r);
|
|
101
101
|
}
|
|
102
|
-
function
|
|
102
|
+
function g(e) {
|
|
103
103
|
let t = i.get(e);
|
|
104
|
-
return t ?
|
|
105
|
-
}
|
|
106
|
-
function g() {
|
|
107
|
-
return [...i.values()].map(l);
|
|
104
|
+
return t ? u(t) : void 0;
|
|
108
105
|
}
|
|
109
106
|
function _() {
|
|
107
|
+
return [...i.values()].map(u);
|
|
108
|
+
}
|
|
109
|
+
function v() {
|
|
110
110
|
i.clear();
|
|
111
111
|
}
|
|
112
|
-
var
|
|
112
|
+
var y = [
|
|
113
113
|
{
|
|
114
114
|
name: "endpointing",
|
|
115
115
|
from: "speechEnded",
|
|
@@ -256,38 +256,38 @@ var v = [
|
|
|
256
256
|
to: "firstAudio"
|
|
257
257
|
}
|
|
258
258
|
];
|
|
259
|
-
function
|
|
259
|
+
function b(e) {
|
|
260
260
|
let t = {};
|
|
261
|
-
for (let { name: n, from: r, to: i } of
|
|
261
|
+
for (let { name: n, from: r, to: i } of y) {
|
|
262
262
|
let a = e.at[r], o = e.at[i];
|
|
263
263
|
a !== void 0 && o !== void 0 && o >= a && (t[n] = o - a);
|
|
264
264
|
}
|
|
265
265
|
return t;
|
|
266
266
|
}
|
|
267
|
-
function
|
|
267
|
+
function x(e, t) {
|
|
268
268
|
return e[Math.max(1, Math.ceil(t * e.length)) - 1];
|
|
269
269
|
}
|
|
270
|
-
function
|
|
270
|
+
function S(e) {
|
|
271
271
|
if (!e.length) return;
|
|
272
272
|
let t = [...e].sort((e, t) => e - t), n = Math.floor(t.length / 2), r = t.length % 2 ? t[n] : (t[n - 1] + t[n]) / 2;
|
|
273
273
|
return {
|
|
274
274
|
n: t.length,
|
|
275
275
|
median: r,
|
|
276
|
-
p90:
|
|
276
|
+
p90: x(t, .9),
|
|
277
277
|
max: t[t.length - 1]
|
|
278
278
|
};
|
|
279
279
|
}
|
|
280
|
-
function
|
|
280
|
+
function C(e) {
|
|
281
281
|
return e.outcome === "answered" && !e.retried;
|
|
282
282
|
}
|
|
283
|
-
function
|
|
283
|
+
function w(e, t, n = C) {
|
|
284
284
|
let r = /* @__PURE__ */ new Map();
|
|
285
285
|
for (let i of e) {
|
|
286
286
|
if (!n(i)) continue;
|
|
287
287
|
let e = t(i), a = r.get(e) ?? /* @__PURE__ */ new Map();
|
|
288
288
|
r.set(e, a);
|
|
289
|
-
let o =
|
|
290
|
-
for (let { name: e } of
|
|
289
|
+
let o = b(i);
|
|
290
|
+
for (let { name: e } of y) {
|
|
291
291
|
let t = o[e];
|
|
292
292
|
if (t === void 0) continue;
|
|
293
293
|
let n = a.get(e) ?? [];
|
|
@@ -298,12 +298,30 @@ function C(e, t, n = S) {
|
|
|
298
298
|
for (let [e, t] of r) {
|
|
299
299
|
let n = {};
|
|
300
300
|
for (let [e, r] of t) {
|
|
301
|
-
let t =
|
|
301
|
+
let t = S(r);
|
|
302
302
|
t && (n[e] = t);
|
|
303
303
|
}
|
|
304
304
|
i[e] = n;
|
|
305
305
|
}
|
|
306
306
|
return i;
|
|
307
307
|
}
|
|
308
|
+
function T(e, t = c()) {
|
|
309
|
+
let n = i.get(e);
|
|
310
|
+
if (!n || n.outcome !== "answered" || n.at.firstText === void 0 || n.channel === "listen") return;
|
|
311
|
+
let r = `listen:${++a}`;
|
|
312
|
+
return f(r, {
|
|
313
|
+
channel: "listen",
|
|
314
|
+
product: n.product,
|
|
315
|
+
mode: n.mode,
|
|
316
|
+
language: n.language,
|
|
317
|
+
device: n.device,
|
|
318
|
+
routedByAuto: !1
|
|
319
|
+
}), p(r, "accepted", t), r;
|
|
320
|
+
}
|
|
321
|
+
function E(e, t, n = c()) {
|
|
322
|
+
if (!e) return;
|
|
323
|
+
let r = i.get(e);
|
|
324
|
+
!r || r.channel !== "listen" || r.outcome !== void 0 || (t === "answered" && p(e, "firstAudio", n), p(e, "complete", n), m(e, { outcome: t }));
|
|
325
|
+
}
|
|
308
326
|
//#endregion
|
|
309
|
-
export { e as TURN_MILESTONES,
|
|
327
|
+
export { e as TURN_MILESTONES, y as TURN_SEGMENTS, n as TURN_TIMELINE_EVENT, T as beginListenTurn, f as beginTurn, m as describeTurn, l as detectTurnDevice, E as finishListenTurn, C as isComparableTurn, p as markTurn, _ as recentTurnTimelines, v as resetTurnTimelines, h as restartAttempt, S as segmentStats, s as subscribeTurnTimelines, w as summariseTurnTimelines, c as turnClockMs, b as turnSegments, g as turnTimeline };
|
|
@@ -18,6 +18,11 @@ export interface AssistantTurnTimingReport {
|
|
|
18
18
|
firstVisibleOutputMs?: number;
|
|
19
19
|
firstUsefulOutputMs?: number;
|
|
20
20
|
firstAudioMs?: number;
|
|
21
|
+
firstUsefulAudioMs?: number;
|
|
22
|
+
speechEndToCommitMs?: number;
|
|
23
|
+
recognizerEndToCommitMs?: number;
|
|
24
|
+
selectedGraceMs?: number;
|
|
25
|
+
completionGraceMs?: number;
|
|
21
26
|
completeMs: number;
|
|
22
27
|
}
|
|
23
28
|
/**
|
|
@@ -48,6 +53,10 @@ export declare const TURN_TIMING_STAGES: readonly [{
|
|
|
48
53
|
readonly field: "firstAudioMs";
|
|
49
54
|
readonly milestone: "firstAudio";
|
|
50
55
|
readonly onRetry: "final";
|
|
56
|
+
}, {
|
|
57
|
+
readonly field: "firstUsefulAudioMs";
|
|
58
|
+
readonly milestone: "firstAudio";
|
|
59
|
+
readonly onRetry: "final";
|
|
51
60
|
}, {
|
|
52
61
|
readonly field: "completeMs";
|
|
53
62
|
readonly milestone: "complete";
|
|
@@ -64,7 +73,7 @@ export declare const ABANDONED_TURN_OUTCOME = "abandoned";
|
|
|
64
73
|
*/
|
|
65
74
|
export declare const MAX_REPORTED_TURN_MS: number;
|
|
66
75
|
/** Every key a report may carry — the privacy allowlist, stated once. */
|
|
67
|
-
export declare const TURN_TIMING_REPORT_FIELDS: readonly ["product", "channel", "mode", "runtime", "prewarm", "outcome", "retried", ...("runtimeReadyMs" | "modelStartMs" | "firstVisibleOutputMs" | "firstUsefulOutputMs" | "firstAudioMs" | "completeMs")[]];
|
|
76
|
+
export declare const TURN_TIMING_REPORT_FIELDS: readonly ["product", "channel", "mode", "runtime", "prewarm", "outcome", "retried", "speechEndToCommitMs", "recognizerEndToCommitMs", "selectedGraceMs", "completionGraceMs", ...("runtimeReadyMs" | "modelStartMs" | "firstVisibleOutputMs" | "firstUsefulOutputMs" | "firstAudioMs" | "firstUsefulAudioMs" | "completeMs")[]];
|
|
68
77
|
/**
|
|
69
78
|
* Finished: it has an outcome and it ended. Every exit path marks `complete`
|
|
70
79
|
* in a `finally`, and every one of them sets an outcome.
|
|
@@ -25,6 +25,11 @@ var e = [
|
|
|
25
25
|
milestone: "firstAudio",
|
|
26
26
|
onRetry: "final"
|
|
27
27
|
},
|
|
28
|
+
{
|
|
29
|
+
field: "firstUsefulAudioMs",
|
|
30
|
+
milestone: "firstAudio",
|
|
31
|
+
onRetry: "final"
|
|
32
|
+
},
|
|
28
33
|
{
|
|
29
34
|
field: "completeMs",
|
|
30
35
|
milestone: "complete",
|
|
@@ -38,6 +43,10 @@ var e = [
|
|
|
38
43
|
"prewarm",
|
|
39
44
|
"outcome",
|
|
40
45
|
"retried",
|
|
46
|
+
"speechEndToCommitMs",
|
|
47
|
+
"recognizerEndToCommitMs",
|
|
48
|
+
"selectedGraceMs",
|
|
49
|
+
"completionGraceMs",
|
|
41
50
|
...e.map((e) => e.field)
|
|
42
51
|
];
|
|
43
52
|
function i(e) {
|
|
@@ -90,10 +99,10 @@ function p(e) {
|
|
|
90
99
|
};
|
|
91
100
|
}
|
|
92
101
|
function m(e, t, n) {
|
|
93
|
-
return e === "firstUsefulOutputMs" ? t === "answered" : e === "firstAudioMs" ? t === "answered" && n === "voice" : !0;
|
|
102
|
+
return e === "firstUsefulOutputMs" ? t === "answered" && n !== "listen" : e === "firstUsefulAudioMs" ? t === "answered" && (n === "voice" || n === "listen") : e === "firstAudioMs" ? t === "answered" && n === "voice" : !0;
|
|
94
103
|
}
|
|
95
104
|
function h(t, n, r) {
|
|
96
|
-
let i = t.retried === !0, { runtime:
|
|
105
|
+
let i = t.retried === !0, { runtime: s, prewarm: c } = p(t), l = {
|
|
97
106
|
product: t.product,
|
|
98
107
|
channel: t.channel,
|
|
99
108
|
mode: t.mode,
|
|
@@ -101,13 +110,17 @@ function h(t, n, r) {
|
|
|
101
110
|
retried: i,
|
|
102
111
|
completeMs: r
|
|
103
112
|
};
|
|
104
|
-
|
|
113
|
+
s !== void 0 && (l.runtime = s), c !== void 0 && (l.prewarm = c);
|
|
105
114
|
for (let { field: r, milestone: a, onRetry: s } of e) {
|
|
106
|
-
if (r === "completeMs" || !m(r, n, t.channel) || i && s === "omit") continue;
|
|
115
|
+
if (r === "completeMs" || r === "firstUsefulAudioMs" && t.channel === "voice" && t.at.firstText === void 0 || !m(r, n, t.channel) || i && s === "omit") continue;
|
|
107
116
|
let e = o(t, a, i && s === "earliest");
|
|
108
|
-
e !== void 0 && (
|
|
117
|
+
e !== void 0 && (l[r] = e);
|
|
118
|
+
}
|
|
119
|
+
if (t.channel === "voice") {
|
|
120
|
+
let e = (e, t) => e === void 0 || t === void 0 || t < e ? void 0 : a(e, t), n = e(t.at.lastSpeechFrame, t.at.accepted), r = e(t.at.recognizerSpeechEnded, t.at.accepted), i = e(t.at.graceStarted, t.at.graceEnded);
|
|
121
|
+
n !== void 0 && (l.speechEndToCommitMs = n), r !== void 0 && (l.recognizerEndToCommitMs = r), i !== void 0 && (l.completionGraceMs = i), t.selectedGraceMs !== void 0 && Number.isSafeInteger(t.selectedGraceMs) && t.selectedGraceMs >= 0 && (l.selectedGraceMs = t.selectedGraceMs);
|
|
109
122
|
}
|
|
110
|
-
return
|
|
123
|
+
return l;
|
|
111
124
|
}
|
|
112
125
|
function g(e) {
|
|
113
126
|
if (!i(e) || !e.outcome || !e.product) return null;
|