@burdenoff/fe-libs 2026.1029.6 → 2026.1029.8

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.
Files changed (39) hide show
  1. package/dist/shared/assistant/appControls/grammar.js +21 -21
  2. package/dist/shared/assistant/appControls/registry.js +1 -1
  3. package/dist/shared/assistant/commandCompletions.js +87 -86
  4. package/dist/shared/assistant/index.d.ts +5 -0
  5. package/dist/shared/assistant/liveDeltas.d.ts +3 -0
  6. package/dist/shared/assistant/liveDeltas.js +17 -1
  7. package/dist/shared/assistant/liveOverlay.d.ts +4 -0
  8. package/dist/shared/assistant/liveOverlay.js +10 -1
  9. package/dist/shared/assistant/localUiCommands.js +106 -112
  10. package/dist/shared/assistant/localeCommands/languageNames.js +13 -13
  11. package/dist/shared/assistant/speech/appendSpeechQueue.d.ts +13 -0
  12. package/dist/shared/assistant/speech/appendSpeechQueue.js +75 -0
  13. package/dist/shared/assistant/speech/browserSpeechEngine.js +93 -46
  14. package/dist/shared/assistant/speech/hostedTtsSpeechEngine.js +173 -109
  15. package/dist/shared/assistant/speech/index.d.ts +1 -1
  16. package/dist/shared/assistant/speech/notifyCancellationSpeechEngine.js +53 -0
  17. package/dist/shared/assistant/speech/routingSpeechEngine.js +107 -23
  18. package/dist/shared/assistant/speech/speechFeed.d.ts +17 -2
  19. package/dist/shared/assistant/speech/speechFeed.js +35 -12
  20. package/dist/shared/assistant/speech/types.d.ts +20 -1
  21. package/dist/shared/assistant/turnTimeline.d.ts +3 -0
  22. package/dist/shared/assistant/turnTimeline.js +4 -1
  23. package/dist/shared/assistant/ui/AssistantChatArea.js +1410 -1393
  24. package/dist/shared/assistant/ui/AssistantSpeechProvider.js +351 -291
  25. package/dist/shared/assistant/ui/useVoiceSession.js +323 -288
  26. package/dist/shared/assistant/voice/livePhraseSpeech.d.ts +14 -0
  27. package/dist/shared/assistant/voice/livePhraseSpeech.js +72 -0
  28. package/dist/shared/assistant/voice/phraseGate.d.ts +11 -0
  29. package/dist/shared/assistant/voice/phraseGate.js +74 -0
  30. package/dist/shared/assistant/voice/phrasePlayback.d.ts +9 -0
  31. package/dist/shared/assistant/voice/phrasePlayback.js +78 -0
  32. package/dist/shared/assistant/voice/phraseSpeechConfig.d.ts +5 -0
  33. package/dist/shared/assistant/voice/phraseSpeechConfig.js +10 -0
  34. package/dist/shared/assistant/voice/speakableText.d.ts +1 -0
  35. package/dist/shared/assistant/voice/speakableText.js +1 -1
  36. package/dist/shared/assistant/voice/voiceSession.d.ts +5 -0
  37. package/dist/shared/assistant/voice/voiceSession.js +17 -1
  38. package/dist/shared-assistant.js +293 -288
  39. package/package.json +1 -1
@@ -24,7 +24,7 @@ var l = 60, u = /^(?:log ?out|sign ?out|(?:log|sign) (?:me )?out(?: of (?:the |m
24
24
  RegExp(`^(?:change|switch|set|update|turn|put|make)(?: over)? ${r}(?:(?:app|ui|user interface|interface|screen|display|site|system|menu|application) )?language (?:to|into|as|over to) (.+)$`),
25
25
  RegExp(`^(?:switch|change|set|put|turn) ${r}(?:app|ui|user interface|interface|screen|display|site|application|menus?) (?:language )?(?:to|into) (.+)$`),
26
26
  RegExp(`^(?:show|display|use|run) ${r}(?:app|ui|user interface|interface|screen|display|site|application)(?: menus?)? in (.+)$`)
27
- ], j = RegExp(`^(?:switch|change)(?: over)? to ${r}(.+)$`), M = RegExp(`^${i} ${r}(?:(?:assistant|ai|conversation|conversations|chat) history|history of (?:my )?(?:conversations|chats)|(?:past|previous|old|earlier) conversations)$`), N = RegExp(`^${i} ${r}history$`), P = RegExp(`^${i} ${r}(?:voice|spoken|speech) transcript$`), F = RegExp(`^${i} ${r}transcript$`), ne = RegExp(`^${i} ${r}(?:ai|assistant) preview(?: panel| pane| surface)?$`), I = RegExp(`^${i} ${r}preview(?: panel| pane)?$`), L = RegExp(`^(?:close|hide|dismiss) ${r}(?:ai|assistant) preview(?: panel| pane| surface)?$`), R = RegExp(`^(?:close|hide) ${r}preview(?: panel| pane)?$`), z = /^(?:(?:start|begin|open) (?:a |an |another )?(?:new |fresh |blank )?conversation|new conversation|(?:start|begin) (?:a )?(?:new|fresh) conversation with you)$/, B = [RegExp(`^(?:go to|open|show|show me|switch to|select|view|change to|move to|take me to|bring up) ${r}(.+) tab$`), /^(?:switch|change|move) tabs? to (.+)$/], V = "(?:filter|narrow|limit)(?: down)?", H = [RegExp(`^${V}(?: ${r}(?:page|list|table|results|items|rows|view))? (?:by|to|for|on) ${r}(.+)$`)], U = [/^(?:show|display|list|keep) only (.+)$/, /^only (?:show|display|list|keep) (.+)$/], W = [
27
+ ], j = RegExp(`^(?:switch|change)(?: over)? to ${r}(.+)$`), M = RegExp(`^${i} ${r}(?:(?:assistant|ai|conversation|conversations|chat) history|history of (?:my )?(?:conversations|chats)|(?:past|previous|old|earlier) conversations)$`), N = RegExp(`^${i} ${r}history$`), P = RegExp(`^${i} ${r}(?:voice|spoken|speech) transcript$`), ne = RegExp(`^${i} ${r}transcript$`), F = RegExp(`^${i} ${r}(?:ai|assistant) preview(?: panel| pane| surface)?$`), I = RegExp(`^${i} ${r}preview(?: panel| pane)?$`), L = RegExp(`^(?:close|hide|dismiss) ${r}(?:ai|assistant) preview(?: panel| pane| surface)?$`), R = RegExp(`^(?:close|hide) ${r}preview(?: panel| pane)?$`), z = /^(?:(?:start|begin|open) (?:a |an |another )?(?:new |fresh |blank )?conversation|new conversation|(?:start|begin) (?:a )?(?:new|fresh) conversation with you)$/, B = [RegExp(`^(?:go to|open|show|show me|switch to|select|view|change to|move to|take me to|bring up) ${r}(.+) tab$`), /^(?:switch|change|move) tabs? to (.+)$/], V = "(?:filter|narrow|limit)(?: down)?", H = [RegExp(`^${V}(?: ${r}(?:page|list|table|results|items|rows|view))? (?:by|to|for|on) ${r}(.+)$`)], U = [/^(?:show|display|list|keep) only (.+)$/, /^only (?:show|display|list|keep) (.+)$/], W = [
28
28
  RegExp(`^(?:set|change|switch|put|make) ${r}(.+?) filter (?:to|as|on) (.+)$`),
29
29
  RegExp(`^${V} ${r}(.+?) (?:by|to|for|on) (.+)$`),
30
30
  RegExp(`^(?:use|apply) ${r}(.+?) filter (?:of|with|for|set to) (.+)$`)
@@ -33,11 +33,11 @@ var l = 60, u = /^(?:log ?out|sign ?out|(?:log|sign) (?:me )?out(?: of (?:the |m
33
33
  [/(?: in)? (?:descending|desc)(?: order)?$/, "desc"],
34
34
  [/ (?:a to z|low to high|lowest first|smallest first|oldest first)$/, "asc"],
35
35
  [/ (?:z to a|high to low|highest first|largest first|biggest first|newest first|latest first)$/, "desc"]
36
- ], q = RegExp(`^(?:sort|order|arrange|rank)(?: ${r}(?:page|list|table|results|items|rows|view|it|them))? by (.+)$`), re = K.map(([e]) => new RegExp(q.source.slice(0, -1) + e.source)), J = /^(?:sort|order)(?: it| them)? (ascending|descending|asc|desc)$/, Y = [
36
+ ], q = `^(?:sort|order|arrange|rank)(?: ${r}(?:page|list|table|results|items|rows|view|it|them))? by (.+)`, J = RegExp(`${q}$`), re = K.map(([e]) => new RegExp(q + e.source)), Y = /^(?:sort|order)(?: it| them)? (ascending|descending|asc|desc)$/, X = [
37
37
  /^(?:search|find|look)(?: (?:this page|the page|the list|the table|this list|this table|here|these|them))? for (.+)$/,
38
38
  /^(?:find|search for) (.+?) (?:on|in) (?:this|the) (?:page|list|table)$/,
39
39
  /^search (?:this page|the page|the list|the table|here) (?:for )?(.+)$/
40
- ], X = /^(?:clear|reset|empty|remove|stop) (?:the |my |this )?(?:page )?search(?:ing)?$/, Z = [RegExp(`^(?:open|show|start|bring up|pull up) ${r}(.+?) (?:form|dialog|dialogue|modal)$`)], Q = RegExp(`^(?:open|show|start|bring up|pull up) ${r}(.+)$`), ie = /\b(?:and then|then|and also|also|after that|afterwards|and open|and show|and go|and sort|and filter)\b/;
40
+ ], Z = /^(?:clear|reset|empty|remove|stop) (?:the |my |this )?(?:page )?search(?:ing)?$/, Q = [RegExp(`^(?:open|show|start|bring up|pull up) ${r}(.+?) (?:form|dialog|dialogue|modal)$`)], ie = RegExp(`^(?:open|show|start|bring up|pull up) ${r}(.+)$`), ae = /\b(?:and then|then|and also|also|after that|afterwards|and open|and show|and go|and sort|and filter)\b/;
41
41
  function $(e, t) {
42
42
  for (let n of e) {
43
43
  let e = n.exec(t);
@@ -45,7 +45,7 @@ function $(e, t) {
45
45
  }
46
46
  return null;
47
47
  }
48
- function ae(e) {
48
+ function oe(e) {
49
49
  for (let [t, n] of K) {
50
50
  let r = t.exec(e);
51
51
  if (r) return {
@@ -58,13 +58,13 @@ function ae(e) {
58
58
  direction: null
59
59
  };
60
60
  }
61
- function oe(e) {
61
+ function se(e) {
62
62
  let t = e.replace(/\b(?:please|pls)$/, "").trim();
63
63
  return !t || t.length > l ? null : t;
64
64
  }
65
- function se(r, i, s) {
65
+ function ce(r, i, s) {
66
66
  let l = s.registered;
67
- if (ie.test(r)) return null;
67
+ if (ae.test(r)) return null;
68
68
  if (l["account.logout"] && u.test(r)) return a({ control: "account.logout" });
69
69
  if (l["header.workspace"] || l["header.context"]) {
70
70
  let e = f.exec(r) ?? p.exec(r);
@@ -88,7 +88,7 @@ function se(r, i, s) {
88
88
  }
89
89
  if (l["header.search"]) {
90
90
  for (let e of C) {
91
- let t = e.exec(r), n = t ? oe(t[1] ?? "") : null;
91
+ let t = e.exec(r), n = t ? se(t[1] ?? "") : null;
92
92
  if (n) return a({
93
93
  control: "header.search",
94
94
  query: c(i, n)
@@ -147,10 +147,10 @@ function se(r, i, s) {
147
147
  }
148
148
  if (l["assistant.transcript"]) {
149
149
  if (P.test(r)) return a({ control: "assistant.transcript" });
150
- if (F.test(r)) return o({ control: "assistant.transcript" });
150
+ if (ne.test(r)) return o({ control: "assistant.transcript" });
151
151
  }
152
152
  if (l["assistant.preview"]) {
153
- if (ne.test(r)) return a({ control: "assistant.preview" });
153
+ if (F.test(r)) return a({ control: "assistant.preview" });
154
154
  if (I.test(r)) return o({ control: "assistant.preview" });
155
155
  if (L.test(r)) return a({ control: "assistant.preview.close" });
156
156
  if (R.test(r)) return o({ control: "assistant.preview.close" });
@@ -203,15 +203,15 @@ function se(r, i, s) {
203
203
  }
204
204
  }
205
205
  if (d.sorts.length > 0) {
206
- let e = J.exec(r);
206
+ let e = Y.exec(r);
207
207
  if (e) return a({
208
208
  control: "page.sort",
209
209
  field: null,
210
210
  direction: /^asc/.test(e[1] ?? "") ? "asc" : "desc"
211
211
  });
212
- let t = q.exec(r);
212
+ let t = J.exec(r);
213
213
  if (t) {
214
- let { field: e, direction: n } = ae((t[1] ?? "").trim());
214
+ let { field: e, direction: n } = oe((t[1] ?? "").trim());
215
215
  if (e) return a({
216
216
  control: "page.sort",
217
217
  field: e,
@@ -220,20 +220,20 @@ function se(r, i, s) {
220
220
  }
221
221
  }
222
222
  if (d.searchable) {
223
- if (X.test(r)) return a({ control: "page.search.clear" });
224
- let e = $(Y, r), t = e ? oe(e[1] ?? "") : null;
223
+ if (Z.test(r)) return a({ control: "page.search.clear" });
224
+ let e = $(X, r), t = e ? se(e[1] ?? "") : null;
225
225
  if (t) return a({
226
226
  control: "page.search",
227
227
  query: c(i, t)
228
228
  });
229
229
  }
230
230
  if (d.openers.length > 0) {
231
- let t = $(Z, r), i = t ? (t[1] ?? "").trim() : "";
231
+ let t = $(Q, r), i = t ? (t[1] ?? "").trim() : "";
232
232
  if (i && n(i, d.openers).kind !== "none") return a({
233
233
  control: "page.open",
234
234
  name: i
235
235
  });
236
- let s = Q.exec(r), c = s ? (s[1] ?? "").trim() : "";
236
+ let s = ie.exec(r), c = s ? (s[1] ?? "").trim() : "";
237
237
  if (c && d.openers.filter((t) => e(t.label) === c).length > 0) return o({
238
238
  control: "page.open",
239
239
  name: c
@@ -241,13 +241,13 @@ function se(r, i, s) {
241
241
  }
242
242
  return null;
243
243
  }
244
- function ce(e) {
244
+ function le(e) {
245
245
  let t = e.registered, n = [], r = (e, ...t) => {
246
246
  e && n.push(...t);
247
247
  };
248
- r(t["account.logout"], u), r(t["header.workspace"], f, p), r(t["header.context"], m, h), r(t["header.notifications"], g, _, v), r(t["header.help"], y, b), r(t["header.search"], x, S, ...C), r(t.sidebar, T, E, O, k), r(t.language, ...A, j), r(t["assistant.history"], M, N), r(t["assistant.transcript"], P, F), r(t["assistant.preview"], ne, I, L, R), r(t["assistant.conversation.new"], z);
248
+ r(t["account.logout"], u), r(t["header.workspace"], f, p), r(t["header.context"], m, h), r(t["header.notifications"], g, _, v), r(t["header.help"], y, b), r(t["header.search"], x, S, ...C), r(t.sidebar, T, E, O, k), r(t.language, ...A, j), r(t["assistant.history"], M, N), r(t["assistant.transcript"], P, ne), r(t["assistant.preview"], F, I, L, R), r(t["assistant.conversation.new"], z);
249
249
  let i = e.page;
250
- return i && (r(i.tabs.length > 0, ...B), r(i.filters.length > 0, ...H, ...U, ...W, G), r(i.sorts.length > 0, q, ...re, J), r(i.searchable, X, ...Y), r(i.openers.length > 0, ...Z, Q)), n;
250
+ return i && (r(i.tabs.length > 0, ...B), r(i.filters.length > 0, ...H, ...U, ...W, G), r(i.sorts.length > 0, J, ...re, Y), r(i.searchable, Z, ...X), r(i.openers.length > 0, ...Q, ie)), n;
251
251
  }
252
252
  //#endregion
253
- export { ce as appControlPrefixPatterns, se as matchAppControl, c as queryAsSaid };
253
+ export { le as appControlPrefixPatterns, ce as matchAppControl, c as queryAsSaid };
@@ -14,7 +14,7 @@ var e = {
14
14
  "assistant.conversation.new": [],
15
15
  page: []
16
16
  }, t = /* @__PURE__ */ new Set(), n = () => {
17
- for (let e of t) e();
17
+ for (let e of [...t]) e();
18
18
  };
19
19
  function r(e) {
20
20
  return t.add(e), () => {
@@ -1,161 +1,162 @@
1
1
  //#region src/shared/assistant/commandCompletions.ts
2
- var e = /* @__PURE__ */ new WeakMap(), t = " abcdefghijklmnopqrstuvwxyz0123456789";
3
- function n(n) {
4
- let r = e.get(n);
5
- if (r) return r;
6
- let i = n.source, a = 0, o = () => {
7
- let e = [], n = [];
8
- for (; a < i.length && i[a] !== ")";) {
9
- let r = i[a++];
10
- if (r === "|") {
2
+ var e = /* @__PURE__ */ new WeakMap(), t = " abcdefghijklmnopqrstuvwxyz0123456789", n = class extends Error {};
3
+ function r(r) {
4
+ let i = e.get(r);
5
+ if (i) return i;
6
+ let a = r.source, o = 0, s = () => {
7
+ let e = [], r = [];
8
+ for (; o < a.length && a[o] !== ")";) {
9
+ let i = a[o++];
10
+ if (i === "|") {
11
11
  e.push({
12
12
  kind: "seq",
13
- nodes: n
14
- }), n = [];
13
+ nodes: r
14
+ }), r = [];
15
15
  continue;
16
16
  }
17
- let s;
18
- if (r === "^" || r === "$") continue;
19
- if (r === "(") {
17
+ let c;
18
+ if (i === "^" || i === "$") continue;
19
+ if (i === "(") {
20
20
  let e;
21
- if (i.startsWith("?:", a)) a += 2;
22
- else if (i.startsWith("?<", a)) {
23
- let t = i.indexOf(">", a);
24
- if (t < 0) throw Error("Invalid command capture");
25
- e = i.slice(a + 2, t), a = t + 1;
26
- } else if (i[a] === "?") throw Error("Unsupported command assertion");
27
- if (s = o(), i[a++] !== ")") throw Error("Unclosed command group");
28
- e && (s = {
21
+ if (a.startsWith("?:", o)) o += 2;
22
+ else if (a.startsWith("?<", o)) {
23
+ let t = a.indexOf(">", o);
24
+ if (t < 0) throw new n("Invalid command capture");
25
+ e = a.slice(o + 2, t), o = t + 1;
26
+ } else if (a[o] === "?") throw new n("Unsupported command assertion");
27
+ if (c = s(), a[o++] !== ")") throw new n("Unclosed command group");
28
+ e && (c = {
29
29
  kind: "slot",
30
30
  name: e,
31
- node: s
31
+ node: c
32
32
  });
33
- } else if (r === ".") s = {
33
+ } else if (i === ".") c = {
34
34
  kind: "free",
35
35
  min: 1,
36
36
  max: 1
37
37
  };
38
- else if (r === "[") {
39
- let e = a - 1;
40
- for (; a < i.length && i[a] !== "]";) i[a] === "\\" && (a += 1), a += 1;
41
- let n = RegExp(`^${i.slice(e, ++a)}$`, "u");
42
- s = {
38
+ else if (i === "[") {
39
+ let e = o - 1;
40
+ for (; o < a.length && a[o] !== "]";) a[o] === "\\" && (o += 1), o += 1;
41
+ let n = RegExp(`^${a.slice(e, ++o)}$`, "u");
42
+ c = {
43
43
  kind: "choice",
44
44
  nodes: [...t].filter((e) => n.test(e)).map((e) => ({
45
45
  kind: "text",
46
46
  text: e
47
47
  }))
48
48
  };
49
- } else if (r === "\\") {
50
- let e = i[a++];
49
+ } else if (i === "\\") {
50
+ let e = a[o++];
51
51
  if (e === "b") continue;
52
- if (e === "s") s = {
52
+ if (e === "s") c = {
53
53
  kind: "text",
54
54
  text: " "
55
55
  };
56
- else if (e === "S") s = {
56
+ else if (e === "S") c = {
57
57
  kind: "free",
58
58
  min: 1,
59
59
  max: 1
60
60
  };
61
- else if (e === "d") s = {
61
+ else if (e === "d") c = {
62
62
  kind: "choice",
63
63
  nodes: [..."0123456789"].map((e) => ({
64
64
  kind: "text",
65
65
  text: e
66
66
  }))
67
67
  };
68
- else if (e && !/[a-zA-Z0-9]/.test(e)) s = {
68
+ else if (e && !/[a-zA-Z0-9]/.test(e)) c = {
69
69
  kind: "text",
70
70
  text: e
71
71
  };
72
- else throw Error("Unsupported command escape");
73
- } else s = {
72
+ else throw new n("Unsupported command escape");
73
+ } else c = {
74
74
  kind: "text",
75
- text: r ?? ""
75
+ text: i ?? ""
76
76
  };
77
- let c = 1, l = 1, u = i[a];
78
- if (u === "?" || u === "*" || u === "+") a += 1, c = +(u === "+"), l = u === "?" ? 1 : Infinity;
79
- else if (u === "{") {
80
- let e = /^\{(\d+)(?:,(\d*))?\}/.exec(i.slice(a));
81
- if (!e) throw Error("Unsupported command repetition");
82
- a += e[0].length, c = Number(e[1]), l = e[2] === void 0 ? c : e[2] === "" ? Infinity : Number(e[2]);
77
+ let l = 1, u = 1, d = a[o];
78
+ if (d === "?" || d === "*" || d === "+") o += 1, l = +(d === "+"), u = d === "?" ? 1 : Infinity;
79
+ else if (d === "{") {
80
+ let e = /^\{(\d+)(?:,(\d*))?\}/.exec(a.slice(o));
81
+ if (!e) throw new n("Unsupported command repetition");
82
+ o += e[0].length, l = Number(e[1]), u = e[2] === void 0 ? l : e[2] === "" ? Infinity : Number(e[2]);
83
83
  }
84
- i[a] === "?" && (c !== 1 || l !== 1) && (a += 1), (c !== 1 || l !== 1) && (s = s.kind === "free" ? {
84
+ a[o] === "?" && (l !== 1 || u !== 1) && (o += 1), (l !== 1 || u !== 1) && (c = c.kind === "free" ? {
85
85
  kind: "free",
86
- min: c,
87
- max: l
86
+ min: l,
87
+ max: u
88
88
  } : {
89
89
  kind: "repeat",
90
- node: s,
91
- min: c,
92
- max: l
93
- }), n.push(s);
90
+ node: c,
91
+ min: l,
92
+ max: u
93
+ }), r.push(c);
94
94
  }
95
95
  return e.push({
96
96
  kind: "seq",
97
- nodes: n
97
+ nodes: r
98
98
  }), e.length === 1 ? e[0] : {
99
99
  kind: "choice",
100
100
  nodes: e
101
101
  };
102
- }, s = o();
103
- if (a !== i.length) throw Error("Unexpected command pattern suffix");
104
- return e.set(n, s), s;
102
+ }, c = s();
103
+ if (o !== a.length) throw new n("Unexpected command pattern suffix");
104
+ return e.set(r, c), c;
105
105
  }
106
- function r(e, t, r, i) {
107
- if (t.length > r.maxLength) return !1;
108
- let a = 0, o = (e) => e.length <= r.maxLength && (t.startsWith(e) || e.startsWith(t));
109
- function* s(e, n) {
110
- if (++a > 2e4) throw Error("Command completion budget");
106
+ function i(e, t, i, a) {
107
+ if (t.length > i.maxLength) return !1;
108
+ let o = 0, s = (e) => e.length <= i.maxLength && (t.startsWith(e) || e.startsWith(t));
109
+ function* c(e, r) {
110
+ if (++o > 2e4) throw new n("Command completion budget");
111
111
  if (e.kind === "text") {
112
- let t = n + e.text;
113
- o(t) && (yield t);
114
- } else if (e.kind === "choice") for (let t of e.nodes) yield* s(t, n);
112
+ let t = r + e.text;
113
+ s(t) && (yield t);
114
+ } else if (e.kind === "choice") for (let t of e.nodes) yield* c(t, r);
115
115
  else if (e.kind === "seq") {
116
116
  let { nodes: t } = e;
117
- function* r(e, n) {
117
+ function* n(e, r) {
118
118
  let i = t[e];
119
119
  if (!i) {
120
- yield n;
120
+ yield r;
121
121
  return;
122
122
  }
123
- for (let t of s(i, n)) yield* r(e + 1, t);
123
+ for (let t of c(i, r)) yield* n(e + 1, t);
124
124
  }
125
- yield* r(0, n);
126
- } else if (e.kind === "slot" && r.slots?.[e.name] !== void 0) for (let t of r.slots[e.name] ?? []) yield* s({
125
+ yield* n(0, r);
126
+ } else if (e.kind === "slot" && i.slots?.[e.name] !== void 0) for (let t of i.slots[e.name] ?? []) yield* c({
127
127
  kind: "text",
128
128
  text: t
129
- }, n);
130
- else if (e.kind === "slot") yield* s(e.node, n);
129
+ }, r);
130
+ else if (e.kind === "slot") yield* c(e.node, r);
131
131
  else if (e.kind === "repeat") {
132
- let { min: t, max: i, node: a } = e;
133
- function* o(e, n) {
134
- if (e >= t && (yield n), !(e >= Math.min(i, r.maxLength + 1))) for (let t of s(a, n)) t !== n && (yield* o(e + 1, t));
132
+ let { min: t, max: n, node: a } = e;
133
+ function* o(e, r) {
134
+ if (e >= t && (yield r), !(e >= Math.min(n, i.maxLength + 1))) for (let t of c(a, r)) t !== r && (yield* o(e + 1, t));
135
135
  }
136
- yield* o(0, n);
136
+ yield* o(0, r);
137
137
  } else {
138
- let i = t.slice(Math.min(n.length, t.length)), a = new Set([
139
- i,
140
- i + "item",
138
+ let n = t.slice(Math.min(r.length, t.length)), a = new Set([
139
+ n,
140
+ n + "item",
141
141
  "item",
142
142
  "x",
143
- ...r.names ?? []
144
- ]), s = i.replace(/ /g, "");
145
- for (let e of r.names ?? []) {
143
+ ...i.names ?? []
144
+ ]), o = n.replace(/ /g, "");
145
+ for (let e of i.names ?? []) {
146
146
  let t = e.replace(/ /g, "");
147
- t.startsWith(s) && a.add(i + t.slice(s.length));
147
+ t.startsWith(o) && a.add(n + t.slice(o.length));
148
148
  }
149
- for (let e = i.length; e >= 0; --e) a.add(i.slice(0, e));
150
- for (let t of a) t.length < e.min || t.length > e.max || o(n + t) && (yield n + t);
149
+ for (let e = n.length; e >= 0; --e) a.add(n.slice(0, e));
150
+ for (let t of a) t.length < e.min || t.length > e.max || s(r + t) && (yield r + t);
151
151
  }
152
152
  }
153
153
  try {
154
- for (let r of s(n(e), "")) if (r.startsWith(t) && e.test(r) && i(r)) return !0;
154
+ for (let n of c(r(e), "")) if (n.startsWith(t) && e.test(n) && a(n)) return !0;
155
155
  return !1;
156
- } catch {
156
+ } catch (e) {
157
+ if (!(e instanceof n)) throw e;
157
158
  return !0;
158
159
  }
159
160
  }
160
161
  //#endregion
161
- export { r as hasCommandCompletion };
162
+ export { i as hasCommandCompletion };
@@ -365,5 +365,10 @@ export * from './avatar/live/LiveAvatarMinutes';
365
365
  export * from './avatar/live/createLiveAvatarSeam';
366
366
  export * from './avatar/live/avatarVoice';
367
367
  export * from './promptDelivery';
368
+ export * from './speech/appendSpeechQueue';
369
+ export * from './voice/phraseSpeechConfig';
370
+ export * from './voice/phraseGate';
371
+ export * from './voice/livePhraseSpeech';
372
+ export * from './voice/phrasePlayback';
368
373
  export * from './attachmentAccess';
369
374
  export * from './attachmentAccessCopy';
@@ -19,6 +19,8 @@ export interface LivePartState {
19
19
  readonly gapped: boolean;
20
20
  /** A new generation began while the part was being written. */
21
21
  readonly frozen: boolean;
22
+ /** S7: a tool began after this text part; it is no longer live narration. */
23
+ readonly toolAfter?: boolean;
22
24
  }
23
25
  export interface LiveMessageState {
24
26
  readonly created?: number;
@@ -27,6 +29,7 @@ export interface LiveMessageState {
27
29
  export interface LiveDeltaState {
28
30
  /** +1 for every re-mint. */
29
31
  readonly generation: number;
32
+ readonly toolIds?: ReadonlySet<string>;
30
33
  readonly parts: ReadonlyMap<string, LivePartState>;
31
34
  readonly messages: ReadonlyMap<string, LiveMessageState>;
32
35
  }
@@ -109,7 +109,23 @@ function p(e, t) {
109
109
  if (!n) return e;
110
110
  switch (t.event) {
111
111
  case "message.updated": return u(e, n);
112
- case "message.part.updated": return n.type === "text" ? d(e, n) : e;
112
+ case "message.part.updated": {
113
+ if (n.type === "text") return d(e, n);
114
+ if (n.type !== "tool") return e;
115
+ let t = a(n.id), r = a(n.messageID);
116
+ if (!t || !r || e.toolIds?.has(t)) return e;
117
+ if ((e.toolIds?.size ?? 0) >= 256) return c(e);
118
+ let i = new Map(e.parts);
119
+ for (let [e, t] of i) t.messageId === r && i.set(e, {
120
+ ...t,
121
+ toolAfter: !0
122
+ });
123
+ return {
124
+ ...e,
125
+ parts: i,
126
+ toolIds: new Set([...e.toolIds ?? [], t])
127
+ };
128
+ }
113
129
  case "message.part.delta": return n.partType === "text" || n.partType === void 0 ? f(e, n) : e;
114
130
  default: return e;
115
131
  }
@@ -34,6 +34,10 @@ export interface LiveRenderOptions {
34
34
  onFirstDelta?: () => void;
35
35
  /** Called once, when the overlay first shows text. */
36
36
  onFirstVisible?: () => void;
37
+ /** S7 reads validated live parts only AFTER this overlay write, never the poll text. */
38
+ /** Safety notifications precede throttling: a tool must cancel a hold timer now. */
39
+ onLiveState?: (live: LiveDeltaState, floor: number) => void;
40
+ onRendered?: (content: string, live: LiveDeltaState, floor: number) => void;
37
41
  /** Minimum gap between live renders. Leading edge, with a trailing call. */
38
42
  throttleMs?: number;
39
43
  now?: () => number;
@@ -31,9 +31,18 @@ function o(n) {
31
31
  }, y = () => {
32
32
  if (f = null, d || l === null) return;
33
33
  let e = _();
34
- e === "" || e === m || (p = i(), m = e, s.setLive(n.messageId, n.conversationId, e), g || (g = !0, n.onFirstVisible?.()));
34
+ if (e !== "") {
35
+ e !== m && (p = i(), m = e, s.setLive(n.messageId, n.conversationId, e));
36
+ try {
37
+ n.onRendered?.(e, n.stream.live, l);
38
+ } catch {}
39
+ g || (g = !0, n.onFirstVisible?.());
40
+ }
35
41
  }, b = n.stream.onLive(() => {
36
42
  if (d || l === null) return;
43
+ try {
44
+ n.onLiveState?.(n.stream.live, l);
45
+ } catch {}
37
46
  v();
38
47
  let e = p + c - i();
39
48
  if (e <= 0) {