@fonoster/autopilot 0.26.0 → 0.30.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/README.md +14 -51
- package/dist/index.d.ts +0 -5
- package/dist/index.js +0 -5
- package/dist/knowledge/AbstractKnowledgeBase.d.ts +3 -2
- package/dist/knowledge/AbstractKnowledgeBase.js +2 -7
- package/dist/knowledge/FilesKnowledgeBase.d.ts +1 -1
- package/dist/knowledge/types.d.ts +1 -1
- package/dist/models/LanguageModelFactory.d.ts +5 -24
- package/dist/models/LanguageModelFactory.js +0 -1
- package/dist/models/createLanguageModel.d.ts +2 -2
- package/dist/models/evaluations/createEvalEffectiveConfig.d.ts +10 -106
- package/dist/models/evaluations/createEvalEffectiveConfig.js +47 -7
- package/dist/models/evaluations/createEvaluateIntelligence.d.ts +10 -20
- package/dist/models/evaluations/createEvaluateIntelligence.js +32 -23
- package/dist/models/evaluations/evalTestCases.d.ts +2 -2
- package/dist/models/evaluations/extractAiResponse.d.ts +2 -3
- package/dist/models/evaluations/index.d.ts +1 -0
- package/dist/models/evaluations/index.js +1 -0
- package/dist/models/evaluations/runEval.d.ts +2 -20
- package/dist/models/evaluations/session/EvalSession.d.ts +73 -0
- package/dist/models/evaluations/session/EvalSession.js +134 -0
- package/dist/models/evaluations/session/evaluateSessionScenario.d.ts +58 -0
- package/dist/models/evaluations/session/evaluateSessionScenario.js +182 -0
- package/dist/{vad → models/evaluations/session}/index.d.ts +3 -2
- package/dist/{vad → models/evaluations/session}/index.js +3 -2
- package/dist/models/evaluations/session/runSessionEval.d.ts +17 -0
- package/dist/models/evaluations/session/runSessionEval.js +59 -0
- package/dist/models/evaluations/types.d.ts +7 -6
- package/dist/models/types.d.ts +19 -1
- package/dist/session/Agent.d.ts +138 -0
- package/dist/session/Agent.js +474 -0
- package/dist/{loadAssistantFromAPI.d.ts → session/AsyncQueue.d.ts} +12 -7
- package/dist/session/AsyncQueue.js +67 -0
- package/dist/{machine/guards/index.d.ts → session/config.d.ts} +2 -2
- package/dist/session/config.js +27 -0
- package/dist/session/convertLegacyAssistant.d.ts +77 -0
- package/dist/session/convertLegacyAssistant.js +118 -0
- package/dist/session/createAutopilot.d.ts +47 -0
- package/dist/session/createAutopilot.js +119 -0
- package/dist/session/hosted.d.ts +456 -0
- package/dist/session/hosted.js +506 -0
- package/dist/{assistants → session}/index.d.ts +11 -2
- package/dist/{machine/actors → session}/index.js +11 -3
- package/dist/{machine/actions/appendSpeech.js → session/knowledge.d.ts} +14 -17
- package/dist/session/knowledge.js +10 -0
- package/dist/session/llm.d.ts +86 -0
- package/dist/session/llm.js +83 -0
- package/dist/session/machine.d.ts +206 -0
- package/dist/session/machine.js +126 -0
- package/dist/session/main.js +44 -0
- package/dist/session/sentences.d.ts +5 -0
- package/dist/session/sentences.js +53 -0
- package/dist/{machine/actors/index.d.ts → session/think.d.ts} +2 -3
- package/dist/{machine/actions/announceSystemError.js → session/think.js} +8 -10
- package/dist/session/tools.d.ts +22 -0
- package/dist/session/tools.js +83 -0
- package/dist/tools/builtin/transferToolDefinition.js +1 -1
- package/dist/voice/index.d.ts +0 -1
- package/dist/voice/index.js +0 -1
- package/dist/voice/types.d.ts +5 -18
- package/package.json +13 -14
- package/dist/Autopilot.d.ts +0 -14
- package/dist/Autopilot.js +0 -133
- package/dist/assistants/index.js +0 -36
- package/dist/assistants/loadAndValidateAssistant.d.ts +0 -3
- package/dist/assistants/loadAndValidateAssistant.js +0 -49
- package/dist/assistants/types.d.ts +0 -24
- package/dist/assistants/types.js +0 -2
- package/dist/envs.d.ts +0 -15
- package/dist/envs.js +0 -78
- package/dist/handleVoiceRequest.d.ts +0 -3
- package/dist/handleVoiceRequest.js +0 -167
- package/dist/loadAssistantConfigFromFile.d.ts +0 -3
- package/dist/loadAssistantConfigFromFile.js +0 -68
- package/dist/loadAssistantFromAPI.js +0 -98
- package/dist/machine/actions/announceSystemError.d.ts +0 -4
- package/dist/machine/actions/appendSpeech.d.ts +0 -1
- package/dist/machine/actions/cleanSpeech.d.ts +0 -1
- package/dist/machine/actions/cleanSpeech.js +0 -23
- package/dist/machine/actions/goodbye.d.ts +0 -4
- package/dist/machine/actions/goodbye.js +0 -31
- package/dist/machine/actions/increaseIdleTimeoutCount.d.ts +0 -1
- package/dist/machine/actions/increaseIdleTimeoutCount.js +0 -31
- package/dist/machine/actions/index.d.ts +0 -26
- package/dist/machine/actions/index.js +0 -37
- package/dist/machine/actions/interruptPlayback.d.ts +0 -4
- package/dist/machine/actions/interruptPlayback.js +0 -43
- package/dist/machine/actions/resetIdleTimeoutCount.d.ts +0 -1
- package/dist/machine/actions/resetIdleTimeoutCount.js +0 -31
- package/dist/machine/actions/resetState.d.ts +0 -1
- package/dist/machine/actions/resetState.js +0 -32
- package/dist/machine/actors/doAnnounceIdleTimeout.d.ts +0 -4
- package/dist/machine/actors/doAnnounceIdleTimeout.js +0 -41
- package/dist/machine/actors/doGreetUser.d.ts +0 -4
- package/dist/machine/actors/doGreetUser.js +0 -45
- package/dist/machine/actors/doProcessUserRequest.d.ts +0 -4
- package/dist/machine/actors/doProcessUserRequest.js +0 -75
- package/dist/machine/context.d.ts +0 -52
- package/dist/machine/context.js +0 -28
- package/dist/machine/delays.d.ts +0 -30
- package/dist/machine/delays.js +0 -37
- package/dist/machine/guards/hasSpeechResult.d.ts +0 -4
- package/dist/machine/guards/hasSpeechResult.js +0 -30
- package/dist/machine/guards/idleTimeoutCountExceedsMax.d.ts +0 -4
- package/dist/machine/guards/idleTimeoutCountExceedsMax.js +0 -31
- package/dist/machine/guards/index.js +0 -25
- package/dist/machine/index.d.ts +0 -19
- package/dist/machine/index.js +0 -23
- package/dist/machine/machine.d.ts +0 -408
- package/dist/machine/machine.js +0 -206
- package/dist/machine/setup.d.ts +0 -328
- package/dist/machine/setup.js +0 -116
- package/dist/machine/types.d.ts +0 -54
- package/dist/machine/types.js +0 -2
- package/dist/sendConversationEndedEvent.d.ts +0 -32
- package/dist/sendConversationEndedEvent.js +0 -66
- package/dist/sendConversationStartedEvent.d.ts +0 -6
- package/dist/sendConversationStartedEvent.js +0 -63
- package/dist/server.d.ts +0 -2
- package/dist/server.js +0 -25
- package/dist/types.d.ts +0 -40
- package/dist/types.js +0 -8
- package/dist/vad/SileroVad.d.ts +0 -18
- package/dist/vad/SileroVad.js +0 -40
- package/dist/vad/SileroVadModel.d.ts +0 -14
- package/dist/vad/SileroVadModel.js +0 -83
- package/dist/vad/chunkToFloat32Array.d.ts +0 -20
- package/dist/vad/chunkToFloat32Array.js +0 -34
- package/dist/vad/createVad.d.ts +0 -3
- package/dist/vad/createVad.js +0 -126
- package/dist/vad/types.d.ts +0 -60
- package/dist/vad/types.js +0 -2
- package/dist/vadWorker.js +0 -36
- package/dist/voice/Voice.d.ts +0 -61
- package/dist/voice/Voice.js +0 -96
- package/dist/voiceServerSetup.d.ts +0 -2
- package/dist/voiceServerSetup.js +0 -29
- /package/dist/{vadWorker.d.ts → session/main.d.ts} +0 -0
package/dist/voice/index.js
CHANGED
|
@@ -32,5 +32,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
32
32
|
* See the License for the specific language governing permissions and
|
|
33
33
|
* limitations under the License.
|
|
34
34
|
*/
|
|
35
|
-
__exportStar(require("./Voice"), exports);
|
|
36
35
|
__exportStar(require("./types"), exports);
|
package/dist/voice/types.d.ts
CHANGED
|
@@ -16,33 +16,20 @@
|
|
|
16
16
|
* See the License for the specific language governing permissions and
|
|
17
17
|
* limitations under the License.
|
|
18
18
|
*/
|
|
19
|
-
import { AudioFilterConfig } from "@fonoster/common";
|
|
20
|
-
type GatherStream = {
|
|
21
|
-
stop: () => Promise<void>;
|
|
22
|
-
onData: (cb: (payload: {
|
|
23
|
-
speech: string;
|
|
24
|
-
responseTime: number;
|
|
25
|
-
}) => void) => void;
|
|
26
|
-
};
|
|
27
|
-
type Stream = {
|
|
28
|
-
stop: () => Promise<void>;
|
|
29
|
-
onData: (cb: (chunk: Uint8Array) => void) => void;
|
|
30
|
-
};
|
|
31
19
|
type TransferOptions = {
|
|
32
20
|
timeout?: number;
|
|
33
21
|
record?: boolean;
|
|
34
22
|
};
|
|
23
|
+
/**
|
|
24
|
+
* The call controls the LangChain models' built-in tools (hangup, transfer) use. Only the
|
|
25
|
+
* evaluations (createEvaluateIntelligence) drive these models now, with a stand-in; the hosted
|
|
26
|
+
* engine in ../session talks to the session SDK instead.
|
|
27
|
+
*/
|
|
35
28
|
type Voice = {
|
|
36
|
-
mediaSessionRef: string;
|
|
37
29
|
answer: () => Promise<void>;
|
|
38
|
-
setAudioFilters: (filters: AudioFilterConfig[]) => Promise<void>;
|
|
39
30
|
hangup: () => Promise<void>;
|
|
40
31
|
say: (text: string) => Promise<void>;
|
|
41
32
|
playDtmf: (dtmf: string) => Promise<void>;
|
|
42
|
-
sgather: () => Promise<GatherStream>;
|
|
43
33
|
transfer: (destination: string, options?: TransferOptions) => Promise<void>;
|
|
44
|
-
stream: () => Promise<Stream>;
|
|
45
|
-
stopSpeech: () => Promise<void>;
|
|
46
|
-
stopStreams: () => Promise<void>;
|
|
47
34
|
};
|
|
48
35
|
export { TransferOptions, Voice };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fonoster/autopilot",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.0",
|
|
4
4
|
"description": "Voice AI for the Fonoster platform",
|
|
5
5
|
"author": "Pedro Sanders <psanders@fonoster.com>",
|
|
6
6
|
"homepage": "https://github.com/fonoster/fonoster#readme",
|
|
@@ -16,11 +16,10 @@
|
|
|
16
16
|
"build": "tsc -b tsconfig.json",
|
|
17
17
|
"clean": "rimraf ./dist node_modules tsconfig.tsbuildinfo",
|
|
18
18
|
"generate:readme": "node ../../.scripts/gen-readme.cjs",
|
|
19
|
-
"start:
|
|
19
|
+
"start:hosted": "node dist/session/main.js"
|
|
20
20
|
},
|
|
21
21
|
"files": [
|
|
22
|
-
"dist"
|
|
23
|
-
"silero_vad.onnx"
|
|
22
|
+
"dist"
|
|
24
23
|
],
|
|
25
24
|
"publishConfig": {
|
|
26
25
|
"access": "public"
|
|
@@ -35,11 +34,12 @@
|
|
|
35
34
|
"dependencies": {
|
|
36
35
|
"@aws-sdk/client-s3": "^3.958.0",
|
|
37
36
|
"@dmitryrechkin/json-schema-to-zod": "^1.0.1",
|
|
38
|
-
"@fonoster/common": "^0.
|
|
39
|
-
"@fonoster/
|
|
40
|
-
"@fonoster/
|
|
41
|
-
"@fonoster/types": "^0.
|
|
42
|
-
"@fonoster/voice": "^0.
|
|
37
|
+
"@fonoster/common": "^0.30.0",
|
|
38
|
+
"@fonoster/community": "^0.30.0",
|
|
39
|
+
"@fonoster/logger": "^0.30.0",
|
|
40
|
+
"@fonoster/types": "^0.30.0",
|
|
41
|
+
"@fonoster/voice": "^0.30.0",
|
|
42
|
+
"@grpc/grpc-js": "~1.14.6",
|
|
43
43
|
"@langchain/anthropic": "^1.3.3",
|
|
44
44
|
"@langchain/community": "^1.1.1",
|
|
45
45
|
"@langchain/core": "^1.1.8",
|
|
@@ -49,15 +49,14 @@
|
|
|
49
49
|
"@langchain/openai": "^1.2.0",
|
|
50
50
|
"@langchain/textsplitters": "^1.0.1",
|
|
51
51
|
"cheerio": "^1.1.2",
|
|
52
|
-
"dotenv": "^16.6.1",
|
|
53
52
|
"js-yaml": "^4.1.1",
|
|
54
53
|
"langchain": "^1.2.3",
|
|
55
|
-
"moment": "^2.30.1",
|
|
56
|
-
"onnxruntime-node": "1.21.1",
|
|
57
54
|
"pdf-parse": "^1.1.1",
|
|
58
|
-
"uuid": "^11.0.3",
|
|
59
55
|
"xstate": "^5.17.3",
|
|
60
56
|
"zod": "^3.25.76"
|
|
61
57
|
},
|
|
62
|
-
"gitHead": "
|
|
58
|
+
"gitHead": "b59b06a3ef325abe3f188c0fb87cc22d50ed5471",
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"yaml": "^2.9.0"
|
|
61
|
+
}
|
|
63
62
|
}
|
package/dist/Autopilot.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { AutopilotParams } from "./types";
|
|
2
|
-
declare class Autopilot {
|
|
3
|
-
private readonly params;
|
|
4
|
-
private readonly actor;
|
|
5
|
-
private vad;
|
|
6
|
-
constructor(params: AutopilotParams);
|
|
7
|
-
start(): Promise<void>;
|
|
8
|
-
stop(): void;
|
|
9
|
-
private setupAudioFilters;
|
|
10
|
-
private setupVoiceStream;
|
|
11
|
-
private handleVoicePayload;
|
|
12
|
-
private setupSpeechGathering;
|
|
13
|
-
}
|
|
14
|
-
export { Autopilot };
|
package/dist/Autopilot.js
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.Autopilot = void 0;
|
|
7
|
-
/**
|
|
8
|
-
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
9
|
-
* http://github.com/fonoster/fonoster
|
|
10
|
-
*
|
|
11
|
-
* This file is part of Fonoster
|
|
12
|
-
*
|
|
13
|
-
* Licensed under the MIT License (the "License");
|
|
14
|
-
* you may not use this file except in compliance with
|
|
15
|
-
* the License. You may obtain a copy of the License at
|
|
16
|
-
*
|
|
17
|
-
* https://opensource.org/licenses/MIT
|
|
18
|
-
*
|
|
19
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
20
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
21
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
22
|
-
* See the License for the specific language governing permissions and
|
|
23
|
-
* limitations under the License.
|
|
24
|
-
*/
|
|
25
|
-
const path_1 = __importDefault(require("path"));
|
|
26
|
-
const logger_1 = require("@fonoster/logger");
|
|
27
|
-
const xstate_1 = require("xstate");
|
|
28
|
-
const machine_1 = require("./machine/machine");
|
|
29
|
-
const vad_1 = require("./vad");
|
|
30
|
-
const logger = (0, logger_1.getLogger)({ service: "autopilot", filePath: __filename });
|
|
31
|
-
class Autopilot {
|
|
32
|
-
constructor(params) {
|
|
33
|
-
this.params = params;
|
|
34
|
-
const { voice, languageModel, conversationSettings } = this.params;
|
|
35
|
-
this.actor = (0, xstate_1.createActor)(machine_1.machine, {
|
|
36
|
-
input: {
|
|
37
|
-
conversationSettings,
|
|
38
|
-
languageModel,
|
|
39
|
-
voice
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
async start() {
|
|
44
|
-
await this.setupAudioFilters();
|
|
45
|
-
const vadParams = this.params.conversationSettings.vad;
|
|
46
|
-
const sileroVad = new vad_1.SileroVad({
|
|
47
|
-
pathToModel: vadParams.pathToModel ||
|
|
48
|
-
path_1.default.resolve(__dirname, "..", "silero_vad_v5.onnx"),
|
|
49
|
-
activationThreshold: vadParams.activationThreshold,
|
|
50
|
-
deactivationThreshold: vadParams.deactivationThreshold,
|
|
51
|
-
debounceFrames: vadParams.debounceFrames
|
|
52
|
-
});
|
|
53
|
-
await sileroVad.init();
|
|
54
|
-
this.vad = sileroVad;
|
|
55
|
-
await this.setupVoiceStream();
|
|
56
|
-
await this.setupSpeechGathering();
|
|
57
|
-
this.actor.start();
|
|
58
|
-
logger.verbose("autopilot is ready");
|
|
59
|
-
this.actor.subscribe((state) => {
|
|
60
|
-
logger.verbose("actor's new state is", { state: state.value });
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
stop() {
|
|
64
|
-
logger.verbose("stopping autopilot");
|
|
65
|
-
this.actor.stop();
|
|
66
|
-
}
|
|
67
|
-
// Asked for before the audio stream is opened, so voice activity detection
|
|
68
|
-
// and speech recognition both see filtered audio from the first frame. A
|
|
69
|
-
// refusal is logged and the call continues unfiltered.
|
|
70
|
-
async setupAudioFilters() {
|
|
71
|
-
const { voice, audioFilters } = this.params;
|
|
72
|
-
if (!audioFilters?.length) {
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
try {
|
|
76
|
-
await voice.setAudioFilters(audioFilters);
|
|
77
|
-
logger.verbose("audio filters requested", {
|
|
78
|
-
filters: audioFilters.map((filter) => filter.name)
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
catch (err) {
|
|
82
|
-
logger.warn("could not set audio filters; continuing unfiltered", {
|
|
83
|
-
error: err?.message
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
async setupVoiceStream() {
|
|
88
|
-
const { voice } = this.params;
|
|
89
|
-
const stream = await voice.stream();
|
|
90
|
-
stream.onData(this.handleVoicePayload.bind(this));
|
|
91
|
-
}
|
|
92
|
-
handleVoicePayload(chunk) {
|
|
93
|
-
try {
|
|
94
|
-
if (!this.vad) {
|
|
95
|
-
logger.error("VAD not initialized");
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
// Process the audio chunk with the VAD directly
|
|
99
|
-
this.vad.processChunk(chunk, (event) => {
|
|
100
|
-
logger.verbose("received speech event from vad", { event });
|
|
101
|
-
if (event === "SPEECH_START") {
|
|
102
|
-
this.actor.send({ type: "SPEECH_START" });
|
|
103
|
-
}
|
|
104
|
-
else if (event === "SPEECH_END") {
|
|
105
|
-
this.actor.send({ type: "SPEECH_END" });
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
catch (err) {
|
|
110
|
-
logger.error("an error occurred while processing vad", err);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
async setupSpeechGathering() {
|
|
114
|
-
const { voice } = this.params;
|
|
115
|
-
const stream = await voice.sgather();
|
|
116
|
-
stream.onData((payload) => {
|
|
117
|
-
const { speech, responseTime } = payload;
|
|
118
|
-
logger.verbose("received speech result", {
|
|
119
|
-
event: "SPEECH_RESULT",
|
|
120
|
-
speech,
|
|
121
|
-
responseTime
|
|
122
|
-
});
|
|
123
|
-
if (payload.speech) {
|
|
124
|
-
this.actor.send({
|
|
125
|
-
type: "SPEECH_RESULT",
|
|
126
|
-
speech: payload.speech ?? "",
|
|
127
|
-
responseTime
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
exports.Autopilot = Autopilot;
|
package/dist/assistants/index.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
/**
|
|
18
|
-
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
19
|
-
* http://github.com/fonoster/fonoster
|
|
20
|
-
*
|
|
21
|
-
* This file is part of Fonoster
|
|
22
|
-
*
|
|
23
|
-
* Licensed under the MIT License (the "License");
|
|
24
|
-
* you may not use this file except in compliance with
|
|
25
|
-
* the License. You may obtain a copy of the License at
|
|
26
|
-
*
|
|
27
|
-
* https://opensource.org/licenses/MIT
|
|
28
|
-
*
|
|
29
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
30
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
31
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
32
|
-
* See the License for the specific language governing permissions and
|
|
33
|
-
* limitations under the License.
|
|
34
|
-
*/
|
|
35
|
-
__exportStar(require("./loadAndValidateAssistant"), exports);
|
|
36
|
-
__exportStar(require("./types"), exports);
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.loadAndValidateAssistant = loadAndValidateAssistant;
|
|
7
|
-
/**
|
|
8
|
-
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
9
|
-
* http://github.com/fonoster/fonoster
|
|
10
|
-
*
|
|
11
|
-
* This file is part of Fonoster
|
|
12
|
-
*
|
|
13
|
-
* Licensed under the MIT License (the "License");
|
|
14
|
-
* you may not use this file except in compliance with
|
|
15
|
-
* the License. You may obtain a copy of the License at
|
|
16
|
-
*
|
|
17
|
-
* https://opensource.org/licenses/MIT
|
|
18
|
-
*
|
|
19
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
20
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
21
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
22
|
-
* See the License for the specific language governing permissions and
|
|
23
|
-
* limitations under the License.
|
|
24
|
-
*/
|
|
25
|
-
const fs_1 = __importDefault(require("fs"));
|
|
26
|
-
const path_1 = __importDefault(require("path"));
|
|
27
|
-
const common_1 = require("@fonoster/common");
|
|
28
|
-
const logger_1 = require("@fonoster/logger");
|
|
29
|
-
const js_yaml_1 = require("js-yaml");
|
|
30
|
-
const logger = (0, logger_1.getLogger)({ service: "autopilot", filePath: __filename });
|
|
31
|
-
function loadAndValidateAssistant(assistantPath) {
|
|
32
|
-
if (!fs_1.default.existsSync(assistantPath)) {
|
|
33
|
-
logger.error("assistant file not found", { path: assistantPath });
|
|
34
|
-
process.exit(1);
|
|
35
|
-
}
|
|
36
|
-
try {
|
|
37
|
-
const fileContent = fs_1.default.readFileSync(assistantPath, "utf8");
|
|
38
|
-
const isYaml = [".yaml", ".yml"].includes(path_1.default.extname(assistantPath).toLowerCase());
|
|
39
|
-
const assistant = (isYaml ? (0, js_yaml_1.load)(fileContent) : JSON.parse(fileContent));
|
|
40
|
-
return common_1.assistantSchema.parse(assistant);
|
|
41
|
-
}
|
|
42
|
-
catch (e) {
|
|
43
|
-
logger.error("error parsing or validating assistant file", {
|
|
44
|
-
path: assistantPath,
|
|
45
|
-
error: e
|
|
46
|
-
});
|
|
47
|
-
process.exit(1);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
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 { assistantSchema, conversationSettingsSchema, languageModelConfigSchema } from "@fonoster/common";
|
|
20
|
-
import { z } from "zod";
|
|
21
|
-
type ConversationSettings = z.infer<typeof conversationSettingsSchema>;
|
|
22
|
-
type LanguageModelConfig = z.infer<typeof languageModelConfigSchema>;
|
|
23
|
-
type AssistantConfig = z.infer<typeof assistantSchema>;
|
|
24
|
-
export { AssistantConfig, ConversationSettings, LanguageModelConfig };
|
package/dist/assistants/types.js
DELETED
package/dist/envs.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export declare const AWS_S3_ACCESS_KEY_ID: string;
|
|
2
|
-
export declare const AWS_S3_ENDPOINT: string;
|
|
3
|
-
export declare const AWS_S3_REGION: string;
|
|
4
|
-
export declare const AWS_S3_SECRET_ACCESS_KEY: string;
|
|
5
|
-
export declare const KNOWLEDGE_BASE_ENABLED: boolean;
|
|
6
|
-
export declare const NODE_ENV: string;
|
|
7
|
-
export declare const UNSTRUCTURED_API_KEY: string;
|
|
8
|
-
export declare const UNSTRUCTURED_API_URL: string;
|
|
9
|
-
export declare const CONVERSATION_PROVIDER: string;
|
|
10
|
-
export declare const CONVERSATION_PROVIDER_FILE: string;
|
|
11
|
-
export declare const APISERVER_ENDPOINT: string;
|
|
12
|
-
export declare const INTEGRATIONS_FILE: string;
|
|
13
|
-
export declare const OPENAI_API_KEY: string;
|
|
14
|
-
export declare const SKIP_IDENTITY: boolean;
|
|
15
|
-
export declare const RECORDING_BASE_URL: string;
|
package/dist/envs.js
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.RECORDING_BASE_URL = exports.SKIP_IDENTITY = exports.OPENAI_API_KEY = exports.INTEGRATIONS_FILE = exports.APISERVER_ENDPOINT = exports.CONVERSATION_PROVIDER_FILE = exports.CONVERSATION_PROVIDER = exports.UNSTRUCTURED_API_URL = exports.UNSTRUCTURED_API_KEY = exports.NODE_ENV = exports.KNOWLEDGE_BASE_ENABLED = exports.AWS_S3_SECRET_ACCESS_KEY = exports.AWS_S3_REGION = exports.AWS_S3_ENDPOINT = exports.AWS_S3_ACCESS_KEY_ID = void 0;
|
|
7
|
-
/**
|
|
8
|
-
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
9
|
-
* http://github.com/fonoster/fonoster
|
|
10
|
-
*
|
|
11
|
-
* This file is part of Fonoster
|
|
12
|
-
*
|
|
13
|
-
* Licensed under the MIT License (the "License");
|
|
14
|
-
* you may not use this file except in compliance with
|
|
15
|
-
* the License. You may obtain a copy of the License at
|
|
16
|
-
*
|
|
17
|
-
* https://opensource.org/licenses/MIT
|
|
18
|
-
*
|
|
19
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
20
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
21
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
22
|
-
* See the License for the specific language governing permissions and
|
|
23
|
-
* limitations under the License.
|
|
24
|
-
*/
|
|
25
|
-
const path_1 = require("path");
|
|
26
|
-
const common_1 = require("@fonoster/common");
|
|
27
|
-
const logger_1 = __importDefault(require("@fonoster/logger"));
|
|
28
|
-
const dotenv_1 = __importDefault(require("dotenv"));
|
|
29
|
-
const types_1 = require("./types");
|
|
30
|
-
if (process.env.NODE_ENV === "development") {
|
|
31
|
-
dotenv_1.default.config({ path: (0, path_1.join)(__dirname, "..", "..", "..", ".env") });
|
|
32
|
-
}
|
|
33
|
-
const e = process.env;
|
|
34
|
-
exports.AWS_S3_ACCESS_KEY_ID = e.AUTOPILOT_AWS_S3_ACCESS_KEY_ID ?? "";
|
|
35
|
-
exports.AWS_S3_ENDPOINT = e.AUTOPILOT_AWS_S3_ENDPOINT || undefined;
|
|
36
|
-
exports.AWS_S3_REGION = e.AUTOPILOT_AWS_S3_REGION ?? "us-east-1";
|
|
37
|
-
exports.AWS_S3_SECRET_ACCESS_KEY = e.AUTOPILOT_AWS_S3_SECRET_ACCESS_KEY ?? "";
|
|
38
|
-
exports.KNOWLEDGE_BASE_ENABLED = e.AUTOPILOT_KNOWLEDGE_BASE_ENABLED === "true";
|
|
39
|
-
exports.NODE_ENV = e.NODE_ENV || "production";
|
|
40
|
-
exports.UNSTRUCTURED_API_KEY = e.AUTOPILOT_UNSTRUCTURED_API_KEY ?? "";
|
|
41
|
-
exports.UNSTRUCTURED_API_URL = e.AUTOPILOT_UNSTRUCTURED_API_URL ??
|
|
42
|
-
"https://api.unstructuredapp.io/general/v0/general";
|
|
43
|
-
exports.CONVERSATION_PROVIDER = e.AUTOPILOT_CONVERSATION_PROVIDER
|
|
44
|
-
? e.AUTOPILOT_CONVERSATION_PROVIDER
|
|
45
|
-
: types_1.ConversationProvider.FILE;
|
|
46
|
-
exports.CONVERSATION_PROVIDER_FILE = e.AUTOPILOT_CONVERSATION_PROVIDER_FILE
|
|
47
|
-
? e.AUTOPILOT_CONVERSATION_PROVIDER_FILE
|
|
48
|
-
: `${process.cwd()}/config/assistant.json`;
|
|
49
|
-
exports.APISERVER_ENDPOINT = e.AUTOPILOT_APISERVER_ENDPOINT
|
|
50
|
-
? e.AUTOPILOT_APISERVER_ENDPOINT
|
|
51
|
-
: "apiserver:50051";
|
|
52
|
-
exports.INTEGRATIONS_FILE = e.AUTOPILOT_INTEGRATIONS_FILE
|
|
53
|
-
? e.AUTOPILOT_INTEGRATIONS_FILE
|
|
54
|
-
: "/opt/fonoster/integrations.json";
|
|
55
|
-
exports.OPENAI_API_KEY = e.AUTOPILOT_OPENAI_API_KEY;
|
|
56
|
-
exports.SKIP_IDENTITY = e.AUTOPILOT_SKIP_IDENTITY === "true";
|
|
57
|
-
exports.RECORDING_BASE_URL = e.AUTOPILOT_RECORDING_BASE_URL
|
|
58
|
-
? e.AUTOPILOT_RECORDING_BASE_URL
|
|
59
|
-
: "http://localhost:9876/api/recordings";
|
|
60
|
-
if (exports.CONVERSATION_PROVIDER.toLocaleLowerCase() !== types_1.ConversationProvider.API &&
|
|
61
|
-
exports.CONVERSATION_PROVIDER.toLocaleLowerCase() !== types_1.ConversationProvider.FILE) {
|
|
62
|
-
console.error("CONVERSATION_PROVIDER must be set to 'api' or 'file'");
|
|
63
|
-
process.exit(1);
|
|
64
|
-
}
|
|
65
|
-
if (exports.CONVERSATION_PROVIDER.toLocaleLowerCase() === types_1.ConversationProvider.API) {
|
|
66
|
-
(0, common_1.assertFileExists)(exports.INTEGRATIONS_FILE);
|
|
67
|
-
}
|
|
68
|
-
if (exports.KNOWLEDGE_BASE_ENABLED) {
|
|
69
|
-
(0, common_1.assertEnvsAreSet)([
|
|
70
|
-
"AUTOPILOT_AWS_S3_ACCESS_KEY_ID",
|
|
71
|
-
"AUTOPILOT_AWS_S3_SECRET_ACCESS_KEY",
|
|
72
|
-
"AUTOPILOT_UNSTRUCTURED_API_KEY"
|
|
73
|
-
]);
|
|
74
|
-
if (!exports.AWS_S3_ENDPOINT && !exports.AWS_S3_REGION) {
|
|
75
|
-
logger_1.default.error("Knowledge base configuration error: Either AUTOPILOT_AWS_S3_ENDPOINT or AUTOPILOT_AWS_S3_REGION must be set when using AWS S3");
|
|
76
|
-
process.exit(1);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
@@ -1,167 +0,0 @@
|
|
|
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
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.handleVoiceRequest = handleVoiceRequest;
|
|
40
|
-
/**
|
|
41
|
-
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
42
|
-
* http://github.com/fonoster/fonoster
|
|
43
|
-
*
|
|
44
|
-
* This file is part of Fonoster
|
|
45
|
-
*
|
|
46
|
-
* Licensed under the MIT License (the "License");
|
|
47
|
-
* you may not use this file except in compliance with
|
|
48
|
-
* the License. You may obtain a copy of the License at
|
|
49
|
-
*
|
|
50
|
-
* https://opensource.org/licenses/MIT
|
|
51
|
-
*
|
|
52
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
53
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
54
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
55
|
-
* See the License for the specific language governing permissions and
|
|
56
|
-
* limitations under the License.
|
|
57
|
-
*/
|
|
58
|
-
const fs_1 = __importDefault(require("fs"));
|
|
59
|
-
const common_1 = require("@fonoster/common");
|
|
60
|
-
const logger_1 = require("@fonoster/logger");
|
|
61
|
-
const envs_1 = require("./envs");
|
|
62
|
-
const loadAssistantConfigFromFile_1 = require("./loadAssistantConfigFromFile");
|
|
63
|
-
const loadAssistantFromAPI_1 = require("./loadAssistantFromAPI");
|
|
64
|
-
const createLanguageModel_1 = require("./models/createLanguageModel");
|
|
65
|
-
const sendConversationEndedEvent_1 = require("./sendConversationEndedEvent");
|
|
66
|
-
const sendConversationStartedEvent_1 = require("./sendConversationStartedEvent");
|
|
67
|
-
const _1 = __importStar(require("."));
|
|
68
|
-
const logger = (0, logger_1.getLogger)({ service: "autopilot", filePath: __filename });
|
|
69
|
-
async function handleVoiceRequest(req, res) {
|
|
70
|
-
const { accessKeyId, callerNumber, ingressNumber, mediaSessionRef, appRef, callRef, callDirection, metadata, amd } = req;
|
|
71
|
-
logger.verbose("voice request", {
|
|
72
|
-
accessKeyId,
|
|
73
|
-
ingressNumber,
|
|
74
|
-
mediaSessionRef,
|
|
75
|
-
appRef,
|
|
76
|
-
callRef,
|
|
77
|
-
metadata
|
|
78
|
-
});
|
|
79
|
-
const assistantConfig = envs_1.CONVERSATION_PROVIDER === _1.ConversationProvider.FILE
|
|
80
|
-
? (0, loadAssistantConfigFromFile_1.loadAssistantConfigFromFile)(envs_1.CONVERSATION_PROVIDER_FILE)
|
|
81
|
-
: await (0, loadAssistantFromAPI_1.loadAssistantFromAPI)(req, JSON.parse(fs_1.default.readFileSync(envs_1.INTEGRATIONS_FILE, "utf8")));
|
|
82
|
-
let knowledgeBase;
|
|
83
|
-
if (envs_1.KNOWLEDGE_BASE_ENABLED) {
|
|
84
|
-
const documents = assistantConfig.languageModel?.knowledgeBase?.map((doc) => doc.document);
|
|
85
|
-
logger.verbose("loading knowledge base", {
|
|
86
|
-
documents,
|
|
87
|
-
bucket: req.accessKeyId.toLowerCase()
|
|
88
|
-
});
|
|
89
|
-
knowledgeBase = new _1.S3KnowledgeBase({
|
|
90
|
-
bucket: req.accessKeyId.toLowerCase(),
|
|
91
|
-
documents,
|
|
92
|
-
s3Config: {
|
|
93
|
-
endpoint: envs_1.AWS_S3_ENDPOINT,
|
|
94
|
-
region: envs_1.AWS_S3_REGION,
|
|
95
|
-
credentials: {
|
|
96
|
-
accessKeyId: envs_1.AWS_S3_ACCESS_KEY_ID,
|
|
97
|
-
secretAccessKey: envs_1.AWS_S3_SECRET_ACCESS_KEY
|
|
98
|
-
},
|
|
99
|
-
forcePathStyle: true
|
|
100
|
-
},
|
|
101
|
-
unstructuredAPIURL: envs_1.UNSTRUCTURED_API_URL,
|
|
102
|
-
unstructuredAPIKey: envs_1.UNSTRUCTURED_API_KEY
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
knowledgeBase?.load().then(() => {
|
|
106
|
-
logger.verbose("knowledge base loaded");
|
|
107
|
-
});
|
|
108
|
-
const voice = new _1.VoiceImpl(mediaSessionRef, res);
|
|
109
|
-
const languageModel = (0, createLanguageModel_1.createLanguageModel)({
|
|
110
|
-
voice,
|
|
111
|
-
assistantConfig,
|
|
112
|
-
knowledgeBase,
|
|
113
|
-
telephonyContext: {
|
|
114
|
-
callDirection,
|
|
115
|
-
ingressNumber,
|
|
116
|
-
callerNumber,
|
|
117
|
-
metadata
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
const { conversationSettings } = assistantConfig;
|
|
121
|
-
try {
|
|
122
|
-
const autopilot = new _1.default({
|
|
123
|
-
audioFilters: assistantConfig.audioFilters,
|
|
124
|
-
conversationSettings: conversationSettings,
|
|
125
|
-
voice: voice,
|
|
126
|
-
languageModel: languageModel
|
|
127
|
-
});
|
|
128
|
-
await autopilot.start();
|
|
129
|
-
if (assistantConfig.eventsHook?.url) {
|
|
130
|
-
await (0, sendConversationStartedEvent_1.sendConversationStartedEvent)(assistantConfig.eventsHook, {
|
|
131
|
-
appRef,
|
|
132
|
-
callRef,
|
|
133
|
-
phone: ingressNumber
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
res.on(common_1.StreamEvent.END, async () => {
|
|
137
|
-
autopilot.stop();
|
|
138
|
-
const rawChatHistory = await languageModel.getChatHistoryMessages();
|
|
139
|
-
const chatHistory = rawChatHistory
|
|
140
|
-
.map((msg) => {
|
|
141
|
-
if (msg.constructor.name === "HumanMessage") {
|
|
142
|
-
return { human: msg.content };
|
|
143
|
-
}
|
|
144
|
-
else if (msg.constructor.name === "AIMessage") {
|
|
145
|
-
return { ai: msg.content };
|
|
146
|
-
}
|
|
147
|
-
return null;
|
|
148
|
-
})
|
|
149
|
-
.filter(Boolean);
|
|
150
|
-
if (assistantConfig.eventsHook?.url) {
|
|
151
|
-
// Construct recording URL: baseUrl + appRef + mediaSessionRef
|
|
152
|
-
const recordingUrl = `${envs_1.RECORDING_BASE_URL}/${appRef}_${mediaSessionRef}.wav`;
|
|
153
|
-
await (0, sendConversationEndedEvent_1.sendConversationEndedEvent)(assistantConfig.eventsHook, {
|
|
154
|
-
appRef,
|
|
155
|
-
callRef,
|
|
156
|
-
phone: ingressNumber,
|
|
157
|
-
chatHistory: chatHistory,
|
|
158
|
-
recordingUrl,
|
|
159
|
-
amd
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
catch (error) {
|
|
165
|
-
logger.error("error handling voice request", { error });
|
|
166
|
-
}
|
|
167
|
-
}
|