supafone-labs 0.6.2 → 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/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
  }
@@ -406,6 +409,17 @@ export interface LabsBrowserTestSession {
406
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
 
@@ -3343,7 +3360,7 @@ class LabsBillingNamespace {
3343
3360
  class LabsAgentsNamespace {
3344
3361
  constructor(private sm: SupafoneLabs) {}
3345
3362
 
3346
- /** Spawn a durable hosted Supafone agent backed by Ultravox and Supafone-managed providers. */
3363
+ /** Create a hosted Supafone agent with the default Ultravox runtime or a selected native S2S model. */
3347
3364
  create(input: CreateLabsAgentRequest): Promise<CreateLabsAgentResponse> {
3348
3365
  return this.sm.requestSupafoneApi<CreateLabsAgentResponse>(
3349
3366
  "POST",
@@ -4757,6 +4774,8 @@ function providerKeysPayload(input: LabsProviderKeys): Record<string, unknown> {
4757
4774
  openai_api_key: input.openai_api_key ?? input.openaiApiKey,
4758
4775
  xai: input.xai,
4759
4776
  xai_api_key: input.xai_api_key ?? input.xaiApiKey,
4777
+ smallest: input.smallest,
4778
+ smallest_api_key: input.smallest_api_key ?? input.smallestApiKey,
4760
4779
  });
4761
4780
  }
4762
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
+ }