@rimelabs/sdk 0.1.0-alpha.23 → 0.1.0-alpha.25
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/CHANGELOG.md +18 -0
- package/dist/realtime/protocol.d.ts +8 -7
- package/dist/realtime/protocol.js +51 -0
- package/dist/realtime/session.d.ts +2 -2
- package/dist/realtime/session.js +19 -7
- package/dist/realtime/types.d.ts +41 -2
- package/dist/realtime/types.js +8 -0
- package/docs/realtime.md +69 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.0-alpha.25](https://github.com/rimelabs/rime-sdk/compare/typescript-v0.1.0-alpha.24...typescript-v0.1.0-alpha.25) (2026-10-28)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* expose Prism reply labels and response data ([#114](https://github.com/rimelabs/rime-sdk/issues/114)) ([4a303a1](https://github.com/rimelabs/rime-sdk/commit/4a303a1b545019dea389f30d0c696e8f7e6cc6b1))
|
|
9
|
+
|
|
10
|
+
## [0.1.0-alpha.24](https://github.com/rimelabs/rime-sdk/compare/typescript-v0.1.0-alpha.23...typescript-v0.1.0-alpha.24) (2026-10-27)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### ⚠ BREAKING CHANGES
|
|
14
|
+
|
|
15
|
+
* Python and TypeScript SessionEvent payload unions now include ItemTruncated. Update exhaustive event handlers to accept ItemTruncated or the item.truncated kind. Handle unavailable retained text separately from an empty string. Rust's event enum remains non-exhaustive.
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* expose realtime truncation events and summaries ([#112](https://github.com/rimelabs/rime-sdk/issues/112)) ([15d6802](https://github.com/rimelabs/rime-sdk/commit/15d6802f71c849ce08b1d0b46e78bd44d5dfc3b7))
|
|
20
|
+
|
|
3
21
|
## [0.1.0-alpha.23](https://github.com/rimelabs/rime-sdk/compare/typescript-v0.1.0-alpha.22...typescript-v0.1.0-alpha.23) (2026-10-27)
|
|
4
22
|
|
|
5
23
|
|
|
@@ -26,6 +26,8 @@ export interface SessionSettings {
|
|
|
26
26
|
}
|
|
27
27
|
/** A copy of the client's labels for every reply: keys to strings. */
|
|
28
28
|
export declare function responseMetadata(value: unknown): t.Labels;
|
|
29
|
+
/** Copy caller labels before combining them with the SDK's protocol fields. */
|
|
30
|
+
export declare function requestMetadata(value: t.Labels | null | undefined, reserved: Record<string, string>): Record<string, string>;
|
|
29
31
|
export interface SessionPatch {
|
|
30
32
|
truncation?: SessionSettings["truncation"];
|
|
31
33
|
voice?: string;
|
|
@@ -76,16 +78,15 @@ export interface ItemDeleted {
|
|
|
76
78
|
export interface AudioCleared {
|
|
77
79
|
kind: "audio.cleared";
|
|
78
80
|
}
|
|
79
|
-
export interface
|
|
80
|
-
kind: "
|
|
81
|
-
|
|
82
|
-
contentIndex: number;
|
|
81
|
+
export interface SessionIdleTimeout {
|
|
82
|
+
kind: "session.idle_timeout";
|
|
83
|
+
idleTimeoutS: number;
|
|
83
84
|
}
|
|
84
85
|
export interface ResponseEnded extends t.ResponseEnded {
|
|
85
86
|
drainToken: string | null;
|
|
86
87
|
}
|
|
87
|
-
export type Acknowledgment = SessionUpdated | HistoryListed | ItemDeleted | ItemCreated | ToolResultCreated | AudioCleared | ItemTruncated | t.ResponseStarted | ResponseEnded;
|
|
88
|
-
export type ServerPayload = SessionCreated | Acknowledgment | t.InputEvent<t.NormalizedRealtimeFault> | t.MessageStarted | t.TextDelta | t.TextDone | t.AudioDelta | t.AudioDone | t.ToolCall | t.FaultEvent<t.NormalizedRealtimeFault
|
|
88
|
+
export type Acknowledgment = SessionUpdated | HistoryListed | ItemDeleted | ItemCreated | ToolResultCreated | AudioCleared | t.ItemTruncated | t.ResponseStarted | ResponseEnded;
|
|
89
|
+
export type ServerPayload = SessionCreated | Acknowledgment | t.InputEvent<t.NormalizedRealtimeFault> | t.MessageStarted | t.TextDelta | t.TextDone | t.AudioDelta | t.AudioDone | t.ToolCall | t.FaultEvent<t.NormalizedRealtimeFault> | SessionIdleTimeout;
|
|
89
90
|
export interface ServerEvent {
|
|
90
91
|
eventId: string;
|
|
91
92
|
requestId: string | null;
|
|
@@ -113,7 +114,7 @@ export declare const requests: {
|
|
|
113
114
|
text: Request<t.ResponseStarted>;
|
|
114
115
|
cancel: Request<ResponseEnded>;
|
|
115
116
|
clear: Request<AudioCleared>;
|
|
116
|
-
truncate: Request<ItemTruncated>;
|
|
117
|
+
truncate: Request<t.ItemTruncated>;
|
|
117
118
|
};
|
|
118
119
|
export declare function truncationSettings(value: t.Truncation): NonNullable<SessionSettings["truncation"]>;
|
|
119
120
|
export declare function decode(raw: string, sessionId: string | null): ServerEvent | null;
|
|
@@ -12,6 +12,13 @@ export function responseMetadata(value) {
|
|
|
12
12
|
throw new RimeInputError("responseMetadata must map keys to strings");
|
|
13
13
|
return Object.freeze({ ...value });
|
|
14
14
|
}
|
|
15
|
+
/** Copy caller labels before combining them with the SDK's protocol fields. */
|
|
16
|
+
export function requestMetadata(value, reserved) {
|
|
17
|
+
const labels = value == null ? {} : responseMetadata(value);
|
|
18
|
+
if (Object.keys(labels).some((key) => key.startsWith("prism_")))
|
|
19
|
+
throw new RimeInputError("request metadata keys cannot start with prism_");
|
|
20
|
+
return { ...labels, ...reserved };
|
|
21
|
+
}
|
|
15
22
|
/** A request carries its result type and checks it before exposing the result. */
|
|
16
23
|
export class Request {
|
|
17
24
|
kind;
|
|
@@ -67,6 +74,9 @@ function id(value, field) {
|
|
|
67
74
|
function optionalString(value, field) {
|
|
68
75
|
return value == null ? null : string(value, field);
|
|
69
76
|
}
|
|
77
|
+
function optionalId(value, field) {
|
|
78
|
+
return value == null ? null : id(value, field);
|
|
79
|
+
}
|
|
70
80
|
function integer(value, field) {
|
|
71
81
|
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0)
|
|
72
82
|
return invalid(field);
|
|
@@ -77,6 +87,31 @@ function revision(value) {
|
|
|
77
87
|
? null
|
|
78
88
|
: integer(value.prism_settings_revision, "prism_settings_revision");
|
|
79
89
|
}
|
|
90
|
+
function responseTruncation(response) {
|
|
91
|
+
if (response.prism_truncation === undefined)
|
|
92
|
+
return null;
|
|
93
|
+
const value = object(response.prism_truncation, "response.prism_truncation");
|
|
94
|
+
const count = integer(value.items_left_out, "prism_truncation.items_left_out");
|
|
95
|
+
if (count === 0)
|
|
96
|
+
return invalid("prism_truncation.items_left_out");
|
|
97
|
+
return Object.freeze({
|
|
98
|
+
itemsLeftOut: count,
|
|
99
|
+
firstKeptItemId: value.first_kept_item_id === undefined
|
|
100
|
+
? null
|
|
101
|
+
: string(value.first_kept_item_id, "prism_truncation.first_kept_item_id"),
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
function responseUsage(response) {
|
|
105
|
+
if (response.usage == null)
|
|
106
|
+
return null;
|
|
107
|
+
const usage = object(response.usage, "response.usage");
|
|
108
|
+
return Object.freeze({
|
|
109
|
+
inputTokens: integer(usage.input_tokens, "response.usage.input_tokens"),
|
|
110
|
+
outputTokens: integer(usage.output_tokens, "response.usage.output_tokens"),
|
|
111
|
+
totalTokens: integer(usage.total_tokens, "response.usage.total_tokens"),
|
|
112
|
+
contextWindow: integer(usage.context_window, "response.usage.context_window"),
|
|
113
|
+
});
|
|
114
|
+
}
|
|
80
115
|
function duration(value, field) {
|
|
81
116
|
if (value == null)
|
|
82
117
|
return null;
|
|
@@ -273,6 +308,15 @@ function decodeValue(value, sessionId) {
|
|
|
273
308
|
case "conversation.item.deleted":
|
|
274
309
|
payload = { kind: "item.deleted", itemId: id(event.item_id, "item_id") };
|
|
275
310
|
break;
|
|
311
|
+
case "session.idle_timeout": {
|
|
312
|
+
if (event.reason !== "idle_timeout")
|
|
313
|
+
return invalid("reason");
|
|
314
|
+
const timeout = duration(event.idle_timeout_s, "idle_timeout_s");
|
|
315
|
+
if (timeout === null || timeout < 1)
|
|
316
|
+
return invalid("idle_timeout_s");
|
|
317
|
+
payload = { kind: "session.idle_timeout", idleTimeoutS: timeout };
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
276
320
|
case "input_audio_buffer.cleared":
|
|
277
321
|
payload = { kind: "audio.cleared" };
|
|
278
322
|
break;
|
|
@@ -281,6 +325,10 @@ function decodeValue(value, sessionId) {
|
|
|
281
325
|
kind: "item.truncated",
|
|
282
326
|
itemId: id(event.item_id, "item_id"),
|
|
283
327
|
contentIndex: integer(event.content_index, "content_index"),
|
|
328
|
+
audioEndMs: integer(event.audio_end_ms, "audio_end_ms"),
|
|
329
|
+
keptText: event.prism_kept_text === undefined
|
|
330
|
+
? null
|
|
331
|
+
: string(event.prism_kept_text, "prism_kept_text"),
|
|
284
332
|
};
|
|
285
333
|
break;
|
|
286
334
|
case "prism.typed_input.ready":
|
|
@@ -380,6 +428,7 @@ function decodeValue(value, sessionId) {
|
|
|
380
428
|
: "unknown",
|
|
381
429
|
parent: parent === null ? null : ref(parent),
|
|
382
430
|
inputItemId,
|
|
431
|
+
instructionItemId: optionalId(metadata.prism_instruction_item_id, "prism_instruction_item_id"),
|
|
383
432
|
metadata: clientMetadata(metadata),
|
|
384
433
|
inputItemIds: Object.freeze(inputItemIds.map((value) => id(value, "prism_input_item_ids"))),
|
|
385
434
|
};
|
|
@@ -396,6 +445,8 @@ function decodeValue(value, sessionId) {
|
|
|
396
445
|
payload = {
|
|
397
446
|
kind: "response.ended",
|
|
398
447
|
settingsRevision: revision(response),
|
|
448
|
+
truncation: responseTruncation(response),
|
|
449
|
+
usage: responseUsage(response),
|
|
399
450
|
response: ref(response.id),
|
|
400
451
|
status: status === "completed" ||
|
|
401
452
|
status === "cancelled" ||
|
|
@@ -56,7 +56,7 @@ export declare class RealtimeSession {
|
|
|
56
56
|
* complete list. Replies already started keep their original settings.
|
|
57
57
|
* Cancellation after submission does not undo an accepted update. */
|
|
58
58
|
update(options?: t.RealtimeUpdateOptions): Promise<t.SessionInfo>;
|
|
59
|
-
sendText(value: string, options?: t.
|
|
59
|
+
sendText(value: string, options?: t.ReplyRequestOptions): Promise<t.ResponseRef>;
|
|
60
60
|
requestReply(options?: t.ReplyOptions): Promise<t.ResponseRef>;
|
|
61
61
|
/** Read the items the next reply would see, in server order. */
|
|
62
62
|
getHistory(options?: t.RealtimeOperationOptions): Promise<readonly t.HistoryItem[]>;
|
|
@@ -66,7 +66,7 @@ export declare class RealtimeSession {
|
|
|
66
66
|
createItem(item: t.HistoryItem, options?: t.HistoryCreateOptions): Promise<t.ItemRef>;
|
|
67
67
|
addMessage(role: "user" | "assistant", value: string, options?: t.RealtimeOperationOptions): Promise<t.ItemRef>;
|
|
68
68
|
submitToolResult(call: t.ToolCallRef, output: string, options?: t.RealtimeOperationOptions): Promise<void>;
|
|
69
|
-
continueReply(parent: t.ResponseRef, options?: t.
|
|
69
|
+
continueReply(parent: t.ResponseRef, options?: t.ReplyRequestOptions): Promise<t.ResponseRef>;
|
|
70
70
|
cancel(response: t.ResponseRef, options?: t.RealtimeOperationOptions): Promise<void>;
|
|
71
71
|
/** Replaces the labels later replies carry; a reply already started keeps
|
|
72
72
|
* its own. Resolves once Prism confirms the change. */
|
package/dist/realtime/session.js
CHANGED
|
@@ -403,11 +403,19 @@ export class RealtimeSession {
|
|
|
403
403
|
}
|
|
404
404
|
async sendText(value, options = {}) {
|
|
405
405
|
text(value);
|
|
406
|
-
|
|
406
|
+
const metadata = p.requestMetadata(options.metadata, {
|
|
407
|
+
prism_cause: "user_text",
|
|
408
|
+
});
|
|
409
|
+
return this.operation(options, (signal) => this.create({
|
|
410
|
+
prism_input_text: value,
|
|
411
|
+
metadata,
|
|
412
|
+
}, signal, p.requests.text));
|
|
407
413
|
}
|
|
408
414
|
async requestReply(options = {}) {
|
|
409
415
|
const body = {
|
|
410
|
-
metadata: {
|
|
416
|
+
metadata: p.requestMetadata(options.metadata, {
|
|
417
|
+
prism_cause: "proactive",
|
|
418
|
+
}),
|
|
411
419
|
};
|
|
412
420
|
if (options.instruction != null) {
|
|
413
421
|
text(options.instruction);
|
|
@@ -498,6 +506,10 @@ export class RealtimeSession {
|
|
|
498
506
|
}
|
|
499
507
|
async continueReply(parent, options = {}) {
|
|
500
508
|
const ref = { ...parent };
|
|
509
|
+
const metadata = p.requestMetadata(options.metadata, {
|
|
510
|
+
prism_cause: "tool_continuation",
|
|
511
|
+
prism_parent_response_id: ref.responseId,
|
|
512
|
+
});
|
|
501
513
|
const state = this.response(ref);
|
|
502
514
|
return this.operation(options, async (signal) => {
|
|
503
515
|
const ready = scope([signal], this.timeouts.readyS, new t.RealtimeAdmissionTimeout("Tool results or parent completion did not arrive before readyS expired"));
|
|
@@ -522,10 +534,7 @@ export class RealtimeSession {
|
|
|
522
534
|
}
|
|
523
535
|
return (await this.request(p.requests.create, {
|
|
524
536
|
response: {
|
|
525
|
-
metadata
|
|
526
|
-
prism_cause: "tool_continuation",
|
|
527
|
-
prism_parent_response_id: ref.responseId,
|
|
528
|
-
},
|
|
537
|
+
metadata,
|
|
529
538
|
},
|
|
530
539
|
}, signal, undefined, state)).response;
|
|
531
540
|
});
|
|
@@ -677,6 +686,9 @@ export class RealtimeSession {
|
|
|
677
686
|
throw new RimeStreamError("Tool result acknowledgment names another call");
|
|
678
687
|
}
|
|
679
688
|
switch (payload.kind) {
|
|
689
|
+
case "session.idle_timeout":
|
|
690
|
+
this.fail(new t.RealtimeIdleTimeout(payload.idleTimeoutS));
|
|
691
|
+
return;
|
|
680
692
|
case "session.created":
|
|
681
693
|
if (this.sessionId === null) {
|
|
682
694
|
this.sessionId = payload.session.id;
|
|
@@ -752,7 +764,7 @@ export class RealtimeSession {
|
|
|
752
764
|
pending.target === payload.itemId &&
|
|
753
765
|
payload.contentIndex === 0)
|
|
754
766
|
this.settle(key, payload);
|
|
755
|
-
|
|
767
|
+
break;
|
|
756
768
|
case "input.ready":
|
|
757
769
|
this.readyEpoch++;
|
|
758
770
|
this.ready.set();
|
package/dist/realtime/types.d.ts
CHANGED
|
@@ -87,7 +87,11 @@ export interface RealtimeUpdateOptions extends RealtimeOperationOptions {
|
|
|
87
87
|
readonly voice?: string;
|
|
88
88
|
readonly interruptOnSpeech?: boolean;
|
|
89
89
|
}
|
|
90
|
-
export interface
|
|
90
|
+
export interface ReplyRequestOptions extends RealtimeOperationOptions {
|
|
91
|
+
/** Labels for this reply. Request labels override matching session labels. */
|
|
92
|
+
readonly metadata?: Labels | null;
|
|
93
|
+
}
|
|
94
|
+
export interface ReplyOptions extends ReplyRequestOptions {
|
|
91
95
|
readonly instruction?: string | null;
|
|
92
96
|
readonly toolCall?: ToolCallRef | null;
|
|
93
97
|
}
|
|
@@ -178,6 +182,11 @@ export interface NormalizedRealtimeFault extends RealtimeFault {
|
|
|
178
182
|
}
|
|
179
183
|
export declare class RealtimeAdmissionTimeout extends RimeTimeoutError {
|
|
180
184
|
}
|
|
185
|
+
/** Prism closed the conversation after this many idle seconds. */
|
|
186
|
+
export declare class RealtimeIdleTimeout extends RimeTimeoutError {
|
|
187
|
+
readonly idleTimeoutS: number;
|
|
188
|
+
constructor(idleTimeoutS: number);
|
|
189
|
+
}
|
|
181
190
|
export declare class RimeRealtimeError extends RimeError {
|
|
182
191
|
readonly fault: NormalizedRealtimeFault;
|
|
183
192
|
constructor(fault: RealtimeFault);
|
|
@@ -244,6 +253,8 @@ export interface ResponseStarted {
|
|
|
244
253
|
readonly cause: "speech" | "text" | "proactive" | "tools" | "unknown";
|
|
245
254
|
readonly parent: ResponseRef | null;
|
|
246
255
|
readonly inputItemId: string | null;
|
|
256
|
+
/** Saved nudge instruction; pass this ID to deleteItem to remove it. */
|
|
257
|
+
readonly instructionItemId?: string | null;
|
|
247
258
|
/** The session's labels when the reply began. Prism's `prism_` keys are
|
|
248
259
|
* left out. */
|
|
249
260
|
readonly metadata: Labels;
|
|
@@ -288,10 +299,28 @@ export interface ResponseAbandoned {
|
|
|
288
299
|
readonly kind: "response.abandoned";
|
|
289
300
|
readonly response: ResponseRef;
|
|
290
301
|
}
|
|
302
|
+
/** History items excluded from this reply's prompt, not deleted from history. */
|
|
303
|
+
export interface ResponseTruncation {
|
|
304
|
+
/** Number of excluded items, not turns. Already hidden items are not counted. */
|
|
305
|
+
readonly itemsLeftOut: number;
|
|
306
|
+
/** Oldest retained item; null when no earlier item was retained. */
|
|
307
|
+
readonly firstKeptItemId: string | null;
|
|
308
|
+
}
|
|
309
|
+
export interface ResponseUsage {
|
|
310
|
+
readonly inputTokens: number;
|
|
311
|
+
readonly outputTokens: number;
|
|
312
|
+
readonly totalTokens: number;
|
|
313
|
+
readonly contextWindow: number;
|
|
314
|
+
}
|
|
291
315
|
export interface ResponseEnded {
|
|
292
316
|
/** Settings revision published by the server; null when unavailable.
|
|
293
317
|
* Optional on caller-created values for compatibility. */
|
|
294
318
|
readonly settingsRevision?: number | null;
|
|
319
|
+
/** Null when the server reports no exclusions or the information is unavailable.
|
|
320
|
+
* Optional on caller-created values for compatibility. */
|
|
321
|
+
readonly truncation?: ResponseTruncation | null;
|
|
322
|
+
/** Null when Prism did not count tokens. */
|
|
323
|
+
readonly usage?: ResponseUsage | null;
|
|
295
324
|
readonly kind: "response.ended";
|
|
296
325
|
readonly response: ResponseRef;
|
|
297
326
|
readonly status: "completed" | "cancelled" | "failed" | "unknown";
|
|
@@ -303,11 +332,21 @@ export interface FaultEvent<Fault extends RealtimeFault = RealtimeFault> {
|
|
|
303
332
|
}
|
|
304
333
|
export type InputEvent<Fault extends RealtimeFault = RealtimeFault> = InputReady | SpeechHint | SpeechStarted | SpeechStopped | InputCommitted | TranscriptDelta | TranscriptFinal | TranscriptFailed<Fault>;
|
|
305
334
|
export type ResponseEvent = ResponseStarted | ResponseAbandoned | MessageStarted | TextDelta | TextDone | AudioDelta | AudioDone | ToolCall | ResponseEnded;
|
|
335
|
+
/** A playback report was recorded. Retained history text can differ from audible
|
|
336
|
+
* text: replies with tool calls retain all words. */
|
|
337
|
+
export interface ItemTruncated {
|
|
338
|
+
readonly kind: "item.truncated";
|
|
339
|
+
readonly itemId: string;
|
|
340
|
+
readonly contentIndex: number;
|
|
341
|
+
readonly audioEndMs: number;
|
|
342
|
+
/** Null when unavailable, including during generation; empty if no words remain. */
|
|
343
|
+
readonly keptText: string | null;
|
|
344
|
+
}
|
|
306
345
|
export interface SessionEvent<Fault extends RealtimeFault = RealtimeFault> {
|
|
307
346
|
readonly sessionId: string;
|
|
308
347
|
readonly eventId: string;
|
|
309
348
|
readonly requestId: string | null;
|
|
310
|
-
readonly payload: InputEvent<Fault> | ResponseEvent | FaultEvent<Fault>;
|
|
349
|
+
readonly payload: InputEvent<Fault> | ResponseEvent | ItemTruncated | FaultEvent<Fault>;
|
|
311
350
|
}
|
|
312
351
|
export interface PlaybackInterrupted {
|
|
313
352
|
readonly kind: "interrupted";
|
package/dist/realtime/types.js
CHANGED
|
@@ -2,6 +2,14 @@ import { RimeError, RimeTimeoutError } from "../errors.js";
|
|
|
2
2
|
import { normalizeFault } from "./faults.js";
|
|
3
3
|
export class RealtimeAdmissionTimeout extends RimeTimeoutError {
|
|
4
4
|
}
|
|
5
|
+
/** Prism closed the conversation after this many idle seconds. */
|
|
6
|
+
export class RealtimeIdleTimeout extends RimeTimeoutError {
|
|
7
|
+
idleTimeoutS;
|
|
8
|
+
constructor(idleTimeoutS) {
|
|
9
|
+
super(`Realtime session idle for ${idleTimeoutS} seconds`);
|
|
10
|
+
this.idleTimeoutS = idleTimeoutS;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
5
13
|
export class RimeRealtimeError extends RimeError {
|
|
6
14
|
fault;
|
|
7
15
|
constructor(fault) {
|
package/docs/realtime.md
CHANGED
|
@@ -294,6 +294,12 @@ instruction, tool call, and signal in one object. `update` returns
|
|
|
294
294
|
`getHistory` returns `Promise<readonly HistoryItem[]>`. The other methods return
|
|
295
295
|
`Promise<void>`.
|
|
296
296
|
|
|
297
|
+
Pass `metadata: { step: "3" }` in the options for `sendText`, `requestReply`, or
|
|
298
|
+
`continueReply` to label only that reply. Request labels replace matching
|
|
299
|
+
session labels in Prism's response. The SDK adds the required `prism_` fields;
|
|
300
|
+
caller keys cannot use that prefix. Omitting `metadata` keeps the existing
|
|
301
|
+
request shape. Replies to speech use the session labels.
|
|
302
|
+
|
|
297
303
|
`sendText` and `addMessage` require nonblank text of at most 4,000 Unicode
|
|
298
304
|
characters. `addMessage` accepts `"user"` and `"assistant"` roles. `createItem`
|
|
299
305
|
also accepts `"system"` messages and allows blank message text, with the same
|
|
@@ -397,12 +403,12 @@ are exported from `@rimelabs/sdk`.
|
|
|
397
403
|
| `input.committed` | `itemId` |
|
|
398
404
|
| `transcript.delta`, `transcript.final` | `itemId` and `delta` or `text` |
|
|
399
405
|
| `transcript.failed` | `itemId`, `error` |
|
|
400
|
-
| `response.started` | `response`, `cause`, nullable `parent` and `
|
|
406
|
+
| `response.started` | `response`, `cause`, nullable `parent`, `inputItemId`, and `instructionItemId`, `inputItemIds` (the user items it answers), `metadata` (your own keys) |
|
|
401
407
|
| `message.started` | `output` |
|
|
402
408
|
| `text.delta`, `text.done` | `output` and `delta` or `text` |
|
|
403
409
|
| `audio.delta`, `audio.done` | `output`; a delta also has `audio.data` and a complete `audio.format` |
|
|
404
410
|
| `tool.call` | `call`, `itemId`, `name`, parsed `arguments` |
|
|
405
|
-
| `response.ended` | `response`, `status`, nullable `reason` |
|
|
411
|
+
| `response.ended` | `response`, `status`, nullable `reason` and `usage` |
|
|
406
412
|
| `response.abandoned` | `response`; the SDK requests cancellation after the requesting caller aborted. |
|
|
407
413
|
| `error` | `error`, a `RealtimeFault` |
|
|
408
414
|
|
|
@@ -460,6 +466,10 @@ the session remains usable. An unknown request outcome closes the connection and
|
|
|
460
466
|
is never replayed. The SDK retries typed-turn admission only after named refusals
|
|
461
467
|
that confirm the request made no change.
|
|
462
468
|
|
|
469
|
+
`RealtimeIdleTimeout` means Prism closed an idle session. Its `idleTimeoutS`
|
|
470
|
+
is the limit reported by Prism. Pending methods and the event iterator reject
|
|
471
|
+
with this error. Reconnect to start a new conversation.
|
|
472
|
+
|
|
463
473
|
Protocol faults appear as `error` events and can also reject an affected method
|
|
464
474
|
with `RimeRealtimeError`. Its `.fault` has `code`, `message`, `scope`, nullable
|
|
465
475
|
`requestId`, `responseId`, `itemId`, `correlationId`, `parameter`, and a `callIds`
|
|
@@ -587,3 +597,60 @@ publish it.
|
|
|
587
597
|
```text
|
|
588
598
|
await session.update({ truncation: { retentionRatio: 0.9 } });
|
|
589
599
|
```
|
|
600
|
+
|
|
601
|
+
## Retained text after interruption
|
|
602
|
+
|
|
603
|
+
Available in the next SDK release. A `conversation.item.truncated` acknowledgment
|
|
604
|
+
also appears in `session.events` as `ItemTruncated`, with kind `item.truncated`.
|
|
605
|
+
The conversation runner forwards it to `onEvent`. Playback reporting does not
|
|
606
|
+
wait for event consumption.
|
|
607
|
+
|
|
608
|
+
Use `itemId`, `contentIndex`, and `audioEndMs` to identify the reported audio.
|
|
609
|
+
`keptText` is the text retained in server history. An empty string means no words
|
|
610
|
+
remain. `null` means unavailable, including older servers and replies still being
|
|
611
|
+
generated. The event does not promise a later text update. Replies with tool calls
|
|
612
|
+
retain all words, so this field can differ from the words heard during playback.
|
|
613
|
+
|
|
614
|
+
```typescript
|
|
615
|
+
function onEvent(event: SessionEvent) {
|
|
616
|
+
if (event.payload.kind === "item.truncated") {
|
|
617
|
+
const cut = event.payload;
|
|
618
|
+
if (cut.keptText !== null) {
|
|
619
|
+
console.log("Retained text", cut.itemId, JSON.stringify(cut.keptText));
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
This event can arrive after `response.ended`. It has no response reference and does
|
|
626
|
+
not require the SDK to retain that response. `text.done` still reports generated
|
|
627
|
+
text. Add `item.truncated` to exhaustive switches on `SessionEvent.payload.kind`.
|
|
628
|
+
|
|
629
|
+
## Response usage and saved nudge instructions
|
|
630
|
+
|
|
631
|
+
`ResponseEnded.usage` contains `inputTokens`, `outputTokens`, `totalTokens`,
|
|
632
|
+
and `contextWindow` when Prism counted the reply's tokens. It is `null` when
|
|
633
|
+
the count is unavailable. For a nudge with an instruction,
|
|
634
|
+
`ResponseStarted.instructionItemId` names the saved instruction. Pass that ID
|
|
635
|
+
to `deleteItem` to remove it from later history.
|
|
636
|
+
|
|
637
|
+
## History excluded from a reply
|
|
638
|
+
|
|
639
|
+
Available in the next SDK release. `ResponseEnded.truncation` exposes the server's
|
|
640
|
+
`response.prism_truncation` summary. It contains `itemsLeftOut` and nullable
|
|
641
|
+
`firstKeptItemId`. The count refers to conversation items excluded from this
|
|
642
|
+
reply's prompt, not turns or items deleted from history. Already hidden items do
|
|
643
|
+
not count. The first ID is absent when no item from before this turn was retained.
|
|
644
|
+
|
|
645
|
+
Decoded events have `truncation: null` when the server reports no exclusions or the
|
|
646
|
+
information is unavailable, including older servers or a reply that ended before
|
|
647
|
+
usage was counted. Caller-created events may omit the property. This does not change
|
|
648
|
+
the session's truncation policy. Session events and conversation callbacks expose
|
|
649
|
+
the same immutable summary.
|
|
650
|
+
|
|
651
|
+
```typescript
|
|
652
|
+
if (event.payload.kind === "response.ended" && event.payload.truncation) {
|
|
653
|
+
const summary = event.payload.truncation;
|
|
654
|
+
console.log(summary.itemsLeftOut, summary.firstKeptItemId);
|
|
655
|
+
}
|
|
656
|
+
```
|