@talk2view/sdk 0.21.4 → 0.23.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.
- package/README.md +37 -20
- package/dist/chat/views/settings.d.ts.map +1 -1
- package/dist/chat/views/settings.js +15 -13
- package/dist/chat/views/settings.js.map +1 -1
- package/dist/chat/voice-button.d.ts.map +1 -1
- package/dist/chat/voice-button.js +46 -7
- package/dist/chat/voice-button.js.map +1 -1
- package/dist/chat-css.js +1 -1
- package/dist/chat.css +1 -1
- package/dist/chat.isolated.css +21 -1
- package/dist/chat.raw.css +21 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +11 -2
- package/dist/client.js.map +1 -1
- package/dist/constants.d.ts +10 -4
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +10 -4
- package/dist/constants.js.map +1 -1
- package/dist/errors.d.ts +25 -5
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +35 -10
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/sessions.d.ts +29 -6
- package/dist/sessions.d.ts.map +1 -1
- package/dist/sessions.js +28 -11
- package/dist/sessions.js.map +1 -1
- package/dist/types.d.ts +59 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +9 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +9 -0
- package/dist/version.js.map +1 -0
- package/dist/voice-elevenlabs.d.ts +197 -0
- package/dist/voice-elevenlabs.d.ts.map +1 -0
- package/dist/voice-elevenlabs.js +358 -0
- package/dist/voice-elevenlabs.js.map +1 -0
- package/dist/voice-facade.js +1 -1
- package/dist/voice-facade.js.map +1 -1
- package/dist/voice-fence.d.ts +37 -0
- package/dist/voice-fence.d.ts.map +1 -0
- package/dist/voice-fence.js +44 -0
- package/dist/voice-fence.js.map +1 -0
- package/dist/voice-turn.d.ts +119 -0
- package/dist/voice-turn.d.ts.map +1 -0
- package/dist/voice-turn.js +207 -0
- package/dist/voice-turn.js.map +1 -0
- package/dist/voice.d.ts +131 -8
- package/dist/voice.d.ts.map +1 -1
- package/dist/voice.js +492 -114
- package/dist/voice.js.map +1 -1
- package/docs/chat.md +13 -7
- package/docs/voice.md +157 -33
- package/package.json +4 -3
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An ElevenLabs voice call, run through the official `@elevenlabs/client`
|
|
3
|
+
* library.
|
|
4
|
+
*
|
|
5
|
+
* The engine mints the call when it picks ElevenLabs (`POST
|
|
6
|
+
* /v1/voice/sessions`): a conversation token, the conversation's id, the
|
|
7
|
+
* time limit the end-user's budget allows (never past the call cap), and the
|
|
8
|
+
* notice the agent speaks when the credit runs out. This module starts the
|
|
9
|
+
* conversation with that token, answers the agent's `ask_talk2view`
|
|
10
|
+
* requests through the voice turn runner (`voice-turn.ts`), says goodbye
|
|
11
|
+
* when the budget's time limit passes or a turn finds the budget spent, ends
|
|
12
|
+
* the call at the cap without one, and tells the engine, once, that the call
|
|
13
|
+
* has ended, so the engine settles the credit it holds for it.
|
|
14
|
+
*
|
|
15
|
+
* Keep this module and the library out of core's up-front bundle: only the
|
|
16
|
+
* voice controller loads this module, with `import()`, and only for an
|
|
17
|
+
* ElevenLabs call; this module loads the library the same way. The
|
|
18
|
+
* controller gets the voice turn runner from this module too, so a Gemini
|
|
19
|
+
* Live call loads neither.
|
|
20
|
+
*/
|
|
21
|
+
import { formatCapabilities, NONE_PLACEHOLDER, unfence } from './voice-fence.js';
|
|
22
|
+
import { VoiceTurnRunner } from './voice-turn.js';
|
|
23
|
+
/** The voice turn runner, for the controller: it loads it only with this module. */
|
|
24
|
+
export { VoiceTurnRunner };
|
|
25
|
+
/** A dynamic import: a bundler splits the library into its own chunk. */
|
|
26
|
+
export const loadElevenLabsLibs = async () => {
|
|
27
|
+
const m = await import('@elevenlabs/client');
|
|
28
|
+
return {
|
|
29
|
+
startSession: (o) => m.Conversation.startSession(o),
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* How long the goodbye waits for the agent to start speaking the notice and,
|
|
34
|
+
* once it has, for it to finish.
|
|
35
|
+
*/
|
|
36
|
+
export const GOODBYE_WAIT_MS = 10_000;
|
|
37
|
+
/** The error when the conversation that started is not the one the engine minted. */
|
|
38
|
+
export const MISMATCH_MESSAGE = 'The call did not start as expected. Try again.';
|
|
39
|
+
/**
|
|
40
|
+
* The longest an ElevenLabs call runs, in seconds, and so the cap on its time
|
|
41
|
+
* limit. Mirrors the engine's `CALL_CAP_SECONDS`
|
|
42
|
+
* (`t2v/services/elevenlabs_calls.py`). A time limit this long is the cap,
|
|
43
|
+
* not the end of the end-user's credit: the call ends there as `session_cap`,
|
|
44
|
+
* with no goodbye, as a Gemini Live call does at its cap.
|
|
45
|
+
*/
|
|
46
|
+
export const CALL_CAP_SECONDS = 900;
|
|
47
|
+
/** The answer to a request still waiting on an engine turn as the call ends. */
|
|
48
|
+
const CALL_ENDED = 'The call ended';
|
|
49
|
+
/** Run `task`, swallowing its failure, thrown or rejected: an ending must go through. */
|
|
50
|
+
async function quietly(task) {
|
|
51
|
+
try {
|
|
52
|
+
await task();
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// Swallowed, as above.
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* One ElevenLabs call, from `start()` until it ends. It ends once: by
|
|
60
|
+
* `stop()`, by the library (the agent or the connection), by the goodbye, at
|
|
61
|
+
* the call cap, or as the page goes away; and it reports that end once,
|
|
62
|
+
* through `reportEnd`. A call whose session never connected reports nothing:
|
|
63
|
+
* `start()` rejects, and the caller reports it.
|
|
64
|
+
*/
|
|
65
|
+
export class ElevenLabsCall {
|
|
66
|
+
deps;
|
|
67
|
+
/** When the time limit runs out: counted from the mint's response (`startedAt`). */
|
|
68
|
+
deadline;
|
|
69
|
+
started = false;
|
|
70
|
+
conversation = null;
|
|
71
|
+
/** The conversation is the one the engine minted. */
|
|
72
|
+
verified = false;
|
|
73
|
+
announced = false;
|
|
74
|
+
/** Transcripts that arrived before the conversation was verified, delivered once it is. */
|
|
75
|
+
early = [];
|
|
76
|
+
/** A disconnect that arrived before the conversation was verified. */
|
|
77
|
+
earlyDisconnect = null;
|
|
78
|
+
closed = false;
|
|
79
|
+
/** The session's ending, under way or done: a later `stop()` joins it. */
|
|
80
|
+
closing = Promise.resolve();
|
|
81
|
+
/** The end report, once the call has ended: settles with the engine's answer, never rejects. */
|
|
82
|
+
reporting = Promise.resolve();
|
|
83
|
+
timer = null;
|
|
84
|
+
/** The agent is speaking, as the library last said. */
|
|
85
|
+
speaking = false;
|
|
86
|
+
saidGoodbye = false;
|
|
87
|
+
/** Since the goodbye was said, the agent started speaking; then it stopped. */
|
|
88
|
+
goodbyeSpeaking = false;
|
|
89
|
+
goodbyeSpoken = false;
|
|
90
|
+
/** Wakes the goodbye's wait: on a mode change, or as the call ends. */
|
|
91
|
+
wake = null;
|
|
92
|
+
constructor(deps) {
|
|
93
|
+
this.deps = deps;
|
|
94
|
+
this.deadline = deps.startedAt + deps.info.time_limit_seconds * 1000;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Start the conversation with the mint's token. Resolves once it is
|
|
98
|
+
* connected, or has ended: a conversation other than the one minted ends
|
|
99
|
+
* the call with {@link MISMATCH_MESSAGE}. Rejects when the session can't
|
|
100
|
+
* connect; the call has then ended, and reported nothing. Runs once.
|
|
101
|
+
*/
|
|
102
|
+
async start() {
|
|
103
|
+
if (this.started || this.closed)
|
|
104
|
+
return;
|
|
105
|
+
this.started = true;
|
|
106
|
+
let conversation;
|
|
107
|
+
try {
|
|
108
|
+
conversation = await this.deps.libs.startSession(this.sessionOptions());
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
// Hung up while it connected: the hang-up reported the end.
|
|
112
|
+
if (this.closed)
|
|
113
|
+
return;
|
|
114
|
+
this.closed = true;
|
|
115
|
+
// No request can reach the runner, but it ends with the call all the same.
|
|
116
|
+
this.deps.turns.abort(CALL_ENDED);
|
|
117
|
+
throw err;
|
|
118
|
+
}
|
|
119
|
+
if (this.closed) {
|
|
120
|
+
// Hung up while it connected: the late session ends, and its microphone with it.
|
|
121
|
+
await quietly(() => conversation.endSession());
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
this.conversation = conversation;
|
|
125
|
+
// The engine holds credit for, and settles, the conversation it minted: any other is hung up.
|
|
126
|
+
if (conversation.getId() !== this.deps.info.conversation_id) {
|
|
127
|
+
this.early = [];
|
|
128
|
+
await this.close('error', true, { type: 'voice_error', message: MISMATCH_MESSAGE });
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
this.verified = true;
|
|
132
|
+
this.timer = setTimeout(() => this.timeUp(), Math.max(0, this.deadline - this.now()));
|
|
133
|
+
if (typeof window !== 'undefined')
|
|
134
|
+
window.addEventListener('pagehide', this.onPageHide);
|
|
135
|
+
this.announce();
|
|
136
|
+
const early = this.early;
|
|
137
|
+
this.early = [];
|
|
138
|
+
for (const transcript of early)
|
|
139
|
+
this.deps.onTranscript(transcript);
|
|
140
|
+
if (this.earlyDisconnect)
|
|
141
|
+
this.disconnected(this.earlyDisconnect.reason);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Hang up: the caller's own ending, so `onEnded` is not called. Resolves
|
|
145
|
+
* once the session has ended, its microphone with it. The end report has
|
|
146
|
+
* gone by then; {@link reported} settles with the engine's answer. On a
|
|
147
|
+
* call that has ended already it joins that ending, and reports nothing
|
|
148
|
+
* more.
|
|
149
|
+
*/
|
|
150
|
+
stop(reason = 'stopped') {
|
|
151
|
+
return this.close(reason, false);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Settles once the engine has answered the end report, or the report
|
|
155
|
+
* failed; never rejects. Settled already while the call has not ended, and
|
|
156
|
+
* for a call that never connected (it reports nothing).
|
|
157
|
+
*/
|
|
158
|
+
reported() {
|
|
159
|
+
return this.reporting;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Say goodbye, then end the call as `budget_exhausted`: the budget's time
|
|
163
|
+
* limit passed, or a turn found the end-user's budget spent. The agent gets
|
|
164
|
+
* the mint's notice as the answer to the request it is waiting on, or else
|
|
165
|
+
* as a message. The call ends once the agent has spoken it: after up to
|
|
166
|
+
* {@link GOODBYE_WAIT_MS} for the agent to start speaking and, once it has,
|
|
167
|
+
* as long again for it to finish. An agent already speaking as the notice
|
|
168
|
+
* goes can run straight on into it, with no fresh start: then the call
|
|
169
|
+
* waits as long again for that speech to end. Runs once; never rejects.
|
|
170
|
+
*/
|
|
171
|
+
async goodbye() {
|
|
172
|
+
if (this.saidGoodbye || this.closed || !this.verified)
|
|
173
|
+
return;
|
|
174
|
+
this.saidGoodbye = true;
|
|
175
|
+
this.clearTimer();
|
|
176
|
+
const { info, turns } = this.deps;
|
|
177
|
+
const speakingAtNotice = this.speaking;
|
|
178
|
+
try {
|
|
179
|
+
if (turns.busy)
|
|
180
|
+
turns.abort(info.budget_notice);
|
|
181
|
+
else
|
|
182
|
+
this.conversation?.sendUserMessage(info.budget_notice);
|
|
183
|
+
}
|
|
184
|
+
catch {
|
|
185
|
+
// The connection is going: the waits below end the call.
|
|
186
|
+
}
|
|
187
|
+
const wait = this.deps.goodbyeWaitMs ?? GOODBYE_WAIT_MS;
|
|
188
|
+
if (await this.waitFor(() => this.goodbyeSpeaking, wait)) {
|
|
189
|
+
await this.waitFor(() => this.goodbyeSpoken, wait);
|
|
190
|
+
}
|
|
191
|
+
else if (speakingAtNotice && this.speaking) {
|
|
192
|
+
// No fresh start: the speech under way as the notice went ran on into it.
|
|
193
|
+
await this.waitFor(() => !this.speaking, wait);
|
|
194
|
+
}
|
|
195
|
+
await this.close('budget_exhausted', true);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* The time limit ran out. A limit at the call cap is the cap, not the end
|
|
199
|
+
* of the end-user's credit: the call ends as `session_cap`, with no
|
|
200
|
+
* goodbye. Under it, the credit ran out: the goodbye.
|
|
201
|
+
*/
|
|
202
|
+
timeUp() {
|
|
203
|
+
if (this.deps.info.time_limit_seconds >= CALL_CAP_SECONDS)
|
|
204
|
+
void this.close('session_cap', true);
|
|
205
|
+
else
|
|
206
|
+
void this.goodbye();
|
|
207
|
+
}
|
|
208
|
+
/** The options `startSession` gets, as `@elevenlabs/client` 1.29.0 names them. */
|
|
209
|
+
sessionOptions() {
|
|
210
|
+
const { info, pagePrompt, turns } = this.deps;
|
|
211
|
+
return {
|
|
212
|
+
conversationToken: info.token,
|
|
213
|
+
connectionType: 'webrtc',
|
|
214
|
+
dynamicVariables: {
|
|
215
|
+
t2v_page_prompt: pagePrompt?.trim() ? unfence(pagePrompt) : NONE_PLACEHOLDER,
|
|
216
|
+
t2v_capabilities: formatCapabilities(info.capabilities),
|
|
217
|
+
t2v_greeting: info.greeting,
|
|
218
|
+
},
|
|
219
|
+
overrides: { agent: { language: info.language } },
|
|
220
|
+
clientTools: {
|
|
221
|
+
ask_talk2view: (parameters) => turns.ask(String(parameters?.request ?? '')),
|
|
222
|
+
},
|
|
223
|
+
onConnect: () => this.announce(),
|
|
224
|
+
onDisconnect: (details) => this.disconnected(details?.reason),
|
|
225
|
+
onModeChange: (change) => this.modeChanged(change?.mode),
|
|
226
|
+
onMessage: (payload) => this.message(payload),
|
|
227
|
+
onError: (message) => {
|
|
228
|
+
if (!this.verified || this.closed)
|
|
229
|
+
return;
|
|
230
|
+
this.deps.onError(typeof message === 'string' && message ? message : 'Voice connection error');
|
|
231
|
+
},
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Tell the caller the call is up, once, and only for the conversation the
|
|
236
|
+
* engine minted. The library fires `onConnect` before `startSession`
|
|
237
|
+
* resolves, so it is `start()` that announces, once the id is checked.
|
|
238
|
+
*/
|
|
239
|
+
announce() {
|
|
240
|
+
if (!this.verified || this.closed || this.announced)
|
|
241
|
+
return;
|
|
242
|
+
this.announced = true;
|
|
243
|
+
this.deps.onConnected();
|
|
244
|
+
}
|
|
245
|
+
/** A line of the transcript; `agent` is the SDK's `bot`. Held back until the conversation is verified. */
|
|
246
|
+
message(payload) {
|
|
247
|
+
if (this.closed || typeof payload?.message !== 'string')
|
|
248
|
+
return;
|
|
249
|
+
const transcript = { role: payload.role === 'agent' ? 'bot' : 'user', text: payload.message, final: true };
|
|
250
|
+
if (this.verified)
|
|
251
|
+
this.deps.onTranscript(transcript);
|
|
252
|
+
else
|
|
253
|
+
this.early.push(transcript);
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* The library's session ended: our own `endSession()` (the call has ended
|
|
257
|
+
* by then), the agent hanging up (`agent`, an `idle` ending), or the
|
|
258
|
+
* connection failing (`error`, a `disconnected` one). During the goodbye
|
|
259
|
+
* the call still ends as `budget_exhausted`.
|
|
260
|
+
*/
|
|
261
|
+
disconnected(reason) {
|
|
262
|
+
if (this.closed)
|
|
263
|
+
return;
|
|
264
|
+
if (!this.verified) {
|
|
265
|
+
this.earlyDisconnect ??= { reason };
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
const ending = this.saidGoodbye ? 'budget_exhausted' : reason === 'agent' ? 'idle' : 'disconnected';
|
|
269
|
+
void this.close(ending, true);
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* The agent started (`speaking`) or stopped (`listening`) speaking. Only
|
|
273
|
+
* the goodbye listens; it also asks whether the agent was speaking as it
|
|
274
|
+
* began.
|
|
275
|
+
*/
|
|
276
|
+
modeChanged(mode) {
|
|
277
|
+
if (mode === 'speaking')
|
|
278
|
+
this.speaking = true;
|
|
279
|
+
else if (mode === 'listening')
|
|
280
|
+
this.speaking = false;
|
|
281
|
+
if (!this.saidGoodbye)
|
|
282
|
+
return;
|
|
283
|
+
if (mode === 'speaking')
|
|
284
|
+
this.goodbyeSpeaking = true;
|
|
285
|
+
else if (mode === 'listening' && this.goodbyeSpeaking)
|
|
286
|
+
this.goodbyeSpoken = true;
|
|
287
|
+
this.wake?.();
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Resolves `true` once `done()` holds, checked now and on every wake;
|
|
291
|
+
* `false` after `ms`, or as soon as the call has ended.
|
|
292
|
+
*/
|
|
293
|
+
waitFor(done, ms) {
|
|
294
|
+
return new Promise((resolve) => {
|
|
295
|
+
let timer;
|
|
296
|
+
const finish = (value) => {
|
|
297
|
+
clearTimeout(timer);
|
|
298
|
+
this.wake = null;
|
|
299
|
+
resolve(value);
|
|
300
|
+
};
|
|
301
|
+
const check = () => {
|
|
302
|
+
if (done())
|
|
303
|
+
finish(true);
|
|
304
|
+
else if (this.closed)
|
|
305
|
+
finish(false);
|
|
306
|
+
};
|
|
307
|
+
this.wake = check;
|
|
308
|
+
timer = setTimeout(() => finish(false), ms);
|
|
309
|
+
check();
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
/** The page is going away: the end report, a keepalive request, leaves before it does. */
|
|
313
|
+
onPageHide = () => {
|
|
314
|
+
void this.close('disconnected', true);
|
|
315
|
+
};
|
|
316
|
+
/**
|
|
317
|
+
* End the call, once. Stop the time limit and the pagehide listener,
|
|
318
|
+
* answer any request still waiting on a turn, report the end, and end the
|
|
319
|
+
* session; then, when the call ended by itself (`notify`), tell the
|
|
320
|
+
* caller. The report goes first, so it is sent even as the page goes away.
|
|
321
|
+
* Resolves once the session has ended, without waiting for the engine's
|
|
322
|
+
* answer to the report ({@link reported}); never rejects.
|
|
323
|
+
*/
|
|
324
|
+
close(reason, notify, error) {
|
|
325
|
+
if (this.closed)
|
|
326
|
+
return this.closing;
|
|
327
|
+
this.closed = true;
|
|
328
|
+
this.clearTimer();
|
|
329
|
+
if (typeof window !== 'undefined')
|
|
330
|
+
window.removeEventListener('pagehide', this.onPageHide);
|
|
331
|
+
this.deps.turns.abort(CALL_ENDED);
|
|
332
|
+
this.reporting = quietly(() => this.deps.reportEnd(reason));
|
|
333
|
+
const conversation = this.conversation;
|
|
334
|
+
this.closing = conversation ? quietly(() => conversation.endSession()) : Promise.resolve();
|
|
335
|
+
this.wake?.();
|
|
336
|
+
if (notify) {
|
|
337
|
+
try {
|
|
338
|
+
if (error)
|
|
339
|
+
this.deps.onEnded(reason, error);
|
|
340
|
+
else
|
|
341
|
+
this.deps.onEnded(reason);
|
|
342
|
+
}
|
|
343
|
+
catch {
|
|
344
|
+
// The caller's failure: the call has ended all the same.
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return this.closing;
|
|
348
|
+
}
|
|
349
|
+
clearTimer() {
|
|
350
|
+
if (this.timer !== null)
|
|
351
|
+
clearTimeout(this.timer);
|
|
352
|
+
this.timer = null;
|
|
353
|
+
}
|
|
354
|
+
now() {
|
|
355
|
+
return (this.deps.now ?? Date.now)();
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
//# sourceMappingURL=voice-elevenlabs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice-elevenlabs.js","sourceRoot":"","sources":["../src/voice-elevenlabs.ts"],"names":[],"mappings":"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"}
|
package/dist/voice-facade.js
CHANGED
|
@@ -10,7 +10,7 @@ import { TypedEventEmitter } from './event-emitter.js';
|
|
|
10
10
|
import { VoiceStartError } from './voice-error.js';
|
|
11
11
|
const loadVoiceController = async () => (await import('./voice.js')).T2VVoiceController;
|
|
12
12
|
/** Every event the controller emits; the facade forwards each one. */
|
|
13
|
-
const FORWARDED = ['transcript', 'toolCall', 'agentState', 'approvalChange', 'error', 'ended'];
|
|
13
|
+
const FORWARDED = ['transcript', 'toolCall', 'agentState', 'approvalChange', 'error', 'ended', 'note', 'callStarted'];
|
|
14
14
|
export class T2VVoice {
|
|
15
15
|
options;
|
|
16
16
|
emitter = new TypedEventEmitter();
|
package/dist/voice-facade.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voice-facade.js","sourceRoot":"","sources":["../src/voice-facade.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAGvD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAWnD,MAAM,mBAAmB,GAA0B,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,kBAAkB,CAAC;AAE/G,sEAAsE;AACtE,MAAM,SAAS,GAAG,CAAC,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,OAAO,EAAE,OAAO,CAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"voice-facade.js","sourceRoot":"","sources":["../src/voice-facade.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The fence guard for an ElevenLabs call's instructions.
|
|
3
|
+
*
|
|
4
|
+
* The engine puts the partner prompt, the page prompt and the app's
|
|
5
|
+
* capabilities between two delimiters in the agent's instructions. An
|
|
6
|
+
* ElevenLabs call's page prompt and capabilities reach the agent as dynamic
|
|
7
|
+
* variables inside that fence, so the SDK guards them as the engine does:
|
|
8
|
+
* nothing from the page or a tool can close the fence early. Each function
|
|
9
|
+
* gives the engine's text for the same input (`t2v/core/voice_rules.py`), so
|
|
10
|
+
* the instructions read the same whichever voice model takes the call, with
|
|
11
|
+
* one difference: `formatCapabilities([])` gives `(none)` where the engine's
|
|
12
|
+
* `format_capabilities` gives `""`, because the dynamic variable needs a
|
|
13
|
+
* value and the agent's placeholder is `(none)`.
|
|
14
|
+
*/
|
|
15
|
+
import type { VoiceCapability } from './types.js';
|
|
16
|
+
/** The delimiter that opens the fence. */
|
|
17
|
+
export declare const PARTNER_PROMPT_BEGIN = "<<<BEGIN APP DESCRIPTION>>>";
|
|
18
|
+
/** The delimiter that closes the fence. */
|
|
19
|
+
export declare const PARTNER_PROMPT_END = "<<<END APP DESCRIPTION>>>";
|
|
20
|
+
/** What a delimiter inside the fenced text is replaced with. */
|
|
21
|
+
export declare const DELIMITER_REMOVED = "[delimiter removed]";
|
|
22
|
+
/** What an empty page prompt or capability list reads as: a dynamic variable needs a value. */
|
|
23
|
+
export declare const NONE_PLACEHOLDER = "(none)";
|
|
24
|
+
/**
|
|
25
|
+
* `text` with each delimiter replaced by {@link DELIMITER_REMOVED}: every
|
|
26
|
+
* occurrence, left to right, as the engine's `str.replace` does. Replaced,
|
|
27
|
+
* never deleted: deleting lets nested fragments such as
|
|
28
|
+
* `<<<END APP<<<END APP DESCRIPTION>>> DESCRIPTION>>>` rejoin into a real fence.
|
|
29
|
+
*/
|
|
30
|
+
export declare function unfence(text: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* The app's capabilities as `- name: description` lines (`- name` when the
|
|
33
|
+
* description is empty), every name and description unfenced; or
|
|
34
|
+
* {@link NONE_PLACEHOLDER} when there are none.
|
|
35
|
+
*/
|
|
36
|
+
export declare function formatCapabilities(capabilities: VoiceCapability[]): string;
|
|
37
|
+
//# sourceMappingURL=voice-fence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice-fence.d.ts","sourceRoot":"","sources":["../src/voice-fence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,0CAA0C;AAC1C,eAAO,MAAM,oBAAoB,gCAAgC,CAAC;AAClE,2CAA2C;AAC3C,eAAO,MAAM,kBAAkB,8BAA8B,CAAC;AAC9D,gEAAgE;AAChE,eAAO,MAAM,iBAAiB,wBAAwB,CAAC;AACvD,+FAA+F;AAC/F,eAAO,MAAM,gBAAgB,WAAW,CAAC;AAEzC;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,eAAe,EAAE,GAAG,MAAM,CAO1E"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The fence guard for an ElevenLabs call's instructions.
|
|
3
|
+
*
|
|
4
|
+
* The engine puts the partner prompt, the page prompt and the app's
|
|
5
|
+
* capabilities between two delimiters in the agent's instructions. An
|
|
6
|
+
* ElevenLabs call's page prompt and capabilities reach the agent as dynamic
|
|
7
|
+
* variables inside that fence, so the SDK guards them as the engine does:
|
|
8
|
+
* nothing from the page or a tool can close the fence early. Each function
|
|
9
|
+
* gives the engine's text for the same input (`t2v/core/voice_rules.py`), so
|
|
10
|
+
* the instructions read the same whichever voice model takes the call, with
|
|
11
|
+
* one difference: `formatCapabilities([])` gives `(none)` where the engine's
|
|
12
|
+
* `format_capabilities` gives `""`, because the dynamic variable needs a
|
|
13
|
+
* value and the agent's placeholder is `(none)`.
|
|
14
|
+
*/
|
|
15
|
+
/** The delimiter that opens the fence. */
|
|
16
|
+
export const PARTNER_PROMPT_BEGIN = '<<<BEGIN APP DESCRIPTION>>>';
|
|
17
|
+
/** The delimiter that closes the fence. */
|
|
18
|
+
export const PARTNER_PROMPT_END = '<<<END APP DESCRIPTION>>>';
|
|
19
|
+
/** What a delimiter inside the fenced text is replaced with. */
|
|
20
|
+
export const DELIMITER_REMOVED = '[delimiter removed]';
|
|
21
|
+
/** What an empty page prompt or capability list reads as: a dynamic variable needs a value. */
|
|
22
|
+
export const NONE_PLACEHOLDER = '(none)';
|
|
23
|
+
/**
|
|
24
|
+
* `text` with each delimiter replaced by {@link DELIMITER_REMOVED}: every
|
|
25
|
+
* occurrence, left to right, as the engine's `str.replace` does. Replaced,
|
|
26
|
+
* never deleted: deleting lets nested fragments such as
|
|
27
|
+
* `<<<END APP<<<END APP DESCRIPTION>>> DESCRIPTION>>>` rejoin into a real fence.
|
|
28
|
+
*/
|
|
29
|
+
export function unfence(text) {
|
|
30
|
+
return text.split(PARTNER_PROMPT_BEGIN).join(DELIMITER_REMOVED).split(PARTNER_PROMPT_END).join(DELIMITER_REMOVED);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The app's capabilities as `- name: description` lines (`- name` when the
|
|
34
|
+
* description is empty), every name and description unfenced; or
|
|
35
|
+
* {@link NONE_PLACEHOLDER} when there are none.
|
|
36
|
+
*/
|
|
37
|
+
export function formatCapabilities(capabilities) {
|
|
38
|
+
if (capabilities.length === 0)
|
|
39
|
+
return NONE_PLACEHOLDER;
|
|
40
|
+
return capabilities
|
|
41
|
+
.map(({ name, description }) => description ? `- ${unfence(name)}: ${unfence(description)}` : `- ${unfence(name)}`)
|
|
42
|
+
.join('\n');
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=voice-fence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice-fence.js","sourceRoot":"","sources":["../src/voice-fence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,0CAA0C;AAC1C,MAAM,CAAC,MAAM,oBAAoB,GAAG,6BAA6B,CAAC;AAClE,2CAA2C;AAC3C,MAAM,CAAC,MAAM,kBAAkB,GAAG,2BAA2B,CAAC;AAC9D,gEAAgE;AAChE,MAAM,CAAC,MAAM,iBAAiB,GAAG,qBAAqB,CAAC;AACvD,+FAA+F;AAC/F,MAAM,CAAC,MAAM,gBAAgB,GAAG,QAAQ,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;AACpH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,YAA+B;IAChE,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,gBAAgB,CAAC;IACvD,OAAO,YAAY;SAChB,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,CAC7B,WAAW,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE,CACnF;SACA,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The voice turn runner: each `ask_talk2view` request of an ElevenLabs voice
|
|
3
|
+
* call becomes an engine turn on the end-user's chat session, one at a time,
|
|
4
|
+
* as the voice service's handoff does for Gemini Live (`va/handoff.py`).
|
|
5
|
+
*
|
|
6
|
+
* An identical request already in flight or queued is merged
|
|
7
|
+
* ({@link ALREADY_WORKING}); a different one waits its turn. Every `ask()`
|
|
8
|
+
* resolves with plain text for the agent to speak.
|
|
9
|
+
*
|
|
10
|
+
* Keep this module out of core's up-front bundle: only the voice controller,
|
|
11
|
+
* which core loads with `import()`, may import it.
|
|
12
|
+
*/
|
|
13
|
+
import type { T2VSession, TurnOptions } from './sessions.js';
|
|
14
|
+
import type { HumanDecision } from './types.js';
|
|
15
|
+
/** The answer to a request identical to one already in flight or queued. */
|
|
16
|
+
export declare const ALREADY_WORKING = "status: already_working (still on the previous request)";
|
|
17
|
+
/** The answer when a turn ends without any text. */
|
|
18
|
+
export declare const NO_TEXT = "(the agent returned no text)";
|
|
19
|
+
/** The answer when a turn could not be run, or ran past its limit. */
|
|
20
|
+
export declare const TURN_FAILED = "error: I couldn\u2019t reach the assistant just now.";
|
|
21
|
+
/**
|
|
22
|
+
* How long a turn may run, its resumes and any wait on a card included,
|
|
23
|
+
* before it is ended with {@link TURN_FAILED}. It is the voice service's
|
|
24
|
+
* `engine_turn_timeout_s` (`va/engine_bridge.py`), and the agent's
|
|
25
|
+
* `ask_talk2view` tool stops waiting for an answer at the same 120 seconds
|
|
26
|
+
* (`response_timeout_secs`).
|
|
27
|
+
*/
|
|
28
|
+
export declare const TURN_TIMEOUT_MS = 120000;
|
|
29
|
+
/**
|
|
30
|
+
* What the engine is told about a voice turn: the reply is spoken, and the
|
|
31
|
+
* call collects no approvals and shows no platform-tool activity.
|
|
32
|
+
*/
|
|
33
|
+
export declare const VOICE_TURN: TurnOptions;
|
|
34
|
+
/**
|
|
35
|
+
* What makes two requests the same: lower-cased, whitespace collapsed to
|
|
36
|
+
* single spaces, and trailing `?`, `.`, `!` and spaces dropped, as the voice
|
|
37
|
+
* service's `normalise_request` (`va/handoff.py`).
|
|
38
|
+
*/
|
|
39
|
+
export declare function normaliseRequest(text: string): string;
|
|
40
|
+
export interface VoiceTurnDeps {
|
|
41
|
+
/** The end-user's chat session the mint names: every turn runs on it. */
|
|
42
|
+
session: T2VSession;
|
|
43
|
+
/** The page prompt, sent as each turn's system message. */
|
|
44
|
+
pagePrompt?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Shows the card for a client tool call that needs the end-user's go-ahead,
|
|
47
|
+
* and resolves with their decision, or with `endedBecause` when the card
|
|
48
|
+
* closed unanswered. The caller remembers an `always`.
|
|
49
|
+
*/
|
|
50
|
+
onApproval: (toolCallId: string, toolName: string, args: Record<string, unknown>) => Promise<{
|
|
51
|
+
decision: HumanDecision;
|
|
52
|
+
endedBecause?: string;
|
|
53
|
+
}>;
|
|
54
|
+
/** Whether the end-user has said `always` to this tool: it runs without a card. */
|
|
55
|
+
isAlwaysAllowed: (toolName: string) => boolean;
|
|
56
|
+
/** `working` as a turn starts, `idle` once it settles. */
|
|
57
|
+
onState: (state: 'working' | 'idle') => void;
|
|
58
|
+
/** A turn found the end-user's budget spent: the call says goodbye. */
|
|
59
|
+
onBudgetExceeded: () => void;
|
|
60
|
+
/** How long a turn may run before it is ended. Default: {@link TURN_TIMEOUT_MS}. */
|
|
61
|
+
turnTimeoutMs?: number;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Runs a voice call's requests as engine turns, one at a time. `abort()`
|
|
65
|
+
* answers every pending `ask()` at once, as the call ends.
|
|
66
|
+
*/
|
|
67
|
+
export declare class VoiceTurnRunner {
|
|
68
|
+
private readonly deps;
|
|
69
|
+
/** Normalised requests in flight or queued. */
|
|
70
|
+
private readonly inFlight;
|
|
71
|
+
/** The last turn queued: the next one starts when it settles. */
|
|
72
|
+
private last;
|
|
73
|
+
/** The controller of the turn in flight. */
|
|
74
|
+
private controller;
|
|
75
|
+
/** Set by {@link abort}: from then on every `ask()` resolves with it. */
|
|
76
|
+
private reason;
|
|
77
|
+
/** Resolves with the reason on {@link abort}; every `ask()` races it. */
|
|
78
|
+
private readonly aborted;
|
|
79
|
+
private resolveAborted;
|
|
80
|
+
constructor(deps: VoiceTurnDeps);
|
|
81
|
+
/** A turn is in flight or queued. */
|
|
82
|
+
get busy(): boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Run `request` as an engine turn. Resolves with the turn's text, trimmed,
|
|
85
|
+
* or {@link NO_TEXT}; `error: <message>` when the engine reports an error;
|
|
86
|
+
* {@link TURN_FAILED} when the turn could not be run or ran past its limit;
|
|
87
|
+
* {@link ALREADY_WORKING} when the same request is already in flight or
|
|
88
|
+
* queued; once aborted, the abort reason.
|
|
89
|
+
*/
|
|
90
|
+
ask(request: string): Promise<string>;
|
|
91
|
+
/**
|
|
92
|
+
* End the runner for good: abort the turn in flight, resolve its `ask()`
|
|
93
|
+
* and every queued one with `reason`, and resolve later ones with it at once.
|
|
94
|
+
*/
|
|
95
|
+
abort(reason: string): void;
|
|
96
|
+
/**
|
|
97
|
+
* One turn, unless the runner was aborted while it waited. A turn still
|
|
98
|
+
* running at its limit is aborted and answers {@link TURN_FAILED}, whether
|
|
99
|
+
* or not its stream has noticed, and the runner moves on: the request
|
|
100
|
+
* leaves the in-flight set and the next turn starts.
|
|
101
|
+
*/
|
|
102
|
+
private run;
|
|
103
|
+
/**
|
|
104
|
+
* Tell the caller the runner's state. A throw from `onState` is swallowed,
|
|
105
|
+
* and nothing is logged: it must not lose the turn's answer, nor stop the
|
|
106
|
+
* turns queued behind it.
|
|
107
|
+
*/
|
|
108
|
+
private reportState;
|
|
109
|
+
/** The turn's answer, from its stream and the stream of each resume. */
|
|
110
|
+
private turn;
|
|
111
|
+
/**
|
|
112
|
+
* The resume of a client tool call that needs the end-user's go-ahead. A
|
|
113
|
+
* tool they always allow runs at once. Otherwise the card decides: the
|
|
114
|
+
* resume carries their decision, or the reason the card closed without one.
|
|
115
|
+
* Nothing runs until the resume is read.
|
|
116
|
+
*/
|
|
117
|
+
private resume;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=voice-turn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice-turn.d.ts","sourceRoot":"","sources":["../src/voice-turn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,KAAK,EAAa,aAAa,EAAmB,MAAM,YAAY,CAAC;AAE5E,4EAA4E;AAC5E,eAAO,MAAM,eAAe,4DAA4D,CAAC;AAEzF,oDAAoD;AACpD,eAAO,MAAM,OAAO,iCAAiC,CAAC;AAEtD,sEAAsE;AACtE,eAAO,MAAM,WAAW,yDAAoD,CAAC;AAE7E;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,SAAU,CAAC;AAEvC;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,WAAsF,CAAC;AAEhH;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKrD;AAED,MAAM,WAAW,aAAa;IAC5B,yEAAyE;IACzE,OAAO,EAAE,UAAU,CAAC;IACpB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,UAAU,EAAE,CACV,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC1B,OAAO,CAAC;QAAE,QAAQ,EAAE,aAAa,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,mFAAmF;IACnF,eAAe,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IAC/C,0DAA0D;IAC1D,OAAO,EAAE,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,KAAK,IAAI,CAAC;IAC7C,uEAAuE;IACvE,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,oFAAoF;IACpF,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,qBAAa,eAAe;IAad,OAAO,CAAC,QAAQ,CAAC,IAAI;IAZjC,+CAA+C;IAC/C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,iEAAiE;IACjE,OAAO,CAAC,IAAI,CAAuC;IACnD,4CAA4C;IAC5C,OAAO,CAAC,UAAU,CAAgC;IAClD,yEAAyE;IACzE,OAAO,CAAC,MAAM,CAAuB;IACrC,yEAAyE;IACzE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;IAC1C,OAAO,CAAC,cAAc,CAA4B;gBAErB,IAAI,EAAE,aAAa;IAMhD,qCAAqC;IACrC,IAAI,IAAI,IAAI,OAAO,CAElB;IAED;;;;;;OAMG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAcrC;;;OAGG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQ3B;;;;;OAKG;YACW,GAAG;IAwBjB;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAQnB,wEAAwE;YAC1D,IAAI;IAgClB;;;;;OAKG;YACW,MAAM;CAerB"}
|