@rimelabs/sdk 0.1.0-alpha.2 → 0.1.0-alpha.21
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 +155 -0
- package/LICENSE-PRISM +201 -0
- package/NOTICE-PRISM +9 -0
- package/README.md +279 -114
- package/dist/auth.d.ts +9 -3
- package/dist/auth.js +12 -4
- package/dist/cancellation.d.ts +6 -0
- package/dist/cancellation.js +54 -0
- package/dist/client.d.ts +24 -23
- package/dist/client.js +41 -92
- package/dist/grpc.d.ts +27 -0
- package/dist/grpc.js +175 -0
- package/dist/index.d.ts +10 -2
- package/dist/index.js +6 -2
- package/dist/pcm.d.ts +21 -0
- package/dist/pcm.js +52 -0
- package/dist/realtime/async.d.ts +23 -0
- package/dist/realtime/async.js +87 -0
- package/dist/realtime/audio.d.ts +2 -0
- package/dist/realtime/audio.js +11 -0
- package/dist/realtime/client.d.ts +12 -0
- package/dist/realtime/client.js +139 -0
- package/dist/realtime/conversation.d.ts +47 -0
- package/dist/realtime/conversation.js +321 -0
- package/dist/realtime/faults.d.ts +2 -0
- package/dist/realtime/faults.js +25 -0
- package/dist/realtime/protocol.d.ts +99 -0
- package/dist/realtime/protocol.js +432 -0
- package/dist/realtime/session.d.ts +79 -0
- package/dist/realtime/session.js +808 -0
- package/dist/realtime/settings.d.ts +11 -0
- package/dist/realtime/settings.js +142 -0
- package/dist/realtime/transport.d.ts +16 -0
- package/dist/realtime/transport.js +86 -0
- package/dist/realtime/types.d.ts +292 -0
- package/dist/realtime/types.js +12 -0
- package/dist/stt/audio.d.ts +15 -0
- package/dist/stt/audio.js +46 -0
- package/dist/stt/client.d.ts +17 -0
- package/dist/stt/client.js +121 -0
- package/dist/stt/policy.d.ts +11 -0
- package/dist/stt/policy.js +11 -0
- package/dist/stt/protocol.d.ts +14 -0
- package/dist/stt/protocol.js +76 -0
- package/dist/stt/queue.d.ts +16 -0
- package/dist/stt/queue.js +45 -0
- package/dist/stt/stream.d.ts +48 -0
- package/dist/stt/stream.js +224 -0
- package/dist/stt/transport.d.ts +15 -0
- package/dist/stt/transport.js +94 -0
- package/dist/stt/types.d.ts +51 -0
- package/dist/stt/types.js +1 -0
- package/dist/{audio.d.ts → tts/audio.d.ts} +9 -0
- package/dist/{audio.js → tts/audio.js} +44 -4
- package/dist/tts/buffer.d.ts +3 -0
- package/dist/tts/buffer.js +53 -0
- package/dist/tts/client.d.ts +53 -0
- package/dist/tts/client.js +151 -0
- package/dist/tts/lexicon.d.ts +7 -0
- package/dist/tts/lexicon.js +23 -0
- package/dist/{policy.d.ts → tts/policy.d.ts} +2 -3
- package/dist/tts/policy.js +41 -0
- package/dist/{stream.d.ts → tts/stream.d.ts} +15 -2
- package/dist/{stream.js → tts/stream.js} +54 -30
- package/dist/tts/timestamps.d.ts +24 -0
- package/dist/tts/timestamps.js +46 -0
- package/dist/{transport.d.ts → tts/transport.d.ts} +10 -13
- package/dist/tts/transport.js +133 -0
- package/dist/validation.d.ts +5 -0
- package/dist/validation.js +28 -0
- package/docs/realtime.md +537 -0
- package/docs/stt.md +186 -0
- package/docs/tts.md +284 -0
- package/package.json +14 -12
- package/dist/policy.js +0 -82
- package/dist/sentences.d.ts +0 -21
- package/dist/sentences.js +0 -142
- package/dist/transport.js +0 -223
- package/vendor/LICENSE.blingfire +0 -21
- package/vendor/README.md +0 -11
- package/vendor/blingfire.cjs +0 -4
- package/vendor/blingfire.upstream.cjs +0 -1
- package/vendor/blingfire.wasm +0 -0
- /package/dist/{queue.d.ts → tts/queue.d.ts} +0 -0
- /package/dist/{queue.js → tts/queue.js} +0 -0
package/docs/realtime.md
ADDED
|
@@ -0,0 +1,537 @@
|
|
|
1
|
+
# Realtime / Prism for Node.js
|
|
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
|
+
|
|
6
|
+
Keep one event consumer running while your application sends input, runs tools,
|
|
7
|
+
and plays audio. The SDK manages the protocol state. Your application owns
|
|
8
|
+
microphone capture, tool execution, and playback.
|
|
9
|
+
|
|
10
|
+
Start with the [recorded-speech quick start](../README.md#prism-send-recorded-speech)
|
|
11
|
+
to save a spoken reply without audio hardware.
|
|
12
|
+
|
|
13
|
+
For live conversations, keep the session open after a response is cancelled.
|
|
14
|
+
Report playback from the output clock. Saving a file is not playback.
|
|
15
|
+
Typed turns also support mixed text and voice applications.
|
|
16
|
+
|
|
17
|
+
## Optional conversation runner
|
|
18
|
+
|
|
19
|
+
Use `runConversation` to connect your audio adapters once. It sends input,
|
|
20
|
+
queues output, handles interruption, reports measured playback, and stops its
|
|
21
|
+
operations when the conversation ends. The direct session methods remain available.
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { Rime, runConversation } from "@rimelabs/sdk";
|
|
25
|
+
|
|
26
|
+
const client = new Rime();
|
|
27
|
+
const controller = new AbortController();
|
|
28
|
+
try {
|
|
29
|
+
const session = await client.realtime.connect();
|
|
30
|
+
// microphone and speaker are adapters owned by your application.
|
|
31
|
+
await runConversation(session, {
|
|
32
|
+
source: microphone,
|
|
33
|
+
playback: speaker,
|
|
34
|
+
onEvent(event) {
|
|
35
|
+
if (event.payload.kind === "transcript.final")
|
|
36
|
+
console.log(event.payload.text);
|
|
37
|
+
},
|
|
38
|
+
signal: controller.signal,
|
|
39
|
+
});
|
|
40
|
+
} finally {
|
|
41
|
+
await client.close();
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The input adapter implements `ConversationSource`.
|
|
46
|
+
`read(signal: AbortSignal): Promise<AudioChunk | null>` returns one chunk,
|
|
47
|
+
with an optional format, or `null` at EOF. An omitted format uses 16 kHz mono
|
|
48
|
+
PCM16. Abort must reject and release a pending
|
|
49
|
+
read. The runner awaits each `session.sendAudio` call before reading again. It
|
|
50
|
+
uses the session's existing PCM conversion and transport backpressure. Input
|
|
51
|
+
continues during output playback.
|
|
52
|
+
|
|
53
|
+
The playback adapter implements `ConversationPlayback`:
|
|
54
|
+
|
|
55
|
+
| Method | Contract |
|
|
56
|
+
| --- | --- |
|
|
57
|
+
| `open(output: OutputRef): ConversationOutput` | Queue this output after previously opened outputs. It can be opened before the first audio chunk. |
|
|
58
|
+
| `interrupt(outputs: readonly OutputRef[]): void` | Stop the selected outputs as one batch, discard their unplayed audio, then resume remaining output in queue order. |
|
|
59
|
+
| `stop(signal: AbortSignal): Promise<void>` | Confirm all playback has stopped and queued audio is discarded. Keep caller-owned resources open. |
|
|
60
|
+
|
|
61
|
+
Each `ConversationOutput` implements:
|
|
62
|
+
|
|
63
|
+
| Method | Contract |
|
|
64
|
+
| --- | --- |
|
|
65
|
+
| `write(chunk: AudioChunk): void` | Queue 24 kHz mono PCM16 without blocking. Bound the queue and throw on overflow. |
|
|
66
|
+
| `end(): void` | Accept no more audio. Let queued and device audio drain. |
|
|
67
|
+
| `completion(signal: AbortSignal): Promise<number>` | Return actual played milliseconds after drain or interruption. Reject if measurement fails or the signal aborts. |
|
|
68
|
+
|
|
69
|
+
All synchronous adapter methods must return promptly. Completion can be awaited
|
|
70
|
+
before `end()`. Keep receipts separate for each `OutputRef`, even when a new
|
|
71
|
+
response starts before an old receipt completes. Play outputs in the order they
|
|
72
|
+
were opened, using one FIFO audio queue. Do not mix outputs, interleave their
|
|
73
|
+
audio, or play later outputs before earlier outputs finish or are interrupted.
|
|
74
|
+
Prism assumes that interrupting a partially played reply leaves later replies
|
|
75
|
+
in the same turn unheard. Independent concurrent playback violates that assumption.
|
|
76
|
+
The runner passes all affected output references in one `interrupt` call. Stop
|
|
77
|
+
them and discard their queued audio before starting any remaining output. Then
|
|
78
|
+
resume valid output in queue order, without waiting for another chunk or event.
|
|
79
|
+
Interruption must work after `end()` and tolerate repeated calls. A remote
|
|
80
|
+
adapter must preserve the batch, for example with one message containing all
|
|
81
|
+
selected output IDs. Shutdown stops all output and must not resume playback.
|
|
82
|
+
Receipt delivery can be delayed or arrive out of order; audible playback cannot.
|
|
83
|
+
A receipt includes the device buffer where device timing is available. Bytes
|
|
84
|
+
received or queued do not measure playback. Zero is valid for an output that
|
|
85
|
+
played no audio.
|
|
86
|
+
|
|
87
|
+
Abort must release each pending adapter operation and remove its listeners.
|
|
88
|
+
Cancellation of a completion wait must not cancel the device receipt. The runner
|
|
89
|
+
stops input, event processing, and report submission on exit. It then awaits
|
|
90
|
+
`stop(signal)` before aborting remaining receipt waits. The stop signal is
|
|
91
|
+
independent of caller cancellation and has a five-second deadline. `stop` must
|
|
92
|
+
resolve only after local or remote playback has stopped, including device
|
|
93
|
+
buffers. Sending a stop command is not confirmation. It must reject and release
|
|
94
|
+
its wait when the stop signal aborts. The runner awaits this cancellation cleanup
|
|
95
|
+
before it returns, so cleanup can extend beyond the deadline. A missing confirmation raises
|
|
96
|
+
`RimeTimeoutError`; disconnects and other shutdown failures must reject too.
|
|
97
|
+
The caller opens and closes the adapter resources. The runner does not open
|
|
98
|
+
audio devices or host a browser.
|
|
99
|
+
|
|
100
|
+
`onEvent` is optional. It receives every event read from `session.events`, in
|
|
101
|
+
order, after the runner applies audio coordination. It must be synchronous and
|
|
102
|
+
nonblocking. Returning a promise is rejected. Callback exceptions reach the
|
|
103
|
+
caller. The callback can schedule application work. Continue to use
|
|
104
|
+
`submitToolResult` and `continueReply`; the runner neither registers nor executes
|
|
105
|
+
tools. The application must cancel and await its own tool tasks. Response
|
|
106
|
+
failures and nonterminal faults are forwarded for application handling. Session
|
|
107
|
+
failures reject the runner promise.
|
|
108
|
+
|
|
109
|
+
The runner is the only event reader. Do not consume `session.events` at the same
|
|
110
|
+
time, call `reportPlayback` independently, or send a second audio source. Other
|
|
111
|
+
session methods remain available for manual tools and application actions.
|
|
112
|
+
|
|
113
|
+
On confirmed `speech.started`, the runner uses the interruption setting of the
|
|
114
|
+
latest reply that is still generating or has unmeasured physical playback. It
|
|
115
|
+
resolves that setting from the reply's revision when the session receives the
|
|
116
|
+
reply. Updates and late event consumption cannot change it. If interruption is
|
|
117
|
+
enabled, the runner stops affected output, waits for the interrupted receipt,
|
|
118
|
+
and reports the measured position. It ignores late audio for that response.
|
|
119
|
+
A `speech.hint` alone does not stop playback. A server
|
|
120
|
+
`truncate_not_current` refusal is forwarded as an event; it does not stop a newer
|
|
121
|
+
response. Finished reports wait for generation completion and every output
|
|
122
|
+
receipt, including outstanding playback from earlier responses. Prism treats
|
|
123
|
+
the latest drain token as confirmation that all earlier playback has stopped.
|
|
124
|
+
An abandoned response also stops its dependent tool continuations, identified
|
|
125
|
+
by response parent references. Unrelated later turns remain eligible to play.
|
|
126
|
+
Late audio from an interrupted response or its continuations is discarded.
|
|
127
|
+
The runner retains at most 128 response parent references.
|
|
128
|
+
A report retains the measured duration of its own response. Waiting for earlier
|
|
129
|
+
playback does not block events or input, and does not wait for later responses.
|
|
130
|
+
|
|
131
|
+
Once called, the runner owns the session's active lifetime. Input EOF, explicit
|
|
132
|
+
session closure, abort, or failure stops all runner operations and closes the
|
|
133
|
+
session. EOF stops remaining playback and waits for shutdown confirmation.
|
|
134
|
+
Abort, including an abort received during cleanup, waits for playback shutdown
|
|
135
|
+
confirmation or its five-second deadline, then awaits adapter cancellation cleanup
|
|
136
|
+
before rejecting with `signal.reason`.
|
|
137
|
+
Explicit session closure ends normally even with playback reports pending;
|
|
138
|
+
remote connection failures reject with the session error.
|
|
139
|
+
Expected cancellation errors during cleanup are ignored. Other cleanup errors
|
|
140
|
+
reach the caller if there is no original failure. They do not replace an
|
|
141
|
+
existing failure or caller abort. The signal is optional. Use
|
|
142
|
+
an application deadline if an adapter can wait indefinitely.
|
|
143
|
+
|
|
144
|
+
The runner adds no input or callback queue. It retains at most 64 responses,
|
|
145
|
+
128 output streams, and 256 pending operations. Exceeding a limit throws
|
|
146
|
+
`RimeResourceLimitError`. The adapters must also bound their audio queues.
|
|
147
|
+
|
|
148
|
+
The [live voice example](https://github.com/rimelabs/rime-sdk/blob/main/typescript/examples/realtime/conversation.ts) supplies the
|
|
149
|
+
[browser audio adapter](https://github.com/rimelabs/rime-sdk/blob/main/typescript/examples/common/browser-audio.ts). Browser hosting
|
|
150
|
+
stays in the example. Its player uses `AudioContext.getOutputTimestamp()` for
|
|
151
|
+
receipts and shutdown confirmation. A disconnect cannot confirm a remote stop.
|
|
152
|
+
The [manual tool example](https://github.com/rimelabs/rime-sdk/blob/main/typescript/examples/realtime/manual-tools.ts) keeps
|
|
153
|
+
tool execution outside the runner.
|
|
154
|
+
|
|
155
|
+
## Connect
|
|
156
|
+
|
|
157
|
+
Use `await client.realtime.connect()` with `RIME_API_KEY` set. It opens a WebSocket,
|
|
158
|
+
initializes one conversation, and returns a `RealtimeSession`. Use
|
|
159
|
+
`session.update` to change instructions, tools, voice, or interruption.
|
|
160
|
+
Use `session.setResponseMetadata` to replace reply labels.
|
|
161
|
+
|
|
162
|
+
| Option | Required? | Default and behavior |
|
|
163
|
+
| --- | --- | --- |
|
|
164
|
+
| `endpoint` | No | Defaults to `wss://prism.api.rime.ai/v1/realtime`. Overrides must be full URLs; plain `ws://` is allowed only for localhost. |
|
|
165
|
+
| `voice` | If the server has no default voice | Omitted or `null` uses the server default. Supplied strings must be nonblank. |
|
|
166
|
+
| `instructions` | No | Omitted or `null` uses server defaults. Supplied strings must be nonblank. |
|
|
167
|
+
| `tools` | No | `[]`. Each tool requires `name` and a JSON Schema `parameters` object. `description` defaults to `""`. |
|
|
168
|
+
| `interruptOnSpeech` | No | `true`. Requests interruption when the server confirms user speech. |
|
|
169
|
+
| `turnDetection` | No | Omitted settings use the server's turn timing defaults. |
|
|
170
|
+
| `timeouts` | No | `{ connectS: 10, readyS: 30, requestS: 10 }`. Each field is optional. Units are seconds. |
|
|
171
|
+
| `model` | No | `"prism"`, the only accepted value. |
|
|
172
|
+
| `requestId` | No | Your id for the session. Sent as `x-request-id`. It must be nonblank printable ASCII, or the SDK throws `RimeInputError`. Prism uses it if it is at most 128 characters, else makes its own. |
|
|
173
|
+
| `responseMetadata` | No | Labels every reply carries in `response.started.metadata`, such as `{ step: "3" }`: up to 16 strings, keys up to 64 characters and values up to 512, no key starting with `prism_`. Prism refuses labels that break these limits, or keys starting with `prism_`, with `RimeRealtimeError` code `invalid_session`. |
|
|
174
|
+
| `signal` | No | An `AbortSignal` that cancels connection setup. It does not cancel an established session. |
|
|
175
|
+
|
|
176
|
+
Credentials come from `new Rime({ apiKey: "..." })` or `RIME_API_KEY`. Prism uses
|
|
177
|
+
`Authorization: Bearer <key>`, without a TTS token exchange. TTS endpoint, model,
|
|
178
|
+
voice, and timeout settings do not apply to Realtime.
|
|
179
|
+
|
|
180
|
+
After connection, `session.info` contains `sessionId`, `requestId`, `model`,
|
|
181
|
+
`voice`, `interruptOnSpeech`, `turnDetection`, `responseMetadata`,
|
|
182
|
+
`toolResultTimeoutS`, and `toolContinuationTimeoutS`. `requestId` is the id
|
|
183
|
+
Prism's logs use; include it when you report a problem. It is `null` on servers
|
|
184
|
+
that do not send it. An event's or error's `requestId` names the SDK request
|
|
185
|
+
that caused it instead.
|
|
186
|
+
Check the effective interruption setting there. Tool wait durations are total
|
|
187
|
+
server deadlines, not remaining time. A `null` duration can mean an omitted
|
|
188
|
+
field; it does not prove that no deadline exists.
|
|
189
|
+
|
|
190
|
+
Close the session in `finally` with `await session.close()`. Closing the parent
|
|
191
|
+
client closes all its TTS and Realtime operations. Both objects also support
|
|
192
|
+
`Symbol.asyncDispose`. Repeated close calls are safe.
|
|
193
|
+
|
|
194
|
+
## Optional turn timing
|
|
195
|
+
|
|
196
|
+
Pass a `TurnDetection` object to override how readily Prism ends a spoken turn.
|
|
197
|
+
Each field is optional; omitted fields use server defaults.
|
|
198
|
+
|
|
199
|
+
| Field | Values | Current server default |
|
|
200
|
+
| --- | --- | --- |
|
|
201
|
+
| `eagerness` | `"low"`, `"medium"`, `"high"`, `"auto"` | `"auto"`, equivalent to `"medium"` |
|
|
202
|
+
| `endOfTurnTimeoutMs` | Integer from 1,000 through 10,000 | 5,000 ms |
|
|
203
|
+
|
|
204
|
+
`"low"` waits for more certainty that the user has finished. `"high"` answers
|
|
205
|
+
sooner, with more risk of cutting in. The timeout is a maximum silence limit,
|
|
206
|
+
not a fixed delay before each reply. If the server falls back to its local
|
|
207
|
+
voice activity detector, it ends turns after 500 ms of silence instead.
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
const session = await client.realtime.connect({
|
|
211
|
+
turnDetection: { eagerness: "low", endOfTurnTimeoutMs: 5000 },
|
|
212
|
+
});
|
|
213
|
+
try {
|
|
214
|
+
console.log(session.info.turnDetection);
|
|
215
|
+
// Send input and consume session.events here.
|
|
216
|
+
} finally {
|
|
217
|
+
await session.close();
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
`session.info.turnDetection` is a `TurnDetectionInfo` with the settings the
|
|
222
|
+
server reported in its initialization acknowledgment. A missing field is
|
|
223
|
+
`null`; the SDK does not substitute a requested value or assume a server
|
|
224
|
+
default. An unrecognized server eagerness becomes `"unknown"`.
|
|
225
|
+
`interruptOnSpeech` remains a separate connection option.
|
|
226
|
+
|
|
227
|
+
## Update session settings
|
|
228
|
+
|
|
229
|
+
This method is available in the repository source and requires an SDK release
|
|
230
|
+
that includes session updates.
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
const info = await session.update({
|
|
234
|
+
instructions: "Handle billing. Use only the supplied tools.",
|
|
235
|
+
tools: [refundTool], // An existing ToolDefinition.
|
|
236
|
+
});
|
|
237
|
+
console.log(info.settingsRevision);
|
|
238
|
+
|
|
239
|
+
// For a transfer triggered by a tool call:
|
|
240
|
+
await session.submitToolResult(call, "Transferred to billing.");
|
|
241
|
+
await session.continueReply(parent);
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
`RealtimeUpdateOptions` has optional `instructions`, `tools`, `voice`,
|
|
245
|
+
`interruptOnSpeech`, and `signal` fields. Omitted fields and `undefined` keep
|
|
246
|
+
their values. `null` is not accepted.
|
|
247
|
+
|
|
248
|
+
Omitted fields keep their values. A supplied tool list replaces the complete
|
|
249
|
+
list. Empty instructions clear the prompt; an empty tool list removes all tools.
|
|
250
|
+
An empty voice selects the deployment default. Instructions and tools supplied
|
|
251
|
+
together change in one request.
|
|
252
|
+
|
|
253
|
+
The method waits for the matching `session.updated` acknowledgment and returns
|
|
254
|
+
session information. The stored session information changes only after that
|
|
255
|
+
acknowledgment. A rejected update leaves it unchanged and keeps the connection
|
|
256
|
+
open. Cancellation after submission does not undo an accepted update.
|
|
257
|
+
|
|
258
|
+
Updates do not wait for turn readiness or tool results. Each reply keeps the
|
|
259
|
+
settings it began with. A reply prepared on an early turn-end guess can be
|
|
260
|
+
announced after an update but still use the previous settings revision.
|
|
261
|
+
Modalities, eagerness, and the end-of-turn timeout cannot change mid-session.
|
|
262
|
+
|
|
263
|
+
`SessionInfo`, `ResponseStarted`, and `ResponseEnded` expose `settingsRevision`.
|
|
264
|
+
It is `null` when the server does not publish it. The field is optional on
|
|
265
|
+
caller-created values. Users do not need to manage it. Use each reply's revision
|
|
266
|
+
to identify its settings, rather than the latest session revision.
|
|
267
|
+
|
|
268
|
+
## Choose an operation
|
|
269
|
+
|
|
270
|
+
Every method returns a promise. Arguments without `?` are required.
|
|
271
|
+
|
|
272
|
+
| Method | Result and behavior |
|
|
273
|
+
| --- | --- |
|
|
274
|
+
| `update(options?)` | Changes supplied settings without reconnecting; returns `SessionInfo` after acknowledgment. |
|
|
275
|
+
| `sendText(text, options?)` | Starts a typed user turn after readiness; returns `ResponseRef` at response creation. |
|
|
276
|
+
| `sendAudio(chunk, options?)` | Sends microphone audio with transport backpressure. |
|
|
277
|
+
| `requestReply(options?)` | Requests a reply without new user input; returns `ResponseRef`. Options can include `instruction` and `toolCall`. |
|
|
278
|
+
| `addMessage(role, text, options?)` | Adds user or assistant history without a reply; returns `ItemRef` after acknowledgment. |
|
|
279
|
+
| `submitToolResult(call, output, options?)` | Records a string result and waits for acknowledgment. |
|
|
280
|
+
| `continueReply(parent, options?)` | Waits for parent completion and all tool result acknowledgments, then returns a new `ResponseRef`. |
|
|
281
|
+
| `cancel(response, options?)` | Requests generation cancellation and waits for a terminal response or refusal. |
|
|
282
|
+
| `clearAudio(options?)` | Clears buffered input and resets audio conversion after acknowledgment. |
|
|
283
|
+
| `setResponseMetadata(metadata, options?)` | Replaces the labels for later replies once Prism confirms. |
|
|
284
|
+
| `reportPlayback(report, options?)` | Reports interrupted or finished playback. |
|
|
285
|
+
| `close()` | Closes the session and releases its resources. |
|
|
286
|
+
|
|
287
|
+
Operation options accept `signal?: AbortSignal`. `requestReply` accepts its
|
|
288
|
+
instruction, tool call, and signal in one object. Methods other than `update`,
|
|
289
|
+
`sendText`, `requestReply`, `addMessage`, and `continueReply` return `Promise<void>`.
|
|
290
|
+
|
|
291
|
+
Text must be nonblank and contain at most 4,000 Unicode characters. History
|
|
292
|
+
roles are `"user"` and `"assistant"`. A reply instruction applies to one response;
|
|
293
|
+
it does not replace session instructions.
|
|
294
|
+
|
|
295
|
+
A returned `ResponseRef` means generation started. Read `response.ended` for the
|
|
296
|
+
terminal status. Generation can finish before cancellation takes effect, so a
|
|
297
|
+
successful `cancel()` does not guarantee a `"cancelled"` status.
|
|
298
|
+
|
|
299
|
+
## Send audio
|
|
300
|
+
|
|
301
|
+
Pass a plain object with `data: Uint8Array`. Node.js `Buffer` is also accepted.
|
|
302
|
+
The optional `format` object defaults to 16 kHz mono signed little-endian PCM16.
|
|
303
|
+
|
|
304
|
+
```typescript
|
|
305
|
+
await session.sendAudio({
|
|
306
|
+
data: pcmBytes,
|
|
307
|
+
format: { sampleRate: 48000, channels: 2 },
|
|
308
|
+
});
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Supported `sampleRate` values are `8000`, `16000`, `24000`, and `48000`.
|
|
312
|
+
Channels can be `1` or `2`; `encoding` can only be `"pcm_s16le"`. Each field in
|
|
313
|
+
`format` is optional. Chunks must contain complete sample frames and at most
|
|
314
|
+
192,000 bytes. The SDK downmixes and resamples to 16 kHz mono, retaining state
|
|
315
|
+
across calls. A format change or acknowledged `clearAudio()` resets that state.
|
|
316
|
+
|
|
317
|
+
Await each send and bound your capture queue. Keep audio flowing, including
|
|
318
|
+
silence and while the assistant speaks or tools run. Prism detects and commits
|
|
319
|
+
speech; there is no manual commit method. Echo cancellation belongs to your app.
|
|
320
|
+
|
|
321
|
+
Received `audio.delta` events carry 24 kHz mono PCM16. The outgoing chunk limit
|
|
322
|
+
does not apply to received audio.
|
|
323
|
+
|
|
324
|
+
## Handle tools
|
|
325
|
+
|
|
326
|
+
Declare tools with plain `ToolDefinition` objects. Names must be nonblank and
|
|
327
|
+
unique; schemas must contain finite JSON values. The SDK copies schemas before
|
|
328
|
+
connection setup, so later caller changes cannot alter initialization.
|
|
329
|
+
|
|
330
|
+
Set `prismFiller` to control what Prism says while the tool runs:
|
|
331
|
+
|
|
332
|
+
```ts
|
|
333
|
+
import type { ToolDefinition } from "@rimelabs/sdk";
|
|
334
|
+
|
|
335
|
+
const pressDigits: ToolDefinition = {
|
|
336
|
+
name: "press_digits",
|
|
337
|
+
parameters: { type: "object", properties: { digits: { type: "string" } } },
|
|
338
|
+
prismFiller: { type: "none" },
|
|
339
|
+
};
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
| Setting | Behavior |
|
|
343
|
+
| --- | --- |
|
|
344
|
+
| Omitted | Use the server default, currently `auto`. |
|
|
345
|
+
| `{ type: "none" }` | Suppress filler for this tool. |
|
|
346
|
+
| `{ type: "text", text: "One moment." }` | Speak the supplied text. |
|
|
347
|
+
| `{ type: "auto" }` | Let Prism write a line from the tool description. |
|
|
348
|
+
| `{ type: "auto", instructions: "Say you are checking the order." }` | Guide the generated line. |
|
|
349
|
+
|
|
350
|
+
Text and instructions must be valid UTF-8, contain at most 500 Unicode scalar
|
|
351
|
+
values, and contain a character outside the Unicode `White_Space` set. This
|
|
352
|
+
matches the engine's validation. The SDK preserves the supplied text and copies
|
|
353
|
+
filler settings before connection setup. Invalid settings raise `RimeInputError` before opening a
|
|
354
|
+
connection, including for JavaScript callers. The exported `PrismFiller` union
|
|
355
|
+
also checks TypeScript callers.
|
|
356
|
+
|
|
357
|
+
Filler applies when the reply has said nothing before calling a tool. If a reply
|
|
358
|
+
calls several tools, the first call's tool controls the filler. `none` suppresses
|
|
359
|
+
filler only; it does not silence other speech. Use `session.update({ tools })` to replace tools and their filler settings.
|
|
360
|
+
|
|
361
|
+
Execute a tool once for each `tool.call` event. Validate its parsed `arguments`,
|
|
362
|
+
then submit a string result with `submitToolResult(payload.call, output)`.
|
|
363
|
+
Use `JSON.stringify(...)` for a structured result. Call
|
|
364
|
+
`continueReply(payload.call)` when the assistant should answer; a tool call
|
|
365
|
+
reference also carries its parent response identity.
|
|
366
|
+
|
|
367
|
+
Keep the event consumer running while submitting tool results and requesting
|
|
368
|
+
continuation. Run slow tools asynchronously or in a worker so they do not block
|
|
369
|
+
the event loop.
|
|
370
|
+
|
|
371
|
+
A new user turn or proactive reply supersedes the old tool round. Late results
|
|
372
|
+
can still be recorded. Use `requestReply({ toolCall: call })` to ask the assistant
|
|
373
|
+
to report a recorded result. Repeating the same result is safe within the live
|
|
374
|
+
session; changing it is rejected. Do not rerun a tool because delivery failed.
|
|
375
|
+
|
|
376
|
+
## Read events and references
|
|
377
|
+
|
|
378
|
+
Use `for await (const event of session.events)`. Each `SessionEvent` has
|
|
379
|
+
`sessionId`, `eventId`, nullable `requestId`, and a `payload`. Switch on
|
|
380
|
+
`payload.kind` to narrow the TypeScript union. All public types and error classes
|
|
381
|
+
are exported from `@rimelabs/sdk`.
|
|
382
|
+
|
|
383
|
+
| Kind | Payload fields |
|
|
384
|
+
| --- | --- |
|
|
385
|
+
| `input.ready` | No data fields. Turn methods handle the readiness wait. |
|
|
386
|
+
| `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. |
|
|
387
|
+
| `speech.started` | `itemId`, `audioStartMs` |
|
|
388
|
+
| `speech.stopped` | `itemId`, `audioEndMs`, `endReason`: what ended the turn (`semantic`, `timeout`, `silence`, `max_duration` or `detector_changed`), `unknown` for a newer value, or null from a server that does not send it |
|
|
389
|
+
| `input.committed` | `itemId` |
|
|
390
|
+
| `transcript.delta`, `transcript.final` | `itemId` and `delta` or `text` |
|
|
391
|
+
| `transcript.failed` | `itemId`, `error` |
|
|
392
|
+
| `response.started` | `response`, `cause`, nullable `parent` and `inputItemId`, `inputItemIds` (the user items it answers), `metadata` (your own keys) |
|
|
393
|
+
| `message.started` | `output` |
|
|
394
|
+
| `text.delta`, `text.done` | `output` and `delta` or `text` |
|
|
395
|
+
| `audio.delta`, `audio.done` | `output`; a delta also has `audio.data` and a complete `audio.format` |
|
|
396
|
+
| `tool.call` | `call`, `itemId`, `name`, parsed `arguments` |
|
|
397
|
+
| `response.ended` | `response`, `status`, nullable `reason` |
|
|
398
|
+
| `response.abandoned` | `response`; the SDK requests cancellation after the requesting caller aborted. |
|
|
399
|
+
| `error` | `error`, a `RealtimeFault` |
|
|
400
|
+
|
|
401
|
+
References come from the SDK. Pass them back to identify the object you mean.
|
|
402
|
+
|
|
403
|
+
| Reference | Fields |
|
|
404
|
+
| --- | --- |
|
|
405
|
+
| `ResponseRef` | `sessionId`, `responseId` |
|
|
406
|
+
| `ItemRef` | `sessionId`, `itemId` |
|
|
407
|
+
| `ToolCallRef` | `sessionId`, `responseId`, `callId` |
|
|
408
|
+
| `OutputRef` | `response`, `itemId`, `outputIndex`, `contentIndex` |
|
|
409
|
+
|
|
410
|
+
Every reference belongs to one session. Only the last 128 responses are retained;
|
|
411
|
+
older references expire. Current output uses `contentIndex: 0`.
|
|
412
|
+
|
|
413
|
+
Unknown event kinds and extra fields are ignored. Unknown response causes,
|
|
414
|
+
terminal statuses, and error scopes become `"unknown"`. An absent response cause
|
|
415
|
+
means speech. The local `response.abandoned` event has an empty `eventId` and
|
|
416
|
+
`requestId: null`; it can follow `response.ended` when completion races cancellation.
|
|
417
|
+
|
|
418
|
+
## Report playback
|
|
419
|
+
|
|
420
|
+
Generation completion and playback completion are separate. Report the player's
|
|
421
|
+
actual state, including output latency and queued audio.
|
|
422
|
+
|
|
423
|
+
| Report object | Required fields | Optional fields |
|
|
424
|
+
| --- | --- | --- |
|
|
425
|
+
| Interrupted | `kind: "interrupted"`, `output`, `audioEndMs` | None |
|
|
426
|
+
| Finished | `kind: "finished"`, `response` | `playedMs`, `audibleTailMs`; both default to `null` |
|
|
427
|
+
|
|
428
|
+
Pass the object to `await session.reportPlayback(report)`. Interruption records
|
|
429
|
+
the point where caller speech stopped an assistant message. `audioEndMs` must
|
|
430
|
+
be an integer from 0 through 4,294,967,295. Finished playback means all queued
|
|
431
|
+
audio has played or has permanently stopped. Optional durations must be finite,
|
|
432
|
+
nonnegative milliseconds. The SDK waits for generation completion and supplies
|
|
433
|
+
the server's drain token.
|
|
434
|
+
|
|
435
|
+
Saving audio does not establish playback. Reports are optional. If you cannot
|
|
436
|
+
measure playback, omit them and let the server use its estimate. The recorded and typed examples have no player and omit these reports.
|
|
437
|
+
The voice examples report actual playback.
|
|
438
|
+
|
|
439
|
+
## Timeouts and failures
|
|
440
|
+
|
|
441
|
+
Configure positive, finite seconds through `timeouts`. `connectS` bounds the
|
|
442
|
+
WebSocket handshake and initial session event. `readyS` bounds turn admission,
|
|
443
|
+
tool readiness, and waiting for generation to end before a playback report.
|
|
444
|
+
Once a request is submitted, `requestS` bounds its write and acknowledgment.
|
|
445
|
+
|
|
446
|
+
These limits do not bound the entire conversation or generation after creation.
|
|
447
|
+
Set an application deadline and close the session when it expires. The recorded and typed examples use a 60-second deadline. Voice conversations
|
|
448
|
+
run until stopped or the connection fails.
|
|
449
|
+
|
|
450
|
+
`RealtimeAdmissionTimeout` means readiness expired with no request outstanding;
|
|
451
|
+
the session remains usable. An unknown request outcome closes the connection and
|
|
452
|
+
is never replayed. The SDK retries typed-turn admission only after named refusals
|
|
453
|
+
that confirm the request made no change.
|
|
454
|
+
|
|
455
|
+
Protocol faults appear as `error` events and can also reject an affected method
|
|
456
|
+
with `RimeRealtimeError`. Its `.fault` has `code`, `message`, `scope`, nullable
|
|
457
|
+
`requestId`, `responseId`, `itemId`, `correlationId`, `parameter`, and a `callIds`
|
|
458
|
+
array. A response fault does not itself end generation. Session faults and lost
|
|
459
|
+
connections end the session.
|
|
460
|
+
|
|
461
|
+
`NormalizedRealtimeFault.retryable` reports whether the same request, unchanged,
|
|
462
|
+
may succeed on another attempt. Read `event.payload.error.retryable` on an `error`
|
|
463
|
+
event or `error.fault.retryable` on `RimeRealtimeError`. The SDK derives this
|
|
464
|
+
value from the code; Prism does not send a retry flag.
|
|
465
|
+
|
|
466
|
+
`RealtimeFault` accepts the previous fault shape, with an optional `retryable`
|
|
467
|
+
field, for caller-created faults. `RimeRealtimeError` accepts this shape and
|
|
468
|
+
ignores any supplied retry flag. Its `.fault` and SDK-emitted event faults are
|
|
469
|
+
`NormalizedRealtimeFault` values with a required boolean `retryable` field.
|
|
470
|
+
The SDK freezes these faults and their `callIds` arrays. Later changes to a
|
|
471
|
+
constructor input do not change the error's fault.
|
|
472
|
+
|
|
473
|
+
`TranscriptFailed`, `FaultEvent`, `InputEvent`, and `SessionEvent` default to
|
|
474
|
+
`RealtimeFault`, so existing event literals can omit `retryable`. These types
|
|
475
|
+
also accept a fault type parameter. `session.events` and the `runConversation`
|
|
476
|
+
event callback use `SessionEvent<NormalizedRealtimeFault>`, which gives their
|
|
477
|
+
faults a required boolean `retryable` field. An explicit `SessionEvent`
|
|
478
|
+
annotation uses the default type and makes `retryable` optional.
|
|
479
|
+
|
|
480
|
+
| Error code | `retryable` |
|
|
481
|
+
| --- | --- |
|
|
482
|
+
| `capacity_exceeded` | `true` |
|
|
483
|
+
| `unavailable` | `true` |
|
|
484
|
+
| `response_timeout` | `true` |
|
|
485
|
+
| `context_length_exceeded` | `false` |
|
|
486
|
+
| All other codes, including unknown codes | `false` |
|
|
487
|
+
|
|
488
|
+
The application chooses the delay, attempt limit, and recovery operation. This
|
|
489
|
+
value does not start a retry. It does not describe a local `RimeTimeoutError` or
|
|
490
|
+
prove that no output or side effect occurred. The SDK's existing readiness
|
|
491
|
+
retries have separate rules: an explicit refusal such as `typed_turn_busy`
|
|
492
|
+
permits another attempt after a new readiness event, although its `retryable`
|
|
493
|
+
value is `false` under this contract.
|
|
494
|
+
|
|
495
|
+
For example, Prism can accept a user's question and then report
|
|
496
|
+
`capacity_exceeded`. `sendText()` has already returned a `ResponseRef`; the
|
|
497
|
+
failure arrives through an `error` event. Wait for `response.ended`, then apply
|
|
498
|
+
the application's retry policy. If the question is already in history, use
|
|
499
|
+
`requestReply()` to ask for another reply when appropriate. Repeating
|
|
500
|
+
`sendText()` can add the question twice. A `response_timeout` can follow partial
|
|
501
|
+
text or audio, which the application must handle before another attempt.
|
|
502
|
+
|
|
503
|
+
For `context_length_exceeded`, the server message contains token counts.
|
|
504
|
+
Unchanged attempts will fail until the conversation is shorter. Start a new
|
|
505
|
+
session with shorter context. The protocol also supports history deletion, but
|
|
506
|
+
this SDK does not yet expose `conversation.item.delete`.
|
|
507
|
+
|
|
508
|
+
Malformed fields in known events and mismatched request acknowledgments close
|
|
509
|
+
the session with `RimeStreamError`. Unknown event kinds and extra fields remain
|
|
510
|
+
accepted and ignored. The SDK does not replay a request after a protocol failure.
|
|
511
|
+
|
|
512
|
+
Aborting an operation rejects it with `RimeCancelledError`. For reply requests,
|
|
513
|
+
the SDK prevents an unsent request or cancels a late accepted response. Control
|
|
514
|
+
operations can wait for acknowledgment before rejecting, to keep acknowledgment
|
|
515
|
+
matching correct. A submitted tool result keeps matching its acknowledgment even
|
|
516
|
+
if its caller aborts. Aborting audio after submission starts closes the session;
|
|
517
|
+
before submission, it restores conversion state. Do not resend a chunk with an
|
|
518
|
+
unknown outcome.
|
|
519
|
+
|
|
520
|
+
Keep up with the event stream. The queue holds 256 events; incoming messages
|
|
521
|
+
are limited to 1 MiB. A slow consumer ends the session. There is no automatic
|
|
522
|
+
reconnect or history replay.
|
|
523
|
+
|
|
524
|
+
Local peer tests cover the SDK protocol handling. Validate the gateway handshake
|
|
525
|
+
and endpoint behavior for the deployment you use.
|
|
526
|
+
|
|
527
|
+
The SDK retains the latest 128 interruption policy changes. Instructions or tools
|
|
528
|
+
updates that keep the same interruption policy do not consume this history.
|
|
529
|
+
If an unannounced reply refers to an older evicted policy, the session fails
|
|
530
|
+
with a resource limit error instead of guessing its policy. A reply already
|
|
531
|
+
received keeps its captured policy even after later settings updates.
|
|
532
|
+
|
|
533
|
+
If an interruption setting changes without a published revision, later reply
|
|
534
|
+
revisions can be ambiguous. The SDK preserves earlier known settings and raises
|
|
535
|
+
a resource limit error for an ambiguous reply instead of guessing. A later
|
|
536
|
+
acknowledgment with a revision establishes a new known setting. Replies without
|
|
537
|
+
a revision use the current acknowledged setting.
|