@fonoster/autopilot 0.12.10 → 0.12.12
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 +2 -2
- package/dist/machine/context.d.ts +2 -1
- package/dist/machine/context.js +2 -1
- package/dist/machine/delays.js +11 -1
- package/dist/machine/machine.d.ts +51 -19
- package/dist/machine/machine.js +27 -19
- package/dist/machine/types.d.ts +2 -1
- package/package.json +2 -2
|
@@ -26,13 +26,13 @@ exports.doProcessUserRequest = (0, xstate_1.fromPromise)(async ({ input }) => {
|
|
|
26
26
|
const { context } = input;
|
|
27
27
|
logger.verbose("called processUserRequest actor", {
|
|
28
28
|
speechBuffer: context.speechBuffer,
|
|
29
|
-
|
|
29
|
+
hasLateSpeech: context.hasLateSpeech
|
|
30
30
|
});
|
|
31
31
|
// Stop any speech that might be playing
|
|
32
32
|
await context.voice.stopSpeech();
|
|
33
33
|
const languageModel = context.languageModel;
|
|
34
34
|
const speech = context.speechBuffer.trim();
|
|
35
|
-
const response = await languageModel.invoke(speech, context.
|
|
35
|
+
const response = await languageModel.invoke(speech, context.hasLateSpeech);
|
|
36
36
|
try {
|
|
37
37
|
if (response.type === "say" && !response.content) {
|
|
38
38
|
logger.warn("ignoring say response with no content");
|
package/dist/machine/context.js
CHANGED
|
@@ -22,6 +22,7 @@ const context = ({ input }) => ({
|
|
|
22
22
|
maxSessionDuration: input.conversationSettings.maxSessionDuration,
|
|
23
23
|
initialDtmf: input.conversationSettings.initialDtmf,
|
|
24
24
|
previousState: null,
|
|
25
|
-
|
|
25
|
+
hasLateSpeech: false,
|
|
26
|
+
isFirstTurn: true
|
|
26
27
|
});
|
|
27
28
|
exports.context = context;
|
package/dist/machine/delays.js
CHANGED
|
@@ -21,7 +21,17 @@ exports.default = void 0;
|
|
|
21
21
|
*/
|
|
22
22
|
const delays = {
|
|
23
23
|
IDLE_TIMEOUT: ({ context }) => context.idleTimeout,
|
|
24
|
-
MAX_SPEECH_WAIT_TIMEOUT: ({ context }) =>
|
|
24
|
+
MAX_SPEECH_WAIT_TIMEOUT: ({ context }) => {
|
|
25
|
+
// If this is the first conversational turn and there is no firstMessage,
|
|
26
|
+
// use 0 timeout to avoid unnecessary delay during the intro. (Outbound calls)
|
|
27
|
+
if (context.isFirstTurn && !context.firstMessage) {
|
|
28
|
+
return 0;
|
|
29
|
+
}
|
|
30
|
+
else if (context.hasLateSpeech) {
|
|
31
|
+
return 0;
|
|
32
|
+
}
|
|
33
|
+
return context.maxSpeechWaitTimeout;
|
|
34
|
+
},
|
|
25
35
|
MAX_SESSION_DURATION: ({ context }) => context.maxSessionDuration
|
|
26
36
|
};
|
|
27
37
|
exports.default = delays;
|
|
@@ -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 N4IgpgJg5mDOIC5QDMB2BBAkgYgB6wBcBDAsAOiOVICcAKAWXQA0B9AZQFE23MB5AORYARAKoAldABU+-AJTY0WANoAGALqJQABwD2sAJYF9O1JpC5EAWgDMADgDsZFQDYATAFYAnLevuAjPYALIF+ADQgAJ6IHoFkrp5B9s6ezn6pzu7uAL5Z4YqYZFDUYGBGqFDYqhpIILoGRiZmFgh+tn5k1vYp9tauti7Obc7hUQievmQJzm5efq6uvvY5eRgF+hAANmDYbAAKHBwAwgAS7JLoYpJVZnWGxqY1zZ4qjrbuC-Z9gT3O9vYjiHstlckxcnXsKlaXUCrmWIHyZHWWzwhBI5EoNFomCEABkOCxpPQOLwRJJ5AikWBrjVbg0HqBmu5AipJu42t5PM8VNYMgCWtY-O05p4-F5XMyVIF3NY4RTNtt8MRSBQqGA6Ni8QTMESSWSFKtEfKlH5qto9HdGo9ENZArYyAF-P5fra+q4+YKFmQgv13EF-DypbKDRt9IQwKh9OVJDoRLA1Tt9kdTmIuCIcVd1DdzXSmohnLayLZnNZPIFi5zkkE+TyWZz7Ez4ipJX5mTLcvDg6HSBGozG49QUUr0ar1bj8YTiaTyZ2wz2oNHY2rqWb6vdcy1BXa-r5gYFnh56+6VMCvX4VF5uf7Pm2VlgyAB3Ih3coAMR01DYWhKAGMABaSfQAFswB0ABXAgEwOE4zguDNTVqbM1ytFoIQ6ZsgU5BZXC6YZIkQLx3ELIJXBUV0-kCIM70fZ8oDfD8vzAP8AOAsCIL2KDk1TdNlwQ1dLQZKwpUmOxviSFxmUFdw+Q+JxvilWw90WB1KIKaiylo99Px-f8gJA8DBzRFVMUYVh2KTFgAHUsEkLUdSnfUqKfdS6K0xidJY8CeNpJCBI3Wwtw+NJxl+YE3TwhBxRBbxbG8dxpji7xWhUsgtGoHRvzgAxykXagxDAABHUC4AgiATHISMADcdAAa3IBFUvSzLIygHK8sK4qEEq9KSHuKovMQ-jzEQOZ3g6QY-HGc9xjaPkLzIZk+m3ToQiCZKGoy2Aspa-s2qKwhIPMthzkufq+PpIb+R5e1rDsYtRR6SVPD5DCyCdYJnEhSFkgo9t6rSjattagq9rYxNoJTNg0zgrMzvXAIFK9CFBlLcTj2rPd7WvTpOm8Y9SxydtUB0CA4DMfIYYtc7mksQIJhcDxvF8AJgjCcKW08V65Liss5h6bxkqKEp1IpnNkMsX44krEiSxIotBj5TxXGcea-kVyVuXrXxkspEWfIu30QVSNJ4lSYIIWsBWlZVroSNbTXsl+mdu2ahd+11wbmgcFl2Wsc8BWLTJAlm1JC36Y8eWmtlkrU5qXIYpjdNY92qeGiXUiLPoPqVssg-CksOc+EIlfGewz1+B3bwKX8iHKUCtGT9dLBIwi3AFEVSMSMLRj8G72l8A3bTihKfsrlL-qa7KduB4qG+Q0VpTGwUgQyUibtmhxQ6bBSeWlRWlgJoA */
|
|
67
67
|
readonly context: ({ input }: {
|
|
68
68
|
input: {
|
|
69
69
|
voice: import("..").Voice;
|
|
@@ -91,7 +91,8 @@ declare const machine: import("xstate").StateMachine<any, import("./types").Auto
|
|
|
91
91
|
maxSessionDuration: number;
|
|
92
92
|
initialDtmf: string;
|
|
93
93
|
previousState: any;
|
|
94
|
-
|
|
94
|
+
hasLateSpeech: boolean;
|
|
95
|
+
isFirstTurn: boolean;
|
|
95
96
|
};
|
|
96
97
|
readonly id: "fnAI";
|
|
97
98
|
readonly initial: "greeting";
|
|
@@ -141,7 +142,13 @@ declare const machine: import("xstate").StateMachine<any, import("./types").Auto
|
|
|
141
142
|
readonly type: "interruptPlayback";
|
|
142
143
|
}, {
|
|
143
144
|
readonly type: "resetIdleTimeoutCount";
|
|
144
|
-
}
|
|
145
|
+
}, import("xstate").ActionFunction<any, import("./types").AutopilotEvents, import("./types").AutopilotEvents, undefined, {
|
|
146
|
+
src: "doProcessUserRequest";
|
|
147
|
+
logic: import("xstate").PromiseActorLogic<void, {
|
|
148
|
+
context: import("./types").AutopilotContext;
|
|
149
|
+
}, import("xstate").EventObject>;
|
|
150
|
+
id: string;
|
|
151
|
+
}, never, never, never, never>];
|
|
145
152
|
readonly on: {
|
|
146
153
|
readonly SPEECH_RESULT: {
|
|
147
154
|
readonly target: "waitingForSpeechTimeout";
|
|
@@ -174,10 +181,25 @@ declare const machine: import("xstate").StateMachine<any, import("./types").Auto
|
|
|
174
181
|
};
|
|
175
182
|
readonly SPEECH_RESULT: {
|
|
176
183
|
readonly target: "waitingForSpeechTimeout";
|
|
177
|
-
readonly description: "
|
|
184
|
+
readonly description: "Capture late speech, but only once.";
|
|
185
|
+
readonly guard: ({ context }: import("xstate/dist/declarations/src/guards").GuardArgs<any, {
|
|
186
|
+
type: "SPEECH_RESULT";
|
|
187
|
+
speech: string;
|
|
188
|
+
responseTime: number;
|
|
189
|
+
}>) => boolean;
|
|
178
190
|
readonly actions: readonly [{
|
|
179
191
|
readonly type: "appendSpeech";
|
|
180
|
-
}
|
|
192
|
+
}, import("xstate").ActionFunction<any, {
|
|
193
|
+
type: "SPEECH_RESULT";
|
|
194
|
+
speech: string;
|
|
195
|
+
responseTime: number;
|
|
196
|
+
}, import("./types").AutopilotEvents, undefined, {
|
|
197
|
+
src: "doProcessUserRequest";
|
|
198
|
+
logic: import("xstate").PromiseActorLogic<void, {
|
|
199
|
+
context: import("./types").AutopilotContext;
|
|
200
|
+
}, import("xstate").EventObject>;
|
|
201
|
+
id: string;
|
|
202
|
+
}, never, never, never, never>];
|
|
181
203
|
};
|
|
182
204
|
};
|
|
183
205
|
readonly after: {
|
|
@@ -205,12 +227,27 @@ declare const machine: import("xstate").StateMachine<any, import("./types").Auto
|
|
|
205
227
|
};
|
|
206
228
|
readonly SPEECH_RESULT: {
|
|
207
229
|
readonly target: "processingUserRequest";
|
|
208
|
-
readonly description: "
|
|
230
|
+
readonly description: "Capture only a single late speech across the entire request processing.";
|
|
231
|
+
readonly guard: ({ context }: import("xstate/dist/declarations/src/guards").GuardArgs<any, {
|
|
232
|
+
type: "SPEECH_RESULT";
|
|
233
|
+
speech: string;
|
|
234
|
+
responseTime: number;
|
|
235
|
+
}>) => boolean;
|
|
209
236
|
readonly actions: readonly [{
|
|
210
237
|
readonly type: "interruptPlayback";
|
|
211
238
|
}, {
|
|
212
239
|
readonly type: "appendSpeech";
|
|
213
|
-
}
|
|
240
|
+
}, import("xstate").ActionFunction<any, {
|
|
241
|
+
type: "SPEECH_RESULT";
|
|
242
|
+
speech: string;
|
|
243
|
+
responseTime: number;
|
|
244
|
+
}, import("./types").AutopilotEvents, undefined, {
|
|
245
|
+
src: "doProcessUserRequest";
|
|
246
|
+
logic: import("xstate").PromiseActorLogic<void, {
|
|
247
|
+
context: import("./types").AutopilotContext;
|
|
248
|
+
}, import("xstate").EventObject>;
|
|
249
|
+
id: string;
|
|
250
|
+
}, never, never, never, never>];
|
|
214
251
|
readonly reenter: true;
|
|
215
252
|
};
|
|
216
253
|
};
|
|
@@ -229,7 +266,13 @@ declare const machine: import("xstate").StateMachine<any, import("./types").Auto
|
|
|
229
266
|
readonly reenter: true;
|
|
230
267
|
readonly actions: readonly [{
|
|
231
268
|
readonly type: "cleanSpeech";
|
|
232
|
-
}
|
|
269
|
+
}, import("xstate").ActionFunction<any, import("xstate").DoneActorEvent<void, string>, import("./types").AutopilotEvents, undefined, {
|
|
270
|
+
src: "doProcessUserRequest";
|
|
271
|
+
logic: import("xstate").PromiseActorLogic<void, {
|
|
272
|
+
context: import("./types").AutopilotContext;
|
|
273
|
+
}, import("xstate").EventObject>;
|
|
274
|
+
id: string;
|
|
275
|
+
}, never, never, never, never>];
|
|
233
276
|
};
|
|
234
277
|
};
|
|
235
278
|
};
|
|
@@ -242,16 +285,5 @@ declare const machine: import("xstate").StateMachine<any, import("./types").Auto
|
|
|
242
285
|
};
|
|
243
286
|
};
|
|
244
287
|
};
|
|
245
|
-
readonly on: {
|
|
246
|
-
readonly "*": {
|
|
247
|
-
readonly actions: import("xstate").ActionFunction<any, import("./types").AutopilotEvents, import("./types").AutopilotEvents, undefined, {
|
|
248
|
-
src: "doProcessUserRequest";
|
|
249
|
-
logic: import("xstate").PromiseActorLogic<void, {
|
|
250
|
-
context: import("./types").AutopilotContext;
|
|
251
|
-
}, import("xstate").EventObject>;
|
|
252
|
-
id: string;
|
|
253
|
-
}, never, never, never, never>;
|
|
254
|
-
};
|
|
255
|
-
};
|
|
256
288
|
}>;
|
|
257
289
|
export { machine };
|
package/dist/machine/machine.js
CHANGED
|
@@ -24,7 +24,7 @@ const xstate_2 = require("xstate");
|
|
|
24
24
|
const context_1 = require("./context");
|
|
25
25
|
const setup_1 = require("./setup");
|
|
26
26
|
const machine = setup_1.machineSetup.createMachine({
|
|
27
|
-
/** @xstate-layout
|
|
27
|
+
/** @xstate-layout N4IgpgJg5mDOIC5QDMB2BBAkgYgB6wBcBDAsAOiOVICcAKAWXQA0B9AZQFE23MB5AORYARAKoAldABU+-AJTY0WANoAGALqJQABwD2sAJYF9O1JpC5EAWgDMADgDsZFQDYATAFYAnLevuAjPYALIF+ADQgAJ6IHoFkrp5B9s6ezn6pzu7uAL5Z4YqYZFDUYGBGqFDYqhpIILoGRiZmFgh+tn5k1vYp9tauti7Obc7hUQievmQJzm5efq6uvvY5eRgF+hAANmDYbAAKHBwAwgAS7JLoYpJVZnWGxqY1zZ4qjrbuC-Z9gT3O9vYjiHstlckxcnXsKlaXUCrmWIHyZHWWzwhBI5EoNFomCEABkOCxpPQOLwRJJ5AikWBrjVbg0HqBmu5AipJu42t5PM8VNYMgCWtY-O05p4-F5XMyVIF3NY4RTNtt8MRSBQqGA6Ni8QTMESSWSFKtEfKlH5qto9HdGo9ENZArYyAF-P5fra+q4+YKFmQgv13EF-DypbKDRt9IQwKh9OVJDoRLA1Tt9kdTmIuCIcVd1DdzXSmohnLayLZnNZPIFi5zkkE+TyWZz7Ez4ipJX5mTLcvDg6HSBGozG49QUUr0ar1bj8YTiaTyZ2wz2oNHY2rqWb6vdcy1BXa-r5gYFnh56+6VMCvX4VF5uf7Pm2VlgyAB3Ih3coAMR01DYWhKAGMABaSfQAFswB0ABXAgEwOE4zguDNTVqbM1ytFoIQ6ZsgU5BZXC6YZIkQLx3ELIJXBUV0-kCIM70fZ8oDfD8vzAP8AOAsCIL2KDk1TdNlwQ1dLQZKwpUmOxviSFxmUFdw+Q+JxvilWw90WB1KIKaiylo99Px-f8gJA8DBzRFVMUYVh2KTFgAHUsEkLUdSnfUqKfdS6K0xidJY8CeNpJCBI3Wwtw+NJxl+YE3TwhBxRBbxbG8dxpji7xWhUsgtGoHRvzgAxykXagxDAABHUC4AgiATHISMADcdAAa3IBFUvSzLIygHK8sK4qEEq9KSHuKovMQ-jzEQOZ3g6QY-HGc9xjaPkLzIZk+m3ToQiCZKGoy2Aspa-s2qKwhIPMthzkufq+PpIb+R5e1rDsYtRR6SVPD5DCyCdYJnEhSFkgo9t6rSjattagq9rYxNoJTNg0zgrMzvXAIFK9CFBlLcTj2rPd7WvTpOm8Y9SxydtUB0CA4DMfIYYtc7mksQIJhcDxvF8AJgjCcKW08V65Liss5h6bxkqKEp1IpnNkMsX44krEiSxIotBj5TxXGcea-kVyVuXrXxkspEWfIu30QVSNJ4lSYIIWsBWlZVroSNbTXsl+mdu2ahd+11wbmgcFl2Wsc8BWLTJAlm1JC36Y8eWmtlkrU5qXIYpjdNY92qeGiXUiLPoPqVssg-CksOc+EIlfGewz1+B3bwKX8iHKUCtGT9dLBIwi3AFEVSMSMLRj8G72l8A3bTihKfsrlL-qa7KduB4qG+Q0VpTGwUgQyUibtmhxQ6bBSeWlRWlgJoA */
|
|
28
28
|
context: context_1.context,
|
|
29
29
|
id: "fnAI",
|
|
30
30
|
initial: "greeting",
|
|
@@ -65,7 +65,11 @@ const machine = setup_1.machineSetup.createMachine({
|
|
|
65
65
|
}
|
|
66
66
|
},
|
|
67
67
|
listeningToUser: {
|
|
68
|
-
entry: [
|
|
68
|
+
entry: [
|
|
69
|
+
{ type: "interruptPlayback" },
|
|
70
|
+
{ type: "resetIdleTimeoutCount" },
|
|
71
|
+
(0, xstate_2.assign)({ hasLateSpeech: false })
|
|
72
|
+
],
|
|
69
73
|
on: {
|
|
70
74
|
SPEECH_RESULT: {
|
|
71
75
|
target: "waitingForSpeechTimeout",
|
|
@@ -97,8 +101,9 @@ const machine = setup_1.machineSetup.createMachine({
|
|
|
97
101
|
},
|
|
98
102
|
SPEECH_RESULT: {
|
|
99
103
|
target: "waitingForSpeechTimeout",
|
|
100
|
-
description: "
|
|
101
|
-
|
|
104
|
+
description: "Capture late speech, but only once.",
|
|
105
|
+
guard: ({ context }) => !context.hasLateSpeech,
|
|
106
|
+
actions: [{ type: "appendSpeech" }, (0, xstate_2.assign)({ hasLateSpeech: true })]
|
|
102
107
|
}
|
|
103
108
|
},
|
|
104
109
|
after: {
|
|
@@ -123,10 +128,19 @@ const machine = setup_1.machineSetup.createMachine({
|
|
|
123
128
|
actions: [{ type: "cleanSpeech" }]
|
|
124
129
|
},
|
|
125
130
|
SPEECH_RESULT: {
|
|
126
|
-
// This makes sure result that
|
|
127
131
|
target: "processingUserRequest",
|
|
128
|
-
description: "
|
|
129
|
-
|
|
132
|
+
description: "Capture only a single late speech across the entire request processing.",
|
|
133
|
+
guard: ({ context }) => !context.hasLateSpeech,
|
|
134
|
+
actions: [
|
|
135
|
+
{ type: "interruptPlayback" },
|
|
136
|
+
{ type: "appendSpeech" },
|
|
137
|
+
(0, xstate_2.assign)(({ self }) => {
|
|
138
|
+
return {
|
|
139
|
+
previousState: self.getSnapshot().value,
|
|
140
|
+
hasLateSpeech: true
|
|
141
|
+
};
|
|
142
|
+
})
|
|
143
|
+
],
|
|
130
144
|
reenter: true
|
|
131
145
|
}
|
|
132
146
|
},
|
|
@@ -137,7 +151,12 @@ const machine = setup_1.machineSetup.createMachine({
|
|
|
137
151
|
onDone: {
|
|
138
152
|
target: "listeningToUser",
|
|
139
153
|
reenter: true,
|
|
140
|
-
actions: [
|
|
154
|
+
actions: [
|
|
155
|
+
{ type: "cleanSpeech" },
|
|
156
|
+
(0, xstate_2.assign)({
|
|
157
|
+
isFirstTurn: false
|
|
158
|
+
})
|
|
159
|
+
]
|
|
141
160
|
}
|
|
142
161
|
}
|
|
143
162
|
}
|
|
@@ -147,17 +166,6 @@ const machine = setup_1.machineSetup.createMachine({
|
|
|
147
166
|
target: ".hangup",
|
|
148
167
|
actions: { type: "goodbye" }
|
|
149
168
|
}
|
|
150
|
-
},
|
|
151
|
-
on: {
|
|
152
|
-
"*": {
|
|
153
|
-
actions: (0, xstate_2.assign)(({ context, self }) => {
|
|
154
|
-
const isReentry = self.getSnapshot().value === context.previousState;
|
|
155
|
-
return {
|
|
156
|
-
previousState: self.getSnapshot().value,
|
|
157
|
-
isReentry
|
|
158
|
-
};
|
|
159
|
-
})
|
|
160
|
-
}
|
|
161
169
|
}
|
|
162
170
|
});
|
|
163
171
|
exports.machine = machine;
|
package/dist/machine/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fonoster/autopilot",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.12",
|
|
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": "47d04a2386eac6890b58bed3ff0974164ea13645"
|
|
63
63
|
}
|