@fonoster/autopilot 0.16.11 → 0.17.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 +13 -7
- package/dist/envs.d.ts +1 -0
- package/dist/envs.js +4 -1
- package/dist/handleVoiceRequest.js +10 -6
- package/dist/machine/actions/interruptPlayback.js +1 -1
- package/dist/machine/context.d.ts +1 -1
- package/dist/machine/context.js +1 -1
- package/dist/machine/machine.d.ts +1 -1
- package/dist/machine/types.d.ts +1 -1
- package/dist/sendConversationEndedEvent.d.ts +4 -3
- package/dist/sendConversationEndedEvent.js +4 -3
- package/dist/voice/Voice.d.ts +2 -2
- package/dist/voice/Voice.js +2 -2
- package/dist/voice/types.d.ts +1 -1
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -183,13 +183,19 @@ For example:
|
|
|
183
183
|
|
|
184
184
|
Please use the following environment variables to configure the Autopilot:
|
|
185
185
|
|
|
186
|
-
- `
|
|
187
|
-
- `
|
|
188
|
-
- `
|
|
189
|
-
- `
|
|
190
|
-
- `
|
|
191
|
-
- `
|
|
192
|
-
- `
|
|
186
|
+
- `AUTOPILOT_AWS_S3_ACCESS_KEY_ID`: The AWS S3 access key.
|
|
187
|
+
- `AUTOPILOT_AWS_S3_ENDPOINT`: The AWS S3 endpoint.
|
|
188
|
+
- `AUTOPILOT_AWS_S3_REGION`: The AWS S3 region.
|
|
189
|
+
- `AUTOPILOT_AWS_S3_SECRET_ACCESS_KEY`: The AWS S3 secret access key.
|
|
190
|
+
- `AUTOPILOT_CONVERSATION_PROVIDER`: The conversation provider.
|
|
191
|
+
- `AUTOPILOT_KNOWLEDGE_BASE_ENABLED`: Enable knowledge base powered by AWS S3 and Unstructured API.
|
|
192
|
+
- `AUTOPILOT_LOGS_FORMAT`: The logs format.
|
|
193
|
+
- `AUTOPILOT_LOGS_LEVEL`: The logs level.
|
|
194
|
+
- `AUTOPILOT_LOGS_TRANSPORT`: The logs transport.
|
|
195
|
+
- `AUTOPILOT_OPENAI_API_KEY`: The OpenAI API key needed for embeddings support.
|
|
196
|
+
- `AUTOPILOT_UNSTRUCTURED_API_KEY`: The Unstructured API key.
|
|
197
|
+
- `AUTOPILOT_UNSTRUCTURED_API_URL`: The Unstructured API URL. Default is `https://api.unstructured.com`.
|
|
198
|
+
- `AUTOPILOT_RECORDING_BASE_URL`: The recording base URL. Default is `http://localhost:9876/api/recordings`.
|
|
193
199
|
|
|
194
200
|
## What's Next
|
|
195
201
|
|
package/dist/envs.d.ts
CHANGED
package/dist/envs.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
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;
|
|
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
7
|
/**
|
|
8
8
|
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
9
9
|
* http://github.com/fonoster/fonoster
|
|
@@ -54,6 +54,9 @@ exports.INTEGRATIONS_FILE = e.AUTOPILOT_INTEGRATIONS_FILE
|
|
|
54
54
|
: "/opt/fonoster/integrations.json";
|
|
55
55
|
exports.OPENAI_API_KEY = e.AUTOPILOT_OPENAI_API_KEY;
|
|
56
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";
|
|
57
60
|
if (exports.CONVERSATION_PROVIDER.toLocaleLowerCase() !== types_1.ConversationProvider.API &&
|
|
58
61
|
exports.CONVERSATION_PROVIDER.toLocaleLowerCase() !== types_1.ConversationProvider.FILE) {
|
|
59
62
|
console.error("CONVERSATION_PROVIDER must be set to 'api' or 'file'");
|
|
@@ -66,12 +66,13 @@ const sendConversationEndedEvent_1 = require("./sendConversationEndedEvent");
|
|
|
66
66
|
const _1 = __importStar(require("."));
|
|
67
67
|
const logger = (0, logger_1.getLogger)({ service: "autopilot", filePath: __filename });
|
|
68
68
|
async function handleVoiceRequest(req, res) {
|
|
69
|
-
const { accessKeyId, callerNumber, ingressNumber,
|
|
69
|
+
const { accessKeyId, callerNumber, ingressNumber, mediaSessionRef, appRef, callRef, callDirection, metadata } = req;
|
|
70
70
|
logger.verbose("voice request", {
|
|
71
71
|
accessKeyId,
|
|
72
72
|
ingressNumber,
|
|
73
|
-
|
|
73
|
+
mediaSessionRef,
|
|
74
74
|
appRef,
|
|
75
|
+
callRef,
|
|
75
76
|
metadata
|
|
76
77
|
});
|
|
77
78
|
const assistantConfig = envs_1.CONVERSATION_PROVIDER === _1.ConversationProvider.FILE
|
|
@@ -103,7 +104,7 @@ async function handleVoiceRequest(req, res) {
|
|
|
103
104
|
knowledgeBase?.load().then(() => {
|
|
104
105
|
logger.verbose("knowledge base loaded");
|
|
105
106
|
});
|
|
106
|
-
const voice = new _1.VoiceImpl(
|
|
107
|
+
const voice = new _1.VoiceImpl(mediaSessionRef, res);
|
|
107
108
|
const languageModel = (0, createLanguageModel_1.createLanguageModel)({
|
|
108
109
|
voice,
|
|
109
110
|
assistantConfig,
|
|
@@ -138,11 +139,14 @@ async function handleVoiceRequest(req, res) {
|
|
|
138
139
|
})
|
|
139
140
|
.filter(Boolean);
|
|
140
141
|
if (assistantConfig.eventsHook?.url) {
|
|
142
|
+
// Construct recording URL: baseUrl + appRef + mediaSessionRef
|
|
143
|
+
const recordingUrl = `${envs_1.RECORDING_BASE_URL}/${appRef}_${mediaSessionRef}.wav`;
|
|
141
144
|
await (0, sendConversationEndedEvent_1.sendConversationEndedEvent)(assistantConfig.eventsHook, {
|
|
142
|
-
chatHistory: chatHistory,
|
|
143
|
-
phone: ingressNumber,
|
|
144
145
|
appRef,
|
|
145
|
-
|
|
146
|
+
callRef,
|
|
147
|
+
phone: ingressNumber,
|
|
148
|
+
chatHistory: chatHistory,
|
|
149
|
+
recordingUrl
|
|
146
150
|
});
|
|
147
151
|
}
|
|
148
152
|
});
|
|
@@ -23,7 +23,7 @@ const logger_1 = require("@fonoster/logger");
|
|
|
23
23
|
const logger = (0, logger_1.getLogger)({ service: "autopilot", filePath: __filename });
|
|
24
24
|
const interruptPlayback = async ({ context }) => {
|
|
25
25
|
logger.verbose("called the interruptPlayback action", {
|
|
26
|
-
|
|
26
|
+
mediaSessionRef: context.mediaSessionRef
|
|
27
27
|
});
|
|
28
28
|
await context.voice.stopSpeech();
|
|
29
29
|
};
|
package/dist/machine/context.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.context = void 0;
|
|
4
4
|
const context = ({ input }) => ({
|
|
5
|
-
|
|
5
|
+
mediaSessionRef: input.voice.mediaSessionRef,
|
|
6
6
|
voice: input.voice,
|
|
7
7
|
languageModel: input.languageModel,
|
|
8
8
|
speechBuffer: "",
|
|
@@ -71,7 +71,7 @@ declare const machine: import("xstate").StateMachine<any, import("./types").Auto
|
|
|
71
71
|
conversationSettings: import("..").ConversationSettings;
|
|
72
72
|
};
|
|
73
73
|
}) => {
|
|
74
|
-
|
|
74
|
+
mediaSessionRef: string;
|
|
75
75
|
voice: import("..").Voice;
|
|
76
76
|
languageModel: import("..").LanguageModel;
|
|
77
77
|
speechBuffer: string;
|
package/dist/machine/types.d.ts
CHANGED
|
@@ -23,8 +23,9 @@ export type EventsHook = {
|
|
|
23
23
|
headers?: Record<string, string>;
|
|
24
24
|
};
|
|
25
25
|
export declare function sendConversationEndedEvent(eventsHook: EventsHook, data: {
|
|
26
|
-
chatHistory: Record<string, string>[];
|
|
27
|
-
phone: string;
|
|
28
26
|
appRef: string;
|
|
29
|
-
|
|
27
|
+
callRef: string;
|
|
28
|
+
phone: string;
|
|
29
|
+
chatHistory: Record<string, string>[];
|
|
30
|
+
recordingUrl: string;
|
|
30
31
|
}): Promise<void>;
|
|
@@ -23,7 +23,7 @@ const common_1 = require("@fonoster/common");
|
|
|
23
23
|
const logger_1 = require("@fonoster/logger");
|
|
24
24
|
const logger = (0, logger_1.getLogger)({ service: "autopilot", filePath: __filename });
|
|
25
25
|
async function sendConversationEndedEvent(eventsHook, data) {
|
|
26
|
-
const { chatHistory, phone, appRef,
|
|
26
|
+
const { chatHistory, phone, appRef, callRef, recordingUrl } = data;
|
|
27
27
|
if (!eventsHook?.events.includes(common_1.EventsHookAllowedEvents.CONVERSATION_ENDED) &&
|
|
28
28
|
!eventsHook?.events.includes(common_1.EventsHookAllowedEvents.ALL)) {
|
|
29
29
|
return;
|
|
@@ -32,9 +32,10 @@ async function sendConversationEndedEvent(eventsHook, data) {
|
|
|
32
32
|
const params = {
|
|
33
33
|
eventType: common_1.EventsHookAllowedEvents.CONVERSATION_ENDED,
|
|
34
34
|
appRef,
|
|
35
|
-
|
|
35
|
+
callRef,
|
|
36
36
|
phone,
|
|
37
|
-
chatHistory
|
|
37
|
+
chatHistory,
|
|
38
|
+
...(recordingUrl && { recordingUrl })
|
|
38
39
|
};
|
|
39
40
|
try {
|
|
40
41
|
await (0, common_1.sendHttpRequest)({
|
package/dist/voice/Voice.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Voice } from "./types";
|
|
|
3
3
|
declare class VoiceImpl implements Voice {
|
|
4
4
|
private readonly voice;
|
|
5
5
|
private readonly playbackRef;
|
|
6
|
-
|
|
6
|
+
mediaSessionRef: string;
|
|
7
7
|
sgatherStream: {
|
|
8
8
|
stop: () => Promise<void>;
|
|
9
9
|
onData: (cb: (payload: {
|
|
@@ -15,7 +15,7 @@ declare class VoiceImpl implements Voice {
|
|
|
15
15
|
stop: () => Promise<void>;
|
|
16
16
|
onData: (cb: (chunk: Uint8Array) => void) => void;
|
|
17
17
|
};
|
|
18
|
-
constructor(
|
|
18
|
+
constructor(mediaSessionRef: string, voice: VoiceResponse);
|
|
19
19
|
answer(): Promise<void>;
|
|
20
20
|
hangup(): Promise<void>;
|
|
21
21
|
say(text: string): Promise<void>;
|
package/dist/voice/Voice.js
CHANGED
|
@@ -22,9 +22,9 @@ exports.VoiceImpl = void 0;
|
|
|
22
22
|
const common_1 = require("@fonoster/common");
|
|
23
23
|
const uuid_1 = require("uuid");
|
|
24
24
|
class VoiceImpl {
|
|
25
|
-
constructor(
|
|
25
|
+
constructor(mediaSessionRef, voice) {
|
|
26
26
|
this.voice = voice;
|
|
27
|
-
this.
|
|
27
|
+
this.mediaSessionRef = mediaSessionRef;
|
|
28
28
|
this.playbackRef = (0, uuid_1.v4)();
|
|
29
29
|
}
|
|
30
30
|
async answer() {
|
package/dist/voice/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fonoster/autopilot",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.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",
|
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@aws-sdk/client-s3": "^3.958.0",
|
|
37
37
|
"@dmitryrechkin/json-schema-to-zod": "^1.0.1",
|
|
38
|
-
"@fonoster/common": "^0.
|
|
39
|
-
"@fonoster/logger": "^0.
|
|
40
|
-
"@fonoster/sdk": "^0.
|
|
41
|
-
"@fonoster/types": "^0.
|
|
42
|
-
"@fonoster/voice": "^0.
|
|
38
|
+
"@fonoster/common": "^0.17.0",
|
|
39
|
+
"@fonoster/logger": "^0.17.0",
|
|
40
|
+
"@fonoster/sdk": "^0.17.0",
|
|
41
|
+
"@fonoster/types": "^0.17.0",
|
|
42
|
+
"@fonoster/voice": "^0.17.0",
|
|
43
43
|
"@langchain/anthropic": "^1.3.3",
|
|
44
44
|
"@langchain/community": "^1.1.1",
|
|
45
45
|
"@langchain/core": "^1.1.8",
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"xstate": "^5.17.3",
|
|
60
60
|
"zod": "^3.25.76"
|
|
61
61
|
},
|
|
62
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "4d1a9afaec6f294184386e009d1a4e292fb3583b"
|
|
63
63
|
}
|