supafone-labs 0.5.2 → 0.5.4

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
@@ -104,13 +104,13 @@ Supafone Labs has two main features:
104
104
 
105
105
  - **Agent Factory**: create the complete hosted agent with managed provider
106
106
  defaults and one Supafone API key.
107
- - **Self-healing watcher**: enable `labs.enabled` to attach the Supafone Labs
108
- second mind to a hosted or BYOK agent.
107
+ - **Supafone Supervisor**: attach live guidance, call scoring, and QA to a
108
+ hosted or BYOK agent.
109
109
 
110
110
  The daily developer workflow is documented in
111
111
  [Developer Workflows](../gitbook/developer-workflows.md): one normalized live
112
112
  voice catalog, fixed BCP-47 language selection, automatic voice compatibility
113
- filtering, structured SecondMind directives, and the same configuration model
113
+ filtering, structured Supervisor directives, and the same configuration model
114
114
  across TypeScript and Python. Fixed language selection does not enable
115
115
  mid-call language or voice switching.
116
116
 
@@ -166,10 +166,9 @@ import { Supafone } from "supafone-labs";
166
166
  const supafone = new Supafone({
167
167
  apiKey: process.env.SUPAFONE_LABS_API_KEY || process.env.SUPAFONE_API_KEY!,
168
168
  supafoneApiKey: process.env.SUPAFONE_API_KEY!,
169
- // voiceWatcher is on by default (also accepts voice_watcher; deprecated: labs).
170
- // Every provisioned agent runs under the Voice Watcher framework (live
171
- // supervision + QA + call scoring). Set false for a raw agent.
172
- voiceWatcher: true,
169
+ // Supafone Supervisor is on by default for live guidance, QA, and scoring.
170
+ // Set false only when you intentionally need an unsupervised agent.
171
+ supervisor: true,
173
172
  // Defaults to https://api.supafone.ai. Override for staging/local tests.
174
173
  // supafoneApiBaseUrl: "http://localhost:8000",
175
174
  });
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * A dependency-free TypeScript client for creating hosted Supafone agents
5
5
  * through the Supafone API, including managed phone numbers, voices, stages,
6
- * tools, recordings, transcripts, widgets, and Supafone Pro watcher. It also
6
+ * tools, recordings, transcripts, widgets, and Supafone Supervisor. It also
7
7
  * includes the Labs cloud sidecar oracle, hosted TTS/STT, live multilingual
8
8
  * transcription, telemetry, agent builder, and objective-driven optimizer.
9
9
  *
@@ -53,15 +53,13 @@ export interface SupafoneLabsOptions {
53
53
  * fall back to the plain zero-billed report.
54
54
  */
55
55
  postCallAnalysis?: boolean;
56
- /**
57
- * Run provisioned agents under Supafone's Voice Watcher framework — live
58
- * supervision, QA, and call scoring (default true). Set false for a raw
59
- * agent with no watcher. `voice_watcher` (snake) and the deprecated `labs`
60
- * are accepted aliases, resolved voiceWatcher > voice_watcher > labs > true.
61
- */
56
+ /** Enable Supafone Supervisor live guidance, QA, and scoring (default true). */
57
+ supervisor?: boolean;
58
+ /** @deprecated Use supervisor. */
62
59
  voiceWatcher?: boolean;
60
+ /** @deprecated Use supervisor. */
63
61
  voice_watcher?: boolean;
64
- /** @deprecated alias for voiceWatcher. */
62
+ /** @deprecated Use supervisor. */
65
63
  labs?: boolean;
66
64
  }
67
65
  export interface ChatMessage {
@@ -87,7 +85,9 @@ export interface WhisperOptions {
87
85
  maxTokens?: number;
88
86
  temperature?: number;
89
87
  }
90
- export type SecondMindDirectiveKind = "empathy" | "tactical" | "guardrail" | "mixed";
88
+ export type SupervisorDirectiveKind = "empathy" | "tactical" | "guardrail" | "mixed";
89
+ /** @deprecated Use SupervisorDirectiveKind. */
90
+ export type SecondMindDirectiveKind = SupervisorDirectiveKind;
91
91
  export interface DirectiveTextControl {
92
92
  enabled?: boolean;
93
93
  instructions?: string;
@@ -102,7 +102,7 @@ export interface DirectiveListControl {
102
102
  itemMaxChars?: number;
103
103
  item_max_chars?: number;
104
104
  }
105
- /** Serializable controls for each field generated by SecondMind. */
105
+ /** Serializable controls for each field generated by Supafone Supervisor. */
106
106
  export interface DirectiveContract {
107
107
  empathyDirective?: DirectiveTextControl;
108
108
  empathy_directive?: DirectiveTextControl;
@@ -115,27 +115,29 @@ export interface DirectiveContract {
115
115
  language_mode?: "caller" | "model" | "fixed";
116
116
  fixedLanguage?: string;
117
117
  fixed_language?: string;
118
- allowedKinds?: SecondMindDirectiveKind[];
119
- allowed_kinds?: SecondMindDirectiveKind[];
118
+ allowedKinds?: SupervisorDirectiveKind[];
119
+ allowed_kinds?: SupervisorDirectiveKind[];
120
120
  confidenceThreshold?: number;
121
121
  confidence_threshold?: number;
122
122
  operatorGuardrails?: string[];
123
123
  operator_guardrails?: string[];
124
124
  }
125
- export interface SecondMindDirective {
125
+ export interface SupervisorDirective {
126
126
  empathy_directive: string;
127
127
  tactical_directive: string;
128
128
  surface_facts: string[];
129
129
  guardrails: string[];
130
130
  language: string;
131
131
  confidence: number;
132
- kind: SecondMindDirectiveKind;
132
+ kind: SupervisorDirectiveKind;
133
133
  }
134
+ /** @deprecated Use SupervisorDirective. */
135
+ export type SecondMindDirective = SupervisorDirective;
134
136
  export interface StructuredWhisperOptions extends WhisperOptions {
135
137
  directiveContract?: DirectiveContract;
136
138
  directive_contract?: DirectiveContract;
137
139
  /** Local final say: revise or suppress the generated directive before use. */
138
- transform?: (directive: SecondMindDirective) => SecondMindDirective | null | Promise<SecondMindDirective | null>;
140
+ transform?: (directive: SupervisorDirective) => SupervisorDirective | null | Promise<SupervisorDirective | null>;
139
141
  }
140
142
  export interface Balance {
141
143
  plan: string;
@@ -539,8 +541,56 @@ export interface LabsToolsConfig {
539
541
  voicemail?: boolean;
540
542
  emergencyEscalation?: boolean;
541
543
  emergency_escalation?: boolean;
542
- customTools?: Array<Record<string, unknown>>;
543
- custom_tools?: Array<Record<string, unknown>>;
544
+ /** Makes the native DTMF tool available for bounded phone-tree navigation. */
545
+ ivrNavigation?: boolean;
546
+ ivr_navigation?: boolean;
547
+ /** Executable customer-owned HTTPS tools, proxied by Supafone at call time. */
548
+ customTools?: LabsCustomToolDefinition[];
549
+ custom_tools?: LabsCustomToolDefinition[];
550
+ }
551
+ export type LabsCustomToolParameterType = "string" | "number" | "integer" | "boolean";
552
+ export interface LabsCustomToolParameter {
553
+ name: string;
554
+ description?: string;
555
+ type?: LabsCustomToolParameterType;
556
+ required?: boolean;
557
+ }
558
+ export interface LabsCustomToolDefinition {
559
+ /** Stable id returned by Supafone. Omit it when creating a tool. */
560
+ id?: string;
561
+ /** Lowercase model tool name, such as lookup_order. */
562
+ name: string;
563
+ description?: string;
564
+ /** HTTPS endpoint called by Supafone's guarded server-side proxy. */
565
+ url: string;
566
+ /** Optional secret header name. Defaults to Authorization: Bearer <apiKey>. */
567
+ header?: string;
568
+ apiKey?: string;
569
+ api_key?: string;
570
+ /** Set false on update to remove a previously stored secret. */
571
+ apiKeySet?: boolean;
572
+ api_key_set?: boolean;
573
+ params?: LabsCustomToolParameter[];
574
+ parameters?: LabsCustomToolParameter[];
575
+ /** Optional call-stage keys where this tool is available. Empty means every stage. */
576
+ stages?: string[];
577
+ allowedStages?: string[];
578
+ allowed_stages?: string[];
579
+ }
580
+ export interface LabsEmailConfig {
581
+ enabled?: boolean;
582
+ fromEmail?: string;
583
+ from_email?: string;
584
+ smtpHost?: string;
585
+ smtp_host?: string;
586
+ smtpPort?: number;
587
+ smtp_port?: number;
588
+ smtpUser?: string;
589
+ smtp_user?: string;
590
+ /** Encrypted by Supafone and never returned. */
591
+ smtpPassword?: string;
592
+ smtp_password?: string;
593
+ smtp_pass?: string;
544
594
  }
545
595
  export interface LabsRecordingConfig {
546
596
  enabled?: boolean;
@@ -579,9 +629,12 @@ export interface LabsArtifactsConfig {
579
629
  retention_days?: number;
580
630
  metadata?: Record<string, unknown>;
581
631
  }
582
- export interface LabsWatcherConfig {
632
+ export interface LabsSupervisorConfig {
583
633
  enabled?: boolean;
634
+ supervisor?: boolean;
635
+ /** @deprecated Use supervisor. */
584
636
  voiceWatcher?: boolean;
637
+ /** @deprecated Use supervisor. */
585
638
  voice_watcher?: boolean;
586
639
  apiKey?: string;
587
640
  api_key?: string;
@@ -596,6 +649,8 @@ export interface LabsWatcherConfig {
596
649
  provider_keys?: Record<string, unknown>;
597
650
  label?: string;
598
651
  }
652
+ /** @deprecated Use LabsSupervisorConfig. */
653
+ export type LabsWatcherConfig = LabsSupervisorConfig;
599
654
  export interface LabsUltravoxRuntime {
600
655
  model?: string;
601
656
  temperature?: number;
@@ -810,9 +865,14 @@ export interface CreateLabsAgentRequest {
810
865
  artifacts?: LabsArtifactsConfig;
811
866
  compliance?: Record<string, unknown>;
812
867
  tools?: LabsToolsConfig;
813
- labs?: LabsWatcherConfig;
868
+ /** Optional per-agent SMTP sender used by the callable send_email tool. */
869
+ email?: LabsEmailConfig;
870
+ labs?: LabsSupervisorConfig;
814
871
  ultravox?: LabsUltravoxRuntime;
872
+ supervisor?: boolean;
873
+ /** @deprecated Use supervisor. */
815
874
  voiceWatcher?: boolean;
875
+ /** @deprecated Use supervisor. */
816
876
  voice_watcher?: boolean;
817
877
  voiceWatcherModel?: string;
818
878
  voice_watcher_model?: string;
@@ -1518,7 +1578,9 @@ export declare class SupafoneLabs {
1518
1578
  private readonly supafoneApiKey;
1519
1579
  private readonly timeoutMs;
1520
1580
  private readonly postCallAnalysis;
1521
- /** Client default for the Voice Watcher framework (supervision + QA + scoring). */
1581
+ /** Client default for Supafone Supervisor (live guidance + QA + scoring). */
1582
+ readonly supervisor: boolean;
1583
+ /** @deprecated Use supervisor. */
1522
1584
  readonly voiceWatcher: boolean;
1523
1585
  private sessionToken?;
1524
1586
  private accountToken?;
@@ -1623,13 +1685,13 @@ export declare class SupafoneLabs {
1623
1685
  */
1624
1686
  whisper(transcript: string, opts?: WhisperOptions): Promise<string>;
1625
1687
  /**
1626
- * Structured SecondMind guidance with developer-controlled field policy.
1688
+ * Structured Supafone Supervisor guidance with developer-controlled field policy.
1627
1689
  * Returns null when JSON is invalid, evidence misses the confidence gate,
1628
1690
  * the generated kind is disallowed, or the local transform suppresses it.
1629
1691
  */
1630
- whisperStructured(transcript: string, opts?: StructuredWhisperOptions): Promise<SecondMindDirective | null>;
1692
+ whisperStructured(transcript: string, opts?: StructuredWhisperOptions): Promise<SupervisorDirective | null>;
1631
1693
  /** Alias that reads naturally in applications building their own watcher loop. */
1632
- directive(transcript: string, opts?: StructuredWhisperOptions): Promise<SecondMindDirective | null>;
1694
+ directive(transcript: string, opts?: StructuredWhisperOptions): Promise<SupervisorDirective | null>;
1633
1695
  /** Hosted TTS — returns raw audio bytes (WAV/PCM per voice). */
1634
1696
  tts(text: string, voice?: string): Promise<Uint8Array>;
1635
1697
  /** Convenience alias for voice preview UI/buttons. */
@@ -2052,10 +2114,9 @@ declare class LabsAgentsNamespace {
2052
2114
  generateCallStages(input: CreateLabsAgentRequest & {
2053
2115
  description?: string;
2054
2116
  }): Promise<LabsCallPlan>;
2055
- /** Default the agent onto the client's Voice Watcher setting (live supervision
2056
- * + QA + scoring) unless the caller set it explicitly; mirror into
2057
- * labs.voice_watcher when a labs block exists. Never overwrites a caller value. */
2058
- private withVoiceWatcher;
2117
+ /** Default the agent onto the client's Supafone Supervisor setting unless the
2118
+ * caller set it explicitly. Legacy wire fields remain unchanged. */
2119
+ private withSupervisor;
2059
2120
  /** Create an inbound receptionist/intake agent. No Twilio account is required. */
2060
2121
  createInbound(input: CreateLabsAgentRequest): Promise<CreateLabsAgentResponse>;
2061
2122
  /** Create an outbound sales/speed-to-lead/campaign agent. No Twilio account is required. */
package/dist/cjs/index.js CHANGED
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * A dependency-free TypeScript client for creating hosted Supafone agents
6
6
  * through the Supafone API, including managed phone numbers, voices, stages,
7
- * tools, recordings, transcripts, widgets, and Supafone Pro watcher. It also
7
+ * tools, recordings, transcripts, widgets, and Supafone Supervisor. It also
8
8
  * includes the Labs cloud sidecar oracle, hosted TTS/STT, live multilingual
9
9
  * transcription, telemetry, agent builder, and objective-driven optimizer.
10
10
  *
@@ -159,11 +159,11 @@ class SupafoneLabsError extends Error {
159
159
  exports.SupafoneLabsError = SupafoneLabsError;
160
160
  const DEFAULT_BASE = "https://api.labs.supafone.ai";
161
161
  const DEFAULT_SUPAFONE_API_BASE = "https://api.supafone.ai";
162
- const COACH_SYSTEM = "You are the coaching core of a second mind for a live voice agent. Read the " +
162
+ const COACH_SYSTEM = "You are the coaching core of a supervisor for a live voice agent. Read the " +
163
163
  "conversation and return ONE short, silent directive the agent reads but never " +
164
164
  "speaks aloud — a correction or nudge, phrased imperatively. If nothing needs " +
165
165
  "correcting, return an empty string.";
166
- const STRUCTURED_COACH_SYSTEM = "You are the coaching core of a second mind for a live voice agent. Read the " +
166
+ const STRUCTURED_COACH_SYSTEM = "You are the coaching core of a supervisor for a live voice agent. Read the " +
167
167
  "conversation and return ONLY one JSON object with exactly these keys: " +
168
168
  "empathy_directive (string), tactical_directive (string), surface_facts (string[]), " +
169
169
  "guardrails (string[]), language (short code), confidence (0-1), and kind " +
@@ -273,7 +273,9 @@ class SupafoneLabs {
273
273
  supafoneApiKey;
274
274
  timeoutMs;
275
275
  postCallAnalysis;
276
- /** Client default for the Voice Watcher framework (supervision + QA + scoring). */
276
+ /** Client default for Supafone Supervisor (live guidance + QA + scoring). */
277
+ supervisor;
278
+ /** @deprecated Use supervisor. */
277
279
  voiceWatcher;
278
280
  sessionToken;
279
281
  accountToken;
@@ -298,8 +300,9 @@ class SupafoneLabs {
298
300
  this.appUrl = (opts.appUrl ?? "https://app.supafone.ai").replace(/\/$/, "");
299
301
  this.timeoutMs = opts.timeoutMs ?? 30_000;
300
302
  this.postCallAnalysis = opts.postCallAnalysis ?? false;
301
- // Precedence: explicit voiceWatcher > voice_watcher (snake) > labs (deprecated) > true.
302
- this.voiceWatcher = opts.voiceWatcher ?? opts.voice_watcher ?? opts.labs ?? true;
303
+ // Precedence: supervisor > legacy aliases > true.
304
+ this.supervisor = opts.supervisor ?? opts.voiceWatcher ?? opts.voice_watcher ?? opts.labs ?? true;
305
+ this.voiceWatcher = this.supervisor;
303
306
  this.sessionToken = opts.sessionToken;
304
307
  this.accountToken = opts.accountToken;
305
308
  this.accountEmail = opts.accountEmail;
@@ -628,7 +631,7 @@ class SupafoneLabs {
628
631
  return out.text.trim();
629
632
  }
630
633
  /**
631
- * Structured SecondMind guidance with developer-controlled field policy.
634
+ * Structured Supafone Supervisor guidance with developer-controlled field policy.
632
635
  * Returns null when JSON is invalid, evidence misses the confidence gate,
633
636
  * the generated kind is disallowed, or the local transform suppresses it.
634
637
  */
@@ -1174,7 +1177,7 @@ class LabsAgentsNamespace {
1174
1177
  }
1175
1178
  /** Spawn a durable hosted Supafone agent backed by Ultravox and Supafone-managed providers. */
1176
1179
  create(input) {
1177
- return this.sm.requestSupafoneApi("POST", "/api/v1/labs/agents", labsAgentPayload(this.withVoiceWatcher(input)));
1180
+ return this.sm.requestSupafoneApi("POST", "/api/v1/labs/agents", labsAgentPayload(this.withSupervisor(input)));
1178
1181
  }
1179
1182
  /** Preview the exact validated call-plan contract the Supafone runtime executes. */
1180
1183
  plan(input) {
@@ -1183,17 +1186,16 @@ class LabsAgentsNamespace {
1183
1186
  generateCallStages(input) {
1184
1187
  return this.plan(input);
1185
1188
  }
1186
- /** Default the agent onto the client's Voice Watcher setting (live supervision
1187
- * + QA + scoring) unless the caller set it explicitly; mirror into
1188
- * labs.voice_watcher when a labs block exists. Never overwrites a caller value. */
1189
- withVoiceWatcher(input) {
1189
+ /** Default the agent onto the client's Supafone Supervisor setting unless the
1190
+ * caller set it explicitly. Legacy wire fields remain unchanged. */
1191
+ withSupervisor(input) {
1190
1192
  const out = { ...input };
1191
- if (out.voice_watcher === undefined && out.voiceWatcher === undefined) {
1192
- out.voice_watcher = this.sm.voiceWatcher;
1193
+ if (out.supervisor === undefined && out.voice_watcher === undefined && out.voiceWatcher === undefined) {
1194
+ out.supervisor = this.sm.supervisor;
1193
1195
  }
1194
1196
  const labs = out.labs;
1195
- if (labs && labs.voice_watcher === undefined && labs.voiceWatcher === undefined) {
1196
- out.labs = { ...labs, voice_watcher: this.sm.voiceWatcher };
1197
+ if (labs && labs.supervisor === undefined && labs.voice_watcher === undefined && labs.voiceWatcher === undefined) {
1198
+ out.labs = { ...labs, supervisor: this.sm.supervisor };
1197
1199
  }
1198
1200
  return out;
1199
1201
  }
@@ -2012,9 +2014,10 @@ function labsAgentPayload(input) {
2012
2014
  artifacts: input.artifacts ? artifactsPayload(input.artifacts) : undefined,
2013
2015
  compliance: input.compliance,
2014
2016
  tools: input.tools ? toolsPayload(input.tools) : undefined,
2017
+ email: input.email ? emailPayload(input.email) : undefined,
2015
2018
  labs: input.labs ? labsPayload(input.labs) : undefined,
2016
2019
  ultravox: input.ultravox ? ultravoxPayload(input.ultravox) : undefined,
2017
- voice_watcher: input.voice_watcher ?? input.voiceWatcher,
2020
+ voice_watcher: input.supervisor ?? input.voice_watcher ?? input.voiceWatcher,
2018
2021
  voice_watcher_model: input.voice_watcher_model ?? input.voiceWatcherModel,
2019
2022
  metadata: labsAgentMetadataPayload(input),
2020
2023
  });
@@ -2373,9 +2376,20 @@ function toolsPayload(input) {
2373
2376
  existing_client_lookup: input.existing_client_lookup ?? input.existingClientLookup,
2374
2377
  voicemail: input.voicemail,
2375
2378
  emergency_escalation: input.emergency_escalation ?? input.emergencyEscalation,
2379
+ ivr_navigation: input.ivr_navigation ?? input.ivrNavigation,
2376
2380
  custom_tools: input.custom_tools ?? input.customTools,
2377
2381
  });
2378
2382
  }
2383
+ function emailPayload(input) {
2384
+ return compact({
2385
+ enabled: input.enabled,
2386
+ from_email: input.from_email ?? input.fromEmail,
2387
+ smtp_host: input.smtp_host ?? input.smtpHost,
2388
+ smtp_port: input.smtp_port ?? input.smtpPort,
2389
+ smtp_user: input.smtp_user ?? input.smtpUser,
2390
+ smtp_pass: input.smtp_pass ?? input.smtp_password ?? input.smtpPassword,
2391
+ });
2392
+ }
2379
2393
  function recordingPayload(input) {
2380
2394
  return compact({
2381
2395
  enabled: input.enabled,
@@ -2415,7 +2429,7 @@ function artifactsPayload(input) {
2415
2429
  function labsPayload(input) {
2416
2430
  return compact({
2417
2431
  enabled: input.enabled,
2418
- voice_watcher: input.voice_watcher ?? input.voiceWatcher,
2432
+ voice_watcher: input.supervisor ?? input.voice_watcher ?? input.voiceWatcher,
2419
2433
  api_key: input.api_key ?? input.apiKey,
2420
2434
  model: input.model,
2421
2435
  mode: input.mode,
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * A dependency-free TypeScript client for creating hosted Supafone agents
5
5
  * through the Supafone API, including managed phone numbers, voices, stages,
6
- * tools, recordings, transcripts, widgets, and Supafone Pro watcher. It also
6
+ * tools, recordings, transcripts, widgets, and Supafone Supervisor. It also
7
7
  * includes the Labs cloud sidecar oracle, hosted TTS/STT, live multilingual
8
8
  * transcription, telemetry, agent builder, and objective-driven optimizer.
9
9
  *
@@ -53,15 +53,13 @@ export interface SupafoneLabsOptions {
53
53
  * fall back to the plain zero-billed report.
54
54
  */
55
55
  postCallAnalysis?: boolean;
56
- /**
57
- * Run provisioned agents under Supafone's Voice Watcher framework — live
58
- * supervision, QA, and call scoring (default true). Set false for a raw
59
- * agent with no watcher. `voice_watcher` (snake) and the deprecated `labs`
60
- * are accepted aliases, resolved voiceWatcher > voice_watcher > labs > true.
61
- */
56
+ /** Enable Supafone Supervisor live guidance, QA, and scoring (default true). */
57
+ supervisor?: boolean;
58
+ /** @deprecated Use supervisor. */
62
59
  voiceWatcher?: boolean;
60
+ /** @deprecated Use supervisor. */
63
61
  voice_watcher?: boolean;
64
- /** @deprecated alias for voiceWatcher. */
62
+ /** @deprecated Use supervisor. */
65
63
  labs?: boolean;
66
64
  }
67
65
  export interface ChatMessage {
@@ -87,7 +85,9 @@ export interface WhisperOptions {
87
85
  maxTokens?: number;
88
86
  temperature?: number;
89
87
  }
90
- export type SecondMindDirectiveKind = "empathy" | "tactical" | "guardrail" | "mixed";
88
+ export type SupervisorDirectiveKind = "empathy" | "tactical" | "guardrail" | "mixed";
89
+ /** @deprecated Use SupervisorDirectiveKind. */
90
+ export type SecondMindDirectiveKind = SupervisorDirectiveKind;
91
91
  export interface DirectiveTextControl {
92
92
  enabled?: boolean;
93
93
  instructions?: string;
@@ -102,7 +102,7 @@ export interface DirectiveListControl {
102
102
  itemMaxChars?: number;
103
103
  item_max_chars?: number;
104
104
  }
105
- /** Serializable controls for each field generated by SecondMind. */
105
+ /** Serializable controls for each field generated by Supafone Supervisor. */
106
106
  export interface DirectiveContract {
107
107
  empathyDirective?: DirectiveTextControl;
108
108
  empathy_directive?: DirectiveTextControl;
@@ -115,27 +115,29 @@ export interface DirectiveContract {
115
115
  language_mode?: "caller" | "model" | "fixed";
116
116
  fixedLanguage?: string;
117
117
  fixed_language?: string;
118
- allowedKinds?: SecondMindDirectiveKind[];
119
- allowed_kinds?: SecondMindDirectiveKind[];
118
+ allowedKinds?: SupervisorDirectiveKind[];
119
+ allowed_kinds?: SupervisorDirectiveKind[];
120
120
  confidenceThreshold?: number;
121
121
  confidence_threshold?: number;
122
122
  operatorGuardrails?: string[];
123
123
  operator_guardrails?: string[];
124
124
  }
125
- export interface SecondMindDirective {
125
+ export interface SupervisorDirective {
126
126
  empathy_directive: string;
127
127
  tactical_directive: string;
128
128
  surface_facts: string[];
129
129
  guardrails: string[];
130
130
  language: string;
131
131
  confidence: number;
132
- kind: SecondMindDirectiveKind;
132
+ kind: SupervisorDirectiveKind;
133
133
  }
134
+ /** @deprecated Use SupervisorDirective. */
135
+ export type SecondMindDirective = SupervisorDirective;
134
136
  export interface StructuredWhisperOptions extends WhisperOptions {
135
137
  directiveContract?: DirectiveContract;
136
138
  directive_contract?: DirectiveContract;
137
139
  /** Local final say: revise or suppress the generated directive before use. */
138
- transform?: (directive: SecondMindDirective) => SecondMindDirective | null | Promise<SecondMindDirective | null>;
140
+ transform?: (directive: SupervisorDirective) => SupervisorDirective | null | Promise<SupervisorDirective | null>;
139
141
  }
140
142
  export interface Balance {
141
143
  plan: string;
@@ -539,8 +541,56 @@ export interface LabsToolsConfig {
539
541
  voicemail?: boolean;
540
542
  emergencyEscalation?: boolean;
541
543
  emergency_escalation?: boolean;
542
- customTools?: Array<Record<string, unknown>>;
543
- custom_tools?: Array<Record<string, unknown>>;
544
+ /** Makes the native DTMF tool available for bounded phone-tree navigation. */
545
+ ivrNavigation?: boolean;
546
+ ivr_navigation?: boolean;
547
+ /** Executable customer-owned HTTPS tools, proxied by Supafone at call time. */
548
+ customTools?: LabsCustomToolDefinition[];
549
+ custom_tools?: LabsCustomToolDefinition[];
550
+ }
551
+ export type LabsCustomToolParameterType = "string" | "number" | "integer" | "boolean";
552
+ export interface LabsCustomToolParameter {
553
+ name: string;
554
+ description?: string;
555
+ type?: LabsCustomToolParameterType;
556
+ required?: boolean;
557
+ }
558
+ export interface LabsCustomToolDefinition {
559
+ /** Stable id returned by Supafone. Omit it when creating a tool. */
560
+ id?: string;
561
+ /** Lowercase model tool name, such as lookup_order. */
562
+ name: string;
563
+ description?: string;
564
+ /** HTTPS endpoint called by Supafone's guarded server-side proxy. */
565
+ url: string;
566
+ /** Optional secret header name. Defaults to Authorization: Bearer <apiKey>. */
567
+ header?: string;
568
+ apiKey?: string;
569
+ api_key?: string;
570
+ /** Set false on update to remove a previously stored secret. */
571
+ apiKeySet?: boolean;
572
+ api_key_set?: boolean;
573
+ params?: LabsCustomToolParameter[];
574
+ parameters?: LabsCustomToolParameter[];
575
+ /** Optional call-stage keys where this tool is available. Empty means every stage. */
576
+ stages?: string[];
577
+ allowedStages?: string[];
578
+ allowed_stages?: string[];
579
+ }
580
+ export interface LabsEmailConfig {
581
+ enabled?: boolean;
582
+ fromEmail?: string;
583
+ from_email?: string;
584
+ smtpHost?: string;
585
+ smtp_host?: string;
586
+ smtpPort?: number;
587
+ smtp_port?: number;
588
+ smtpUser?: string;
589
+ smtp_user?: string;
590
+ /** Encrypted by Supafone and never returned. */
591
+ smtpPassword?: string;
592
+ smtp_password?: string;
593
+ smtp_pass?: string;
544
594
  }
545
595
  export interface LabsRecordingConfig {
546
596
  enabled?: boolean;
@@ -579,9 +629,12 @@ export interface LabsArtifactsConfig {
579
629
  retention_days?: number;
580
630
  metadata?: Record<string, unknown>;
581
631
  }
582
- export interface LabsWatcherConfig {
632
+ export interface LabsSupervisorConfig {
583
633
  enabled?: boolean;
634
+ supervisor?: boolean;
635
+ /** @deprecated Use supervisor. */
584
636
  voiceWatcher?: boolean;
637
+ /** @deprecated Use supervisor. */
585
638
  voice_watcher?: boolean;
586
639
  apiKey?: string;
587
640
  api_key?: string;
@@ -596,6 +649,8 @@ export interface LabsWatcherConfig {
596
649
  provider_keys?: Record<string, unknown>;
597
650
  label?: string;
598
651
  }
652
+ /** @deprecated Use LabsSupervisorConfig. */
653
+ export type LabsWatcherConfig = LabsSupervisorConfig;
599
654
  export interface LabsUltravoxRuntime {
600
655
  model?: string;
601
656
  temperature?: number;
@@ -810,9 +865,14 @@ export interface CreateLabsAgentRequest {
810
865
  artifacts?: LabsArtifactsConfig;
811
866
  compliance?: Record<string, unknown>;
812
867
  tools?: LabsToolsConfig;
813
- labs?: LabsWatcherConfig;
868
+ /** Optional per-agent SMTP sender used by the callable send_email tool. */
869
+ email?: LabsEmailConfig;
870
+ labs?: LabsSupervisorConfig;
814
871
  ultravox?: LabsUltravoxRuntime;
872
+ supervisor?: boolean;
873
+ /** @deprecated Use supervisor. */
815
874
  voiceWatcher?: boolean;
875
+ /** @deprecated Use supervisor. */
816
876
  voice_watcher?: boolean;
817
877
  voiceWatcherModel?: string;
818
878
  voice_watcher_model?: string;
@@ -1518,7 +1578,9 @@ export declare class SupafoneLabs {
1518
1578
  private readonly supafoneApiKey;
1519
1579
  private readonly timeoutMs;
1520
1580
  private readonly postCallAnalysis;
1521
- /** Client default for the Voice Watcher framework (supervision + QA + scoring). */
1581
+ /** Client default for Supafone Supervisor (live guidance + QA + scoring). */
1582
+ readonly supervisor: boolean;
1583
+ /** @deprecated Use supervisor. */
1522
1584
  readonly voiceWatcher: boolean;
1523
1585
  private sessionToken?;
1524
1586
  private accountToken?;
@@ -1623,13 +1685,13 @@ export declare class SupafoneLabs {
1623
1685
  */
1624
1686
  whisper(transcript: string, opts?: WhisperOptions): Promise<string>;
1625
1687
  /**
1626
- * Structured SecondMind guidance with developer-controlled field policy.
1688
+ * Structured Supafone Supervisor guidance with developer-controlled field policy.
1627
1689
  * Returns null when JSON is invalid, evidence misses the confidence gate,
1628
1690
  * the generated kind is disallowed, or the local transform suppresses it.
1629
1691
  */
1630
- whisperStructured(transcript: string, opts?: StructuredWhisperOptions): Promise<SecondMindDirective | null>;
1692
+ whisperStructured(transcript: string, opts?: StructuredWhisperOptions): Promise<SupervisorDirective | null>;
1631
1693
  /** Alias that reads naturally in applications building their own watcher loop. */
1632
- directive(transcript: string, opts?: StructuredWhisperOptions): Promise<SecondMindDirective | null>;
1694
+ directive(transcript: string, opts?: StructuredWhisperOptions): Promise<SupervisorDirective | null>;
1633
1695
  /** Hosted TTS — returns raw audio bytes (WAV/PCM per voice). */
1634
1696
  tts(text: string, voice?: string): Promise<Uint8Array>;
1635
1697
  /** Convenience alias for voice preview UI/buttons. */
@@ -2052,10 +2114,9 @@ declare class LabsAgentsNamespace {
2052
2114
  generateCallStages(input: CreateLabsAgentRequest & {
2053
2115
  description?: string;
2054
2116
  }): Promise<LabsCallPlan>;
2055
- /** Default the agent onto the client's Voice Watcher setting (live supervision
2056
- * + QA + scoring) unless the caller set it explicitly; mirror into
2057
- * labs.voice_watcher when a labs block exists. Never overwrites a caller value. */
2058
- private withVoiceWatcher;
2117
+ /** Default the agent onto the client's Supafone Supervisor setting unless the
2118
+ * caller set it explicitly. Legacy wire fields remain unchanged. */
2119
+ private withSupervisor;
2059
2120
  /** Create an inbound receptionist/intake agent. No Twilio account is required. */
2060
2121
  createInbound(input: CreateLabsAgentRequest): Promise<CreateLabsAgentResponse>;
2061
2122
  /** Create an outbound sales/speed-to-lead/campaign agent. No Twilio account is required. */