@scribeberry/sdk 0.2.0
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/LICENSE +22 -0
- package/README.md +312 -0
- package/dist/index.d.mts +707 -0
- package/dist/index.d.ts +707 -0
- package/dist/index.js +832 -0
- package/dist/index.mjs +791 -0
- package/package.json +69 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,707 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error classes for the Scribeberry SDK.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Base error thrown by the Scribeberry SDK.
|
|
6
|
+
* All SDK errors extend this class.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* try {
|
|
11
|
+
* await sb.templates.list();
|
|
12
|
+
* } catch (error) {
|
|
13
|
+
* if (error instanceof ScribeberryError) {
|
|
14
|
+
* console.error(`[${error.code}] ${error.message}`);
|
|
15
|
+
* }
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
declare class ScribeberryError extends Error {
|
|
20
|
+
/** Machine-readable error code. */
|
|
21
|
+
readonly code: string;
|
|
22
|
+
/** HTTP status code (if applicable). */
|
|
23
|
+
readonly status?: number | undefined;
|
|
24
|
+
constructor(message: string,
|
|
25
|
+
/** Machine-readable error code. */
|
|
26
|
+
code: string,
|
|
27
|
+
/** HTTP status code (if applicable). */
|
|
28
|
+
status?: number | undefined);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Thrown when authentication fails (invalid or expired API key / token).
|
|
32
|
+
*/
|
|
33
|
+
declare class AuthenticationError extends ScribeberryError {
|
|
34
|
+
constructor(message?: string);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Thrown when the rate limit is exceeded.
|
|
38
|
+
*/
|
|
39
|
+
declare class RateLimitError extends ScribeberryError {
|
|
40
|
+
constructor(message?: string);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Result from a `getRealtimeToken` callback.
|
|
45
|
+
*/
|
|
46
|
+
interface RealtimeTokenResult {
|
|
47
|
+
/** Temporary token prefixed with `sb_rt_`. */
|
|
48
|
+
token: string;
|
|
49
|
+
/** ISO 8601 expiration timestamp. */
|
|
50
|
+
expiresAt: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Configuration for the Scribeberry SDK.
|
|
54
|
+
*
|
|
55
|
+
* @example Server-side (full API key)
|
|
56
|
+
* ```typescript
|
|
57
|
+
* const sb = new Scribeberry({ apiKey: 'sk_live_...' });
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* @example Browser with token callback (recommended)
|
|
61
|
+
* ```typescript
|
|
62
|
+
* const sb = new Scribeberry({
|
|
63
|
+
* baseUrl: 'https://sandbox.api.scribeberry.com',
|
|
64
|
+
* getRealtimeToken: async () => {
|
|
65
|
+
* const res = await fetch('/api/realtime-token', { method: 'POST' });
|
|
66
|
+
* return res.json(); // { token: 'sb_rt_...', expiresAt: '...' }
|
|
67
|
+
* },
|
|
68
|
+
* });
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @example Browser with static token (manual refresh)
|
|
72
|
+
* ```typescript
|
|
73
|
+
* const sb = new Scribeberry({ apiKey: 'sb_rt_...' });
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
interface ScribeberryConfig {
|
|
77
|
+
/**
|
|
78
|
+
* Your API key or temporary realtime token.
|
|
79
|
+
*
|
|
80
|
+
* - `sk_test_*` / `sk_live_*` — Full API key (server-side only).
|
|
81
|
+
* - `sb_rt_*` — Temporary realtime token (safe for browser use).
|
|
82
|
+
*
|
|
83
|
+
* **Not required** if `getRealtimeToken` is provided.
|
|
84
|
+
*/
|
|
85
|
+
apiKey?: string;
|
|
86
|
+
/**
|
|
87
|
+
* Async callback that fetches a temporary realtime token from your server.
|
|
88
|
+
*
|
|
89
|
+
* This is the **recommended pattern for browser-side realtime transcription**.
|
|
90
|
+
* The SDK calls this function when it needs a token (on connect and before expiry),
|
|
91
|
+
* so you never have to manage token lifecycle manually.
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```typescript
|
|
95
|
+
* const sb = new Scribeberry({
|
|
96
|
+
* getRealtimeToken: async () => {
|
|
97
|
+
* const res = await fetch('/api/realtime-token', {
|
|
98
|
+
* method: 'POST',
|
|
99
|
+
* headers: { Authorization: `Bearer ${myUserJwt}` },
|
|
100
|
+
* });
|
|
101
|
+
* return res.json(); // { token: 'sb_rt_...', expiresAt: '...' }
|
|
102
|
+
* },
|
|
103
|
+
* });
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
getRealtimeToken?: () => Promise<RealtimeTokenResult>;
|
|
107
|
+
/**
|
|
108
|
+
* API base URL. Defaults to `https://api.scribeberry.com`.
|
|
109
|
+
*
|
|
110
|
+
* Use `https://sandbox.api.scribeberry.com` for development/testing.
|
|
111
|
+
*/
|
|
112
|
+
baseUrl?: string;
|
|
113
|
+
/**
|
|
114
|
+
* Request timeout in milliseconds. Default: 30000 (30 seconds).
|
|
115
|
+
*/
|
|
116
|
+
timeout?: number;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Paginated API response.
|
|
120
|
+
*/
|
|
121
|
+
interface PaginatedResponse<T> {
|
|
122
|
+
items: T[];
|
|
123
|
+
meta: {
|
|
124
|
+
page: number;
|
|
125
|
+
pageSize: number;
|
|
126
|
+
totalPages: number;
|
|
127
|
+
totalCount: number;
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Low-level HTTP client for the Scribeberry API.
|
|
133
|
+
* Handles authentication, error mapping, and request/response serialization.
|
|
134
|
+
*
|
|
135
|
+
* @internal Used by resource classes. Not intended for direct use.
|
|
136
|
+
*/
|
|
137
|
+
declare class HttpClient {
|
|
138
|
+
readonly apiKey: string | undefined;
|
|
139
|
+
readonly baseUrl: string;
|
|
140
|
+
readonly timeout: number;
|
|
141
|
+
/** True if the API key is a temporary realtime token (sb_rt_*). */
|
|
142
|
+
readonly isTemporaryToken: boolean;
|
|
143
|
+
/** True if a getRealtimeToken callback was provided (browser token-provider mode). */
|
|
144
|
+
readonly hasTokenProvider: boolean;
|
|
145
|
+
/** The token provider callback (if any). */
|
|
146
|
+
private readonly getRealtimeToken?;
|
|
147
|
+
/** Current realtime token (fetched via callback or static). */
|
|
148
|
+
private currentToken;
|
|
149
|
+
/** When the current token expires. */
|
|
150
|
+
private tokenExpiresAt;
|
|
151
|
+
/** Active refresh timer. */
|
|
152
|
+
private refreshTimer;
|
|
153
|
+
/** Listeners notified on token refresh. */
|
|
154
|
+
private tokenRefreshListeners;
|
|
155
|
+
constructor(config: ScribeberryConfig);
|
|
156
|
+
/**
|
|
157
|
+
* The WebSocket URL derived from the base URL.
|
|
158
|
+
*/
|
|
159
|
+
get wsUrl(): string;
|
|
160
|
+
/**
|
|
161
|
+
* Get the current realtime token for WebSocket connections.
|
|
162
|
+
* If a getRealtimeToken callback is configured, fetches/refreshes as needed.
|
|
163
|
+
* Otherwise returns the static apiKey.
|
|
164
|
+
*/
|
|
165
|
+
getWsToken(): Promise<string>;
|
|
166
|
+
/**
|
|
167
|
+
* Fetch a fresh token from the callback and schedule auto-refresh.
|
|
168
|
+
*/
|
|
169
|
+
refreshToken(): Promise<string>;
|
|
170
|
+
/**
|
|
171
|
+
* Register a listener that's called when the token is refreshed.
|
|
172
|
+
* Used by RealtimeTranscriptionSession to reconnect with the new token.
|
|
173
|
+
*/
|
|
174
|
+
onTokenRefresh(listener: (token: string) => void): void;
|
|
175
|
+
/**
|
|
176
|
+
* Remove a token refresh listener.
|
|
177
|
+
*/
|
|
178
|
+
offTokenRefresh(listener: (token: string) => void): void;
|
|
179
|
+
/**
|
|
180
|
+
* Schedule an automatic token refresh before the current token expires.
|
|
181
|
+
*/
|
|
182
|
+
private scheduleRefresh;
|
|
183
|
+
/**
|
|
184
|
+
* Make an authenticated HTTP request to the Scribeberry API.
|
|
185
|
+
*/
|
|
186
|
+
request<T>(method: string, path: string, options?: {
|
|
187
|
+
body?: any;
|
|
188
|
+
params?: Record<string, string | number | boolean | undefined>;
|
|
189
|
+
timeout?: number;
|
|
190
|
+
}): Promise<T>;
|
|
191
|
+
private getFetch;
|
|
192
|
+
private handleError;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* A note template defining the output structure.
|
|
197
|
+
*/
|
|
198
|
+
interface Template {
|
|
199
|
+
id: string;
|
|
200
|
+
name: string;
|
|
201
|
+
description: string;
|
|
202
|
+
documentType: string;
|
|
203
|
+
headings: string[];
|
|
204
|
+
categories: string[];
|
|
205
|
+
isPublic: boolean;
|
|
206
|
+
createdAt: string;
|
|
207
|
+
updatedAt: string;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Options for creating a new template.
|
|
211
|
+
*/
|
|
212
|
+
interface CreateTemplateOptions {
|
|
213
|
+
name: string;
|
|
214
|
+
description?: string;
|
|
215
|
+
content: string;
|
|
216
|
+
documentType: string;
|
|
217
|
+
headings?: string[];
|
|
218
|
+
categories?: string[];
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Options for listing templates.
|
|
222
|
+
*/
|
|
223
|
+
interface ListTemplatesOptions {
|
|
224
|
+
page?: number;
|
|
225
|
+
pageSize?: number;
|
|
226
|
+
sortBy?: string;
|
|
227
|
+
sortOrder?: 'asc' | 'desc';
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Manage note templates.
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* ```typescript
|
|
235
|
+
* const templates = await sb.templates.list();
|
|
236
|
+
* const template = await sb.templates.get('template-id');
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
declare class Templates {
|
|
240
|
+
private readonly http;
|
|
241
|
+
constructor(http: HttpClient);
|
|
242
|
+
/**
|
|
243
|
+
* List all templates (paginated).
|
|
244
|
+
*/
|
|
245
|
+
list(options?: ListTemplatesOptions): Promise<PaginatedResponse<Template>>;
|
|
246
|
+
/**
|
|
247
|
+
* Get a template by ID.
|
|
248
|
+
*/
|
|
249
|
+
get(templateId: string): Promise<Template>;
|
|
250
|
+
/**
|
|
251
|
+
* Create a new template.
|
|
252
|
+
*/
|
|
253
|
+
create(options: CreateTemplateOptions): Promise<Template>;
|
|
254
|
+
/**
|
|
255
|
+
* Delete a template.
|
|
256
|
+
*/
|
|
257
|
+
delete(templateId: string): Promise<void>;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Options for generating a note.
|
|
262
|
+
*
|
|
263
|
+
* Provide either `conversationText` or `audioUrl` (or both).
|
|
264
|
+
*/
|
|
265
|
+
interface GenerateNoteOptions {
|
|
266
|
+
/** Template ID to use for note generation. */
|
|
267
|
+
templateId: string;
|
|
268
|
+
/** Conversation text to generate the note from. */
|
|
269
|
+
conversationText?: string;
|
|
270
|
+
/** URL of an audio file to transcribe and generate a note from. */
|
|
271
|
+
audioUrl?: string;
|
|
272
|
+
/** Source language for transcription. Default: 'en-US'. */
|
|
273
|
+
sourceLanguage?: string;
|
|
274
|
+
/** Transcription quality. Default: 'high'. */
|
|
275
|
+
transcriptionQuality?: 'low' | 'medium' | 'high';
|
|
276
|
+
/** Additional context for the note generation. */
|
|
277
|
+
context?: Record<string, string>;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* A generated note.
|
|
281
|
+
*/
|
|
282
|
+
interface Note {
|
|
283
|
+
/** Note content in Markdown format. */
|
|
284
|
+
markdown: string;
|
|
285
|
+
/** Note content as plain text. */
|
|
286
|
+
text: string;
|
|
287
|
+
/** Structured note sections (key = heading, value = content). */
|
|
288
|
+
structured: Record<string, string>;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Result of a note generation request.
|
|
292
|
+
*/
|
|
293
|
+
interface GenerateNoteResult {
|
|
294
|
+
/** The generated note. */
|
|
295
|
+
note: Note;
|
|
296
|
+
/** Transcript data (if audio was provided). */
|
|
297
|
+
transcript?: {
|
|
298
|
+
text: string;
|
|
299
|
+
confidence: number;
|
|
300
|
+
duration: number;
|
|
301
|
+
sourceLanguage: string;
|
|
302
|
+
};
|
|
303
|
+
/** Template that was used. */
|
|
304
|
+
template: {
|
|
305
|
+
id: string;
|
|
306
|
+
name: string;
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Generate structured medical notes from text or audio.
|
|
312
|
+
*
|
|
313
|
+
* @example
|
|
314
|
+
* ```typescript
|
|
315
|
+
* // From text
|
|
316
|
+
* const result = await sb.notes.generate({
|
|
317
|
+
* templateId: 'template-id',
|
|
318
|
+
* conversationText: 'Patient presents with...',
|
|
319
|
+
* });
|
|
320
|
+
*
|
|
321
|
+
* // From audio URL
|
|
322
|
+
* const result = await sb.notes.generate({
|
|
323
|
+
* templateId: 'template-id',
|
|
324
|
+
* audioUrl: 'https://example.com/recording.wav',
|
|
325
|
+
* });
|
|
326
|
+
* ```
|
|
327
|
+
*/
|
|
328
|
+
declare class Notes {
|
|
329
|
+
private readonly http;
|
|
330
|
+
constructor(http: HttpClient);
|
|
331
|
+
/**
|
|
332
|
+
* Generate a note from conversation text or audio.
|
|
333
|
+
*
|
|
334
|
+
* @param options - Note generation options.
|
|
335
|
+
* @returns The generated note with optional transcript data.
|
|
336
|
+
*/
|
|
337
|
+
generate(options: GenerateNoteOptions): Promise<GenerateNoteResult>;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Configuration for a realtime transcription session.
|
|
342
|
+
*/
|
|
343
|
+
interface RealtimeConfig {
|
|
344
|
+
/** Source language. Default: `'en-US'`. */
|
|
345
|
+
language?: string;
|
|
346
|
+
/** Enable speaker diarization. Default: `true`. */
|
|
347
|
+
enableDiarization?: boolean;
|
|
348
|
+
/**
|
|
349
|
+
* Template ID for automatic note generation when the session stops.
|
|
350
|
+
* If provided, the server generates a note from the accumulated transcript
|
|
351
|
+
* and pushes it back via the `'note'` event.
|
|
352
|
+
*/
|
|
353
|
+
templateId?: string;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* A confirmed transcript segment from the realtime stream.
|
|
357
|
+
*/
|
|
358
|
+
interface TranscriptSegment {
|
|
359
|
+
/** Confirmed text content. */
|
|
360
|
+
text: string;
|
|
361
|
+
/** Speaker identifier (if diarization is enabled). */
|
|
362
|
+
speaker?: number;
|
|
363
|
+
/** Segment start time in milliseconds from session start. */
|
|
364
|
+
startMs: number;
|
|
365
|
+
/** Segment end time in milliseconds from session start. */
|
|
366
|
+
endMs: number;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Result returned when a realtime session is stopped.
|
|
370
|
+
*/
|
|
371
|
+
interface RealtimeSessionResult {
|
|
372
|
+
/** Full accumulated transcript text. */
|
|
373
|
+
transcript: string;
|
|
374
|
+
/** Individual confirmed transcript segments. */
|
|
375
|
+
segments: TranscriptSegment[];
|
|
376
|
+
/** Session duration in seconds. */
|
|
377
|
+
durationSeconds: number;
|
|
378
|
+
/** Generated note (if `templateId` was provided). */
|
|
379
|
+
note?: Note;
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Events emitted by a `RealtimeTranscriptionSession`.
|
|
383
|
+
*/
|
|
384
|
+
interface RealtimeSessionEvents {
|
|
385
|
+
/**
|
|
386
|
+
* Partial (interim) transcript — updates in real-time as words
|
|
387
|
+
* are recognized. Each partial replaces the previous one.
|
|
388
|
+
*/
|
|
389
|
+
partial: (text: string, speaker?: number) => void;
|
|
390
|
+
/**
|
|
391
|
+
* Final confirmed transcript segment. This text is stable and won't change.
|
|
392
|
+
* Accumulate these segments to build the full transcript.
|
|
393
|
+
*/
|
|
394
|
+
final: (segment: TranscriptSegment) => void;
|
|
395
|
+
/**
|
|
396
|
+
* Natural speech endpoint detected (pause between utterances).
|
|
397
|
+
*/
|
|
398
|
+
endpoint: () => void;
|
|
399
|
+
/**
|
|
400
|
+
* Note generated from the accumulated transcript (requires `templateId`).
|
|
401
|
+
*/
|
|
402
|
+
note: (note: Note) => void;
|
|
403
|
+
/**
|
|
404
|
+
* Session started and ready to receive audio.
|
|
405
|
+
*/
|
|
406
|
+
started: (sessionId: string) => void;
|
|
407
|
+
/**
|
|
408
|
+
* Session stopped. Contains final transcript and usage info.
|
|
409
|
+
*/
|
|
410
|
+
stopped: (result: RealtimeSessionResult) => void;
|
|
411
|
+
/**
|
|
412
|
+
* An error occurred during the session.
|
|
413
|
+
*/
|
|
414
|
+
error: (error: Error) => void;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Options for creating a temporary realtime token.
|
|
418
|
+
*/
|
|
419
|
+
interface CreateRealtimeTokenOptions {
|
|
420
|
+
/**
|
|
421
|
+
* Token lifetime in seconds. Default: 3600 (1 hour). Maximum: 3600.
|
|
422
|
+
*/
|
|
423
|
+
expiresInSeconds?: number;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* A temporary realtime token for browser-side WebSocket access.
|
|
427
|
+
*/
|
|
428
|
+
interface RealtimeToken {
|
|
429
|
+
/** Temporary token prefixed with `sb_rt_`. */
|
|
430
|
+
token: string;
|
|
431
|
+
/** ISO 8601 expiration timestamp. */
|
|
432
|
+
expiresAt: string;
|
|
433
|
+
/** WebSocket URL to connect to for realtime transcription. */
|
|
434
|
+
wsUrl: string;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* A realtime transcription session over WebSocket.
|
|
439
|
+
*
|
|
440
|
+
* Audio is streamed to the Scribeberry server and transcript events are
|
|
441
|
+
* emitted as speech is recognized. The session accumulates confirmed
|
|
442
|
+
* segments so you can retrieve the full transcript at any time.
|
|
443
|
+
*
|
|
444
|
+
* **Audio format:** PCM 16-bit signed little-endian, 16kHz, mono.
|
|
445
|
+
*
|
|
446
|
+
* @example
|
|
447
|
+
* ```typescript
|
|
448
|
+
* const session = sb.realtime.transcribe({
|
|
449
|
+
* language: 'en-US',
|
|
450
|
+
* templateId: 'template-id', // auto-generate note on stop
|
|
451
|
+
* });
|
|
452
|
+
*
|
|
453
|
+
* session.on('partial', (text) => console.log('Interim:', text));
|
|
454
|
+
* session.on('final', (segment) => console.log('Confirmed:', segment.text));
|
|
455
|
+
* session.on('stopped', (result) => console.log('Full:', result.transcript));
|
|
456
|
+
*
|
|
457
|
+
* // Stream audio chunks
|
|
458
|
+
* session.sendAudio(audioBuffer);
|
|
459
|
+
*
|
|
460
|
+
* // When done
|
|
461
|
+
* const result = await session.stop();
|
|
462
|
+
* console.log(result.transcript);
|
|
463
|
+
* ```
|
|
464
|
+
*/
|
|
465
|
+
declare class RealtimeTranscriptionSession {
|
|
466
|
+
private readonly http;
|
|
467
|
+
private readonly config;
|
|
468
|
+
private ws;
|
|
469
|
+
private _sessionId;
|
|
470
|
+
private _state;
|
|
471
|
+
private segments;
|
|
472
|
+
private durationSeconds;
|
|
473
|
+
private note;
|
|
474
|
+
private stopResolver;
|
|
475
|
+
private handlers;
|
|
476
|
+
constructor(http: HttpClient, config: RealtimeConfig);
|
|
477
|
+
/** Current session state. */
|
|
478
|
+
get state(): "idle" | "connecting" | "active" | "stopping" | "stopped";
|
|
479
|
+
/** Session ID (available after `'started'` event). */
|
|
480
|
+
get sessionId(): string | null;
|
|
481
|
+
/**
|
|
482
|
+
* Get the full accumulated transcript text at any point during the session.
|
|
483
|
+
*
|
|
484
|
+
* @returns Concatenated text from all confirmed segments.
|
|
485
|
+
*/
|
|
486
|
+
getTranscript(): string;
|
|
487
|
+
/**
|
|
488
|
+
* Get all confirmed transcript segments.
|
|
489
|
+
*
|
|
490
|
+
* @returns A copy of the segments array.
|
|
491
|
+
*/
|
|
492
|
+
getSegments(): TranscriptSegment[];
|
|
493
|
+
/**
|
|
494
|
+
* Connect to the realtime transcription server.
|
|
495
|
+
*
|
|
496
|
+
* Called automatically by `sb.realtime.transcribe()`. You don't usually
|
|
497
|
+
* need to call this directly.
|
|
498
|
+
*
|
|
499
|
+
* @throws {ScribeberryError} If the session has already been started
|
|
500
|
+
*/
|
|
501
|
+
connect(): Promise<void>;
|
|
502
|
+
/**
|
|
503
|
+
* Send an audio chunk to the server for transcription.
|
|
504
|
+
*
|
|
505
|
+
* **Required format:** PCM 16-bit signed little-endian, 16kHz, mono.
|
|
506
|
+
*
|
|
507
|
+
* @param data - Raw audio data
|
|
508
|
+
* @throws {ScribeberryError} If the session is not active
|
|
509
|
+
*/
|
|
510
|
+
sendAudio(data: ArrayBuffer | Uint8Array | Buffer): void;
|
|
511
|
+
/**
|
|
512
|
+
* Stream audio from an async iterable source (e.g., microphone stream).
|
|
513
|
+
*
|
|
514
|
+
* @param stream - Async iterable of audio chunks.
|
|
515
|
+
*/
|
|
516
|
+
sendStream(stream: AsyncIterable<ArrayBuffer | Uint8Array | Buffer>): Promise<void>;
|
|
517
|
+
/**
|
|
518
|
+
* Pause audio streaming. The WebSocket connection stays alive.
|
|
519
|
+
*/
|
|
520
|
+
pause(): void;
|
|
521
|
+
/**
|
|
522
|
+
* Resume audio streaming after a pause.
|
|
523
|
+
*/
|
|
524
|
+
resume(): void;
|
|
525
|
+
/**
|
|
526
|
+
* Request finalization of the current audio buffer.
|
|
527
|
+
* Forces the server to emit any pending partial results as final.
|
|
528
|
+
*/
|
|
529
|
+
finalize(): void;
|
|
530
|
+
/**
|
|
531
|
+
* Stop the session gracefully.
|
|
532
|
+
*
|
|
533
|
+
* Waits for the server to confirm the stop and (if configured) for
|
|
534
|
+
* note generation to complete.
|
|
535
|
+
*
|
|
536
|
+
* @returns Final transcript, segments, duration, and optional note.
|
|
537
|
+
*/
|
|
538
|
+
stop(): Promise<RealtimeSessionResult>;
|
|
539
|
+
/**
|
|
540
|
+
* Register an event handler.
|
|
541
|
+
*
|
|
542
|
+
* @param event - Event name
|
|
543
|
+
* @param handler - Event handler function
|
|
544
|
+
* @returns `this` for chaining
|
|
545
|
+
*
|
|
546
|
+
* @example
|
|
547
|
+
* ```typescript
|
|
548
|
+
* session
|
|
549
|
+
* .on('partial', (text) => console.log('Interim:', text))
|
|
550
|
+
* .on('final', (segment) => console.log('Confirmed:', segment.text))
|
|
551
|
+
* .on('error', (err) => console.error(err));
|
|
552
|
+
* ```
|
|
553
|
+
*/
|
|
554
|
+
on<E extends keyof RealtimeSessionEvents>(event: E, handler: RealtimeSessionEvents[E]): this;
|
|
555
|
+
/**
|
|
556
|
+
* Remove an event handler.
|
|
557
|
+
*
|
|
558
|
+
* @param event - Event name
|
|
559
|
+
* @param handler - Handler to remove
|
|
560
|
+
* @returns `this` for chaining
|
|
561
|
+
*/
|
|
562
|
+
off<E extends keyof RealtimeSessionEvents>(event: E, handler: RealtimeSessionEvents[E]): this;
|
|
563
|
+
private emit;
|
|
564
|
+
private send;
|
|
565
|
+
private handleMessage;
|
|
566
|
+
private resolveStop;
|
|
567
|
+
private buildResult;
|
|
568
|
+
private cleanup;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* Realtime transcription API.
|
|
573
|
+
*
|
|
574
|
+
* @example Server-side: create a temporary token for browser clients
|
|
575
|
+
* ```typescript
|
|
576
|
+
* const sb = new Scribeberry({ apiKey: 'sk_live_...' });
|
|
577
|
+
* const { token, wsUrl } = await sb.realtime.createToken();
|
|
578
|
+
* // Send token + wsUrl to the browser
|
|
579
|
+
* ```
|
|
580
|
+
*
|
|
581
|
+
* @example Browser: use a temporary token for realtime transcription
|
|
582
|
+
* ```typescript
|
|
583
|
+
* const sb = new Scribeberry({ apiKey: 'sb_rt_...' });
|
|
584
|
+
* const session = sb.realtime.transcribe({ language: 'en-US' });
|
|
585
|
+
*
|
|
586
|
+
* session.on('partial', (text) => updateUI(text));
|
|
587
|
+
* session.on('final', (segment) => appendTranscript(segment));
|
|
588
|
+
*
|
|
589
|
+
* session.sendAudio(audioChunk);
|
|
590
|
+
*
|
|
591
|
+
* const result = await session.stop();
|
|
592
|
+
* ```
|
|
593
|
+
*/
|
|
594
|
+
declare class Realtime {
|
|
595
|
+
private readonly http;
|
|
596
|
+
constructor(http: HttpClient);
|
|
597
|
+
/**
|
|
598
|
+
* Create a temporary realtime token for browser-side WebSocket access.
|
|
599
|
+
*
|
|
600
|
+
* **Server-side only.** Call this from your backend, then pass the token
|
|
601
|
+
* to your frontend for use with `new Scribeberry({ apiKey: token })`.
|
|
602
|
+
*
|
|
603
|
+
* @param options - Token creation options.
|
|
604
|
+
* @returns A temporary token and the WebSocket URL.
|
|
605
|
+
*
|
|
606
|
+
* @example
|
|
607
|
+
* ```typescript
|
|
608
|
+
* // On your server
|
|
609
|
+
* const sb = new Scribeberry({ apiKey: 'sk_live_...' });
|
|
610
|
+
* const { token, wsUrl, expiresAt } = await sb.realtime.createToken({
|
|
611
|
+
* expiresInSeconds: 3600,
|
|
612
|
+
* });
|
|
613
|
+
*
|
|
614
|
+
* // Return token to the browser client
|
|
615
|
+
* res.json({ token, wsUrl, expiresAt });
|
|
616
|
+
* ```
|
|
617
|
+
*
|
|
618
|
+
* @throws {ScribeberryError} If called in a browser environment
|
|
619
|
+
* @throws {ScribeberryError} If called with a temporary token (sb_rt_*)
|
|
620
|
+
*/
|
|
621
|
+
createToken(options?: CreateRealtimeTokenOptions): Promise<RealtimeToken>;
|
|
622
|
+
/**
|
|
623
|
+
* Start a new realtime transcription session.
|
|
624
|
+
*
|
|
625
|
+
* The session connects via WebSocket and streams transcription results
|
|
626
|
+
* back as audio is sent. Optionally generates a note when stopped.
|
|
627
|
+
*
|
|
628
|
+
* **Audio format:** PCM 16-bit signed little-endian, 16kHz, mono.
|
|
629
|
+
*
|
|
630
|
+
* @param config - Session configuration.
|
|
631
|
+
* @returns A realtime transcription session.
|
|
632
|
+
*
|
|
633
|
+
* @example
|
|
634
|
+
* ```typescript
|
|
635
|
+
* const session = sb.realtime.transcribe({
|
|
636
|
+
* language: 'en-US',
|
|
637
|
+
* enableDiarization: true,
|
|
638
|
+
* templateId: 'template-id',
|
|
639
|
+
* });
|
|
640
|
+
*
|
|
641
|
+
* session.on('partial', (text) => console.log('Partial:', text));
|
|
642
|
+
* session.on('final', (segment) => console.log('Final:', segment.text));
|
|
643
|
+
* session.on('stopped', (result) => console.log('Transcript:', result.transcript));
|
|
644
|
+
*
|
|
645
|
+
* // Stream audio chunks from your microphone
|
|
646
|
+
* session.sendAudio(audioChunk);
|
|
647
|
+
*
|
|
648
|
+
* // When done
|
|
649
|
+
* const result = await session.stop();
|
|
650
|
+
* ```
|
|
651
|
+
*/
|
|
652
|
+
transcribe(config?: RealtimeConfig): RealtimeTranscriptionSession;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* Scribeberry SDK — Medical transcription, AI note generation, and realtime speech-to-text.
|
|
657
|
+
*
|
|
658
|
+
* Universal package: works in both Node.js and browser environments.
|
|
659
|
+
*
|
|
660
|
+
* @example Server-side (Node.js)
|
|
661
|
+
* ```typescript
|
|
662
|
+
* import { Scribeberry } from '@scribeberry/sdk';
|
|
663
|
+
*
|
|
664
|
+
* const sb = new Scribeberry({ apiKey: 'sk_live_...' });
|
|
665
|
+
*
|
|
666
|
+
* // List templates
|
|
667
|
+
* const templates = await sb.templates.list();
|
|
668
|
+
*
|
|
669
|
+
* // Generate a note
|
|
670
|
+
* const result = await sb.notes.generate({
|
|
671
|
+
* templateId: templates.items[0].id,
|
|
672
|
+
* conversationText: 'Patient presents with...',
|
|
673
|
+
* });
|
|
674
|
+
*
|
|
675
|
+
* // Create a temporary token for browser clients
|
|
676
|
+
* const { token, wsUrl } = await sb.realtime.createToken();
|
|
677
|
+
* ```
|
|
678
|
+
*
|
|
679
|
+
* @example Browser with token callback (recommended)
|
|
680
|
+
* ```typescript
|
|
681
|
+
* import { Scribeberry } from '@scribeberry/sdk';
|
|
682
|
+
*
|
|
683
|
+
* const sb = new Scribeberry({
|
|
684
|
+
* getRealtimeToken: async () => {
|
|
685
|
+
* const res = await fetch('/api/realtime-token', { method: 'POST' });
|
|
686
|
+
* return res.json(); // { token, expiresAt }
|
|
687
|
+
* },
|
|
688
|
+
* });
|
|
689
|
+
*
|
|
690
|
+
* const session = sb.realtime.transcribe({ language: 'en-US' });
|
|
691
|
+
* session.on('final', (segment) => console.log(segment.text));
|
|
692
|
+
* session.sendAudio(audioChunk);
|
|
693
|
+
* const result = await session.stop();
|
|
694
|
+
* ```
|
|
695
|
+
*/
|
|
696
|
+
declare class Scribeberry {
|
|
697
|
+
private readonly http;
|
|
698
|
+
/** Manage note templates (requires full API key). */
|
|
699
|
+
readonly templates: Templates;
|
|
700
|
+
/** Generate medical notes from text or audio (requires full API key). */
|
|
701
|
+
readonly notes: Notes;
|
|
702
|
+
/** Realtime audio transcription via WebSocket. */
|
|
703
|
+
readonly realtime: Realtime;
|
|
704
|
+
constructor(config: ScribeberryConfig);
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
export { AuthenticationError, type CreateRealtimeTokenOptions, type CreateTemplateOptions, type GenerateNoteOptions, type GenerateNoteResult, type ListTemplatesOptions, type Note, type PaginatedResponse, RateLimitError, type RealtimeConfig, type RealtimeSessionEvents, type RealtimeSessionResult, type RealtimeToken, type RealtimeTokenResult, RealtimeTranscriptionSession, Scribeberry, type ScribeberryConfig, ScribeberryError, type Template, type TranscriptSegment };
|