@burdenoff/fe-libs 2026.1004.8 → 2026.1005.2

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 (99) hide show
  1. package/dist/shared/assistant/api.d.ts +18 -0
  2. package/dist/shared/assistant/api.d.ts.map +1 -1
  3. package/dist/shared/assistant/api.js +169 -147
  4. package/dist/shared/assistant/capabilities.d.ts +21 -0
  5. package/dist/shared/assistant/capabilities.d.ts.map +1 -1
  6. package/dist/shared/assistant/capabilities.js +11 -1
  7. package/dist/shared/assistant/i18nManifest.d.ts +4 -0
  8. package/dist/shared/assistant/i18nManifest.d.ts.map +1 -1
  9. package/dist/shared/assistant/i18nManifest.js +4 -0
  10. package/dist/shared/assistant/index.d.ts +20 -0
  11. package/dist/shared/assistant/index.d.ts.map +1 -1
  12. package/dist/shared/assistant/liveDeltas.d.ts +76 -0
  13. package/dist/shared/assistant/liveDeltas.d.ts.map +1 -0
  14. package/dist/shared/assistant/liveDeltas.js +196 -0
  15. package/dist/shared/assistant/liveOverlay.d.ts +62 -0
  16. package/dist/shared/assistant/liveOverlay.d.ts.map +1 -0
  17. package/dist/shared/assistant/liveOverlay.js +64 -0
  18. package/dist/shared/assistant/snapshotPoller.d.ts +48 -0
  19. package/dist/shared/assistant/snapshotPoller.d.ts.map +1 -0
  20. package/dist/shared/assistant/snapshotPoller.js +58 -0
  21. package/dist/shared/assistant/speech/browserSpeechEngine.d.ts.map +1 -1
  22. package/dist/shared/assistant/speech/browserSpeechEngine.js +46 -45
  23. package/dist/shared/assistant/speech/hostedTtsSpeechEngine.d.ts.map +1 -1
  24. package/dist/shared/assistant/speech/hostedTtsSpeechEngine.js +80 -79
  25. package/dist/shared/assistant/store.d.ts +3 -0
  26. package/dist/shared/assistant/store.d.ts.map +1 -1
  27. package/dist/shared/assistant/store.js +43 -35
  28. package/dist/shared/assistant/turnStream.d.ts +71 -0
  29. package/dist/shared/assistant/turnStream.d.ts.map +1 -0
  30. package/dist/shared/assistant/turnStream.js +266 -0
  31. package/dist/shared/assistant/turnTimeline.d.ts +27 -2
  32. package/dist/shared/assistant/turnTimeline.d.ts.map +1 -1
  33. package/dist/shared/assistant/turnTimeline.js +17 -28
  34. package/dist/shared/assistant/types.d.ts +10 -0
  35. package/dist/shared/assistant/types.d.ts.map +1 -1
  36. package/dist/shared/assistant/ui/AssistantChatArea.d.ts.map +1 -1
  37. package/dist/shared/assistant/ui/AssistantChatArea.js +886 -843
  38. package/dist/shared/assistant/ui/AssistantMessageList.d.ts +2 -0
  39. package/dist/shared/assistant/ui/AssistantMessageList.d.ts.map +1 -1
  40. package/dist/shared/assistant/ui/AssistantMessageList.js +48 -32
  41. package/dist/shared/assistant/ui/AssistantMoreMenu.d.ts.map +1 -1
  42. package/dist/shared/assistant/ui/AssistantMoreMenu.js +59 -57
  43. package/dist/shared/assistant/ui/composer/AssistantHandsFreeInterruptToggle.d.ts +17 -0
  44. package/dist/shared/assistant/ui/composer/AssistantHandsFreeInterruptToggle.d.ts.map +1 -0
  45. package/dist/shared/assistant/ui/composer/AssistantHandsFreeInterruptToggle.js +34 -0
  46. package/dist/shared/assistant/ui/useVoiceSession.d.ts +29 -2
  47. package/dist/shared/assistant/ui/useVoiceSession.d.ts.map +1 -1
  48. package/dist/shared/assistant/ui/useVoiceSession.js +247 -213
  49. package/dist/shared/assistant/ui/voice/AssistantVoiceSession.js +2 -0
  50. package/dist/shared/assistant/voice/handsfree/audioTrackTransport.d.ts +33 -0
  51. package/dist/shared/assistant/voice/handsfree/audioTrackTransport.d.ts.map +1 -0
  52. package/dist/shared/assistant/voice/handsfree/audioTrackTransport.js +98 -0
  53. package/dist/shared/assistant/voice/handsfree/backendStreamTransport.d.ts +34 -0
  54. package/dist/shared/assistant/voice/handsfree/backendStreamTransport.d.ts.map +1 -0
  55. package/dist/shared/assistant/voice/handsfree/backendStreamTransport.js +130 -0
  56. package/dist/shared/assistant/voice/handsfree/bargeIn.d.ts +43 -0
  57. package/dist/shared/assistant/voice/handsfree/bargeIn.d.ts.map +1 -0
  58. package/dist/shared/assistant/voice/handsfree/bargeIn.js +32 -0
  59. package/dist/shared/assistant/voice/handsfree/captureWorklet.d.ts +47 -0
  60. package/dist/shared/assistant/voice/handsfree/captureWorklet.d.ts.map +1 -0
  61. package/dist/shared/assistant/voice/handsfree/captureWorklet.js +85 -0
  62. package/dist/shared/assistant/voice/handsfree/echoGate.d.ts +140 -0
  63. package/dist/shared/assistant/voice/handsfree/echoGate.d.ts.map +1 -0
  64. package/dist/shared/assistant/voice/handsfree/echoGate.js +198 -0
  65. package/dist/shared/assistant/voice/handsfree/handsFreeController.d.ts +77 -0
  66. package/dist/shared/assistant/voice/handsfree/handsFreeController.d.ts.map +1 -0
  67. package/dist/shared/assistant/voice/handsfree/handsFreeController.js +126 -0
  68. package/dist/shared/assistant/voice/handsfree/handsFreeRuntime.d.ts +15 -0
  69. package/dist/shared/assistant/voice/handsfree/handsFreeRuntime.d.ts.map +1 -0
  70. package/dist/shared/assistant/voice/handsfree/handsFreeRuntime.js +78 -0
  71. package/dist/shared/assistant/voice/handsfree/handsFreeSetting.d.ts +26 -0
  72. package/dist/shared/assistant/voice/handsfree/handsFreeSetting.d.ts.map +1 -0
  73. package/dist/shared/assistant/voice/handsfree/handsFreeSetting.js +25 -0
  74. package/dist/shared/assistant/voice/handsfree/micCapture.d.ts +21 -0
  75. package/dist/shared/assistant/voice/handsfree/micCapture.d.ts.map +1 -0
  76. package/dist/shared/assistant/voice/handsfree/micCapture.js +72 -0
  77. package/dist/shared/assistant/voice/handsfree/playbackReference.d.ts +38 -0
  78. package/dist/shared/assistant/voice/handsfree/playbackReference.d.ts.map +1 -0
  79. package/dist/shared/assistant/voice/handsfree/playbackReference.js +55 -0
  80. package/dist/shared/assistant/voice/handsfree/preRollRing.d.ts +32 -0
  81. package/dist/shared/assistant/voice/handsfree/preRollRing.d.ts.map +1 -0
  82. package/dist/shared/assistant/voice/handsfree/preRollRing.js +34 -0
  83. package/dist/shared/assistant/voice/handsfree/sttTransport.d.ts +94 -0
  84. package/dist/shared/assistant/voice/handsfree/sttTransport.d.ts.map +1 -0
  85. package/dist/shared/assistant/voice/handsfree/sttTransport.js +27 -0
  86. package/dist/shared/assistant/voice/handsfree/useHandsFreeInterrupt.d.ts +33 -0
  87. package/dist/shared/assistant/voice/handsfree/useHandsFreeInterrupt.d.ts.map +1 -0
  88. package/dist/shared/assistant/voice/handsfree/useHandsFreeInterrupt.js +70 -0
  89. package/dist/shared/assistant/voice/handsfree/vad.d.ts +55 -0
  90. package/dist/shared/assistant/voice/handsfree/vad.d.ts.map +1 -0
  91. package/dist/shared/assistant/voice/handsfree/vad.js +41 -0
  92. package/dist/shared/assistant/voice/handsfree/webSpeechTransport.d.ts +3 -0
  93. package/dist/shared/assistant/voice/handsfree/webSpeechTransport.d.ts.map +1 -0
  94. package/dist/shared/assistant/voice/handsfree/webSpeechTransport.js +16 -0
  95. package/dist/shared/assistant/voice/voiceSession.d.ts +9 -0
  96. package/dist/shared/assistant/voice/voiceSession.d.ts.map +1 -1
  97. package/dist/shared/assistant/voice/voiceSession.js +2 -2
  98. package/dist/shared-assistant.js +224 -204
  99. package/package.json +2 -1
@@ -50,5 +50,26 @@ export declare function isUnknownFieldError(error: unknown): boolean;
50
50
  * found" and "404" are deliberately not matched here.
51
51
  */
52
52
  export declare function isMissingGatewayFieldError(error: unknown, field: string, typeNames?: readonly string[]): boolean;
53
+ /**
54
+ * ★★ BOFF-7914 (speed S3): the turn stream's OWN mint backoff, separate from the
55
+ * `sse` capability above. `getAssistantStreamAccess` (the widget transport's
56
+ * mint) latches `sse: unsupported` for the page on any failure; this one must
57
+ * not: a mint that answered 404 because the relay is off in prod, or failed
58
+ * once on a bad network, is retried after a pause, and never disables the
59
+ * stream for the rest of the page (design rule 6).
60
+ *
61
+ * - a 404 (relay off, product not allowlisted, bridge without the projection)
62
+ * backs off 5 minutes: it is a deployment answer, not a blip;
63
+ * - any other failure backs off 60 seconds;
64
+ * - a success clears it.
65
+ *
66
+ * Per page load, like every capability here. It only ever LENGTHENS a backoff.
67
+ */
68
+ export declare const STREAM_MINT_BACKOFF_UNAVAILABLE_MS: number;
69
+ export declare const STREAM_MINT_BACKOFF_ERROR_MS = 60000;
70
+ /** Is a mint inside its backoff window? */
71
+ export declare function streamMintBackedOff(now?: number): boolean;
72
+ export declare function backOffStreamMint(ms: number, now?: number): void;
73
+ export declare function clearStreamMintBackoff(): void;
53
74
  export {};
54
75
  //# sourceMappingURL=capabilities.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/capabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,WAAW,GAAG,aAAa,CAAC;AAEtE,UAAU,qBAAqB;IAC7B,qBAAqB,EAAE,eAAe,CAAC;IACvC,UAAU,EAAE,eAAe,CAAC;IAC5B,GAAG,EAAE,eAAe,CAAC;IACrB;;;OAGG;IACH,WAAW,EAAE,eAAe,CAAC;IAC7B;;;;OAIG;IACH,yBAAyB,EAAE,eAAe,CAAC;IAC3C,sBAAsB,EAAE,eAAe,CAAC;IACxC,2BAA2B,EAAE,eAAe,CAAC;CAC9C;AAYD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,qBAAqB,GAAG,eAAe,CAE/E;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,qBAAqB,GAAG,IAAI,CAEpE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,qBAAqB,GAAG,IAAI,CAEtE;AAED,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAK3D;AAID;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,SAAS,MAAM,EAAO,GAChC,OAAO,CAWT"}
1
+ {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/capabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,WAAW,GAAG,aAAa,CAAC;AAEtE,UAAU,qBAAqB;IAC7B,qBAAqB,EAAE,eAAe,CAAC;IACvC,UAAU,EAAE,eAAe,CAAC;IAC5B,GAAG,EAAE,eAAe,CAAC;IACrB;;;OAGG;IACH,WAAW,EAAE,eAAe,CAAC;IAC7B;;;;OAIG;IACH,yBAAyB,EAAE,eAAe,CAAC;IAC3C,sBAAsB,EAAE,eAAe,CAAC;IACxC,2BAA2B,EAAE,eAAe,CAAC;CAC9C;AAYD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,qBAAqB,GAAG,eAAe,CAE/E;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,qBAAqB,GAAG,IAAI,CAEpE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,qBAAqB,GAAG,IAAI,CAEtE;AAED,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAK3D;AAID;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,SAAS,MAAM,EAAO,GAChC,OAAO,CAWT;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,kCAAkC,QAAa,CAAC;AAC7D,eAAO,MAAM,4BAA4B,QAAS,CAAC;AAInD,2CAA2C;AAC3C,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,MAAmB,GAAG,OAAO,CAErE;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,IAAI,CAE5E;AAED,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}
@@ -27,5 +27,15 @@ function s(t, n, r = []) {
27
27
  let i = t instanceof Error ? t.message : String(t), a = (e) => `["'\u201C]${o(e)}["'\u201D]`;
28
28
  return /missing @rbac directive/i.test(i) ? RegExp(`Field ${a(n)}`).test(i) ? !0 : e(t).some((e) => e.code === "FORBIDDEN" && e.field === n) : RegExp(`Cannot query field ${a(n)}`).test(i) ? !0 : r.some((e) => RegExp(`Unknown type ${a(e)}`).test(i));
29
29
  }
30
+ var c = 5 * 6e4, l = 6e4, u = 0;
31
+ function d(e = Date.now()) {
32
+ return e < u;
33
+ }
34
+ function f(e, t = Date.now()) {
35
+ u = Math.max(u, t + e);
36
+ }
37
+ function p() {
38
+ u = 0;
39
+ }
30
40
  //#endregion
31
- export { n as getCapability, s as isMissingGatewayFieldError, a as isUnknownFieldError, r as markSupported, i as markUnsupported };
41
+ export { l as STREAM_MINT_BACKOFF_ERROR_MS, c as STREAM_MINT_BACKOFF_UNAVAILABLE_MS, f as backOffStreamMint, p as clearStreamMintBackoff, n as getCapability, s as isMissingGatewayFieldError, a as isUnknownFieldError, r as markSupported, i as markUnsupported, d as streamMintBackedOff };
@@ -402,6 +402,8 @@ export declare const ASSISTANT_I18N_LITERAL_COPY: {
402
402
  readonly "voice.graceLabel": "Wait after I stop talking";
403
403
  readonly "voice.graceOption": "{{seconds}} seconds";
404
404
  readonly "voice.graceOptionDefault": "{{seconds}} seconds (default)";
405
+ readonly "voice.handsFreeHint": "Let the assistant listen while it answers, so you can speak over it to correct it. Works best with headphones. You can always tap to interrupt.";
406
+ readonly "voice.handsFreeLabel": "Hands-free interrupt (beta)";
405
407
  readonly "voice.languageFollowApp": "Same as interface";
406
408
  readonly "voice.languageLabel": "Language you speak to the assistant";
407
409
  readonly "voice.languageNotSupported": "This browser cannot recognise spoken {{language}}. Try a different browser, or type instead.";
@@ -440,6 +442,8 @@ export declare const ASSISTANT_I18N_LITERAL_COPY: {
440
442
  readonly "voiceSession.newSession": "New voice session";
441
443
  readonly "voiceSession.noSpeechSupport": "This browser cannot listen. Try a different browser, or type instead.";
442
444
  readonly "voiceSession.noVoiceSupport": "This device has no voice that can speak this language.";
445
+ readonly "voiceSession.noticeHandsFreeFallback": "Hands-free interrupt turned itself off for this conversation. Tap to interrupt still works.";
446
+ readonly "voiceSession.noticeHandsFreeNothingHeard": "Stopped, but I did not catch that. Say it again, or tap to replay.";
443
447
  readonly "voiceSession.noticeNetwork": "Speech recognition lost its connection. Check your network — it will retry.";
444
448
  readonly "voiceSession.noticeNotCapturing": "The microphone did not start. Check that this site is allowed to use it, then try again.";
445
449
  readonly "voiceSession.noticeNothingHeard": "Nothing heard yet. Check your microphone is not muted or in use by another app.";
@@ -1 +1 @@
1
- {"version":3,"file":"i18nManifest.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/i18nManifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAa1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0GG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAodG,CAAC;AAE5C,mDAAmD;AACnD,MAAM,MAAM,uBAAuB,GAAG,MAAM,OAAO,2BAA2B,CAAC;AAW/E;;;GAGG;AACH,eAAO,MAAM,4BAA4B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgCtE,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,+BAA+B;;EAGjC,CAAC;AAEZ;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAKjE,CAAC;AAEL,kEAAkE;AAClE,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACxC,mBAAmB,EACnB,IAAI,GAAG,OAAO,GAAG,mBAAmB,CACrC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,SAAS,uBAAuB,EAAE,GACxC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAexB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,SAAS,uBAAuB,EAAE,CAAC;IAC1C,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC9C,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiCzB"}
1
+ {"version":3,"file":"i18nManifest.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/i18nManifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAa1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0GG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2dG,CAAC;AAE5C,mDAAmD;AACnD,MAAM,MAAM,uBAAuB,GAAG,MAAM,OAAO,2BAA2B,CAAC;AAW/E;;;GAGG;AACH,eAAO,MAAM,4BAA4B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgCtE,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,+BAA+B;;EAGjC,CAAC;AAEZ;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAKjE,CAAC;AAEL,kEAAkE;AAClE,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACxC,mBAAmB,EACnB,IAAI,GAAG,OAAO,GAAG,mBAAmB,CACrC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,SAAS,uBAAuB,EAAE,GACxC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAexB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,SAAS,uBAAuB,EAAE,CAAC;IAC1C,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC9C,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiCzB"}
@@ -300,6 +300,8 @@ var p = {
300
300
  "voice.graceLabel": "Wait after I stop talking",
301
301
  "voice.graceOption": "{{seconds}} seconds",
302
302
  "voice.graceOptionDefault": "{{seconds}} seconds (default)",
303
+ "voice.handsFreeHint": "Let the assistant listen while it answers, so you can speak over it to correct it. Works best with headphones. You can always tap to interrupt.",
304
+ "voice.handsFreeLabel": "Hands-free interrupt (beta)",
303
305
  "voice.languageFollowApp": "Same as interface",
304
306
  "voice.languageLabel": "Language you speak to the assistant",
305
307
  "voice.languageNotSupported": "This browser cannot recognise spoken {{language}}. Try a different browser, or type instead.",
@@ -338,6 +340,8 @@ var p = {
338
340
  "voiceSession.newSession": "New voice session",
339
341
  "voiceSession.noSpeechSupport": "This browser cannot listen. Try a different browser, or type instead.",
340
342
  "voiceSession.noVoiceSupport": "This device has no voice that can speak this language.",
343
+ "voiceSession.noticeHandsFreeFallback": "Hands-free interrupt turned itself off for this conversation. Tap to interrupt still works.",
344
+ "voiceSession.noticeHandsFreeNothingHeard": "Stopped, but I did not catch that. Say it again, or tap to replay.",
341
345
  "voiceSession.noticeNetwork": "Speech recognition lost its connection. Check your network — it will retry.",
342
346
  "voiceSession.noticeNotCapturing": "The microphone did not start. Check that this site is allowed to use it, then try again.",
343
347
  "voiceSession.noticeNothingHeard": "Nothing heard yet. Check your microphone is not muted or in use by another app.",
@@ -51,6 +51,21 @@ export * from './voice/voiceStatus';
51
51
  export * from './voice/rotationClock';
52
52
  export * from './voice/voiceSession';
53
53
  export * from './voice/handsFree';
54
+ export * from './voice/handsfree/audioTrackTransport';
55
+ export * from './voice/handsfree/backendStreamTransport';
56
+ export * from './voice/handsfree/bargeIn';
57
+ export * from './voice/handsfree/captureWorklet';
58
+ export * from './voice/handsfree/echoGate';
59
+ export * from './voice/handsfree/handsFreeController';
60
+ export * from './voice/handsfree/handsFreeRuntime';
61
+ export * from './voice/handsfree/handsFreeSetting';
62
+ export * from './voice/handsfree/micCapture';
63
+ export * from './voice/handsfree/playbackReference';
64
+ export * from './voice/handsfree/preRollRing';
65
+ export * from './voice/handsfree/sttTransport';
66
+ export * from './voice/handsfree/useHandsFreeInterrupt';
67
+ export * from './voice/handsfree/vad';
68
+ export * from './voice/handsfree/webSpeechTransport';
54
69
  export * from './voice/affirmations';
55
70
  export * from './voice/supersededTurns';
56
71
  export * from './voice/speechVoices';
@@ -143,6 +158,7 @@ export * from './ui/composer/AssistantModeSelector';
143
158
  export * from './ui/composer/AssistantVoiceButton';
144
159
  export * from './ui/composer/AssistantVoiceSelector';
145
160
  export * from './ui/composer/AssistantVoiceGraceSelector';
161
+ export * from './ui/composer/AssistantHandsFreeInterruptToggle';
146
162
  export * from './ui/voice/AssistantVoiceOrb';
147
163
  export * from './ui/voice/AssistantVoiceSessionButton';
148
164
  export * from './ui/voice/VoiceCaption';
@@ -202,6 +218,10 @@ export * from './permissionError';
202
218
  export * from './autoRouting';
203
219
  export * from './turnOutcome';
204
220
  export * from './turnTimeline';
221
+ export * from './turnStream';
222
+ export * from './liveDeltas';
223
+ export * from './liveOverlay';
224
+ export * from './snapshotPoller';
205
225
  export * from './turnTimingReport';
206
226
  export * from './turnTimingReporter';
207
227
  export * from './prewarm';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ import { AssistantRawMessage } from './types';
2
+ /** One frame as the stream hands it over: the SSE event name and its JSON data. */
3
+ export interface LiveFrame {
4
+ readonly event: string;
5
+ readonly data: unknown;
6
+ }
7
+ /** What the reducer holds about one text part. */
8
+ export interface LivePartState {
9
+ readonly messageId: string;
10
+ /** The stream generation that started the part (`LiveDeltaState.generation`). */
11
+ readonly generation: number;
12
+ /** The redacted text so far — or, once `ended`, the final redacted text. */
13
+ readonly text: string;
14
+ /** Began live: this stream saw the part's start frame. `false` is poll-only. */
15
+ readonly live: boolean;
16
+ /** The part's end frame arrived. */
17
+ readonly ended: boolean;
18
+ /** A delta did not continue the text: no later delta is applied. */
19
+ readonly gapped: boolean;
20
+ /** A new generation began while the part was being written. */
21
+ readonly frozen: boolean;
22
+ }
23
+ export interface LiveMessageState {
24
+ readonly created?: number;
25
+ readonly completed?: number;
26
+ }
27
+ export interface LiveDeltaState {
28
+ /** +1 for every re-mint. */
29
+ readonly generation: number;
30
+ readonly parts: ReadonlyMap<string, LivePartState>;
31
+ readonly messages: ReadonlyMap<string, LiveMessageState>;
32
+ }
33
+ /** Bounds on what one turn's stream may make this reducer remember. */
34
+ export declare const LIVE_PART_LIMIT = 256;
35
+ export declare const LIVE_MESSAGE_LIMIT = 256;
36
+ /** The longest live text one part may hold; past it the part is frozen. */
37
+ export declare const LIVE_TEXT_LIMIT: number;
38
+ export declare function createLiveState(): LiveDeltaState;
39
+ /**
40
+ * The stream was lost: whatever arrives next is unknown, so every part still
41
+ * being written is frozen at its text. The generation does not change.
42
+ */
43
+ export declare function freezeLiveParts(state: LiveDeltaState): LiveDeltaState;
44
+ /**
45
+ * A new generation: the stream was replaced (a re-mint). Every part still being
46
+ * written is frozen at its text — the frames between two streams are unknown —
47
+ * and parts the new stream starts belong to the new generation.
48
+ */
49
+ export declare function beginLiveGeneration(state: LiveDeltaState): LiveDeltaState;
50
+ /**
51
+ * Fold one frame into the state. Frames that are not about text (a tool part, a
52
+ * reasoning part, `session.idle`, `stream.end`) change nothing here: they wake
53
+ * the poll loop, and that is `turnStream`'s business.
54
+ */
55
+ export declare function reduceLiveFrame(state: LiveDeltaState, frame: LiveFrame): LiveDeltaState;
56
+ /**
57
+ * The poll's messages with the live text merged in, for DISPLAY ONLY.
58
+ *
59
+ * - Only messages created after `floor` are touched.
60
+ * - A text part the poll already has is rewritten in place (same id); a
61
+ * live-from-start part the poll has not seen yet is appended to its message,
62
+ * or to a synthetic assistant message that is NOT completed.
63
+ * - A part first seen mid-way (`live: false`) is never taken from the stream.
64
+ * - The input is never modified; nothing is removed; nothing but the text of
65
+ * text parts changes.
66
+ */
67
+ export declare function applyLiveDeltas(polled: readonly AssistantRawMessage[], state: LiveDeltaState, floor: number): AssistantRawMessage[];
68
+ /**
69
+ * How much of the turn's text the stream carried: `full` when every text part
70
+ * it saw was live from its start and none was gapped or frozen, `partial` when
71
+ * the stream carried some but not all, `none` when it carried nothing.
72
+ */
73
+ export declare function liveCoverage(state: LiveDeltaState): "full" | "partial" | "none";
74
+ /** Has any live text arrived that could be shown? */
75
+ export declare function hasLiveText(state: LiveDeltaState): boolean;
76
+ //# sourceMappingURL=liveDeltas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"liveDeltas.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/liveDeltas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAA2B,MAAM,SAAS,CAAC;AAE5E,mFAAmF;AACnF,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED,kDAAkD;AAClD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,iFAAiF;IACjF,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,oCAAoC;IACpC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,oEAAoE;IACpE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,4BAA4B;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACnD,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAC1D;AAED,uEAAuE;AACvE,eAAO,MAAM,eAAe,MAAM,CAAC;AACnC,eAAO,MAAM,kBAAkB,MAAM,CAAC;AACtC,2EAA2E;AAC3E,eAAO,MAAM,eAAe,QAAa,CAAC;AAE1C,wBAAgB,eAAe,IAAI,cAAc,CAEhD;AAqBD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,GAAG,cAAc,CASrE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,cAAc,GAAG,cAAc,CAGzE;AA+HD;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,cAAc,EACrB,KAAK,EAAE,SAAS,GACf,cAAc,CAehB;AAoCD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,SAAS,mBAAmB,EAAE,EACtC,KAAK,EAAE,cAAc,EACrB,KAAK,EAAE,MAAM,GACZ,mBAAmB,EAAE,CAmEvB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAa/E;AAED,qDAAqD;AACrD,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAK1D"}
@@ -0,0 +1,196 @@
1
+ //#region src/shared/assistant/liveDeltas.ts
2
+ var e = 256, t = 256, n = 512 * 1024;
3
+ function r() {
4
+ return {
5
+ generation: 0,
6
+ parts: /* @__PURE__ */ new Map(),
7
+ messages: /* @__PURE__ */ new Map()
8
+ };
9
+ }
10
+ function i(e) {
11
+ return typeof e == "object" && e && !Array.isArray(e) ? e : void 0;
12
+ }
13
+ var a = (e) => typeof e == "string" && e !== "" ? e : void 0, o = (e) => typeof e == "number" && Number.isFinite(e) ? e : void 0;
14
+ function s(e, t, n) {
15
+ let r = new Map(e);
16
+ return r.set(t, n), r;
17
+ }
18
+ function c(e) {
19
+ let t = null;
20
+ for (let [n, r] of e.parts) r.live && !r.ended && !r.frozen && (t ??= new Map(e.parts), t.set(n, {
21
+ ...r,
22
+ frozen: !0
23
+ }));
24
+ return t ? {
25
+ ...e,
26
+ parts: t
27
+ } : e;
28
+ }
29
+ function l(e) {
30
+ let t = c(e);
31
+ return {
32
+ ...t,
33
+ generation: t.generation + 1
34
+ };
35
+ }
36
+ function u(e, t) {
37
+ let n = i(t.info), r = a(n?.id);
38
+ if (!n || !r || n.role !== "assistant" || !e.messages.has(r) && e.messages.size >= 256) return e;
39
+ let c = i(n.time), l = o(c?.created), u = o(c?.completed), d = e.messages.get(r);
40
+ return {
41
+ ...e,
42
+ messages: s(e.messages, r, {
43
+ ...l === void 0 ? d?.created === void 0 ? {} : { created: d.created } : { created: l },
44
+ ...u === void 0 ? d?.completed === void 0 ? {} : { completed: d.completed } : { completed: u }
45
+ })
46
+ };
47
+ }
48
+ function d(e, t) {
49
+ let r = a(t.id), c = a(t.messageID);
50
+ if (!r || !c) return e;
51
+ let l = o(i(t.time)?.end) !== void 0, u = typeof t.text == "string" ? t.text : void 0, d = e.parts.get(r);
52
+ if (!d) {
53
+ if (e.parts.size >= 256) return e;
54
+ let n = t.live === !0 && u === "" && !l;
55
+ return {
56
+ ...e,
57
+ parts: s(e.parts, r, {
58
+ messageId: c,
59
+ generation: e.generation,
60
+ text: "",
61
+ live: n,
62
+ ended: l,
63
+ gapped: !1,
64
+ frozen: !1
65
+ })
66
+ };
67
+ }
68
+ return d.ended || !l ? e : !d.live || u === void 0 ? {
69
+ ...e,
70
+ parts: s(e.parts, r, {
71
+ ...d,
72
+ ended: !0
73
+ })
74
+ } : {
75
+ ...e,
76
+ parts: s(e.parts, r, {
77
+ ...d,
78
+ text: u.length > 524288 ? u.slice(0, n) : u,
79
+ ended: !0
80
+ })
81
+ };
82
+ }
83
+ function f(e, t) {
84
+ let n = a(t.partID), r = typeof t.delta == "string" ? t.delta : void 0, i = o(t.offset);
85
+ if (!n || r === void 0) return e;
86
+ let c = e.parts.get(n);
87
+ return !c || !c.live || c.ended || c.gapped || c.frozen ? e : c.generation === e.generation ? i !== c.text.length || c.text.length + r.length > 524288 ? {
88
+ ...e,
89
+ parts: s(e.parts, n, {
90
+ ...c,
91
+ gapped: !0
92
+ })
93
+ } : r === "" ? e : {
94
+ ...e,
95
+ parts: s(e.parts, n, {
96
+ ...c,
97
+ text: c.text + r
98
+ })
99
+ } : {
100
+ ...e,
101
+ parts: s(e.parts, n, {
102
+ ...c,
103
+ frozen: !0
104
+ })
105
+ };
106
+ }
107
+ function p(e, t) {
108
+ let n = i(t.data);
109
+ if (!n) return e;
110
+ switch (t.event) {
111
+ case "message.updated": return u(e, n);
112
+ case "message.part.updated": return n.type === "text" ? d(e, n) : e;
113
+ case "message.part.delta": return n.partType === "text" || n.partType === void 0 ? f(e, n) : e;
114
+ default: return e;
115
+ }
116
+ }
117
+ function m(e, t) {
118
+ return e.time?.end !== void 0 || t.info?.time?.completed !== void 0;
119
+ }
120
+ function h(e, t, n) {
121
+ return t !== void 0 && n ? t : t === void 0 ? e.text : t.startsWith(e.text) ? t : e.text.startsWith(t) ? e.text : t;
122
+ }
123
+ function g(e, t, n) {
124
+ if (t.parts.size === 0) return [...e];
125
+ let r = /* @__PURE__ */ new Map();
126
+ for (let e of t.parts) {
127
+ let [, t] = e;
128
+ if (!t.live || t.text === "" && !t.ended) continue;
129
+ let n = r.get(t.messageId);
130
+ n ? n.push(e) : r.set(t.messageId, [e]);
131
+ }
132
+ if (r.size === 0) return [...e];
133
+ let i = [], a = /* @__PURE__ */ new Set();
134
+ for (let t of e) {
135
+ let e = t.info?.id, o = e ? r.get(e) : void 0;
136
+ if (!e || !o) {
137
+ i.push(t);
138
+ continue;
139
+ }
140
+ a.add(e);
141
+ let s = t.info?.time?.created ?? 0;
142
+ if (t.info?.role !== "assistant" || s <= n) {
143
+ i.push(t);
144
+ continue;
145
+ }
146
+ let c = [...t.parts ?? []];
147
+ for (let [e, n] of o) {
148
+ let r = c.findIndex((t) => t.type === "text" && t.id === e);
149
+ if (r < 0) {
150
+ c.push({
151
+ type: "text",
152
+ id: e,
153
+ text: n.text
154
+ });
155
+ continue;
156
+ }
157
+ let i = c[r], a = h(n, typeof i.text == "string" ? i.text : void 0, m(i, t));
158
+ a !== i.text && (c[r] = {
159
+ ...i,
160
+ text: a
161
+ });
162
+ }
163
+ i.push({
164
+ ...t,
165
+ parts: c
166
+ });
167
+ }
168
+ for (let [e, o] of r) {
169
+ if (a.has(e)) continue;
170
+ let r = t.messages.get(e)?.created;
171
+ r === void 0 || r <= n || i.push({
172
+ info: {
173
+ id: e,
174
+ role: "assistant",
175
+ time: { created: r }
176
+ },
177
+ parts: o.map(([e, t]) => ({
178
+ type: "text",
179
+ id: e,
180
+ text: t.text
181
+ }))
182
+ });
183
+ }
184
+ return i;
185
+ }
186
+ function _(e) {
187
+ let t = 0, n = 0;
188
+ for (let r of e.parts.values()) r.live && r.text !== "" ? (t += 1, (r.gapped || r.frozen) && (n += 1)) : r.live || (n += 1);
189
+ return t === 0 ? "none" : n === 0 ? "full" : "partial";
190
+ }
191
+ function v(e) {
192
+ for (let t of e.parts.values()) if (t.live && t.text !== "") return !0;
193
+ return !1;
194
+ }
195
+ //#endregion
196
+ export { t as LIVE_MESSAGE_LIMIT, e as LIVE_PART_LIMIT, n as LIVE_TEXT_LIMIT, g as applyLiveDeltas, l as beginLiveGeneration, r as createLiveState, c as freezeLiveParts, v as hasLiveText, _ as liveCoverage, p as reduceLiveFrame };
@@ -0,0 +1,62 @@
1
+ import { LiveDeltaState } from './liveDeltas';
2
+ import { AssistantRawMessage } from './types';
3
+ export interface LiveOverlayEntry {
4
+ readonly conversationId: string;
5
+ readonly content: string;
6
+ }
7
+ interface LiveOverlayState {
8
+ readonly byMessageId: Readonly<Record<string, LiveOverlayEntry>>;
9
+ setLive: (messageId: string, conversationId: string, content: string) => void;
10
+ clearLive: (messageId: string) => void;
11
+ }
12
+ /** Not persisted, by construction: there is no `persist` in this file. */
13
+ export declare const useLiveOverlay: import('zustand').UseBoundStore<import('zustand').StoreApi<LiveOverlayState>>;
14
+ /** The live text for one message, or null when there is none. */
15
+ export declare function useLiveOverlayContent(messageId: string | null | undefined): string | null;
16
+ /** What the live renderer needs of the stream. `TurnStream` satisfies it. */
17
+ export interface LiveSource {
18
+ readonly live: LiveDeltaState;
19
+ onLive(listener: () => void): () => void;
20
+ endLive(): void;
21
+ }
22
+ export interface LiveRenderOptions {
23
+ stream: LiveSource;
24
+ conversationId: string;
25
+ /** The turn's own assistant message id: the only key this writes. */
26
+ messageId: string;
27
+ /**
28
+ * The bubble's text for these messages — the SAME builder the poll uses
29
+ * (`buildAssistantProgress` + `sanitizeAssistantResponse`), so the live text
30
+ * and the finished answer are made the same way.
31
+ */
32
+ build: (messages: AssistantRawMessage[], floor: number) => string;
33
+ /** Called once, when live text first exists for this turn (after arming). */
34
+ onFirstDelta?: () => void;
35
+ /** Called once, when the overlay first shows text. */
36
+ onFirstVisible?: () => void;
37
+ /** Minimum gap between live renders. Leading edge, with a trailing call. */
38
+ throttleMs?: number;
39
+ now?: () => number;
40
+ setTimer?: (run: () => void, ms: number) => unknown;
41
+ clearTimer?: (timer: unknown) => void;
42
+ /** Tests only: a store other than the shared one. */
43
+ overlay?: Pick<LiveOverlayState, "setLive" | "clearLive">;
44
+ }
45
+ export interface LiveRender {
46
+ /**
47
+ * Allow rendering, once the reply floor is known AND the prompt is sent
48
+ * (design rule 3). Frames that arrived earlier were only kept; they render
49
+ * now, if they are this turn's.
50
+ */
51
+ arm(floor: number): void;
52
+ /** The poll landed: re-merge its messages with the live text, at once. */
53
+ refresh(polled: readonly AssistantRawMessage[]): void;
54
+ /** Synchronous, idempotent. Detaches, cancels the throttle, drops the overlay. */
55
+ end(): void;
56
+ readonly armed: boolean;
57
+ readonly ended: boolean;
58
+ }
59
+ export declare const LIVE_RENDER_THROTTLE_MS = 100;
60
+ export declare function createLiveRender(options: LiveRenderOptions): LiveRender;
61
+ export {};
62
+ //# sourceMappingURL=liveOverlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"liveOverlay.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/liveOverlay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEnD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,UAAU,gBAAgB;IACxB,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACjE,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9E,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED,0EAA0E;AAC1E,eAAO,MAAM,cAAc,+EAyBxB,CAAC;AAEJ,iEAAiE;AACjE,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACnC,MAAM,GAAG,IAAI,CAIf;AAED,6EAA6E;AAC7E,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,MAAM,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;IACzC,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,UAAU,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,KAAK,EAAE,CAAC,QAAQ,EAAE,mBAAmB,EAAE,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAClE,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,sDAAsD;IACtD,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;IACpD,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,qDAAqD;IACrD,OAAO,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,SAAS,GAAG,WAAW,CAAC,CAAC;CAC3D;AAED,MAAM,WAAW,UAAU;IACzB;;;;OAIG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,0EAA0E;IAC1E,OAAO,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,GAAG,IAAI,CAAC;IACtD,kFAAkF;IAClF,GAAG,IAAI,IAAI,CAAC;IACZ,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,UAAU,CAkGvE"}
@@ -0,0 +1,64 @@
1
+ import { applyLiveDeltas as e, hasLiveText as t } from "./liveDeltas.js";
2
+ import { create as n } from "zustand";
3
+ //#region src/shared/assistant/liveOverlay.ts
4
+ var r = n()((e) => ({
5
+ byMessageId: {},
6
+ setLive: (t, n, r) => e((e) => {
7
+ let i = e.byMessageId[t];
8
+ return i && i.content === r && i.conversationId === n ? e : { byMessageId: {
9
+ ...e.byMessageId,
10
+ [t]: {
11
+ conversationId: n,
12
+ content: r
13
+ }
14
+ } };
15
+ }),
16
+ clearLive: (t) => e((e) => {
17
+ if (!(t in e.byMessageId)) return e;
18
+ let n = { ...e.byMessageId };
19
+ return delete n[t], { byMessageId: n };
20
+ })
21
+ }));
22
+ function i(e) {
23
+ return r((t) => e ? t.byMessageId[e]?.content ?? null : null);
24
+ }
25
+ var a = 100;
26
+ function o(n) {
27
+ let i = n.now ?? Date.now, a = n.setTimer ?? ((e, t) => setTimeout(e, t)), o = n.clearTimer ?? ((e) => {
28
+ clearTimeout(e);
29
+ }), s = n.overlay ?? r.getState(), c = n.throttleMs ?? 100, l = null, u = [], d = !1, f = null, p = -Infinity, m = "", h = !1, g = !1, _ = () => l === null ? "" : n.build(e(u, n.stream.live, l), l), v = () => {
30
+ h || l === null || t(n.stream.live) && _() !== "" && (h = !0, n.onFirstDelta?.());
31
+ }, y = () => {
32
+ if (f = null, d || l === null) return;
33
+ let e = _();
34
+ e === "" || e === m || (p = i(), m = e, s.setLive(n.messageId, n.conversationId, e), g || (g = !0, n.onFirstVisible?.()));
35
+ }, b = n.stream.onLive(() => {
36
+ if (d || l === null) return;
37
+ v();
38
+ let e = p + c - i();
39
+ if (e <= 0) {
40
+ f !== null && (o(f), f = null), y();
41
+ return;
42
+ }
43
+ f === null && (f = a(y, e));
44
+ });
45
+ return {
46
+ arm(e) {
47
+ d || l !== null || (l = e, v(), y());
48
+ },
49
+ refresh(e) {
50
+ u = e, !(d || l === null) && y();
51
+ },
52
+ end() {
53
+ d || (d = !0, f !== null && (o(f), f = null), b(), s.clearLive(n.messageId), n.stream.endLive());
54
+ },
55
+ get armed() {
56
+ return l !== null;
57
+ },
58
+ get ended() {
59
+ return d;
60
+ }
61
+ };
62
+ }
63
+ //#endregion
64
+ export { a as LIVE_RENDER_THROTTLE_MS, o as createLiveRender, r as useLiveOverlay, i as useLiveOverlayContent };
@@ -0,0 +1,48 @@
1
+ /**
2
+ * ★★ BOFF-7914 (speed S3): the completion fast path.
3
+ *
4
+ * A turn's completion is discovered by a GET of the session's messages — the
5
+ * poll — and only by it. Without a stream the poll is the whole mechanism.
6
+ * With one, the bridge's `session.idle` says the turn is over, and the question
7
+ * becomes how soon after it the poll can SEE that.
8
+ *
9
+ * Take the common case: a GET started just before the idle is still in flight.
10
+ * Its answer was read before the turn settled, so it will probably say "not
11
+ * done", and the loop would then sleep and issue another. Instead, the idle
12
+ * starts ONE extra GET at once, beside the one in flight. Then:
13
+ *
14
+ * - Snapshots are applied in START order. Whichever finishes first is applied;
15
+ * an OLDER snapshot that arrives after a newer one is discarded.
16
+ * - At most one extra request is outstanding, and at most two are started per
17
+ * turn. The cadence of an ordinary poll is unchanged.
18
+ * - A failed request is skipped when a newer one is still pending or has
19
+ * succeeded; it is thrown only when nothing newer can answer.
20
+ * - A snapshot says nothing by itself: the caller applies it exactly as it
21
+ * applies a snapshot without a stream. This module decides nothing about the
22
+ * turn.
23
+ */
24
+ export interface SnapshotPollerOptions {
25
+ /** Extra requests the idle fast path may start per turn. */
26
+ maxExtra?: number;
27
+ }
28
+ export interface SnapshotPoller<T> {
29
+ /**
30
+ * The next snapshot to apply. Starts a request when none is pending; when a
31
+ * newer request than the one that answered is pending, it stays pending for
32
+ * the next call (`hasPending`).
33
+ */
34
+ next(): Promise<T>;
35
+ /**
36
+ * The bridge said the turn is idle. If a request is in flight, start one
37
+ * extra now and return true; otherwise (or past the caps) return false and
38
+ * leave it to the next `next()`.
39
+ */
40
+ startExtra(): boolean;
41
+ /** A started request has not been applied yet: do not sleep before `next()`. */
42
+ hasPending(): boolean;
43
+ /** Requests started in all, for tests and for the timeline. */
44
+ readonly started: number;
45
+ readonly extraStarted: number;
46
+ }
47
+ export declare function createSnapshotPoller<T>(fetch: () => Promise<T>, options?: SnapshotPollerOptions): SnapshotPoller<T>;
48
+ //# sourceMappingURL=snapshotPoller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshotPoller.d.ts","sourceRoot":"","sources":["../../../src/shared/assistant/snapshotPoller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,MAAM,WAAW,qBAAqB;IACpC,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B;;;;OAIG;IACH,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;IACnB;;;;OAIG;IACH,UAAU,IAAI,OAAO,CAAC;IACtB,gFAAgF;IAChF,UAAU,IAAI,OAAO,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAUD,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,KAAK,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACvB,OAAO,GAAE,qBAA0B,GAClC,cAAc,CAAC,CAAC,CAAC,CAoGnB"}