supafone-labs 0.5.2 → 0.5.3
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 +6 -7
- package/dist/cjs/index.d.ts +36 -25
- package/dist/cjs/index.js +20 -18
- package/dist/index.d.ts +36 -25
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -18
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +57 -42
package/src/index.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
|
|
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
|
*
|
|
@@ -54,15 +54,13 @@ export interface SupafoneLabsOptions {
|
|
|
54
54
|
* fall back to the plain zero-billed report.
|
|
55
55
|
*/
|
|
56
56
|
postCallAnalysis?: boolean;
|
|
57
|
-
/**
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
* agent with no watcher. `voice_watcher` (snake) and the deprecated `labs`
|
|
61
|
-
* are accepted aliases, resolved voiceWatcher > voice_watcher > labs > true.
|
|
62
|
-
*/
|
|
57
|
+
/** Enable Supafone Supervisor live guidance, QA, and scoring (default true). */
|
|
58
|
+
supervisor?: boolean;
|
|
59
|
+
/** @deprecated Use supervisor. */
|
|
63
60
|
voiceWatcher?: boolean;
|
|
61
|
+
/** @deprecated Use supervisor. */
|
|
64
62
|
voice_watcher?: boolean;
|
|
65
|
-
/** @deprecated
|
|
63
|
+
/** @deprecated Use supervisor. */
|
|
66
64
|
labs?: boolean;
|
|
67
65
|
}
|
|
68
66
|
|
|
@@ -93,7 +91,10 @@ export interface WhisperOptions {
|
|
|
93
91
|
temperature?: number;
|
|
94
92
|
}
|
|
95
93
|
|
|
96
|
-
export type
|
|
94
|
+
export type SupervisorDirectiveKind = "empathy" | "tactical" | "guardrail" | "mixed";
|
|
95
|
+
|
|
96
|
+
/** @deprecated Use SupervisorDirectiveKind. */
|
|
97
|
+
export type SecondMindDirectiveKind = SupervisorDirectiveKind;
|
|
97
98
|
|
|
98
99
|
export interface DirectiveTextControl {
|
|
99
100
|
enabled?: boolean;
|
|
@@ -111,7 +112,7 @@ export interface DirectiveListControl {
|
|
|
111
112
|
item_max_chars?: number;
|
|
112
113
|
}
|
|
113
114
|
|
|
114
|
-
/** Serializable controls for each field generated by
|
|
115
|
+
/** Serializable controls for each field generated by Supafone Supervisor. */
|
|
115
116
|
export interface DirectiveContract {
|
|
116
117
|
empathyDirective?: DirectiveTextControl;
|
|
117
118
|
empathy_directive?: DirectiveTextControl;
|
|
@@ -124,31 +125,34 @@ export interface DirectiveContract {
|
|
|
124
125
|
language_mode?: "caller" | "model" | "fixed";
|
|
125
126
|
fixedLanguage?: string;
|
|
126
127
|
fixed_language?: string;
|
|
127
|
-
allowedKinds?:
|
|
128
|
-
allowed_kinds?:
|
|
128
|
+
allowedKinds?: SupervisorDirectiveKind[];
|
|
129
|
+
allowed_kinds?: SupervisorDirectiveKind[];
|
|
129
130
|
confidenceThreshold?: number;
|
|
130
131
|
confidence_threshold?: number;
|
|
131
132
|
operatorGuardrails?: string[];
|
|
132
133
|
operator_guardrails?: string[];
|
|
133
134
|
}
|
|
134
135
|
|
|
135
|
-
export interface
|
|
136
|
+
export interface SupervisorDirective {
|
|
136
137
|
empathy_directive: string;
|
|
137
138
|
tactical_directive: string;
|
|
138
139
|
surface_facts: string[];
|
|
139
140
|
guardrails: string[];
|
|
140
141
|
language: string;
|
|
141
142
|
confidence: number;
|
|
142
|
-
kind:
|
|
143
|
+
kind: SupervisorDirectiveKind;
|
|
143
144
|
}
|
|
144
145
|
|
|
146
|
+
/** @deprecated Use SupervisorDirective. */
|
|
147
|
+
export type SecondMindDirective = SupervisorDirective;
|
|
148
|
+
|
|
145
149
|
export interface StructuredWhisperOptions extends WhisperOptions {
|
|
146
150
|
directiveContract?: DirectiveContract;
|
|
147
151
|
directive_contract?: DirectiveContract;
|
|
148
152
|
/** Local final say: revise or suppress the generated directive before use. */
|
|
149
153
|
transform?: (
|
|
150
|
-
directive:
|
|
151
|
-
) =>
|
|
154
|
+
directive: SupervisorDirective,
|
|
155
|
+
) => SupervisorDirective | null | Promise<SupervisorDirective | null>;
|
|
152
156
|
}
|
|
153
157
|
|
|
154
158
|
export interface Balance {
|
|
@@ -618,9 +622,12 @@ export interface LabsArtifactsConfig {
|
|
|
618
622
|
metadata?: Record<string, unknown>;
|
|
619
623
|
}
|
|
620
624
|
|
|
621
|
-
export interface
|
|
625
|
+
export interface LabsSupervisorConfig {
|
|
622
626
|
enabled?: boolean;
|
|
627
|
+
supervisor?: boolean;
|
|
628
|
+
/** @deprecated Use supervisor. */
|
|
623
629
|
voiceWatcher?: boolean;
|
|
630
|
+
/** @deprecated Use supervisor. */
|
|
624
631
|
voice_watcher?: boolean;
|
|
625
632
|
apiKey?: string;
|
|
626
633
|
api_key?: string;
|
|
@@ -636,6 +643,9 @@ export interface LabsWatcherConfig {
|
|
|
636
643
|
label?: string;
|
|
637
644
|
}
|
|
638
645
|
|
|
646
|
+
/** @deprecated Use LabsSupervisorConfig. */
|
|
647
|
+
export type LabsWatcherConfig = LabsSupervisorConfig;
|
|
648
|
+
|
|
639
649
|
export interface LabsUltravoxRuntime {
|
|
640
650
|
model?: string;
|
|
641
651
|
temperature?: number;
|
|
@@ -948,9 +958,12 @@ export interface CreateLabsAgentRequest {
|
|
|
948
958
|
artifacts?: LabsArtifactsConfig;
|
|
949
959
|
compliance?: Record<string, unknown>;
|
|
950
960
|
tools?: LabsToolsConfig;
|
|
951
|
-
labs?:
|
|
961
|
+
labs?: LabsSupervisorConfig;
|
|
952
962
|
ultravox?: LabsUltravoxRuntime;
|
|
963
|
+
supervisor?: boolean;
|
|
964
|
+
/** @deprecated Use supervisor. */
|
|
953
965
|
voiceWatcher?: boolean;
|
|
966
|
+
/** @deprecated Use supervisor. */
|
|
954
967
|
voice_watcher?: boolean;
|
|
955
968
|
voiceWatcherModel?: string;
|
|
956
969
|
voice_watcher_model?: string;
|
|
@@ -1722,13 +1735,13 @@ const DEFAULT_BASE = "https://api.labs.supafone.ai";
|
|
|
1722
1735
|
const DEFAULT_SUPAFONE_API_BASE = "https://api.supafone.ai";
|
|
1723
1736
|
|
|
1724
1737
|
const COACH_SYSTEM =
|
|
1725
|
-
"You are the coaching core of a
|
|
1738
|
+
"You are the coaching core of a supervisor for a live voice agent. Read the " +
|
|
1726
1739
|
"conversation and return ONE short, silent directive the agent reads but never " +
|
|
1727
1740
|
"speaks aloud — a correction or nudge, phrased imperatively. If nothing needs " +
|
|
1728
1741
|
"correcting, return an empty string.";
|
|
1729
1742
|
|
|
1730
1743
|
const STRUCTURED_COACH_SYSTEM =
|
|
1731
|
-
"You are the coaching core of a
|
|
1744
|
+
"You are the coaching core of a supervisor for a live voice agent. Read the " +
|
|
1732
1745
|
"conversation and return ONLY one JSON object with exactly these keys: " +
|
|
1733
1746
|
"empathy_directive (string), tactical_directive (string), surface_facts (string[]), " +
|
|
1734
1747
|
"guardrails (string[]), language (short code), confidence (0-1), and kind " +
|
|
@@ -1747,7 +1760,7 @@ interface NormalizedDirectiveContract {
|
|
|
1747
1760
|
};
|
|
1748
1761
|
language_mode: "caller" | "model" | "fixed";
|
|
1749
1762
|
fixed_language: string;
|
|
1750
|
-
allowed_kinds:
|
|
1763
|
+
allowed_kinds: SupervisorDirectiveKind[];
|
|
1751
1764
|
confidence_threshold: number;
|
|
1752
1765
|
operator_guardrails: string[];
|
|
1753
1766
|
}
|
|
@@ -1787,7 +1800,7 @@ function normalizeDirectiveContract(input: DirectiveContract = {}): NormalizedDi
|
|
|
1787
1800
|
guardrails: listControl(input.guardrails),
|
|
1788
1801
|
language_mode: languageMode,
|
|
1789
1802
|
fixed_language: String(input.fixed_language ?? input.fixedLanguage ?? "").trim(),
|
|
1790
|
-
allowed_kinds: allowed.filter((kind): kind is
|
|
1803
|
+
allowed_kinds: allowed.filter((kind): kind is SupervisorDirectiveKind =>
|
|
1791
1804
|
["empathy", "tactical", "guardrail", "mixed"].includes(kind),
|
|
1792
1805
|
),
|
|
1793
1806
|
confidence_threshold: Number.isFinite(threshold) ? Math.max(0, Math.min(1, threshold)) : 0.5,
|
|
@@ -1832,8 +1845,8 @@ function clipList(value: unknown, maxItems: number, itemMaxChars: number): strin
|
|
|
1832
1845
|
function normalizeStructuredDirective(
|
|
1833
1846
|
raw: Record<string, unknown>,
|
|
1834
1847
|
contract: NormalizedDirectiveContract,
|
|
1835
|
-
):
|
|
1836
|
-
const kind = String(raw.kind ?? "mixed") as
|
|
1848
|
+
): SupervisorDirective | null {
|
|
1849
|
+
const kind = String(raw.kind ?? "mixed") as SupervisorDirectiveKind;
|
|
1837
1850
|
if (!["empathy", "tactical", "guardrail", "mixed"].includes(kind)) return null;
|
|
1838
1851
|
const parsedConfidence = Number(raw.confidence ?? 0);
|
|
1839
1852
|
const confidence = Number.isFinite(parsedConfidence) ? Math.max(0, Math.min(1, parsedConfidence)) : 0;
|
|
@@ -1869,7 +1882,9 @@ export class SupafoneLabs {
|
|
|
1869
1882
|
private readonly supafoneApiKey: string;
|
|
1870
1883
|
private readonly timeoutMs: number;
|
|
1871
1884
|
private readonly postCallAnalysis: boolean;
|
|
1872
|
-
/** Client default for
|
|
1885
|
+
/** Client default for Supafone Supervisor (live guidance + QA + scoring). */
|
|
1886
|
+
readonly supervisor: boolean;
|
|
1887
|
+
/** @deprecated Use supervisor. */
|
|
1873
1888
|
readonly voiceWatcher: boolean;
|
|
1874
1889
|
private sessionToken?: string;
|
|
1875
1890
|
private accountToken?: string;
|
|
@@ -1898,8 +1913,9 @@ export class SupafoneLabs {
|
|
|
1898
1913
|
this.appUrl = (opts.appUrl ?? "https://app.supafone.ai").replace(/\/$/, "");
|
|
1899
1914
|
this.timeoutMs = opts.timeoutMs ?? 30_000;
|
|
1900
1915
|
this.postCallAnalysis = opts.postCallAnalysis ?? false;
|
|
1901
|
-
// Precedence:
|
|
1902
|
-
this.
|
|
1916
|
+
// Precedence: supervisor > legacy aliases > true.
|
|
1917
|
+
this.supervisor = opts.supervisor ?? opts.voiceWatcher ?? opts.voice_watcher ?? opts.labs ?? true;
|
|
1918
|
+
this.voiceWatcher = this.supervisor;
|
|
1903
1919
|
this.sessionToken = opts.sessionToken;
|
|
1904
1920
|
this.accountToken = opts.accountToken;
|
|
1905
1921
|
this.accountEmail = opts.accountEmail;
|
|
@@ -2259,14 +2275,14 @@ export class SupafoneLabs {
|
|
|
2259
2275
|
}
|
|
2260
2276
|
|
|
2261
2277
|
/**
|
|
2262
|
-
* Structured
|
|
2278
|
+
* Structured Supafone Supervisor guidance with developer-controlled field policy.
|
|
2263
2279
|
* Returns null when JSON is invalid, evidence misses the confidence gate,
|
|
2264
2280
|
* the generated kind is disallowed, or the local transform suppresses it.
|
|
2265
2281
|
*/
|
|
2266
2282
|
async whisperStructured(
|
|
2267
2283
|
transcript: string,
|
|
2268
2284
|
opts: StructuredWhisperOptions = {},
|
|
2269
|
-
): Promise<
|
|
2285
|
+
): Promise<SupervisorDirective | null> {
|
|
2270
2286
|
const contract = normalizeDirectiveContract(
|
|
2271
2287
|
opts.directive_contract ?? opts.directiveContract ?? {},
|
|
2272
2288
|
);
|
|
@@ -2300,7 +2316,7 @@ export class SupafoneLabs {
|
|
|
2300
2316
|
directive(
|
|
2301
2317
|
transcript: string,
|
|
2302
2318
|
opts: StructuredWhisperOptions = {},
|
|
2303
|
-
): Promise<
|
|
2319
|
+
): Promise<SupervisorDirective | null> {
|
|
2304
2320
|
return this.whisperStructured(transcript, opts);
|
|
2305
2321
|
}
|
|
2306
2322
|
|
|
@@ -3097,7 +3113,7 @@ class LabsAgentsNamespace {
|
|
|
3097
3113
|
return this.sm.requestSupafoneApi<CreateLabsAgentResponse>(
|
|
3098
3114
|
"POST",
|
|
3099
3115
|
"/api/v1/labs/agents",
|
|
3100
|
-
labsAgentPayload(this.
|
|
3116
|
+
labsAgentPayload(this.withSupervisor(input)),
|
|
3101
3117
|
);
|
|
3102
3118
|
}
|
|
3103
3119
|
|
|
@@ -3114,17 +3130,16 @@ class LabsAgentsNamespace {
|
|
|
3114
3130
|
return this.plan(input);
|
|
3115
3131
|
}
|
|
3116
3132
|
|
|
3117
|
-
/** Default the agent onto the client's
|
|
3118
|
-
*
|
|
3119
|
-
|
|
3120
|
-
private withVoiceWatcher(input: CreateLabsAgentRequest): CreateLabsAgentRequest {
|
|
3133
|
+
/** Default the agent onto the client's Supafone Supervisor setting unless the
|
|
3134
|
+
* caller set it explicitly. Legacy wire fields remain unchanged. */
|
|
3135
|
+
private withSupervisor(input: CreateLabsAgentRequest): CreateLabsAgentRequest {
|
|
3121
3136
|
const out: CreateLabsAgentRequest = { ...input };
|
|
3122
|
-
if (out.voice_watcher === undefined && out.voiceWatcher === undefined) {
|
|
3123
|
-
out.
|
|
3137
|
+
if (out.supervisor === undefined && out.voice_watcher === undefined && out.voiceWatcher === undefined) {
|
|
3138
|
+
out.supervisor = this.sm.supervisor;
|
|
3124
3139
|
}
|
|
3125
3140
|
const labs = out.labs;
|
|
3126
|
-
if (labs && labs.voice_watcher === undefined && labs.voiceWatcher === undefined) {
|
|
3127
|
-
out.labs = { ...labs,
|
|
3141
|
+
if (labs && labs.supervisor === undefined && labs.voice_watcher === undefined && labs.voiceWatcher === undefined) {
|
|
3142
|
+
out.labs = { ...labs, supervisor: this.sm.supervisor };
|
|
3128
3143
|
}
|
|
3129
3144
|
return out;
|
|
3130
3145
|
}
|
|
@@ -4101,7 +4116,7 @@ function labsAgentPayload(input: CreateLabsAgentRequest): Record<string, unknown
|
|
|
4101
4116
|
tools: input.tools ? toolsPayload(input.tools) : undefined,
|
|
4102
4117
|
labs: input.labs ? labsPayload(input.labs) : undefined,
|
|
4103
4118
|
ultravox: input.ultravox ? ultravoxPayload(input.ultravox) : undefined,
|
|
4104
|
-
voice_watcher: input.voice_watcher ?? input.voiceWatcher,
|
|
4119
|
+
voice_watcher: input.supervisor ?? input.voice_watcher ?? input.voiceWatcher,
|
|
4105
4120
|
voice_watcher_model: input.voice_watcher_model ?? input.voiceWatcherModel,
|
|
4106
4121
|
metadata: labsAgentMetadataPayload(input),
|
|
4107
4122
|
});
|
|
@@ -4533,10 +4548,10 @@ function artifactsPayload(input: LabsArtifactsConfig): Record<string, unknown> {
|
|
|
4533
4548
|
});
|
|
4534
4549
|
}
|
|
4535
4550
|
|
|
4536
|
-
function labsPayload(input:
|
|
4551
|
+
function labsPayload(input: LabsSupervisorConfig): Record<string, unknown> {
|
|
4537
4552
|
return compact({
|
|
4538
4553
|
enabled: input.enabled,
|
|
4539
|
-
voice_watcher: input.voice_watcher ?? input.voiceWatcher,
|
|
4554
|
+
voice_watcher: input.supervisor ?? input.voice_watcher ?? input.voiceWatcher,
|
|
4540
4555
|
api_key: input.api_key ?? input.apiKey,
|
|
4541
4556
|
model: input.model,
|
|
4542
4557
|
mode: input.mode,
|