vocalstack 1.0.0a0__py3-none-any.whl

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.
vocalstack/_models.py ADDED
@@ -0,0 +1,1745 @@
1
+ # GENERATED by @vocalstack/contract tools/generate.mjs — do not edit.
2
+ from __future__ import annotations
3
+
4
+ import json
5
+ from typing import Annotated, Any, Dict, List, Literal, Optional, Union
6
+
7
+ from pydantic import BaseModel, ConfigDict, Field, TypeAdapter
8
+
9
+
10
+ class _Base(BaseModel):
11
+ # extra="ignore": additive contract changes must not break clients.
12
+ model_config = ConfigDict(populate_by_name=True, extra="ignore")
13
+
14
+
15
+ Access = Literal["public", "private"]
16
+
17
+ ErrorCode = Literal["invalid_audio", "invalid_options", "invalid_token", "capacity_exceeded", "slow_consumer", "engine_unavailable", "internal", "session_expired", "forbidden", "broadcast_archived", "not_found", "conflict", "invalid_state", "password_required", "rate_limited", "preview_pending", "language_unavailable", "suspended", "key_expired", "key_revoked", "key_from_browser", "insufficient_credit", "payment_method_required", "payment_method_in_use", "billing_details_required", "promo_code_invalid", "auto_top_up_off", "range_too_long", "quota_exceeded", "idempotency_key_reused", "method_not_allowed", "payload_too_large", "unsupported_media_type", "invalid_body", "timeout", "unavailable"]
18
+
19
+ AudioEncoding = Literal["pcm_f32le"]
20
+
21
+ FixKind = Literal["extension", "scheme", "page_stream"]
22
+
23
+ SourceProblem = Literal["not_found", "refused", "server_error", "unknown_host", "unreachable", "private_address", "timeout", "web_page", "bad_playlist", "not_audio", "unsupported", "youtube_upcoming", "youtube_not_live", "youtube_unavailable", "youtube_busy"]
24
+
25
+ AudioSourceState = Literal["ready", "error"]
26
+
27
+ RecordingState = Literal["pending", "live", "paused", "processing", "ended", "finalized"]
28
+
29
+ Lifecycle = Literal["active", "archived", "purged"]
30
+
31
+ LatencyMode = Literal["auto", "fast", "accuracy"]
32
+
33
+ SpeakerLabels = Literal["auto", "on", "off"]
34
+
35
+ Decoder = Literal["fast", "accuracy"]
36
+
37
+ NotVoicedReason = Literal["rewrite"]
38
+
39
+ DoneReason = Literal["eof", "max_duration", "cancelled"]
40
+
41
+ ExportFormat = Literal["json", "srt", "xlsx", "pdf"]
42
+
43
+ HealthStatus = Literal["ok"]
44
+
45
+ IngestState = Literal["connecting", "streaming", "reconnecting", "stopped", "failed"]
46
+
47
+ InputKind = Literal["live", "file", "url", "stream"]
48
+
49
+ JobState = Literal["queued", "fetching", "transcribing", "done", "failed", "cropping"]
50
+
51
+ LinkKind = Literal["live", "file", "unknown"]
52
+
53
+ LoadingStage = Literal["download", "model"]
54
+
55
+ RecordingKind = Literal["live", "upload"]
56
+
57
+ SourceKind = Literal["file", "url"]
58
+
59
+ PullState = Literal["connecting", "streaming", "reconnecting", "failed"]
60
+
61
+ SentenceStatus = Literal["open", "closed", "dropped"]
62
+
63
+ VoiceStatusState = Literal["preparing", "unavailable"]
64
+
65
+
66
+ class Actor(_Base):
67
+ api_key_id: Optional[str] = Field(default=None, alias="apiKeyId")
68
+ display_name: Optional[str] = Field(default=None, alias="displayName")
69
+ user_id: Optional[str] = Field(default=None, alias="userId")
70
+
71
+
72
+ class WordAlt(_Base):
73
+ prob: float
74
+ text: str
75
+
76
+
77
+ class Word(_Base):
78
+ alts: Optional[List["WordAlt"]] = None
79
+ end: float
80
+ llm: Optional[bool] = None
81
+ prob: Optional[float] = None
82
+ recognized: Optional[str] = None
83
+ script: Optional[bool] = None
84
+ start: float
85
+ text: str
86
+
87
+
88
+ class AmendTail(_Base):
89
+ """The words an amend gave a segment's end: `words` replace its last
90
+ `replaced` words."""
91
+
92
+ replaced: int
93
+ words: List["Word"]
94
+
95
+
96
+ class ErrorData(_Base):
97
+ details: Optional[Any] = None
98
+ retryable: bool
99
+
100
+
101
+ class ApiErrorBody(_Base):
102
+ code: ErrorCode
103
+ data: "ErrorData"
104
+ defined: bool
105
+ message: str
106
+ request_id: Optional[str] = Field(default=None, alias="requestId")
107
+ status: int
108
+
109
+
110
+ class AudioCapabilities(_Base):
111
+ channels: List[int]
112
+ encodings: List[AudioEncoding]
113
+ sample_rates: List[int] = Field(alias="sampleRates")
114
+
115
+
116
+ class AudioFormat(_Base):
117
+ channels: Optional[int] = None
118
+ encoding: Optional[AudioEncoding] = None
119
+ sample_rate: Optional[int] = Field(default=None, alias="sampleRate")
120
+
121
+
122
+ class AudioSource(_Base):
123
+ """A stream a broadcast can record from (`Broadcast.audioSources`, design
124
+ 78): a YouTube live or an internet radio address kept with the
125
+ broadcast. `POST /v1/broadcasts/{id}/recordings` with `audioSource` set
126
+ to its id starts a recording of it."""
127
+
128
+ id: str
129
+ name: str
130
+ url: str
131
+
132
+
133
+ class AudioSourceFix(_Base):
134
+ """An address that was opened and gave audio, offered in place of the one
135
+ that did not."""
136
+
137
+ kind: FixKind
138
+ label: str
139
+ url: str
140
+
141
+
142
+ class AudioSourceCheck(_Base):
143
+ """`GET /v1/broadcasts/{id}/audio-sources/{source}/check`."""
144
+
145
+ checked_at: str = Field(alias="checkedAt")
146
+ fix: Optional["AudioSourceFix"] = None
147
+ http_status: Optional[int] = Field(default=None, alias="httpStatus")
148
+ message: Optional[str] = None
149
+ problem: Optional[SourceProblem] = None
150
+ state: AudioSourceState
151
+
152
+
153
+ class AutoTopUpAttempt(_Base):
154
+ amount: float
155
+ at: str
156
+ outcome: str
157
+
158
+
159
+ class MoneyRange(_Base):
160
+ """Two amounts, both inclusive."""
161
+
162
+ max: float
163
+ min: float
164
+
165
+
166
+ class AutoTopUpChoices(_Base):
167
+ amount_range: "MoneyRange" = Field(alias="amountRange")
168
+ amounts: List[float]
169
+ threshold_range: "MoneyRange" = Field(alias="thresholdRange")
170
+ thresholds: List[float]
171
+
172
+
173
+ class AutoTopUpSettings(_Base):
174
+ """`PUT /v1/billing/auto-top-up`."""
175
+
176
+ amount: Optional[float] = None
177
+ enabled: bool
178
+ threshold: Optional[float] = None
179
+
180
+
181
+ class AutoTopUpView(_Base):
182
+ amount: Optional[float] = None
183
+ available: bool
184
+ enabled: bool
185
+ last: Optional["AutoTopUpAttempt"] = None
186
+ offered: bool
187
+ threshold: Optional[float] = None
188
+
189
+
190
+ class BillingDetails(_Base):
191
+ """`GET / PUT /v1/billing/details`."""
192
+
193
+ city: Optional[str] = None
194
+ country: Optional[str] = None
195
+ email: Optional[str] = None
196
+ line1: Optional[str] = None
197
+ name: Optional[str] = None
198
+ postal_code: Optional[str] = Field(default=None, alias="postalCode")
199
+ tax_id: Optional[str] = Field(default=None, alias="taxId")
200
+
201
+
202
+ class CardView(_Base):
203
+ brand: str
204
+ declined: bool
205
+ exp_month: Optional[int] = Field(default=None, alias="expMonth")
206
+ exp_year: Optional[int] = Field(default=None, alias="expYear")
207
+ last4: str
208
+
209
+
210
+ class Limits2(_Base):
211
+ """The limits of a version. `null` is unlimited."""
212
+
213
+ concurrent_transcriptions: Optional[int] = Field(default=None, alias="concurrentTranscriptions")
214
+ creates_per_hour: Optional[int] = Field(default=None, alias="createsPerHour")
215
+ creates_per_hour_unpaid: Optional[int] = Field(default=None, alias="createsPerHourUnpaid")
216
+ max_file_bytes: Optional[int] = Field(default=None, alias="maxFileBytes")
217
+ max_live_seconds: Optional[int] = Field(default=None, alias="maxLiveSeconds")
218
+ requests_per_min: Optional[int] = Field(default=None, alias="requestsPerMin")
219
+ retention_audio_days: Optional[int] = Field(default=None, alias="retentionAudioDays")
220
+ retention_transcriptions_days: Optional[int] = Field(default=None, alias="retentionTranscriptionsDays")
221
+ retention_voices_days: Optional[int] = Field(default=None, alias="retentionVoicesDays")
222
+
223
+
224
+ class LimitsUsage(_Base):
225
+ """The plan's counted limits, as used now."""
226
+
227
+ concurrent_limit: Optional[int] = Field(default=None, alias="concurrentLimit")
228
+ create_limit: Optional[int] = Field(default=None, alias="createLimit")
229
+ created_last_hour: int = Field(alias="createdLastHour")
230
+ resets_at: Optional[str] = Field(default=None, alias="resetsAt")
231
+ running: int
232
+
233
+
234
+ class LowBalanceAlertView(_Base):
235
+ enabled: bool
236
+ threshold: float
237
+
238
+
239
+ class MonthlyCreditView(_Base):
240
+ granted: float
241
+ granted_at: str = Field(alias="grantedAt")
242
+ remaining: float
243
+ renews_at: Optional[str] = Field(default=None, alias="renewsAt")
244
+ used: float
245
+
246
+
247
+ class Rates(_Base):
248
+ """The rates of a version, in dollars per hour."""
249
+
250
+ file_per_hour: float = Field(alias="filePerHour")
251
+ live_per_hour: float = Field(alias="livePerHour")
252
+
253
+
254
+ class PendingChange(_Base):
255
+ applies_at: str = Field(alias="appliesAt")
256
+ rates: "Rates"
257
+
258
+
259
+ class PendingPayment(_Base):
260
+ amount: float
261
+ kind: str
262
+ since: str
263
+
264
+
265
+ class DateRange(_Base):
266
+ """Two days, both inclusive (`YYYY-MM-DD`)."""
267
+
268
+ end: str
269
+ start: str
270
+
271
+
272
+ class PlanRef(_Base):
273
+ id: str
274
+ kind: str
275
+ name: str
276
+
277
+
278
+ class NextPayment(_Base):
279
+ amount: float
280
+ at: str
281
+
282
+
283
+ class PendingInterval(_Base):
284
+ applies_at: str = Field(alias="appliesAt")
285
+ interval: str
286
+
287
+
288
+ class SubscriptionView(_Base):
289
+ cancel_at_period_end: bool = Field(alias="cancelAtPeriodEnd")
290
+ current_period_end: Optional[str] = Field(default=None, alias="currentPeriodEnd")
291
+ current_period_start: Optional[str] = Field(default=None, alias="currentPeriodStart")
292
+ interval: str
293
+ next_payment: Optional["NextPayment"] = Field(default=None, alias="nextPayment")
294
+ past_due_since: Optional[str] = Field(default=None, alias="pastDueSince")
295
+ pending_interval: Optional["PendingInterval"] = Field(default=None, alias="pendingInterval")
296
+ status: str
297
+
298
+
299
+ class BillingView(_Base):
300
+ """`GET /v1/billing`: the account as the Dashboard shows it. The plan's
301
+ debt cap (the grace amount) is never on it: `inGrace` says whether
302
+ running transcriptions go on below zero, never how far."""
303
+
304
+ account_created: Optional[str] = Field(default=None, alias="accountCreated")
305
+ auto_top_up: "AutoTopUpView" = Field(alias="autoTopUp")
306
+ balance: float
307
+ can_start: bool = Field(alias="canStart")
308
+ card: Optional["CardView"] = None
309
+ enabled: bool
310
+ has_paid: bool = Field(alias="hasPaid")
311
+ in_grace: bool = Field(alias="inGrace")
312
+ limits: Optional["Limits2"] = None
313
+ limits_usage: Optional["LimitsUsage"] = Field(default=None, alias="limitsUsage")
314
+ low_balance_alert: "LowBalanceAlertView" = Field(alias="lowBalanceAlert")
315
+ monthly_credit: Optional["MonthlyCreditView"] = Field(default=None, alias="monthlyCredit")
316
+ pending_change: Optional["PendingChange"] = Field(default=None, alias="pendingChange")
317
+ pending_payment: Optional["PendingPayment"] = Field(default=None, alias="pendingPayment")
318
+ period: Optional["DateRange"] = None
319
+ plan: Optional["PlanRef"] = None
320
+ previous_period: Optional["DateRange"] = Field(default=None, alias="previousPeriod")
321
+ rates: Optional["Rates"] = None
322
+ retention_deadline: Optional[str] = Field(default=None, alias="retentionDeadline")
323
+ start_block: Optional[str] = Field(default=None, alias="startBlock")
324
+ subscription: Optional["SubscriptionView"] = None
325
+ top_up_url: str = Field(alias="topUpUrl")
326
+
327
+
328
+ class CurrentRecording(_Base):
329
+ """The recording in flight (`currentRecording`): on a transcription, its
330
+ open recording; on a broadcast, the open recording
331
+ of a live transcription feeding it, which is what its listeners are sent."""
332
+
333
+ recording_id: str = Field(alias="recordingId")
334
+ started_at: Optional[str] = Field(default=None, alias="startedAt")
335
+ state: RecordingState
336
+ transcription_id: Optional[str] = Field(default=None, alias="transcriptionId")
337
+
338
+
339
+ class LastRecording(_Base):
340
+ """A live transcription's newest recording (`lastRecording`): what
341
+ its row in a list reads from — how long it ran, when, and whether it is
342
+ still running — and the recording a tap on that row opens."""
343
+
344
+ duration_s: Optional[float] = Field(default=None, alias="durationS")
345
+ recording_id: str = Field(alias="recordingId")
346
+ started_at: Optional[str] = Field(default=None, alias="startedAt")
347
+ state: RecordingState
348
+ title: Optional[str] = None
349
+ transcription_id: Optional[str] = Field(default=None, alias="transcriptionId")
350
+
351
+
352
+ class ConfidencePolicy(_Base):
353
+ """Env defaults, overridden per broadcast, transcription or recording."""
354
+
355
+ hide_below: Optional[float] = Field(default=None, alias="hideBelow")
356
+ low_threshold: Optional[float] = Field(default=None, alias="lowThreshold")
357
+ suppress_count: Optional[int] = Field(default=None, alias="suppressCount")
358
+
359
+
360
+ class Settings(_Base):
361
+ """A broadcast's, transcription's or recording's capture settings (the
362
+ design's settings sheet): what a recording made in it starts with."""
363
+
364
+ confidence: Optional["ConfidencePolicy"] = None
365
+ latency_mode: Optional[LatencyMode] = Field(default=None, alias="latencyMode")
366
+ llm_fix: Optional[bool] = Field(default=None, alias="llmFix")
367
+ max_duration_s: Optional[int] = Field(default=None, alias="maxDurationS")
368
+ max_pause_s: Optional[int] = Field(default=None, alias="maxPauseS")
369
+ silence_auto_pause_s: Optional[int] = Field(default=None, alias="silenceAutoPauseS")
370
+ speaker_labels: Optional[SpeakerLabels] = Field(default=None, alias="speakerLabels")
371
+ spoken_language: Optional[str] = Field(default=None, alias="spokenLanguage")
372
+ voice: Optional[bool] = None
373
+ voice_by_lang: Optional[Dict[str, str]] = Field(default=None, alias="voiceByLang")
374
+
375
+
376
+ class TranscriptionRef(_Base):
377
+ """A live transcription feeding a broadcast (`Broadcast.transcriptions`)."""
378
+
379
+ id: str
380
+ last_recorded_at: Optional[str] = Field(default=None, alias="lastRecordedAt")
381
+ made: Optional[bool] = None
382
+ name: str
383
+ recording: bool
384
+ source: "CaptureSource"
385
+
386
+
387
+ class Broadcast(_Base):
388
+ """A broadcast: the link listeners open (`code`), fed by the live
389
+ transcriptions attached to it (`transcriptions`) or recording one of
390
+ its own audio sources (`audioSources`). Its recordings are made in
391
+ those live transcriptions."""
392
+
393
+ access: Access
394
+ archived_at: Optional[str] = Field(default=None, alias="archivedAt")
395
+ audio_sources: Optional[List["AudioSource"]] = Field(default=None, alias="audioSources")
396
+ code: str
397
+ created_at: str = Field(alias="createdAt")
398
+ current_recording: Optional["CurrentRecording"] = Field(default=None, alias="currentRecording")
399
+ id: str
400
+ kind: Literal["broadcast"] = "broadcast"
401
+ last_recorded_at: Optional[str] = Field(default=None, alias="lastRecordedAt")
402
+ last_recording: Optional["LastRecording"] = Field(default=None, alias="lastRecording")
403
+ lifecycle: Lifecycle
404
+ listeners_now: Optional[int] = Field(default=None, alias="listenersNow")
405
+ name: str
406
+ owner_principal_id: str = Field(alias="ownerPrincipalId")
407
+ purge_after: Optional[str] = Field(default=None, alias="purgeAfter")
408
+ recording_count: int = Field(alias="recordingCount")
409
+ settings: "Settings"
410
+ share_url: str = Field(alias="shareUrl")
411
+ source: "CaptureSource"
412
+ transcriptions: Optional[List["TranscriptionRef"]] = None
413
+ updated_at: str = Field(alias="updatedAt")
414
+
415
+
416
+ class BroadcastRef(_Base):
417
+ """A broadcast a live transcription feeds (`Transcription.broadcasts`)."""
418
+
419
+ access: Access
420
+ code: str
421
+ id: str
422
+ name: str
423
+ share_url: str = Field(alias="shareUrl")
424
+
425
+
426
+ class Limits(_Base):
427
+ audio_buffer_s: int = Field(alias="audioBufferS")
428
+ max_duration_s: int = Field(alias="maxDurationS")
429
+ max_upload_bytes: int = Field(alias="maxUploadBytes")
430
+ recording_max_duration_s: Optional[int] = Field(default=None, alias="recordingMaxDurationS")
431
+ session_token_ttl_s: int = Field(alias="sessionTokenTtlS")
432
+
433
+
434
+ class Capabilities(_Base):
435
+ audio: "AudioCapabilities"
436
+ languages: List[str]
437
+ latency_modes: List[LatencyMode] = Field(alias="latencyModes")
438
+ limits: "Limits"
439
+ speaker_label_modes: List[SpeakerLabels] = Field(alias="speakerLabelModes")
440
+
441
+
442
+ class CaptureSpan(_Base):
443
+ idx: int
444
+ media_end: Optional[float] = Field(default=None, alias="mediaEnd")
445
+ media_start: float = Field(alias="mediaStart")
446
+ reason: str
447
+ wall_end: Optional[float] = Field(default=None, alias="wallEnd")
448
+ wall_start: float = Field(alias="wallStart")
449
+
450
+
451
+ class RecordingCharge(_Base):
452
+ """A charge on the wire (`GET /v1/billing/charges`)."""
453
+
454
+ amount: float
455
+ kind: str
456
+ name: Optional[str] = None
457
+ opened_at: str = Field(alias="openedAt")
458
+ rate_per_hour: float = Field(alias="ratePerHour")
459
+ recording_id: str = Field(alias="recordingId")
460
+ seconds_billed: float = Field(alias="secondsBilled")
461
+ settled_at: Optional[str] = Field(default=None, alias="settledAt")
462
+ state: str
463
+ transcription_id: Optional[str] = Field(default=None, alias="transcriptionId")
464
+
465
+
466
+ class ChargePage(_Base):
467
+ """`GET /v1/billing/charges`."""
468
+
469
+ charges: List["RecordingCharge"]
470
+ next_cursor: Optional[str] = Field(default=None, alias="nextCursor")
471
+
472
+
473
+ class CheckPromoCode(_Base):
474
+ """`POST /v1/billing/promo-codes/check`."""
475
+
476
+ code: str
477
+ for_: str = Field(alias="for")
478
+
479
+
480
+ class CheckoutView(_Base):
481
+ """A checkout as the Dashboard sees it."""
482
+
483
+ amount: Optional[float] = None
484
+ checkout_id: str = Field(alias="checkoutId")
485
+ completed_at: Optional[str] = Field(default=None, alias="completedAt")
486
+ created_at: str = Field(alias="createdAt")
487
+ expires_at: Optional[str] = Field(default=None, alias="expiresAt")
488
+ interval: Optional[str] = None
489
+ kind: str
490
+ plan_id: Optional[str] = Field(default=None, alias="planId")
491
+ status: str
492
+ url: Optional[str] = None
493
+
494
+
495
+ class CommittedSegment(_Base):
496
+ catchup: Optional[bool] = None
497
+ confidence: Optional[float] = None
498
+ decoder: Optional[Decoder] = None
499
+ end: float
500
+ gap_before: Optional[float] = Field(default=None, alias="gapBefore")
501
+ language: Optional[str] = None
502
+ latency_s: Optional[float] = Field(default=None, alias="latencyS")
503
+ recognized_text: Optional[str] = Field(default=None, alias="recognizedText")
504
+ script_from: Optional[int] = Field(default=None, alias="scriptFrom")
505
+ script_pos: Optional[int] = Field(default=None, alias="scriptPos")
506
+ seq: int
507
+ speaker: int
508
+ speaker_confidence: Optional[float] = Field(default=None, alias="speakerConfidence")
509
+ speaker_provisional: Optional[bool] = Field(default=None, alias="speakerProvisional")
510
+ start: float
511
+ text: str
512
+ translation_sources: Optional[Dict[str, str]] = Field(default=None, alias="translationSources")
513
+ translations: Optional[Dict[str, str]] = None
514
+ words: List["Word"]
515
+
516
+
517
+ class Correction(_Base):
518
+ actor: "Actor"
519
+ applied_at: str = Field(alias="appliedAt")
520
+ batch_id: str = Field(alias="batchId")
521
+ from_: str = Field(alias="from")
522
+ id: str
523
+ kind: str
524
+ not_voiced_reason: Optional[NotVoicedReason] = Field(default=None, alias="notVoicedReason")
525
+ reverted_at: Optional[str] = Field(default=None, alias="revertedAt")
526
+ seq: Optional[int] = None
527
+ speaker: Optional[int] = None
528
+ to: str
529
+ voiced: Optional[bool] = None
530
+ word_idx: Optional[int] = Field(default=None, alias="wordIdx")
531
+
532
+
533
+ class WordEdit(_Base):
534
+ seq: int
535
+ to: str
536
+ word_idx: int = Field(alias="wordIdx")
537
+
538
+
539
+ class LineEdit(_Base):
540
+ """Retype a whole segment. The word count may change; the new words are
541
+ timed evenly across the segment's span and all count as settled."""
542
+
543
+ seq: int
544
+ to: str
545
+
546
+
547
+ class CorrectionBatch(_Base):
548
+ edits: Optional[List["WordEdit"]] = None
549
+ lines: Optional[List["LineEdit"]] = None
550
+
551
+
552
+ class CorrectionPage(_Base):
553
+ """`GET /v1/recordings/{id}/corrections`: one page, newest first."""
554
+
555
+ corrections: List["Correction"]
556
+ next_cursor: Optional[str] = Field(default=None, alias="nextCursor")
557
+
558
+
559
+ class CreateAudioSource(_Base):
560
+ """`POST /v1/broadcasts/{id}/audio-sources`."""
561
+
562
+ name: Optional[str] = None
563
+ url: str
564
+
565
+
566
+ class CreateBroadcast(_Base):
567
+ """`POST /v1/broadcasts`."""
568
+
569
+ access: Optional[Access] = None
570
+ code: Optional[str] = None
571
+ name: str
572
+ password: Optional[str] = None
573
+ settings: Optional["Settings"] = None
574
+ source: Optional["CaptureSource"] = None
575
+
576
+
577
+ class CreateCheckout(_Base):
578
+ """`POST /v1/billing/checkouts`."""
579
+
580
+ accept_terms: Optional[bool] = Field(default=None, alias="acceptTerms")
581
+ amount: Optional[float] = None
582
+ interval: Optional[str] = None
583
+ kind: str
584
+ plan_id: Optional[str] = Field(default=None, alias="planId")
585
+ promo_code: Optional[str] = Field(default=None, alias="promoCode")
586
+ waive_withdrawal: Optional[bool] = Field(default=None, alias="waiveWithdrawal")
587
+
588
+
589
+ class CreateLiveTranscription(_Base):
590
+ """`POST /v1/transcriptions/live`: a transcription captured as it is
591
+ spoken — this device's microphone, or a stream the server pulls.
592
+ It is created idle; `POST /v1/transcriptions/{id}/recordings` starts it."""
593
+
594
+ broadcasts: Optional[List[str]] = None
595
+ name: str
596
+ settings: Optional["Settings"] = None
597
+ source: Optional["CaptureSource"] = None
598
+
599
+
600
+ class CreateSessionResponse(_Base):
601
+ expires_at: str = Field(alias="expiresAt")
602
+ session_id: str = Field(alias="sessionId")
603
+ stream_url: str = Field(alias="streamUrl")
604
+
605
+
606
+ class CreateShareLink(_Base):
607
+ allow_download: Optional[bool] = Field(default=None, alias="allowDownload")
608
+ allow_export: Optional[bool] = Field(default=None, alias="allowExport")
609
+ allow_translate: Optional[bool] = Field(default=None, alias="allowTranslate")
610
+ label: str
611
+
612
+
613
+ class SettingsPatch(_Base):
614
+ """Partial update (PATCH) — every field optional, `null` for
615
+ `spokenLanguage` means back to auto-detect."""
616
+
617
+ confidence: Optional["ConfidencePolicy"] = None
618
+ latency_mode: Optional[LatencyMode] = Field(default=None, alias="latencyMode")
619
+ llm_fix: Optional[bool] = Field(default=None, alias="llmFix")
620
+ max_duration_s: Optional[int] = Field(default=None, alias="maxDurationS")
621
+ max_pause_s: Optional[int] = Field(default=None, alias="maxPauseS")
622
+ silence_auto_pause_s: Optional[int] = Field(default=None, alias="silenceAutoPauseS")
623
+ speaker_labels: Optional[SpeakerLabels] = Field(default=None, alias="speakerLabels")
624
+ spoken_language: Optional[str] = Field(default=None, alias="spokenLanguage")
625
+ voice: Optional[bool] = None
626
+ voice_by_lang: Optional[Dict[str, str]] = Field(default=None, alias="voiceByLang")
627
+
628
+
629
+ class CreateTranscription(_Base):
630
+ """`POST /v1/transcriptions`: JSON for a URL, or the `options` part of a
631
+ multipart upload whose `file` part carries the media."""
632
+
633
+ crop: Optional[bool] = None
634
+ duration_s: Optional[float] = Field(default=None, alias="durationS")
635
+ end_s: Optional[float] = Field(default=None, alias="endS")
636
+ name: Optional[str] = None
637
+ settings: Optional["SettingsPatch"] = None
638
+ share_link: Optional[bool] = Field(default=None, alias="shareLink")
639
+ start_s: Optional[float] = Field(default=None, alias="startS")
640
+ url: Optional[str] = None
641
+
642
+
643
+ class CreateVoice(_Base):
644
+ color: Optional[str] = None
645
+ consent: Optional[bool] = None
646
+ draft: Optional[bool] = None
647
+ gender: Optional[str] = None
648
+ name: str
649
+ sample_url: Optional[str] = Field(default=None, alias="sampleUrl")
650
+
651
+
652
+ class CreateVoiceFromSpeaker(_Base):
653
+ color: Optional[str] = None
654
+ consent: Optional[bool] = None
655
+ name: str
656
+ recording_id: str = Field(alias="recordingId")
657
+ speaker: int
658
+
659
+
660
+ class CropRange(_Base):
661
+ """A window of a file, in seconds into it. `end_s` absent = to the end."""
662
+
663
+ end_s: Optional[float] = Field(default=None, alias="endS")
664
+ start_s: Optional[float] = Field(default=None, alias="startS")
665
+
666
+
667
+ class CropWindow(_Base):
668
+ """A window of the source, in seconds into it. `end_s` absent = to the end."""
669
+
670
+ end_s: Optional[float] = Field(default=None, alias="endS")
671
+ start_s: float = Field(alias="startS")
672
+
673
+
674
+ class DraftSegment(_Base):
675
+ speaker: int
676
+ start: float
677
+ tentative: bool
678
+ text: str
679
+ translations: Optional[Dict[str, str]] = None
680
+
681
+
682
+ class EventOptions(_Base):
683
+ drafts: Optional[bool] = None
684
+ words: Optional[bool] = None
685
+
686
+
687
+ class Fix(_Base):
688
+ """One word-level correction inside a `transcript.amended` frame."""
689
+
690
+ kind: str
691
+ orig: str
692
+ repl: str
693
+
694
+
695
+ class Health(_Base):
696
+ status: HealthStatus
697
+
698
+
699
+ class InputOptions(_Base):
700
+ crop: Optional["CropRange"] = None
701
+ kind: Optional[InputKind] = None
702
+ prepare: Optional[bool] = None
703
+ url: Optional[str] = None
704
+
705
+
706
+ class JobProgress(_Base):
707
+ fetch_total_bytes: Optional[int] = Field(default=None, alias="fetchTotalBytes")
708
+ fetched_bytes: Optional[int] = Field(default=None, alias="fetchedBytes")
709
+ pct: int
710
+ phase: Optional[str] = None
711
+ phase_pct: Optional[int] = Field(default=None, alias="phasePct")
712
+ processed_s: float = Field(alias="processedS")
713
+ segments_done: int = Field(alias="segmentsDone")
714
+ segments_total: Optional[int] = Field(default=None, alias="segmentsTotal")
715
+ total_s: Optional[float] = Field(default=None, alias="totalS")
716
+
717
+
718
+ class KnownVoice(_Base):
719
+ """One voice a realtime session may recognise a speaker as.
720
+
721
+ The `id` is a cloned voice's id; the engine loads its embedding from
722
+ the same place it loads the voice itself, so a caller names the voice
723
+ and never carries a vector over the wire. `name` is what to call the
724
+ person when they are recognised — the voice's own name, ordinarily,
725
+ but the caller's to choose, because a voice called "Marcus —
726
+ narration" belongs to a person called Marcus Reed."""
727
+
728
+ color: Optional[str] = None
729
+ id: str
730
+ name: str
731
+
732
+
733
+ class LanguageInfo(_Base):
734
+ code: str
735
+ flag: Optional[str] = None
736
+ name: str
737
+ native: str
738
+ preview_line: Optional[str] = Field(default=None, alias="previewLine")
739
+ speakers_m: Optional[int] = Field(default=None, alias="speakersM")
740
+ transcription: bool
741
+ translation: bool
742
+ voice: bool
743
+
744
+
745
+ class LanguageLists(_Base):
746
+ languages: List["LanguageInfo"]
747
+ transcription: List[str]
748
+ translation: List[str]
749
+ voice: List[str]
750
+
751
+
752
+ class LedgerEntry(_Base):
753
+ """A ledger entry on the wire (`GET /v1/billing/ledger`)."""
754
+
755
+ amount: float
756
+ balance_after: float = Field(alias="balanceAfter")
757
+ created_at: str = Field(alias="createdAt")
758
+ description: str
759
+ id: str
760
+ kind: str
761
+ metadata: Any
762
+ provider_order_id: Optional[str] = Field(default=None, alias="providerOrderId")
763
+ realtime_session_id: Optional[str] = Field(default=None, alias="realtimeSessionId")
764
+ recording_id: Optional[str] = Field(default=None, alias="recordingId")
765
+ staff_user: Optional[str] = Field(default=None, alias="staffUser")
766
+ subscription_id: Optional[str] = Field(default=None, alias="subscriptionId")
767
+
768
+
769
+ class LedgerPage(_Base):
770
+ """`GET /v1/billing/ledger`."""
771
+
772
+ entries: List["LedgerEntry"]
773
+ next_cursor: Optional[str] = Field(default=None, alias="nextCursor")
774
+
775
+
776
+ class LinkProbe(_Base):
777
+ kind: LinkKind
778
+ ok: bool
779
+ problem: Optional[str] = None
780
+ source: str
781
+
782
+
783
+ class LowBalanceAlertChoices(_Base):
784
+ default: float
785
+ presets: List[float]
786
+ range: "MoneyRange"
787
+
788
+
789
+ class LowBalanceAlertSettings(_Base):
790
+ """`PUT /v1/billing/low-balance-alert`."""
791
+
792
+ enabled: bool
793
+ threshold: Optional[float] = None
794
+
795
+
796
+ class MediaSummary(_Base):
797
+ bytes: int
798
+ codec: str
799
+ container: str
800
+ duration_s: Optional[float] = Field(default=None, alias="durationS")
801
+ kind: str
802
+ state: str
803
+
804
+
805
+ class NameSpeaker(_Base):
806
+ name: Optional[str] = None
807
+
808
+
809
+ class PatchVoice(_Base):
810
+ color: Optional[str] = None
811
+ consent: Optional[bool] = None
812
+ draft: Optional[bool] = None
813
+ enabled: Optional[bool] = None
814
+ gender: Optional[str] = None
815
+ name: Optional[str] = None
816
+
817
+
818
+ class Payment(_Base):
819
+ """One line of the history."""
820
+
821
+ amount: float
822
+ at: str
823
+ description: str
824
+ document: Optional[str] = None
825
+ id: str
826
+ kind: str
827
+ status: str
828
+
829
+
830
+ class PaymentDocument(_Base):
831
+ """`GET /v1/billing/payments/:id/document`: `url` when it is ready,
832
+ `pending: true` (with `202`) while the provider makes it."""
833
+
834
+ pending: Optional[bool] = None
835
+ url: Optional[str] = None
836
+
837
+
838
+ class PaymentMethodView(_Base):
839
+ """One saved method."""
840
+
841
+ brand: str
842
+ declined: bool
843
+ exp_month: Optional[int] = Field(default=None, alias="expMonth")
844
+ exp_year: Optional[int] = Field(default=None, alias="expYear")
845
+ id: str
846
+ is_default: bool = Field(alias="isDefault")
847
+ last4: str
848
+ wallet: Optional[str] = None
849
+
850
+
851
+ class PaymentMethodList(_Base):
852
+ """`GET /v1/billing/payment-methods`."""
853
+
854
+ methods: List["PaymentMethodView"]
855
+
856
+
857
+ class PaymentPage(_Base):
858
+ """`GET /v1/billing/payments`."""
859
+
860
+ next_cursor: Optional[str] = Field(default=None, alias="nextCursor")
861
+ payments: List["Payment"]
862
+
863
+
864
+ class PlanListing(_Base):
865
+ """One plan on the price list: its current version's rates, prices,
866
+ credit, limits and features."""
867
+
868
+ billed_externally: bool = Field(alias="billedExternally")
869
+ features: Any
870
+ grace_on_zero: bool = Field(alias="graceOnZero")
871
+ id: str
872
+ kind: str
873
+ limits: "Limits2"
874
+ monthly_credit: float = Field(alias="monthlyCredit")
875
+ name: str
876
+ price_month: float = Field(alias="priceMonth")
877
+ price_year: float = Field(alias="priceYear")
878
+ rates: "Rates"
879
+ warm_start: str = Field(alias="warmStart")
880
+
881
+
882
+ class PlanList(_Base):
883
+ """`GET /v1/billing/plans`."""
884
+
885
+ auto_top_up: "AutoTopUpChoices" = Field(alias="autoTopUp")
886
+ downgrade_grace_days: int = Field(alias="downgradeGraceDays")
887
+ enabled: bool
888
+ low_balance_alert: "LowBalanceAlertChoices" = Field(alias="lowBalanceAlert")
889
+ plans: List["PlanListing"]
890
+ signup_credit: float = Field(alias="signupCredit")
891
+ top_up_amounts: List[float] = Field(alias="topUpAmounts")
892
+ top_up_range: "MoneyRange" = Field(alias="topUpRange")
893
+
894
+
895
+ class PortalLink(_Base):
896
+ """`GET /v1/billing/portal`."""
897
+
898
+ url: str
899
+
900
+
901
+ class PromoCodeView(_Base):
902
+ """What a promo code gives for the purchase it was checked for."""
903
+
904
+ bonus_credit: Optional[float] = Field(default=None, alias="bonusCredit")
905
+ code: str
906
+ description: str
907
+ first_payment_discount: Optional[float] = Field(default=None, alias="firstPaymentDiscount")
908
+
909
+
910
+ class StreamIngest(_Base):
911
+ """The server-side publisher of a stream source's recording, on the
912
+ `Recording` DTO as `ingest`."""
913
+
914
+ attempts: int
915
+ bytes_in: int = Field(alias="bytesIn")
916
+ detected: Optional[str] = None
917
+ error: Optional[str] = None
918
+ failures: int
919
+ finished_at: Optional[str] = Field(default=None, alias="finishedAt")
920
+ last_audio_at: Optional[str] = Field(default=None, alias="lastAudioAt")
921
+ media_at: Optional[str] = Field(default=None, alias="mediaAt")
922
+ media_s: float = Field(alias="mediaS")
923
+ started_at: Optional[str] = Field(default=None, alias="startedAt")
924
+ state: IngestState
925
+ stream_started_at: Optional[str] = Field(default=None, alias="streamStartedAt")
926
+ updated_at: str = Field(alias="updatedAt")
927
+ url: str
928
+
929
+
930
+ class RecordingMetrics(_Base):
931
+ settle_p50_s: Optional[float] = Field(default=None, alias="settleP50S")
932
+ settle_p95_s: Optional[float] = Field(default=None, alias="settleP95S")
933
+ silence_paused: int = Field(alias="silencePaused")
934
+ suppressed_segments: Optional[int] = Field(default=None, alias="suppressedSegments")
935
+ translation_latency_p50_s: Optional[float] = Field(default=None, alias="translationLatencyP50S")
936
+
937
+
938
+ class PublisherInfo(_Base):
939
+ attached: bool
940
+ lease_expires_at: Optional[str] = Field(default=None, alias="leaseExpiresAt")
941
+ machine_id: Optional[str] = Field(default=None, alias="machineId")
942
+
943
+
944
+ class SourceInfo(_Base):
945
+ """What the recording was made from (design `j.meta`: "M4A · 34.2 MB",
946
+ "Video URL")."""
947
+
948
+ bytes: Optional[int] = None
949
+ duration_s: Optional[float] = Field(default=None, alias="durationS")
950
+ format: Optional[str] = None
951
+ kind: SourceKind
952
+ mime: Optional[str] = None
953
+ name: str
954
+ url: Optional[str] = None
955
+
956
+
957
+ class Recording(_Base):
958
+ created_at: str = Field(alias="createdAt")
959
+ end_reason: Optional[str] = Field(default=None, alias="endReason")
960
+ ended_at: Optional[str] = Field(default=None, alias="endedAt")
961
+ finalized_at: Optional[str] = Field(default=None, alias="finalizedAt")
962
+ id: str
963
+ ingest: Optional["StreamIngest"] = None
964
+ kind: RecordingKind
965
+ last_seq: int = Field(alias="lastSeq")
966
+ lifecycle: Lifecycle
967
+ max_duration_s: int = Field(alias="maxDurationS")
968
+ max_pause_s: int = Field(alias="maxPauseS")
969
+ media: List["MediaSummary"]
970
+ media_duration_s: Optional[float] = Field(default=None, alias="mediaDurationS")
971
+ metrics: Optional["RecordingMetrics"] = None
972
+ peak_latency_s: Optional[float] = Field(default=None, alias="peakLatencyS")
973
+ peak_listeners: Optional[int] = Field(default=None, alias="peakListeners")
974
+ publisher: "PublisherInfo"
975
+ script_id: Optional[str] = Field(default=None, alias="scriptId")
976
+ script_text: Optional[str] = Field(default=None, alias="scriptText")
977
+ settings: "Settings"
978
+ source: Optional["SourceInfo"] = None
979
+ spans: List["CaptureSpan"]
980
+ speaker_count: Optional[int] = Field(default=None, alias="speakerCount")
981
+ spoken_language: Optional[str] = Field(default=None, alias="spokenLanguage")
982
+ started_at: Optional[str] = Field(default=None, alias="startedAt")
983
+ state: RecordingState
984
+ summarized_at: Optional[str] = Field(default=None, alias="summarizedAt")
985
+ summary: Optional[str] = None
986
+ summary_language: Optional[str] = Field(default=None, alias="summaryLanguage")
987
+ title: Optional[str] = None
988
+ transcription_id: str = Field(alias="transcriptionId")
989
+ wall_duration_s: Optional[float] = Field(default=None, alias="wallDurationS")
990
+
991
+
992
+ class PublishGrant(_Base):
993
+ expires_at: Optional[str] = Field(default=None, alias="expiresAt")
994
+ recording: "Recording"
995
+ session_id: Optional[str] = Field(default=None, alias="sessionId")
996
+ stream_url: Optional[str] = Field(default=None, alias="streamUrl")
997
+
998
+
999
+ class RecordingEvent(_Base):
1000
+ """One durable frame of a recording, as the host's screen received it."""
1001
+
1002
+ at: str
1003
+ kind: str
1004
+ payload: Any
1005
+ seq: int
1006
+
1007
+
1008
+ class RecordingEvents(_Base):
1009
+ """`GET /v1/recordings/{id}/events`: one page of the log, in order."""
1010
+
1011
+ events: List["RecordingEvent"]
1012
+ next_cursor: Optional[str] = Field(default=None, alias="nextCursor")
1013
+
1014
+
1015
+ class RecordingPage(_Base):
1016
+ """A broadcast's or a transcription's recordings, one page, newest first."""
1017
+
1018
+ next_cursor: Optional[str] = Field(default=None, alias="nextCursor")
1019
+ recordings: List["Recording"]
1020
+
1021
+
1022
+ class RetranscribeLine(_Base):
1023
+ """Design 50: read one line's audio again in a named language.
1024
+
1025
+ Not an edit the caller writes — an edit the caller ASKS FOR: the text
1026
+ comes from the recognizer, and lands as the same `line` corrections a
1027
+ hand-typed rewrite would."""
1028
+
1029
+ lang: str
1030
+ seqs: List[int]
1031
+
1032
+
1033
+ class RtmpStatus(_Base):
1034
+ """`GET /v1/rtmp`: what the setup panel shows."""
1035
+
1036
+ audio: Optional[str] = None
1037
+ enabled: bool
1038
+ live: bool
1039
+ masked_stream_key: str = Field(alias="maskedStreamKey")
1040
+ monitor_url: str = Field(alias="monitorUrl")
1041
+ server_url: str = Field(alias="serverUrl")
1042
+ stream_key: Optional[str] = Field(default=None, alias="streamKey")
1043
+
1044
+
1045
+ class SearchHit(_Base):
1046
+ link_code: str = Field(alias="linkCode")
1047
+ link_name: str = Field(alias="linkName")
1048
+ live: bool
1049
+ media_start: float = Field(alias="mediaStart")
1050
+ recorded_at: Optional[str] = Field(default=None, alias="recordedAt")
1051
+ recording_id: str = Field(alias="recordingId")
1052
+ rendered: Optional[str] = None
1053
+ score: float
1054
+ sentence_id: int = Field(alias="sentenceId")
1055
+ speaker: int
1056
+ text: str
1057
+ transcription_id: str = Field(alias="transcriptionId")
1058
+ wall_start: float = Field(alias="wallStart")
1059
+
1060
+
1061
+ class SearchResults(_Base):
1062
+ hits: List["SearchHit"]
1063
+ query: str
1064
+ query_en: str = Field(alias="queryEn")
1065
+
1066
+
1067
+ class SegmentView(_Base):
1068
+ catchup: bool
1069
+ confidence: Optional[float] = None
1070
+ corrected: bool
1071
+ decoder: Optional[str] = None
1072
+ end: float
1073
+ gap_before: Optional[float] = Field(default=None, alias="gapBefore")
1074
+ language: Optional[str] = None
1075
+ latency_s: Optional[float] = Field(default=None, alias="latencyS")
1076
+ script_from: Optional[int] = Field(default=None, alias="scriptFrom")
1077
+ script_pos: Optional[int] = Field(default=None, alias="scriptPos")
1078
+ seq: int
1079
+ settled: bool
1080
+ speaker: int
1081
+ speaker_confidence: Optional[float] = Field(default=None, alias="speakerConfidence")
1082
+ start: float
1083
+ suppressed: Optional[bool] = None
1084
+ text: str
1085
+ translations: Optional[Dict[str, str]] = None
1086
+ unclear: Optional[bool] = None
1087
+ wall_start: float = Field(alias="wallStart")
1088
+ words: Optional[List["Word"]] = None
1089
+
1090
+
1091
+ class SentenceOptions(_Base):
1092
+ enabled: Optional[bool] = None
1093
+ idle_close_s: Optional[float] = Field(default=None, alias="idleCloseS")
1094
+ provisional_translations: Optional[bool] = Field(default=None, alias="provisionalTranslations")
1095
+
1096
+
1097
+ class SentenceSegment(_Base):
1098
+ close_reason: Optional[str] = Field(default=None, alias="closeReason")
1099
+ end: float
1100
+ language: Optional[str] = None
1101
+ provisional: Optional[bool] = None
1102
+ sentence_id: int = Field(alias="sentenceId")
1103
+ seqs: List[int]
1104
+ settled: Optional[bool] = None
1105
+ speaker: int
1106
+ start: float
1107
+ status: SentenceStatus
1108
+ text: str
1109
+ translation_latency_s: Optional[Dict[str, float]] = Field(default=None, alias="translationLatencyS")
1110
+ translation_sources: Optional[Dict[str, str]] = Field(default=None, alias="translationSources")
1111
+ translations: Optional[Dict[str, str]] = None
1112
+
1113
+
1114
+ class SentenceView(_Base):
1115
+ end: float
1116
+ language: Optional[str] = None
1117
+ provisional: Optional[bool] = None
1118
+ sentence_id: int = Field(alias="sentenceId")
1119
+ seqs: List[int]
1120
+ settled: bool
1121
+ speaker: int
1122
+ start: float
1123
+ status: str
1124
+ suppressed: Optional[bool] = None
1125
+ text: str
1126
+ translations: Optional[Dict[str, str]] = None
1127
+ unclear: Optional[bool] = None
1128
+ wall_start: float = Field(alias="wallStart")
1129
+
1130
+
1131
+ class SessionStats(_Base):
1132
+ audio_s: float = Field(alias="audioS")
1133
+ processing_s: float = Field(alias="processingS")
1134
+ realtime_factor: float = Field(alias="realtimeFactor")
1135
+
1136
+
1137
+ class SessionOptions(_Base):
1138
+ audio: Optional["AudioFormat"] = None
1139
+ events: Optional["EventOptions"] = None
1140
+ identify_voices: Optional[List["KnownVoice"]] = Field(default=None, alias="identifyVoices")
1141
+ input: Optional["InputOptions"] = None
1142
+ latency_mode: Optional[LatencyMode] = Field(default=None, alias="latencyMode")
1143
+ llm_fix: Optional[bool] = Field(default=None, alias="llmFix")
1144
+ sentences: Optional["SentenceOptions"] = None
1145
+ speaker_labels: Optional[SpeakerLabels] = Field(default=None, alias="speakerLabels")
1146
+ spoken_language: Optional[str] = Field(default=None, alias="spokenLanguage")
1147
+ translate: Optional[List[str]] = None
1148
+ voice: Optional[List[str]] = None
1149
+ voice_by_lang: Optional[Dict[str, str]] = Field(default=None, alias="voiceByLang")
1150
+ voice_cast: Optional[bool] = Field(default=None, alias="voiceCast")
1151
+
1152
+
1153
+ class SetInterval(_Base):
1154
+ """`POST /v1/billing/subscription/interval`."""
1155
+
1156
+ interval: str
1157
+
1158
+
1159
+ class ShareLink(_Base):
1160
+ """The broadcast or transcription something belongs to (a script, a share
1161
+ link): exactly one of `broadcastId` and `transcriptionId` is set.
1162
+ Flattened into its owner."""
1163
+
1164
+ allow_download: bool = Field(alias="allowDownload")
1165
+ allow_export: bool = Field(alias="allowExport")
1166
+ allow_translate: bool = Field(alias="allowTranslate")
1167
+ broadcast_id: Optional[str] = Field(default=None, alias="broadcastId")
1168
+ code: str
1169
+ created_at: str = Field(alias="createdAt")
1170
+ id: str
1171
+ label: str
1172
+ last_viewed_at: Optional[str] = Field(default=None, alias="lastViewedAt")
1173
+ revoked_at: Optional[str] = Field(default=None, alias="revokedAt")
1174
+ transcription_id: Optional[str] = Field(default=None, alias="transcriptionId")
1175
+ url: str
1176
+ views: int
1177
+
1178
+
1179
+ class SpeakerView(_Base):
1180
+ gender: Optional[str] = None
1181
+ gender_confidence: Optional[float] = Field(default=None, alias="genderConfidence")
1182
+ identified: Optional[bool] = None
1183
+ identified_confidence: Optional[float] = Field(default=None, alias="identifiedConfidence")
1184
+ name: str
1185
+ speaker: int
1186
+ voice_color: Optional[str] = Field(default=None, alias="voiceColor")
1187
+ voice_id: Optional[str] = Field(default=None, alias="voiceId")
1188
+
1189
+
1190
+ class StartJob(_Base):
1191
+ """`POST /v1/recordings/{id}/job/start`: the window a job in
1192
+ `cropping` should transcribe. Both bounds optional: the start of the
1193
+ file and its end."""
1194
+
1195
+ end_s: Optional[float] = Field(default=None, alias="endS")
1196
+ start_s: Optional[float] = Field(default=None, alias="startS")
1197
+
1198
+
1199
+ class StartRecording(_Base):
1200
+ audio_source: Optional[str] = Field(default=None, alias="audioSource")
1201
+ device_id: Optional[str] = Field(default=None, alias="deviceId")
1202
+ script_id: Optional[str] = Field(default=None, alias="scriptId")
1203
+ script_text: Optional[str] = Field(default=None, alias="scriptText")
1204
+ settings: Optional["SettingsPatch"] = None
1205
+ takeover: Optional[bool] = None
1206
+
1207
+
1208
+ class StopRequest(_Base):
1209
+ reason: Optional[str] = None
1210
+
1211
+
1212
+ class SummaryStatus(_Base):
1213
+ """Where a recording's summary stands, for `POST /v1/recordings/:id/summarize`."""
1214
+
1215
+ lang: Optional[str] = None
1216
+ state: str
1217
+ summary: Optional[str] = None
1218
+ title: Optional[str] = None
1219
+
1220
+
1221
+ class TranscriptSnapshot(_Base):
1222
+ lang: Optional[str] = None
1223
+ last_seq: int = Field(alias="lastSeq")
1224
+ recording_id: str = Field(alias="recordingId")
1225
+ segments: List["SegmentView"]
1226
+ sentences: List["SentenceView"]
1227
+ spans: List["CaptureSpan"]
1228
+ speaker_labels: Optional[SpeakerLabels] = Field(default=None, alias="speakerLabels")
1229
+ speakers: List["SpeakerView"]
1230
+ state: RecordingState
1231
+
1232
+
1233
+ class TranscriptionJob(_Base):
1234
+ attempts: int
1235
+ created_at: str = Field(alias="createdAt")
1236
+ crop: Optional["CropWindow"] = None
1237
+ error: Optional[str] = None
1238
+ error_code: Optional[str] = Field(default=None, alias="errorCode")
1239
+ finished_at: Optional[str] = Field(default=None, alias="finishedAt")
1240
+ has_audio: bool = Field(alias="hasAudio")
1241
+ peaks: Optional[List[float]] = None
1242
+ preview: Optional[bool] = None
1243
+ progress: "JobProgress"
1244
+ recording_id: str = Field(alias="recordingId")
1245
+ source: Optional["SourceInfo"] = None
1246
+ started_at: Optional[str] = Field(default=None, alias="startedAt")
1247
+ state: JobState
1248
+ transcription_id: str = Field(alias="transcriptionId")
1249
+
1250
+
1251
+ class Transcription(_Base):
1252
+ """A transcription: a file, a link (with its `transcription` job), or
1253
+ something captured as it is spoken (`live: true`: a microphone, a
1254
+ stream, an RTMP encoder), which may feed broadcasts (`broadcasts`)."""
1255
+
1256
+ archived_at: Optional[str] = Field(default=None, alias="archivedAt")
1257
+ broadcasts: Optional[List["BroadcastRef"]] = None
1258
+ code: str
1259
+ created_at: str = Field(alias="createdAt")
1260
+ created_by_api_key_id: Optional[str] = Field(default=None, alias="createdByApiKeyId")
1261
+ current_recording: Optional["CurrentRecording"] = Field(default=None, alias="currentRecording")
1262
+ id: str
1263
+ job: Optional["TranscriptionJob"] = None
1264
+ kind: Literal["transcription"] = "transcription"
1265
+ last_recorded_at: Optional[str] = Field(default=None, alias="lastRecordedAt")
1266
+ last_recording: Optional["LastRecording"] = Field(default=None, alias="lastRecording")
1267
+ lifecycle: Lifecycle
1268
+ live: Optional[bool] = None
1269
+ name: str
1270
+ owner_principal_id: str = Field(alias="ownerPrincipalId")
1271
+ purge_after: Optional[str] = Field(default=None, alias="purgeAfter")
1272
+ recording_count: int = Field(alias="recordingCount")
1273
+ settings: "Settings"
1274
+ share_url: str = Field(alias="shareUrl")
1275
+ source: "CaptureSource"
1276
+ updated_at: str = Field(alias="updatedAt")
1277
+
1278
+
1279
+ class TranscriptionPage(_Base):
1280
+ """`GET /v1/transcriptions`: one page, newest first."""
1281
+
1282
+ next_cursor: Optional[str] = Field(default=None, alias="nextCursor")
1283
+ transcriptions: List["Transcription"]
1284
+
1285
+
1286
+ class UpdateBroadcast(_Base):
1287
+ """`PATCH /v1/broadcasts/{id}`: fields left out are unchanged."""
1288
+
1289
+ access: Optional[Access] = None
1290
+ code: Optional[str] = None
1291
+ name: Optional[str] = None
1292
+ password: Optional[str] = None
1293
+ settings: Optional["SettingsPatch"] = None
1294
+
1295
+
1296
+ class UpdateShareLink(_Base):
1297
+ allow_download: Optional[bool] = Field(default=None, alias="allowDownload")
1298
+ allow_export: Optional[bool] = Field(default=None, alias="allowExport")
1299
+ allow_translate: Optional[bool] = Field(default=None, alias="allowTranslate")
1300
+ label: Optional[str] = None
1301
+
1302
+
1303
+ class UpdateTranscription(_Base):
1304
+ """`PATCH /v1/transcriptions/{id}`: fields left out are unchanged. A
1305
+ transcription is shared through its share links, so it has no access,
1306
+ password or link to change here."""
1307
+
1308
+ name: Optional[str] = None
1309
+ settings: Optional["SettingsPatch"] = None
1310
+
1311
+
1312
+ class UploadRecording(_Base):
1313
+ settings: Optional["SettingsPatch"] = None
1314
+ url: Optional[str] = None
1315
+
1316
+
1317
+ class UsageRow(_Base):
1318
+ """One day, source and kind."""
1319
+
1320
+ amount: float
1321
+ date: str
1322
+ kind: str
1323
+ seconds: float
1324
+ source: str
1325
+
1326
+
1327
+ class UsageSource(_Base):
1328
+ """Where usage came from."""
1329
+
1330
+ id: str
1331
+ name: str
1332
+ prefix: Optional[str] = None
1333
+ revoked: bool
1334
+
1335
+
1336
+ class UsageReport(_Base):
1337
+ """`GET /v1/billing/usage`."""
1338
+
1339
+ end_date: str = Field(alias="endDate")
1340
+ rows: List["UsageRow"]
1341
+ sources: List["UsageSource"]
1342
+ start_date: str = Field(alias="startDate")
1343
+ total: float
1344
+ tz: str
1345
+
1346
+
1347
+ class Voice(_Base):
1348
+ color: Optional[str] = None
1349
+ consent_at: Optional[str] = Field(default=None, alias="consentAt")
1350
+ created_at: str = Field(alias="createdAt")
1351
+ draft: bool
1352
+ enabled: bool
1353
+ error: Optional[str] = None
1354
+ gender: Optional[str] = None
1355
+ id: str
1356
+ name: str
1357
+ preview_url: Optional[str] = Field(default=None, alias="previewUrl")
1358
+ progress: int
1359
+ sample_s: float = Field(alias="sampleS")
1360
+ speech_s: Optional[float] = Field(default=None, alias="speechS")
1361
+ state: str
1362
+ updated_at: str = Field(alias="updatedAt")
1363
+ uses: int
1364
+
1365
+
1366
+ class VoiceOption(_Base):
1367
+ accent: Optional[str] = None
1368
+ cloned: bool
1369
+ default: bool
1370
+ gender: Optional[str] = None
1371
+ id: str
1372
+ lag_s: Optional[float] = Field(default=None, alias="lagS")
1373
+ name: str
1374
+ preview_url: Optional[str] = Field(default=None, alias="previewUrl")
1375
+ quality: int
1376
+ ready: Optional[bool] = None
1377
+ speakers: Optional[int] = None
1378
+
1379
+
1380
+ class VoiceCatalogue(_Base):
1381
+ lang: str
1382
+ voices: List["VoiceOption"]
1383
+
1384
+
1385
+ class VoiceTrack(_Base):
1386
+ clip_dur: Optional[Dict[str, float]] = Field(default=None, alias="clipDur")
1387
+ clip_parts: Optional[Dict[str, int]] = Field(default=None, alias="clipParts")
1388
+ clip_rev: Optional[Dict[str, str]] = Field(default=None, alias="clipRev")
1389
+ clips: List[int]
1390
+ duration_s: Optional[float] = Field(default=None, alias="durationS")
1391
+ error: Optional[str] = None
1392
+ lang: str
1393
+ state: str
1394
+ voice: Optional[str] = None
1395
+ voice_key: str = Field(alias="voiceKey")
1396
+ word_times: Optional[Dict[str, List[List[float]]]] = Field(default=None, alias="wordTimes")
1397
+
1398
+
1399
+ class CaptureSourceMic(_Base):
1400
+ kind: Literal["mic"] = "mic"
1401
+
1402
+
1403
+ class CaptureSourceStream(_Base):
1404
+ kind: Literal["stream"] = "stream"
1405
+ url: str
1406
+
1407
+
1408
+ CaptureSource = Annotated[Union[CaptureSourceMic, CaptureSourceStream], Field(discriminator="kind")]
1409
+
1410
+ class Eof(_Base):
1411
+ type: Literal["eof"] = "eof"
1412
+
1413
+
1414
+ class Cancel(_Base):
1415
+ type: Literal["cancel"] = "cancel"
1416
+
1417
+
1418
+ class SessionUpdate(_Base):
1419
+ latency_mode: Optional[LatencyMode] = Field(default=None, alias="latencyMode")
1420
+ llm_fix: Optional[bool] = Field(default=None, alias="llmFix")
1421
+ speaker_labels: Optional[SpeakerLabels] = Field(default=None, alias="speakerLabels")
1422
+ spoken_language: Optional[str] = Field(default=None, alias="spokenLanguage")
1423
+ translate: Optional[List[str]] = None
1424
+ type: Literal["session.update"] = "session.update"
1425
+ voice: Optional[List[str]] = None
1426
+ voice_by_lang: Optional[Dict[str, str]] = Field(default=None, alias="voiceByLang")
1427
+
1428
+
1429
+ class Clock(_Base):
1430
+ pcm: int
1431
+ type: Literal["clock"] = "clock"
1432
+ wall: float
1433
+
1434
+
1435
+ ClientFrame = Annotated[Union[Eof, Cancel, SessionUpdate, Clock], Field(discriminator="type")]
1436
+
1437
+ class SessionLoading(_Base):
1438
+ stage: LoadingStage
1439
+ type: Literal["session.loading"] = "session.loading"
1440
+
1441
+
1442
+ class SessionReady(_Base):
1443
+ type: Literal["session.ready"] = "session.ready"
1444
+
1445
+
1446
+ class TranscriptCommitted(_Base):
1447
+ segment: "CommittedSegment"
1448
+ type: Literal["transcript.committed"] = "transcript.committed"
1449
+
1450
+
1451
+ class TranscriptDraft(_Base):
1452
+ segments: List["DraftSegment"]
1453
+ type: Literal["transcript.draft"] = "transcript.draft"
1454
+
1455
+
1456
+ class TranscriptWords(_Base):
1457
+ type: Literal["transcript.words"] = "transcript.words"
1458
+ words: List["Word"]
1459
+
1460
+
1461
+ class TranscriptAmended(_Base):
1462
+ fixes: Optional[List["Fix"]] = None
1463
+ script_words: Optional[List[int]] = Field(default=None, alias="scriptWords")
1464
+ seq: int
1465
+ speaker: int
1466
+ speaker_confidence: Optional[float] = Field(default=None, alias="speakerConfidence")
1467
+ tail: Optional["AmendTail"] = None
1468
+ text: str
1469
+ type: Literal["transcript.amended"] = "transcript.amended"
1470
+
1471
+
1472
+ class TranscriptLatency(_Base):
1473
+ latency_s: float = Field(alias="latencyS")
1474
+ seq: int
1475
+ type: Literal["transcript.latency"] = "transcript.latency"
1476
+
1477
+
1478
+ class TranscriptSpeaker(_Base):
1479
+ seq: int
1480
+ speaker: int
1481
+ speaker_confidence: Optional[float] = Field(default=None, alias="speakerConfidence")
1482
+ type: Literal["transcript.speaker"] = "transcript.speaker"
1483
+ verdict: str
1484
+
1485
+
1486
+ class TranscriptSpeakerGender(_Base):
1487
+ confidence: Optional[float] = None
1488
+ gender: str
1489
+ speaker: int
1490
+ type: Literal["transcript.speakerGender"] = "transcript.speakerGender"
1491
+
1492
+
1493
+ class TranscriptSpeakerIdentified(_Base):
1494
+ color: Optional[str] = None
1495
+ confidence: Optional[float] = None
1496
+ name: str
1497
+ speaker: int
1498
+ tone: Optional[bool] = None
1499
+ type: Literal["transcript.speakerIdentified"] = "transcript.speakerIdentified"
1500
+ voice_id: Optional[str] = Field(default=None, alias="voiceId")
1501
+
1502
+
1503
+ class TranscriptSentence(_Base):
1504
+ sentence: "SentenceSegment"
1505
+ type: Literal["transcript.sentence"] = "transcript.sentence"
1506
+
1507
+
1508
+ class TranscriptTranslated(_Base):
1509
+ seq: int
1510
+ sources: Optional[Dict[str, str]] = None
1511
+ translations: Dict[str, str]
1512
+ type: Literal["transcript.translated"] = "transcript.translated"
1513
+
1514
+
1515
+ class TranscriptVoice(_Base):
1516
+ audio: Optional[str] = None
1517
+ cloned: Optional[bool] = None
1518
+ duration_s: float = Field(alias="durationS")
1519
+ format: str
1520
+ generation: int
1521
+ lang: str
1522
+ latency_s: Optional[float] = Field(default=None, alias="latencyS")
1523
+ part: Optional[int] = None
1524
+ parts: Optional[int] = None
1525
+ queue_wait_s: Optional[float] = Field(default=None, alias="queueWaitS")
1526
+ sentence_id: int = Field(alias="sentenceId")
1527
+ speaker_to_audio_s: Optional[float] = Field(default=None, alias="speakerToAudioS")
1528
+ synth_s: float = Field(alias="synthS")
1529
+ translation_latency_s: Optional[float] = Field(default=None, alias="translationLatencyS")
1530
+ type: Literal["transcript.voice"] = "transcript.voice"
1531
+ url: Optional[str] = None
1532
+ voice: Optional[str] = None
1533
+ voice_key: Optional[str] = Field(default=None, alias="voiceKey")
1534
+
1535
+
1536
+ class TranscriptVoiceStatus(_Base):
1537
+ detail: str
1538
+ lang: str
1539
+ state: VoiceStatusState
1540
+ type: Literal["transcript.voiceStatus"] = "transcript.voiceStatus"
1541
+ voice_key: Optional[str] = Field(default=None, alias="voiceKey")
1542
+
1543
+
1544
+ class TranscriptProgress(_Base):
1545
+ processed_s: float = Field(alias="processedS")
1546
+ total_s: Optional[float] = Field(default=None, alias="totalS")
1547
+ type: Literal["transcript.progress"] = "transcript.progress"
1548
+
1549
+
1550
+ class StreamPull(_Base):
1551
+ bytes_in: int = Field(alias="bytesIn")
1552
+ detected: Optional[str] = None
1553
+ error: Optional[str] = None
1554
+ failures: int
1555
+ media_s: float = Field(alias="mediaS")
1556
+ program_at_ms: Optional[int] = Field(default=None, alias="programAtMs")
1557
+ sequence_offset_ms: Optional[int] = Field(default=None, alias="sequenceOffsetMs")
1558
+ state: PullState
1559
+ type: Literal["stream.pull"] = "stream.pull"
1560
+
1561
+
1562
+ class SourceProgress(_Base):
1563
+ bytes: int
1564
+ done_s: float = Field(alias="doneS")
1565
+ phase: str
1566
+ total: Optional[int] = None
1567
+ total_s: Optional[float] = Field(default=None, alias="totalS")
1568
+ type: Literal["source.progress"] = "source.progress"
1569
+
1570
+
1571
+ class SourcePrepared(_Base):
1572
+ duration_s: Optional[float] = Field(default=None, alias="durationS")
1573
+ peaks: Optional[List[float]] = None
1574
+ type: Literal["source.prepared"] = "source.prepared"
1575
+
1576
+
1577
+ class SessionDone(_Base):
1578
+ reason: DoneReason
1579
+ stats: "SessionStats"
1580
+ type: Literal["session.done"] = "session.done"
1581
+
1582
+
1583
+ class ErrorFrame(_Base):
1584
+ code: ErrorCode
1585
+ message: str
1586
+ retryable: bool
1587
+ type: Literal["error"] = "error"
1588
+
1589
+
1590
+ ServerFrame = Annotated[Union[SessionLoading, SessionReady, TranscriptCommitted, TranscriptDraft, TranscriptWords, TranscriptAmended, TranscriptLatency, TranscriptSpeaker, TranscriptSpeakerGender, TranscriptSpeakerIdentified, TranscriptSentence, TranscriptTranslated, TranscriptVoice, TranscriptVoiceStatus, TranscriptProgress, StreamPull, SourceProgress, SourcePrepared, SessionDone, ErrorFrame], Field(discriminator="type")]
1591
+
1592
+ class SubscribeUpdate(_Base):
1593
+ audio: Optional[bool] = None
1594
+ lang: Optional[str] = None
1595
+ type: Literal["subscribe.update"] = "subscribe.update"
1596
+
1597
+
1598
+ class Ping(_Base):
1599
+ type: Literal["ping"] = "ping"
1600
+
1601
+
1602
+ SubscriberClientFrame = Annotated[Union[SubscribeUpdate, Ping], Field(discriminator="type")]
1603
+
1604
+ class SubscribeReady(_Base):
1605
+ instance: str
1606
+ last_seq: int = Field(alias="lastSeq")
1607
+ recording_id: str = Field(alias="recordingId")
1608
+ state: RecordingState
1609
+ type: Literal["subscribe.ready"] = "subscribe.ready"
1610
+
1611
+
1612
+ class RecordingState(_Base):
1613
+ media_s: Optional[float] = Field(default=None, alias="mediaS")
1614
+ reason: Optional[str] = None
1615
+ recording_id: str = Field(alias="recordingId")
1616
+ state: RecordingState
1617
+ type: Literal["recording.state"] = "recording.state"
1618
+
1619
+
1620
+ class RecordingSettings(_Base):
1621
+ recording_id: str = Field(alias="recordingId")
1622
+ settings: Any
1623
+ type: Literal["recording.settings"] = "recording.settings"
1624
+
1625
+
1626
+ class RecordingSilence(_Base):
1627
+ pauses_in_s: float = Field(alias="pausesInS")
1628
+ recording_id: str = Field(alias="recordingId")
1629
+ silent_s: float = Field(alias="silentS")
1630
+ type: Literal["recording.silence"] = "recording.silence"
1631
+
1632
+
1633
+ class RecordingExpiring(_Base):
1634
+ ends_in_s: float = Field(alias="endsInS")
1635
+ recording_id: str = Field(alias="recordingId")
1636
+ type: Literal["recording.expiring"] = "recording.expiring"
1637
+
1638
+
1639
+ class TranscriptCorrected(_Base):
1640
+ actor: Optional["Actor"] = None
1641
+ from_: str = Field(alias="from")
1642
+ reverted: bool
1643
+ sentence_id: Optional[int] = Field(default=None, alias="sentenceId")
1644
+ sentence_text: Optional[str] = Field(default=None, alias="sentenceText")
1645
+ seq: int
1646
+ text: str
1647
+ to: str
1648
+ type: Literal["transcript.corrected"] = "transcript.corrected"
1649
+ word_idx: int = Field(alias="wordIdx")
1650
+ words: Optional[List["Word"]] = None
1651
+
1652
+
1653
+ class TranscriptSpeakerGender(_Base):
1654
+ confidence: Optional[float] = None
1655
+ gender: str
1656
+ speaker: int
1657
+ type: Literal["transcript.speakerGender"] = "transcript.speakerGender"
1658
+
1659
+
1660
+ class TranscriptSpeakerIdentified(_Base):
1661
+ color: Optional[str] = None
1662
+ confidence: Optional[float] = None
1663
+ name: str
1664
+ speaker: int
1665
+ type: Literal["transcript.speakerIdentified"] = "transcript.speakerIdentified"
1666
+ voice_id: Optional[str] = Field(default=None, alias="voiceId")
1667
+
1668
+
1669
+ class TranscriptSpeakerNamed(_Base):
1670
+ name: Optional[str] = None
1671
+ speaker: int
1672
+ type: Literal["transcript.speakerNamed"] = "transcript.speakerNamed"
1673
+
1674
+
1675
+ class RecordingStarted(_Base):
1676
+ recording_id: str = Field(alias="recordingId")
1677
+ transcription_id: str = Field(alias="transcriptionId")
1678
+ type: Literal["recording.started"] = "recording.started"
1679
+
1680
+
1681
+ class JobProgress(_Base):
1682
+ error: Optional[str] = None
1683
+ fetch_total_bytes: Optional[int] = Field(default=None, alias="fetchTotalBytes")
1684
+ fetched_bytes: Optional[int] = Field(default=None, alias="fetchedBytes")
1685
+ pct: int
1686
+ phase: Optional[str] = None
1687
+ phase_pct: Optional[int] = Field(default=None, alias="phasePct")
1688
+ preview: Optional[bool] = None
1689
+ processed_s: float = Field(alias="processedS")
1690
+ recording_id: str = Field(alias="recordingId")
1691
+ segments_done: int = Field(alias="segmentsDone")
1692
+ segments_total: Optional[int] = Field(default=None, alias="segmentsTotal")
1693
+ state: JobState
1694
+ total_s: Optional[float] = Field(default=None, alias="totalS")
1695
+ transcription_id: str = Field(alias="transcriptionId")
1696
+ type: Literal["job.progress"] = "job.progress"
1697
+
1698
+
1699
+ class StreamIngest(_Base):
1700
+ detected: Optional[str] = None
1701
+ error: Optional[str] = None
1702
+ failures: Optional[int] = None
1703
+ last_audio_at: Optional[str] = Field(default=None, alias="lastAudioAt")
1704
+ recording_id: str = Field(alias="recordingId")
1705
+ state: IngestState
1706
+ transcription_id: str = Field(alias="transcriptionId")
1707
+ type: Literal["stream.ingest"] = "stream.ingest"
1708
+ url: str
1709
+
1710
+
1711
+ class RecordingEnded(_Base):
1712
+ recording_id: str = Field(alias="recordingId")
1713
+ transcription_id: str = Field(alias="transcriptionId")
1714
+ type: Literal["recording.ended"] = "recording.ended"
1715
+
1716
+
1717
+ class Audience(_Base):
1718
+ languages: Any
1719
+ listeners: int
1720
+ type: Literal["audience"] = "audience"
1721
+
1722
+
1723
+ class SubscribeGap(_Base):
1724
+ expected: int
1725
+ got: int
1726
+ type: Literal["subscribe.gap"] = "subscribe.gap"
1727
+
1728
+
1729
+ SubscriberFrame = Annotated[Union[SubscribeReady, RecordingState, RecordingSettings, RecordingSilence, RecordingExpiring, TranscriptCorrected, TranscriptSpeakerGender, TranscriptSpeakerIdentified, TranscriptSpeakerNamed, RecordingStarted, JobProgress, StreamIngest, RecordingEnded, Audience, SubscribeGap], Field(discriminator="type")]
1730
+
1731
+ SERVER_FRAME_TYPES = frozenset(["session.loading", "session.ready", "transcript.committed", "transcript.draft", "transcript.words", "transcript.amended", "transcript.latency", "transcript.speaker", "transcript.speakerGender", "transcript.speakerIdentified", "transcript.sentence", "transcript.translated", "transcript.voice", "transcript.voiceStatus", "transcript.progress", "stream.pull", "source.progress", "source.prepared", "session.done", "error"])
1732
+
1733
+ _server_frame_adapter: TypeAdapter[ServerFrame] = TypeAdapter(ServerFrame)
1734
+
1735
+
1736
+ TranscriptEvent = Union[TranscriptCommitted, TranscriptDraft, TranscriptWords, TranscriptAmended, TranscriptLatency, TranscriptSpeaker, TranscriptSpeakerGender, TranscriptSpeakerIdentified, TranscriptSentence, TranscriptTranslated, TranscriptVoice, TranscriptVoiceStatus, TranscriptProgress]
1737
+
1738
+
1739
+ def parse_server_frame(text: str) -> Optional[ServerFrame]:
1740
+ """Parse one WS text frame. Returns None for unknown frame types
1741
+ (forward compatibility)."""
1742
+ raw = json.loads(text)
1743
+ if not isinstance(raw, dict) or raw.get("type") not in SERVER_FRAME_TYPES:
1744
+ return None
1745
+ return _server_frame_adapter.validate_python(raw)