@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
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.ENDED_CAUSES = exports.SESSION_EVENT_TYPES = exports.NODE_MESSAGE_TYPES = exports.APP_MESSAGE_TYPES = exports.SESSION_SERVICE_NAME = exports.SESSION_PORT = exports.SESSION_PROTO = void 0;
|
|
37
|
+
exports.messageType = messageType;
|
|
38
|
+
exports.sessionPackage = sessionPackage;
|
|
39
|
+
exports.sessionService = sessionService;
|
|
40
|
+
exports.sessionClient = sessionClient;
|
|
41
|
+
/**
|
|
42
|
+
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
43
|
+
* http://github.com/fonoster/fonoster
|
|
44
|
+
*
|
|
45
|
+
* This file is part of Fonoster
|
|
46
|
+
*
|
|
47
|
+
* Licensed under the MIT License (the "License");
|
|
48
|
+
* you may not use this file except in compliance with
|
|
49
|
+
* the License. You may obtain a copy of the License at
|
|
50
|
+
*
|
|
51
|
+
* https://opensource.org/licenses/MIT
|
|
52
|
+
*
|
|
53
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
54
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
55
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
56
|
+
* See the License for the specific language governing permissions and
|
|
57
|
+
* limitations under the License.
|
|
58
|
+
*/
|
|
59
|
+
const path = __importStar(require("path"));
|
|
60
|
+
const grpc = __importStar(require("@grpc/grpc-js"));
|
|
61
|
+
const protoLoader = __importStar(require("@grpc/proto-loader"));
|
|
62
|
+
// The per-call control stream (session.v1.Session, redesign-roomr media-control "Each call opens
|
|
63
|
+
// one control stream to the session endpoint"). The Roomr node is the client: it opens one
|
|
64
|
+
// connection per call and sends Start first; the session endpoint (AppBridge) answers with
|
|
65
|
+
// Answer, Ready or Reject and sends the app's commands. Audio never travels here. The proto is
|
|
66
|
+
// fonoster/roomr's api/session/v1/session.proto; src/protos/session.proto is the copy of the
|
|
67
|
+
// pinned release (npm run sync:roomr; the client test checks it).
|
|
68
|
+
/** The proto file this module loads. */
|
|
69
|
+
exports.SESSION_PROTO = path.join(__dirname, "..", "protos", "session.proto");
|
|
70
|
+
/** The port AppBridge serves Session.Connect (and grpc.health.v1) on by default. */
|
|
71
|
+
exports.SESSION_PORT = 50071;
|
|
72
|
+
/** The gRPC service name, as the health service reports it. */
|
|
73
|
+
exports.SESSION_SERVICE_NAME = "session.v1.Session";
|
|
74
|
+
/** The member a message carries (the oneof's name), for logs and fakes. */
|
|
75
|
+
function messageType(message, members) {
|
|
76
|
+
if (typeof message.msg === "string")
|
|
77
|
+
return message.msg;
|
|
78
|
+
return members.find((m) => message[m] !== undefined && message[m] !== null);
|
|
79
|
+
}
|
|
80
|
+
exports.APP_MESSAGE_TYPES = [
|
|
81
|
+
"answer",
|
|
82
|
+
"ready",
|
|
83
|
+
"reject",
|
|
84
|
+
"transfer",
|
|
85
|
+
"transferComplete",
|
|
86
|
+
"hold",
|
|
87
|
+
"resume",
|
|
88
|
+
"sendDtmf",
|
|
89
|
+
"addListener",
|
|
90
|
+
"removeListener",
|
|
91
|
+
"hangup"
|
|
92
|
+
];
|
|
93
|
+
exports.NODE_MESSAGE_TYPES = ["start", "dtmf", "event"];
|
|
94
|
+
exports.SESSION_EVENT_TYPES = [
|
|
95
|
+
"participantJoined",
|
|
96
|
+
"participantLeft",
|
|
97
|
+
"transferResult",
|
|
98
|
+
"ended"
|
|
99
|
+
];
|
|
100
|
+
/** Ended causes the node sends (media-control "Endings carry a reason"). */
|
|
101
|
+
exports.ENDED_CAUSES = [
|
|
102
|
+
"caller_hangup",
|
|
103
|
+
"callee_hangup",
|
|
104
|
+
"busy",
|
|
105
|
+
"no_answer",
|
|
106
|
+
"rejected",
|
|
107
|
+
"media_timeout",
|
|
108
|
+
"node_error",
|
|
109
|
+
"max_duration",
|
|
110
|
+
"removed",
|
|
111
|
+
"app_gone"
|
|
112
|
+
];
|
|
113
|
+
let loaded;
|
|
114
|
+
/** The session.v1 package (protoLoader options as for the other Fonoster services). */
|
|
115
|
+
function sessionPackage() {
|
|
116
|
+
loaded !== null && loaded !== void 0 ? loaded : (loaded = grpc.loadPackageDefinition(protoLoader.loadSync(exports.SESSION_PROTO, {
|
|
117
|
+
keepCase: false,
|
|
118
|
+
longs: Number,
|
|
119
|
+
enums: String,
|
|
120
|
+
defaults: true,
|
|
121
|
+
oneofs: true
|
|
122
|
+
})));
|
|
123
|
+
return loaded.session.v1;
|
|
124
|
+
}
|
|
125
|
+
/** The Session service definition (AppBridge serves it). */
|
|
126
|
+
function sessionService() {
|
|
127
|
+
return sessionPackage().Session.service;
|
|
128
|
+
}
|
|
129
|
+
/** The Session client constructor (the node's side; fakes use it). */
|
|
130
|
+
function sessionClient() {
|
|
131
|
+
return sessionPackage().Session;
|
|
132
|
+
}
|
package/dist/session/schema.d.ts
CHANGED
|
@@ -56,6 +56,9 @@ export declare const sessionStartSchema: {
|
|
|
56
56
|
readonly type: "object";
|
|
57
57
|
}];
|
|
58
58
|
};
|
|
59
|
+
readonly traceparent: {
|
|
60
|
+
readonly type: "string";
|
|
61
|
+
};
|
|
59
62
|
readonly audio: {
|
|
60
63
|
readonly type: "object";
|
|
61
64
|
readonly required: readonly ["codec", "rate"];
|
|
@@ -118,7 +121,7 @@ export declare const sessionEndSchema: {
|
|
|
118
121
|
};
|
|
119
122
|
};
|
|
120
123
|
};
|
|
121
|
-
export declare const ERROR_CODES: readonly ["bad_message", "unknown_command", "read_only", "not_supported_by_protocol", "provider_unavailable", "provider_timeout", "invalid_catalog_id", "feature_not_supported", "transfer_failed", "on_hold", "queue_full", "play_fetch_failed", "internal"];
|
|
124
|
+
export declare const ERROR_CODES: readonly ["bad_message", "unknown_command", "read_only", "not_supported_by_protocol", "provider_unavailable", "provider_timeout", "invalid_catalog_id", "feature_not_supported", "transfer_failed", "transfer_not_answered", "on_hold", "queue_full", "play_fetch_failed", "key_unavailable", "internal"];
|
|
122
125
|
export declare const errorSchema: {
|
|
123
126
|
readonly type: "object";
|
|
124
127
|
readonly required: readonly ["type", "code", "message", "fatal"];
|
|
@@ -328,7 +331,22 @@ export declare const dtmfEventSchema: {
|
|
|
328
331
|
};
|
|
329
332
|
};
|
|
330
333
|
};
|
|
331
|
-
/**
|
|
334
|
+
/** A warm transfer's new party answered; the app may now send transfer.complete. */
|
|
335
|
+
export declare const transferAnsweredSchema: {
|
|
336
|
+
readonly type: "object";
|
|
337
|
+
readonly required: readonly ["type", "relatesTo"];
|
|
338
|
+
readonly properties: {
|
|
339
|
+
readonly type: {
|
|
340
|
+
readonly const: "transfer.answered";
|
|
341
|
+
};
|
|
342
|
+
readonly relatesTo: {
|
|
343
|
+
readonly type: "string";
|
|
344
|
+
readonly minLength: 1;
|
|
345
|
+
readonly maxLength: 128;
|
|
346
|
+
};
|
|
347
|
+
};
|
|
348
|
+
};
|
|
349
|
+
/** Answering-machine detection, once per call, for apps with `amd` (add-roomr 4.3). */
|
|
332
350
|
export declare const amdResultSchema: {
|
|
333
351
|
readonly type: "object";
|
|
334
352
|
readonly required: readonly ["type", "status", "confidence", "detector", "audioMs"];
|
|
@@ -630,6 +648,54 @@ export declare const handoffSchema: {
|
|
|
630
648
|
};
|
|
631
649
|
};
|
|
632
650
|
};
|
|
651
|
+
/**
|
|
652
|
+
* Model token usage from Fonoster's own Autopilot (add-usage-metering D4). Reserved like
|
|
653
|
+
* record.note: accepted only from Autopilot agents and left out of the public docs.
|
|
654
|
+
*/
|
|
655
|
+
export declare const usageReportSchema: {
|
|
656
|
+
readonly type: "object";
|
|
657
|
+
readonly required: readonly ["type", "lines"];
|
|
658
|
+
readonly properties: {
|
|
659
|
+
readonly type: {
|
|
660
|
+
readonly const: "usage.report";
|
|
661
|
+
};
|
|
662
|
+
readonly id: {
|
|
663
|
+
readonly type: "string";
|
|
664
|
+
readonly minLength: 1;
|
|
665
|
+
readonly maxLength: 128;
|
|
666
|
+
};
|
|
667
|
+
readonly lines: {
|
|
668
|
+
readonly type: "array";
|
|
669
|
+
readonly minItems: 1;
|
|
670
|
+
readonly maxItems: 64;
|
|
671
|
+
readonly items: {
|
|
672
|
+
readonly type: "object";
|
|
673
|
+
readonly required: readonly ["meter", "quantity", "provider", "keySource"];
|
|
674
|
+
readonly additionalProperties: false;
|
|
675
|
+
readonly properties: {
|
|
676
|
+
readonly meter: {
|
|
677
|
+
readonly enum: readonly ["llm.tokens.in", "llm.tokens.out", "llm.tokens.cached", "embedding.tokens"];
|
|
678
|
+
};
|
|
679
|
+
readonly quantity: {
|
|
680
|
+
readonly type: "integer";
|
|
681
|
+
readonly minimum: 0;
|
|
682
|
+
};
|
|
683
|
+
readonly provider: {
|
|
684
|
+
readonly type: "string";
|
|
685
|
+
readonly minLength: 1;
|
|
686
|
+
};
|
|
687
|
+
readonly model: {
|
|
688
|
+
readonly type: "string";
|
|
689
|
+
readonly minLength: 1;
|
|
690
|
+
};
|
|
691
|
+
readonly keySource: {
|
|
692
|
+
readonly enum: readonly ["platform", "workspace"];
|
|
693
|
+
};
|
|
694
|
+
};
|
|
695
|
+
};
|
|
696
|
+
};
|
|
697
|
+
};
|
|
698
|
+
};
|
|
633
699
|
export declare const recordNoteSchema: {
|
|
634
700
|
readonly type: "object";
|
|
635
701
|
readonly required: readonly ["type", "data"];
|
|
@@ -665,6 +731,7 @@ export type OutputInterrupted = FromSchema<typeof outputInterruptedSchema>;
|
|
|
665
731
|
export type MarkEvent = FromSchema<typeof markEventSchema>;
|
|
666
732
|
export type DtmfEvent = FromSchema<typeof dtmfEventSchema>;
|
|
667
733
|
export type AmdResult = FromSchema<typeof amdResultSchema>;
|
|
734
|
+
export type TransferAnswered = FromSchema<typeof transferAnsweredSchema>;
|
|
668
735
|
export type Speak = FromSchema<typeof speakSchema>;
|
|
669
736
|
export type Play = FromSchema<typeof playSchema>;
|
|
670
737
|
export type ListenUpdate = FromSchema<typeof listenUpdateSchema>;
|
|
@@ -680,10 +747,10 @@ export type Hold = FromSchema<typeof holdSchema>;
|
|
|
680
747
|
export type Resume = FromSchema<typeof resumeSchema>;
|
|
681
748
|
export type Handoff = FromSchema<typeof handoffSchema>;
|
|
682
749
|
export type RecordNote = FromSchema<typeof recordNoteSchema>;
|
|
683
|
-
export type
|
|
750
|
+
export type AppBridgeMessage = SessionStart | SessionEnd | SessionError | TurnUserStarted | TurnLikelyEnded | TurnEnded | TurnResumed | TurnBackchannel | TurnEstimate | TranscriptPartial | OutputStarted | OutputDone | OutputInterrupted | MarkEvent | DtmfEvent | TransferAnswered | AmdResult;
|
|
684
751
|
export type AppCommand = Speak | Play | ListenUpdate | Subscribe | MarkCommand | Clear | Hangup | DtmfSend | Transfer | TransferComplete | Hold | Resume | Handoff | RecordNote;
|
|
685
752
|
/** Schemas by message type, per direction. "mark" exists in both directions. */
|
|
686
|
-
export declare const
|
|
753
|
+
export declare const APPBRIDGE_MESSAGE_SCHEMAS: {
|
|
687
754
|
readonly "session.start": {
|
|
688
755
|
readonly type: "object";
|
|
689
756
|
readonly required: readonly ["type", "protocol", "sessionRef", "callRef", "appRef", "direction", "from", "to", "metadata", "handoff", "audio", "tracks", "speech"];
|
|
@@ -722,6 +789,9 @@ export declare const GATEWAY_MESSAGE_SCHEMAS: {
|
|
|
722
789
|
readonly type: "object";
|
|
723
790
|
}];
|
|
724
791
|
};
|
|
792
|
+
readonly traceparent: {
|
|
793
|
+
readonly type: "string";
|
|
794
|
+
};
|
|
725
795
|
readonly audio: {
|
|
726
796
|
readonly type: "object";
|
|
727
797
|
readonly required: readonly ["codec", "rate"];
|
|
@@ -992,6 +1062,20 @@ export declare const GATEWAY_MESSAGE_SCHEMAS: {
|
|
|
992
1062
|
};
|
|
993
1063
|
};
|
|
994
1064
|
};
|
|
1065
|
+
readonly "transfer.answered": {
|
|
1066
|
+
readonly type: "object";
|
|
1067
|
+
readonly required: readonly ["type", "relatesTo"];
|
|
1068
|
+
readonly properties: {
|
|
1069
|
+
readonly type: {
|
|
1070
|
+
readonly const: "transfer.answered";
|
|
1071
|
+
};
|
|
1072
|
+
readonly relatesTo: {
|
|
1073
|
+
readonly type: "string";
|
|
1074
|
+
readonly minLength: 1;
|
|
1075
|
+
readonly maxLength: 128;
|
|
1076
|
+
};
|
|
1077
|
+
};
|
|
1078
|
+
};
|
|
995
1079
|
readonly "amd.result": {
|
|
996
1080
|
readonly type: "object";
|
|
997
1081
|
readonly required: readonly ["type", "status", "confidence", "detector", "audioMs"];
|
|
@@ -1310,9 +1394,53 @@ export declare const APP_COMMAND_SCHEMAS: {
|
|
|
1310
1394
|
};
|
|
1311
1395
|
};
|
|
1312
1396
|
};
|
|
1397
|
+
readonly "usage.report": {
|
|
1398
|
+
readonly type: "object";
|
|
1399
|
+
readonly required: readonly ["type", "lines"];
|
|
1400
|
+
readonly properties: {
|
|
1401
|
+
readonly type: {
|
|
1402
|
+
readonly const: "usage.report";
|
|
1403
|
+
};
|
|
1404
|
+
readonly id: {
|
|
1405
|
+
readonly type: "string";
|
|
1406
|
+
readonly minLength: 1;
|
|
1407
|
+
readonly maxLength: 128;
|
|
1408
|
+
};
|
|
1409
|
+
readonly lines: {
|
|
1410
|
+
readonly type: "array";
|
|
1411
|
+
readonly minItems: 1;
|
|
1412
|
+
readonly maxItems: 64;
|
|
1413
|
+
readonly items: {
|
|
1414
|
+
readonly type: "object";
|
|
1415
|
+
readonly required: readonly ["meter", "quantity", "provider", "keySource"];
|
|
1416
|
+
readonly additionalProperties: false;
|
|
1417
|
+
readonly properties: {
|
|
1418
|
+
readonly meter: {
|
|
1419
|
+
readonly enum: readonly ["llm.tokens.in", "llm.tokens.out", "llm.tokens.cached", "embedding.tokens"];
|
|
1420
|
+
};
|
|
1421
|
+
readonly quantity: {
|
|
1422
|
+
readonly type: "integer";
|
|
1423
|
+
readonly minimum: 0;
|
|
1424
|
+
};
|
|
1425
|
+
readonly provider: {
|
|
1426
|
+
readonly type: "string";
|
|
1427
|
+
readonly minLength: 1;
|
|
1428
|
+
};
|
|
1429
|
+
readonly model: {
|
|
1430
|
+
readonly type: "string";
|
|
1431
|
+
readonly minLength: 1;
|
|
1432
|
+
};
|
|
1433
|
+
readonly keySource: {
|
|
1434
|
+
readonly enum: readonly ["platform", "workspace"];
|
|
1435
|
+
};
|
|
1436
|
+
};
|
|
1437
|
+
};
|
|
1438
|
+
};
|
|
1439
|
+
};
|
|
1440
|
+
};
|
|
1313
1441
|
};
|
|
1314
1442
|
export type AppCommandType = keyof typeof APP_COMMAND_SCHEMAS;
|
|
1315
|
-
export type
|
|
1443
|
+
export type AppBridgeMessageType = keyof typeof APPBRIDGE_MESSAGE_SCHEMAS;
|
|
1316
1444
|
/** The whole protocol as one JSON Schema document, as exported to schema/session.v1.json. */
|
|
1317
1445
|
export declare function sessionProtocolDocument(): {
|
|
1318
1446
|
$schema: string;
|
|
@@ -1320,7 +1448,7 @@ export declare function sessionProtocolDocument(): {
|
|
|
1320
1448
|
title: string;
|
|
1321
1449
|
description: string;
|
|
1322
1450
|
protocol: string;
|
|
1323
|
-
|
|
1451
|
+
appBridgeToApp: {
|
|
1324
1452
|
readonly "session.start": {
|
|
1325
1453
|
readonly type: "object";
|
|
1326
1454
|
readonly required: readonly ["type", "protocol", "sessionRef", "callRef", "appRef", "direction", "from", "to", "metadata", "handoff", "audio", "tracks", "speech"];
|
|
@@ -1359,6 +1487,9 @@ export declare function sessionProtocolDocument(): {
|
|
|
1359
1487
|
readonly type: "object";
|
|
1360
1488
|
}];
|
|
1361
1489
|
};
|
|
1490
|
+
readonly traceparent: {
|
|
1491
|
+
readonly type: "string";
|
|
1492
|
+
};
|
|
1362
1493
|
readonly audio: {
|
|
1363
1494
|
readonly type: "object";
|
|
1364
1495
|
readonly required: readonly ["codec", "rate"];
|
|
@@ -1629,6 +1760,20 @@ export declare function sessionProtocolDocument(): {
|
|
|
1629
1760
|
};
|
|
1630
1761
|
};
|
|
1631
1762
|
};
|
|
1763
|
+
readonly "transfer.answered": {
|
|
1764
|
+
readonly type: "object";
|
|
1765
|
+
readonly required: readonly ["type", "relatesTo"];
|
|
1766
|
+
readonly properties: {
|
|
1767
|
+
readonly type: {
|
|
1768
|
+
readonly const: "transfer.answered";
|
|
1769
|
+
};
|
|
1770
|
+
readonly relatesTo: {
|
|
1771
|
+
readonly type: "string";
|
|
1772
|
+
readonly minLength: 1;
|
|
1773
|
+
readonly maxLength: 128;
|
|
1774
|
+
};
|
|
1775
|
+
};
|
|
1776
|
+
};
|
|
1632
1777
|
readonly "amd.result": {
|
|
1633
1778
|
readonly type: "object";
|
|
1634
1779
|
readonly required: readonly ["type", "status", "confidence", "detector", "audioMs"];
|
|
@@ -1664,7 +1809,7 @@ export declare function sessionProtocolDocument(): {
|
|
|
1664
1809
|
};
|
|
1665
1810
|
};
|
|
1666
1811
|
};
|
|
1667
|
-
|
|
1812
|
+
appToAppBridge: {
|
|
1668
1813
|
readonly speak: {
|
|
1669
1814
|
readonly type: "object";
|
|
1670
1815
|
readonly required: readonly ["type", "text"];
|
|
@@ -1947,5 +2092,49 @@ export declare function sessionProtocolDocument(): {
|
|
|
1947
2092
|
};
|
|
1948
2093
|
};
|
|
1949
2094
|
};
|
|
2095
|
+
readonly "usage.report": {
|
|
2096
|
+
readonly type: "object";
|
|
2097
|
+
readonly required: readonly ["type", "lines"];
|
|
2098
|
+
readonly properties: {
|
|
2099
|
+
readonly type: {
|
|
2100
|
+
readonly const: "usage.report";
|
|
2101
|
+
};
|
|
2102
|
+
readonly id: {
|
|
2103
|
+
readonly type: "string";
|
|
2104
|
+
readonly minLength: 1;
|
|
2105
|
+
readonly maxLength: 128;
|
|
2106
|
+
};
|
|
2107
|
+
readonly lines: {
|
|
2108
|
+
readonly type: "array";
|
|
2109
|
+
readonly minItems: 1;
|
|
2110
|
+
readonly maxItems: 64;
|
|
2111
|
+
readonly items: {
|
|
2112
|
+
readonly type: "object";
|
|
2113
|
+
readonly required: readonly ["meter", "quantity", "provider", "keySource"];
|
|
2114
|
+
readonly additionalProperties: false;
|
|
2115
|
+
readonly properties: {
|
|
2116
|
+
readonly meter: {
|
|
2117
|
+
readonly enum: readonly ["llm.tokens.in", "llm.tokens.out", "llm.tokens.cached", "embedding.tokens"];
|
|
2118
|
+
};
|
|
2119
|
+
readonly quantity: {
|
|
2120
|
+
readonly type: "integer";
|
|
2121
|
+
readonly minimum: 0;
|
|
2122
|
+
};
|
|
2123
|
+
readonly provider: {
|
|
2124
|
+
readonly type: "string";
|
|
2125
|
+
readonly minLength: 1;
|
|
2126
|
+
};
|
|
2127
|
+
readonly model: {
|
|
2128
|
+
readonly type: "string";
|
|
2129
|
+
readonly minLength: 1;
|
|
2130
|
+
};
|
|
2131
|
+
readonly keySource: {
|
|
2132
|
+
readonly enum: readonly ["platform", "workspace"];
|
|
2133
|
+
};
|
|
2134
|
+
};
|
|
2135
|
+
};
|
|
2136
|
+
};
|
|
2137
|
+
};
|
|
2138
|
+
};
|
|
1950
2139
|
};
|
|
1951
2140
|
};
|
package/dist/session/schema.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.APP_COMMAND_SCHEMAS = exports.
|
|
3
|
+
exports.APP_COMMAND_SCHEMAS = exports.APPBRIDGE_MESSAGE_SCHEMAS = exports.recordNoteSchema = exports.usageReportSchema = exports.handoffSchema = exports.resumeSchema = exports.holdSchema = exports.transferCompleteSchema = exports.transferSchema = exports.TRANSFER_MODES = exports.dtmfSendSchema = exports.hangupSchema = exports.clearSchema = exports.markCommandSchema = exports.subscribeSchema = exports.SUBSCRIBABLE_EVENTS = exports.listenUpdateSchema = exports.playSchema = exports.speakSchema = exports.amdResultSchema = exports.transferAnsweredSchema = exports.dtmfEventSchema = exports.markEventSchema = exports.outputInterruptedSchema = exports.outputDoneSchema = exports.outputStartedSchema = exports.transcriptPartialSchema = exports.turnEstimateSchema = exports.turnBackchannelSchema = exports.turnResumedSchema = exports.turnEndedSchema = exports.turnLikelyEndedSchema = exports.turnUserStartedSchema = exports.errorSchema = exports.ERROR_CODES = exports.sessionEndSchema = exports.SESSION_END_REASONS = exports.sessionStartSchema = exports.SESSION_PROTOCOL = void 0;
|
|
4
4
|
exports.sessionProtocolDocument = sessionProtocolDocument;
|
|
5
5
|
// The fonoster.session.v1 messages (fonoster protocol), as JSON Schema. These schemas are the source
|
|
6
6
|
// of truth: TypeScript types are derived from them below, and schema/session.v1.json is exported
|
|
@@ -11,7 +11,7 @@ exports.sessionProtocolDocument = sessionProtocolDocument;
|
|
|
11
11
|
exports.SESSION_PROTOCOL = "fonoster.session.v1";
|
|
12
12
|
const id = { type: "string", minLength: 1, maxLength: 128 };
|
|
13
13
|
const catalogId = { type: "string", minLength: 1 };
|
|
14
|
-
// ----
|
|
14
|
+
// ---- appbridge → app ---------------------------------------------------------------------
|
|
15
15
|
exports.sessionStartSchema = {
|
|
16
16
|
type: "object",
|
|
17
17
|
required: [
|
|
@@ -40,6 +40,8 @@ exports.sessionStartSchema = {
|
|
|
40
40
|
to: { type: "string" },
|
|
41
41
|
metadata: { type: "object" },
|
|
42
42
|
handoff: { oneOf: [{ type: "null" }, { type: "object" }] },
|
|
43
|
+
// W3C traceparent of the call's span, so the app's spans join the call's trace (optional).
|
|
44
|
+
traceparent: { type: "string" },
|
|
43
45
|
audio: {
|
|
44
46
|
type: "object",
|
|
45
47
|
required: ["codec", "rate"],
|
|
@@ -95,9 +97,11 @@ exports.ERROR_CODES = [
|
|
|
95
97
|
"invalid_catalog_id",
|
|
96
98
|
"feature_not_supported",
|
|
97
99
|
"transfer_failed",
|
|
100
|
+
"transfer_not_answered",
|
|
98
101
|
"on_hold",
|
|
99
102
|
"queue_full",
|
|
100
103
|
"play_fetch_failed",
|
|
104
|
+
"key_unavailable",
|
|
101
105
|
"internal"
|
|
102
106
|
];
|
|
103
107
|
exports.errorSchema = {
|
|
@@ -204,7 +208,16 @@ exports.dtmfEventSchema = {
|
|
|
204
208
|
digit: { type: "string", pattern: "^[0-9A-D*#]$" }
|
|
205
209
|
}
|
|
206
210
|
};
|
|
207
|
-
/**
|
|
211
|
+
/** A warm transfer's new party answered; the app may now send transfer.complete. */
|
|
212
|
+
exports.transferAnsweredSchema = {
|
|
213
|
+
type: "object",
|
|
214
|
+
required: ["type", "relatesTo"],
|
|
215
|
+
properties: {
|
|
216
|
+
type: { const: "transfer.answered" },
|
|
217
|
+
relatesTo: id
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
/** Answering-machine detection, once per call, for apps with `amd` (add-roomr 4.3). */
|
|
208
221
|
exports.amdResultSchema = {
|
|
209
222
|
type: "object",
|
|
210
223
|
required: ["type", "status", "confidence", "detector", "audioMs"],
|
|
@@ -221,7 +234,7 @@ exports.amdResultSchema = {
|
|
|
221
234
|
reason: { type: "string" }
|
|
222
235
|
}
|
|
223
236
|
};
|
|
224
|
-
// ---- app →
|
|
237
|
+
// ---- app → appbridge ---------------------------------------------------------------------
|
|
225
238
|
exports.speakSchema = {
|
|
226
239
|
type: "object",
|
|
227
240
|
required: ["type", "text"],
|
|
@@ -339,6 +352,42 @@ exports.handoffSchema = {
|
|
|
339
352
|
payload: { type: "object" }
|
|
340
353
|
}
|
|
341
354
|
};
|
|
355
|
+
/**
|
|
356
|
+
* Model token usage from Fonoster's own Autopilot (add-usage-metering D4). Reserved like
|
|
357
|
+
* record.note: accepted only from Autopilot agents and left out of the public docs.
|
|
358
|
+
*/
|
|
359
|
+
exports.usageReportSchema = {
|
|
360
|
+
type: "object",
|
|
361
|
+
required: ["type", "lines"],
|
|
362
|
+
properties: {
|
|
363
|
+
type: { const: "usage.report" },
|
|
364
|
+
id,
|
|
365
|
+
lines: {
|
|
366
|
+
type: "array",
|
|
367
|
+
minItems: 1,
|
|
368
|
+
maxItems: 64,
|
|
369
|
+
items: {
|
|
370
|
+
type: "object",
|
|
371
|
+
required: ["meter", "quantity", "provider", "keySource"],
|
|
372
|
+
additionalProperties: false,
|
|
373
|
+
properties: {
|
|
374
|
+
meter: {
|
|
375
|
+
enum: [
|
|
376
|
+
"llm.tokens.in",
|
|
377
|
+
"llm.tokens.out",
|
|
378
|
+
"llm.tokens.cached",
|
|
379
|
+
"embedding.tokens"
|
|
380
|
+
]
|
|
381
|
+
},
|
|
382
|
+
quantity: { type: "integer", minimum: 0 },
|
|
383
|
+
provider: { type: "string", minLength: 1 },
|
|
384
|
+
model: { type: "string", minLength: 1 },
|
|
385
|
+
keySource: { enum: ["platform", "workspace"] }
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
};
|
|
342
391
|
exports.recordNoteSchema = {
|
|
343
392
|
type: "object",
|
|
344
393
|
required: ["type", "data"],
|
|
@@ -349,7 +398,7 @@ exports.recordNoteSchema = {
|
|
|
349
398
|
}
|
|
350
399
|
};
|
|
351
400
|
/** Schemas by message type, per direction. "mark" exists in both directions. */
|
|
352
|
-
exports.
|
|
401
|
+
exports.APPBRIDGE_MESSAGE_SCHEMAS = {
|
|
353
402
|
"session.start": exports.sessionStartSchema,
|
|
354
403
|
"session.end": exports.sessionEndSchema,
|
|
355
404
|
error: exports.errorSchema,
|
|
@@ -365,6 +414,7 @@ exports.GATEWAY_MESSAGE_SCHEMAS = {
|
|
|
365
414
|
"output.interrupted": exports.outputInterruptedSchema,
|
|
366
415
|
mark: exports.markEventSchema,
|
|
367
416
|
dtmf: exports.dtmfEventSchema,
|
|
417
|
+
"transfer.answered": exports.transferAnsweredSchema,
|
|
368
418
|
"amd.result": exports.amdResultSchema
|
|
369
419
|
};
|
|
370
420
|
exports.APP_COMMAND_SCHEMAS = {
|
|
@@ -381,7 +431,8 @@ exports.APP_COMMAND_SCHEMAS = {
|
|
|
381
431
|
hold: exports.holdSchema,
|
|
382
432
|
resume: exports.resumeSchema,
|
|
383
433
|
handoff: exports.handoffSchema,
|
|
384
|
-
"record.note": exports.recordNoteSchema
|
|
434
|
+
"record.note": exports.recordNoteSchema,
|
|
435
|
+
"usage.report": exports.usageReportSchema
|
|
385
436
|
};
|
|
386
437
|
/** The whole protocol as one JSON Schema document, as exported to schema/session.v1.json. */
|
|
387
438
|
function sessionProtocolDocument() {
|
|
@@ -391,7 +442,7 @@ function sessionProtocolDocument() {
|
|
|
391
442
|
title: exports.SESSION_PROTOCOL,
|
|
392
443
|
description: "Messages of the Fonoster session protocol (a stream with protocol fonoster). Unknown types and fields must be ignored.",
|
|
393
444
|
protocol: exports.SESSION_PROTOCOL,
|
|
394
|
-
|
|
395
|
-
|
|
445
|
+
appBridgeToApp: exports.APPBRIDGE_MESSAGE_SCHEMAS,
|
|
446
|
+
appToAppBridge: exports.APP_COMMAND_SCHEMAS
|
|
396
447
|
};
|
|
397
448
|
}
|
package/dist/sessions/index.d.ts
CHANGED
|
@@ -18,26 +18,29 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import type { KV, NatsConnection } from "nats";
|
|
20
20
|
/**
|
|
21
|
-
* The session registry (add-platform 2.3, add-
|
|
21
|
+
* The session registry (add-platform 2.3, add-roomr 3.2, decision D3): one NATS JetStream KV
|
|
22
22
|
* bucket shared by every service. Keys are `<kind>.<id>`:
|
|
23
23
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
24
|
+
* calls.<callRef> appbridge: { callRef, bridgeRef, nodeId, roomRef, direction, at }
|
|
25
|
+
* + once answered: { appRef, workspaceRef, from, to, startedAt }
|
|
26
|
+
* appbridges.<bridgeRef> retired: AppBridge no longer writes it (redesign-roomr 15.3)
|
|
27
|
+
* placements.<callRef> apiserver: { callRef, nodeRef, controlAddr, roomRef?, at }
|
|
28
|
+
* while an outbound call is being placed (CreateCall)
|
|
29
29
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
30
|
+
* Roomr nodes write nothing here (core NATS only: heartbeat and events); the control plane learns
|
|
31
|
+
* nodes from their heartbeats.
|
|
32
|
+
*
|
|
33
|
+
* The control plane reads `calls` (billing counts active calls from them). A call that loses its
|
|
34
|
+
* AppBridge mid-call is reported by its node's `call.ended` with cause `app_gone` (redesign-roomr
|
|
35
|
+
* 15.4), not by expired `appbridges` entries.
|
|
32
36
|
*
|
|
33
37
|
* Entries are leases: the bucket keeps a value for SESSIONS_TTL_MS after its last write, owners
|
|
34
|
-
* rewrite theirs every SESSIONS_REFRESH_MS, and a crashed owner's entries expire on their own.
|
|
35
|
-
* Go node uses the same bucket, TTL and key rules (go/medianode/internal/registry).
|
|
38
|
+
* rewrite theirs every SESSIONS_REFRESH_MS, and a crashed owner's entries expire on their own.
|
|
36
39
|
*/
|
|
37
40
|
export declare const SESSIONS_BUCKET = "fonoster_sessions";
|
|
38
41
|
export declare const SESSIONS_TTL_MS = 15000;
|
|
39
42
|
export declare const SESSIONS_REFRESH_MS = 5000;
|
|
40
|
-
export type SessionKind = "nodes" | "rooms" | "calls" | "
|
|
43
|
+
export type SessionKind = "nodes" | "rooms" | "calls" | "appbridges" | "placements";
|
|
41
44
|
/** `<kind>.<id>` with characters KV keys do not allow replaced by `_`. */
|
|
42
45
|
export declare const sessionKey: (kind: SessionKind, id: string) => string;
|
|
43
46
|
/** Opens the bucket, creating it when it does not exist yet. */
|
|
@@ -49,7 +52,7 @@ type Logger = {
|
|
|
49
52
|
warn(message: string): void;
|
|
50
53
|
};
|
|
51
54
|
/**
|
|
52
|
-
* An owner's entries, kept alive until deleted (
|
|
55
|
+
* An owner's entries, kept alive until deleted (AppBridge's calls and its own appbridge entry).
|
|
53
56
|
* Writes never throw: the registry is best effort and entries are rewritten on the next refresh.
|
|
54
57
|
*/
|
|
55
58
|
export declare class SessionLeases {
|