@kognitivedev/cloud-voice 0.2.29
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/.turbo/turbo-build.log +2 -0
- package/.turbo/turbo-test.log +13 -0
- package/CHANGELOG.md +10 -0
- package/README.md +226 -0
- package/dist/browser.d.ts +7 -0
- package/dist/browser.js +301 -0
- package/dist/client.d.ts +219 -0
- package/dist/client.js +535 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +15 -0
- package/dist/server.d.ts +58 -0
- package/dist/server.js +92 -0
- package/dist/server.test.d.ts +1 -0
- package/dist/server.test.js +78 -0
- package/dist/sse.d.ts +7 -0
- package/dist/sse.js +75 -0
- package/dist/types.d.ts +865 -0
- package/dist/types.js +2 -0
- package/package.json +52 -0
- package/src/__tests__/browser.test.ts +196 -0
- package/src/__tests__/client.test.ts +482 -0
- package/src/__tests__/server.test.ts +84 -0
- package/src/browser.ts +342 -0
- package/src/client.ts +610 -0
- package/src/index.ts +100 -0
- package/src/server.ts +140 -0
- package/src/sse.ts +57 -0
- package/src/types.ts +927 -0
- package/tsconfig.json +14 -0
- package/vitest.config.ts +8 -0
package/dist/client.js
ADDED
|
@@ -0,0 +1,535 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
3
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
4
|
+
var m = o[Symbol.asyncIterator], i;
|
|
5
|
+
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
6
|
+
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
7
|
+
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
8
|
+
};
|
|
9
|
+
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
|
10
|
+
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
|
11
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
12
|
+
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
13
|
+
return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
|
|
14
|
+
function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
|
|
15
|
+
function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
|
|
16
|
+
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
|
|
17
|
+
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
|
18
|
+
function fulfill(value) { resume("next", value); }
|
|
19
|
+
function reject(value) { resume("throw", value); }
|
|
20
|
+
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.KognitiveCloudVoiceEmbedClient = exports.KognitiveCloudVoiceClient = void 0;
|
|
24
|
+
const client_core_1 = require("@kognitivedev/client-core");
|
|
25
|
+
const sse_1 = require("./sse");
|
|
26
|
+
function isTransportLike(value) {
|
|
27
|
+
return Boolean(value && typeof value === "object" && "baseUrl" in value && "json" in value && "raw" in value);
|
|
28
|
+
}
|
|
29
|
+
function assertString(value, name) {
|
|
30
|
+
if (!value || !value.trim())
|
|
31
|
+
throw new Error(`${name} is required`);
|
|
32
|
+
return value.trim();
|
|
33
|
+
}
|
|
34
|
+
function isNotFoundError(error) {
|
|
35
|
+
return error instanceof client_core_1.KognitiveApiError && error.status === 404
|
|
36
|
+
|| Boolean(error && typeof error === "object" && "status" in error && error.status === 404);
|
|
37
|
+
}
|
|
38
|
+
const TERMINAL_CALL_STATUSES = new Set(["completed", "cancelled", "canceled", "failed", "busy", "no-answer", "error"]);
|
|
39
|
+
const TERMINAL_SESSION_STATUSES = new Set(["completed", "cancelled", "canceled", "error"]);
|
|
40
|
+
function sleep(ms) {
|
|
41
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
42
|
+
}
|
|
43
|
+
function isTerminalCall(call) {
|
|
44
|
+
return Boolean(call.endedAt)
|
|
45
|
+
|| TERMINAL_CALL_STATUSES.has(call.status)
|
|
46
|
+
|| Boolean(call.sessionStatus && TERMINAL_SESSION_STATUSES.has(call.sessionStatus));
|
|
47
|
+
}
|
|
48
|
+
function callStatusFingerprint(call) {
|
|
49
|
+
var _a, _b, _c;
|
|
50
|
+
return [
|
|
51
|
+
call.status,
|
|
52
|
+
(_a = call.sessionStatus) !== null && _a !== void 0 ? _a : "",
|
|
53
|
+
call.stateLabel,
|
|
54
|
+
(_b = call.latestEventType) !== null && _b !== void 0 ? _b : "",
|
|
55
|
+
(_c = call.outcomeStatus) !== null && _c !== void 0 ? _c : "",
|
|
56
|
+
].join("|");
|
|
57
|
+
}
|
|
58
|
+
function toCallStatusChange(call, previousStatus) {
|
|
59
|
+
return {
|
|
60
|
+
call,
|
|
61
|
+
status: call.status,
|
|
62
|
+
previousStatus,
|
|
63
|
+
sessionStatus: call.sessionStatus,
|
|
64
|
+
stateLabel: call.stateLabel,
|
|
65
|
+
latestEventType: call.latestEventType,
|
|
66
|
+
outcomeStatus: call.outcomeStatus,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
class KognitiveCloudVoiceClient {
|
|
70
|
+
constructor(config) {
|
|
71
|
+
this.agents = {
|
|
72
|
+
list: () => this.listAgents(),
|
|
73
|
+
get: (slug) => this.getAgent(slug),
|
|
74
|
+
use: (slug, input = {}) => this.useAgent(slug, input),
|
|
75
|
+
management: {
|
|
76
|
+
list: () => this.listAgents(),
|
|
77
|
+
create: (input) => this.createAgent(input),
|
|
78
|
+
createOrUse: (slug, input = {}) => this.useAgent(slug, input),
|
|
79
|
+
get: (slug) => this.getAgent(slug),
|
|
80
|
+
update: (slug, input) => this.updateAgent(slug, input),
|
|
81
|
+
delete: (slug) => this.deleteAgent(slug),
|
|
82
|
+
publish: (slug) => this.publishAgent(slug),
|
|
83
|
+
unpublish: (slug) => this.unpublishAgent(slug),
|
|
84
|
+
use: (slug, input = {}) => this.useAgent(slug, input),
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
this.sessions = {
|
|
88
|
+
list: (agentId) => this.listSessions(agentId),
|
|
89
|
+
create: (agentSlug, input = {}) => this.createSession(Object.assign(Object.assign({}, input), { agentSlug })),
|
|
90
|
+
get: (sessionId) => this.getSession(sessionId),
|
|
91
|
+
cancel: (sessionId, reason) => this.cancelSession(sessionId, reason),
|
|
92
|
+
events: (sessionId) => this.getSessionEvents(sessionId),
|
|
93
|
+
appendEvent: (sessionId, event) => this.appendSessionEvent(sessionId, event),
|
|
94
|
+
stream: (sessionId, init) => this.streamSessionEvents(sessionId, init),
|
|
95
|
+
subscribe: (sessionId, init) => this.subscribeToSession(sessionId, init),
|
|
96
|
+
executeTool: (sessionId, toolId, input) => this.executeTool(sessionId, toolId, input),
|
|
97
|
+
recordings: (sessionId) => this.getSessionRecordings(sessionId),
|
|
98
|
+
};
|
|
99
|
+
this.calls = {
|
|
100
|
+
list: () => this.listCalls(),
|
|
101
|
+
live: (input = {}) => this.listLiveCalls(input),
|
|
102
|
+
get: (sessionId) => this.getCall(sessionId),
|
|
103
|
+
create: (input) => this.createCall(input),
|
|
104
|
+
wait: (sessionId, options) => this.waitForCall(sessionId, options),
|
|
105
|
+
hangup: (sessionId, reason) => this.hangupCall(sessionId, reason),
|
|
106
|
+
listenToken: (sessionId, input = {}) => this.createCallListenToken(sessionId, input),
|
|
107
|
+
handoff: {
|
|
108
|
+
create: (sessionId, input = {}) => this.createCallHandoff(sessionId, input),
|
|
109
|
+
accept: (sessionId, handoffId, input = {}) => this.acceptCallHandoff(sessionId, handoffId, input),
|
|
110
|
+
cancel: (sessionId, handoffId, input = {}) => this.cancelCallHandoff(sessionId, handoffId, input),
|
|
111
|
+
},
|
|
112
|
+
events: (sessionId) => this.getSessionEvents(sessionId),
|
|
113
|
+
stream: (sessionId, init) => this.streamSessionEvents(sessionId, init),
|
|
114
|
+
subscribe: (sessionId, init) => this.subscribeToSession(sessionId, init),
|
|
115
|
+
executeTool: (sessionId, toolId, input) => this.executeCallTool(sessionId, toolId, input),
|
|
116
|
+
};
|
|
117
|
+
this.phone = {
|
|
118
|
+
connections: {
|
|
119
|
+
list: () => this.listPhoneConnections(),
|
|
120
|
+
create: (input) => this.createPhoneConnection(input),
|
|
121
|
+
},
|
|
122
|
+
numbers: {
|
|
123
|
+
list: () => this.listPhoneNumbers(),
|
|
124
|
+
create: (input) => this.createPhoneNumber(input),
|
|
125
|
+
update: (input) => this.updatePhoneNumber(input),
|
|
126
|
+
},
|
|
127
|
+
bridge: {
|
|
128
|
+
health: () => this.getPhoneBridgeHealth(),
|
|
129
|
+
},
|
|
130
|
+
sip: {
|
|
131
|
+
diagnostics: () => this.getSipDiagnostics(),
|
|
132
|
+
reload: () => this.reloadSipBridge(),
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
this.recordings = {
|
|
136
|
+
getForSession: (sessionId) => this.getSessionRecordings(sessionId),
|
|
137
|
+
};
|
|
138
|
+
this.tools = {
|
|
139
|
+
catalog: {
|
|
140
|
+
list: () => this.listToolCatalog(),
|
|
141
|
+
sync: (input) => this.syncToolCatalog(input),
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
this.customVoices = {
|
|
145
|
+
list: () => this.listCustomVoices(),
|
|
146
|
+
import: (input) => this.importCustomVoice(input),
|
|
147
|
+
clone: (input) => this.cloneCustomVoice(input),
|
|
148
|
+
update: (voiceId, input) => this.updateCustomVoice(voiceId, input),
|
|
149
|
+
delete: (voiceId) => this.deleteCustomVoice(voiceId),
|
|
150
|
+
};
|
|
151
|
+
this.transport = isTransportLike(config) ? config : new client_core_1.HttpTransport(config);
|
|
152
|
+
}
|
|
153
|
+
async listAgents() {
|
|
154
|
+
const res = await this.transport.json("/api/cloud/voice/agents");
|
|
155
|
+
return res.agents;
|
|
156
|
+
}
|
|
157
|
+
async getAgent(slug) {
|
|
158
|
+
return this.transport.json(`/api/cloud/voice/agents/${encodeURIComponent(assertString(slug, "slug"))}`);
|
|
159
|
+
}
|
|
160
|
+
async createAgent(input) {
|
|
161
|
+
return this.transport.json("/api/cloud/voice/agents", {
|
|
162
|
+
method: "POST",
|
|
163
|
+
body: JSON.stringify(input),
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
async listCustomVoices() {
|
|
167
|
+
const res = await this.transport.json("/api/cloud/voice/custom-voices");
|
|
168
|
+
return res.voices;
|
|
169
|
+
}
|
|
170
|
+
async importCustomVoice(input) {
|
|
171
|
+
return this.transport.json("/api/cloud/voice/custom-voices/import", {
|
|
172
|
+
method: "POST",
|
|
173
|
+
body: JSON.stringify(input),
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
async cloneCustomVoice(input) {
|
|
177
|
+
var _a;
|
|
178
|
+
const form = new FormData();
|
|
179
|
+
form.append("file", input.file, (_a = input.fileName) !== null && _a !== void 0 ? _a : "reference.wav");
|
|
180
|
+
const fields = {
|
|
181
|
+
name: input.name,
|
|
182
|
+
description: input.description,
|
|
183
|
+
gender: input.gender,
|
|
184
|
+
accent: input.accent,
|
|
185
|
+
age: input.age,
|
|
186
|
+
language: input.language,
|
|
187
|
+
use_case: input.useCase,
|
|
188
|
+
tone: input.tone,
|
|
189
|
+
};
|
|
190
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
191
|
+
if (typeof value === "string" && value.trim())
|
|
192
|
+
form.append(key, value.trim());
|
|
193
|
+
}
|
|
194
|
+
form.append("consent", JSON.stringify(input.consent));
|
|
195
|
+
return this.transport.multipart("/api/cloud/voice/custom-voices/clone", form, {
|
|
196
|
+
method: "POST",
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
async updateCustomVoice(voiceId, input) {
|
|
200
|
+
return this.transport.json(`/api/cloud/voice/custom-voices/${encodeURIComponent(assertString(voiceId, "voiceId"))}`, {
|
|
201
|
+
method: "PATCH",
|
|
202
|
+
body: JSON.stringify(Object.assign(Object.assign({}, input), (input.useCase !== undefined ? { use_case: input.useCase } : {}))),
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
async deleteCustomVoice(voiceId) {
|
|
206
|
+
return this.transport.json(`/api/cloud/voice/custom-voices/${encodeURIComponent(assertString(voiceId, "voiceId"))}`, {
|
|
207
|
+
method: "DELETE",
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
async updateAgent(slug, input) {
|
|
211
|
+
return this.transport.json(`/api/cloud/voice/agents/${encodeURIComponent(assertString(slug, "slug"))}`, {
|
|
212
|
+
method: "PUT",
|
|
213
|
+
body: JSON.stringify(input),
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
async useAgent(slug, input = {}) {
|
|
217
|
+
var _a;
|
|
218
|
+
const normalizedSlug = assertString(slug, "slug");
|
|
219
|
+
let existing = null;
|
|
220
|
+
try {
|
|
221
|
+
existing = await this.getAgent(normalizedSlug);
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
if (!isNotFoundError(error))
|
|
225
|
+
throw error;
|
|
226
|
+
}
|
|
227
|
+
const hasUpdates = input.name !== undefined
|
|
228
|
+
|| input.description !== undefined
|
|
229
|
+
|| input.status !== undefined
|
|
230
|
+
|| input.config !== undefined;
|
|
231
|
+
let action = existing ? "used" : "created";
|
|
232
|
+
let agent = existing;
|
|
233
|
+
if (existing && hasUpdates) {
|
|
234
|
+
agent = await this.updateAgent(normalizedSlug, Object.assign(Object.assign(Object.assign(Object.assign({}, (input.name !== undefined ? { name: input.name } : {})), (input.description !== undefined ? { description: input.description } : {})), (input.status !== undefined ? { status: input.status } : {})), (input.config !== undefined ? { config: input.config } : {})));
|
|
235
|
+
action = "updated";
|
|
236
|
+
}
|
|
237
|
+
else if (!existing) {
|
|
238
|
+
agent = await this.createAgent({
|
|
239
|
+
name: (_a = input.name) !== null && _a !== void 0 ? _a : normalizedSlug,
|
|
240
|
+
slug: normalizedSlug,
|
|
241
|
+
description: input.description,
|
|
242
|
+
config: input.config,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
if (!agent) {
|
|
246
|
+
throw new Error(`Cloud voice agent "${normalizedSlug}" could not be created or resolved`);
|
|
247
|
+
}
|
|
248
|
+
if (input.publish) {
|
|
249
|
+
agent = await this.publishAgent(agent.slug);
|
|
250
|
+
}
|
|
251
|
+
return { action, agent };
|
|
252
|
+
}
|
|
253
|
+
async deleteAgent(slug) {
|
|
254
|
+
return this.transport.json(`/api/cloud/voice/agents/${encodeURIComponent(assertString(slug, "slug"))}`, {
|
|
255
|
+
method: "DELETE",
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
async publishAgent(slug) {
|
|
259
|
+
return this.transport.json(`/api/cloud/voice/agents/${encodeURIComponent(assertString(slug, "slug"))}/publish`, {
|
|
260
|
+
method: "POST",
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
async unpublishAgent(slug) {
|
|
264
|
+
return this.transport.json(`/api/cloud/voice/agents/${encodeURIComponent(assertString(slug, "slug"))}/unpublish`, {
|
|
265
|
+
method: "POST",
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
async listSessions(agentId) {
|
|
269
|
+
const path = agentId ? `/api/cloud/voice/sessions?agentId=${encodeURIComponent(agentId)}` : "/api/cloud/voice/sessions";
|
|
270
|
+
const res = await this.transport.json(path);
|
|
271
|
+
return res.sessions;
|
|
272
|
+
}
|
|
273
|
+
async createSession(input) {
|
|
274
|
+
return this.transport.json("/api/cloud/voice/sessions", {
|
|
275
|
+
method: "POST",
|
|
276
|
+
body: JSON.stringify(input),
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
async getSession(sessionId) {
|
|
280
|
+
return this.transport.json(`/api/cloud/voice/sessions/${encodeURIComponent(assertString(sessionId, "sessionId"))}`);
|
|
281
|
+
}
|
|
282
|
+
async cancelSession(sessionId, reason) {
|
|
283
|
+
return this.transport.json(`/api/cloud/voice/sessions/${encodeURIComponent(assertString(sessionId, "sessionId"))}/cancel`, {
|
|
284
|
+
method: "POST",
|
|
285
|
+
body: JSON.stringify({ reason }),
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
async getSessionEvents(sessionId) {
|
|
289
|
+
const res = await this.transport.json(`/api/cloud/voice/sessions/${encodeURIComponent(assertString(sessionId, "sessionId"))}/events`);
|
|
290
|
+
return res.events;
|
|
291
|
+
}
|
|
292
|
+
async appendSessionEvent(sessionId, event) {
|
|
293
|
+
return this.transport.json(`/api/cloud/voice/sessions/${encodeURIComponent(assertString(sessionId, "sessionId"))}/events`, {
|
|
294
|
+
method: "POST",
|
|
295
|
+
body: JSON.stringify(event),
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
async streamSessionEvents(sessionId, init) {
|
|
299
|
+
return this.transport.raw(`/api/cloud/voice/sessions/${encodeURIComponent(assertString(sessionId, "sessionId"))}/events/stream`, init);
|
|
300
|
+
}
|
|
301
|
+
async subscribeToSession(sessionId, init) {
|
|
302
|
+
const response = await this.streamSessionEvents(sessionId, init);
|
|
303
|
+
if (!response.body)
|
|
304
|
+
throw new Error("Cloud voice event stream response did not include a body");
|
|
305
|
+
const events = (0, sse_1.readSSEStream)(response.body);
|
|
306
|
+
function decode() {
|
|
307
|
+
return __asyncGenerator(this, arguments, function* decode_1() {
|
|
308
|
+
var _a, e_1, _b, _c;
|
|
309
|
+
try {
|
|
310
|
+
for (var _d = true, events_1 = __asyncValues(events), events_1_1; events_1_1 = yield __await(events_1.next()), _a = events_1_1.done, !_a; _d = true) {
|
|
311
|
+
_c = events_1_1.value;
|
|
312
|
+
_d = false;
|
|
313
|
+
const frame = _c;
|
|
314
|
+
try {
|
|
315
|
+
yield yield __await(JSON.parse(frame.data));
|
|
316
|
+
}
|
|
317
|
+
catch (_e) {
|
|
318
|
+
yield yield __await({ type: "unknown", frame });
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
323
|
+
finally {
|
|
324
|
+
try {
|
|
325
|
+
if (!_d && !_a && (_b = events_1.return)) yield __await(_b.call(events_1));
|
|
326
|
+
}
|
|
327
|
+
finally { if (e_1) throw e_1.error; }
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
return decode();
|
|
332
|
+
}
|
|
333
|
+
async executeTool(sessionId, toolId, input) {
|
|
334
|
+
return this.transport.json(`/api/cloud/voice/sessions/${encodeURIComponent(assertString(sessionId, "sessionId"))}/tools/${encodeURIComponent(assertString(toolId, "toolId"))}/execute`, {
|
|
335
|
+
method: "POST",
|
|
336
|
+
body: JSON.stringify({ input }),
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
async getSessionRecordings(sessionId) {
|
|
340
|
+
return this.transport.json(`/api/cloud/voice/sessions/${encodeURIComponent(assertString(sessionId, "sessionId"))}/recordings`);
|
|
341
|
+
}
|
|
342
|
+
async listPhoneConnections() {
|
|
343
|
+
const res = await this.transport.json("/api/cloud/voice/phone/connections");
|
|
344
|
+
return res.connections;
|
|
345
|
+
}
|
|
346
|
+
async createPhoneConnection(input) {
|
|
347
|
+
return this.transport.json("/api/cloud/voice/phone/connections", {
|
|
348
|
+
method: "POST",
|
|
349
|
+
body: JSON.stringify(input),
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
async listPhoneNumbers() {
|
|
353
|
+
const res = await this.transport.json("/api/cloud/voice/phone/numbers");
|
|
354
|
+
return res.numbers;
|
|
355
|
+
}
|
|
356
|
+
async createPhoneNumber(input) {
|
|
357
|
+
return this.transport.json("/api/cloud/voice/phone/numbers", {
|
|
358
|
+
method: "POST",
|
|
359
|
+
body: JSON.stringify(input),
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
async updatePhoneNumber(input) {
|
|
363
|
+
return this.transport.json("/api/cloud/voice/phone/numbers", {
|
|
364
|
+
method: "PATCH",
|
|
365
|
+
body: JSON.stringify(input),
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
async getPhoneBridgeHealth() {
|
|
369
|
+
const res = await this.transport.json("/api/cloud/voice/phone/bridge");
|
|
370
|
+
return res.bridge;
|
|
371
|
+
}
|
|
372
|
+
async getSipDiagnostics() {
|
|
373
|
+
const res = await this.transport.json("/api/cloud/voice/phone/sip");
|
|
374
|
+
return res.sip;
|
|
375
|
+
}
|
|
376
|
+
async reloadSipBridge() {
|
|
377
|
+
const res = await this.transport.json("/api/cloud/voice/phone/sip", {
|
|
378
|
+
method: "POST",
|
|
379
|
+
body: "{}",
|
|
380
|
+
});
|
|
381
|
+
return res.sip;
|
|
382
|
+
}
|
|
383
|
+
async listToolCatalog() {
|
|
384
|
+
return this.transport.json("/api/cloud/voice/tools/catalog");
|
|
385
|
+
}
|
|
386
|
+
async syncToolCatalog(input) {
|
|
387
|
+
return this.transport.json("/api/cloud/voice/tools/sync", {
|
|
388
|
+
method: "POST",
|
|
389
|
+
body: JSON.stringify(input),
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
async listCalls() {
|
|
393
|
+
const res = await this.transport.json("/api/cloud/voice/calls");
|
|
394
|
+
return res.calls;
|
|
395
|
+
}
|
|
396
|
+
async listLiveCalls(input = {}) {
|
|
397
|
+
const params = new URLSearchParams();
|
|
398
|
+
if (input.status === "all")
|
|
399
|
+
params.set("status", "all");
|
|
400
|
+
if (input.limit !== undefined)
|
|
401
|
+
params.set("limit", String(input.limit));
|
|
402
|
+
const qs = params.toString();
|
|
403
|
+
const res = await this.transport.json(`/api/cloud/voice/calls/live${qs ? `?${qs}` : ""}`);
|
|
404
|
+
return res.calls;
|
|
405
|
+
}
|
|
406
|
+
async getCall(sessionId) {
|
|
407
|
+
return this.transport.json(`/api/cloud/voice/calls/${encodeURIComponent(assertString(sessionId, "sessionId"))}`);
|
|
408
|
+
}
|
|
409
|
+
async createCall(input) {
|
|
410
|
+
return this.transport.json("/api/cloud/voice/calls", {
|
|
411
|
+
method: "POST",
|
|
412
|
+
body: JSON.stringify(input),
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
async finalizeCall(sessionId) {
|
|
416
|
+
return this.transport.json(`/api/cloud/voice/calls/${encodeURIComponent(assertString(sessionId, "sessionId"))}/finalize`, {
|
|
417
|
+
method: "POST",
|
|
418
|
+
body: JSON.stringify({}),
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
async waitForCall(sessionId, options = {}) {
|
|
422
|
+
var _a, _b, _c, _d, _e, _f;
|
|
423
|
+
const normalizedSessionId = assertString(sessionId, "sessionId");
|
|
424
|
+
const intervalMs = Math.max(10, (_a = options.intervalMs) !== null && _a !== void 0 ? _a : 1000);
|
|
425
|
+
const timeoutMs = Math.max(intervalMs, (_b = options.timeoutMs) !== null && _b !== void 0 ? _b : 30 * 60000);
|
|
426
|
+
const deadline = Date.now() + timeoutMs;
|
|
427
|
+
let lastFingerprint = null;
|
|
428
|
+
let previousStatus;
|
|
429
|
+
while (true) {
|
|
430
|
+
const call = await this.getCall(normalizedSessionId);
|
|
431
|
+
const fingerprint = callStatusFingerprint(call);
|
|
432
|
+
if (fingerprint !== lastFingerprint) {
|
|
433
|
+
const event = toCallStatusChange(call, previousStatus);
|
|
434
|
+
(_c = options.onStatusChange) === null || _c === void 0 ? void 0 : _c.call(options, event);
|
|
435
|
+
(_d = options.onEvent) === null || _d === void 0 ? void 0 : _d.call(options, event);
|
|
436
|
+
lastFingerprint = fingerprint;
|
|
437
|
+
previousStatus = call.status;
|
|
438
|
+
}
|
|
439
|
+
if (isTerminalCall(call)) {
|
|
440
|
+
const result = await this.finalizeCall(normalizedSessionId);
|
|
441
|
+
const finalFingerprint = callStatusFingerprint(result.call);
|
|
442
|
+
if (finalFingerprint !== lastFingerprint) {
|
|
443
|
+
const event = toCallStatusChange(result.call, previousStatus);
|
|
444
|
+
(_e = options.onStatusChange) === null || _e === void 0 ? void 0 : _e.call(options, event);
|
|
445
|
+
(_f = options.onEvent) === null || _f === void 0 ? void 0 : _f.call(options, event);
|
|
446
|
+
}
|
|
447
|
+
return result;
|
|
448
|
+
}
|
|
449
|
+
if (Date.now() >= deadline) {
|
|
450
|
+
throw new Error(`Cloud voice call ${normalizedSessionId} did not complete within ${timeoutMs}ms`);
|
|
451
|
+
}
|
|
452
|
+
await sleep(intervalMs);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
async executeCallTool(sessionId, toolId, input) {
|
|
456
|
+
return this.transport.json(`/api/cloud/voice/calls/${encodeURIComponent(assertString(sessionId, "sessionId"))}/tools/${encodeURIComponent(assertString(toolId, "toolId"))}`, {
|
|
457
|
+
method: "POST",
|
|
458
|
+
body: JSON.stringify({ input }),
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
async hangupCall(sessionId, reason) {
|
|
462
|
+
return this.transport.json(`/api/cloud/voice/calls/${encodeURIComponent(assertString(sessionId, "sessionId"))}/hangup`, {
|
|
463
|
+
method: "POST",
|
|
464
|
+
body: JSON.stringify({ reason }),
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
async createCallListenToken(sessionId, input = {}) {
|
|
468
|
+
return this.transport.json(`/api/cloud/voice/calls/${encodeURIComponent(assertString(sessionId, "sessionId"))}/listen-token`, {
|
|
469
|
+
method: "POST",
|
|
470
|
+
body: JSON.stringify(input),
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
async createCallHandoff(sessionId, input = {}) {
|
|
474
|
+
return this.transport.json(`/api/cloud/voice/calls/${encodeURIComponent(assertString(sessionId, "sessionId"))}/handoff`, {
|
|
475
|
+
method: "POST",
|
|
476
|
+
body: JSON.stringify(input),
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
async acceptCallHandoff(sessionId, handoffId, input = {}) {
|
|
480
|
+
return this.transport.json(`/api/cloud/voice/calls/${encodeURIComponent(assertString(sessionId, "sessionId"))}/handoff/${encodeURIComponent(assertString(handoffId, "handoffId"))}/accept`, {
|
|
481
|
+
method: "POST",
|
|
482
|
+
body: JSON.stringify(input),
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
async cancelCallHandoff(sessionId, handoffId, input = {}) {
|
|
486
|
+
return this.transport.json(`/api/cloud/voice/calls/${encodeURIComponent(assertString(sessionId, "sessionId"))}/handoff/${encodeURIComponent(assertString(handoffId, "handoffId"))}/cancel`, {
|
|
487
|
+
method: "POST",
|
|
488
|
+
body: JSON.stringify(input),
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
exports.KognitiveCloudVoiceClient = KognitiveCloudVoiceClient;
|
|
493
|
+
class KognitiveCloudVoiceEmbedClient {
|
|
494
|
+
constructor(config) {
|
|
495
|
+
var _a;
|
|
496
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
497
|
+
this.publicKey = assertString(config.publicKey, "publicKey");
|
|
498
|
+
this.fetchImpl = (_a = config.fetch) !== null && _a !== void 0 ? _a : globalThis.fetch.bind(globalThis);
|
|
499
|
+
}
|
|
500
|
+
headers(extra) {
|
|
501
|
+
const headers = new Headers(extra);
|
|
502
|
+
headers.set("x-kognitive-public-key", this.publicKey);
|
|
503
|
+
headers.set("Content-Type", "application/json");
|
|
504
|
+
return headers;
|
|
505
|
+
}
|
|
506
|
+
async config(agent) {
|
|
507
|
+
const res = await this.fetchImpl(`${this.baseUrl}/api/cloud/voice/embed/config?agent=${encodeURIComponent(agent)}`, {
|
|
508
|
+
headers: this.headers(),
|
|
509
|
+
});
|
|
510
|
+
if (!res.ok)
|
|
511
|
+
throw new Error(await res.text());
|
|
512
|
+
return res.json();
|
|
513
|
+
}
|
|
514
|
+
async createSession(input) {
|
|
515
|
+
const res = await this.fetchImpl(`${this.baseUrl}/api/cloud/voice/embed/sessions`, {
|
|
516
|
+
method: "POST",
|
|
517
|
+
headers: this.headers(),
|
|
518
|
+
body: JSON.stringify(input),
|
|
519
|
+
});
|
|
520
|
+
if (!res.ok)
|
|
521
|
+
throw new Error(await res.text());
|
|
522
|
+
return res.json();
|
|
523
|
+
}
|
|
524
|
+
async executeTool(sessionId, toolId, input) {
|
|
525
|
+
const res = await this.fetchImpl(`${this.baseUrl}/api/cloud/voice/sessions/${encodeURIComponent(assertString(sessionId, "sessionId"))}/tools/${encodeURIComponent(assertString(toolId, "toolId"))}/execute`, {
|
|
526
|
+
method: "POST",
|
|
527
|
+
headers: this.headers(),
|
|
528
|
+
body: JSON.stringify({ input }),
|
|
529
|
+
});
|
|
530
|
+
if (!res.ok)
|
|
531
|
+
throw new Error(await res.text());
|
|
532
|
+
return res.json();
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
exports.KognitiveCloudVoiceEmbedClient = KognitiveCloudVoiceEmbedClient;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { KognitiveCloudVoiceClient, KognitiveCloudVoiceEmbedClient } from "./client";
|
|
2
|
+
export { createCloudVoiceTools, syncCloudVoiceCodeDefinedTools } from "./server";
|
|
3
|
+
export { createVoiceSession, createVoiceWidget, mountIframe } from "./browser";
|
|
4
|
+
export { readSSEStream } from "./sse";
|
|
5
|
+
export type { ParsedSSEEvent } from "./sse";
|
|
6
|
+
export type { CloudVoiceAgentConfig, CloudVoiceAgentConfigInput, CloudVoiceAgentMetadata, CloudVoiceAgentRecord, CloudVoiceAgentStatus, CloudVoiceChannel, CloudVoiceChannelSettings, CloudVoiceClientTool, CloudVoiceClientConfig, CloudVoiceClientToolDefinition, CloudVoiceClientToolExecuteContext, CloudVoiceClientToolManifest, CloudVoiceClientToolRenderContext, CloudVoiceClientToolRenderer, CloudVoiceClientTools, CloudVoiceClientToolState, CloudVoiceCustomVoiceConsent, CloudVoiceCustomVoiceRecord, CloudVoiceCustomVoiceSource, CloudVoiceCustomVoiceVerificationStatus, CloudVoiceHumanizationConfig, CloudVoiceSipConfig, CloudVoiceTelephonyDestination, CloudVoiceTelephonyProvider, CloudVoiceTransferDestination, CloudVoiceTransferMode, CloudVoiceTransferPolicy, CloudVoiceFlowEdge, CloudVoiceFlowGraph, CloudVoiceFlowNode, CloudVoiceFlowNodeOutput, CloudVoiceFlowNodeType, CloudVoiceNodeModelSettings, CloudVoiceNodeVoiceSettings, CloudVoiceParameterDefinition, CloudVoiceParameterPreset, CloudVoiceParameterSource, CloudVoiceParameterType, CloudVoiceParameterValueMap, CloudVoiceSpeechConfig, CloudVoiceEmbedConfig, CloudVoiceEmbedOptions, CloudVoiceCallLegRecord, CloudVoiceCallOutcome, CloudVoiceCallOutcomeSource, CloudVoiceCallStatusChange, CloudVoiceCallWaitOptions, CloudVoiceCallWaitResult, CloudVoiceHandoffAction, CloudVoiceHandoffMode, CloudVoiceHandoffRecord, CloudVoiceHandoffStatus, CloudVoiceCallJudgeResult, CloudVoiceListenTokenResult, CloudVoiceLiveCallRecord, CloudVoiceLiveCallHandoffState, CloudVoiceLiveCallTranscriptMessage, CloudVoicePhoneBridgeHealth, CloudVoicePhoneConnectionRecord, CloudVoicePhoneNumberRecord, CloudVoiceSipDiagnostics, CloudVoiceRecordingAsset, CloudVoiceRecordingAssetKind, CloudVoiceSessionBootstrap, CloudVoiceSessionEventRecord, CloudVoiceSessionRecord, CloudVoiceSessionStatus, CloudVoiceProvider, CloudVoiceToolType, CloudVoiceTransport, CloudVoiceToolBinding, CloudVoiceToolCatalog, CloudVoiceToolCatalogEntry, CloudVoiceToolCatalogSource, CloudVoiceWidgetConfig, CreateCloudVoiceAgentInput, CloneCloudVoiceCustomVoiceInput, ImportCloudVoiceCustomVoiceInput, AcceptCloudVoiceHandoffInput, CancelCloudVoiceHandoffInput, CreateCloudVoiceHandoffInput, CreateCloudVoiceOutboundCallInput, CreateCloudVoicePhoneConnectionInput, CreateCloudVoicePhoneNumberInput, CreateCloudVoiceSessionInput, LogLevel, UpdateCloudVoiceAgentInput, UpdateCloudVoiceCustomVoiceInput, UpdateCloudVoicePhoneNumberInput, SyncCloudVoiceToolCatalogInput, UseCloudVoiceAgentInput, UseCloudVoiceAgentResult, UseCloudVoiceAgentAction, } from "./types";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.readSSEStream = exports.mountIframe = exports.createVoiceWidget = exports.createVoiceSession = exports.syncCloudVoiceCodeDefinedTools = exports.createCloudVoiceTools = exports.KognitiveCloudVoiceEmbedClient = exports.KognitiveCloudVoiceClient = void 0;
|
|
4
|
+
var client_1 = require("./client");
|
|
5
|
+
Object.defineProperty(exports, "KognitiveCloudVoiceClient", { enumerable: true, get: function () { return client_1.KognitiveCloudVoiceClient; } });
|
|
6
|
+
Object.defineProperty(exports, "KognitiveCloudVoiceEmbedClient", { enumerable: true, get: function () { return client_1.KognitiveCloudVoiceEmbedClient; } });
|
|
7
|
+
var server_1 = require("./server");
|
|
8
|
+
Object.defineProperty(exports, "createCloudVoiceTools", { enumerable: true, get: function () { return server_1.createCloudVoiceTools; } });
|
|
9
|
+
Object.defineProperty(exports, "syncCloudVoiceCodeDefinedTools", { enumerable: true, get: function () { return server_1.syncCloudVoiceCodeDefinedTools; } });
|
|
10
|
+
var browser_1 = require("./browser");
|
|
11
|
+
Object.defineProperty(exports, "createVoiceSession", { enumerable: true, get: function () { return browser_1.createVoiceSession; } });
|
|
12
|
+
Object.defineProperty(exports, "createVoiceWidget", { enumerable: true, get: function () { return browser_1.createVoiceWidget; } });
|
|
13
|
+
Object.defineProperty(exports, "mountIframe", { enumerable: true, get: function () { return browser_1.mountIframe; } });
|
|
14
|
+
var sse_1 = require("./sse");
|
|
15
|
+
Object.defineProperty(exports, "readSSEStream", { enumerable: true, get: function () { return sse_1.readSSEStream; } });
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { KognitiveCloudVoiceClient } from "./client";
|
|
2
|
+
import type { CloudVoiceToolCatalog } from "./types";
|
|
3
|
+
export interface CloudVoiceToolRequest<TInput = unknown> {
|
|
4
|
+
type: "cloud_voice.tool.execute";
|
|
5
|
+
toolCallId: string;
|
|
6
|
+
toolId: string;
|
|
7
|
+
toolName?: string;
|
|
8
|
+
input: TInput;
|
|
9
|
+
session: {
|
|
10
|
+
id: string;
|
|
11
|
+
sessionId: string;
|
|
12
|
+
agentSlug: string;
|
|
13
|
+
channel: string;
|
|
14
|
+
userId: string;
|
|
15
|
+
resourceId: Record<string, unknown>;
|
|
16
|
+
parameters: Record<string, unknown>;
|
|
17
|
+
metadata: Record<string, unknown>;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export interface CloudVoiceToolContext<TInput = unknown> {
|
|
21
|
+
request: CloudVoiceToolRequest<TInput>;
|
|
22
|
+
abortSignal: AbortSignal;
|
|
23
|
+
toolCallId: string;
|
|
24
|
+
session: CloudVoiceToolRequest<TInput>["session"];
|
|
25
|
+
}
|
|
26
|
+
export interface CloudVoiceToolDefinition<TInput = unknown, TOutput = unknown> {
|
|
27
|
+
description?: string;
|
|
28
|
+
input?: {
|
|
29
|
+
parse: (value: unknown) => TInput;
|
|
30
|
+
};
|
|
31
|
+
execute: (input: TInput, context: CloudVoiceToolContext<TInput>) => Promise<TOutput> | TOutput;
|
|
32
|
+
}
|
|
33
|
+
export type CloudVoiceToolMap = Record<string, CloudVoiceToolDefinition<any, any> | ((input: any, context: CloudVoiceToolContext<any>) => unknown)>;
|
|
34
|
+
export interface CreateCloudVoiceToolsOptions<TTools extends CloudVoiceToolMap> {
|
|
35
|
+
tools: TTools;
|
|
36
|
+
secret?: string;
|
|
37
|
+
signatureToleranceMs?: number;
|
|
38
|
+
}
|
|
39
|
+
export declare function createCloudVoiceTools<TTools extends CloudVoiceToolMap>(options: CreateCloudVoiceToolsOptions<TTools>): (request: Request) => Promise<Response>;
|
|
40
|
+
export declare function syncCloudVoiceCodeDefinedTools(input: {
|
|
41
|
+
kognitive: {
|
|
42
|
+
getToolMetadataList: () => Array<{
|
|
43
|
+
id: string;
|
|
44
|
+
description?: string;
|
|
45
|
+
inputSchema?: unknown;
|
|
46
|
+
requireApproval?: boolean;
|
|
47
|
+
}>;
|
|
48
|
+
};
|
|
49
|
+
sourceKey: string;
|
|
50
|
+
bridgeUrl: string;
|
|
51
|
+
name?: string;
|
|
52
|
+
bridgeAuthorization?: string | null;
|
|
53
|
+
bridgeToken?: string | null;
|
|
54
|
+
metadata?: Record<string, unknown>;
|
|
55
|
+
client?: KognitiveCloudVoiceClient;
|
|
56
|
+
baseUrl?: string;
|
|
57
|
+
apiKey?: string;
|
|
58
|
+
}): Promise<CloudVoiceToolCatalog>;
|