@rimelabs/sdk 0.1.0-alpha.14 → 0.1.0-alpha.16
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 +14 -0
- package/dist/realtime/protocol.js +19 -13
- package/dist/realtime/session.js +7 -7
- package/dist/realtime/types.d.ts +8 -1
- package/docs/realtime.md +4 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.0-alpha.16](https://github.com/rimelabs/rime-sdk/compare/typescript-v0.1.0-alpha.15...typescript-v0.1.0-alpha.16) (2026-10-16)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **realtime:** expose Prism's speech hint ([#73](https://github.com/rimelabs/rime-sdk/issues/73)) ([cb7187d](https://github.com/rimelabs/rime-sdk/commit/cb7187d687c2210332fee704d43ac9ba45c760ea))
|
|
9
|
+
|
|
10
|
+
## [0.1.0-alpha.15](https://github.com/rimelabs/rime-sdk/compare/typescript-v0.1.0-alpha.14...typescript-v0.1.0-alpha.15) (2026-10-13)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* **realtime:** align Prism protocol names and contract fixtures ([#68](https://github.com/rimelabs/rime-sdk/issues/68)) ([806d8a4](https://github.com/rimelabs/rime-sdk/commit/806d8a4811f0baf6b220487dfc6ccd21cfe8ea18))
|
|
16
|
+
|
|
3
17
|
## [0.1.0-alpha.14](https://github.com/rimelabs/rime-sdk/compare/typescript-v0.1.0-alpha.13...typescript-v0.1.0-alpha.14) (2026-10-12)
|
|
4
18
|
|
|
5
19
|
|
|
@@ -66,15 +66,15 @@ function duration(value, field) {
|
|
|
66
66
|
}
|
|
67
67
|
function session(value) {
|
|
68
68
|
const view = object(value, "session");
|
|
69
|
-
const waits = view.
|
|
69
|
+
const waits = view.prism_tool_waits === undefined
|
|
70
70
|
? {}
|
|
71
|
-
: object(view.
|
|
72
|
-
if (view.
|
|
71
|
+
: object(view.prism_tool_waits, "session.prism_tool_waits");
|
|
72
|
+
if (view.prism_tool_waits !== undefined &&
|
|
73
73
|
(!("result_timeout_s" in waits) || !("continuation_timeout_s" in waits)))
|
|
74
|
-
invalid("session.
|
|
75
|
-
const interrupt = view.
|
|
74
|
+
invalid("session.prism_tool_waits");
|
|
75
|
+
const interrupt = view.prism_effective_interrupt_response;
|
|
76
76
|
if (interrupt !== undefined && typeof interrupt !== "boolean")
|
|
77
|
-
invalid("session.
|
|
77
|
+
invalid("session.prism_effective_interrupt_response");
|
|
78
78
|
return {
|
|
79
79
|
id: id(view.id, "session.id"),
|
|
80
80
|
voice: view.voice === undefined ? "" : string(view.voice, "session.voice"),
|
|
@@ -189,9 +189,15 @@ function decodeValue(value, sessionId) {
|
|
|
189
189
|
contentIndex: integer(event.content_index, "content_index"),
|
|
190
190
|
};
|
|
191
191
|
break;
|
|
192
|
-
case "
|
|
192
|
+
case "prism.typed_input.ready":
|
|
193
193
|
payload = { kind: "input.ready" };
|
|
194
194
|
break;
|
|
195
|
+
case "prism.input_audio_buffer.speech_hint":
|
|
196
|
+
payload = {
|
|
197
|
+
kind: "speech.hint",
|
|
198
|
+
audioStartMs: integer(event.audio_start_ms, "audio_start_ms"),
|
|
199
|
+
};
|
|
200
|
+
break;
|
|
195
201
|
case "input_audio_buffer.speech_started":
|
|
196
202
|
payload = {
|
|
197
203
|
kind: "speech.started",
|
|
@@ -244,10 +250,10 @@ function decodeValue(value, sessionId) {
|
|
|
244
250
|
const response = object(event.response, "response"), metadata = response.metadata == null
|
|
245
251
|
? {}
|
|
246
252
|
: object(response.metadata, "metadata");
|
|
247
|
-
const cause = metadata.
|
|
253
|
+
const cause = metadata.prism_cause === undefined
|
|
248
254
|
? undefined
|
|
249
|
-
: string(metadata.
|
|
250
|
-
const parent = optionalString(metadata.
|
|
255
|
+
: string(metadata.prism_cause, "prism_cause");
|
|
256
|
+
const parent = optionalString(metadata.prism_parent_response_id, "prism_parent_response_id");
|
|
251
257
|
payload = {
|
|
252
258
|
kind: "response.started",
|
|
253
259
|
response: ref(response.id),
|
|
@@ -261,7 +267,7 @@ function decodeValue(value, sessionId) {
|
|
|
261
267
|
? "proactive"
|
|
262
268
|
: "unknown",
|
|
263
269
|
parent: parent === null ? null : ref(parent),
|
|
264
|
-
inputItemId: optionalString(metadata.
|
|
270
|
+
inputItemId: optionalString(metadata.prism_input_item_id, "prism_input_item_id"),
|
|
265
271
|
};
|
|
266
272
|
break;
|
|
267
273
|
}
|
|
@@ -282,7 +288,7 @@ function decodeValue(value, sessionId) {
|
|
|
282
288
|
? status
|
|
283
289
|
: "unknown",
|
|
284
290
|
reason: optionalString(details.reason, "reason"),
|
|
285
|
-
drainToken: optionalString(metadata.
|
|
291
|
+
drainToken: optionalString(metadata.prism_drain_token, "prism_drain_token"),
|
|
286
292
|
};
|
|
287
293
|
break;
|
|
288
294
|
}
|
|
@@ -348,7 +354,7 @@ function decodeValue(value, sessionId) {
|
|
|
348
354
|
}
|
|
349
355
|
return {
|
|
350
356
|
eventId: event.event_id === undefined ? "" : string(event.event_id, "event_id"),
|
|
351
|
-
requestId: optionalString(event.
|
|
357
|
+
requestId: optionalString(event.prism_request_event_id, "prism_request_event_id"),
|
|
352
358
|
payload,
|
|
353
359
|
};
|
|
354
360
|
}
|
package/dist/realtime/session.js
CHANGED
|
@@ -348,21 +348,21 @@ export class RealtimeSession {
|
|
|
348
348
|
}
|
|
349
349
|
async sendText(value, options = {}) {
|
|
350
350
|
text(value);
|
|
351
|
-
return this.operation(options, (signal) => this.create({
|
|
351
|
+
return this.operation(options, (signal) => this.create({ prism_input_text: value, metadata: { prism_cause: "user_text" } }, signal, p.requests.text));
|
|
352
352
|
}
|
|
353
353
|
async requestReply(options = {}) {
|
|
354
354
|
const body = {
|
|
355
|
-
metadata: {
|
|
355
|
+
metadata: { prism_cause: "proactive" },
|
|
356
356
|
};
|
|
357
357
|
if (options.instruction != null) {
|
|
358
358
|
text(options.instruction);
|
|
359
|
-
body.
|
|
359
|
+
body.prism_instruction = options.instruction;
|
|
360
360
|
}
|
|
361
361
|
if (options.toolCall != null) {
|
|
362
362
|
const state = this.response(options.toolCall);
|
|
363
363
|
if (state.calls.get(options.toolCall.callId) === null)
|
|
364
364
|
throw new RimeInputError("Record the tool result before requesting its report");
|
|
365
|
-
body.
|
|
365
|
+
body.prism_call_id = options.toolCall.callId;
|
|
366
366
|
}
|
|
367
367
|
return this.operation(options, (signal) => this.create(body, signal));
|
|
368
368
|
}
|
|
@@ -434,8 +434,8 @@ export class RealtimeSession {
|
|
|
434
434
|
return (await this.request(p.requests.create, {
|
|
435
435
|
response: {
|
|
436
436
|
metadata: {
|
|
437
|
-
|
|
438
|
-
|
|
437
|
+
prism_cause: "tool_continuation",
|
|
438
|
+
prism_parent_response_id: ref.responseId,
|
|
439
439
|
},
|
|
440
440
|
},
|
|
441
441
|
}, signal, undefined, state)).response;
|
|
@@ -524,7 +524,7 @@ export class RealtimeSession {
|
|
|
524
524
|
this.check();
|
|
525
525
|
if (state.token)
|
|
526
526
|
await this.send({
|
|
527
|
-
type: "
|
|
527
|
+
type: "prism.playback.drained",
|
|
528
528
|
response_id: state.ref.responseId,
|
|
529
529
|
drain_token: state.token,
|
|
530
530
|
played_ms: played,
|
package/dist/realtime/types.d.ts
CHANGED
|
@@ -81,6 +81,13 @@ export declare class RimeRealtimeError extends RimeError {
|
|
|
81
81
|
export interface InputReady {
|
|
82
82
|
readonly kind: "input.ready";
|
|
83
83
|
}
|
|
84
|
+
/** The user may have started speaking over a playing reply. Prism sends it
|
|
85
|
+
* before `speech.started` when it may interrupt the reply; it can be a false
|
|
86
|
+
* alarm, so lower playback on it rather than stopping. */
|
|
87
|
+
export interface SpeechHint {
|
|
88
|
+
readonly kind: "speech.hint";
|
|
89
|
+
readonly audioStartMs: number;
|
|
90
|
+
}
|
|
84
91
|
export interface SpeechStarted {
|
|
85
92
|
readonly kind: "speech.started";
|
|
86
93
|
readonly itemId: string;
|
|
@@ -164,7 +171,7 @@ export interface FaultEvent {
|
|
|
164
171
|
readonly kind: "error";
|
|
165
172
|
readonly error: RealtimeFault;
|
|
166
173
|
}
|
|
167
|
-
export type InputEvent = InputReady | SpeechStarted | SpeechStopped | InputCommitted | TranscriptDelta | TranscriptFinal | TranscriptFailed;
|
|
174
|
+
export type InputEvent = InputReady | SpeechHint | SpeechStarted | SpeechStopped | InputCommitted | TranscriptDelta | TranscriptFinal | TranscriptFailed;
|
|
168
175
|
export type ResponseEvent = ResponseStarted | ResponseAbandoned | MessageStarted | TextDelta | TextDone | AudioDelta | AudioDone | ToolCall | ResponseEnded;
|
|
169
176
|
export interface SessionEvent {
|
|
170
177
|
readonly sessionId: string;
|
package/docs/realtime.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Realtime / Prism for Node.js
|
|
2
2
|
|
|
3
|
+
The endpoint must use Rime's `prism.` events and `prism_` fields. Endpoints
|
|
4
|
+
that use the former `prsm` names are not supported.
|
|
5
|
+
|
|
3
6
|
Keep one event consumer running while your application sends input, runs tools,
|
|
4
7
|
and plays audio. The SDK manages the protocol state. Your application owns
|
|
5
8
|
microphone capture, tool execution, and playback.
|
|
@@ -127,6 +130,7 @@ are exported from `@rimelabs/sdk`.
|
|
|
127
130
|
| Kind | Payload fields |
|
|
128
131
|
| --- | --- |
|
|
129
132
|
| `input.ready` | No data fields. Turn methods handle the readiness wait. |
|
|
133
|
+
| `speech.hint` | `audioStartMs`; the user may have started speaking over a playing reply. It can be a false alarm: lower playback, do not stop it. |
|
|
130
134
|
| `speech.started`, `speech.stopped` | `itemId` and `audioStartMs` or `audioEndMs` |
|
|
131
135
|
| `input.committed` | `itemId` |
|
|
132
136
|
| `transcript.delta`, `transcript.final` | `itemId` and `delta` or `text` |
|