@voicethere/client 0.16.0 → 0.17.0

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.
@@ -0,0 +1,54 @@
1
+ /** Passed as third `onUpsert` argument for spoken `assistant_*` turns only. */
2
+ export type SpokenTurnUpsertInfo = {
3
+ /** The turn's text is complete and this is all that will ever be shown. */
4
+ final: boolean;
5
+ inReplyTo?: string;
6
+ };
7
+ export type SpokenChatCaptionOptions = {
8
+ enabled: boolean;
9
+ /**
10
+ * Default `true`. When `false`, a plain `chat_reply` is shown at once (no pacing, no start
11
+ * wait) while spoken `assistant_*` turns are still paced by speech events.
12
+ */
13
+ paceChatReply?: boolean;
14
+ onUpsert: (utteranceId: string, visibleText: string, info?: SpokenTurnUpsertInfo) => void;
15
+ setTimeout?: typeof setTimeout;
16
+ clearTimeout?: typeof clearTimeout;
17
+ };
18
+ export type SpokenChatCaption = {
19
+ handleControlMessage: (payload: Record<string, unknown>) => void;
20
+ setEnabled: (enabled: boolean) => void;
21
+ dispose: () => void;
22
+ };
23
+ export declare function createSpokenChatCaption(opts: SpokenChatCaptionOptions): SpokenChatCaption;
24
+ /**
25
+ * `playback` (default): spoken agent text is revealed word by word while the agent speaks.
26
+ * `immediate`: spoken agent text is reported as soon as the agent hands it to speech.
27
+ */
28
+ export type SpokenTextRevealMode = "playback" | "immediate";
29
+ export type AgentTextUpdate = {
30
+ turnId: string;
31
+ /** Visible text of the whole turn so far (not a delta). */
32
+ text: string;
33
+ spoken: boolean;
34
+ /** No further update for this turn will follow. */
35
+ final: boolean;
36
+ inReplyTo?: string;
37
+ };
38
+ export type AgentTextReveal = {
39
+ handleControlMessage: (payload: Record<string, unknown>) => void;
40
+ dispose: () => void;
41
+ };
42
+ /**
43
+ * Maps the agent's `assistant_delta` / `assistant_done` messages onto `onAgentText`, one call per
44
+ * visible change. Spoken turns go through {@link createSpokenChatCaption} (paced when `mode` is
45
+ * `playback`); typed turns are passed through at once. The `chat_reply` that follows a typed
46
+ * `assistant_done` carries the same text and is never reported.
47
+ */
48
+ export declare function createAgentTextReveal(opts: {
49
+ mode?: SpokenTextRevealMode;
50
+ onAgentText: (update: AgentTextUpdate) => void;
51
+ setTimeout?: typeof setTimeout;
52
+ clearTimeout?: typeof clearTimeout;
53
+ }): AgentTextReveal;
54
+ //# sourceMappingURL=spoken-text-reveal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spoken-text-reveal.d.ts","sourceRoot":"","sources":["../src/spoken-text-reveal.ts"],"names":[],"mappings":"AASA,+EAA+E;AAC/E,MAAM,MAAM,oBAAoB,GAAG;IACjC,2EAA2E;IAC3E,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,EAAE,CACR,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE,oBAAoB,KACxB,IAAI,CAAC;IACV,UAAU,CAAC,EAAE,OAAO,UAAU,CAAC;IAC/B,YAAY,CAAC,EAAE,OAAO,YAAY,CAAC;CACpC,CAAC;AAiCF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,oBAAoB,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACjE,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAgEF,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,wBAAwB,GAC7B,iBAAiB,CA4enB;AAED;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG,WAAW,CAAC;AAI5D,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,mDAAmD;IACnD,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,oBAAoB,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACjE,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B,WAAW,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IAC/C,UAAU,CAAC,EAAE,OAAO,UAAU,CAAC;IAC/B,YAAY,CAAC,EAAE,OAAO,YAAY,CAAC;CACpC,GAAG,eAAe,CA+ElB"}
@@ -0,0 +1,591 @@
1
+ const START_FALLBACK_MS = 400;
2
+ /**
3
+ * A completed spoken turn whose audio never starts shows its full text after this wait.
4
+ * Internal: spoken turns never use START_FALLBACK_MS, they wait for `agent_speaking_start`.
5
+ */
6
+ const SPOKEN_START_FALLBACK_MS = 5000;
7
+ const DEFAULT_MS_PER_WORD = 330;
8
+ const COMPLETED_IDS_MAX = 32;
9
+ function splitWords(text) {
10
+ return text.split(/\s+/).filter(Boolean);
11
+ }
12
+ function incomingAgentTextFromControlMessage(payload, options) {
13
+ const type = typeof payload.type === "string" ? payload.type : "";
14
+ if (type === "session_error" ||
15
+ type === "agent_error" ||
16
+ type === "session_close" ||
17
+ type === "session_reconnect_token") {
18
+ return null;
19
+ }
20
+ if (type === "speech_event") {
21
+ if (options.ignoreSpeechEventAgentText) {
22
+ return null;
23
+ }
24
+ const event = typeof payload.event === "string" ? payload.event : "";
25
+ const text = typeof payload.text === "string" ? payload.text.trim() : "";
26
+ if (!text)
27
+ return null;
28
+ if (event.includes("final") || event.includes("agent")) {
29
+ return text;
30
+ }
31
+ return null;
32
+ }
33
+ if (type === "chat_reply") {
34
+ const text = typeof payload.text === "string" ? payload.text.trim() : "";
35
+ return text || null;
36
+ }
37
+ if (type === "chat_broadcast") {
38
+ const text = typeof payload.text === "string" ? payload.text.trim() : "";
39
+ return text || null;
40
+ }
41
+ if (type === "chat") {
42
+ const role = typeof payload.role === "string" ? payload.role : "";
43
+ const text = typeof payload.text === "string" ? payload.text.trim() : "";
44
+ if (!text)
45
+ return null;
46
+ if (role === "agent" || role === "assistant") {
47
+ return text;
48
+ }
49
+ return null;
50
+ }
51
+ const text = typeof payload.text === "string" ? payload.text.trim() : "";
52
+ if (text &&
53
+ (type === "agent_message" || type === "message" || type === "assistant")) {
54
+ return text;
55
+ }
56
+ return null;
57
+ }
58
+ export function createSpokenChatCaption(opts) {
59
+ let enabled = opts.enabled;
60
+ let state = null;
61
+ let utteranceCounter = 0;
62
+ const completed = new Map();
63
+ const spokenTurns = new Map();
64
+ // The caption follows one utterance at a time: a new turnId drops the previous state and
65
+ // leaves its line at a prefix. A finished, unfrozen turn is settled to its full text first.
66
+ let currentSpoken = null;
67
+ /** Single send path for every visible change; spoken turns carry `info`. */
68
+ const emit = (utteranceId, visibleText) => {
69
+ const turn = spokenTurns.get(utteranceId);
70
+ if (!turn) {
71
+ opts.onUpsert(utteranceId, visibleText);
72
+ return;
73
+ }
74
+ turn.lastEmitted = visibleText;
75
+ const final = turn.done && (turn.frozen || visibleText === turn.text);
76
+ if (final)
77
+ turn.finalReported = true;
78
+ opts.onUpsert(utteranceId, visibleText, {
79
+ final,
80
+ ...(turn.inReplyTo !== undefined ? { inReplyTo: turn.inReplyTo } : {}),
81
+ });
82
+ };
83
+ const setTimeoutFn = opts.setTimeout ?? setTimeout;
84
+ const clearTimeoutFn = opts.clearTimeout ?? clearTimeout;
85
+ const newUtteranceId = () => {
86
+ utteranceCounter += 1;
87
+ return `utterance-${utteranceCounter}`;
88
+ };
89
+ const clearUtteranceTimers = (utterance) => {
90
+ if (utterance.startTimeoutId !== undefined) {
91
+ clearTimeoutFn(utterance.startTimeoutId);
92
+ utterance.startTimeoutId = undefined;
93
+ }
94
+ if (utterance.tickTimeoutId !== undefined) {
95
+ clearTimeoutFn(utterance.tickTimeoutId);
96
+ utterance.tickTimeoutId = undefined;
97
+ }
98
+ };
99
+ const visibleTextFor = (utterance) => {
100
+ if (utterance.visibleWordCount <= 0)
101
+ return "";
102
+ return utterance.words.slice(0, utterance.visibleWordCount).join(" ");
103
+ };
104
+ const upsertCurrent = () => {
105
+ if (!state)
106
+ return;
107
+ emit(state.utteranceId, visibleTextFor(state));
108
+ };
109
+ const markCompleted = (utterance) => {
110
+ completed.delete(utterance.utteranceId);
111
+ completed.set(utterance.utteranceId, utterance.words.join(" "));
112
+ while (completed.size > COMPLETED_IDS_MAX) {
113
+ const oldest = completed.keys().next().value;
114
+ if (oldest === undefined)
115
+ break;
116
+ completed.delete(oldest);
117
+ }
118
+ };
119
+ /** A streamed utterance is done when its text is final and fully shown. */
120
+ const finishStreamedIfComplete = (utterance) => {
121
+ if (!utterance.streamed ||
122
+ !utterance.final ||
123
+ utterance.frozen ||
124
+ utterance.visibleWordCount < utterance.words.length) {
125
+ return;
126
+ }
127
+ clearUtteranceTimers(utterance);
128
+ markCompleted(utterance);
129
+ if (state === utterance) {
130
+ state = null;
131
+ }
132
+ };
133
+ const scheduleNextWord = (utterance) => {
134
+ if (utterance.frozen ||
135
+ utterance.paused ||
136
+ utterance.tickTimeoutId !== undefined ||
137
+ utterance.visibleWordCount >= utterance.words.length) {
138
+ return;
139
+ }
140
+ utterance.tickTimeoutId = setTimeoutFn(() => {
141
+ utterance.tickTimeoutId = undefined;
142
+ if (!state || state !== utterance || utterance.frozen)
143
+ return;
144
+ if (utterance.paused)
145
+ return;
146
+ utterance.visibleWordCount += 1;
147
+ upsertCurrent();
148
+ scheduleNextWord(utterance);
149
+ finishStreamedIfComplete(utterance);
150
+ }, utterance.intervalMs);
151
+ };
152
+ const startReveal = (utterance) => {
153
+ if (utterance.revealStarted || utterance.frozen)
154
+ return;
155
+ utterance.revealStarted = true;
156
+ utterance.waitingForStart = false;
157
+ if (utterance.startTimeoutId !== undefined) {
158
+ clearTimeoutFn(utterance.startTimeoutId);
159
+ utterance.startTimeoutId = undefined;
160
+ }
161
+ if (utterance.words.length === 0) {
162
+ upsertCurrent();
163
+ return;
164
+ }
165
+ if (utterance.visibleWordCount === 0) {
166
+ utterance.visibleWordCount = 1;
167
+ }
168
+ upsertCurrent();
169
+ if (utterance.visibleWordCount < utterance.words.length) {
170
+ scheduleNextWord(utterance);
171
+ }
172
+ finishStreamedIfComplete(utterance);
173
+ };
174
+ const snapToFull = (utterance) => {
175
+ if (utterance.frozen)
176
+ return;
177
+ clearUtteranceTimers(utterance);
178
+ utterance.revealStarted = true;
179
+ utterance.waitingForStart = false;
180
+ utterance.visibleWordCount = utterance.words.length;
181
+ emit(utterance.utteranceId, utterance.words.join(" "));
182
+ if (state === utterance) {
183
+ state = null;
184
+ }
185
+ };
186
+ const resetUtteranceState = () => {
187
+ if (state) {
188
+ clearUtteranceTimers(state);
189
+ state = null;
190
+ }
191
+ };
192
+ const updateStreamed = (utterance, text, partial) => {
193
+ if (utterance.frozen)
194
+ return;
195
+ const words = splitWords(text);
196
+ const isPrefix = utterance.words.length <= words.length &&
197
+ utterance.words.every((word, i) => word === words[i]);
198
+ utterance.words = words;
199
+ if (!partial) {
200
+ utterance.final = true;
201
+ // Once final, the line is never paused: assistant_done can arrive after
202
+ // the last chunk's agent_speaking_end.
203
+ utterance.paused = false;
204
+ }
205
+ if (!isPrefix) {
206
+ utterance.visibleWordCount = Math.min(utterance.visibleWordCount, words.length);
207
+ if (utterance.revealStarted)
208
+ upsertCurrent();
209
+ }
210
+ if (utterance.revealStarted) {
211
+ scheduleNextWord(utterance);
212
+ }
213
+ finishStreamedIfComplete(utterance);
214
+ };
215
+ const handleChatReply = (payload, spoken = false) => {
216
+ const text = typeof payload.text === "string" ? payload.text.trim() : "";
217
+ if (!text)
218
+ return;
219
+ const utteranceId = typeof payload.utteranceId === "string" && payload.utteranceId.trim()
220
+ ? payload.utteranceId.trim()
221
+ : newUtteranceId();
222
+ const durationMs = typeof payload.durationMs === "number" && payload.durationMs > 0
223
+ ? payload.durationMs
224
+ : undefined;
225
+ const streamExplicit = payload.stream === true;
226
+ const partial = payload.partial === true;
227
+ if (!enabled) {
228
+ resetUtteranceState();
229
+ emit(utteranceId, text);
230
+ return;
231
+ }
232
+ if (!spoken && opts.paceChatReply === false) {
233
+ // Shown at once; a spoken turn's reveal in progress is left alone.
234
+ emit(utteranceId, text);
235
+ return;
236
+ }
237
+ if (state && state.utteranceId === utteranceId && state.streamed) {
238
+ updateStreamed(state, text, partial);
239
+ return;
240
+ }
241
+ if (completed.get(utteranceId) === splitWords(text).join(" ")) {
242
+ return;
243
+ }
244
+ if (state &&
245
+ state.utteranceId !== utteranceId &&
246
+ state.revealStarted &&
247
+ !state.frozen &&
248
+ state.visibleWordCount < state.words.length) {
249
+ clearUtteranceTimers(state);
250
+ state = null;
251
+ }
252
+ else if (state && state.utteranceId !== utteranceId) {
253
+ resetUtteranceState();
254
+ }
255
+ else if (state && state.utteranceId === utteranceId) {
256
+ clearUtteranceTimers(state);
257
+ }
258
+ const words = splitWords(text);
259
+ const wordCount = Math.max(words.length, 1);
260
+ const intervalMs = durationMs !== undefined ? durationMs / wordCount : DEFAULT_MS_PER_WORD;
261
+ state = {
262
+ utteranceId,
263
+ words,
264
+ visibleWordCount: 0,
265
+ intervalMs,
266
+ frozen: false,
267
+ revealStarted: false,
268
+ waitingForStart: true,
269
+ streamExplicit,
270
+ streamed: partial,
271
+ final: !partial,
272
+ paused: false,
273
+ };
274
+ // A spoken turn is never shown before its audio starts.
275
+ if (spoken)
276
+ return;
277
+ state.startTimeoutId = setTimeoutFn(() => {
278
+ if (!state?.waitingForStart || state.revealStarted)
279
+ return;
280
+ if (state.streamExplicit || state.streamed) {
281
+ startReveal(state);
282
+ }
283
+ else {
284
+ snapToFull(state);
285
+ }
286
+ }, START_FALLBACK_MS);
287
+ };
288
+ const handleSpeechEvent = (payload) => {
289
+ const event = typeof payload.event === "string" ? payload.event : "";
290
+ if (event === "agent_speaking_start") {
291
+ if (state?.streamed && !state.frozen) {
292
+ state.paused = false;
293
+ if (!state.revealStarted) {
294
+ startReveal(state);
295
+ }
296
+ else {
297
+ scheduleNextWord(state);
298
+ }
299
+ return;
300
+ }
301
+ if (state && (state.waitingForStart || !state.revealStarted)) {
302
+ startReveal(state);
303
+ }
304
+ return;
305
+ }
306
+ if (event === "agent_speaking_end") {
307
+ if (state?.streamed) {
308
+ if (state.final)
309
+ return;
310
+ state.paused = true;
311
+ if (state.tickTimeoutId !== undefined) {
312
+ clearTimeoutFn(state.tickTimeoutId);
313
+ state.tickTimeoutId = undefined;
314
+ }
315
+ return;
316
+ }
317
+ if (state) {
318
+ clearUtteranceTimers(state);
319
+ state.visibleWordCount = state.words.length;
320
+ state.waitingForStart = false;
321
+ upsertCurrent();
322
+ state = null;
323
+ }
324
+ return;
325
+ }
326
+ if (event === "barge_in") {
327
+ if (currentSpoken)
328
+ currentSpoken.frozen = true;
329
+ if (state) {
330
+ clearUtteranceTimers(state);
331
+ state.frozen = true;
332
+ state.waitingForStart = false;
333
+ }
334
+ }
335
+ };
336
+ const settleOtherSpoken = (turnId) => {
337
+ const previous = currentSpoken;
338
+ if (!previous || previous.turnId === turnId)
339
+ return;
340
+ if (previous.done &&
341
+ !previous.frozen &&
342
+ previous.lastEmitted !== previous.text) {
343
+ emit(previous.turnId, previous.text);
344
+ }
345
+ currentSpoken = null;
346
+ };
347
+ /** Spoken `assistant_delta` / `assistant_done`, paired by `turnId` only. */
348
+ const handleSpokenAssistant = (type, payload, turnId) => {
349
+ let turn = spokenTurns.get(turnId);
350
+ const isNew = !turn;
351
+ if (!turn) {
352
+ turn = {
353
+ turnId,
354
+ text: "",
355
+ done: false,
356
+ frozen: false,
357
+ lastEmitted: "",
358
+ finalReported: false,
359
+ };
360
+ spokenTurns.set(turnId, turn);
361
+ while (spokenTurns.size > COMPLETED_IDS_MAX) {
362
+ const oldest = spokenTurns.keys().next().value;
363
+ if (oldest === undefined || oldest === turnId)
364
+ break;
365
+ spokenTurns.delete(oldest);
366
+ }
367
+ }
368
+ if (typeof payload.inReplyTo === "string" && payload.inReplyTo) {
369
+ turn.inReplyTo = payload.inReplyTo;
370
+ }
371
+ const chunk = typeof payload.text === "string" ? payload.text.trim() : "";
372
+ // A message for an earlier turn only settles its own line; the current reveal is untouched.
373
+ if (enabled && !isNew && currentSpoken?.turnId !== turnId) {
374
+ if (type === "assistant_delta") {
375
+ if (chunk && !turn.done) {
376
+ turn.text = turn.text ? `${turn.text} ${chunk}` : chunk;
377
+ }
378
+ return;
379
+ }
380
+ const lateStatus = typeof payload.status === "string" ? payload.status : "";
381
+ if (lateStatus === "interrupted" ||
382
+ lateStatus === "cancelled" ||
383
+ lateStatus === "failed") {
384
+ turn.frozen = true;
385
+ }
386
+ if (chunk)
387
+ turn.text = chunk;
388
+ turn.done = true;
389
+ const shown = turn.frozen ? turn.lastEmitted : turn.text;
390
+ if (shown && !(turn.finalReported && turn.lastEmitted === shown)) {
391
+ emit(turnId, shown);
392
+ }
393
+ return;
394
+ }
395
+ if (type === "assistant_delta") {
396
+ if (!chunk || turn.done)
397
+ return;
398
+ turn.text = turn.text ? `${turn.text} ${chunk}` : chunk;
399
+ if (!enabled) {
400
+ emit(turnId, turn.text);
401
+ return;
402
+ }
403
+ settleOtherSpoken(turnId);
404
+ currentSpoken = turn;
405
+ handleChatReply({
406
+ type: "chat_reply",
407
+ utteranceId: turnId,
408
+ stream: true,
409
+ partial: true,
410
+ text: turn.text,
411
+ }, true);
412
+ return;
413
+ }
414
+ const status = typeof payload.status === "string" ? payload.status : "";
415
+ const stopped = status === "interrupted" || status === "cancelled" || status === "failed";
416
+ const text = chunk || turn.text;
417
+ if (text)
418
+ turn.text = text;
419
+ turn.done = true;
420
+ if (!enabled) {
421
+ if (turn.text)
422
+ emit(turnId, turn.text);
423
+ return;
424
+ }
425
+ settleOtherSpoken(turnId);
426
+ currentSpoken = turn;
427
+ if (stopped)
428
+ turn.frozen = true;
429
+ if (turn.text) {
430
+ handleChatReply({
431
+ type: "chat_reply",
432
+ utteranceId: turnId,
433
+ stream: true,
434
+ text: turn.text,
435
+ }, true);
436
+ }
437
+ if (stopped)
438
+ handleSpeechEvent({ event: "barge_in" });
439
+ const pending = state;
440
+ if (!stopped &&
441
+ pending &&
442
+ pending.utteranceId === turnId &&
443
+ !pending.revealStarted &&
444
+ !pending.frozen) {
445
+ // Audio that never starts must not hide a completed reply forever.
446
+ clearUtteranceTimers(pending);
447
+ pending.startTimeoutId = setTimeoutFn(() => {
448
+ pending.startTimeoutId = undefined;
449
+ if (state !== pending || pending.revealStarted || pending.frozen)
450
+ return;
451
+ snapToFull(pending);
452
+ }, SPOKEN_START_FALLBACK_MS);
453
+ }
454
+ // Nothing visible changed since the last emit but the turn is now final.
455
+ if (!turn.finalReported &&
456
+ turn.lastEmitted &&
457
+ (turn.frozen || turn.lastEmitted === turn.text)) {
458
+ emit(turnId, turn.lastEmitted);
459
+ }
460
+ };
461
+ const handleControlMessage = (payload) => {
462
+ const type = typeof payload.type === "string" ? payload.type : "";
463
+ if (payload.spoken === true &&
464
+ (type === "assistant_delta" || type === "assistant_done") &&
465
+ typeof payload.turnId === "string" &&
466
+ payload.turnId) {
467
+ handleSpokenAssistant(type, payload, payload.turnId);
468
+ return;
469
+ }
470
+ if (type === "chat_reply") {
471
+ handleChatReply(payload);
472
+ return;
473
+ }
474
+ if (type === "speech_event") {
475
+ if (enabled) {
476
+ handleSpeechEvent(payload);
477
+ return;
478
+ }
479
+ }
480
+ const incoming = incomingAgentTextFromControlMessage(payload, {
481
+ ignoreSpeechEventAgentText: enabled,
482
+ });
483
+ if (incoming) {
484
+ resetUtteranceState();
485
+ emit(newUtteranceId(), incoming);
486
+ }
487
+ };
488
+ const dispose = () => {
489
+ resetUtteranceState();
490
+ spokenTurns.clear();
491
+ currentSpoken = null;
492
+ };
493
+ return {
494
+ handleControlMessage,
495
+ setEnabled: (next) => {
496
+ enabled = next;
497
+ if (!enabled) {
498
+ dispose();
499
+ }
500
+ },
501
+ dispose,
502
+ };
503
+ }
504
+ const DEFAULT_SPOKEN_TEXT_REVEAL = "playback";
505
+ /**
506
+ * Maps the agent's `assistant_delta` / `assistant_done` messages onto `onAgentText`, one call per
507
+ * visible change. Spoken turns go through {@link createSpokenChatCaption} (paced when `mode` is
508
+ * `playback`); typed turns are passed through at once. The `chat_reply` that follows a typed
509
+ * `assistant_done` carries the same text and is never reported.
510
+ */
511
+ export function createAgentTextReveal(opts) {
512
+ const playback = (opts.mode ?? DEFAULT_SPOKEN_TEXT_REVEAL) === "playback";
513
+ // A customer callback that throws must not break the control path or a timer tick.
514
+ const report = (update) => {
515
+ try {
516
+ opts.onAgentText(update);
517
+ }
518
+ catch {
519
+ /* customer callback error */
520
+ }
521
+ };
522
+ const caption = createSpokenChatCaption({
523
+ enabled: playback,
524
+ onUpsert: (turnId, text, info) => {
525
+ if (!info)
526
+ return;
527
+ report({
528
+ turnId,
529
+ text,
530
+ spoken: true,
531
+ final: info.final,
532
+ ...(info.inReplyTo !== undefined ? { inReplyTo: info.inReplyTo } : {}),
533
+ });
534
+ },
535
+ setTimeout: opts.setTimeout,
536
+ clearTimeout: opts.clearTimeout,
537
+ });
538
+ const typed = new Map();
539
+ const handleTyped = (type, payload, turnId) => {
540
+ const chunk = typeof payload.text === "string" ? payload.text.trim() : "";
541
+ const known = typed.get(turnId) ?? "";
542
+ const inReplyTo = typeof payload.inReplyTo === "string" && payload.inReplyTo
543
+ ? { inReplyTo: payload.inReplyTo }
544
+ : {};
545
+ if (type === "assistant_delta") {
546
+ if (!chunk)
547
+ return;
548
+ const text = known ? `${known} ${chunk}` : chunk;
549
+ typed.set(turnId, text);
550
+ report({
551
+ turnId,
552
+ text,
553
+ spoken: false,
554
+ final: false,
555
+ ...inReplyTo,
556
+ });
557
+ return;
558
+ }
559
+ const text = chunk || known;
560
+ typed.delete(turnId);
561
+ if (!text)
562
+ return;
563
+ report({ turnId, text, spoken: false, final: true, ...inReplyTo });
564
+ };
565
+ return {
566
+ handleControlMessage(payload) {
567
+ const type = typeof payload.type === "string" ? payload.type : "";
568
+ if (type === "speech_event") {
569
+ // Speech events pace the reveal; without playback there is nothing to pace.
570
+ if (playback)
571
+ caption.handleControlMessage(payload);
572
+ return;
573
+ }
574
+ if (type !== "assistant_delta" && type !== "assistant_done")
575
+ return;
576
+ const turnId = typeof payload.turnId === "string" ? payload.turnId : "";
577
+ if (!turnId)
578
+ return;
579
+ if (payload.spoken === true) {
580
+ caption.handleControlMessage(payload);
581
+ return;
582
+ }
583
+ handleTyped(type, payload, turnId);
584
+ },
585
+ dispose() {
586
+ caption.dispose();
587
+ typed.clear();
588
+ },
589
+ };
590
+ }
591
+ //# sourceMappingURL=spoken-text-reveal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spoken-text-reveal.js","sourceRoot":"","sources":["../src/spoken-text-reveal.ts"],"names":[],"mappings":"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"}