@nuancelabs/js-sdk 0.12.0 → 0.13.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 +120 -0
- package/index.js +44 -4
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -217,6 +217,37 @@ export declare interface Conversation {
|
|
|
217
217
|
* @returns A function that removes the handler.
|
|
218
218
|
*/
|
|
219
219
|
on<K extends keyof SessionEventMap>(type: K, handler: (event: SessionEventMap[K]) => void): () => void;
|
|
220
|
+
/**
|
|
221
|
+
* Subscribes to the agent's calls of the conversation's tools, named when
|
|
222
|
+
* your server mints the session token. Run the tool in your page and answer each call with
|
|
223
|
+
* {@link Conversation.sendToolResult}. The agent keeps talking while a call
|
|
224
|
+
* is open, and uses the result when it arrives.
|
|
225
|
+
*
|
|
226
|
+
* @example
|
|
227
|
+
* ```ts
|
|
228
|
+
* conversation.onToolCall(async (call) => {
|
|
229
|
+
* if (call.name === "show_confetti") {
|
|
230
|
+
* launchConfetti();
|
|
231
|
+
* await conversation.sendToolResult(call.callId, "Confetti is falling.");
|
|
232
|
+
* }
|
|
233
|
+
* });
|
|
234
|
+
* ```
|
|
235
|
+
*
|
|
236
|
+
* @returns A function that removes the handler.
|
|
237
|
+
*/
|
|
238
|
+
onToolCall(handler: (call: ToolCall) => void): () => void;
|
|
239
|
+
/**
|
|
240
|
+
* Answers a tool call: what it produced, or with `isError` what went wrong.
|
|
241
|
+
* The agent keeps the first 2,000 characters of an output, so return what
|
|
242
|
+
* it needs, not everything you have.
|
|
243
|
+
*
|
|
244
|
+
* @param callId - The call's {@link ToolCall.callId}.
|
|
245
|
+
* @returns Whether the runtime took the result: `status` is `"rejected"`,
|
|
246
|
+
* with the reason in `error`, for an unknown or closed call.
|
|
247
|
+
* @throws If the conversation is not connected, or the runtime does not
|
|
248
|
+
* answer in time.
|
|
249
|
+
*/
|
|
250
|
+
sendToolResult(callId: string, output: ToolOutput, options?: ToolResultOptions): Promise<CommandResult>;
|
|
220
251
|
}
|
|
221
252
|
|
|
222
253
|
|
|
@@ -487,6 +518,33 @@ export declare interface FloorEvent extends SessionEventBase {
|
|
|
487
518
|
state: "waiting" | "listening" | "speaking" | (string & {});
|
|
488
519
|
}
|
|
489
520
|
|
|
521
|
+
/**
|
|
522
|
+
* A tool the agent may call, which your page runs: show something on the
|
|
523
|
+
* screen, read what the user has open, look something up in your app. The
|
|
524
|
+
* agent decides when to call it from its `description`, and fills its
|
|
525
|
+
* arguments to match its `parameters`. A conversation has up to 16 tools.
|
|
526
|
+
*/
|
|
527
|
+
export declare interface FunctionTool {
|
|
528
|
+
/** Always `"function"`, the default. */
|
|
529
|
+
type?: "function";
|
|
530
|
+
/**
|
|
531
|
+
* The tool's name: letters, digits, `_` and `-`, up to 64 characters,
|
|
532
|
+
* unique in the conversation. `ask_user`, `get_current_time`, `web_search`
|
|
533
|
+
* and the agent's other own tools' names are taken.
|
|
534
|
+
*/
|
|
535
|
+
name: string;
|
|
536
|
+
/**
|
|
537
|
+
* What the tool does and when to use it, written for the agent, up to
|
|
538
|
+
* 2,000 characters. Say when to call it, not only what it does.
|
|
539
|
+
*/
|
|
540
|
+
description: string;
|
|
541
|
+
/**
|
|
542
|
+
* The arguments, as a JSON Schema whose `type` is `"object"`, up to 16,000
|
|
543
|
+
* characters as compact JSON. `{ type: "object", properties: {} }` takes none.
|
|
544
|
+
*/
|
|
545
|
+
parameters: Record<string, unknown>;
|
|
546
|
+
}
|
|
547
|
+
|
|
490
548
|
/**
|
|
491
549
|
* Raised by {@link Conversation.connect} when the server refuses a guest's new
|
|
492
550
|
* session because a guest limit is used up. `reason` says which: `used` (this
|
|
@@ -499,6 +557,7 @@ export declare class GuestLimitError extends Error {
|
|
|
499
557
|
constructor(reason: string, message: string);
|
|
500
558
|
}
|
|
501
559
|
|
|
560
|
+
|
|
502
561
|
/**
|
|
503
562
|
* Raised by {@link Conversation.connect} when the server refuses a new session
|
|
504
563
|
* because the account has not completed onboarding or accepted the current
|
|
@@ -651,6 +710,23 @@ export declare interface SessionPersonality {
|
|
|
651
710
|
export declare interface SessionTokenRequest {
|
|
652
711
|
/** Who the avatar is in the conversation. Leave it out for the default personality. */
|
|
653
712
|
personality?: SessionPersonality;
|
|
713
|
+
/**
|
|
714
|
+
* Tools the agent may call, which your page runs and answers with
|
|
715
|
+
* `onToolCall` and `sendToolResult`;
|
|
716
|
+
* up to 16. Fixed for the conversation: the page can't change them.
|
|
717
|
+
*
|
|
718
|
+
* @example
|
|
719
|
+
* ```ts
|
|
720
|
+
* tools: [
|
|
721
|
+
* {
|
|
722
|
+
* name: "show_confetti",
|
|
723
|
+
* description: "Plays confetti on the user's screen. Use it to celebrate with them.",
|
|
724
|
+
* parameters: { type: "object", properties: {} },
|
|
725
|
+
* },
|
|
726
|
+
* ]
|
|
727
|
+
* ```
|
|
728
|
+
*/
|
|
729
|
+
tools?: FunctionTool[];
|
|
654
730
|
/**
|
|
655
731
|
* Your own id for the person this conversation is for, such as a hash of
|
|
656
732
|
* your user id. After repeated policy violations, new conversations pause
|
|
@@ -673,9 +749,53 @@ export declare interface SessionTokenResponse {
|
|
|
673
749
|
/** When the avatar starts speaking: see {@link CreateNuanceConversationOptions.startOn}. */
|
|
674
750
|
export declare type StartOn = "first-frame" | "full-quality";
|
|
675
751
|
|
|
752
|
+
/**
|
|
753
|
+
* The agent's call of one of the conversation's tools: run it, then answer
|
|
754
|
+
* with {@link Conversation.sendToolResult} and its `callId`.
|
|
755
|
+
*/
|
|
756
|
+
export declare interface ToolCall {
|
|
757
|
+
/** Identifies the call; answer with it. */
|
|
758
|
+
callId: string;
|
|
759
|
+
/** The tool, by its `name`. */
|
|
760
|
+
name: string;
|
|
761
|
+
/** The agent's own short name for this use of the tool, such as `"confetti"`. */
|
|
762
|
+
label: string;
|
|
763
|
+
/** The call's arguments, held to the tool's `parameters` schema. */
|
|
764
|
+
arguments: Record<string, unknown>;
|
|
765
|
+
}
|
|
676
766
|
|
|
767
|
+
/**
|
|
768
|
+
* An image a tool produced, for the agent to look at: a screenshot, say, or
|
|
769
|
+
* a page of a document. Up to 8,000,000 base64 characters (about 6 MB); the
|
|
770
|
+
* runtime fits it to 1920 px on its long side.
|
|
771
|
+
*/
|
|
772
|
+
export declare interface ToolImage {
|
|
773
|
+
mediaType: "image/jpeg" | "image/png";
|
|
774
|
+
/** The encoded image, base64. */
|
|
775
|
+
data: string;
|
|
776
|
+
}
|
|
677
777
|
|
|
778
|
+
/**
|
|
779
|
+
* What a tool call produced: text, or JSON the agent reads as it is. Up to
|
|
780
|
+
* 24,000 characters (its JSON, for an object); the agent keeps the first 2,000.
|
|
781
|
+
*/
|
|
782
|
+
export declare type ToolOutput = string | Record<string, unknown> | unknown[];
|
|
678
783
|
|
|
784
|
+
/**
|
|
785
|
+
* How {@link Conversation.sendToolResult} reports a result.
|
|
786
|
+
*/
|
|
787
|
+
export declare interface ToolResultOptions {
|
|
788
|
+
/** Images the tool produced, up to 4; the agent looks at them, in order,
|
|
789
|
+
* where the result enters the conversation. */
|
|
790
|
+
images?: ToolImage[];
|
|
791
|
+
/** The output says what went wrong rather than what the tool produced. */
|
|
792
|
+
isError?: boolean;
|
|
793
|
+
/** Whether this is the call's last part; a part with `final: false` adds to
|
|
794
|
+
* what the agent knows and keeps the call open.
|
|
795
|
+
*
|
|
796
|
+
* @defaultValue `true` */
|
|
797
|
+
final?: boolean;
|
|
798
|
+
}
|
|
679
799
|
|
|
680
800
|
/**
|
|
681
801
|
* The local user participant in a conversation.
|
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.
|
|
7
|
+
var SDK_HEADER = `js/${"0.13.1"}`;
|
|
8
8
|
|
|
9
9
|
// src/utils.ts
|
|
10
10
|
function normalizeHost(host) {
|
|
@@ -1676,6 +1676,10 @@ var COMMAND_TIMEOUT_MS = 5000;
|
|
|
1676
1676
|
var STREAM_TIMEOUT_MS = 30000;
|
|
1677
1677
|
var BACKGROUND_ID = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
1678
1678
|
var AVATAR_RETURN_TIMEOUT_MS = 8000;
|
|
1679
|
+
function contextItem(item) {
|
|
1680
|
+
const name = item.name === undefined ? {} : { name: item.name };
|
|
1681
|
+
return item.type === "text" ? { type: "text", text: item.text, ...name } : { type: "image", media_type: item.mediaType, data: item.data, ...name };
|
|
1682
|
+
}
|
|
1679
1683
|
function isReconnecting(lkState) {
|
|
1680
1684
|
return lkState === ConnectionState2.Reconnecting || lkState === ConnectionState2.SignalReconnecting;
|
|
1681
1685
|
}
|
|
@@ -1736,6 +1740,7 @@ class LiveKitConversation {
|
|
|
1736
1740
|
awayTimer = null;
|
|
1737
1741
|
presentationPaused = false;
|
|
1738
1742
|
readySending = false;
|
|
1743
|
+
contextSent = null;
|
|
1739
1744
|
leaving = null;
|
|
1740
1745
|
connectGeneration = 0;
|
|
1741
1746
|
_id;
|
|
@@ -1744,6 +1749,8 @@ class LiveKitConversation {
|
|
|
1744
1749
|
cameraFacing;
|
|
1745
1750
|
tokenProvider;
|
|
1746
1751
|
opensOnReady;
|
|
1752
|
+
presentsAtFullSize;
|
|
1753
|
+
initialContext;
|
|
1747
1754
|
resilient;
|
|
1748
1755
|
constructor(config) {
|
|
1749
1756
|
this.room = new Room({
|
|
@@ -1765,6 +1772,8 @@ class LiveKitConversation {
|
|
|
1765
1772
|
this.cameraFacing = config.mediaDevices?.cameraFacing;
|
|
1766
1773
|
this.tokenProvider = config.tokenProvider;
|
|
1767
1774
|
this.opensOnReady = config.opensOnReady ?? false;
|
|
1775
|
+
this.presentsAtFullSize = config.presentsAtFullSize ?? this.opensOnReady;
|
|
1776
|
+
this.initialContext = config.initialContext ?? [];
|
|
1768
1777
|
this.resilient = config.resilientReconnect ?? false;
|
|
1769
1778
|
}
|
|
1770
1779
|
get id() {
|
|
@@ -1780,6 +1789,7 @@ class LiveKitConversation {
|
|
|
1780
1789
|
this.sequence.stop();
|
|
1781
1790
|
this.sequence = this.newSequence();
|
|
1782
1791
|
this.readyOwed = false;
|
|
1792
|
+
this.contextSent = null;
|
|
1783
1793
|
this.everConnected = false;
|
|
1784
1794
|
if (!this.eventsRegistered) {
|
|
1785
1795
|
this.registerRoomEvents();
|
|
@@ -2150,6 +2160,7 @@ class LiveKitConversation {
|
|
|
2150
2160
|
if (packet === null)
|
|
2151
2161
|
return;
|
|
2152
2162
|
this.speaksProtocol = true;
|
|
2163
|
+
this.sendContext();
|
|
2153
2164
|
const { seq, event } = packet;
|
|
2154
2165
|
if (this.sequence.repeats(seq))
|
|
2155
2166
|
return;
|
|
@@ -2243,6 +2254,10 @@ class LiveKitConversation {
|
|
|
2243
2254
|
this.emit({ type: "avatar-presented" });
|
|
2244
2255
|
return;
|
|
2245
2256
|
}
|
|
2257
|
+
if (!this.presentsAtFullSize) {
|
|
2258
|
+
this.markAvatarPresented();
|
|
2259
|
+
return;
|
|
2260
|
+
}
|
|
2246
2261
|
this.startPresentation();
|
|
2247
2262
|
}
|
|
2248
2263
|
startPresentation() {
|
|
@@ -2253,7 +2268,7 @@ class LiveKitConversation {
|
|
|
2253
2268
|
markAvatarPresented() {
|
|
2254
2269
|
this.presentation = null;
|
|
2255
2270
|
if (this.speaksProtocol && this.room.state === ConnectionState2.Connected) {
|
|
2256
|
-
this.
|
|
2271
|
+
this.ready().catch(() => {
|
|
2257
2272
|
return;
|
|
2258
2273
|
});
|
|
2259
2274
|
} else if (this.resilient && this.speaksProtocol && isReconnecting(this.room.state)) {
|
|
@@ -2261,11 +2276,28 @@ class LiveKitConversation {
|
|
|
2261
2276
|
}
|
|
2262
2277
|
this.emit({ type: "avatar-presented" });
|
|
2263
2278
|
}
|
|
2279
|
+
sendContext() {
|
|
2280
|
+
if (this.contextSent !== null || this.initialContext.length === 0)
|
|
2281
|
+
return;
|
|
2282
|
+
this.contextSent = this.command({
|
|
2283
|
+
type: "session.context",
|
|
2284
|
+
items: this.initialContext.map(contextItem)
|
|
2285
|
+
}).then(() => {
|
|
2286
|
+
return;
|
|
2287
|
+
}, () => {
|
|
2288
|
+
return;
|
|
2289
|
+
});
|
|
2290
|
+
}
|
|
2291
|
+
ready() {
|
|
2292
|
+
this.sendContext();
|
|
2293
|
+
const ready = () => this.command({ type: "session.ready" });
|
|
2294
|
+
return this.contextSent === null ? ready() : this.contextSent.then(ready);
|
|
2295
|
+
}
|
|
2264
2296
|
sendOwedReady() {
|
|
2265
2297
|
if (!this.readyOwed || !this.speaksProtocol || this.readySending)
|
|
2266
2298
|
return;
|
|
2267
2299
|
this.readySending = true;
|
|
2268
|
-
this.
|
|
2300
|
+
this.ready().then(() => {
|
|
2269
2301
|
this.readyOwed = false;
|
|
2270
2302
|
}).catch(() => {
|
|
2271
2303
|
return;
|
|
@@ -2428,6 +2460,8 @@ class NuanceConversation {
|
|
|
2428
2460
|
ticker;
|
|
2429
2461
|
sessionOverrides;
|
|
2430
2462
|
personality;
|
|
2463
|
+
tools;
|
|
2464
|
+
initialContext;
|
|
2431
2465
|
variant;
|
|
2432
2466
|
maxSessionSeconds;
|
|
2433
2467
|
videoCapture;
|
|
@@ -2466,6 +2500,8 @@ class NuanceConversation {
|
|
|
2466
2500
|
this.ticker = deps.ticker ?? pageTicker;
|
|
2467
2501
|
this.sessionOverrides = options.sessionOverrides ?? {};
|
|
2468
2502
|
this.personality = options.personality;
|
|
2503
|
+
this.tools = options.tools;
|
|
2504
|
+
this.initialContext = options.initialContext ?? [];
|
|
2469
2505
|
this.variant = options.variant;
|
|
2470
2506
|
this.maxSessionSeconds = options.maxSessionSeconds;
|
|
2471
2507
|
this.videoCapture = options.videoCapture;
|
|
@@ -2495,13 +2531,15 @@ class NuanceConversation {
|
|
|
2495
2531
|
try {
|
|
2496
2532
|
const request = {
|
|
2497
2533
|
session_overrides: this.sessionOverrides,
|
|
2498
|
-
client_ready: this.startOn === "full-quality"
|
|
2534
|
+
client_ready: this.startOn === "full-quality" || this.initialContext.length > 0
|
|
2499
2535
|
};
|
|
2500
2536
|
const timezone = this.timezone();
|
|
2501
2537
|
if (timezone)
|
|
2502
2538
|
request.timezone = timezone;
|
|
2503
2539
|
if (this.personality)
|
|
2504
2540
|
request.personality = this.personality;
|
|
2541
|
+
if (this.tools)
|
|
2542
|
+
request.tools = this.tools;
|
|
2505
2543
|
if (this.variant)
|
|
2506
2544
|
request.variant = this.variant;
|
|
2507
2545
|
if (this.maxSessionSeconds !== undefined) {
|
|
@@ -2805,6 +2843,8 @@ class NuanceConversation {
|
|
|
2805
2843
|
cameraEnabled: !this.sessionOverrides.disable_camera && mediaDevices.cameraEnabled !== false,
|
|
2806
2844
|
videoCapture: this.videoCapture,
|
|
2807
2845
|
opensOnReady: conversation.provider_metadata?.client_ready === true,
|
|
2846
|
+
presentsAtFullSize: this.startOn === "full-quality",
|
|
2847
|
+
initialContext: this.initialContext,
|
|
2808
2848
|
resilientReconnect: this.resilient
|
|
2809
2849
|
});
|
|
2810
2850
|
}
|