supafone-labs 0.4.9 → 0.4.12
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 +13 -0
- package/dist/cjs/index.d.ts +162 -7
- package/dist/cjs/index.js +150 -3
- package/dist/index.d.ts +162 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +150 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +284 -10
package/README.md
CHANGED
|
@@ -432,6 +432,12 @@ await sf.campaigns.launch(campaign.id); // real calls
|
|
|
432
432
|
|
|
433
433
|
const live = await sf.campaigns.live(campaign.id); // in-flight calls + listen links
|
|
434
434
|
await sf.callFromAgent({ agentId: agents[0].id, toNumber: "+15551234567" }); // ring a phone right now
|
|
435
|
+
|
|
436
|
+
// Browser voice: creates WebRTC credentials without dialing a phone number.
|
|
437
|
+
const webCall = await sf.startWebRtcCall({ agentId: agents[0].id });
|
|
438
|
+
if (!webCall.browser_session.available) throw new Error("Browser voice unavailable");
|
|
439
|
+
// Pass webCall.browser_session.join_url to the adapter named by
|
|
440
|
+
// webCall.browser_session.transport (currently the Ultravox browser client).
|
|
435
441
|
```
|
|
436
442
|
|
|
437
443
|
`campaigns.live()` returns a portal link (`app.supafone.ai/app/developer`) and
|
|
@@ -462,6 +468,7 @@ and `const { Supafone } = require("supafone-labs")` both work, with full types.
|
|
|
462
468
|
| `labs.agents.create/createInbound/createOutbound/list/get` | `/api/v1/labs/agents*` on the Supafone API |
|
|
463
469
|
| `labs.agents.createInboundWithNumber/createOutboundWithNumber` | Agent creation plus Supafone-managed number buy/assign |
|
|
464
470
|
| `labs.phoneNumbers.search/buy/assign/list/buyAndAssign` | `/api/v1/labs/phone-numbers*` |
|
|
471
|
+
| `labs.billing.checkout/status/portal` | Stripe-hosted Checkout, payment polling, and Customer Portal |
|
|
465
472
|
| `labs.telephony.get/configure/useSupafoneManaged` | `/api/v1/labs/telephony` |
|
|
466
473
|
| `labs.presets.list()` · `labs.tools.list()` · `labs.voices.list()` | Supafone hosted-agent discovery |
|
|
467
474
|
| `whisper(transcript, opts?)` | convenience over the oracle |
|
|
@@ -477,6 +484,12 @@ and `const { Supafone } = require("supafone-labs")` both work, with full types.
|
|
|
477
484
|
|
|
478
485
|
Get a key (5 free minutes, no card): <https://labs.supafone.ai/get-key.html>
|
|
479
486
|
|
|
487
|
+
For `dedicated` or `premium`, `labs.phoneNumbers.buy()` first returns a public
|
|
488
|
+
`checkout_url`. Open it, poll `labs.billing.status()`, then call `buy()` again
|
|
489
|
+
with `billingCheckoutSessionId`. The server verifies and consumes the paid
|
|
490
|
+
entitlement before carrier provisioning; Stripe secrets and card data never
|
|
491
|
+
enter the SDK.
|
|
492
|
+
|
|
480
493
|
The runtime, all provider adapters, and the offline (bring-your-own-keys) mode
|
|
481
494
|
are open source and MIT-licensed — the Python package `pip install supafone-labs`
|
|
482
495
|
is the full harness. This client is the thin cloud SDK.
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -131,13 +131,29 @@ export interface LabsCallStage {
|
|
|
131
131
|
key?: string;
|
|
132
132
|
id?: string;
|
|
133
133
|
name: string;
|
|
134
|
+
/** Plain-English job description used by the hosted call-plan generator. */
|
|
135
|
+
description?: string;
|
|
134
136
|
goal?: string;
|
|
135
137
|
instructions?: string;
|
|
136
138
|
exitCriteria?: string[];
|
|
137
139
|
exit_criteria?: string[];
|
|
138
140
|
tools?: string[];
|
|
141
|
+
temperature?: number;
|
|
142
|
+
nextStages?: string[];
|
|
143
|
+
next_stages?: string[];
|
|
139
144
|
metadata?: Record<string, unknown>;
|
|
140
145
|
}
|
|
146
|
+
export type LabsStageGeneration = "oracle" | "template" | "off";
|
|
147
|
+
export interface LabsCallPlan {
|
|
148
|
+
version: "supafone_call_plan_v1" | string;
|
|
149
|
+
summary: string;
|
|
150
|
+
base_system_prompt: string;
|
|
151
|
+
call_stages: LabsCallStage[];
|
|
152
|
+
generated_by: "supafone_hosted_haiku" | "deterministic_template" | "deterministic_fallback" | "developer" | string;
|
|
153
|
+
model: string;
|
|
154
|
+
fallback: boolean;
|
|
155
|
+
warnings?: string[];
|
|
156
|
+
}
|
|
141
157
|
export interface LabsVoiceSelection {
|
|
142
158
|
provider?: string;
|
|
143
159
|
voiceId?: string;
|
|
@@ -454,6 +470,8 @@ export interface CreateLabsAgentRequest {
|
|
|
454
470
|
agentStyle?: LabsAgentStyle;
|
|
455
471
|
agent_style?: LabsAgentStyle;
|
|
456
472
|
name: string;
|
|
473
|
+
/** Plain-language job description used by the hosted call-plan generator. */
|
|
474
|
+
description?: string;
|
|
457
475
|
assistantName?: string;
|
|
458
476
|
assistant_name?: string;
|
|
459
477
|
businessName?: string;
|
|
@@ -473,12 +491,18 @@ export interface CreateLabsAgentRequest {
|
|
|
473
491
|
preset_key?: string;
|
|
474
492
|
runtimeMode?: LabsRuntimeMode;
|
|
475
493
|
runtime_mode?: LabsRuntimeMode;
|
|
476
|
-
/**
|
|
477
|
-
callStages?: boolean | LabsCallStage[];
|
|
478
|
-
call_stages?: boolean | LabsCallStage[];
|
|
494
|
+
/** Defaults to Supafone's hosted planner; model credentials remain server-side. */
|
|
495
|
+
callStages?: boolean | LabsStageGeneration | LabsCallStage[];
|
|
496
|
+
call_stages?: boolean | LabsStageGeneration | LabsCallStage[];
|
|
479
497
|
stages?: LabsCallStage[];
|
|
480
498
|
autoCallStages?: boolean;
|
|
481
499
|
auto_call_stages?: boolean;
|
|
500
|
+
stageGeneration?: LabsStageGeneration;
|
|
501
|
+
stage_generation?: LabsStageGeneration;
|
|
502
|
+
stageCount?: number;
|
|
503
|
+
stage_count?: number;
|
|
504
|
+
stageDetail?: "compact" | "standard" | "detailed";
|
|
505
|
+
stage_detail?: "compact" | "standard" | "detailed";
|
|
482
506
|
goal?: string;
|
|
483
507
|
greeting?: string;
|
|
484
508
|
systemPrompt?: string;
|
|
@@ -544,6 +568,10 @@ export interface LabsToolListResponse {
|
|
|
544
568
|
}
|
|
545
569
|
export interface LabsVoiceListOptions {
|
|
546
570
|
provider?: string;
|
|
571
|
+
search?: string;
|
|
572
|
+
language?: string;
|
|
573
|
+
cursor?: number;
|
|
574
|
+
limit?: number;
|
|
547
575
|
}
|
|
548
576
|
export interface LabsVoiceListResponse {
|
|
549
577
|
voices: Array<Record<string, unknown>>;
|
|
@@ -552,6 +580,14 @@ export interface LabsVoiceListResponse {
|
|
|
552
580
|
provider_accounts?: Record<string, unknown>;
|
|
553
581
|
errors?: Record<string, string>;
|
|
554
582
|
}
|
|
583
|
+
export interface LabsRuntimeResponse {
|
|
584
|
+
account_id: string;
|
|
585
|
+
provider: "ultravox" | string;
|
|
586
|
+
managed: boolean;
|
|
587
|
+
byok_connected: boolean;
|
|
588
|
+
base_url?: string;
|
|
589
|
+
updated_at?: string;
|
|
590
|
+
}
|
|
555
591
|
export interface LabsCallListOptions {
|
|
556
592
|
agencyId?: string;
|
|
557
593
|
agentKey?: string;
|
|
@@ -669,6 +705,8 @@ export interface LabsPhoneNumberProvisionRequest {
|
|
|
669
705
|
numberPool?: string;
|
|
670
706
|
number_pool?: string;
|
|
671
707
|
premium?: boolean;
|
|
708
|
+
billingCheckoutSessionId?: string;
|
|
709
|
+
billing_checkout_session_id?: string;
|
|
672
710
|
style?: LabsAgentStyle;
|
|
673
711
|
agentStyle?: LabsAgentStyle;
|
|
674
712
|
agent_style?: LabsAgentStyle;
|
|
@@ -721,7 +759,7 @@ export interface CreateLabsAgentWithNumberRequest extends CreateLabsAgentRequest
|
|
|
721
759
|
number?: LabsPhoneNumberBuyAndAssignRequest;
|
|
722
760
|
}
|
|
723
761
|
export interface CreateLabsAgentWithNumberResponse extends CreateLabsAgentResponse {
|
|
724
|
-
number?: LabsPhoneNumberProvisionResponse;
|
|
762
|
+
number?: LabsPhoneNumberProvisionResponse | LabsBillingCheckoutResponse;
|
|
725
763
|
}
|
|
726
764
|
export interface LabsAgentResponse {
|
|
727
765
|
id?: string;
|
|
@@ -745,6 +783,7 @@ export interface CreateLabsAgentResponse {
|
|
|
745
783
|
snippet?: string;
|
|
746
784
|
[extra: string]: unknown;
|
|
747
785
|
};
|
|
786
|
+
call_plan?: LabsCallPlan;
|
|
748
787
|
[extra: string]: unknown;
|
|
749
788
|
}
|
|
750
789
|
export interface ListLabsAgentsResponse {
|
|
@@ -1029,6 +1068,13 @@ export declare class SupafoneLabs {
|
|
|
1029
1068
|
readonly optimizer: OptimizerNamespace;
|
|
1030
1069
|
readonly campaigns: CampaignsNamespace;
|
|
1031
1070
|
constructor(opts: SupafoneLabsOptions);
|
|
1071
|
+
/** Build a complete hosted plan with the same Supafone key used to create agents. */
|
|
1072
|
+
generateCallStages(input: CreateLabsAgentRequest & {
|
|
1073
|
+
description?: string;
|
|
1074
|
+
}): Promise<LabsCallPlan>;
|
|
1075
|
+
generate_call_stages(input: CreateLabsAgentRequest & {
|
|
1076
|
+
description?: string;
|
|
1077
|
+
}): Promise<LabsCallPlan>;
|
|
1032
1078
|
/** True once login() (or a passed sessionToken) is in effect. */
|
|
1033
1079
|
get isLoggedIn(): boolean;
|
|
1034
1080
|
/**
|
|
@@ -1069,6 +1115,18 @@ export declare class SupafoneLabs {
|
|
|
1069
1115
|
agentId: string;
|
|
1070
1116
|
toNumber: string;
|
|
1071
1117
|
}): Promise<PlaceCallResult>;
|
|
1118
|
+
/**
|
|
1119
|
+
* Start a browser WebRTC session for an owned voice agent. No phone number or
|
|
1120
|
+
* PSTN leg is created. Join browser_session.join_url with the provider's
|
|
1121
|
+
* browser client (currently Ultravox).
|
|
1122
|
+
*/
|
|
1123
|
+
startWebRtcCall(opts: {
|
|
1124
|
+
agentId: string;
|
|
1125
|
+
}): Promise<WebRtcCallResult>;
|
|
1126
|
+
/** Alias for startWebRtcCall(), named for browser-oriented applications. */
|
|
1127
|
+
startBrowserCall(opts: {
|
|
1128
|
+
agentId: string;
|
|
1129
|
+
}): Promise<WebRtcCallResult>;
|
|
1072
1130
|
/** The account's voice agents — pick an agent id for campaigns/calls. */
|
|
1073
1131
|
listVoiceAgents(): Promise<{
|
|
1074
1132
|
agents: Record<string, unknown>[];
|
|
@@ -1190,6 +1248,33 @@ export interface PlaceCallResult {
|
|
|
1190
1248
|
call_sid?: string | null;
|
|
1191
1249
|
provider?: string;
|
|
1192
1250
|
}
|
|
1251
|
+
export interface BrowserVoiceSession {
|
|
1252
|
+
version: string;
|
|
1253
|
+
available: boolean;
|
|
1254
|
+
provider: string;
|
|
1255
|
+
transport: string;
|
|
1256
|
+
join_url: string | null;
|
|
1257
|
+
features: {
|
|
1258
|
+
microphone: boolean;
|
|
1259
|
+
speaker_audio: boolean;
|
|
1260
|
+
live_transcripts: boolean;
|
|
1261
|
+
};
|
|
1262
|
+
}
|
|
1263
|
+
export interface WebRtcCallResult {
|
|
1264
|
+
success: boolean;
|
|
1265
|
+
simulated?: boolean;
|
|
1266
|
+
call_id?: string | null;
|
|
1267
|
+
call_record_id?: string | null;
|
|
1268
|
+
join_url?: string | null;
|
|
1269
|
+
max_duration_seconds?: number;
|
|
1270
|
+
free_calls_remaining?: number;
|
|
1271
|
+
browser_session: BrowserVoiceSession;
|
|
1272
|
+
test_capabilities?: {
|
|
1273
|
+
browser_voice: boolean;
|
|
1274
|
+
universal_phone_grade: boolean;
|
|
1275
|
+
phone_grade_url: string;
|
|
1276
|
+
};
|
|
1277
|
+
}
|
|
1193
1278
|
export interface CampaignRecipientInput {
|
|
1194
1279
|
name?: string;
|
|
1195
1280
|
phone?: string;
|
|
@@ -1420,9 +1505,11 @@ declare class CampaignsNamespace {
|
|
|
1420
1505
|
declare class LabsNamespace {
|
|
1421
1506
|
private sm;
|
|
1422
1507
|
readonly agents: LabsAgentsNamespace;
|
|
1508
|
+
readonly billing: LabsBillingNamespace;
|
|
1423
1509
|
readonly presets: LabsPresetsNamespace;
|
|
1424
1510
|
readonly tools: LabsToolsNamespace;
|
|
1425
1511
|
readonly voices: LabsVoicesNamespace;
|
|
1512
|
+
readonly runtime: LabsRuntimeNamespace;
|
|
1426
1513
|
readonly phoneNumbers: LabsPhoneNumbersNamespace;
|
|
1427
1514
|
readonly telephony: LabsTelephonyNamespace;
|
|
1428
1515
|
readonly calls: LabsCallsNamespace;
|
|
@@ -1432,11 +1519,57 @@ declare class LabsNamespace {
|
|
|
1432
1519
|
/** Discover the Supafone convenience layer over Ultravox. */
|
|
1433
1520
|
capabilities(): Promise<LabsCapabilitiesResponse>;
|
|
1434
1521
|
}
|
|
1522
|
+
export type LabsBillingCheckoutKind = "plan" | "credits" | "number_addon";
|
|
1523
|
+
export interface LabsBillingCheckoutInput {
|
|
1524
|
+
kind?: LabsBillingCheckoutKind;
|
|
1525
|
+
planKey?: "developer" | "growth" | "scale" | string;
|
|
1526
|
+
plan_key?: string;
|
|
1527
|
+
numberStrategy?: "dedicated" | "premium" | string;
|
|
1528
|
+
number_strategy?: string;
|
|
1529
|
+
phoneNumber?: string;
|
|
1530
|
+
phone_number?: string;
|
|
1531
|
+
quantity?: number;
|
|
1532
|
+
successUrl?: string;
|
|
1533
|
+
success_url?: string;
|
|
1534
|
+
cancelUrl?: string;
|
|
1535
|
+
cancel_url?: string;
|
|
1536
|
+
}
|
|
1537
|
+
export interface LabsBillingCheckoutResponse {
|
|
1538
|
+
status: "requires_payment" | "pending" | "paid" | string;
|
|
1539
|
+
checkout_session_id: string;
|
|
1540
|
+
checkout_url?: string;
|
|
1541
|
+
kind: LabsBillingCheckoutKind | string;
|
|
1542
|
+
plan_key?: string | null;
|
|
1543
|
+
number_strategy?: string | null;
|
|
1544
|
+
phone_number?: string | null;
|
|
1545
|
+
stripe_subscription_id?: string | null;
|
|
1546
|
+
ready_to_provision?: boolean;
|
|
1547
|
+
next_step?: string;
|
|
1548
|
+
}
|
|
1549
|
+
declare class LabsBillingNamespace {
|
|
1550
|
+
private sm;
|
|
1551
|
+
constructor(sm: SupafoneLabs);
|
|
1552
|
+
/** Start hosted Stripe Checkout. MCP callers should render checkout_url as a link. */
|
|
1553
|
+
checkout(input?: LabsBillingCheckoutInput): Promise<LabsBillingCheckoutResponse>;
|
|
1554
|
+
status(checkoutSessionId: string): Promise<LabsBillingCheckoutResponse>;
|
|
1555
|
+
portal(): Promise<{
|
|
1556
|
+
url: string;
|
|
1557
|
+
}>;
|
|
1558
|
+
createCheckout(input?: LabsBillingCheckoutInput): Promise<LabsBillingCheckoutResponse>;
|
|
1559
|
+
getCheckout(checkoutSessionId: string): Promise<LabsBillingCheckoutResponse>;
|
|
1560
|
+
}
|
|
1435
1561
|
declare class LabsAgentsNamespace {
|
|
1436
1562
|
private sm;
|
|
1437
1563
|
constructor(sm: SupafoneLabs);
|
|
1438
1564
|
/** Spawn a durable hosted Supafone agent backed by Ultravox and Supafone-managed providers. */
|
|
1439
1565
|
create(input: CreateLabsAgentRequest): Promise<CreateLabsAgentResponse>;
|
|
1566
|
+
/** Preview the exact validated call-plan contract the Supafone runtime executes. */
|
|
1567
|
+
plan(input: CreateLabsAgentRequest & {
|
|
1568
|
+
description?: string;
|
|
1569
|
+
}): Promise<LabsCallPlan>;
|
|
1570
|
+
generateCallStages(input: CreateLabsAgentRequest & {
|
|
1571
|
+
description?: string;
|
|
1572
|
+
}): Promise<LabsCallPlan>;
|
|
1440
1573
|
/** Default the agent onto the client's Voice Watcher setting (live supervision
|
|
1441
1574
|
* + QA + scoring) unless the caller set it explicitly; mirror into
|
|
1442
1575
|
* labs.voice_watcher when a labs block exists. Never overwrites a caller value. */
|
|
@@ -1480,6 +1613,25 @@ declare class LabsVoicesNamespace {
|
|
|
1480
1613
|
/** Supafone-managed Cartesia voices. Other TTS engines remain explicit BYOK choices. */
|
|
1481
1614
|
list(opts?: LabsVoiceListOptions): Promise<LabsVoiceListResponse>;
|
|
1482
1615
|
}
|
|
1616
|
+
declare class LabsRuntimeNamespace {
|
|
1617
|
+
private sm;
|
|
1618
|
+
constructor(sm: SupafoneLabs);
|
|
1619
|
+
get(opts?: {
|
|
1620
|
+
agencyId?: string;
|
|
1621
|
+
agency_id?: string;
|
|
1622
|
+
}): Promise<LabsRuntimeResponse>;
|
|
1623
|
+
configure(input: {
|
|
1624
|
+
agencyId?: string;
|
|
1625
|
+
agency_id?: string;
|
|
1626
|
+
provider?: "ultravox" | string;
|
|
1627
|
+
credentials?: {
|
|
1628
|
+
apiKey?: string;
|
|
1629
|
+
api_key?: string;
|
|
1630
|
+
baseUrl?: string;
|
|
1631
|
+
base_url?: string;
|
|
1632
|
+
};
|
|
1633
|
+
}): Promise<LabsRuntimeResponse>;
|
|
1634
|
+
}
|
|
1483
1635
|
declare class LabsCallsNamespace {
|
|
1484
1636
|
private sm;
|
|
1485
1637
|
constructor(sm: SupafoneLabs);
|
|
@@ -1515,8 +1667,11 @@ declare class LabsPhoneNumbersNamespace {
|
|
|
1515
1667
|
list(opts?: LabsPhoneNumberListOptions): Promise<LabsPhoneNumberListResponse>;
|
|
1516
1668
|
/** Search Supafone-managed inventory. This uses Supafone's master telephony account. */
|
|
1517
1669
|
search(opts?: LabsPhoneNumberSearchOptions): Promise<LabsPhoneNumberSearchResponse>;
|
|
1518
|
-
/**
|
|
1519
|
-
|
|
1670
|
+
/**
|
|
1671
|
+
* Buy a managed number. Paid strategies return a hosted Checkout link first;
|
|
1672
|
+
* call again with billingCheckoutSessionId after Checkout reports paid.
|
|
1673
|
+
*/
|
|
1674
|
+
buy(input: LabsPhoneNumberProvisionRequest): Promise<LabsPhoneNumberProvisionResponse | LabsBillingCheckoutResponse>;
|
|
1520
1675
|
/** Attach an existing Supafone number to an inbound or outbound agent. */
|
|
1521
1676
|
assign(numberId: string, input?: LabsPhoneNumberAssignRequest): Promise<LabsPhoneNumberAssignResponse>;
|
|
1522
1677
|
/** Unassign a number from an agent but keep it reserved on the account. */
|
|
@@ -1531,7 +1686,7 @@ declare class LabsPhoneNumbersNamespace {
|
|
|
1531
1686
|
* Search if needed, buy the first matching Supafone-managed number, and assign
|
|
1532
1687
|
* it to the supplied agent. This is the zero-Twilio-account happy path.
|
|
1533
1688
|
*/
|
|
1534
|
-
buyAndAssign(input: LabsPhoneNumberBuyAndAssignRequest): Promise<LabsPhoneNumberProvisionResponse>;
|
|
1689
|
+
buyAndAssign(input: LabsPhoneNumberBuyAndAssignRequest): Promise<LabsPhoneNumberProvisionResponse | LabsBillingCheckoutResponse>;
|
|
1535
1690
|
}
|
|
1536
1691
|
declare class LabsTelephonyNamespace {
|
|
1537
1692
|
private sm;
|
package/dist/cjs/index.js
CHANGED
|
@@ -94,6 +94,13 @@ class SupafoneLabs {
|
|
|
94
94
|
this.optimizer = new OptimizerNamespace(this);
|
|
95
95
|
this.campaigns = new CampaignsNamespace(this);
|
|
96
96
|
}
|
|
97
|
+
/** Build a complete hosted plan with the same Supafone key used to create agents. */
|
|
98
|
+
generateCallStages(input) {
|
|
99
|
+
return this.labs.agents.plan(input);
|
|
100
|
+
}
|
|
101
|
+
generate_call_stages(input) {
|
|
102
|
+
return this.generateCallStages(input);
|
|
103
|
+
}
|
|
97
104
|
/** True once login() (or a passed sessionToken) is in effect. */
|
|
98
105
|
get isLoggedIn() {
|
|
99
106
|
return !!this.sessionToken;
|
|
@@ -268,6 +275,21 @@ class SupafoneLabs {
|
|
|
268
275
|
async placeCall(opts) {
|
|
269
276
|
return this.callFromAgent(opts);
|
|
270
277
|
}
|
|
278
|
+
/**
|
|
279
|
+
* Start a browser WebRTC session for an owned voice agent. No phone number or
|
|
280
|
+
* PSTN leg is created. Join browser_session.join_url with the provider's
|
|
281
|
+
* browser client (currently Ultravox).
|
|
282
|
+
*/
|
|
283
|
+
async startWebRtcCall(opts) {
|
|
284
|
+
if (!opts?.agentId) {
|
|
285
|
+
throw new SupafoneLabsError("agentId is required (see listVoiceAgents())");
|
|
286
|
+
}
|
|
287
|
+
return this.requestAccountApi("POST", `/api/v1/agents/${encodeURIComponent(opts.agentId)}/test-call`);
|
|
288
|
+
}
|
|
289
|
+
/** Alias for startWebRtcCall(), named for browser-oriented applications. */
|
|
290
|
+
async startBrowserCall(opts) {
|
|
291
|
+
return this.startWebRtcCall(opts);
|
|
292
|
+
}
|
|
271
293
|
/** The account's voice agents — pick an agent id for campaigns/calls. */
|
|
272
294
|
async listVoiceAgents() {
|
|
273
295
|
return this.requestAccountApi("GET", "/api/v1/agents");
|
|
@@ -758,9 +780,11 @@ class CampaignsNamespace {
|
|
|
758
780
|
class LabsNamespace {
|
|
759
781
|
sm;
|
|
760
782
|
agents;
|
|
783
|
+
billing;
|
|
761
784
|
presets;
|
|
762
785
|
tools;
|
|
763
786
|
voices;
|
|
787
|
+
runtime;
|
|
764
788
|
phoneNumbers;
|
|
765
789
|
telephony;
|
|
766
790
|
calls;
|
|
@@ -769,9 +793,11 @@ class LabsNamespace {
|
|
|
769
793
|
constructor(sm) {
|
|
770
794
|
this.sm = sm;
|
|
771
795
|
this.agents = new LabsAgentsNamespace(sm);
|
|
796
|
+
this.billing = new LabsBillingNamespace(sm);
|
|
772
797
|
this.presets = new LabsPresetsNamespace(sm);
|
|
773
798
|
this.tools = new LabsToolsNamespace(sm);
|
|
774
799
|
this.voices = new LabsVoicesNamespace(sm);
|
|
800
|
+
this.runtime = new LabsRuntimeNamespace(sm);
|
|
775
801
|
this.phoneNumbers = new LabsPhoneNumbersNamespace(sm);
|
|
776
802
|
this.telephony = new LabsTelephonyNamespace(sm);
|
|
777
803
|
this.calls = new LabsCallsNamespace(sm);
|
|
@@ -783,6 +809,38 @@ class LabsNamespace {
|
|
|
783
809
|
return this.sm.requestSupafoneApi("GET", "/api/v1/labs/capabilities");
|
|
784
810
|
}
|
|
785
811
|
}
|
|
812
|
+
class LabsBillingNamespace {
|
|
813
|
+
sm;
|
|
814
|
+
constructor(sm) {
|
|
815
|
+
this.sm = sm;
|
|
816
|
+
}
|
|
817
|
+
/** Start hosted Stripe Checkout. MCP callers should render checkout_url as a link. */
|
|
818
|
+
checkout(input = {}) {
|
|
819
|
+
return this.sm.request("POST", "/v1/billing/checkout", compact({
|
|
820
|
+
kind: input.kind ?? "plan",
|
|
821
|
+
plan_key: input.plan_key ?? input.planKey,
|
|
822
|
+
number_strategy: input.number_strategy ?? input.numberStrategy,
|
|
823
|
+
phone_number: input.phone_number ?? input.phoneNumber,
|
|
824
|
+
quantity: input.quantity,
|
|
825
|
+
success_url: input.success_url ?? input.successUrl,
|
|
826
|
+
cancel_url: input.cancel_url ?? input.cancelUrl,
|
|
827
|
+
}));
|
|
828
|
+
}
|
|
829
|
+
status(checkoutSessionId) {
|
|
830
|
+
if (!checkoutSessionId?.trim())
|
|
831
|
+
throw new SupafoneLabsError("checkoutSessionId is required");
|
|
832
|
+
return this.sm.request("GET", `/v1/billing/checkout/${encodeURIComponent(checkoutSessionId)}`);
|
|
833
|
+
}
|
|
834
|
+
portal() {
|
|
835
|
+
return this.sm.request("POST", "/v1/billing/portal", {});
|
|
836
|
+
}
|
|
837
|
+
createCheckout(input = {}) {
|
|
838
|
+
return this.checkout(input);
|
|
839
|
+
}
|
|
840
|
+
getCheckout(checkoutSessionId) {
|
|
841
|
+
return this.status(checkoutSessionId);
|
|
842
|
+
}
|
|
843
|
+
}
|
|
786
844
|
class LabsAgentsNamespace {
|
|
787
845
|
sm;
|
|
788
846
|
constructor(sm) {
|
|
@@ -792,6 +850,13 @@ class LabsAgentsNamespace {
|
|
|
792
850
|
create(input) {
|
|
793
851
|
return this.sm.requestSupafoneApi("POST", "/api/v1/labs/agents", labsAgentPayload(this.withVoiceWatcher(input)));
|
|
794
852
|
}
|
|
853
|
+
/** Preview the exact validated call-plan contract the Supafone runtime executes. */
|
|
854
|
+
plan(input) {
|
|
855
|
+
return this.sm.requestSupafoneApi("POST", "/api/v1/labs/agent-plans", stagePlanPayload(input));
|
|
856
|
+
}
|
|
857
|
+
generateCallStages(input) {
|
|
858
|
+
return this.plan(input);
|
|
859
|
+
}
|
|
795
860
|
/** Default the agent onto the client's Voice Watcher setting (live supervision
|
|
796
861
|
* + QA + scoring) unless the caller set it explicitly; mirror into
|
|
797
862
|
* labs.voice_watcher when a labs block exists. Never overwrites a caller value. */
|
|
@@ -929,10 +994,43 @@ class LabsVoicesNamespace {
|
|
|
929
994
|
const q = new URLSearchParams();
|
|
930
995
|
if (opts.provider)
|
|
931
996
|
q.set("provider", opts.provider);
|
|
997
|
+
if (opts.search)
|
|
998
|
+
q.set("search", opts.search);
|
|
999
|
+
if (opts.language)
|
|
1000
|
+
q.set("language", opts.language);
|
|
1001
|
+
if (opts.cursor !== undefined)
|
|
1002
|
+
q.set("cursor", String(opts.cursor));
|
|
1003
|
+
if (opts.limit !== undefined)
|
|
1004
|
+
q.set("limit", String(opts.limit));
|
|
932
1005
|
const suffix = q.toString() ? `?${q}` : "";
|
|
933
1006
|
return this.sm.requestSupafoneApi("GET", `/api/v1/labs/voices${suffix}`);
|
|
934
1007
|
}
|
|
935
1008
|
}
|
|
1009
|
+
class LabsRuntimeNamespace {
|
|
1010
|
+
sm;
|
|
1011
|
+
constructor(sm) {
|
|
1012
|
+
this.sm = sm;
|
|
1013
|
+
}
|
|
1014
|
+
get(opts = {}) {
|
|
1015
|
+
const q = new URLSearchParams();
|
|
1016
|
+
const agencyId = opts.agency_id ?? opts.agencyId;
|
|
1017
|
+
if (agencyId)
|
|
1018
|
+
q.set("agency_id", agencyId);
|
|
1019
|
+
const suffix = q.toString() ? `?${q}` : "";
|
|
1020
|
+
return this.sm.requestSupafoneApi("GET", `/api/v1/labs/runtime${suffix}`);
|
|
1021
|
+
}
|
|
1022
|
+
configure(input) {
|
|
1023
|
+
const credentials = input.credentials ?? {};
|
|
1024
|
+
return this.sm.requestSupafoneApi("PUT", "/api/v1/labs/runtime", compact({
|
|
1025
|
+
agency_id: input.agency_id ?? input.agencyId,
|
|
1026
|
+
provider: input.provider ?? "ultravox",
|
|
1027
|
+
credentials: compact({
|
|
1028
|
+
api_key: credentials.api_key ?? credentials.apiKey,
|
|
1029
|
+
base_url: credentials.base_url ?? credentials.baseUrl,
|
|
1030
|
+
}),
|
|
1031
|
+
}));
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
936
1034
|
class LabsCallsNamespace {
|
|
937
1035
|
sm;
|
|
938
1036
|
constructor(sm) {
|
|
@@ -1021,10 +1119,27 @@ class LabsPhoneNumbersNamespace {
|
|
|
1021
1119
|
search(opts = {}) {
|
|
1022
1120
|
return this.sm.requestSupafoneApi("POST", "/api/v1/labs/phone-numbers/search", phoneNumberSearchPayload(opts));
|
|
1023
1121
|
}
|
|
1024
|
-
/**
|
|
1122
|
+
/**
|
|
1123
|
+
* Buy a managed number. Paid strategies return a hosted Checkout link first;
|
|
1124
|
+
* call again with billingCheckoutSessionId after Checkout reports paid.
|
|
1125
|
+
*/
|
|
1025
1126
|
buy(input) {
|
|
1127
|
+
const strategy = input.number_strategy ?? input.numberStrategy ?? (input.premium ? "premium" : "default_pool");
|
|
1128
|
+
const checkoutSessionId = input.billing_checkout_session_id ?? input.billingCheckoutSessionId;
|
|
1129
|
+
if ((strategy === "dedicated" || strategy === "premium") && !checkoutSessionId) {
|
|
1130
|
+
const phoneNumber = input.phone_number ?? input.phoneNumber;
|
|
1131
|
+
if (!phoneNumber) {
|
|
1132
|
+
return Promise.reject(new SupafoneLabsError("phoneNumber is required before starting number Checkout"));
|
|
1133
|
+
}
|
|
1134
|
+
return this.sm.labs.billing.checkout({
|
|
1135
|
+
kind: "number_addon",
|
|
1136
|
+
numberStrategy: strategy,
|
|
1137
|
+
phoneNumber,
|
|
1138
|
+
});
|
|
1139
|
+
}
|
|
1026
1140
|
return this.sm.requestSupafoneApi("POST", "/api/v1/labs/phone-numbers", phoneNumberProvisionPayload({
|
|
1027
1141
|
...input,
|
|
1142
|
+
numberStrategy: strategy,
|
|
1028
1143
|
telephony: input.telephony ?? { mode: "supafone_managed", provider: "supafone" },
|
|
1029
1144
|
}));
|
|
1030
1145
|
}
|
|
@@ -1247,6 +1362,7 @@ function labsAgentPayload(input) {
|
|
|
1247
1362
|
agent_type: input.agent_type ?? input.agentType,
|
|
1248
1363
|
style: input.agent_style ?? input.agentStyle ?? input.style,
|
|
1249
1364
|
name: input.name,
|
|
1365
|
+
description: input.description,
|
|
1250
1366
|
assistant_name: input.assistant_name ?? input.assistantName,
|
|
1251
1367
|
business_name: input.business_name ?? input.businessName,
|
|
1252
1368
|
industry: input.industry,
|
|
@@ -1259,6 +1375,9 @@ function labsAgentPayload(input) {
|
|
|
1259
1375
|
preset_key: input.preset_key ?? input.presetKey,
|
|
1260
1376
|
runtime_mode: input.runtime_mode ?? input.runtimeMode,
|
|
1261
1377
|
call_stages: callStagesPayload(input),
|
|
1378
|
+
stage_generation: input.stage_generation ?? input.stageGeneration,
|
|
1379
|
+
stage_count: input.stage_count ?? input.stageCount,
|
|
1380
|
+
stage_detail: input.stage_detail ?? input.stageDetail,
|
|
1262
1381
|
goal: input.goal,
|
|
1263
1382
|
greeting: input.greeting,
|
|
1264
1383
|
system_prompt: input.system_prompt ?? input.systemPrompt,
|
|
@@ -1360,6 +1479,7 @@ function phoneNumberProvisionPayload(input) {
|
|
|
1360
1479
|
number_strategy: input.number_strategy ?? input.numberStrategy,
|
|
1361
1480
|
number_pool: input.number_pool ?? input.numberPool,
|
|
1362
1481
|
premium: input.premium,
|
|
1482
|
+
billing_checkout_session_id: input.billing_checkout_session_id ?? input.billingCheckoutSessionId,
|
|
1363
1483
|
style: input.agent_style ?? input.agentStyle ?? input.style,
|
|
1364
1484
|
direction: input.direction,
|
|
1365
1485
|
telephony: input.telephony ? telephonyPayload(input.telephony) : undefined,
|
|
@@ -1397,8 +1517,31 @@ function callStagesPayload(input) {
|
|
|
1397
1517
|
if (Array.isArray(explicit))
|
|
1398
1518
|
return explicit.map(callStagePayload);
|
|
1399
1519
|
if (explicit === false || auto === false)
|
|
1400
|
-
return
|
|
1401
|
-
|
|
1520
|
+
return false;
|
|
1521
|
+
if (explicit === "oracle" || explicit === "template" || explicit === "off")
|
|
1522
|
+
return explicit;
|
|
1523
|
+
// Omitted means the private Supafone API generates and compiles the plan.
|
|
1524
|
+
return undefined;
|
|
1525
|
+
}
|
|
1526
|
+
function stagePlanPayload(input) {
|
|
1527
|
+
return compact({
|
|
1528
|
+
agency_id: input.agency_id ?? input.agencyId,
|
|
1529
|
+
description: input.description,
|
|
1530
|
+
name: input.name,
|
|
1531
|
+
assistant_name: input.assistant_name ?? input.assistantName,
|
|
1532
|
+
business_name: input.business_name ?? input.businessName,
|
|
1533
|
+
industry: input.industry,
|
|
1534
|
+
direction: input.direction ?? input.agent_style ?? input.agentStyle ?? input.style,
|
|
1535
|
+
goal: input.goal,
|
|
1536
|
+
system_prompt: input.system_prompt ?? input.systemPrompt,
|
|
1537
|
+
tools: input.tools ? toolsPayload(input.tools) : undefined,
|
|
1538
|
+
call_stages: Array.isArray(input.call_stages ?? input.callStages ?? input.stages)
|
|
1539
|
+
? (input.call_stages ?? input.callStages ?? input.stages)
|
|
1540
|
+
: undefined,
|
|
1541
|
+
stage_generation: input.stage_generation ?? input.stageGeneration,
|
|
1542
|
+
stage_count: input.stage_count ?? input.stageCount,
|
|
1543
|
+
stage_detail: input.stage_detail ?? input.stageDetail,
|
|
1544
|
+
});
|
|
1402
1545
|
}
|
|
1403
1546
|
function callStagePayload(input) {
|
|
1404
1547
|
return compact({
|
|
@@ -1408,10 +1551,14 @@ function callStagePayload(input) {
|
|
|
1408
1551
|
instructions: input.instructions,
|
|
1409
1552
|
exit_criteria: input.exit_criteria ?? input.exitCriteria,
|
|
1410
1553
|
tools: input.tools,
|
|
1554
|
+
temperature: input.temperature,
|
|
1555
|
+
next_stages: input.next_stages ?? input.nextStages,
|
|
1411
1556
|
metadata: input.metadata,
|
|
1412
1557
|
});
|
|
1413
1558
|
}
|
|
1414
1559
|
function generateCallStages(input) {
|
|
1560
|
+
// Offline compatibility template. New code should use
|
|
1561
|
+
// client.generateCallStages(...) for the hosted, executable plan.
|
|
1415
1562
|
const direction = String(input.direction ?? input.agent_style ?? input.agentStyle ?? input.style ?? "inbound").toLowerCase();
|
|
1416
1563
|
const haystack = [
|
|
1417
1564
|
input.name,
|