@voicelayer/sdk 0.6.0 → 0.6.2
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/dist/brain/index.d.ts +2 -2
- package/dist/brain/index.js +155 -162
- package/dist/index.d.ts +707 -257
- package/dist/index.js +1251 -454
- package/dist/runtime/text-session.d.ts +1 -1
- package/dist/runtime/text-session.js +256 -176
- package/dist/{text-session-CoyEcdmg.d.ts → text-session-B-T33y5P.d.ts} +116 -110
- package/package.json +5 -5
package/dist/brain/index.d.ts
CHANGED
|
@@ -81,14 +81,14 @@ declare const ConnectorUpFrame: z.ZodDiscriminatedUnion<"kind", [z.ZodObject<{
|
|
|
81
81
|
code: z.ZodEnum<["upstream_timeout", "upstream_error", "bad_response", "normalize_failed", "unreachable"]>;
|
|
82
82
|
message: z.ZodString;
|
|
83
83
|
}, "strip", z.ZodTypeAny, {
|
|
84
|
-
kind: "brain.error";
|
|
85
84
|
code: "upstream_timeout" | "upstream_error" | "bad_response" | "normalize_failed" | "unreachable";
|
|
86
85
|
message: string;
|
|
86
|
+
kind: "brain.error";
|
|
87
87
|
streamId: string;
|
|
88
88
|
}, {
|
|
89
|
-
kind: "brain.error";
|
|
90
89
|
code: "upstream_timeout" | "upstream_error" | "bad_response" | "normalize_failed" | "unreachable";
|
|
91
90
|
message: string;
|
|
91
|
+
kind: "brain.error";
|
|
92
92
|
streamId: string;
|
|
93
93
|
}>]>;
|
|
94
94
|
type ConnectorUpFrame = z.infer<typeof ConnectorUpFrame>;
|
package/dist/brain/index.js
CHANGED
|
@@ -883,7 +883,9 @@ var CallEventKind = z.enum([
|
|
|
883
883
|
"dtmf.sent",
|
|
884
884
|
// A host's runtime intervention (burn-down G-6): call_say / call_send_guidance / call_inject_context / call_instruct,
|
|
885
885
|
// with masked args and the API key — written by the API only, never through the worker's /events endpoint.
|
|
886
|
-
"mcp.interaction"
|
|
886
|
+
"mcp.interaction",
|
|
887
|
+
// One per caller turn the agent answered (burn-down G-44): where that turn's wait went — see TurnLatencyPayload.
|
|
888
|
+
"turn.latency"
|
|
887
889
|
]);
|
|
888
890
|
var OP_CALL_EVENT_KIND = /^(tool|handoff|lookup|record|notify|engine)\.[a-z0-9_]{1,48}(\.[a-z0-9_]{1,48})?$/;
|
|
889
891
|
var OpCallEventKind = z.string().regex(OP_CALL_EVENT_KIND);
|
|
@@ -910,6 +912,17 @@ z.object({
|
|
|
910
912
|
code: z.number().int().min(0).max(15),
|
|
911
913
|
participantId: z.string().optional()
|
|
912
914
|
});
|
|
915
|
+
var LatencyMs = z.number().int().min(0).max(6e5).nullable();
|
|
916
|
+
z.object({
|
|
917
|
+
turn: z.number().int().min(1),
|
|
918
|
+
atMs: z.number().int().min(0),
|
|
919
|
+
endpointingMs: LatencyMs,
|
|
920
|
+
sttMs: LatencyMs,
|
|
921
|
+
llmMs: LatencyMs,
|
|
922
|
+
ttsMs: LatencyMs,
|
|
923
|
+
endToEndMs: LatencyMs,
|
|
924
|
+
realtime: z.boolean().optional()
|
|
925
|
+
});
|
|
913
926
|
z.object({
|
|
914
927
|
totalUsd: z.string(),
|
|
915
928
|
breakdown: z.object({
|
|
@@ -1019,6 +1032,58 @@ z.union([
|
|
|
1019
1032
|
error: z.object({ code: TextTurnErrorCode, detail: z.string().max(500).optional() })
|
|
1020
1033
|
})
|
|
1021
1034
|
]);
|
|
1035
|
+
var PLATFORM_MAX_CALL_MINUTES = 240;
|
|
1036
|
+
var Message = z.string().trim().min(1).max(300);
|
|
1037
|
+
var CallerRateLimit = z.object({
|
|
1038
|
+
enabled: z.boolean().optional(),
|
|
1039
|
+
perTenMinutes: z.number().int().min(1).max(100).optional(),
|
|
1040
|
+
perDay: z.number().int().min(1).max(1e3).optional(),
|
|
1041
|
+
withheldPerTenMinutes: z.number().int().min(1).max(100).optional(),
|
|
1042
|
+
withheldPerDay: z.number().int().min(1).max(1e3).optional()
|
|
1043
|
+
});
|
|
1044
|
+
var CallLimits = z.object({
|
|
1045
|
+
/** The agent's own ceiling in minutes; clamped to the workspace's plan ceiling. Absent ⇒ DEFAULT_MAX_CALL_MINUTES. */
|
|
1046
|
+
maxDurationMinutes: z.number().int().min(1).max(PLATFORM_MAX_CALL_MINUTES).optional(),
|
|
1047
|
+
/** Seconds before the limit the wrap-up line is spoken; 0 ⇒ no warning. */
|
|
1048
|
+
wrapUpWarningSeconds: z.number().int().min(0).max(300).optional(),
|
|
1049
|
+
wrapUpMessage: Message.optional(),
|
|
1050
|
+
goodbyeMessage: Message.optional(),
|
|
1051
|
+
callerRateLimit: CallerRateLimit.optional(),
|
|
1052
|
+
rateLimitedMessage: Message.optional()
|
|
1053
|
+
});
|
|
1054
|
+
var CallerChannel = z.enum(["phone", "web"]);
|
|
1055
|
+
z.object({
|
|
1056
|
+
roomName: z.string().min(1).max(256),
|
|
1057
|
+
/** From the dispatch metadata: lets the API admit (gate) a room whose call row doesn't exist yet. */
|
|
1058
|
+
agentId: z.string().max(128).optional(),
|
|
1059
|
+
phoneNumberId: z.string().max(128).optional(),
|
|
1060
|
+
caller: z.object({
|
|
1061
|
+
channel: CallerChannel,
|
|
1062
|
+
/** The caller's number as the carrier presented it; null / absent / not E.164 ⇒ the withheld bucket. */
|
|
1063
|
+
number: z.string().max(64).nullable().optional()
|
|
1064
|
+
})
|
|
1065
|
+
});
|
|
1066
|
+
var CallDurationLimits = z.object({
|
|
1067
|
+
/** The agent's own ceiling (already clamped to the plan), or null when it set none. */
|
|
1068
|
+
agentMaxSeconds: z.number().int().min(1).nullable(),
|
|
1069
|
+
/** The plan ceiling — the platform bound no call outlives. */
|
|
1070
|
+
ceilingSeconds: z.number().int().min(1),
|
|
1071
|
+
wrapUpWarningSeconds: z.number().int().min(0),
|
|
1072
|
+
wrapUpMessage: z.string(),
|
|
1073
|
+
goodbyeMessage: z.string()
|
|
1074
|
+
});
|
|
1075
|
+
z.discriminatedUnion("admitted", [
|
|
1076
|
+
z.object({ admitted: z.literal(true), limits: CallDurationLimits }),
|
|
1077
|
+
z.object({
|
|
1078
|
+
admitted: z.literal(false),
|
|
1079
|
+
/** 'rate_limited:caller' | 'inbound_refused:<code>' — already recorded as the call's end reason. */
|
|
1080
|
+
endReason: z.string(),
|
|
1081
|
+
/** The fixed line to speak before hanging up. */
|
|
1082
|
+
message: z.string()
|
|
1083
|
+
})
|
|
1084
|
+
]);
|
|
1085
|
+
|
|
1086
|
+
// ../contracts/src/agent-config.ts
|
|
1022
1087
|
var VoiceConfig = z.object({
|
|
1023
1088
|
// Finite, vetted list — platform-level enum.
|
|
1024
1089
|
provider: z.enum(["deepgram", "elevenlabs", "openai", "cartesia"]),
|
|
@@ -1181,6 +1246,9 @@ var AgentConfig = z.object({
|
|
|
1181
1246
|
// LLM slot through the connector instead of a first-party model. Null/absent →
|
|
1182
1247
|
// first-party pipeline (unchanged default). See docs/specs/voice-brain-connector.
|
|
1183
1248
|
brainConnectorId: z.string().uuid().nullable().optional(),
|
|
1249
|
+
// Per-agent call bounds: caller rate limit, max duration and their spoken lines (burn-down G-41, G-43). Absent ⇒
|
|
1250
|
+
// every default (call-limits.ts) — the rate limit is ON by default.
|
|
1251
|
+
callLimits: CallLimits.optional(),
|
|
1184
1252
|
// Provenance: 'sdk' (hand-coded defineAgent worker), 'flow' (canvas deploy),
|
|
1185
1253
|
// 'playbook' (agent-mode deploy), or 'connector' (brain-connector agent).
|
|
1186
1254
|
// DERIVED from the linked agents row's deploy tags (flowId / playbookId /
|
|
@@ -1474,6 +1542,8 @@ z.object({
|
|
|
1474
1542
|
consultation: ConsultationPolicy,
|
|
1475
1543
|
tags: z.array(z.string().max(64)).max(32).nullable(),
|
|
1476
1544
|
brainConnectorId: z.string().uuid().nullable(),
|
|
1545
|
+
// Versions published before call limits existed carry none: read as null (every default).
|
|
1546
|
+
callLimits: CallLimits.nullable().default(null),
|
|
1477
1547
|
flowVersion: z.number().int().nullable(),
|
|
1478
1548
|
processSchema: ProcessSchemaDTO.nullable()
|
|
1479
1549
|
});
|
|
@@ -1509,6 +1579,7 @@ var AgentConfigDiffField = z.enum([
|
|
|
1509
1579
|
"language",
|
|
1510
1580
|
"tools",
|
|
1511
1581
|
"brainConnectorId",
|
|
1582
|
+
"callLimits",
|
|
1512
1583
|
"consultation",
|
|
1513
1584
|
"tags",
|
|
1514
1585
|
"flowVersion",
|
|
@@ -1634,6 +1705,9 @@ var CostEstimatePerMinute = z.object({
|
|
|
1634
1705
|
var CostEstimateBilledPerMinute = z.object({
|
|
1635
1706
|
platformFee: z.number().nonnegative(),
|
|
1636
1707
|
providerPassthrough: z.number().nonnegative(),
|
|
1708
|
+
// The flat own-key fee per minute (burn-down B-26); 0 when every provider runs on the platform's keys. Optional
|
|
1709
|
+
// only for responses from an API older than the fee.
|
|
1710
|
+
ownKeyFee: z.number().nonnegative().optional(),
|
|
1637
1711
|
telephony: z.number().nonnegative(),
|
|
1638
1712
|
allIn: z.number().nonnegative()
|
|
1639
1713
|
});
|
|
@@ -1834,6 +1908,38 @@ z.object({
|
|
|
1834
1908
|
note: z.string().max(2e3).nullable().optional(),
|
|
1835
1909
|
reviewed: z.boolean().optional()
|
|
1836
1910
|
});
|
|
1911
|
+
var CAPTURED_FIELDS_MAX = 200;
|
|
1912
|
+
var CAPTURED_STRING_MAX_CHARS = 8e3;
|
|
1913
|
+
var CAPTURED_ARRAY_MAX_ITEMS = 100;
|
|
1914
|
+
var CapturedFieldValue = z.union([
|
|
1915
|
+
z.string().max(CAPTURED_STRING_MAX_CHARS),
|
|
1916
|
+
z.number().finite(),
|
|
1917
|
+
z.boolean(),
|
|
1918
|
+
z.array(z.string().max(CAPTURED_STRING_MAX_CHARS)).max(CAPTURED_ARRAY_MAX_ITEMS),
|
|
1919
|
+
z.null()
|
|
1920
|
+
]);
|
|
1921
|
+
var CapturedField = z.object({
|
|
1922
|
+
name: z.string().min(1).max(64),
|
|
1923
|
+
type: ProcessFieldType,
|
|
1924
|
+
required: z.boolean(),
|
|
1925
|
+
// false ⇒ the call never captured it; `value` is then null
|
|
1926
|
+
filled: z.boolean(),
|
|
1927
|
+
value: CapturedFieldValue
|
|
1928
|
+
});
|
|
1929
|
+
var StructuredOutputs = z.record(CapturedFieldValue);
|
|
1930
|
+
z.object({
|
|
1931
|
+
// Every declared field, in declaration order; empty when the agent declares none.
|
|
1932
|
+
fields: z.array(CapturedField).max(CAPTURED_FIELDS_MAX)
|
|
1933
|
+
}).superRefine((body, ctx) => {
|
|
1934
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1935
|
+
for (const f of body.fields) {
|
|
1936
|
+
if (seen.has(f.name)) ctx.addIssue({ code: z.ZodIssueCode.custom, message: `duplicate field ${f.name}` });
|
|
1937
|
+
seen.add(f.name);
|
|
1938
|
+
if (!f.filled && f.value !== null) ctx.addIssue({ code: z.ZodIssueCode.custom, message: `${f.name}: an unfilled field has no value` });
|
|
1939
|
+
}
|
|
1940
|
+
});
|
|
1941
|
+
|
|
1942
|
+
// ../contracts/src/call-result.ts
|
|
1837
1943
|
var TranscriptTurn = z.object({
|
|
1838
1944
|
speaker: z.enum(["caller", "agent"]),
|
|
1839
1945
|
text: z.string(),
|
|
@@ -1882,9 +1988,13 @@ z.object({
|
|
|
1882
1988
|
startedAt: z.string().datetime(),
|
|
1883
1989
|
endedAt: z.string().datetime(),
|
|
1884
1990
|
durationMs: z.number().int().min(0),
|
|
1991
|
+
// Final segments only, in call order.
|
|
1885
1992
|
transcript: z.array(TranscriptTurn),
|
|
1886
|
-
//
|
|
1887
|
-
|
|
1993
|
+
// The filled fields of the agent's process / flow, keyed by name (burn-down G-20). Absent when the agent declares no
|
|
1994
|
+
// fields, or its worker never reported them.
|
|
1995
|
+
structuredOutputs: StructuredOutputs.optional(),
|
|
1996
|
+
// Every declared field with what the call captured and whether it was filled — the same list `call.ended` carries.
|
|
1997
|
+
fields: z.array(CapturedField).optional(),
|
|
1888
1998
|
recordingUrl: z.string().url().optional(),
|
|
1889
1999
|
cost: z.object({
|
|
1890
2000
|
totalUsd: z.string(),
|
|
@@ -1911,7 +2021,18 @@ z.object({
|
|
|
1911
2021
|
// set, it is the same value `call.ended` carries; `call.ended` always has one.
|
|
1912
2022
|
direction: CallWebhookDirection.nullable()
|
|
1913
2023
|
});
|
|
2024
|
+
var CALL_ENDED_PAYLOAD_VERSION = 2;
|
|
2025
|
+
var CallEndedTranscript = z.object({
|
|
2026
|
+
// Final segments only (what was said, never an interim STT guess), in call order. Empty when `truncated`.
|
|
2027
|
+
turns: z.array(TranscriptTurn),
|
|
2028
|
+
// How many final turns the call has — the length of `turns` unless truncated.
|
|
2029
|
+
turnCount: z.number().int().min(0),
|
|
2030
|
+
truncated: z.boolean(),
|
|
2031
|
+
// Where the whole transcript is: GET /v1/calls/:callId/result (its `transcript`). Always set.
|
|
2032
|
+
fetchPath: z.string().regex(/^\/v1\/calls\/[0-9a-f-]{36}\/result$/)
|
|
2033
|
+
});
|
|
1914
2034
|
z.object({
|
|
2035
|
+
version: z.literal(CALL_ENDED_PAYLOAD_VERSION),
|
|
1915
2036
|
callId: z.string().uuid(),
|
|
1916
2037
|
durationMs: z.number().int().min(0),
|
|
1917
2038
|
endedAt: z.string().datetime(),
|
|
@@ -1922,7 +2043,20 @@ z.object({
|
|
|
1922
2043
|
toE164: Party,
|
|
1923
2044
|
direction: CallWebhookDirection,
|
|
1924
2045
|
outcome: CallWebhookOutcome,
|
|
1925
|
-
attributes: CallWebhookAttributes
|
|
2046
|
+
attributes: CallWebhookAttributes,
|
|
2047
|
+
// Every field the agent declared (its process, or a flow's slots), in declaration order, with what the call captured
|
|
2048
|
+
// and whether it was filled. Empty when the agent declares none.
|
|
2049
|
+
fields: z.array(CapturedField),
|
|
2050
|
+
// The filled fields as one object keyed by name (as GET /v1/calls/:id/result returns them). Absent when the agent
|
|
2051
|
+
// declares no fields.
|
|
2052
|
+
structuredOutputs: StructuredOutputs.optional(),
|
|
2053
|
+
transcript: CallEndedTranscript,
|
|
2054
|
+
// true: the agent's worker confirmed its last transcript segment and captured field had landed before this payload
|
|
2055
|
+
// was built. false: built without that word (a worker that crashed or runs an SDK before 0.6.2, or one that didn't
|
|
2056
|
+
// answer within the hold) — the transcript and fields are what had arrived; GET /v1/calls/:id/result has any later.
|
|
2057
|
+
finalized: z.boolean(),
|
|
2058
|
+
// true: the payload would have passed CALL_ENDED_PAYLOAD_MAX_BYTES, so values were left out (see the cap) — fetch them.
|
|
2059
|
+
valuesOmitted: z.boolean()
|
|
1926
2060
|
});
|
|
1927
2061
|
z.object({
|
|
1928
2062
|
callId: z.string().uuid(),
|
|
@@ -2267,161 +2401,6 @@ z.object({
|
|
|
2267
2401
|
settings: TelephonySettings,
|
|
2268
2402
|
profile: EffectiveCallProfile
|
|
2269
2403
|
});
|
|
2270
|
-
var SHORTENER_HOSTS = [
|
|
2271
|
-
"bit.ly",
|
|
2272
|
-
"tinyurl.com",
|
|
2273
|
-
"t.co",
|
|
2274
|
-
"goo.gl",
|
|
2275
|
-
"ow.ly",
|
|
2276
|
-
"is.gd",
|
|
2277
|
-
"buff.ly",
|
|
2278
|
-
"rebrand.ly",
|
|
2279
|
-
"cutt.ly",
|
|
2280
|
-
"shorturl.at",
|
|
2281
|
-
"tiny.cc"
|
|
2282
|
-
];
|
|
2283
|
-
var PLACEHOLDER_HOSTS = ["acme.com", "example.com", "example.org", "test.com", "localhost"];
|
|
2284
|
-
var PublicUrl = z.string().url().refine((v) => v.startsWith("https://"), "must be https").refine((v) => {
|
|
2285
|
-
try {
|
|
2286
|
-
const host = new URL(v).hostname.toLowerCase().replace(/^www\./, "");
|
|
2287
|
-
return !SHORTENER_HOSTS.includes(host);
|
|
2288
|
-
} catch {
|
|
2289
|
-
return false;
|
|
2290
|
-
}
|
|
2291
|
-
}, "public URL shorteners are rejected by carriers \u2014 use your own domain").refine((v) => {
|
|
2292
|
-
try {
|
|
2293
|
-
const host = new URL(v).hostname.toLowerCase().replace(/^www\./, "");
|
|
2294
|
-
return !PLACEHOLDER_HOSTS.some((p) => host === p || host.endsWith(`.${p}`));
|
|
2295
|
-
} catch {
|
|
2296
|
-
return false;
|
|
2297
|
-
}
|
|
2298
|
-
}, "placeholder domain \u2014 reviewers will follow this link and reject the campaign");
|
|
2299
|
-
var A2pBusinessType = z.enum([
|
|
2300
|
-
"Sole Proprietorship",
|
|
2301
|
-
"Partnership",
|
|
2302
|
-
"Corporation",
|
|
2303
|
-
"Co-operative",
|
|
2304
|
-
"Limited Liability Corporation",
|
|
2305
|
-
"Non-profit Corporation"
|
|
2306
|
-
]);
|
|
2307
|
-
var A2pBusinessInfo = z.object({
|
|
2308
|
-
legalName: z.string().trim().min(2).max(200),
|
|
2309
|
-
/** EIN (US) or equivalent registration number. */
|
|
2310
|
-
registrationNumber: z.string().trim().min(4).max(50),
|
|
2311
|
-
businessType: A2pBusinessType,
|
|
2312
|
-
/** Publicly reachable production site — not staging, not a 404. */
|
|
2313
|
-
website: PublicUrl,
|
|
2314
|
-
industry: z.string().trim().min(2).max(60),
|
|
2315
|
-
address: z.object({
|
|
2316
|
-
street: z.string().trim().min(2).max(200),
|
|
2317
|
-
city: z.string().trim().min(1).max(100),
|
|
2318
|
-
region: z.string().trim().min(1).max(100),
|
|
2319
|
-
postalCode: z.string().trim().min(2).max(20),
|
|
2320
|
-
isoCountry: z.string().trim().length(2)
|
|
2321
|
-
}),
|
|
2322
|
-
authorizedRep: z.object({
|
|
2323
|
-
firstName: z.string().trim().min(1).max(100),
|
|
2324
|
-
lastName: z.string().trim().min(1).max(100),
|
|
2325
|
-
email: z.string().trim().email(),
|
|
2326
|
-
phone: z.string().trim().regex(/^\+[1-9]\d{6,14}$/, "must be E.164"),
|
|
2327
|
-
jobTitle: z.string().trim().min(2).max(100)
|
|
2328
|
-
})
|
|
2329
|
-
});
|
|
2330
|
-
var A2pOptInType = z.enum(["WEB_FORM", "PAPER_FORM", "VERBAL", "VIA_TEXT", "MOBILE_QR_CODE"]);
|
|
2331
|
-
var A2pUseCase = z.enum([
|
|
2332
|
-
"MIXED",
|
|
2333
|
-
"CUSTOMER_CARE",
|
|
2334
|
-
"MARKETING",
|
|
2335
|
-
"ACCOUNT_NOTIFICATION",
|
|
2336
|
-
"2FA",
|
|
2337
|
-
"DELIVERY_NOTIFICATION",
|
|
2338
|
-
"HIGHER_EDUCATION",
|
|
2339
|
-
"POLLING_VOTING",
|
|
2340
|
-
"PUBLIC_SERVICE_ANNOUNCEMENT",
|
|
2341
|
-
"LOW_VOLUME"
|
|
2342
|
-
]);
|
|
2343
|
-
var A2pMessagingProfile = z.object({
|
|
2344
|
-
useCase: A2pUseCase,
|
|
2345
|
-
/** Specific, not generic. "We send texts" gets rejected; describe the actual
|
|
2346
|
-
* messages and when they are sent. */
|
|
2347
|
-
description: z.string().trim().min(40).max(4096),
|
|
2348
|
-
/**
|
|
2349
|
-
* The single most-rejected field. Must describe HOW people opt in, state the
|
|
2350
|
-
* message frequency, include the "message and data rates may apply"
|
|
2351
|
-
* disclosure, and link to publicly reachable evidence. Twilio's API bounds it
|
|
2352
|
-
* to 40–2049 characters.
|
|
2353
|
-
*/
|
|
2354
|
-
messageFlow: z.string().trim().min(40).max(2049),
|
|
2355
|
-
optInType: A2pOptInType,
|
|
2356
|
-
/** Publicly accessible screenshots/pages showing the opt-in. Reviewers open
|
|
2357
|
-
* these; anything behind a login fails. */
|
|
2358
|
-
optInEvidenceUrls: z.array(PublicUrl).min(1).max(5),
|
|
2359
|
-
/** Real messages the customer will send. Must reflect the declared use case
|
|
2360
|
-
* and carry opt-out language. */
|
|
2361
|
-
messageSamples: z.array(z.string().trim().min(10).max(1024)).min(2).max(5),
|
|
2362
|
-
privacyPolicyUrl: PublicUrl,
|
|
2363
|
-
termsAndConditionsUrl: PublicUrl,
|
|
2364
|
-
hasEmbeddedLinks: z.boolean().default(false),
|
|
2365
|
-
hasEmbeddedPhone: z.boolean().default(false)
|
|
2366
|
-
});
|
|
2367
|
-
z.object({
|
|
2368
|
-
business: A2pBusinessInfo,
|
|
2369
|
-
messaging: A2pMessagingProfile,
|
|
2370
|
-
/** Register against Twilio's mock endpoints — exercises the full pipeline
|
|
2371
|
-
* with no fees and no real carrier submission. Used in CI and staging. */
|
|
2372
|
-
mock: z.boolean().default(false)
|
|
2373
|
-
}).superRefine((v, ctx) => {
|
|
2374
|
-
const flow = v.messaging.messageFlow.toLowerCase();
|
|
2375
|
-
if (!/(msg|message)\s*(&|and)\s*data rates/.test(flow)) {
|
|
2376
|
-
ctx.addIssue({
|
|
2377
|
-
code: z.ZodIssueCode.custom,
|
|
2378
|
-
path: ["messaging", "messageFlow"],
|
|
2379
|
-
message: 'must include a "Message and data rates may apply" disclosure \u2014 carriers reject without it'
|
|
2380
|
-
});
|
|
2381
|
-
}
|
|
2382
|
-
if (!/\d/.test(flow) || !/(msg|message|text)/.test(flow)) {
|
|
2383
|
-
ctx.addIssue({
|
|
2384
|
-
code: z.ZodIssueCode.custom,
|
|
2385
|
-
path: ["messaging", "messageFlow"],
|
|
2386
|
-
message: 'must state message frequency, e.g. "Up to 4 msgs/month"'
|
|
2387
|
-
});
|
|
2388
|
-
}
|
|
2389
|
-
const hasOptOut = v.messaging.messageSamples.some((s) => /stop/i.test(s));
|
|
2390
|
-
if (!hasOptOut) {
|
|
2391
|
-
ctx.addIssue({
|
|
2392
|
-
code: z.ZodIssueCode.custom,
|
|
2393
|
-
path: ["messaging", "messageSamples"],
|
|
2394
|
-
message: 'at least one sample must include opt-out language (e.g. "Reply STOP to opt out")'
|
|
2395
|
-
});
|
|
2396
|
-
}
|
|
2397
|
-
});
|
|
2398
|
-
var A2pState = z.enum([
|
|
2399
|
-
"none",
|
|
2400
|
-
"profile_pending",
|
|
2401
|
-
"profile_approved",
|
|
2402
|
-
"profile_failed",
|
|
2403
|
-
"brand_pending",
|
|
2404
|
-
"brand_approved",
|
|
2405
|
-
"brand_failed",
|
|
2406
|
-
"campaign_pending",
|
|
2407
|
-
"messaging_ready",
|
|
2408
|
-
"campaign_failed"
|
|
2409
|
-
]);
|
|
2410
|
-
z.object({
|
|
2411
|
-
state: A2pState,
|
|
2412
|
-
customerProfileSid: z.string().nullable(),
|
|
2413
|
-
trustProductSid: z.string().nullable(),
|
|
2414
|
-
brandSid: z.string().nullable(),
|
|
2415
|
-
messagingServiceSid: z.string().nullable(),
|
|
2416
|
-
campaignSid: z.string().nullable(),
|
|
2417
|
-
mock: z.boolean(),
|
|
2418
|
-
/** Carrier/Twilio rejection details, surfaced verbatim so the customer can
|
|
2419
|
-
* fix the specific field rather than guess. */
|
|
2420
|
-
failures: z.array(z.object({ code: z.number().nullable(), field: z.string().nullable(), message: z.string() })).default([]),
|
|
2421
|
-
/** Plain-language next step for the dashboard. */
|
|
2422
|
-
nextAction: z.string().nullable(),
|
|
2423
|
-
updatedAt: z.string().nullable()
|
|
2424
|
-
});
|
|
2425
2404
|
var ConnectorMode = z.enum(["tunnel", "direct"]);
|
|
2426
2405
|
var ConnectorStatus = z.enum(["online", "degraded", "offline"]);
|
|
2427
2406
|
var ConnectorNormalize = z.enum(["auto", "on", "off"]);
|
|
@@ -2536,9 +2515,11 @@ var FLOW_BOOT_FAILURES = [
|
|
|
2536
2515
|
"worker_identity_refused",
|
|
2537
2516
|
"provider_unavailable"
|
|
2538
2517
|
];
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
)
|
|
2518
|
+
var AGENT_END_REASONS = [
|
|
2519
|
+
"max_duration",
|
|
2520
|
+
...FLOW_BOOT_FAILURES.map((cause) => `flow_boot:${cause}`)
|
|
2521
|
+
];
|
|
2522
|
+
z.enum(AGENT_END_REASONS);
|
|
2542
2523
|
var EnvironmentSpec = z.enum(["draft", "live"]);
|
|
2543
2524
|
z.object({
|
|
2544
2525
|
agentName: z.string().min(1),
|
|
@@ -3603,6 +3584,18 @@ z.object({
|
|
|
3603
3584
|
thresholdUsd: z.number().min(1).max(TOPUP_MAX_USD),
|
|
3604
3585
|
amountUsd: z.number().int().min(TOPUP_MIN_USD).max(TOPUP_MAX_USD)
|
|
3605
3586
|
});
|
|
3587
|
+
var PipelineSlotKey = z.object({
|
|
3588
|
+
/** The provider as the slot reports it (LiveKit's label: `openai`, `api.openai.com`, `Deepgram`, …). */
|
|
3589
|
+
provider: z.string().min(1).max(200),
|
|
3590
|
+
/** true = the workspace's own key built it; false = the platform's. */
|
|
3591
|
+
byok: z.boolean()
|
|
3592
|
+
});
|
|
3593
|
+
z.object({
|
|
3594
|
+
llm: PipelineSlotKey.optional(),
|
|
3595
|
+
stt: PipelineSlotKey.optional(),
|
|
3596
|
+
tts: PipelineSlotKey.optional(),
|
|
3597
|
+
realtime: PipelineSlotKey.optional()
|
|
3598
|
+
});
|
|
3606
3599
|
|
|
3607
3600
|
// src/brain/transport-tunnel.ts
|
|
3608
3601
|
var AsyncQueue = class {
|