supafone-labs 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -52,68 +52,100 @@ silent directive, and the exact primitive for each, is in
52
52
 
53
53
  ## Supported frameworks
54
54
 
55
- Silent injection feeds the live agent hidden guidance it acts on but never
56
- speaks. Two mechanisms cover every supported framework:
57
-
58
- - **Mode A — native silent event:** speech-to-speech models take a vendor event
59
- that adds context without triggering speech.
60
- - **Mode B — own the LLM:** for STT→LLM→TTS pipelines, Supafone plugs in as the
61
- LLM and splices a `system`/`developer` message into the prompt.
62
-
63
- **Possible — 10 frameworks**, each with a real injection door:
64
-
65
- | Framework | Mode | Exact primitive |
66
- | --- | :--: | --- |
67
- | Ultravox | A | `send_data_message` (`urgency:"later"`) — **live/proven today** |
68
- | OpenAI Realtime | A | `conversation.item.create` (role `system`, no `response.create`) |
69
- | Grok (xAI) | A | OpenAI-Realtime-compatible item inject |
70
- | Gemini Live | A | `clientContent` (`turnComplete:false`, role `user`) |
71
- | ElevenLabs | A | `contextual_update` |
72
- | Inworld | A | OpenAI-Realtime-compatible item inject |
73
- | Vapi | A+B | `add-message` (`triggerResponseEnabled:false`) or custom-LLM splice |
74
- | Retell | B | `system` message into the custom-LLM turn |
75
- | Deepgram | A+B | `UpdatePrompt`, or own the `think` LLM |
76
- | LiveKit | B | inject into `chat_ctx` in-process |
77
-
78
- **Impossible — Bland:** its live-call API is stop/listen/transfer only, with no
79
- mid-call inject channel and no custom-LLM. Observe and score it, but you cannot
80
- whisper to it live — a permanent vendor limitation, not a Supafone gap.
81
- **Cartesia** (a TTS voice) and **Pipecat** (a DIY framework you own end to end)
82
- are not conversational agents, so there is nothing to inject into.
83
-
84
- Injection is *possible* for all 10, but managed delivery is wired end-to-end
85
- **only for the legacy managed Supervisor delivery path**; the other nine are
86
- supported via their native primitive with managed delivery rolling out / BYO.
87
- Native realtime Agent Factory delivery is a separate first-class path. A live test against any vendor
88
- needs that vendor's key — free/trial tiers exist for all except OpenAI Realtime
89
- (paid, no free tier). Full matrix:
90
- [gitbook/framework-support.md](../gitbook/framework-support.md). *(The npm
91
- package-page copy updates on the next release.)*
92
-
93
- ## Native realtime Agent Factory
94
-
95
- Version 0.6.1 can create direct speech-to-speech browser and phone agents with
96
- `realtime: { provider, model, voice }`. Supported entries are OpenAI GPT
97
- Realtime 2.1, GPT Live 1, Google Gemini Live 3.1, and xAI Grok Voice. Each
98
- entry keeps the same Supafone-managed, Twilio, Telnyx, Plivo, or SIP phone
99
- transport. Use `labs.agents.testCall(agentKey)` for an authenticated browser
100
- preview. Provider keys and carrier credentials are required for live calls; see
101
- the [full guide](../gitbook/realtime-agent-factory.md).
102
-
103
- | Provider | Model | Default voice |
55
+ Supervisor delivers approved guidance through the control surface exposed by
56
+ the selected adapter. The standalone SDK and hosted Agent Factory have separate
57
+ capability contracts:
58
+
59
+ - **Native control adapters:** Supafone/Ultravox, OpenAI Realtime, Grok,
60
+ Vapi, ElevenLabs Agents, Deepgram Voice Agent and Inworld Realtime.
61
+ For example, Ultravox uses a deferred data message; Grok uses
62
+ `response.create.instructions`, with `response.created` followed by
63
+ `response.done` as protocol acknowledgement.
64
+ - **Developer-owned conversation context:** Retell custom LLM, LiveKit Agents
65
+ and Pipecat apply guidance inside the loop the integrator controls.
66
+ - **Observation-only by default:** Gemini Developer Live and Bland emit no
67
+ hidden instruction through the default standalone adapter. Ordinary Gemini
68
+ `clientContent` is conversation history, not privileged system control.
69
+ Cartesia Line needs an explicit custom-event hook in the target agent.
70
+
71
+ Hosted Agent Factory supports coaching across Ultravox, OpenAI, Gemini, Grok
72
+ and Hydra through its managed call paths. Native calls use `check_guidance`
73
+ tool results; Hydra's live observations are model-reported because it supplies
74
+ no native transcript stream. This does not change the standalone adapter's
75
+ capabilities or prove that a model followed the guidance.
76
+
77
+ See the [framework matrix](../gitbook/framework-support.md) and
78
+ [provider contracts](../docs/providers.md) for delivery and acceptance details.
79
+ Live validation requires configured provider access; local contract tests do
80
+ not certify a production call.
81
+
82
+ ## One S2S interface, five providers
83
+
84
+ Since version 0.6.3, the SDK exports `SupafoneS2S`, the shared parent of `UltravoxS2S`,
85
+ `OpenAIS2S`, `GeminiS2S`, `GrokS2S`, and `HydraS2S`. These classes use
86
+ Supafone's hosted Agent Factory. Supafone handles the audio adapter, tools,
87
+ stages, and supported phone transport behind one API.
88
+
89
+ ```ts
90
+ import { Supafone, HydraS2S, OpenAIS2S, UltravoxS2S } from "supafone-labs";
91
+
92
+ const client = new Supafone({ apiKey: process.env.SUPAFONE_API_KEY! });
93
+ const hydra = new HydraS2S(client, { model: "hydra-v1.1", voice: "maya" });
94
+ const created = await hydra.create({
95
+ name: "Intake", goal: "Collect the caller's details and book a consultation",
96
+ telephony: { mode: "supafone_managed", provider: "supafone" },
97
+ });
98
+ const agentKey = created.agent.agent_key!;
99
+ await hydra.testCall(agentKey);
100
+
101
+ // Switch the same agent for its next call, preserving its assigned number.
102
+ await new OpenAIS2S(client, { model: "gpt-realtime-2.1", voice: "marin" }).apply(agentKey);
103
+ // Return to the existing default Ultravox runtime.
104
+ await new UltravoxS2S(client).apply(agentKey);
105
+ ```
106
+
107
+ `apply` saves a selection for subsequent calls. `testCall` previews the saved
108
+ agent and does not implicitly switch providers. The same constructors and
109
+ `create`, `apply`, and `test_call` methods are available in Python.
110
+
111
+ | Provider family | Selection | Default voice |
104
112
  | --- | --- | --- |
113
+ | Ultravox | Default hosted runtime (`realtime: null` resets it) | Agent voice settings |
105
114
  | OpenAI | `gpt-realtime-2.1` | `marin` |
106
115
  | OpenAI | `gpt-live-1` | `marin` |
107
116
  | Google | `gemini-3.1-flash-live-preview` | `Puck` |
108
117
  | xAI | `grok-voice-latest` | `eve` |
109
-
110
- ```ts
111
- const agent = await supafone.labs.agents.createInbound({
112
- name: "Realtime intake",
113
- realtime: { provider: "openai", model: "gpt-realtime-2.1", voice: "marin" },
114
- });
115
- const preview = await supafone.labs.agents.testCall(agent.agent.agent_key!);
116
- ```
118
+ | Smallest AI | `hydra-v1.1` | `maya` |
119
+ | Smallest AI | `hydra-v1.0` | `sterling` |
120
+
121
+ The existing `realtime: { provider, model, voice }` API remains supported.
122
+ All five speaking families use the shared generated/custom stage plan, Manager
123
+ and specialist consultations. The phone
124
+ paths are Supafone-managed numbers, BYO Twilio, Telnyx, Plivo, and SIP through
125
+ LiveKit. Carrier provisioning and credentials still determine call readiness.
126
+
127
+ Supafone's configured server-side provider keys are used by default. An
128
+ existing encrypted account key takes priority; customers do not need to add a
129
+ provider key when Supafone has one configured. Missing keys produce an
130
+ unavailable preview instead of a live provider call.
131
+
132
+ Hydra supports English audio and tools, without transcript events or mutable
133
+ mid-session persona/voice. Supafone supplies the frozen call plan at session start
134
+ and advances the stage using tool results. Hydra 1.1 uses 16 kHz input / 24 kHz
135
+ output; 1.0 uses 16 kHz / 48 kHz and a different voice roster. Native sessions
136
+ support opt-in recording, public widgets, configured carrier controls and
137
+ allowed-model handoff. A handoff opens a replacement session; a carrier transfer
138
+ acknowledgement does not mean a human answered. Hydra has no live transcript
139
+ stream; optional post-call transcription needs a recording and server Deepgram
140
+ credentials. Ultravox retains compatible external TTS and its profile router.
141
+ All five hosted speaking families support optional Supervisor coaching. Native
142
+ models receive guidance through `check_guidance`; Hydra supplies explicitly
143
+ labeled model-reported context rather than transcripts.
144
+ See the [unified S2S guide](https://labs.supafone.ai/docs/unified-s2s/) and
145
+ [capability matrix](https://labs.supafone.ai/docs/realtime-agent-factory/).
146
+ See [Shared runtime, Manager and teams](https://labs.supafone.ai/docs/shared-agent-runtime/)
147
+ for `manager`, `agentTeam`, structured stage requirements, `recording` and
148
+ `runtimeRouting`. Both SDKs preserve explicit empty stage-tool and edge arrays.
117
149
 
118
150
  ## Spawn a hosted Supafone agent
119
151
 
@@ -198,7 +230,7 @@ import { Supafone } from "supafone-labs";
198
230
  const supafone = new Supafone({
199
231
  apiKey: process.env.SUPAFONE_LABS_API_KEY || process.env.SUPAFONE_API_KEY!,
200
232
  supafoneApiKey: process.env.SUPAFONE_API_KEY!,
201
- // Supafone Supervisor is on by default for live guidance, QA, and scoring.
233
+ // Requests Supervisor by default; its model credentials must also be configured.
202
234
  // Set false only when you intentionally need an unsupervised agent.
203
235
  supervisor: true,
204
236
  // Defaults to https://api.supafone.ai. Override for staging/local tests.
@@ -226,11 +258,7 @@ const inbound = await supafone.labs.agents.createInboundWithNumber({
226
258
  },
227
259
  recording: {
228
260
  enabled: true,
229
- recordAudio: true,
230
- consentRequired: true,
231
- announcement: "This call may be recorded for quality and training.",
232
- retentionDays: 30,
233
- redactPii: true,
261
+ transcribe: true,
234
262
  },
235
263
  transcription: {
236
264
  enabled: true,
@@ -353,37 +381,40 @@ agent; fetches it back; verifies `runtime.telephony.mode` is `supafone_managed`
353
381
  and the runtime is managed (`runtime.managed === true`, no developer Ultravox key
354
382
  required); and prints the returned widget snippet.
355
383
 
356
- ## Hosted voices
384
+ ## Hosted voices: Ultravox + custom TTS
357
385
 
358
- Select a current provider voice from plain-language intent:
386
+ The managed Ultravox option remains part of the shared S2S offering. Its
387
+ conversation runtime and compatible TTS voice are separate choices:
359
388
 
360
389
  ```ts
361
- const matches = await supafone.labs.voices.recommend({
362
- description: "calm Spanish customer-support voice",
363
- language: "es-MX",
364
- configuredOnly: true,
365
- });
390
+ import { UltravoxS2S } from "supafone-labs";
391
+
392
+ const catalog = await supafone.labs.voices.list({ provider: "cartesia" });
393
+ console.log(catalog.voices);
366
394
 
367
- const voice = matches.matches[0].voice;
368
- await supafone.labs.agents.createInbound({
395
+ await new UltravoxS2S(supafone).create({
369
396
  name: "Spanish support",
370
- voice: supafone.labs.voices.selection(voice),
397
+ voice: { provider: "cartesia", voiceId: process.env.CARTESIA_VOICE_ID! },
371
398
  });
372
399
  ```
373
400
 
374
- The hosted catalog refreshes Ultravox, Cartesia, ElevenLabs, and Inworld and
375
- normalizes names, languages, gender, accent, voice type, model limits, and the
376
- Ultravox-compatible language intersection. Full reference:
377
- [Dynamic Voice Catalog and Selection](../gitbook/voice-catalog-and-selection.md).
378
-
379
- Labs Cloud also exposes direct hosted TTS and STT:
380
-
381
- ```ts
382
- const wav = await supafone.tts("You're all set — talk soon!", "supafone-labs-calm-en");
383
- // wav: Uint8Array
384
-
385
- const text = await supafone.stt(audioBytes, { language: "en" });
386
- ```
401
+ Use a real, configured catalog voice. Compatible Ultravox, Cartesia, ElevenLabs,
402
+ and Inworld voices can supply the managed agent's speech. Native OpenAI,
403
+ Gemini, Grok, and Hydra use their own model voices; external TTS is not a
404
+ universal override. Deepgram is preview-only in the current hosted Ultravox
405
+ integration. Custom TTS backends are for developer-owned synthesis unless a
406
+ hosted runtime bridge explicitly supports them.
407
+
408
+ The published SDK 0.7.0 exposes `labs.voices.list`, `listAll`, `capabilities`,
409
+ `recommend`, `preview`, and `selection`. Use `listAll` for automatic catalog
410
+ pagination, then pass `selection(voice)` into managed agent creation. These
411
+ helpers query the hosted voice catalog; they do not enable external TTS on
412
+ native OpenAI, Gemini, Grok, or Hydra sessions.
413
+ See [voice-output choices](https://labs.supafone.ai/docs/voice-output-modes/) and
414
+ [the voice catalog](https://labs.supafone.ai/docs/voice-catalog-and-selection/).
415
+
416
+ Labs Cloud's standalone `tts` and `stt` methods remain separate synthesis and
417
+ transcription tools; using them does not change a saved agent's speaking model.
387
418
 
388
419
  ## Live multilingual transcription
389
420
 
@@ -1,3 +1,5 @@
1
+ export { SupafoneS2S, UltravoxS2S, OpenAIS2S, GeminiS2S, GrokS2S, HydraS2S } from "./s2s.js";
2
+ export type { S2SProviderName, S2SModelOptions, S2SOptions } from "./s2s.js";
1
3
  /**
2
4
  * Supafone Labs — the agent framework behind Supafone.
3
5
  *
@@ -197,8 +199,74 @@ export interface LabsCallStage {
197
199
  temperature?: number;
198
200
  nextStages?: string[];
199
201
  next_stages?: string[];
202
+ /** Server-enforced exit gates, independent of conversational exit criteria. */
203
+ requirements?: LabsStageRequirements;
204
+ role?: string;
205
+ specialistId?: string;
206
+ specialist_id?: string;
200
207
  metadata?: Record<string, unknown>;
201
208
  }
209
+ export interface LabsStageRequirements {
210
+ requiredFields?: string[];
211
+ required_fields?: string[];
212
+ successfulTools?: string[];
213
+ successful_tools?: string[];
214
+ }
215
+ export interface LabsManagerConfig {
216
+ enabled?: boolean;
217
+ /** Reuse the existing encrypted Supervisor profile, or use managed reasoning. */
218
+ reasoning?: "managed" | "supervisor";
219
+ model?: "supafone-manager" | "supafone-manager-pro";
220
+ maxTasks?: number;
221
+ max_tasks?: number;
222
+ maxParallel?: number;
223
+ max_parallel?: number;
224
+ timeoutSeconds?: number;
225
+ timeout_seconds?: number;
226
+ }
227
+ export interface LabsSpecialist {
228
+ id: string;
229
+ role?: string;
230
+ label?: string;
231
+ description?: string;
232
+ instructions?: string;
233
+ enabled?: boolean;
234
+ stageKeys?: string[];
235
+ stage_keys?: string[];
236
+ tools?: string[];
237
+ }
238
+ export interface LabsAgentTeam {
239
+ enabled?: boolean;
240
+ routingMode?: "auto" | "sequential";
241
+ routing_mode?: "auto" | "sequential";
242
+ fallbackMemberId?: string;
243
+ fallback_member_id?: string;
244
+ members?: LabsSpecialist[];
245
+ routingRules?: Array<{
246
+ intent: string;
247
+ member_id: string;
248
+ priority?: string;
249
+ action?: string;
250
+ }>;
251
+ routing_rules?: Array<{
252
+ intent: string;
253
+ member_id: string;
254
+ priority?: string;
255
+ action?: string;
256
+ }>;
257
+ }
258
+ export interface LabsRuntimeRoutingConfig {
259
+ enabled?: boolean;
260
+ allowedModels?: LabsRealtimeSelection[];
261
+ allowed_models?: LabsRealtimeSelection[];
262
+ /** Server-supported range is 1–3 handoffs per call. */
263
+ maxHandoffs?: number;
264
+ max_handoffs?: number;
265
+ recoverOnDisconnect?: boolean;
266
+ recover_on_disconnect?: boolean;
267
+ allowedLanguages?: string[];
268
+ allowed_languages?: string[];
269
+ }
202
270
  export type LabsStageGeneration = "managed" | "template" | "off" | "oracle";
203
271
  export interface LabsCallPlan {
204
272
  version: "supafone_call_plan_v1" | string;
@@ -353,7 +421,7 @@ export interface LabsVoicePreference {
353
421
  }
354
422
  /** Direct speech-to-speech configuration for browser previews and carrier phone calls. */
355
423
  export interface LabsRealtimeSelection {
356
- provider: "openai" | "google" | "xai";
424
+ provider: "openai" | "google" | "xai" | "smallest";
357
425
  model?: string;
358
426
  voice?: string;
359
427
  }
@@ -373,6 +441,17 @@ export interface LabsBrowserTestSession {
373
441
  token?: string | null;
374
442
  input_sample_rate?: number;
375
443
  output_sample_rate?: number;
444
+ capabilities?: {
445
+ stages?: boolean;
446
+ tools?: boolean;
447
+ transcripts?: boolean;
448
+ recording?: boolean;
449
+ supervisor?: boolean;
450
+ transfer?: boolean;
451
+ mutable_instructions?: boolean;
452
+ stage_update_mode?: string;
453
+ languages?: string[];
454
+ };
376
455
  };
377
456
  }
378
457
  export interface LabsProviderKeys {
@@ -449,6 +528,9 @@ export interface LabsProviderKeys {
449
528
  xai?: string;
450
529
  xaiApiKey?: string;
451
530
  xai_api_key?: string;
531
+ smallest?: string;
532
+ smallestApiKey?: string;
533
+ smallest_api_key?: string;
452
534
  [extra: string]: unknown;
453
535
  }
454
536
  export interface LabsCustomSipConfig {
@@ -630,6 +712,8 @@ export interface LabsEmailConfig {
630
712
  }
631
713
  export interface LabsRecordingConfig {
632
714
  enabled?: boolean;
715
+ /** Request post-call transcription of the recording where configured. */
716
+ transcribe?: boolean;
633
717
  recordAudio?: boolean;
634
718
  record_audio?: boolean;
635
719
  consentRequired?: boolean;
@@ -869,6 +953,17 @@ export interface CreateLabsAgentRequest {
869
953
  presetKey?: string;
870
954
  preset_key?: string;
871
955
  realtime?: LabsRealtimeSelection;
956
+ manager?: boolean | LabsManagerConfig;
957
+ agentTeam?: LabsAgentTeam;
958
+ agent_team?: LabsAgentTeam;
959
+ runtimeRouting?: LabsRuntimeRoutingConfig;
960
+ runtime_routing?: LabsRuntimeRoutingConfig;
961
+ captureFields?: string[];
962
+ capture_fields?: string[];
963
+ timezone?: string;
964
+ businessTimezone?: string;
965
+ timeAwareness?: boolean;
966
+ time_awareness?: boolean;
872
967
  runtimeMode?: LabsRuntimeMode;
873
968
  runtime_mode?: LabsRuntimeMode;
874
969
  /** Defaults to Supafone's hosted planner; model credentials remain server-side. */
@@ -911,7 +1006,7 @@ export interface CreateLabsAgentRequest {
911
1006
  customSip?: LabsCustomSipConfig;
912
1007
  custom_sip?: LabsCustomSipConfig;
913
1008
  sip?: LabsCustomSipConfig;
914
- recording?: LabsRecordingConfig;
1009
+ recording?: boolean | LabsRecordingConfig;
915
1010
  transcription?: LabsTranscriptionConfig;
916
1011
  artifacts?: LabsArtifactsConfig;
917
1012
  compliance?: Record<string, unknown>;
@@ -2217,7 +2312,7 @@ declare class LabsBillingNamespace {
2217
2312
  declare class LabsAgentsNamespace {
2218
2313
  private sm;
2219
2314
  constructor(sm: SupafoneLabs);
2220
- /** Spawn a durable hosted Supafone agent backed by Ultravox and Supafone-managed providers. */
2315
+ /** Create a hosted Supafone agent with the default Ultravox runtime or a selected native S2S model. */
2221
2316
  create(input: CreateLabsAgentRequest): Promise<CreateLabsAgentResponse>;
2222
2317
  /** Preview the exact validated call-plan contract the Supafone runtime executes. */
2223
2318
  plan(input: CreateLabsAgentRequest & {
package/dist/cjs/index.js CHANGED
@@ -1,30 +1,16 @@
1
1
  "use strict";
2
- /**
3
- * Supafone Labs — the agent framework behind Supafone.
4
- *
5
- * A dependency-free TypeScript client for creating hosted Supafone agents
6
- * through the Supafone API, including managed phone numbers, voices, stages,
7
- * tools, recordings, transcripts, widgets, and Supafone Supervisor. It also
8
- * includes Supafone Supervisor, hosted TTS/STT, live multilingual
9
- * transcription, telemetry, agent builder, and objective-driven optimizer.
10
- *
11
- * Works in Node 18+ (native fetch/WebSocket) and the browser.
12
- *
13
- * npm i supafone-labs
14
- *
15
- * import { Supafone } from "supafone-labs";
16
- * const supafone = new Supafone({ apiKey: process.env.SUPAFONE_API_KEY! });
17
- * const agent = await supafone.labs.agents.createInboundWithNumber({
18
- * agentKey: "northline-intake",
19
- * name: "Northline intake",
20
- * number: { search: { areaCode: "415" } },
21
- * });
22
- */
23
2
  Object.defineProperty(exports, "__esModule", { value: true });
24
- exports.Supafone = exports.SupafoneLabs = exports.SupafoneLabsError = exports.OUTBOUND_CALL_MODE_PROVIDER_MATRIX = exports.OUTBOUND_CALL_MODE_DEFAULTS = exports.OUTBOUND_CALL_MODE_BOUNDS = void 0;
3
+ exports.Supafone = exports.SupafoneLabs = exports.SupafoneLabsError = exports.OUTBOUND_CALL_MODE_PROVIDER_MATRIX = exports.OUTBOUND_CALL_MODE_DEFAULTS = exports.OUTBOUND_CALL_MODE_BOUNDS = exports.HydraS2S = exports.GrokS2S = exports.GeminiS2S = exports.OpenAIS2S = exports.UltravoxS2S = exports.SupafoneS2S = void 0;
25
4
  exports.outboundCallModeProviderProfile = outboundCallModeProviderProfile;
26
5
  exports.outboundCallModeReadiness = outboundCallModeReadiness;
27
6
  exports.generateCallStages = generateCallStages;
7
+ var s2s_js_1 = require("./s2s.js");
8
+ Object.defineProperty(exports, "SupafoneS2S", { enumerable: true, get: function () { return s2s_js_1.SupafoneS2S; } });
9
+ Object.defineProperty(exports, "UltravoxS2S", { enumerable: true, get: function () { return s2s_js_1.UltravoxS2S; } });
10
+ Object.defineProperty(exports, "OpenAIS2S", { enumerable: true, get: function () { return s2s_js_1.OpenAIS2S; } });
11
+ Object.defineProperty(exports, "GeminiS2S", { enumerable: true, get: function () { return s2s_js_1.GeminiS2S; } });
12
+ Object.defineProperty(exports, "GrokS2S", { enumerable: true, get: function () { return s2s_js_1.GrokS2S; } });
13
+ Object.defineProperty(exports, "HydraS2S", { enumerable: true, get: function () { return s2s_js_1.HydraS2S; } });
28
14
  exports.OUTBOUND_CALL_MODE_BOUNDS = {
29
15
  maxDurationSeconds: { default: 180, min: 30, max: 900 },
30
16
  maxKeypresses: { default: 12, min: 1, max: 64 },
@@ -1202,7 +1188,7 @@ class LabsAgentsNamespace {
1202
1188
  constructor(sm) {
1203
1189
  this.sm = sm;
1204
1190
  }
1205
- /** Spawn a durable hosted Supafone agent backed by Ultravox and Supafone-managed providers. */
1191
+ /** Create a hosted Supafone agent with the default Ultravox runtime or a selected native S2S model. */
1206
1192
  create(input) {
1207
1193
  return this.sm.requestSupafoneApi("POST", "/api/v1/labs/agents", labsAgentPayload(this.withSupervisor(input)));
1208
1194
  }
@@ -2029,6 +2015,40 @@ function outboundCallModeRequiredCapabilities(payload) {
2029
2015
  required.push("observability");
2030
2016
  return required;
2031
2017
  }
2018
+ function managerPayload(input) {
2019
+ if (typeof input !== "object" || input === null)
2020
+ return input;
2021
+ return compact({
2022
+ enabled: input.enabled, reasoning: input.reasoning, model: input.model,
2023
+ max_tasks: input.max_tasks ?? input.maxTasks,
2024
+ max_parallel: input.max_parallel ?? input.maxParallel,
2025
+ timeout_seconds: input.timeout_seconds ?? input.timeoutSeconds,
2026
+ });
2027
+ }
2028
+ function agentTeamPayload(input) {
2029
+ if (!input)
2030
+ return undefined;
2031
+ return compact({
2032
+ enabled: input.enabled, routing_mode: input.routing_mode ?? input.routingMode,
2033
+ fallback_member_id: input.fallback_member_id ?? input.fallbackMemberId,
2034
+ routing_rules: input.routing_rules ?? input.routingRules,
2035
+ members: input.members?.map((member) => compact({
2036
+ id: member.id, role: member.role, label: member.label, description: member.description,
2037
+ instructions: member.instructions, enabled: member.enabled, tools: member.tools,
2038
+ stage_keys: member.stage_keys ?? member.stageKeys,
2039
+ })),
2040
+ });
2041
+ }
2042
+ function runtimeRoutingPayload(input) {
2043
+ if (!input)
2044
+ return undefined;
2045
+ return compact({
2046
+ enabled: input.enabled, allowed_models: input.allowed_models ?? input.allowedModels,
2047
+ max_handoffs: input.max_handoffs ?? input.maxHandoffs,
2048
+ recover_on_disconnect: input.recover_on_disconnect ?? input.recoverOnDisconnect,
2049
+ allowed_languages: input.allowed_languages ?? input.allowedLanguages,
2050
+ });
2051
+ }
2032
2052
  function labsAgentMetadataPayload(input) {
2033
2053
  const metadata = { ...(input.metadata ?? {}) };
2034
2054
  const mode = input.outboundCallMode ?? input.outbound_call_mode;
@@ -2070,6 +2090,12 @@ function labsAgentPayload(input) {
2070
2090
  preset_key: input.preset_key ?? input.presetKey,
2071
2091
  runtime_mode: input.runtime_mode ?? input.runtimeMode,
2072
2092
  realtime: input.realtime,
2093
+ manager: managerPayload(input.manager),
2094
+ agent_team: agentTeamPayload(input.agent_team ?? input.agentTeam),
2095
+ runtime_routing: runtimeRoutingPayload(input.runtime_routing ?? input.runtimeRouting),
2096
+ capture_fields: input.capture_fields ?? input.captureFields,
2097
+ timezone: input.timezone ?? input.businessTimezone,
2098
+ time_awareness: input.time_awareness ?? input.timeAwareness,
2073
2099
  call_stages: callStagesPayload(input),
2074
2100
  stage_generation: input.stage_generation ?? input.stageGeneration,
2075
2101
  stage_count: input.stage_count ?? input.stageCount,
@@ -2087,7 +2113,7 @@ function labsAgentPayload(input) {
2087
2113
  byok: input.byok ? byokPayload(input.byok) : undefined,
2088
2114
  telephony: input.telephony ? telephonyPayload(input.telephony) : undefined,
2089
2115
  custom_sip: customSipPayload(input.custom_sip ?? input.customSip ?? input.sip),
2090
- recording: input.recording ? recordingPayload(input.recording) : undefined,
2116
+ recording: input.recording !== undefined ? recordingPayload(input.recording) : undefined,
2091
2117
  transcription: input.transcription ? transcriptionPayload(input.transcription) : undefined,
2092
2118
  artifacts: input.artifacts ? artifactsPayload(input.artifacts) : undefined,
2093
2119
  compliance: input.compliance,
@@ -2231,9 +2257,6 @@ function callStagesPayload(input) {
2231
2257
  return explicit;
2232
2258
  if (explicit === "oracle")
2233
2259
  return "managed";
2234
- // The S2S backend owns its validated intake → booking → confirmation flow.
2235
- if (input.realtime)
2236
- return undefined;
2237
2260
  // Omitted means the private Supafone API generates and compiles the plan.
2238
2261
  return undefined;
2239
2262
  }
@@ -2250,8 +2273,7 @@ function stagePlanPayload(input) {
2250
2273
  system_prompt: input.system_prompt ?? input.systemPrompt,
2251
2274
  tools: input.tools ? toolsPayload(input.tools) : undefined,
2252
2275
  call_stages: Array.isArray(input.call_stages ?? input.callStages ?? input.stages)
2253
- ? (input.call_stages ?? input.callStages ?? input.stages)
2254
- : undefined,
2276
+ ? callStagesPayload(input) : undefined,
2255
2277
  stage_generation: input.stage_generation ?? input.stageGeneration,
2256
2278
  stage_count: input.stage_count ?? input.stageCount,
2257
2279
  stage_detail: input.stage_detail ?? input.stageDetail,
@@ -2267,6 +2289,12 @@ function callStagePayload(input) {
2267
2289
  tools: input.tools,
2268
2290
  temperature: input.temperature,
2269
2291
  next_stages: input.next_stages ?? input.nextStages,
2292
+ requirements: input.requirements ? compact({
2293
+ required_fields: input.requirements.required_fields ?? input.requirements.requiredFields,
2294
+ successful_tools: input.requirements.successful_tools ?? input.requirements.successfulTools,
2295
+ }) : undefined,
2296
+ role: input.role,
2297
+ specialist_id: input.specialist_id ?? input.specialistId,
2270
2298
  metadata: input.metadata,
2271
2299
  });
2272
2300
  }
@@ -2408,6 +2436,8 @@ function providerKeysPayload(input) {
2408
2436
  openai_api_key: input.openai_api_key ?? input.openaiApiKey,
2409
2437
  xai: input.xai,
2410
2438
  xai_api_key: input.xai_api_key ?? input.xaiApiKey,
2439
+ smallest: input.smallest,
2440
+ smallest_api_key: input.smallest_api_key ?? input.smallestApiKey,
2411
2441
  });
2412
2442
  }
2413
2443
  function byokPayload(input) {
@@ -2483,8 +2513,11 @@ function emailPayload(input) {
2483
2513
  });
2484
2514
  }
2485
2515
  function recordingPayload(input) {
2516
+ if (typeof input === "boolean")
2517
+ return input;
2486
2518
  return compact({
2487
2519
  enabled: input.enabled,
2520
+ transcribe: input.transcribe,
2488
2521
  record_audio: input.record_audio ?? input.recordAudio,
2489
2522
  consent_required: input.consent_required ?? input.consentRequired,
2490
2523
  announcement: input.announcement,
@@ -0,0 +1,41 @@
1
+ import type { CreateLabsAgentRequest, GetLabsAgentOptions, LabsRealtimeSelection, SupafoneLabs } from "./index.js";
2
+ export type S2SProviderName = "ultravox" | "openai" | "google" | "xai" | "smallest";
3
+ export interface S2SModelOptions {
4
+ model?: string;
5
+ voice?: string;
6
+ }
7
+ export interface S2SOptions extends S2SModelOptions {
8
+ provider?: S2SProviderName;
9
+ }
10
+ /** Shared parent for Supafone-hosted S2S agents. Vendor keys stay on the server. */
11
+ export declare class SupafoneS2S {
12
+ protected readonly client: SupafoneLabs;
13
+ readonly provider: S2SProviderName;
14
+ private readonly selection;
15
+ constructor(client: SupafoneLabs, options?: S2SOptions);
16
+ /** A fresh wire selection; null explicitly restores the default Ultravox runtime. */
17
+ get realtime(): LabsRealtimeSelection | null;
18
+ /** Create through the normal hosted agent factory with this provider. */
19
+ create(input: Omit<CreateLabsAgentRequest, "realtime">): Promise<import("./index.js").CreateLabsAgentResponse>;
20
+ /** Change the saved selection for subsequent calls, preserving the agent and number. */
21
+ apply(agentKey: string, options?: GetLabsAgentOptions): Promise<import("./index.js").LabsAgentLifecycleResponse>;
22
+ /** Preview the saved agent. Call apply first when switching providers. */
23
+ testCall(agentKey: string, options?: GetLabsAgentOptions): Promise<import("./index.js").LabsBrowserTestSession>;
24
+ private checkAgentKey;
25
+ }
26
+ export declare class UltravoxS2S extends SupafoneS2S {
27
+ constructor(client: SupafoneLabs);
28
+ }
29
+ export declare class OpenAIS2S extends SupafoneS2S {
30
+ constructor(client: SupafoneLabs, options?: S2SModelOptions);
31
+ }
32
+ export declare class GeminiS2S extends SupafoneS2S {
33
+ constructor(client: SupafoneLabs, options?: S2SModelOptions);
34
+ }
35
+ export declare class GrokS2S extends SupafoneS2S {
36
+ constructor(client: SupafoneLabs, options?: S2SModelOptions);
37
+ }
38
+ /** Smallest AI Hydra: full-duplex audio, without transcript events. */
39
+ export declare class HydraS2S extends SupafoneS2S {
40
+ constructor(client: SupafoneLabs, options?: S2SModelOptions);
41
+ }