@rimelabs/sdk 0.1.0-alpha.16 → 0.1.0-alpha.17
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 +7 -0
- package/README.md +40 -1
- package/dist/client.d.ts +3 -1
- package/dist/client.js +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/stt/client.d.ts +6 -1
- package/dist/stt/client.js +69 -22
- package/dist/stt/transport.d.ts +3 -1
- package/dist/stt/transport.js +50 -3
- package/dist/stt/types.d.ts +8 -0
- package/docs/stt.md +40 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.0-alpha.17](https://github.com/rimelabs/rime-sdk/compare/typescript-v0.1.0-alpha.16...typescript-v0.1.0-alpha.17) (2026-10-16)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add unary STT transcription to all SDKs ([#80](https://github.com/rimelabs/rime-sdk/issues/80)) ([39427eb](https://github.com/rimelabs/rime-sdk/commit/39427eba7738e4f2fe0514a2cddaa219137dcc4d))
|
|
9
|
+
|
|
3
10
|
## [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
11
|
|
|
5
12
|
|
package/README.md
CHANGED
|
@@ -224,12 +224,51 @@ and model/language support.
|
|
|
224
224
|
|
|
225
225
|
## STT
|
|
226
226
|
|
|
227
|
+
### Transcribe a complete WAV recording
|
|
228
|
+
|
|
229
|
+
For a complete recording, use the native unary `Transcribe` RPC through the SDK.
|
|
230
|
+
Pass **complete WAV bytes, including the header**, up to **16 MiB (16,777,216
|
|
231
|
+
bytes)**. PCM16 mono 16 kHz WAV is the portable format. The SDK sends the file
|
|
232
|
+
unchanged; it does not decode, resample, or add a header. The service validates
|
|
233
|
+
its encoding and the supplied language and recognition hints.
|
|
234
|
+
|
|
235
|
+
The result is a `Transcription` containing final text, resolved language, and a
|
|
236
|
+
request ID when available. Silence may return empty text. There are no partial
|
|
237
|
+
updates or automatic retries. TTS client settings do not apply. An optional
|
|
238
|
+
overall timeout includes connection and upload; the SDK also bounds connection
|
|
239
|
+
time and the unary request (120 seconds). Timeout, cancellation, and service
|
|
240
|
+
errors use the existing SDK error categories. A request ID is included when the
|
|
241
|
+
transport has made it available.
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
import { readFile } from "node:fs/promises";
|
|
245
|
+
import { Rime } from "@rimelabs/sdk";
|
|
246
|
+
|
|
247
|
+
const client = new Rime();
|
|
248
|
+
try {
|
|
249
|
+
const result = await client.stt.transcribe(await readFile("utterance.wav"), {
|
|
250
|
+
language: "en",
|
|
251
|
+
mode: "written",
|
|
252
|
+
contextTerms: ["Super-G", "USOC"],
|
|
253
|
+
timeout: 120,
|
|
254
|
+
});
|
|
255
|
+
console.log(result.text, result.language, result.requestId);
|
|
256
|
+
} finally {
|
|
257
|
+
await client.close();
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
`TranscribeOptions` also accepts an `AbortSignal` as `signal`. Aborting it or
|
|
262
|
+
closing the client cancels pending requests with `RimeCancelledError`.
|
|
263
|
+
|
|
264
|
+
### Stream an utterance
|
|
265
|
+
|
|
227
266
|
Use `client.stt.stream(audioChunks, options)` to transcribe one utterance.
|
|
228
267
|
The required source is an async iterable of headerless signed PCM16 little-endian
|
|
229
268
|
`Uint8Array` chunks (`Buffer` also works). Ending the source ends the utterance;
|
|
230
269
|
your application decides when to stop.
|
|
231
270
|
|
|
232
|
-
STT uses
|
|
271
|
+
STT uses gRPC over TLS to `stt.api.rime.ai:443`, with the client's API
|
|
233
272
|
key. There is no STT model, endpoint, or protocol selector. TTS client settings,
|
|
234
273
|
including its timeout, do not apply to STT.
|
|
235
274
|
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AudioSource, TranscriptionOptions } from "./stt/types.js";
|
|
1
|
+
import type { AudioSource, TranscriptionOptions, TranscribeOptions, Transcription } from "./stt/types.js";
|
|
2
2
|
import type { TranscriptStream } from "./stt/stream.js";
|
|
3
3
|
import { type SynthesisOptions, type DiscoveryOptions, type VoiceListOptions } from "./tts/client.js";
|
|
4
4
|
import { type AudioStream, type TextSource } from "./tts/stream.js";
|
|
@@ -17,6 +17,8 @@ export declare class Rime {
|
|
|
17
17
|
private readonly ttsClient;
|
|
18
18
|
private readonly sttClient;
|
|
19
19
|
readonly stt: {
|
|
20
|
+
/** Transcribe complete WAV bytes. PCM16 mono 16 kHz is the portable format; maximum 16 MiB. */
|
|
21
|
+
transcribe: (audio: Uint8Array, options: TranscribeOptions) => Promise<Transcription>;
|
|
20
22
|
stream: (audio: AudioSource, options: TranscriptionOptions) => TranscriptStream;
|
|
21
23
|
};
|
|
22
24
|
private readonly realtimeClient;
|
package/dist/client.js
CHANGED
|
@@ -27,6 +27,7 @@ export class Rime {
|
|
|
27
27
|
this.credentials = new Credentials(key, deployment);
|
|
28
28
|
this.sttClient = new STT(this.credentials, () => this.checkOpen());
|
|
29
29
|
this.stt = {
|
|
30
|
+
transcribe: (audio, options) => this.sttClient.transcribe(audio, options),
|
|
30
31
|
stream: (audio, options) => this.sttClient.stream(audio, options),
|
|
31
32
|
};
|
|
32
33
|
this.realtimeClient = new Realtime(this.credentials, () => this.checkOpen());
|
package/dist/index.d.ts
CHANGED
|
@@ -7,4 +7,4 @@ export * from "./errors.js";
|
|
|
7
7
|
export { RealtimeSession } from "./realtime/session.js";
|
|
8
8
|
export * from "./realtime/types.js";
|
|
9
9
|
export { TranscriptStream } from "./stt/stream.js";
|
|
10
|
-
export type { AudioSource, TranscriptionOptions, TranscriptionMode, TranscriptionPartial, TranscriptionFinal, TranscriptionUpdate, } from "./stt/types.js";
|
|
10
|
+
export type { AudioSource, TranscribeOptions, Transcription, TranscriptionOptions, TranscriptionMode, TranscriptionPartial, TranscriptionFinal, TranscriptionUpdate, } from "./stt/types.js";
|
package/dist/stt/client.d.ts
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import { Credentials } from "../auth.js";
|
|
2
2
|
import { TranscriptStream } from "./stream.js";
|
|
3
|
-
import type { AudioSource, TranscriptionOptions } from "./types.js";
|
|
3
|
+
import type { AudioSource, TranscriptionOptions, TranscribeOptions, Transcription } from "./types.js";
|
|
4
4
|
export declare class STT {
|
|
5
5
|
private readonly credentials;
|
|
6
6
|
private readonly checkOpen;
|
|
7
7
|
private connection;
|
|
8
8
|
private streams;
|
|
9
|
+
private readonly cancellation;
|
|
10
|
+
private readonly requests;
|
|
9
11
|
constructor(credentials: Credentials, checkOpen: () => void);
|
|
12
|
+
/** Transcribe complete WAV bytes (at most 16 MiB), without replay or retries. */
|
|
13
|
+
transcribe(audio: Uint8Array, options: TranscribeOptions): Promise<Transcription>;
|
|
14
|
+
private prepare;
|
|
10
15
|
stream(source: AudioSource, options: TranscriptionOptions): TranscriptStream;
|
|
11
16
|
close(): Promise<void>;
|
|
12
17
|
}
|
package/dist/stt/client.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { connect, metadata } from "../grpc.js";
|
|
2
2
|
import { timeout } from "../validation.js";
|
|
3
|
-
import { RimeInputError } from "../errors.js";
|
|
3
|
+
import { RimeInputError, RimeAudioFormatError, RimeResourceLimitError, RimeCancelledError, RimeTimeoutError, } from "../errors.js";
|
|
4
|
+
import { scope } from "../cancellation.js";
|
|
4
5
|
import { resolvePCMFormat } from "../pcm.js";
|
|
5
|
-
import { transport, requireSchema } from "./transport.js";
|
|
6
|
+
import { transport, requireSchema, transcribe, MAX_WAV_BYTES, } from "./transport.js";
|
|
6
7
|
import { TranscriptStream } from "./stream.js";
|
|
7
8
|
import { policy } from "./policy.js";
|
|
8
9
|
export class STT {
|
|
@@ -10,40 +11,72 @@ export class STT {
|
|
|
10
11
|
checkOpen;
|
|
11
12
|
connection = null;
|
|
12
13
|
streams = new Set();
|
|
14
|
+
cancellation = new AbortController();
|
|
15
|
+
requests = new Set();
|
|
13
16
|
constructor(credentials, checkOpen) {
|
|
14
17
|
this.credentials = credentials;
|
|
15
18
|
this.checkOpen = checkOpen;
|
|
16
19
|
}
|
|
20
|
+
/** Transcribe complete WAV bytes (at most 16 MiB), without replay or retries. */
|
|
21
|
+
transcribe(audio, options) {
|
|
22
|
+
this.checkOpen();
|
|
23
|
+
if (!(audio instanceof Uint8Array) || audio.byteLength === 0)
|
|
24
|
+
throw new RimeAudioFormatError("audio must contain complete WAV bytes");
|
|
25
|
+
if (audio.byteLength > MAX_WAV_BYTES)
|
|
26
|
+
throw new RimeResourceLimitError("WAV input exceeds 16 MiB");
|
|
27
|
+
validateOptions(options);
|
|
28
|
+
const settings = {
|
|
29
|
+
...options,
|
|
30
|
+
contextTerms: [...(options.contextTerms ?? [])],
|
|
31
|
+
};
|
|
32
|
+
const data = Buffer.from(audio);
|
|
33
|
+
const deadline = scope([options.signal, this.cancellation.signal], timeout(options.timeout) ?? undefined, new RimeTimeoutError("Overall transcription deadline expired"));
|
|
34
|
+
const operation = (async () => {
|
|
35
|
+
try {
|
|
36
|
+
const prepared = await this.prepare(deadline.signal, policy.target);
|
|
37
|
+
return await transcribe(prepared.client, prepared.metadata, data, settings, deadline.signal);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
if (deadline.signal.aborted &&
|
|
41
|
+
!(error instanceof RimeTimeoutError) &&
|
|
42
|
+
!(error instanceof RimeCancelledError)) {
|
|
43
|
+
if (deadline.signal.reason instanceof RimeTimeoutError)
|
|
44
|
+
throw deadline.signal.reason;
|
|
45
|
+
throw new RimeCancelledError("Transcription cancelled");
|
|
46
|
+
}
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
deadline.dispose();
|
|
51
|
+
}
|
|
52
|
+
})();
|
|
53
|
+
this.requests.add(operation);
|
|
54
|
+
void operation.then(() => this.requests.delete(operation), () => this.requests.delete(operation));
|
|
55
|
+
return operation;
|
|
56
|
+
}
|
|
57
|
+
async prepare(signal, target) {
|
|
58
|
+
this.checkOpen();
|
|
59
|
+
requireSchema();
|
|
60
|
+
signal.throwIfAborted();
|
|
61
|
+
const headers = metadata(this.credentials.authorization());
|
|
62
|
+
this.connection ??= transport.makeClient(target);
|
|
63
|
+
await connect(this.connection, signal, policy.connectionTimeout);
|
|
64
|
+
signal.throwIfAborted();
|
|
65
|
+
return { client: this.connection, metadata: headers };
|
|
66
|
+
}
|
|
17
67
|
stream(source, options) {
|
|
18
68
|
this.checkOpen();
|
|
19
69
|
if (!source || typeof source[Symbol.asyncIterator] !== "function")
|
|
20
70
|
throw new RimeInputError("audio must be an async iterable of Uint8Array chunks");
|
|
21
|
-
|
|
22
|
-
throw new RimeInputError("language must be a string");
|
|
71
|
+
validateOptions(options);
|
|
23
72
|
const mode = options.mode ?? "written";
|
|
24
|
-
if (mode !== "written" && mode !== "verbatim")
|
|
25
|
-
throw new RimeInputError("mode must be written or verbatim");
|
|
26
73
|
const terms = options.contextTerms ?? [];
|
|
27
|
-
if (!Array.isArray(terms) || terms.some((term) => typeof term !== "string"))
|
|
28
|
-
throw new RimeInputError("contextTerms must be an array of strings");
|
|
29
74
|
const format = resolvePCMFormat(options.inputFormat);
|
|
30
75
|
const target = policy.target;
|
|
31
76
|
const stream = new TranscriptStream({
|
|
32
77
|
checkOpen: this.checkOpen,
|
|
33
78
|
forget: (stream) => this.streams.delete(stream),
|
|
34
|
-
prepare:
|
|
35
|
-
this.checkOpen();
|
|
36
|
-
requireSchema();
|
|
37
|
-
signal.throwIfAborted();
|
|
38
|
-
const headers = metadata(this.credentials.authorization());
|
|
39
|
-
this.connection ??= transport.makeClient(target);
|
|
40
|
-
await connect(this.connection, signal, policy.connectionTimeout);
|
|
41
|
-
signal.throwIfAborted();
|
|
42
|
-
return {
|
|
43
|
-
client: this.connection,
|
|
44
|
-
metadata: headers,
|
|
45
|
-
};
|
|
46
|
-
},
|
|
79
|
+
prepare: (signal) => this.prepare(signal, target),
|
|
47
80
|
}, source, {
|
|
48
81
|
language: options.language,
|
|
49
82
|
mode,
|
|
@@ -56,8 +89,12 @@ export class STT {
|
|
|
56
89
|
return stream;
|
|
57
90
|
}
|
|
58
91
|
async close() {
|
|
92
|
+
this.cancellation.abort(new RimeCancelledError("Client closed"));
|
|
59
93
|
try {
|
|
60
|
-
const results = await Promise.allSettled([
|
|
94
|
+
const results = await Promise.allSettled([
|
|
95
|
+
...[...this.streams].map((stream) => stream.cancel()),
|
|
96
|
+
...[...this.requests].map((request) => request.catch(() => { })),
|
|
97
|
+
]);
|
|
61
98
|
for (const result of results)
|
|
62
99
|
if (result.status === "rejected")
|
|
63
100
|
throw result.reason;
|
|
@@ -67,3 +104,13 @@ export class STT {
|
|
|
67
104
|
}
|
|
68
105
|
}
|
|
69
106
|
}
|
|
107
|
+
function validateOptions(options) {
|
|
108
|
+
if (!options || typeof options.language !== "string")
|
|
109
|
+
throw new RimeInputError("language must be a string");
|
|
110
|
+
const mode = options.mode ?? "written";
|
|
111
|
+
if (mode !== "written" && mode !== "verbatim")
|
|
112
|
+
throw new RimeInputError("mode must be written or verbatim");
|
|
113
|
+
const terms = options.contextTerms ?? [];
|
|
114
|
+
if (!Array.isArray(terms) || terms.some((term) => typeof term !== "string"))
|
|
115
|
+
throw new RimeInputError("contextTerms must be an array of strings");
|
|
116
|
+
}
|
package/dist/stt/transport.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import * as grpc from "@grpc/grpc-js";
|
|
2
2
|
import * as schema from "@rimelabs/api";
|
|
3
3
|
import { BidiCall } from "../grpc.js";
|
|
4
|
-
import type { TranscriptionMode } from "./types.js";
|
|
4
|
+
import type { TranscriptionMode, TranscribeOptions, Transcription } from "./types.js";
|
|
5
|
+
export declare const MAX_WAV_BYTES: number;
|
|
5
6
|
export declare function requireSchema(): void;
|
|
6
7
|
export declare const transport: {
|
|
7
8
|
makeClient: (target: string) => grpc.Client;
|
|
8
9
|
};
|
|
10
|
+
export declare function transcribe(client: grpc.Client, auth: grpc.Metadata, audio: Uint8Array, options: TranscribeOptions, signal: AbortSignal): Promise<Transcription>;
|
|
9
11
|
export declare class TranscriptionCall extends BidiCall<schema.StreamingTranscriptionRequest, schema.StreamingTranscriptionResponse> {
|
|
10
12
|
constructor(client: grpc.Client, auth: grpc.Metadata, signal: AbortSignal);
|
|
11
13
|
start(language: string, mode: TranscriptionMode, contextTerms: readonly string[]): Promise<void>;
|
package/dist/stt/transport.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import * as grpc from "@grpc/grpc-js";
|
|
2
2
|
import { create } from "@bufbuild/protobuf";
|
|
3
3
|
import * as schema from "@rimelabs/api";
|
|
4
|
-
import { BidiCall, serializer, deserializer } from "../grpc.js";
|
|
5
|
-
import {
|
|
4
|
+
import { BidiCall, serializer, deserializer, requestId, nativeError, } from "../grpc.js";
|
|
5
|
+
import { abortable, scope } from "../cancellation.js";
|
|
6
|
+
import { RimeInputError, RimeStreamError, RimeResourceLimitError, RimeTimeoutError, RimeCancelledError, } from "../errors.js";
|
|
6
7
|
import { policy } from "./policy.js";
|
|
8
|
+
export const MAX_WAV_BYTES = 16 * 1024 * 1024;
|
|
7
9
|
export function requireSchema() {
|
|
8
10
|
if (!schema.SpeechToText)
|
|
9
11
|
throw new RimeInputError("STT requires @rimelabs/api with SpeechToText definitions");
|
|
@@ -12,9 +14,54 @@ export const transport = {
|
|
|
12
14
|
makeClient: (target) => new grpc.Client(target, grpc.credentials.createSsl(), {
|
|
13
15
|
"grpc.enable_retries": 0,
|
|
14
16
|
"grpc.max_receive_message_length": policy.receiveBytes,
|
|
15
|
-
"grpc.max_send_message_length":
|
|
17
|
+
"grpc.max_send_message_length": MAX_WAV_BYTES + 65536,
|
|
16
18
|
}),
|
|
17
19
|
};
|
|
20
|
+
export async function transcribe(client, auth, audio, options, signal) {
|
|
21
|
+
const method = schema.SpeechToText.method.transcribe;
|
|
22
|
+
const deadline = scope([signal], policy.completionTimeout, new RimeTimeoutError("Transcription request timed out"));
|
|
23
|
+
let call;
|
|
24
|
+
let id = null;
|
|
25
|
+
try {
|
|
26
|
+
deadline.signal.throwIfAborted();
|
|
27
|
+
const result = await abortable(new Promise((resolve, reject) => {
|
|
28
|
+
call = client.makeUnaryRequest(`/${schema.SpeechToText.typeName}/${method.name}`, serializer(method.input), deserializer(method.output), create(method.input, {
|
|
29
|
+
audio,
|
|
30
|
+
options: {
|
|
31
|
+
language: options.language,
|
|
32
|
+
mode: options.mode === "verbatim"
|
|
33
|
+
? schema.TranscriptionMode.VERBATIM
|
|
34
|
+
: schema.TranscriptionMode.WRITTEN,
|
|
35
|
+
contextTerms: [...(options.contextTerms ?? [])],
|
|
36
|
+
},
|
|
37
|
+
}), auth, (error, response) => (error ? reject(error) : resolve(response)));
|
|
38
|
+
call.on("metadata", (headers) => {
|
|
39
|
+
id = requestId(headers);
|
|
40
|
+
});
|
|
41
|
+
call.on("status", (status) => {
|
|
42
|
+
id ??= requestId(status.metadata);
|
|
43
|
+
});
|
|
44
|
+
}), deadline.signal);
|
|
45
|
+
if (!result.language?.tag || !result.language.source)
|
|
46
|
+
throw new RimeStreamError("The service did not confirm a resolved language", id);
|
|
47
|
+
if (Buffer.byteLength(result.text) > policy.transcriptBytes)
|
|
48
|
+
throw new RimeResourceLimitError("The transcript exceeds the SDK text limit", id);
|
|
49
|
+
return { text: result.text, language: result.language.tag, requestId: id };
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
if (deadline.signal.aborted) {
|
|
53
|
+
const reason = deadline.signal.reason;
|
|
54
|
+
if (reason instanceof RimeTimeoutError)
|
|
55
|
+
throw new RimeTimeoutError(reason.message, id);
|
|
56
|
+
throw new RimeCancelledError("Transcription cancelled", id);
|
|
57
|
+
}
|
|
58
|
+
throw nativeError(error, id);
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
call?.cancel();
|
|
62
|
+
deadline.dispose();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
18
65
|
export class TranscriptionCall extends BidiCall {
|
|
19
66
|
constructor(client, auth, signal) {
|
|
20
67
|
requireSchema();
|
package/dist/stt/types.d.ts
CHANGED
|
@@ -32,3 +32,11 @@ export interface TranscriptionFinal {
|
|
|
32
32
|
readonly language: string;
|
|
33
33
|
}
|
|
34
34
|
export type TranscriptionUpdate = TranscriptionPartial | TranscriptionFinal;
|
|
35
|
+
/** Options for a complete WAV recording. Audio is sent unchanged. */
|
|
36
|
+
export type TranscribeOptions = Omit<TranscriptionOptions, "inputFormat">;
|
|
37
|
+
/** A successful whole-recording transcription. Silence may produce empty text. */
|
|
38
|
+
export interface Transcription {
|
|
39
|
+
readonly text: string;
|
|
40
|
+
readonly language: string;
|
|
41
|
+
readonly requestId: string | null;
|
|
42
|
+
}
|
package/docs/stt.md
CHANGED
|
@@ -1,4 +1,43 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Speech recognition
|
|
2
|
+
|
|
3
|
+
## Complete recordings
|
|
4
|
+
|
|
5
|
+
For a complete recording, use the native unary `Transcribe` RPC through the SDK.
|
|
6
|
+
Pass **complete WAV bytes, including the header**, up to **16 MiB (16,777,216
|
|
7
|
+
bytes)**. PCM16 mono 16 kHz WAV is the portable format. The SDK sends the file
|
|
8
|
+
unchanged; it does not decode, resample, or add a header. The service validates
|
|
9
|
+
its encoding and the supplied language and recognition hints.
|
|
10
|
+
|
|
11
|
+
The result is a `Transcription` containing final text, resolved language, and a
|
|
12
|
+
request ID when available. Silence may return empty text. There are no partial
|
|
13
|
+
updates or automatic retries. TTS client settings do not apply. An optional
|
|
14
|
+
overall timeout includes connection and upload; the SDK also bounds connection
|
|
15
|
+
time and the unary request (120 seconds). Timeout, cancellation, and service
|
|
16
|
+
errors use the existing SDK error categories. A request ID is included when the
|
|
17
|
+
transport has made it available.
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { readFile } from "node:fs/promises";
|
|
21
|
+
import { Rime } from "@rimelabs/sdk";
|
|
22
|
+
|
|
23
|
+
const client = new Rime();
|
|
24
|
+
try {
|
|
25
|
+
const result = await client.stt.transcribe(await readFile("utterance.wav"), {
|
|
26
|
+
language: "en",
|
|
27
|
+
mode: "written",
|
|
28
|
+
contextTerms: ["Super-G", "USOC"],
|
|
29
|
+
timeout: 120,
|
|
30
|
+
});
|
|
31
|
+
console.log(result.text, result.language, result.requestId);
|
|
32
|
+
} finally {
|
|
33
|
+
await client.close();
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`TranscribeOptions` also accepts an `AbortSignal` as `signal`. Aborting it or
|
|
38
|
+
closing the client cancels pending requests with `RimeCancelledError`.
|
|
39
|
+
|
|
40
|
+
## Streaming recognition
|
|
2
41
|
|
|
3
42
|
`client.stt.stream` transcribes one utterance from an async source of `Uint8Array` chunks (including Node buffers).
|
|
4
43
|
The SDK handles the gRPC protocol, authentication, audio conversion, transcript
|