@fonoster/autopilot 0.12.9 → 0.12.11
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/machine/actors/doProcessUserRequest.js +3 -2
- package/dist/machine/context.d.ts +2 -0
- package/dist/machine/context.js +3 -1
- package/dist/machine/machine.d.ts +14 -2
- package/dist/machine/machine.js +13 -3
- package/dist/machine/types.d.ts +2 -0
- package/dist/models/AbstractLanguageModel.d.ts +1 -1
- package/dist/models/AbstractLanguageModel.js +8 -1
- package/dist/models/types.d.ts +1 -1
- package/package.json +2 -2
|
@@ -25,13 +25,14 @@ const logger = (0, logger_1.getLogger)({ service: "autopilot", filePath: __filen
|
|
|
25
25
|
exports.doProcessUserRequest = (0, xstate_1.fromPromise)(async ({ input }) => {
|
|
26
26
|
const { context } = input;
|
|
27
27
|
logger.verbose("called processUserRequest actor", {
|
|
28
|
-
speechBuffer: context.speechBuffer
|
|
28
|
+
speechBuffer: context.speechBuffer,
|
|
29
|
+
isReentry: context.isReentry
|
|
29
30
|
});
|
|
30
31
|
// Stop any speech that might be playing
|
|
31
32
|
await context.voice.stopSpeech();
|
|
32
33
|
const languageModel = context.languageModel;
|
|
33
34
|
const speech = context.speechBuffer.trim();
|
|
34
|
-
const response = await languageModel.invoke(speech);
|
|
35
|
+
const response = await languageModel.invoke(speech, context.isReentry);
|
|
35
36
|
try {
|
|
36
37
|
if (response.type === "say" && !response.content) {
|
|
37
38
|
logger.warn("ignoring say response with no content");
|
package/dist/machine/context.js
CHANGED
|
@@ -20,6 +20,8 @@ const context = ({ input }) => ({
|
|
|
20
20
|
allowUserBargeIn: input.conversationSettings.allowUserBargeIn,
|
|
21
21
|
sessionStartTime: Date.now(),
|
|
22
22
|
maxSessionDuration: input.conversationSettings.maxSessionDuration,
|
|
23
|
-
initialDtmf: input.conversationSettings.initialDtmf
|
|
23
|
+
initialDtmf: input.conversationSettings.initialDtmf,
|
|
24
|
+
previousState: null,
|
|
25
|
+
isReentry: false
|
|
24
26
|
});
|
|
25
27
|
exports.context = context;
|
|
@@ -63,7 +63,7 @@ declare const machine: import("xstate").StateMachine<any, import("./types").Auto
|
|
|
63
63
|
languageModel: import("..").LanguageModel;
|
|
64
64
|
voice: import("..").Voice;
|
|
65
65
|
}, {}, import("xstate").EventObject, import("xstate").MetaObject, {
|
|
66
|
-
/** @xstate-layout
|
|
66
|
+
/** @xstate-layout N4IgpgJg5mDOIC5QDMB2BBAkgYgFQG0AGAXUVAAcB7WASwBcbLUyQAPRAWgFYBmARgB0ADi58A7CMIA2HgBYuATj4AaEAE9EPAEwDZYsQqljZQnoT18pUgL7XVaLNlaw6AQzpgBr5B4BOACgBZdAANAH0AZQBRCIjMAHkAOTCAEQBVACV0ABUExIBKbAdMIlIkECpaBiYWdgQOHiExAWktRVNRY1kVdUQ22QEtBWMxKUNLSy4uW3sMTAEoXzAwBlQobFKWSvpGZnK6viFBHgMjbSFpKSOpVQ0EBR4uAWGrNqUtLUexGZBigRoIAAbMDYCIABSiUQAwgAJSLZdAZbKbcrbap7UB1BSEZoiT5iLRCPQ8IxiW6ICQ6bEyfSEQ4GWRaH5-AHApwudyebx+fyYFIAGSiYVygSi8TS2UKLKBYBRFGoOxq+0QXFkhGeXCOCiECmxhBJXHJCD4-EEfCGfEUWjV5l4zLm-xl7LcHi8PjAAT5guFmFF4slRQdrNlfDK8qqu1qmhMAnEolERhMhK0Rr45p4AmMFy4xlEJPk9qwAkBNBcYFQNDW2UoaVgHtBEOhcIyMTS-ORJC2CvRUYQUhjQhkClkQ8Mw1kRpJ6t1YlVQ0I5j4ap4hfmJbLFarNbrvmdnLdPK9QpFYolUod648m6g1drHrlFW7keVxrTQkzYkeQmt2Las9ThDfpmfCEIo+p5gSK52L8DoAO6uDsawAGKUL4ETkMsADGAAW2Q0AAtmAlAAK50A2kKwvCiIdmGj4RkqmKIOI6pmN0Ei6p8WinEaihPE0jKEMm+iyKuAjwYhUAoWhGFgDheGESRZHghRzatu2D5os+jH1PIzyNHoozSGqaaGr0CD4i0ejyESDw5nGoniaskmoehWG4QRRGkXurrch6QShJEjaUQA6lg2Q+n6Z6BkWjmVs50lufJnl0BpT4MWwTGHO+kFiJYDxGN+KZmdaVJCDqIhWFwYxHEIonkL4lCYXAtBrHevgZGAACOxFwGREBMJ4lYAG6UAA1p4fz1Y1zVxW1HXdb1CDDY17i7KUqX0RiGXGm0OgklqZiKI0PR3GBuiCU0n4nGxInQZNDVNbALVQHNXU9S45FNlRSIbYqW0HDwJKxoDg78DmrEKEa7ECAmsgjnSdJjLdsxFlNj3Pa9C0fcpX0thEbY0V2m29uIRIftIOpqv2gGTrICixpBJwnNqgHDrY0GoJQEBwCwxRE39vYcLIjwtFIbwdOIcMnUxdMw1ZVxDDqXD6qJizLE5-M9i+HBGIMYwEvqChaIBVhCEaRtSLo+hG+Y+qzo8onBprWnbTmOhSGmYvjHDYj6ubWiWwZNvLvb0x3RepZXnFt47s76V1E06oHaB-AyFME5mVVghlQuphjI0moOQhTlSa5snuQppFx-9TG6x7g6ElIgn9v2k66pm1rmvnuXSLOonYa4azEeQ1eC8bTxi-wSiCSMRV3Ca-ACI8bsmFVVVs+HqMPTNrU7vN710KPL6WrwS8e6TUjK58PA8U0wgXIBwuXzwRvfOzQA */
|
|
67
67
|
readonly context: ({ input }: {
|
|
68
68
|
input: {
|
|
69
69
|
voice: import("..").Voice;
|
|
@@ -90,6 +90,8 @@ declare const machine: import("xstate").StateMachine<any, import("./types").Auto
|
|
|
90
90
|
sessionStartTime: number;
|
|
91
91
|
maxSessionDuration: number;
|
|
92
92
|
initialDtmf: string;
|
|
93
|
+
previousState: any;
|
|
94
|
+
isReentry: boolean;
|
|
93
95
|
};
|
|
94
96
|
readonly id: "fnAI";
|
|
95
97
|
readonly initial: "greeting";
|
|
@@ -208,7 +210,17 @@ declare const machine: import("xstate").StateMachine<any, import("./types").Auto
|
|
|
208
210
|
readonly type: "interruptPlayback";
|
|
209
211
|
}, {
|
|
210
212
|
readonly type: "appendSpeech";
|
|
211
|
-
}
|
|
213
|
+
}, import("xstate").ActionFunction<any, {
|
|
214
|
+
type: "SPEECH_RESULT";
|
|
215
|
+
speech: string;
|
|
216
|
+
responseTime: number;
|
|
217
|
+
}, import("./types").AutopilotEvents, undefined, {
|
|
218
|
+
src: "doProcessUserRequest";
|
|
219
|
+
logic: import("xstate").PromiseActorLogic<void, {
|
|
220
|
+
context: import("./types").AutopilotContext;
|
|
221
|
+
}, import("xstate").EventObject>;
|
|
222
|
+
id: string;
|
|
223
|
+
}, never, never, never, never>];
|
|
212
224
|
readonly reenter: true;
|
|
213
225
|
};
|
|
214
226
|
};
|
package/dist/machine/machine.js
CHANGED
|
@@ -20,10 +20,11 @@ exports.machine = void 0;
|
|
|
20
20
|
* limitations under the License.
|
|
21
21
|
*/
|
|
22
22
|
const xstate_1 = require("xstate");
|
|
23
|
+
const xstate_2 = require("xstate");
|
|
23
24
|
const context_1 = require("./context");
|
|
24
25
|
const setup_1 = require("./setup");
|
|
25
26
|
const machine = setup_1.machineSetup.createMachine({
|
|
26
|
-
/** @xstate-layout
|
|
27
|
+
/** @xstate-layout N4IgpgJg5mDOIC5QDMB2BBAkgYgFQG0AGAXUVAAcB7WASwBcbLUyQAPRAWgFYBmARgB0ADi58A7CMIA2HgBYuATj4AaEAE9EPAEwDZYsQqljZQnoT18pUgL7XVaLNlaw6AQzpgBr5B4BOACgBZdAANAH0AZQBRCIjMAHkAOTCAEQBVACV0ABUExIBKbAdMIlIkECpaBiYWdgQOHiExAWktRVNRY1kVdUQ22QEtBWMxKUNLSy4uW3sMTAEoXzAwBlQobFKWSvpGZnK6viFBHgMjbSFpKSOpVQ0EBR4uAWGrNqUtLUexGZBigRoIAAbMDYCIABSiUQAwgAJSLZdAZbKbcrbap7UB1BSEZoiT5iLRCPQ8IxiW6ICQ6bEyfSEQ4GWRaH5-AHApwudyebx+fyYFIAGSiYVygSi8TS2UKLKBYBRFGoOxq+0QXFkhGeXCOCiECmxhBJXHJCD4-EEfCGfEUWjV5l4zLm-xl7LcHi8PjAAT5guFmFF4slRQdrNlfDK8qqu1qmhMAnEolERhMhK0Rr45p4AmMFy4xlEJPk9qwAkBNBcYFQNDW2UoaVgHtBEOhcIyMTS-ORJC2CvRUYQUhjQhkClkQ8Mw1kRpJ6t1YlVQ0I5j4ap4hfmJbLFarNbrvmdnLdPK9QpFYolUod648m6g1drHrlFW7keVxrTQkzYkeQmt2Las9ThDfpmfCEIo+p5gSK52L8DoAO6uDsawAGKUL4ETkMsADGAAW2Q0AAtmAlAAK50A2kKwvCiIdmGj4RkqmKIOI6pmN0Ei6p8WinEaihPE0jKEMm+iyKuAjwYhUAoWhGFgDheGESRZHghRzatu2D5os+jH1PIzyNHoozSGqaaGr0CD4i0ejyESDw5nGoniaskmoehWG4QRRGkXurrch6QShJEjaUQA6lg2Q+n6Z6BkWjmVs50lufJnl0BpT4MWwTGHO+kFiJYDxGN+KZmdaVJCDqIhWFwYxHEIonkL4lCYXAtBrHevgZGAACOxFwGREBMJ4lYAG6UAA1p4fz1Y1zVxW1HXdb1CDDY17i7KUqX0RiGXGm0OgklqZiKI0PR3GBuiCU0n4nGxInQZNDVNbALVQHNXU9S45FNlRSIbYqW0HDwJKxoDg78DmrEKEa7ECAmsgjnSdJjLdsxFlNj3Pa9C0fcpX0thEbY0V2m29uIRIftIOpqv2gGTrICixpBJwnNqgHDrY0GoJQEBwCwxRE39vYcLIjwtFIbwdOIcMnUxdMw1ZVxDDqXD6qJizLE5-M9i+HBGIMYwEvqChaIBVhCEaRtSLo+hG+Y+qzo8onBprWnbTmOhSGmYvjHDYj6ubWiWwZNvLvb0x3RepZXnFt47s76V1E06oHaB-AyFME5mVVghlQuphjI0moOQhTlSa5snuQppFx-9TG6x7g6ElIgn9v2k66pm1rmvnuXSLOonYa4azEeQ1eC8bTxi-wSiCSMRV3Ca-ACI8bsmFVVVs+HqMPTNrU7vN710KPL6WrwS8e6TUjK58PA8U0wgXIBwuXzwRvfOzQA */
|
|
27
28
|
context: context_1.context,
|
|
28
29
|
id: "fnAI",
|
|
29
30
|
initial: "greeting",
|
|
@@ -122,10 +123,19 @@ const machine = setup_1.machineSetup.createMachine({
|
|
|
122
123
|
actions: [{ type: "cleanSpeech" }]
|
|
123
124
|
},
|
|
124
125
|
SPEECH_RESULT: {
|
|
125
|
-
// This makes sure result that
|
|
126
126
|
target: "processingUserRequest",
|
|
127
127
|
description: "Append speech and go back to listening.",
|
|
128
|
-
actions: [
|
|
128
|
+
actions: [
|
|
129
|
+
{ type: "interruptPlayback" },
|
|
130
|
+
{ type: "appendSpeech" },
|
|
131
|
+
(0, xstate_2.assign)(({ context, self }) => {
|
|
132
|
+
const isReentry = self.getSnapshot().value === context.previousState;
|
|
133
|
+
return {
|
|
134
|
+
previousState: self.getSnapshot().value,
|
|
135
|
+
isReentry
|
|
136
|
+
};
|
|
137
|
+
})
|
|
138
|
+
],
|
|
129
139
|
reenter: true
|
|
130
140
|
}
|
|
131
141
|
},
|
package/dist/machine/types.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ declare abstract class AbstractLanguageModel implements LanguageModel {
|
|
|
9
9
|
private readonly firstMessage;
|
|
10
10
|
private readonly transferOptions;
|
|
11
11
|
constructor(params: LanguageModelParams, voice: Voice, telephonyContext: TelephonyContext);
|
|
12
|
-
invoke(text: string): Promise<InvocationResult>;
|
|
12
|
+
invoke(text: string, isReentry: boolean): Promise<InvocationResult>;
|
|
13
13
|
getChatHistoryMessages(): Promise<import("@langchain/core/messages").BaseMessage[]>;
|
|
14
14
|
}
|
|
15
15
|
export { AbstractLanguageModel };
|
|
@@ -41,7 +41,7 @@ class AbstractLanguageModel {
|
|
|
41
41
|
});
|
|
42
42
|
this.chain = (0, createChain_1.createChain)(model, knowledgeBase, promptTemplate, this.chatHistory);
|
|
43
43
|
}
|
|
44
|
-
async invoke(text) {
|
|
44
|
+
async invoke(text, isReentry) {
|
|
45
45
|
const { chain, chatHistory, toolsCatalog } = this;
|
|
46
46
|
const response = (await chain.invoke({ text }));
|
|
47
47
|
let isFirstTool = true;
|
|
@@ -51,6 +51,13 @@ class AbstractLanguageModel {
|
|
|
51
51
|
hasTools: (response.tool_calls?.length ?? 0) > 0,
|
|
52
52
|
tools: response.tool_calls?.map((tool) => tool.name)
|
|
53
53
|
});
|
|
54
|
+
// This handles late speech recognition
|
|
55
|
+
if (isReentry) {
|
|
56
|
+
logger.verbose("xxx reentry detected, discarding last conversation turn");
|
|
57
|
+
const messages = await chatHistory.getMessages();
|
|
58
|
+
messages.pop(); // Last AI message
|
|
59
|
+
messages.pop(); // Last user message
|
|
60
|
+
}
|
|
54
61
|
// Begin the conversation with the first message
|
|
55
62
|
if ((await chatHistory.getMessages()).length === 0 && this.firstMessage) {
|
|
56
63
|
await chatHistory.addAIMessage(this.firstMessage);
|
package/dist/models/types.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ import { ToolCall } from "@langchain/core/messages/tool";
|
|
|
22
22
|
import { KnowledgeBase } from "../knowledge";
|
|
23
23
|
import { Tool } from "../tools/types";
|
|
24
24
|
type LanguageModel = {
|
|
25
|
-
invoke: (text: string) => Promise<InvocationResult>;
|
|
25
|
+
invoke: (text: string, isReentry?: boolean) => Promise<InvocationResult>;
|
|
26
26
|
};
|
|
27
27
|
type BaseModelParams = {
|
|
28
28
|
firstMessage?: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fonoster/autopilot",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.11",
|
|
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",
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"xstate": "^5.17.3",
|
|
60
60
|
"zod": "^3.23.8"
|
|
61
61
|
},
|
|
62
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "e17be36f4b161521bb87df754975f33a8a7b8aa9"
|
|
63
63
|
}
|