@nuancelabs/js-sdk 0.10.0 → 0.10.1
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/index.d.ts +4 -0
- package/index.js +60 -5
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -512,6 +512,10 @@ export declare interface SessionTokenResponse {
|
|
|
512
512
|
/** When the avatar starts speaking: see {@link CreateNuanceConversationOptions.startOn}. */
|
|
513
513
|
export declare type StartOn = "first-frame" | "full-quality";
|
|
514
514
|
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
|
|
515
519
|
/**
|
|
516
520
|
* The local user participant in a conversation.
|
|
517
521
|
*/
|
package/index.js
CHANGED
|
@@ -4,7 +4,7 @@ function isRecord(value) {
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
// src/core/sdk-version.ts
|
|
7
|
-
var SDK_HEADER = `js/${"0.10.
|
|
7
|
+
var SDK_HEADER = `js/${"0.10.1"}`;
|
|
8
8
|
|
|
9
9
|
// src/utils.ts
|
|
10
10
|
function normalizeHost(host) {
|
|
@@ -1098,6 +1098,17 @@ function parseSessionEvent(payload) {
|
|
|
1098
1098
|
if (decoded.type === "floor") {
|
|
1099
1099
|
return { type: "floor", speaking: decoded.state === "speaking" };
|
|
1100
1100
|
}
|
|
1101
|
+
if (decoded.type === "tool.call" && typeof decoded.call_id === "string" && typeof decoded.name === "string" && isRecord(decoded.arguments)) {
|
|
1102
|
+
return {
|
|
1103
|
+
type: "tool-call",
|
|
1104
|
+
call: {
|
|
1105
|
+
callId: decoded.call_id,
|
|
1106
|
+
name: decoded.name,
|
|
1107
|
+
label: typeof decoded.label === "string" ? decoded.label : "",
|
|
1108
|
+
arguments: decoded.arguments
|
|
1109
|
+
}
|
|
1110
|
+
};
|
|
1111
|
+
}
|
|
1101
1112
|
if (decoded.type === "session.status" && decoded.status === "ended") {
|
|
1102
1113
|
return {
|
|
1103
1114
|
type: "ended",
|
|
@@ -1544,6 +1555,7 @@ class LiveKitUserParticipant {
|
|
|
1544
1555
|
// src/providers/livekit/conversation.ts
|
|
1545
1556
|
var DATA_EVENT_TOPIC = "nuance.data";
|
|
1546
1557
|
var SESSION_TOPIC = "nuance.v1";
|
|
1558
|
+
var PACKET_MAX_BYTES = 14000;
|
|
1547
1559
|
var RUNTIME_TOPIC = "runtime";
|
|
1548
1560
|
var CLOCK_SYNC_TOPIC = "clock-sync";
|
|
1549
1561
|
var STATS_FLUSH_TIMEOUT_MS = 300;
|
|
@@ -1551,6 +1563,7 @@ var SESSION_END_TIMEOUT_MS = 300;
|
|
|
1551
1563
|
var SESSION_END_ID = "client-session-end";
|
|
1552
1564
|
var REFUSAL_REASON_WAIT_MS = 500;
|
|
1553
1565
|
var COMMAND_TIMEOUT_MS = 5000;
|
|
1566
|
+
var STREAM_TIMEOUT_MS = 30000;
|
|
1554
1567
|
var BACKGROUND_ID = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
1555
1568
|
var AVATAR_RETURN_TIMEOUT_MS = 8000;
|
|
1556
1569
|
function isReconnecting(lkState) {
|
|
@@ -1764,9 +1777,24 @@ class LiveKitConversation {
|
|
|
1764
1777
|
async releaseAgent() {
|
|
1765
1778
|
return this.command({ type: "floor.release" });
|
|
1766
1779
|
}
|
|
1780
|
+
async sendToolResult(callId, output, options = {}) {
|
|
1781
|
+
return this.command({
|
|
1782
|
+
type: "tool.result",
|
|
1783
|
+
call_id: callId,
|
|
1784
|
+
output,
|
|
1785
|
+
...options.images?.length && {
|
|
1786
|
+
images: options.images.map(({ mediaType, data }) => ({
|
|
1787
|
+
media_type: mediaType,
|
|
1788
|
+
data
|
|
1789
|
+
}))
|
|
1790
|
+
},
|
|
1791
|
+
is_error: options.isError ?? false,
|
|
1792
|
+
final: options.final ?? true
|
|
1793
|
+
});
|
|
1794
|
+
}
|
|
1767
1795
|
onChange(handler) {
|
|
1768
1796
|
return this.onEvent((event) => {
|
|
1769
|
-
if (event.type !== "data-event" && event.type !== "screen-share-changed")
|
|
1797
|
+
if (event.type !== "data-event" && event.type !== "screen-share-changed" && event.type !== "tool-call")
|
|
1770
1798
|
handler(event);
|
|
1771
1799
|
});
|
|
1772
1800
|
}
|
|
@@ -1783,6 +1811,12 @@ class LiveKitConversation {
|
|
|
1783
1811
|
}
|
|
1784
1812
|
});
|
|
1785
1813
|
}
|
|
1814
|
+
onToolCall(handler) {
|
|
1815
|
+
return this.onEvent((event) => {
|
|
1816
|
+
if (event.type === "tool-call")
|
|
1817
|
+
handler(event.call);
|
|
1818
|
+
});
|
|
1819
|
+
}
|
|
1786
1820
|
async command(command) {
|
|
1787
1821
|
if (this.room.state !== ConnectionState2.Connected) {
|
|
1788
1822
|
throw new Error("Not connected — call connect() first");
|
|
@@ -1794,11 +1828,18 @@ class LiveKitConversation {
|
|
|
1794
1828
|
const answer = Promise.withResolvers();
|
|
1795
1829
|
this.commands.set(id, { type: command.type, settle: answer.resolve });
|
|
1796
1830
|
let timer;
|
|
1831
|
+
const text = JSON.stringify({ ...command, id });
|
|
1832
|
+
const payload = new TextEncoder().encode(text);
|
|
1833
|
+
const streamed = payload.byteLength > PACKET_MAX_BYTES;
|
|
1834
|
+
const sent = streamed ? this.room.localParticipant.sendText(text, { topic: SESSION_TOPIC }) : this.room.localParticipant.publishData(payload, {
|
|
1835
|
+
reliable: true,
|
|
1836
|
+
topic: SESSION_TOPIC
|
|
1837
|
+
});
|
|
1797
1838
|
try {
|
|
1798
1839
|
return await Promise.race([
|
|
1799
|
-
|
|
1840
|
+
sent.then(() => answer.promise),
|
|
1800
1841
|
new Promise((_, reject) => {
|
|
1801
|
-
timer = setTimeout(() => reject(new Error(`The runtime did not answer ${command.type}`)), COMMAND_TIMEOUT_MS);
|
|
1842
|
+
timer = setTimeout(() => reject(new Error(`The runtime did not answer ${command.type}`)), streamed ? STREAM_TIMEOUT_MS : COMMAND_TIMEOUT_MS);
|
|
1802
1843
|
})
|
|
1803
1844
|
]);
|
|
1804
1845
|
} finally {
|
|
@@ -2006,6 +2047,8 @@ class LiveKitConversation {
|
|
|
2006
2047
|
}
|
|
2007
2048
|
} else if (event.type === "floor") {
|
|
2008
2049
|
this.setAvatarSpeaking(event.speaking);
|
|
2050
|
+
} else if (event.type === "tool-call") {
|
|
2051
|
+
this.emit({ type: "tool-call", call: event.call });
|
|
2009
2052
|
} else if (event.type === "ended") {
|
|
2010
2053
|
this.answered?.();
|
|
2011
2054
|
if (!event.byClient)
|
|
@@ -2446,9 +2489,15 @@ class NuanceConversation {
|
|
|
2446
2489
|
}
|
|
2447
2490
|
return this.delegate.releaseAgent();
|
|
2448
2491
|
}
|
|
2492
|
+
async sendToolResult(callId, output, options) {
|
|
2493
|
+
if (!this.delegate) {
|
|
2494
|
+
throw new Error("Not connected — call connect() first");
|
|
2495
|
+
}
|
|
2496
|
+
return this.delegate.sendToolResult(callId, output, options);
|
|
2497
|
+
}
|
|
2449
2498
|
onChange(handler) {
|
|
2450
2499
|
return this.onEvent((event) => {
|
|
2451
|
-
if (event.type !== "data-event" && event.type !== "screen-share-changed")
|
|
2500
|
+
if (event.type !== "data-event" && event.type !== "screen-share-changed" && event.type !== "tool-call")
|
|
2452
2501
|
handler(event);
|
|
2453
2502
|
});
|
|
2454
2503
|
}
|
|
@@ -2465,6 +2514,12 @@ class NuanceConversation {
|
|
|
2465
2514
|
}
|
|
2466
2515
|
});
|
|
2467
2516
|
}
|
|
2517
|
+
onToolCall(handler) {
|
|
2518
|
+
return this.onEvent((event) => {
|
|
2519
|
+
if (event.type === "tool-call")
|
|
2520
|
+
handler(event.call);
|
|
2521
|
+
});
|
|
2522
|
+
}
|
|
2468
2523
|
async waitForSlot(conversationId, attempt) {
|
|
2469
2524
|
const admission = await this.followEvents(conversationId, attempt);
|
|
2470
2525
|
if (admission !== null) {
|