@fonoster/common 0.30.0 → 0.31.0
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/{assistants → agents}/index.d.ts +1 -1
- package/dist/{assistants → agents}/index.js +1 -1
- package/dist/{assistants/sessionAssistantSchema.d.ts → agents/sessionAgentSchema.d.ts} +20 -6
- package/dist/{assistants/sessionAssistantSchema.js → agents/sessionAgentSchema.js} +16 -11
- package/dist/cellsecrets/index.d.ts +2 -2
- package/dist/cellsecrets/index.js +3 -3
- package/dist/config/cli/render.d.ts +1 -1
- package/dist/config/cli/render.js +3 -3
- package/dist/config/configHints.d.ts +1 -14
- package/dist/config/configHints.js +16 -30
- package/dist/config/index.d.ts +0 -1
- package/dist/config/index.js +0 -1
- package/dist/config/interpolateEnv.d.ts +1 -1
- package/dist/config/loadServiceConfig.d.ts +0 -5
- package/dist/config/loadServiceConfig.js +3 -12
- package/dist/constants.d.ts +1 -3
- package/dist/constants.js +3 -5
- package/dist/errors/handleZodError.js +3 -1
- package/dist/filters/index.d.ts +70 -0
- package/dist/filters/index.js +101 -0
- package/dist/identity/roles.js +11 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +5 -2
- package/dist/protos/applications.proto +16 -2
- package/dist/protos/authz.proto +3 -0
- package/dist/protos/billing.proto +92 -0
- package/dist/protos/calls.proto +4 -0
- package/dist/protos/capabilities.proto +8 -0
- package/dist/protos/providers.proto +6 -2
- package/dist/protos/roomr.proto +146 -0
- package/dist/protos/session.proto +194 -0
- package/dist/protos/usage.proto +59 -0
- package/dist/registry/Registry.d.ts +13 -5
- package/dist/registry/Registry.js +49 -35
- package/dist/registry/cli.js +19 -7
- package/dist/registry/features.d.ts +2 -2
- package/dist/registry/features.js +7 -5
- package/dist/registry/prisma.d.ts +2 -2
- package/dist/registry/prisma.js +26 -18
- package/dist/registry/types.d.ts +17 -5
- package/dist/registry/types.js +2 -0
- package/dist/roomr/health.d.ts +9 -0
- package/dist/roomr/health.js +75 -0
- package/dist/roomr/index.d.ts +75 -0
- package/dist/roomr/index.js +146 -0
- package/dist/roomr/session.d.ts +133 -0
- package/dist/roomr/session.js +132 -0
- package/dist/session/schema.d.ts +196 -7
- package/dist/session/schema.js +59 -8
- package/dist/sessions/index.d.ts +15 -12
- package/dist/sessions/index.js +15 -12
- package/dist/telemetry.d.ts +1 -1
- package/dist/usage/CallUsage.d.ts +38 -0
- package/dist/usage/CallUsage.js +76 -0
- package/dist/{utils/types.d.ts → usage/index.d.ts} +4 -5
- package/dist/usage/index.js +38 -0
- package/dist/usage/meters.d.ts +113 -0
- package/dist/usage/meters.js +90 -0
- package/dist/usage/types.d.ts +159 -0
- package/dist/usage/types.js +84 -0
- package/dist/usage/usageId.d.ts +6 -0
- package/dist/usage/usageId.js +45 -0
- package/dist/utils/index.d.ts +0 -2
- package/dist/utils/index.js +0 -2
- package/dist/utils/withErrorHandling.js +1 -1
- package/dist/validators/calls.d.ts +5 -2
- package/dist/validators/calls.js +8 -1
- package/dist/validators/sip.d.ts +2 -2
- package/dist/validators/sip.js +3 -3
- package/dist/webhooks/bus.d.ts +29 -10
- package/dist/webhooks/bus.js +58 -50
- package/dist/webhooks/events.d.ts +1 -1
- package/dist/webhooks/events.js +1 -1
- package/package.json +9 -8
- package/schema/session.v1.json +82 -2
- package/dist/config/integrationsSchema.d.ts +0 -32
- package/dist/config/integrationsSchema.js +0 -56
- package/dist/utils/createFetchSingleCallByCallId.d.ts +0 -22
- package/dist/utils/createFetchSingleCallByCallId.js +0 -33
- package/dist/utils/types.js +0 -2
- /package/dist/{assistants → agents}/testCasesSchema.d.ts +0 -0
- /package/dist/{assistants → agents}/testCasesSchema.js +0 -0
- /package/dist/{assistants → agents}/tools/index.d.ts +0 -0
- /package/dist/{assistants → agents}/tools/index.js +0 -0
- /package/dist/{assistants → agents}/tools/propertySchema.d.ts +0 -0
- /package/dist/{assistants → agents}/tools/propertySchema.js +0 -0
- /package/dist/{assistants → agents}/tools/toolSchema.d.ts +0 -0
- /package/dist/{assistants → agents}/tools/toolSchema.js +0 -0
|
@@ -33,5 +33,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
33
33
|
* limitations under the License.
|
|
34
34
|
*/
|
|
35
35
|
__exportStar(require("./tools"), exports);
|
|
36
|
-
__exportStar(require("./
|
|
36
|
+
__exportStar(require("./sessionAgentSchema"), exports);
|
|
37
37
|
__exportStar(require("./testCasesSchema"), exports);
|
|
@@ -214,12 +214,16 @@ export declare const sessionConversationSettingsSchema: z.ZodObject<{
|
|
|
214
214
|
transferOptions: z.ZodOptional<z.ZodObject<{
|
|
215
215
|
phoneNumber: z.ZodString;
|
|
216
216
|
message: z.ZodString;
|
|
217
|
+
/** Said when the transfer fails, before the conversation goes on (default in Autopilot). */
|
|
218
|
+
failedMessage: z.ZodOptional<z.ZodString>;
|
|
217
219
|
}, "strip", z.ZodTypeAny, {
|
|
218
220
|
message?: string;
|
|
219
221
|
phoneNumber?: string;
|
|
222
|
+
failedMessage?: string;
|
|
220
223
|
}, {
|
|
221
224
|
message?: string;
|
|
222
225
|
phoneNumber?: string;
|
|
226
|
+
failedMessage?: string;
|
|
223
227
|
}>>;
|
|
224
228
|
idleOptions: z.ZodOptional<z.ZodObject<{
|
|
225
229
|
message: z.ZodString;
|
|
@@ -236,7 +240,7 @@ export declare const sessionConversationSettingsSchema: z.ZodObject<{
|
|
|
236
240
|
}>>;
|
|
237
241
|
allowUserBargeIn: z.ZodDefault<z.ZodBoolean>;
|
|
238
242
|
/**
|
|
239
|
-
* The turn-taking patience knob (TT-B5): sent to
|
|
243
|
+
* The turn-taking patience knob (TT-B5): sent to AppBridge with listen.update so its Pacing
|
|
240
244
|
* policy waits less (low) or more (high) before turn.ended. Autopilot prepares a reply on
|
|
241
245
|
* turn.likely_ended at low and normal, and only on turn.ended at high.
|
|
242
246
|
*/
|
|
@@ -266,6 +270,7 @@ export declare const sessionConversationSettingsSchema: z.ZodObject<{
|
|
|
266
270
|
transferOptions?: {
|
|
267
271
|
message?: string;
|
|
268
272
|
phoneNumber?: string;
|
|
273
|
+
failedMessage?: string;
|
|
269
274
|
};
|
|
270
275
|
idleOptions?: {
|
|
271
276
|
message?: string;
|
|
@@ -292,6 +297,7 @@ export declare const sessionConversationSettingsSchema: z.ZodObject<{
|
|
|
292
297
|
transferOptions?: {
|
|
293
298
|
message?: string;
|
|
294
299
|
phoneNumber?: string;
|
|
300
|
+
failedMessage?: string;
|
|
295
301
|
};
|
|
296
302
|
idleOptions?: {
|
|
297
303
|
message?: string;
|
|
@@ -309,7 +315,7 @@ export declare const sessionConversationSettingsSchema: z.ZodObject<{
|
|
|
309
315
|
vad?: any;
|
|
310
316
|
maxSpeechWaitTimeout?: any;
|
|
311
317
|
}>;
|
|
312
|
-
export declare const
|
|
318
|
+
export declare const sessionAgentSchema: z.ZodObject<{
|
|
313
319
|
conversationSettings: z.ZodObject<{
|
|
314
320
|
firstMessage: z.ZodOptional<z.ZodString>;
|
|
315
321
|
systemPrompt: z.ZodString;
|
|
@@ -320,12 +326,16 @@ export declare const sessionAssistantSchema: z.ZodObject<{
|
|
|
320
326
|
transferOptions: z.ZodOptional<z.ZodObject<{
|
|
321
327
|
phoneNumber: z.ZodString;
|
|
322
328
|
message: z.ZodString;
|
|
329
|
+
/** Said when the transfer fails, before the conversation goes on (default in Autopilot). */
|
|
330
|
+
failedMessage: z.ZodOptional<z.ZodString>;
|
|
323
331
|
}, "strip", z.ZodTypeAny, {
|
|
324
332
|
message?: string;
|
|
325
333
|
phoneNumber?: string;
|
|
334
|
+
failedMessage?: string;
|
|
326
335
|
}, {
|
|
327
336
|
message?: string;
|
|
328
337
|
phoneNumber?: string;
|
|
338
|
+
failedMessage?: string;
|
|
329
339
|
}>>;
|
|
330
340
|
idleOptions: z.ZodOptional<z.ZodObject<{
|
|
331
341
|
message: z.ZodString;
|
|
@@ -342,7 +352,7 @@ export declare const sessionAssistantSchema: z.ZodObject<{
|
|
|
342
352
|
}>>;
|
|
343
353
|
allowUserBargeIn: z.ZodDefault<z.ZodBoolean>;
|
|
344
354
|
/**
|
|
345
|
-
* The turn-taking patience knob (TT-B5): sent to
|
|
355
|
+
* The turn-taking patience knob (TT-B5): sent to AppBridge with listen.update so its Pacing
|
|
346
356
|
* policy waits less (low) or more (high) before turn.ended. Autopilot prepares a reply on
|
|
347
357
|
* turn.likely_ended at low and normal, and only on turn.ended at high.
|
|
348
358
|
*/
|
|
@@ -372,6 +382,7 @@ export declare const sessionAssistantSchema: z.ZodObject<{
|
|
|
372
382
|
transferOptions?: {
|
|
373
383
|
message?: string;
|
|
374
384
|
phoneNumber?: string;
|
|
385
|
+
failedMessage?: string;
|
|
375
386
|
};
|
|
376
387
|
idleOptions?: {
|
|
377
388
|
message?: string;
|
|
@@ -398,6 +409,7 @@ export declare const sessionAssistantSchema: z.ZodObject<{
|
|
|
398
409
|
transferOptions?: {
|
|
399
410
|
message?: string;
|
|
400
411
|
phoneNumber?: string;
|
|
412
|
+
failedMessage?: string;
|
|
401
413
|
};
|
|
402
414
|
idleOptions?: {
|
|
403
415
|
message?: string;
|
|
@@ -617,6 +629,7 @@ export declare const sessionAssistantSchema: z.ZodObject<{
|
|
|
617
629
|
transferOptions?: {
|
|
618
630
|
message?: string;
|
|
619
631
|
phoneNumber?: string;
|
|
632
|
+
failedMessage?: string;
|
|
620
633
|
};
|
|
621
634
|
idleOptions?: {
|
|
622
635
|
message?: string;
|
|
@@ -681,6 +694,7 @@ export declare const sessionAssistantSchema: z.ZodObject<{
|
|
|
681
694
|
transferOptions?: {
|
|
682
695
|
message?: string;
|
|
683
696
|
phoneNumber?: string;
|
|
697
|
+
failedMessage?: string;
|
|
684
698
|
};
|
|
685
699
|
idleOptions?: {
|
|
686
700
|
message?: string;
|
|
@@ -735,7 +749,7 @@ export declare const sessionAssistantSchema: z.ZodObject<{
|
|
|
735
749
|
eventsHook?: any;
|
|
736
750
|
audioFilters?: any;
|
|
737
751
|
}>;
|
|
738
|
-
export type
|
|
739
|
-
export type SessionConversationSettings =
|
|
740
|
-
export type SessionLanguageModel =
|
|
752
|
+
export type SessionAgent = z.infer<typeof sessionAgentSchema>;
|
|
753
|
+
export type SessionConversationSettings = SessionAgent["conversationSettings"];
|
|
754
|
+
export type SessionLanguageModel = SessionAgent["languageModel"];
|
|
741
755
|
export type ToolDefinition = SessionLanguageModel["tools"][number];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.sessionAgentSchema = exports.sessionConversationSettingsSchema = exports.sessionLanguageModelSchema = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
6
6
|
* http://github.com/fonoster/fonoster
|
|
@@ -21,10 +21,10 @@ exports.sessionAssistantSchema = exports.sessionConversationSettingsSchema = exp
|
|
|
21
21
|
*/
|
|
22
22
|
const zod_1 = require("zod");
|
|
23
23
|
const tools_1 = require("./tools");
|
|
24
|
-
// The
|
|
25
|
-
// 5.4). Strict: vendor credentials, vendor enums, VAD settings and the
|
|
26
|
-
// rejected with messages pointing to where they moved. It is the only
|
|
27
|
-
// one was deleted after the cutover job converts stored
|
|
24
|
+
// The agent config for the rebuilt Autopilot (rework-autopilot A8, A11, A12; tasks 5.1, 5.2,
|
|
25
|
+
// 5.4). Strict: vendor credentials, vendor enums, VAD settings and the agent webhook are
|
|
26
|
+
// rejected with messages pointing to where they moved. It is the only agent schema: the legacy
|
|
27
|
+
// one was deleted after the cutover job converts stored agents (rework-autopilot 8.2).
|
|
28
28
|
const removed = (key, message) => zod_1.z
|
|
29
29
|
.any()
|
|
30
30
|
.optional()
|
|
@@ -73,7 +73,12 @@ exports.sessionConversationSettingsSchema = zod_1.z
|
|
|
73
73
|
.positive()
|
|
74
74
|
.default(30 * 60 * 1000),
|
|
75
75
|
transferOptions: zod_1.z
|
|
76
|
-
.object({
|
|
76
|
+
.object({
|
|
77
|
+
phoneNumber: zod_1.z.string(),
|
|
78
|
+
message: zod_1.z.string(),
|
|
79
|
+
/** Said when the transfer fails, before the conversation goes on (default in Autopilot). */
|
|
80
|
+
failedMessage: zod_1.z.string().optional()
|
|
81
|
+
})
|
|
77
82
|
.optional(),
|
|
78
83
|
idleOptions: zod_1.z
|
|
79
84
|
.object({
|
|
@@ -84,7 +89,7 @@ exports.sessionConversationSettingsSchema = zod_1.z
|
|
|
84
89
|
.optional(),
|
|
85
90
|
allowUserBargeIn: zod_1.z.boolean().default(true),
|
|
86
91
|
/**
|
|
87
|
-
* The turn-taking patience knob (TT-B5): sent to
|
|
92
|
+
* The turn-taking patience knob (TT-B5): sent to AppBridge with listen.update so its Pacing
|
|
88
93
|
* policy waits less (low) or more (high) before turn.ended. Autopilot prepares a reply on
|
|
89
94
|
* turn.likely_ended at low and normal, and only on turn.ended at high.
|
|
90
95
|
*/
|
|
@@ -96,17 +101,17 @@ exports.sessionConversationSettingsSchema = zod_1.z
|
|
|
96
101
|
/** Catalog ids overriding the app's speech defaults on every speak. */
|
|
97
102
|
voice: zod_1.z.string().optional(),
|
|
98
103
|
language: zod_1.z.string().optional(),
|
|
99
|
-
vad: removed("vad", "turn detection moved to
|
|
100
|
-
maxSpeechWaitTimeout: removed("maxSpeechWaitTimeout", "turn detection moved to
|
|
104
|
+
vad: removed("vad", "turn detection moved to AppBridge (turn-taking configuration)"),
|
|
105
|
+
maxSpeechWaitTimeout: removed("maxSpeechWaitTimeout", "turn detection moved to AppBridge")
|
|
101
106
|
})
|
|
102
107
|
.strict();
|
|
103
|
-
exports.
|
|
108
|
+
exports.sessionAgentSchema = zod_1.z
|
|
104
109
|
.object({
|
|
105
110
|
conversationSettings: exports.sessionConversationSettingsSchema,
|
|
106
111
|
languageModel: exports.sessionLanguageModelSchema,
|
|
107
112
|
/** Conversation eval cases, kept as they were (evaluated outside calls). */
|
|
108
113
|
testCases: zod_1.z.any().optional(),
|
|
109
|
-
eventsHook: removed("eventsHook", "
|
|
114
|
+
eventsHook: removed("eventsHook", "agent webhooks were retired; use workspace webhooks (conversation.ended → call.ended or call_record.sealed)"),
|
|
110
115
|
audioFilters: removed("audioFilters", "audio filters are part of the app's configuration")
|
|
111
116
|
})
|
|
112
117
|
.strict();
|
|
@@ -52,7 +52,7 @@ export declare class DirectorySecretStore implements CellSecretStore {
|
|
|
52
52
|
/** The store a config names (dir wins over file). */
|
|
53
53
|
export declare function openCellSecrets(config: CellSecretsConfig, env?: Record<string, string | undefined>): CellSecretStore;
|
|
54
54
|
/**
|
|
55
|
-
* The cell's secrets as a workspace key source (
|
|
55
|
+
* The cell's secrets as a workspace key source (appbridge Catalog, Autopilot): a private region
|
|
56
56
|
* serves one workspace, so the provider name alone picks the key. Read errors count as unset.
|
|
57
57
|
*/
|
|
58
58
|
export declare class CellSecretKeys {
|
|
@@ -84,7 +84,7 @@ export declare const CELL_WORKSPACE_KEYS_SUBJECT = "cell.workspacekeys.get";
|
|
|
84
84
|
export declare class NatsWorkspaceKeys {
|
|
85
85
|
private readonly requester;
|
|
86
86
|
private readonly timeoutMs;
|
|
87
|
-
/** Never cached:
|
|
87
|
+
/** Never cached: AppBridge keeps no adapter built with these keys past the call's lookup. */
|
|
88
88
|
readonly cacheable = false;
|
|
89
89
|
constructor(requester: () => Promise<KeyRequester>, timeoutMs?: number);
|
|
90
90
|
get(workspaceRef: string, providerId: string): Promise<string | undefined>;
|
|
@@ -72,7 +72,7 @@ const path = __importStar(require("path"));
|
|
|
72
72
|
// - an encrypted file (Compose, bare metal): AES-256-GCM, key derived with scrypt from a
|
|
73
73
|
// passphrase in the environment (default FONOSTER_REGION_SECRETS_KEY);
|
|
74
74
|
// - a directory with one file per secret: a mounted Kubernetes Secret.
|
|
75
|
-
//
|
|
75
|
+
// AppBridge and the hosted Autopilot read it; `fonoster-region secrets` writes it. Values are
|
|
76
76
|
// never logged; `names()` is what the region agent reports in heartbeats.
|
|
77
77
|
/** Secret names: provider ids and credential refs (`deepgram`, `groq`, `openai`, `s3.secret`). */
|
|
78
78
|
exports.SECRET_NAME = /^[a-z0-9][a-z0-9._-]{0,63}$/;
|
|
@@ -224,7 +224,7 @@ function openCellSecrets(config, env = process.env) {
|
|
|
224
224
|
return new EncryptedFileSecretStore(config.file, key);
|
|
225
225
|
}
|
|
226
226
|
/**
|
|
227
|
-
* The cell's secrets as a workspace key source (
|
|
227
|
+
* The cell's secrets as a workspace key source (appbridge Catalog, Autopilot): a private region
|
|
228
228
|
* serves one workspace, so the provider name alone picks the key. Read errors count as unset.
|
|
229
229
|
*/
|
|
230
230
|
class CellSecretKeys {
|
|
@@ -275,7 +275,7 @@ class NatsWorkspaceKeys {
|
|
|
275
275
|
constructor(requester, timeoutMs = 2000) {
|
|
276
276
|
this.requester = requester;
|
|
277
277
|
this.timeoutMs = timeoutMs;
|
|
278
|
-
/** Never cached:
|
|
278
|
+
/** Never cached: AppBridge keeps no adapter built with these keys past the call's lookup. */
|
|
279
279
|
this.cacheable = false;
|
|
280
280
|
}
|
|
281
281
|
get(workspaceRef, providerId) {
|
|
@@ -27,7 +27,7 @@ export declare const FONOSTER_SERVICE_FILES: string[];
|
|
|
27
27
|
export declare function renderTemplate(text: string, env: Env, file?: string, substitute?: boolean): string;
|
|
28
28
|
export declare function deepMerge(base: unknown, overlay: unknown): unknown;
|
|
29
29
|
export declare const EXAMPLE: RegExp;
|
|
30
|
-
/** The rendered name of an example (`
|
|
30
|
+
/** The rendered name of an example (`appbridge.example.yaml` → `appbridge.yaml`). */
|
|
31
31
|
export declare function renderedName(example: string): string | undefined;
|
|
32
32
|
export declare function listExamples(configDir: string): string[];
|
|
33
33
|
export type RenderOptions = {
|
|
@@ -40,9 +40,9 @@ exports.RenderError = RenderError;
|
|
|
40
40
|
exports.FONOSTER_SERVICE_FILES = [
|
|
41
41
|
"fonoster",
|
|
42
42
|
"identity",
|
|
43
|
-
"
|
|
43
|
+
"appbridge",
|
|
44
44
|
"autopilot",
|
|
45
|
-
"
|
|
45
|
+
"roomr"
|
|
46
46
|
];
|
|
47
47
|
/**
|
|
48
48
|
* Checks one template's placeholders and returns it with them kept (`substitute` false) or
|
|
@@ -82,7 +82,7 @@ function deepMerge(base, overlay) {
|
|
|
82
82
|
return out;
|
|
83
83
|
}
|
|
84
84
|
exports.EXAMPLE = /^(.+)\.example\.([A-Za-z0-9]+)$/;
|
|
85
|
-
/** The rendered name of an example (`
|
|
85
|
+
/** The rendered name of an example (`appbridge.example.yaml` → `appbridge.yaml`). */
|
|
86
86
|
function renderedName(example) {
|
|
87
87
|
const m = exports.EXAMPLE.exec(example);
|
|
88
88
|
return m ? `${m[1]}.${m[2]}` : undefined;
|
|
@@ -16,19 +16,6 @@
|
|
|
16
16
|
* See the License for the specific language governing permissions and
|
|
17
17
|
* limitations under the License.
|
|
18
18
|
*/
|
|
19
|
-
type Env = Record<string, string | undefined>;
|
|
20
|
-
/** Old key path → new key path, e.g. `{ encryptionKey: "encryption.key" }`. */
|
|
21
|
-
type MovedKeys = Record<string, string>;
|
|
22
|
-
/**
|
|
23
|
-
* Lists the moved keys present in a raw config, as readable hints. The new
|
|
24
|
-
* location may itself be valid, so this only reports what was found.
|
|
25
|
-
*/
|
|
26
|
-
declare function findMovedKeys(raw: unknown, movedKeys: MovedKeys): string[];
|
|
27
|
-
/**
|
|
28
|
-
* Names of environment variables that look like the old env-based config for
|
|
29
|
-
* this service. Values are never returned, so they can be logged safely.
|
|
30
|
-
*/
|
|
31
|
-
declare function findLegacyEnv(prefixes: string[], env?: Env): string[];
|
|
32
19
|
/** Edit distance between two strings (insertions, deletions, substitutions). */
|
|
33
20
|
declare function levenshtein(a: string, b: string): number;
|
|
34
21
|
/**
|
|
@@ -36,4 +23,4 @@ declare function levenshtein(a: string, b: string): number;
|
|
|
36
23
|
* to be a typo: at most a third of the key's length (at least 1) edits away, ignoring case.
|
|
37
24
|
*/
|
|
38
25
|
declare function suggestKey(unknown: string, known: string[]): string | undefined;
|
|
39
|
-
export {
|
|
26
|
+
export { levenshtein, suggestKey };
|
|
@@ -1,39 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.findMovedKeys = findMovedKeys;
|
|
4
|
-
exports.findLegacyEnv = findLegacyEnv;
|
|
5
3
|
exports.levenshtein = levenshtein;
|
|
6
4
|
exports.suggestKey = suggestKey;
|
|
7
|
-
function hasPath(input, path) {
|
|
8
|
-
let current = input;
|
|
9
|
-
for (const segment of path.split(".")) {
|
|
10
|
-
if (current === null ||
|
|
11
|
-
typeof current !== "object" ||
|
|
12
|
-
!(segment in current)) {
|
|
13
|
-
return false;
|
|
14
|
-
}
|
|
15
|
-
current = current[segment];
|
|
16
|
-
}
|
|
17
|
-
return true;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Lists the moved keys present in a raw config, as readable hints. The new
|
|
21
|
-
* location may itself be valid, so this only reports what was found.
|
|
22
|
-
*/
|
|
23
|
-
function findMovedKeys(raw, movedKeys) {
|
|
24
|
-
return Object.entries(movedKeys)
|
|
25
|
-
.filter(([from]) => hasPath(raw, from))
|
|
26
|
-
.map(([from, to]) => `"${from}" moved to "${to}"`);
|
|
27
|
-
}
|
|
28
5
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
6
|
+
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
7
|
+
* http://github.com/fonoster/fonoster
|
|
8
|
+
*
|
|
9
|
+
* This file is part of Fonoster
|
|
10
|
+
*
|
|
11
|
+
* Licensed under the MIT License (the "License");
|
|
12
|
+
* you may not use this file except in compliance with
|
|
13
|
+
* the License. You may obtain a copy of the License at
|
|
14
|
+
*
|
|
15
|
+
* https://opensource.org/licenses/MIT
|
|
16
|
+
*
|
|
17
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
18
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
19
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
20
|
+
* See the License for the specific language governing permissions and
|
|
21
|
+
* limitations under the License.
|
|
31
22
|
*/
|
|
32
|
-
function findLegacyEnv(prefixes, env = process.env) {
|
|
33
|
-
return Object.keys(env)
|
|
34
|
-
.filter((name) => prefixes.some((prefix) => name.startsWith(prefix)))
|
|
35
|
-
.sort();
|
|
36
|
-
}
|
|
37
23
|
/** Edit distance between two strings (insertions, deletions, substitutions). */
|
|
38
24
|
function levenshtein(a, b) {
|
|
39
25
|
let prev = Array.from({ length: b.length + 1 }, (_, j) => j);
|
package/dist/config/index.d.ts
CHANGED
package/dist/config/index.js
CHANGED
|
@@ -33,7 +33,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
33
33
|
* limitations under the License.
|
|
34
34
|
*/
|
|
35
35
|
__exportStar(require("./configHints"), exports);
|
|
36
|
-
__exportStar(require("./integrationsSchema"), exports);
|
|
37
36
|
__exportStar(require("./interpolateEnv"), exports);
|
|
38
37
|
__exportStar(require("./loadServiceConfig"), exports);
|
|
39
38
|
__exportStar(require("./logsSchema"), exports);
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
type Env = Record<string, string | undefined>;
|
|
20
20
|
type InterpolateOptions = {
|
|
21
21
|
/**
|
|
22
|
-
* Key paths where `${VAR}` may appear, e.g. `database.url` or `
|
|
22
|
+
* Key paths where `${VAR}` may appear, e.g. `database.url` or `nats.*`
|
|
23
23
|
* (`*` matches the key and everything below it; `*` alone matches every key). When given,
|
|
24
24
|
* `${...}` at any other path is an error. When omitted, every string is interpolated.
|
|
25
25
|
*/
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { z, ZodTypeAny } from "zod";
|
|
2
|
-
import { MovedKeys } from "./configHints";
|
|
3
2
|
type Env = Record<string, string | undefined>;
|
|
4
3
|
type LoadServiceConfigOptions<S extends ZodTypeAny> = {
|
|
5
4
|
/** Service name, used in messages. */
|
|
@@ -20,10 +19,6 @@ type LoadServiceConfigOptions<S extends ZodTypeAny> = {
|
|
|
20
19
|
* else is an error.
|
|
21
20
|
*/
|
|
22
21
|
interpolatePaths?: string[];
|
|
23
|
-
/** Old key path → new key path, reported as hints. */
|
|
24
|
-
movedKeys?: MovedKeys;
|
|
25
|
-
/** Env var prefixes of the old env-based config, reported as a warning. */
|
|
26
|
-
legacyEnvPrefixes?: string[];
|
|
27
22
|
};
|
|
28
23
|
/**
|
|
29
24
|
* Loads, interpolates and strictly validates a service's config file.
|
|
@@ -21,7 +21,6 @@ exports.loadServiceConfig = loadServiceConfig;
|
|
|
21
21
|
*/
|
|
22
22
|
const fs_1 = require("fs");
|
|
23
23
|
const logger_1 = require("@fonoster/logger");
|
|
24
|
-
const configHints_1 = require("./configHints");
|
|
25
24
|
const interpolateEnv_1 = require("./interpolateEnv");
|
|
26
25
|
const parseConfigFile_1 = require("./parseConfigFile");
|
|
27
26
|
const resolveConfigFile_1 = require("./resolveConfigFile");
|
|
@@ -56,17 +55,13 @@ function formatIssues(error) {
|
|
|
56
55
|
* Throws with the file path and the offending key path on any problem.
|
|
57
56
|
*/
|
|
58
57
|
function loadServiceConfig(options) {
|
|
59
|
-
var _a, _b, _c, _d, _e
|
|
58
|
+
var _a, _b, _c, _d, _e;
|
|
60
59
|
const { service, schema } = options;
|
|
61
60
|
const fileBase = (_a = options.fileBase) !== null && _a !== void 0 ? _a : service;
|
|
62
61
|
const argv = (_b = options.argv) !== null && _b !== void 0 ? _b : process.argv;
|
|
63
62
|
const env = (_c = options.env) !== null && _c !== void 0 ? _c : process.env;
|
|
64
|
-
const legacy = (0, configHints_1.findLegacyEnv)((_d = options.legacyEnvPrefixes) !== null && _d !== void 0 ? _d : [], env);
|
|
65
|
-
if (legacy.length > 0) {
|
|
66
|
-
logger.warn(`ignoring ${legacy.length} legacy environment variable(s); ${service} now reads its config file only: ${legacy.join(", ")}`);
|
|
67
|
-
}
|
|
68
63
|
const resolved = (0, resolveConfigFile_1.resolveConfigFile)(fileBase, argv, options.searchDirs);
|
|
69
|
-
const where = (
|
|
64
|
+
const where = (_d = resolved.path) !== null && _d !== void 0 ? _d : "(built-in defaults)";
|
|
70
65
|
let raw = {};
|
|
71
66
|
if ("searched" in resolved) {
|
|
72
67
|
logger.warn(`no ${service} config file found (looked for ${resolved.searched.join(", ")}); using built-in defaults`);
|
|
@@ -88,14 +83,10 @@ function loadServiceConfig(options) {
|
|
|
88
83
|
delete rest.$schema;
|
|
89
84
|
raw = rest;
|
|
90
85
|
}
|
|
91
|
-
const moved = (0, configHints_1.findMovedKeys)(raw, (_f = options.movedKeys) !== null && _f !== void 0 ? _f : {});
|
|
92
|
-
if (moved.length > 0) {
|
|
93
|
-
throw new Error(`invalid ${service} config at ${where}: ${moved.join("; ")}`);
|
|
94
|
-
}
|
|
95
86
|
let interpolated;
|
|
96
87
|
try {
|
|
97
88
|
interpolated = (0, interpolateEnv_1.interpolateEnv)(raw, env, {
|
|
98
|
-
allowedPaths: (
|
|
89
|
+
allowedPaths: (_e = options.interpolatePaths) !== null && _e !== void 0 ? _e : []
|
|
99
90
|
});
|
|
100
91
|
}
|
|
101
92
|
catch (e) {
|
package/dist/constants.d.ts
CHANGED
|
@@ -19,10 +19,8 @@
|
|
|
19
19
|
import { ServingStatus } from "grpc-health-check";
|
|
20
20
|
export declare const GRPC_NOT_SERVING_STATUS: ServingStatus;
|
|
21
21
|
export declare const GRPC_SERVING_STATUS: ServingStatus;
|
|
22
|
-
export declare const CALL_DETAIL_RECORD_MEASUREMENT = "cdr";
|
|
23
|
-
export declare const INFLUXDB_CALLS_BUCKET = "calls";
|
|
24
22
|
export declare const APP_REF_HEADER = "x-app-ref";
|
|
25
|
-
export declare const ROUTR_DEFAULT_PEER_AOR = "sip:
|
|
23
|
+
export declare const ROUTR_DEFAULT_PEER_AOR = "sip:roomr@default";
|
|
26
24
|
export declare const AUTOPILOT_SPECIAL_LOCAL_ADDRESS = "autopilot.fonoster.local";
|
|
27
25
|
export declare const AUTOPILOT_INTERNAL_ADDRESS = "autopilot:50061";
|
|
28
26
|
export declare const WELCOME_DEMO_SPECIAL_LOCAL_ADDRESS = "welcome.demo.fonoster.local";
|
package/dist/constants.js
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WELCOME_DEMO_SPECIAL_LOCAL_ADDRESS = exports.AUTOPILOT_INTERNAL_ADDRESS = exports.AUTOPILOT_SPECIAL_LOCAL_ADDRESS = exports.ROUTR_DEFAULT_PEER_AOR = exports.APP_REF_HEADER = exports.
|
|
3
|
+
exports.WELCOME_DEMO_SPECIAL_LOCAL_ADDRESS = exports.AUTOPILOT_INTERNAL_ADDRESS = exports.AUTOPILOT_SPECIAL_LOCAL_ADDRESS = exports.ROUTR_DEFAULT_PEER_AOR = exports.APP_REF_HEADER = exports.GRPC_SERVING_STATUS = exports.GRPC_NOT_SERVING_STATUS = void 0;
|
|
4
4
|
exports.GRPC_NOT_SERVING_STATUS = "NOT_SERVING";
|
|
5
5
|
exports.GRPC_SERVING_STATUS = "SERVING";
|
|
6
|
-
exports.CALL_DETAIL_RECORD_MEASUREMENT = "cdr";
|
|
7
|
-
exports.INFLUXDB_CALLS_BUCKET = "calls";
|
|
8
6
|
exports.APP_REF_HEADER = "x-app-ref";
|
|
9
|
-
// The peer app-linked numbers point at: the Go
|
|
7
|
+
// The peer app-linked numbers point at: the Go Roomr nodes (least-sessions). Asterisk's
|
|
10
8
|
// sip:voice@default is gone (cleanbreak CB-B3).
|
|
11
|
-
exports.ROUTR_DEFAULT_PEER_AOR = "sip:
|
|
9
|
+
exports.ROUTR_DEFAULT_PEER_AOR = "sip:roomr@default";
|
|
12
10
|
exports.AUTOPILOT_SPECIAL_LOCAL_ADDRESS = "autopilot.fonoster.local";
|
|
13
11
|
exports.AUTOPILOT_INTERNAL_ADDRESS = "autopilot:50061";
|
|
14
12
|
exports.WELCOME_DEMO_SPECIAL_LOCAL_ADDRESS = "welcome.demo.fonoster.local";
|
|
@@ -25,7 +25,9 @@ const zod_validation_error_1 = require("zod-validation-error");
|
|
|
25
25
|
const logger = (0, logger_1.getLogger)({ service: "apiserver", filePath: __filename });
|
|
26
26
|
function handleZodError(error, callback) {
|
|
27
27
|
if ((error === null || error === void 0 ? void 0 : error.issues[0].code) === "custom") {
|
|
28
|
-
|
|
28
|
+
// Named like the other validation errors, so the caller knows which field is at fault.
|
|
29
|
+
const { message: text, path } = error.issues[0];
|
|
30
|
+
const message = path.length ? `${text} at "${path.join(".")}"` : text;
|
|
29
31
|
logger.error("custom validation error", { message });
|
|
30
32
|
callback({ code: grpc_js_1.status.INVALID_ARGUMENT, message });
|
|
31
33
|
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
3
|
+
* http://github.com/fonoster/fonoster
|
|
4
|
+
*
|
|
5
|
+
* This file is part of Fonoster
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the MIT License (the "License");
|
|
8
|
+
* you may not use this file except in compliance with
|
|
9
|
+
* the License. You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* https://opensource.org/licenses/MIT
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
import { z } from "zod";
|
|
20
|
+
/**
|
|
21
|
+
* The audio filters an app may configure (voice-session, "An app's audio filters are set through
|
|
22
|
+
* the Applications API"). Apps are untrusted input, so each filter exposes a public option schema
|
|
23
|
+
* here, shared by the apiserver (validation on write) and the appbridge (the filter factory).
|
|
24
|
+
* Anything that touches the media server's filesystem, environment or credentials stays out.
|
|
25
|
+
*/
|
|
26
|
+
export declare const AI_COUSTICS_FILTER = "aiCoustics";
|
|
27
|
+
/** The ai-coustics filter's public options. */
|
|
28
|
+
export declare const aiCousticsPublicOptionsSchema: z.ZodObject<{
|
|
29
|
+
model: z.ZodDefault<z.ZodString>;
|
|
30
|
+
enhancementLevel: z.ZodDefault<z.ZodNumber>;
|
|
31
|
+
bypass: z.ZodDefault<z.ZodBoolean>;
|
|
32
|
+
}, "strict", z.ZodTypeAny, {
|
|
33
|
+
model?: string;
|
|
34
|
+
enhancementLevel?: number;
|
|
35
|
+
bypass?: boolean;
|
|
36
|
+
}, {
|
|
37
|
+
model?: string;
|
|
38
|
+
enhancementLevel?: number;
|
|
39
|
+
bypass?: boolean;
|
|
40
|
+
}>;
|
|
41
|
+
/** Public option schemas by filter name. */
|
|
42
|
+
export declare const FILTER_SCHEMAS: Record<string, z.ZodObject<z.ZodRawShape>>;
|
|
43
|
+
/** The filter a noise-cancelling (`nc`) provider runs, by provider id. */
|
|
44
|
+
export declare const FILTER_BY_PROVIDER: Record<string, string>;
|
|
45
|
+
export declare const FILTER_NAMES: string[];
|
|
46
|
+
/** The `nc` provider whose credential a filter runs with, or undefined for a filter without one. */
|
|
47
|
+
export declare function providerOfFilter(name: string): string | undefined;
|
|
48
|
+
export type AudioFilterConfig = {
|
|
49
|
+
name: string;
|
|
50
|
+
options?: Record<string, unknown>;
|
|
51
|
+
};
|
|
52
|
+
export declare const audioFilterConfigSchema: z.ZodObject<{
|
|
53
|
+
name: z.ZodString;
|
|
54
|
+
options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
55
|
+
}, "strict", z.ZodTypeAny, {
|
|
56
|
+
options?: Record<string, unknown>;
|
|
57
|
+
name?: string;
|
|
58
|
+
}, {
|
|
59
|
+
options?: Record<string, unknown>;
|
|
60
|
+
name?: string;
|
|
61
|
+
}>;
|
|
62
|
+
export declare class AudioFilterConfigError extends Error {
|
|
63
|
+
constructor(message: string);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Validates an app's `filters` list: known names and public options only. Returns the list with
|
|
67
|
+
* each filter's options as given (defaults are applied by the filter itself). Throws
|
|
68
|
+
* AudioFilterConfigError naming the first offending filter or option.
|
|
69
|
+
*/
|
|
70
|
+
export declare function parseFilters(input: unknown): AudioFilterConfig[];
|