supafone-labs 0.4.10 → 0.4.13

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/README.md CHANGED
@@ -107,6 +107,13 @@ Supafone Labs has two main features:
107
107
  - **Self-healing watcher**: enable `labs.enabled` to attach the Supafone Labs
108
108
  second mind to a hosted or BYOK agent.
109
109
 
110
+ The daily developer workflow is documented in
111
+ [Developer Workflows](../gitbook/developer-workflows.md): one normalized live
112
+ voice catalog, fixed BCP-47 language selection, automatic voice compatibility
113
+ filtering, structured SecondMind directives, and the same configuration model
114
+ across TypeScript and Python. Fixed language selection does not enable
115
+ mid-call language or voice switching.
116
+
110
117
  BYOK is advanced and split into three independent lanes:
111
118
 
112
119
  | Lane | Examples |
@@ -279,6 +286,29 @@ required); and prints the returned widget snippet.
279
286
 
280
287
  ## Hosted voices
281
288
 
289
+ Select a current provider voice from plain-language intent:
290
+
291
+ ```ts
292
+ const matches = await supafone.labs.voices.recommend({
293
+ description: "calm Spanish customer-support voice",
294
+ language: "es-MX",
295
+ configuredOnly: true,
296
+ });
297
+
298
+ const voice = matches.matches[0].voice;
299
+ await supafone.labs.agents.createInbound({
300
+ name: "Spanish support",
301
+ voice: supafone.labs.voices.selection(voice),
302
+ });
303
+ ```
304
+
305
+ The hosted catalog refreshes Ultravox, Cartesia, ElevenLabs, and Inworld and
306
+ normalizes names, languages, gender, accent, voice type, model limits, and the
307
+ Ultravox-compatible language intersection. Full reference:
308
+ [Dynamic Voice Catalog and Selection](../gitbook/voice-catalog-and-selection.md).
309
+
310
+ Labs Cloud also exposes direct hosted TTS and STT:
311
+
282
312
  ```ts
283
313
  const wav = await supafone.tts("You're all set — talk soon!", "supafone-labs-calm-en");
284
314
  // wav: Uint8Array
@@ -468,6 +498,7 @@ and `const { Supafone } = require("supafone-labs")` both work, with full types.
468
498
  | `labs.agents.create/createInbound/createOutbound/list/get` | `/api/v1/labs/agents*` on the Supafone API |
469
499
  | `labs.agents.createInboundWithNumber/createOutboundWithNumber` | Agent creation plus Supafone-managed number buy/assign |
470
500
  | `labs.phoneNumbers.search/buy/assign/list/buyAndAssign` | `/api/v1/labs/phone-numbers*` |
501
+ | `labs.billing.checkout/status/portal` | Stripe-hosted Checkout, payment polling, and Customer Portal |
471
502
  | `labs.telephony.get/configure/useSupafoneManaged` | `/api/v1/labs/telephony` |
472
503
  | `labs.presets.list()` · `labs.tools.list()` · `labs.voices.list()` | Supafone hosted-agent discovery |
473
504
  | `whisper(transcript, opts?)` | convenience over the oracle |
@@ -483,6 +514,12 @@ and `const { Supafone } = require("supafone-labs")` both work, with full types.
483
514
 
484
515
  Get a key (5 free minutes, no card): <https://labs.supafone.ai/get-key.html>
485
516
 
517
+ For `dedicated` or `premium`, `labs.phoneNumbers.buy()` first returns a public
518
+ `checkout_url`. Open it, poll `labs.billing.status()`, then call `buy()` again
519
+ with `billingCheckoutSessionId`. The server verifies and consumes the paid
520
+ entitlement before carrier provisioning; Stripe secrets and card data never
521
+ enter the SDK.
522
+
486
523
  The runtime, all provider adapters, and the offline (bring-your-own-keys) mode
487
524
  are open source and MIT-licensed — the Python package `pip install supafone-labs`
488
525
  is the full harness. This client is the thin cloud SDK.
@@ -87,6 +87,56 @@ export interface WhisperOptions {
87
87
  maxTokens?: number;
88
88
  temperature?: number;
89
89
  }
90
+ export type SecondMindDirectiveKind = "empathy" | "tactical" | "guardrail" | "mixed";
91
+ export interface DirectiveTextControl {
92
+ enabled?: boolean;
93
+ instructions?: string;
94
+ maxChars?: number;
95
+ max_chars?: number;
96
+ }
97
+ export interface DirectiveListControl {
98
+ enabled?: boolean;
99
+ instructions?: string;
100
+ maxItems?: number;
101
+ max_items?: number;
102
+ itemMaxChars?: number;
103
+ item_max_chars?: number;
104
+ }
105
+ /** Serializable controls for each field generated by SecondMind. */
106
+ export interface DirectiveContract {
107
+ empathyDirective?: DirectiveTextControl;
108
+ empathy_directive?: DirectiveTextControl;
109
+ tacticalDirective?: DirectiveTextControl;
110
+ tactical_directive?: DirectiveTextControl;
111
+ surfaceFacts?: DirectiveListControl;
112
+ surface_facts?: DirectiveListControl;
113
+ guardrails?: DirectiveListControl;
114
+ languageMode?: "caller" | "model" | "fixed";
115
+ language_mode?: "caller" | "model" | "fixed";
116
+ fixedLanguage?: string;
117
+ fixed_language?: string;
118
+ allowedKinds?: SecondMindDirectiveKind[];
119
+ allowed_kinds?: SecondMindDirectiveKind[];
120
+ confidenceThreshold?: number;
121
+ confidence_threshold?: number;
122
+ operatorGuardrails?: string[];
123
+ operator_guardrails?: string[];
124
+ }
125
+ export interface SecondMindDirective {
126
+ empathy_directive: string;
127
+ tactical_directive: string;
128
+ surface_facts: string[];
129
+ guardrails: string[];
130
+ language: string;
131
+ confidence: number;
132
+ kind: SecondMindDirectiveKind;
133
+ }
134
+ export interface StructuredWhisperOptions extends WhisperOptions {
135
+ directiveContract?: DirectiveContract;
136
+ directive_contract?: DirectiveContract;
137
+ /** Local final say: revise or suppress the generated directive before use. */
138
+ transform?: (directive: SecondMindDirective) => SecondMindDirective | null | Promise<SecondMindDirective | null>;
139
+ }
90
140
  export interface Balance {
91
141
  plan: string;
92
142
  seconds_remaining: number;
@@ -131,19 +181,142 @@ export interface LabsCallStage {
131
181
  key?: string;
132
182
  id?: string;
133
183
  name: string;
184
+ /** Plain-English job description used by the hosted call-plan generator. */
185
+ description?: string;
134
186
  goal?: string;
135
187
  instructions?: string;
136
188
  exitCriteria?: string[];
137
189
  exit_criteria?: string[];
138
190
  tools?: string[];
191
+ temperature?: number;
192
+ nextStages?: string[];
193
+ next_stages?: string[];
139
194
  metadata?: Record<string, unknown>;
140
195
  }
196
+ export type LabsStageGeneration = "oracle" | "template" | "off";
197
+ export interface LabsCallPlan {
198
+ version: "supafone_call_plan_v1" | string;
199
+ summary: string;
200
+ base_system_prompt: string;
201
+ call_stages: LabsCallStage[];
202
+ generated_by: "supafone_hosted_haiku" | "deterministic_template" | "deterministic_fallback" | "developer" | string;
203
+ model: string;
204
+ fallback: boolean;
205
+ warnings?: string[];
206
+ }
141
207
  export interface LabsVoiceSelection {
142
208
  provider?: string;
143
209
  voiceId?: string;
144
210
  voice_id?: string;
145
211
  model?: string;
146
212
  }
213
+ export type LabsVoiceGender = "female" | "male" | "neutral";
214
+ export interface LabsVoiceLanguage {
215
+ code: string;
216
+ locale: string;
217
+ name: string;
218
+ native_name: string;
219
+ aliases?: string[];
220
+ routing_supported?: boolean;
221
+ }
222
+ export interface LabsVoiceLanguageSupport {
223
+ provider: string;
224
+ model?: string | null;
225
+ known: boolean;
226
+ language_codes: string[];
227
+ /** Number of language codes Supafone can enumerate from provider docs. */
228
+ enumerated_language_count: number;
229
+ generally_available_language_codes: string[];
230
+ experimental_language_codes: string[];
231
+ documented_language_count: number;
232
+ documented_language_count_is_minimum: boolean;
233
+ support_tier: string;
234
+ cross_lingual: boolean | null;
235
+ documentation_url?: string | null;
236
+ verified_at: string;
237
+ native_language_codes: string[];
238
+ ultravox_routing_language_codes: string[];
239
+ primary_language_support_tier: "generally_available" | "experimental" | "unknown";
240
+ }
241
+ export interface LabsVoiceProviderTraits {
242
+ countries: string[];
243
+ accents: string[];
244
+ age_groups: string[];
245
+ categories: string[];
246
+ use_cases: string[];
247
+ descriptors: string[];
248
+ native_locales: string[];
249
+ created_at?: string | number | null;
250
+ is_public?: boolean | null;
251
+ is_owner?: boolean | null;
252
+ }
253
+ export interface LabsVoiceCatalogItem {
254
+ /** Stable runtime reference, including provider prefix when required. */
255
+ id: string;
256
+ voice_id: string;
257
+ /** Human-readable provider display name. */
258
+ provider: string;
259
+ /** Canonical SDK/runtime provider key. */
260
+ provider_key: string;
261
+ /** Runtime adapter used to place the voice on an Ultravox call. */
262
+ runtime_provider_key: string;
263
+ /** Actual TTS engine behind the voice (can differ for Ultravox built-ins). */
264
+ synthesis_provider_key: string;
265
+ /** Raw identifier used by the provider API. */
266
+ provider_voice_id: string;
267
+ name: string;
268
+ label: string;
269
+ description: string;
270
+ style: string;
271
+ model?: string | null;
272
+ language: string;
273
+ language_code: string;
274
+ language_locale: string;
275
+ language_name: string;
276
+ native_language_name: string;
277
+ languages: LabsVoiceLanguage[];
278
+ native_language_codes: string[];
279
+ model_language_codes: string[];
280
+ runtime_supported_language_codes: string[];
281
+ routing_supported: boolean;
282
+ language_support: LabsVoiceLanguageSupport;
283
+ gender: LabsVoiceGender;
284
+ accent: string;
285
+ age: string;
286
+ provider_traits: LabsVoiceProviderTraits;
287
+ voice_types: string[];
288
+ primary_voice_type: string;
289
+ tags: string[];
290
+ /** Sanitized provider-native fields retained for forward-compatible filtering. */
291
+ provider_metadata: Record<string, unknown>;
292
+ provider_metadata_fields: string[];
293
+ preview_url?: string | null;
294
+ preview_available: boolean;
295
+ source: string;
296
+ ownership?: string | null;
297
+ configured: boolean;
298
+ recommended: boolean;
299
+ premium?: boolean;
300
+ is_custom: boolean;
301
+ runtime: {
302
+ provider: string;
303
+ voice_id: string;
304
+ model?: string;
305
+ };
306
+ [extra: string]: unknown;
307
+ }
308
+ export interface LabsVoicePreference {
309
+ description: string;
310
+ language?: string;
311
+ provider?: string;
312
+ gender?: LabsVoiceGender;
313
+ voiceType?: string;
314
+ voice_type?: string;
315
+ model?: string;
316
+ configuredOnly?: boolean;
317
+ configured_only?: boolean;
318
+ premium?: boolean;
319
+ }
147
320
  export interface LabsProviderKeys {
148
321
  /** Agent runtime/platform providers. */
149
322
  ultravox?: string;
@@ -454,6 +627,8 @@ export interface CreateLabsAgentRequest {
454
627
  agentStyle?: LabsAgentStyle;
455
628
  agent_style?: LabsAgentStyle;
456
629
  name: string;
630
+ /** Plain-language job description used by the hosted call-plan generator. */
631
+ description?: string;
457
632
  assistantName?: string;
458
633
  assistant_name?: string;
459
634
  businessName?: string;
@@ -473,18 +648,30 @@ export interface CreateLabsAgentRequest {
473
648
  preset_key?: string;
474
649
  runtimeMode?: LabsRuntimeMode;
475
650
  runtime_mode?: LabsRuntimeMode;
476
- /** Default true. When true, the SDK creates sensible call stages from prompt metadata. */
477
- callStages?: boolean | LabsCallStage[];
478
- call_stages?: boolean | LabsCallStage[];
651
+ /** Defaults to Supafone's hosted planner; model credentials remain server-side. */
652
+ callStages?: boolean | LabsStageGeneration | LabsCallStage[];
653
+ call_stages?: boolean | LabsStageGeneration | LabsCallStage[];
479
654
  stages?: LabsCallStage[];
480
655
  autoCallStages?: boolean;
481
656
  auto_call_stages?: boolean;
657
+ stageGeneration?: LabsStageGeneration;
658
+ stage_generation?: LabsStageGeneration;
659
+ stageCount?: number;
660
+ stage_count?: number;
661
+ stageDetail?: "compact" | "standard" | "detailed";
662
+ stage_detail?: "compact" | "standard" | "detailed";
482
663
  goal?: string;
483
664
  greeting?: string;
484
665
  systemPrompt?: string;
485
666
  system_prompt?: string;
667
+ /** Fixed language for the full call. Does not enable mid-call switching. */
486
668
  language?: string;
669
+ preferredLanguage?: string;
670
+ preferred_language?: string;
487
671
  voice?: LabsVoiceSelection;
672
+ /** Resolve a real current catalog voice from this plain-language preference. */
673
+ voicePreference?: LabsVoicePreference;
674
+ voice_preference?: LabsVoicePreference;
488
675
  providerKeys?: LabsProviderKeys;
489
676
  provider_keys?: LabsProviderKeys;
490
677
  byok?: LabsProviderKeys | LabsByokConfig;
@@ -544,19 +731,115 @@ export interface LabsToolListResponse {
544
731
  }
545
732
  export interface LabsVoiceListOptions {
546
733
  provider?: string;
734
+ search?: string;
735
+ /** Native/accent language advertised for the individual voice. */
736
+ language?: string;
737
+ /** Language that the provider model and Ultravox can both run live. */
738
+ compatibleLanguage?: string;
739
+ compatible_language?: string;
740
+ gender?: LabsVoiceGender;
741
+ voiceType?: string;
742
+ voice_type?: string;
743
+ model?: string;
744
+ runtimeProvider?: string;
745
+ runtime_provider?: string;
746
+ configuredOnly?: boolean;
747
+ configured_only?: boolean;
748
+ cursor?: number;
749
+ limit?: number;
750
+ agencyId?: string;
751
+ agency_id?: string;
547
752
  }
548
753
  export interface LabsVoiceListResponse {
549
- voices: Array<Record<string, unknown>>;
754
+ account_id?: string;
755
+ voices: LabsVoiceCatalogItem[];
550
756
  total: number;
551
- providers: Array<Record<string, unknown>>;
757
+ cursor?: number;
758
+ next_cursor?: number | null;
759
+ providers: Array<{
760
+ id: string;
761
+ label: string;
762
+ configured: boolean;
763
+ voice_count: number;
764
+ error?: string | null;
765
+ }>;
552
766
  provider_accounts?: Record<string, unknown>;
553
767
  errors?: Record<string, string>;
768
+ catalog?: {
769
+ dynamic: boolean;
770
+ source: string;
771
+ normalization_schema_version: number;
772
+ cache_ttl_seconds: number;
773
+ capabilities_url?: string;
774
+ };
775
+ }
776
+ export interface LabsVoiceModelCapability {
777
+ provider: string;
778
+ model?: string | null;
779
+ known: boolean;
780
+ language_codes: string[];
781
+ enumerated_language_count: number;
782
+ generally_available_language_codes: string[];
783
+ experimental_language_codes: string[];
784
+ documented_language_count: number;
785
+ documented_language_count_is_minimum: boolean;
786
+ support_tier: string;
787
+ cross_lingual: boolean | null;
788
+ documentation_url?: string | null;
789
+ verified_at: string;
790
+ ultravox_routing_language_codes: string[];
791
+ ultravox_routing_language_count: number;
792
+ }
793
+ export interface LabsVoiceProviderCapability {
794
+ provider: string;
795
+ label: string;
796
+ ultravox_integration: "native" | "named_external" | string;
797
+ default_model?: string | null;
798
+ models: LabsVoiceModelCapability[];
799
+ }
800
+ export interface LabsVoiceCapabilitiesResponse {
801
+ runtime: "ultravox" | string;
802
+ runtime_spoken_languages: LabsVoiceLanguage[];
803
+ runtime_spoken_language_count: number;
804
+ providers: LabsVoiceProviderCapability[];
805
+ selection_rule: Record<string, string>;
806
+ normalization_schema_version: number;
807
+ }
808
+ export interface LabsVoiceRecommendOptions extends LabsVoicePreference {
809
+ limit?: number;
810
+ agencyId?: string;
811
+ agency_id?: string;
812
+ }
813
+ export interface LabsVoiceRecommendation {
814
+ voice: LabsVoiceCatalogItem;
815
+ score: number;
816
+ reasons: string[];
817
+ }
818
+ export interface LabsVoiceRecommendResponse {
819
+ account_id?: string;
820
+ description: string;
821
+ matches: LabsVoiceRecommendation[];
822
+ total_considered: number;
823
+ }
824
+ export interface LabsVoicePreview {
825
+ content: ArrayBuffer;
826
+ mediaType: string;
827
+ }
828
+ export interface LabsRuntimeResponse {
829
+ account_id: string;
830
+ provider: "ultravox" | string;
831
+ managed: boolean;
832
+ byok_connected: boolean;
833
+ base_url?: string;
834
+ updated_at?: string;
554
835
  }
555
836
  export interface LabsCallListOptions {
556
837
  agencyId?: string;
838
+ agency_id?: string;
557
839
  agentKey?: string;
558
840
  agent_key?: string;
559
841
  limit?: number;
842
+ offset?: number;
560
843
  }
561
844
  export interface LabsCallArtifact {
562
845
  id?: string;
@@ -566,7 +849,11 @@ export interface LabsCallArtifact {
566
849
  started_at?: string;
567
850
  duration_seconds?: number;
568
851
  recording_url?: string;
852
+ recording_download_url?: string;
853
+ recording_archived?: boolean;
569
854
  transcript_url?: string;
855
+ watcher_events?: LabsDeveloperActivityEvent[];
856
+ watcher_event_count?: number;
570
857
  [extra: string]: unknown;
571
858
  }
572
859
  export interface LabsCallListResponse {
@@ -589,6 +876,37 @@ export interface LabsTranscriptListResponse {
589
876
  transcripts: Array<Record<string, unknown>>;
590
877
  [extra: string]: unknown;
591
878
  }
879
+ export interface LabsDeveloperActivityEvent {
880
+ id: string;
881
+ account_id: string;
882
+ event_type: string;
883
+ resource_type: string;
884
+ resource_id: string;
885
+ source?: string;
886
+ detail?: Record<string, unknown>;
887
+ created_at: string;
888
+ [extra: string]: unknown;
889
+ }
890
+ export interface LabsActivityListOptions {
891
+ accountId?: string;
892
+ account_id?: string;
893
+ agencyId?: string;
894
+ agency_id?: string;
895
+ eventType?: string;
896
+ event_type?: string;
897
+ resourceType?: string;
898
+ resource_type?: string;
899
+ resourceId?: string;
900
+ resource_id?: string;
901
+ limit?: number;
902
+ offset?: number;
903
+ }
904
+ export interface LabsActivityListResponse {
905
+ events: LabsDeveloperActivityEvent[];
906
+ count: number;
907
+ next_offset?: number | null;
908
+ account_id?: string;
909
+ }
592
910
  export interface LabsPhoneNumberSearchOptions {
593
911
  agencyId?: string;
594
912
  agency_id?: string;
@@ -669,6 +987,8 @@ export interface LabsPhoneNumberProvisionRequest {
669
987
  numberPool?: string;
670
988
  number_pool?: string;
671
989
  premium?: boolean;
990
+ billingCheckoutSessionId?: string;
991
+ billing_checkout_session_id?: string;
672
992
  style?: LabsAgentStyle;
673
993
  agentStyle?: LabsAgentStyle;
674
994
  agent_style?: LabsAgentStyle;
@@ -721,7 +1041,7 @@ export interface CreateLabsAgentWithNumberRequest extends CreateLabsAgentRequest
721
1041
  number?: LabsPhoneNumberBuyAndAssignRequest;
722
1042
  }
723
1043
  export interface CreateLabsAgentWithNumberResponse extends CreateLabsAgentResponse {
724
- number?: LabsPhoneNumberProvisionResponse;
1044
+ number?: LabsPhoneNumberProvisionResponse | LabsBillingCheckoutResponse;
725
1045
  }
726
1046
  export interface LabsAgentResponse {
727
1047
  id?: string;
@@ -745,6 +1065,7 @@ export interface CreateLabsAgentResponse {
745
1065
  snippet?: string;
746
1066
  [extra: string]: unknown;
747
1067
  };
1068
+ call_plan?: LabsCallPlan;
748
1069
  [extra: string]: unknown;
749
1070
  }
750
1071
  export interface ListLabsAgentsResponse {
@@ -1029,6 +1350,13 @@ export declare class SupafoneLabs {
1029
1350
  readonly optimizer: OptimizerNamespace;
1030
1351
  readonly campaigns: CampaignsNamespace;
1031
1352
  constructor(opts: SupafoneLabsOptions);
1353
+ /** Build a complete hosted plan with the same Supafone key used to create agents. */
1354
+ generateCallStages(input: CreateLabsAgentRequest & {
1355
+ description?: string;
1356
+ }): Promise<LabsCallPlan>;
1357
+ generate_call_stages(input: CreateLabsAgentRequest & {
1358
+ description?: string;
1359
+ }): Promise<LabsCallPlan>;
1032
1360
  /** True once login() (or a passed sessionToken) is in effect. */
1033
1361
  get isLoggedIn(): boolean;
1034
1362
  /**
@@ -1040,6 +1368,8 @@ export declare class SupafoneLabs {
1040
1368
  request<T>(method: string, path: string, body?: unknown, useSession?: boolean): Promise<T>;
1041
1369
  /** @internal Authenticated JSON request to the Supafone app API (`/api/v1/labs/*`). */
1042
1370
  requestSupafoneApi<T>(method: string, path: string, body?: unknown): Promise<T>;
1371
+ /** @internal Authenticated binary request to the Supafone app API. */
1372
+ requestSupafoneBinary(path: string): Promise<LabsVoicePreview>;
1043
1373
  /**
1044
1374
  * Exchange the account email/password for a product-API JWT (the same login
1045
1375
  * as app.supafone.ai). Called lazily by campaigns/calls — call directly only
@@ -1108,6 +1438,14 @@ export declare class SupafoneLabs {
1108
1438
  * (empty string when the agent is doing fine).
1109
1439
  */
1110
1440
  whisper(transcript: string, opts?: WhisperOptions): Promise<string>;
1441
+ /**
1442
+ * Structured SecondMind guidance with developer-controlled field policy.
1443
+ * Returns null when JSON is invalid, evidence misses the confidence gate,
1444
+ * the generated kind is disallowed, or the local transform suppresses it.
1445
+ */
1446
+ whisperStructured(transcript: string, opts?: StructuredWhisperOptions): Promise<SecondMindDirective | null>;
1447
+ /** Alias that reads naturally in applications building their own watcher loop. */
1448
+ directive(transcript: string, opts?: StructuredWhisperOptions): Promise<SecondMindDirective | null>;
1111
1449
  /** Hosted TTS — returns raw audio bytes (WAV/PCM per voice). */
1112
1450
  tts(text: string, voice?: string): Promise<Uint8Array>;
1113
1451
  /** Convenience alias for voice preview UI/buttons. */
@@ -1459,23 +1797,73 @@ declare class CampaignsNamespace {
1459
1797
  declare class LabsNamespace {
1460
1798
  private sm;
1461
1799
  readonly agents: LabsAgentsNamespace;
1800
+ readonly billing: LabsBillingNamespace;
1462
1801
  readonly presets: LabsPresetsNamespace;
1463
1802
  readonly tools: LabsToolsNamespace;
1464
1803
  readonly voices: LabsVoicesNamespace;
1804
+ readonly runtime: LabsRuntimeNamespace;
1465
1805
  readonly phoneNumbers: LabsPhoneNumbersNamespace;
1466
1806
  readonly telephony: LabsTelephonyNamespace;
1467
1807
  readonly calls: LabsCallsNamespace;
1808
+ readonly activity: LabsActivityNamespace;
1809
+ readonly plans: LabsPlansNamespace;
1468
1810
  readonly recordings: LabsRecordingsNamespace;
1469
1811
  readonly transcripts: LabsTranscriptsNamespace;
1470
1812
  constructor(sm: SupafoneLabs);
1471
1813
  /** Discover the Supafone convenience layer over Ultravox. */
1472
1814
  capabilities(): Promise<LabsCapabilitiesResponse>;
1473
1815
  }
1816
+ export type LabsBillingCheckoutKind = "plan" | "credits" | "number_addon";
1817
+ export interface LabsBillingCheckoutInput {
1818
+ kind?: LabsBillingCheckoutKind;
1819
+ planKey?: "developer" | "growth" | "scale" | string;
1820
+ plan_key?: string;
1821
+ numberStrategy?: "dedicated" | "premium" | string;
1822
+ number_strategy?: string;
1823
+ phoneNumber?: string;
1824
+ phone_number?: string;
1825
+ quantity?: number;
1826
+ successUrl?: string;
1827
+ success_url?: string;
1828
+ cancelUrl?: string;
1829
+ cancel_url?: string;
1830
+ }
1831
+ export interface LabsBillingCheckoutResponse {
1832
+ status: "requires_payment" | "pending" | "paid" | string;
1833
+ checkout_session_id: string;
1834
+ checkout_url?: string;
1835
+ kind: LabsBillingCheckoutKind | string;
1836
+ plan_key?: string | null;
1837
+ number_strategy?: string | null;
1838
+ phone_number?: string | null;
1839
+ stripe_subscription_id?: string | null;
1840
+ ready_to_provision?: boolean;
1841
+ next_step?: string;
1842
+ }
1843
+ declare class LabsBillingNamespace {
1844
+ private sm;
1845
+ constructor(sm: SupafoneLabs);
1846
+ /** Start hosted Stripe Checkout. MCP callers should render checkout_url as a link. */
1847
+ checkout(input?: LabsBillingCheckoutInput): Promise<LabsBillingCheckoutResponse>;
1848
+ status(checkoutSessionId: string): Promise<LabsBillingCheckoutResponse>;
1849
+ portal(): Promise<{
1850
+ url: string;
1851
+ }>;
1852
+ createCheckout(input?: LabsBillingCheckoutInput): Promise<LabsBillingCheckoutResponse>;
1853
+ getCheckout(checkoutSessionId: string): Promise<LabsBillingCheckoutResponse>;
1854
+ }
1474
1855
  declare class LabsAgentsNamespace {
1475
1856
  private sm;
1476
1857
  constructor(sm: SupafoneLabs);
1477
1858
  /** Spawn a durable hosted Supafone agent backed by Ultravox and Supafone-managed providers. */
1478
1859
  create(input: CreateLabsAgentRequest): Promise<CreateLabsAgentResponse>;
1860
+ /** Preview the exact validated call-plan contract the Supafone runtime executes. */
1861
+ plan(input: CreateLabsAgentRequest & {
1862
+ description?: string;
1863
+ }): Promise<LabsCallPlan>;
1864
+ generateCallStages(input: CreateLabsAgentRequest & {
1865
+ description?: string;
1866
+ }): Promise<LabsCallPlan>;
1479
1867
  /** Default the agent onto the client's Voice Watcher setting (live supervision
1480
1868
  * + QA + scoring) unless the caller set it explicitly; mirror into
1481
1869
  * labs.voice_watcher when a labs block exists. Never overwrites a caller value. */
@@ -1516,8 +1904,43 @@ declare class LabsToolsNamespace {
1516
1904
  declare class LabsVoicesNamespace {
1517
1905
  private sm;
1518
1906
  constructor(sm: SupafoneLabs);
1519
- /** Supafone-managed Cartesia voices. Other TTS engines remain explicit BYOK choices. */
1907
+ /** Live normalized catalog from every connected/managed TTS provider. */
1520
1908
  list(opts?: LabsVoiceListOptions): Promise<LabsVoiceListResponse>;
1909
+ /** Provider/model language limits and their Ultravox-compatible intersection. */
1910
+ capabilities(): Promise<LabsVoiceCapabilitiesResponse>;
1911
+ /** Page through the complete normalized catalog. */
1912
+ listAll(opts?: Omit<LabsVoiceListOptions, "cursor" | "limit"> & {
1913
+ pageSize?: number;
1914
+ maxPages?: number;
1915
+ }): Promise<LabsVoiceListResponse>;
1916
+ /** Rank real current voices from a plain-language description. */
1917
+ recommend(opts: LabsVoiceRecommendOptions): Promise<LabsVoiceRecommendResponse>;
1918
+ /** Download an authenticated voice preview. */
1919
+ preview(voiceId: string, opts?: {
1920
+ agencyId?: string;
1921
+ agency_id?: string;
1922
+ }): Promise<LabsVoicePreview>;
1923
+ /** Convert a catalog row into the exact Agent Factory voice field. */
1924
+ selection(voice: LabsVoiceCatalogItem): LabsVoiceSelection;
1925
+ }
1926
+ declare class LabsRuntimeNamespace {
1927
+ private sm;
1928
+ constructor(sm: SupafoneLabs);
1929
+ get(opts?: {
1930
+ agencyId?: string;
1931
+ agency_id?: string;
1932
+ }): Promise<LabsRuntimeResponse>;
1933
+ configure(input: {
1934
+ agencyId?: string;
1935
+ agency_id?: string;
1936
+ provider?: "ultravox" | string;
1937
+ credentials?: {
1938
+ apiKey?: string;
1939
+ api_key?: string;
1940
+ baseUrl?: string;
1941
+ base_url?: string;
1942
+ };
1943
+ }): Promise<LabsRuntimeResponse>;
1521
1944
  }
1522
1945
  declare class LabsCallsNamespace {
1523
1946
  private sm;
@@ -1525,8 +1948,25 @@ declare class LabsCallsNamespace {
1525
1948
  list(opts?: LabsCallListOptions): Promise<LabsCallListResponse>;
1526
1949
  get(callId: string, opts?: {
1527
1950
  agencyId?: string;
1951
+ agency_id?: string;
1952
+ }): Promise<{
1953
+ call: LabsCallArtifact;
1954
+ }>;
1955
+ delete(callId: string, opts?: {
1956
+ agencyId?: string;
1957
+ agency_id?: string;
1528
1958
  }): Promise<Record<string, unknown>>;
1529
1959
  }
1960
+ declare class LabsActivityNamespace {
1961
+ private sm;
1962
+ constructor(sm: SupafoneLabs);
1963
+ list(opts?: LabsActivityListOptions): Promise<LabsActivityListResponse>;
1964
+ }
1965
+ declare class LabsPlansNamespace {
1966
+ private sm;
1967
+ constructor(sm: SupafoneLabs);
1968
+ list(opts?: Omit<LabsActivityListOptions, "eventType" | "event_type" | "resourceType" | "resource_type">): Promise<LabsActivityListResponse>;
1969
+ }
1530
1970
  declare class LabsRecordingsNamespace {
1531
1971
  private sm;
1532
1972
  constructor(sm: SupafoneLabs);
@@ -1554,8 +1994,11 @@ declare class LabsPhoneNumbersNamespace {
1554
1994
  list(opts?: LabsPhoneNumberListOptions): Promise<LabsPhoneNumberListResponse>;
1555
1995
  /** Search Supafone-managed inventory. This uses Supafone's master telephony account. */
1556
1996
  search(opts?: LabsPhoneNumberSearchOptions): Promise<LabsPhoneNumberSearchResponse>;
1557
- /** Buy a Supafone-managed number. Developers do not need a Twilio account. */
1558
- buy(input: LabsPhoneNumberProvisionRequest): Promise<LabsPhoneNumberProvisionResponse>;
1997
+ /**
1998
+ * Buy a managed number. Paid strategies return a hosted Checkout link first;
1999
+ * call again with billingCheckoutSessionId after Checkout reports paid.
2000
+ */
2001
+ buy(input: LabsPhoneNumberProvisionRequest): Promise<LabsPhoneNumberProvisionResponse | LabsBillingCheckoutResponse>;
1559
2002
  /** Attach an existing Supafone number to an inbound or outbound agent. */
1560
2003
  assign(numberId: string, input?: LabsPhoneNumberAssignRequest): Promise<LabsPhoneNumberAssignResponse>;
1561
2004
  /** Unassign a number from an agent but keep it reserved on the account. */
@@ -1570,7 +2013,7 @@ declare class LabsPhoneNumbersNamespace {
1570
2013
  * Search if needed, buy the first matching Supafone-managed number, and assign
1571
2014
  * it to the supplied agent. This is the zero-Twilio-account happy path.
1572
2015
  */
1573
- buyAndAssign(input: LabsPhoneNumberBuyAndAssignRequest): Promise<LabsPhoneNumberProvisionResponse>;
2016
+ buyAndAssign(input: LabsPhoneNumberBuyAndAssignRequest): Promise<LabsPhoneNumberProvisionResponse | LabsBillingCheckoutResponse>;
1574
2017
  }
1575
2018
  declare class LabsTelephonyNamespace {
1576
2019
  private sm;