supafone-labs 0.6.1 → 0.6.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 +59 -2
- package/dist/cjs/index.d.ts +24 -5
- package/dist/cjs/index.js +15 -24
- package/dist/cjs/s2s.d.ts +41 -0
- package/dist/cjs/s2s.js +89 -0
- package/dist/index.d.ts +24 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -23
- package/dist/index.js.map +1 -1
- package/dist/s2s.d.ts +42 -0
- package/dist/s2s.d.ts.map +1 -0
- package/dist/s2s.js +81 -0
- package/dist/s2s.js.map +1 -0
- package/package.json +2 -2
- package/src/index.ts +30 -6
- package/src/s2s.ts +100 -0
package/src/index.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
export { SupafoneS2S, UltravoxS2S, OpenAIS2S, GeminiS2S, GrokS2S, HydraS2S } from "./s2s.js";
|
|
2
|
+
export type { S2SProviderName, S2SModelOptions, S2SOptions } from "./s2s.js";
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* Supafone Labs — the agent framework behind Supafone.
|
|
3
6
|
*
|
|
@@ -385,7 +388,7 @@ export interface LabsVoicePreference {
|
|
|
385
388
|
|
|
386
389
|
/** Direct speech-to-speech configuration for browser previews and carrier phone calls. */
|
|
387
390
|
export interface LabsRealtimeSelection {
|
|
388
|
-
provider: "openai" | "google" | "xai";
|
|
391
|
+
provider: "openai" | "google" | "xai" | "smallest";
|
|
389
392
|
model?: string;
|
|
390
393
|
voice?: string;
|
|
391
394
|
}
|
|
@@ -402,10 +405,21 @@ export interface LabsBrowserTestSession {
|
|
|
402
405
|
provider: string;
|
|
403
406
|
transport: "ultravox" | "supafone_realtime";
|
|
404
407
|
join_url?: string | null;
|
|
405
|
-
websocket_url?: string;
|
|
406
|
-
token?: string;
|
|
408
|
+
websocket_url?: string | null;
|
|
409
|
+
token?: string | null;
|
|
407
410
|
input_sample_rate?: number;
|
|
408
411
|
output_sample_rate?: number;
|
|
412
|
+
capabilities?: {
|
|
413
|
+
stages?: boolean;
|
|
414
|
+
tools?: boolean;
|
|
415
|
+
transcripts?: boolean;
|
|
416
|
+
recording?: boolean;
|
|
417
|
+
supervisor?: boolean;
|
|
418
|
+
transfer?: boolean;
|
|
419
|
+
mutable_instructions?: boolean;
|
|
420
|
+
stage_update_mode?: string;
|
|
421
|
+
languages?: string[];
|
|
422
|
+
};
|
|
409
423
|
};
|
|
410
424
|
}
|
|
411
425
|
|
|
@@ -483,6 +497,9 @@ export interface LabsProviderKeys {
|
|
|
483
497
|
xai?: string;
|
|
484
498
|
xaiApiKey?: string;
|
|
485
499
|
xai_api_key?: string;
|
|
500
|
+
smallest?: string;
|
|
501
|
+
smallestApiKey?: string;
|
|
502
|
+
smallest_api_key?: string;
|
|
486
503
|
[extra: string]: unknown;
|
|
487
504
|
}
|
|
488
505
|
|
|
@@ -1123,7 +1140,10 @@ export interface LabsAgentReadiness {
|
|
|
1123
1140
|
[extra: string]: unknown;
|
|
1124
1141
|
}
|
|
1125
1142
|
|
|
1126
|
-
export type UpdateLabsAgentRequest = Partial<CreateLabsAgentRequest
|
|
1143
|
+
export type UpdateLabsAgentRequest = Omit<Partial<CreateLabsAgentRequest>, "realtime"> & {
|
|
1144
|
+
/** Select another native model, or null to return to the default Ultravox runtime. */
|
|
1145
|
+
realtime?: LabsRealtimeSelection | null;
|
|
1146
|
+
};
|
|
1127
1147
|
|
|
1128
1148
|
export interface LabsAgentLifecycleResponse {
|
|
1129
1149
|
success?: boolean;
|
|
@@ -3340,7 +3360,7 @@ class LabsBillingNamespace {
|
|
|
3340
3360
|
class LabsAgentsNamespace {
|
|
3341
3361
|
constructor(private sm: SupafoneLabs) {}
|
|
3342
3362
|
|
|
3343
|
-
/**
|
|
3363
|
+
/** Create a hosted Supafone agent with the default Ultravox runtime or a selected native S2S model. */
|
|
3344
3364
|
create(input: CreateLabsAgentRequest): Promise<CreateLabsAgentResponse> {
|
|
3345
3365
|
return this.sm.requestSupafoneApi<CreateLabsAgentResponse>(
|
|
3346
3366
|
"POST",
|
|
@@ -4351,7 +4371,9 @@ function labsAgentMetadataPayload(input: CreateLabsAgentRequest): Record<string,
|
|
|
4351
4371
|
}
|
|
4352
4372
|
|
|
4353
4373
|
function labsAgentUpdatePayload(input: UpdateLabsAgentRequest): Record<string, unknown> {
|
|
4354
|
-
|
|
4374
|
+
const payload = labsAgentPayload(input as CreateLabsAgentRequest);
|
|
4375
|
+
if (input.realtime === null) payload.realtime = null;
|
|
4376
|
+
return payload;
|
|
4355
4377
|
}
|
|
4356
4378
|
|
|
4357
4379
|
function campaignSettingsPayload(
|
|
@@ -4752,6 +4774,8 @@ function providerKeysPayload(input: LabsProviderKeys): Record<string, unknown> {
|
|
|
4752
4774
|
openai_api_key: input.openai_api_key ?? input.openaiApiKey,
|
|
4753
4775
|
xai: input.xai,
|
|
4754
4776
|
xai_api_key: input.xai_api_key ?? input.xaiApiKey,
|
|
4777
|
+
smallest: input.smallest,
|
|
4778
|
+
smallest_api_key: input.smallest_api_key ?? input.smallestApiKey,
|
|
4755
4779
|
});
|
|
4756
4780
|
}
|
|
4757
4781
|
|
package/src/s2s.ts
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CreateLabsAgentRequest,
|
|
3
|
+
GetLabsAgentOptions,
|
|
4
|
+
LabsRealtimeSelection,
|
|
5
|
+
SupafoneLabs,
|
|
6
|
+
} from "./index.js";
|
|
7
|
+
|
|
8
|
+
export type S2SProviderName = "ultravox" | "openai" | "google" | "xai" | "smallest";
|
|
9
|
+
export interface S2SModelOptions {
|
|
10
|
+
model?: string;
|
|
11
|
+
voice?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface S2SOptions extends S2SModelOptions {
|
|
14
|
+
provider?: S2SProviderName;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Shared parent for Supafone-hosted S2S agents. Vendor keys stay on the server. */
|
|
18
|
+
export class SupafoneS2S {
|
|
19
|
+
readonly provider: S2SProviderName;
|
|
20
|
+
private readonly selection: LabsRealtimeSelection | null;
|
|
21
|
+
|
|
22
|
+
constructor(protected readonly client: SupafoneLabs, options: S2SOptions = {}) {
|
|
23
|
+
const provider = options.provider ?? "ultravox";
|
|
24
|
+
if (!["ultravox", "openai", "google", "xai", "smallest"].includes(provider)) {
|
|
25
|
+
throw new Error("Unsupported Supafone S2S provider");
|
|
26
|
+
}
|
|
27
|
+
if (provider === "ultravox" && (options.model !== undefined || options.voice !== undefined)) {
|
|
28
|
+
throw new Error("Configure Ultravox voices through the agent's voice settings");
|
|
29
|
+
}
|
|
30
|
+
for (const field of ["model", "voice"] as const) {
|
|
31
|
+
const value = options[field];
|
|
32
|
+
if (value !== undefined && (typeof value !== "string" || !value.trim())) {
|
|
33
|
+
throw new Error(`${field} must be a non-empty string`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
this.provider = provider;
|
|
37
|
+
this.selection = provider === "ultravox" ? null : {
|
|
38
|
+
provider,
|
|
39
|
+
...(options.model !== undefined ? { model: options.model.trim() } : {}),
|
|
40
|
+
...(options.voice !== undefined ? { voice: options.voice.trim() } : {}),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** A fresh wire selection; null explicitly restores the default Ultravox runtime. */
|
|
45
|
+
get realtime(): LabsRealtimeSelection | null {
|
|
46
|
+
return this.selection ? { ...this.selection } : null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Create through the normal hosted agent factory with this provider. */
|
|
50
|
+
create(input: Omit<CreateLabsAgentRequest, "realtime">) {
|
|
51
|
+
if ("realtime" in input) {
|
|
52
|
+
throw new Error("Set provider/model/voice on the S2S adapter, not create({realtime: ...})");
|
|
53
|
+
}
|
|
54
|
+
return this.client.labs.agents.create({
|
|
55
|
+
...input,
|
|
56
|
+
...(this.realtime ? { realtime: this.realtime } : {}),
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Change the saved selection for subsequent calls, preserving the agent and number. */
|
|
61
|
+
apply(agentKey: string, options: GetLabsAgentOptions = {}) {
|
|
62
|
+
this.checkAgentKey(agentKey);
|
|
63
|
+
return this.client.labs.agents.update(agentKey, { realtime: this.realtime }, options);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Preview the saved agent. Call apply first when switching providers. */
|
|
67
|
+
testCall(agentKey: string, options: GetLabsAgentOptions = {}) {
|
|
68
|
+
this.checkAgentKey(agentKey);
|
|
69
|
+
return this.client.labs.agents.testCall(agentKey, options);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private checkAgentKey(agentKey: string): void {
|
|
73
|
+
if (typeof agentKey !== "string" || !agentKey.trim()) throw new Error("agentKey is required");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export class UltravoxS2S extends SupafoneS2S {
|
|
78
|
+
constructor(client: SupafoneLabs) { super(client, { provider: "ultravox" }); }
|
|
79
|
+
}
|
|
80
|
+
export class OpenAIS2S extends SupafoneS2S {
|
|
81
|
+
constructor(client: SupafoneLabs, options: S2SModelOptions = {}) {
|
|
82
|
+
super(client, { ...options, provider: "openai" });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
export class GeminiS2S extends SupafoneS2S {
|
|
86
|
+
constructor(client: SupafoneLabs, options: S2SModelOptions = {}) {
|
|
87
|
+
super(client, { ...options, provider: "google" });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
export class GrokS2S extends SupafoneS2S {
|
|
91
|
+
constructor(client: SupafoneLabs, options: S2SModelOptions = {}) {
|
|
92
|
+
super(client, { ...options, provider: "xai" });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/** Smallest AI Hydra: full-duplex audio, without transcript events. */
|
|
96
|
+
export class HydraS2S extends SupafoneS2S {
|
|
97
|
+
constructor(client: SupafoneLabs, options: S2SModelOptions = {}) {
|
|
98
|
+
super(client, { ...options, provider: "smallest" });
|
|
99
|
+
}
|
|
100
|
+
}
|