@scout9/app 1.0.0-alpha.0.8.8 → 1.0.0-alpha.0.9.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/_rollupPluginBabelHelpers-9c73c95c.cjs +733 -0
- package/dist/{dev-b085bde6.cjs → dev-024a0325.cjs} +204 -203
- package/dist/{index-02973b72.cjs → index-93d877d8.cjs} +112 -112
- package/dist/index.cjs +5 -4
- package/dist/{macros-f62cceac.cjs → macros-77983cef.cjs} +4 -2
- package/dist/{multipart-parser-efb778dc.cjs → multipart-parser-593e5511.cjs} +5 -4
- package/dist/schemas.cjs +2 -1
- package/dist/spirits.cjs +1175 -2
- package/dist/testing-tools.cjs +4 -3
- package/package.json +1 -1
- package/src/public.d.ts +5 -0
- package/src/runtime/schemas/entity.js +1 -0
- package/src/testing-tools/spirits.js +67 -7
- package/types/index.d.ts +32 -27
- package/types/index.d.ts.map +1 -1
- package/dist/spirits-2d7d7919.cjs +0 -1734
package/dist/spirits.cjs
CHANGED
|
@@ -2,8 +2,1181 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _rollupPluginBabelHelpers = require("./_rollupPluginBabelHelpers-9c73c95c.cjs");
|
|
6
6
|
|
|
7
|
+
var _excluded = ["keywords"];
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {Object} Document
|
|
10
|
+
* @property {string} id
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Represents a change with before and after states of a given type.
|
|
14
|
+
* @template Type The type of the before and after properties.
|
|
15
|
+
* @typedef {Object} Change
|
|
16
|
+
* @property {Type} before - The state before the change.
|
|
17
|
+
* @property {Type} after - The state after the change.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* @typedef {Object} ConversationData
|
|
21
|
+
* @property {import('@scout9/app').Scout9ProjectBuildConfig} config - used to define generation and extract persona metadata
|
|
22
|
+
* @property {import('@scout9/app').Conversation} conversation
|
|
23
|
+
* @property {Array<import('@scout9/admin').Message>} messages
|
|
24
|
+
* @property {import('@scout9/admin').Message} message - the message sent by the customer (should exist in messages)
|
|
25
|
+
* @property {import('@scout9/app').Customer} customer
|
|
26
|
+
* @property {import('@scout9/app').ConversationProgress} progress - progress checklist for manual/auto ingress workflows
|
|
27
|
+
* @property {any} context - event context
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* @typedef {Object} ParseOutput
|
|
31
|
+
* @property {Array<import('@scout9/admin').Message>} messages
|
|
32
|
+
* @property {import('@scout9/app').Conversation} conversation
|
|
33
|
+
* @property {import('@scout9/admin').Message} message
|
|
34
|
+
* @property {any} context
|
|
35
|
+
*/
|
|
36
|
+
/**
|
|
37
|
+
* @typedef {Object} WorkflowOutput
|
|
38
|
+
* @property {Array<import('@scout9/app').WorkflowResponseSlot>} slots
|
|
39
|
+
* @property {Array<import('@scout9/admin').Message>} messages
|
|
40
|
+
* @property {import('@scout9/app').Conversation} conversation
|
|
41
|
+
* @property {any} context
|
|
42
|
+
*/
|
|
43
|
+
/**
|
|
44
|
+
* @typedef {Object} GenerateOutput
|
|
45
|
+
* @property {import('@scout9/admin').GenerateResponse | undefined} generate
|
|
46
|
+
* @property {Array<import('@scout9/admin').Message>} messages
|
|
47
|
+
* @property {import('@scout9/app').Conversation} conversation
|
|
48
|
+
* @property {any} context
|
|
49
|
+
*/
|
|
50
|
+
/**
|
|
51
|
+
* @callback ParseFun
|
|
52
|
+
* @param {string} message - message to send
|
|
53
|
+
* @param {string | undefined} language - language to parse in, defaults to "en" for english
|
|
54
|
+
* @returns {Promise<import('@scout9/admin').ParseResponse>}
|
|
55
|
+
*/
|
|
56
|
+
/**
|
|
57
|
+
* @callback ContextualizerFun
|
|
58
|
+
* @param {Pick<import('@scout9/app').WorkflowEvent, 'messages' | 'conversation'>} args - message to send
|
|
59
|
+
* @returns {Promise<import('@scout9/app').WorkflowEvent['messages']>}
|
|
60
|
+
*/
|
|
61
|
+
/**
|
|
62
|
+
* @callback WorkflowFun
|
|
63
|
+
* @param {import('@scout9/app').WorkflowEvent} event - conversation data
|
|
64
|
+
* @returns {Promise<import('@scout9/app').WorkflowResponse>}
|
|
65
|
+
*/
|
|
66
|
+
/**
|
|
67
|
+
* @callback GenerateFun
|
|
68
|
+
* @param {import('@scout9/admin').GenerateRequestOneOf1} data - data to generate from
|
|
69
|
+
* @returns {Promise<import('@scout9/admin').GenerateResponse>}
|
|
70
|
+
*/
|
|
71
|
+
/**
|
|
72
|
+
* @callback TransformerFun
|
|
73
|
+
* @param {import('@scout9/admin').PmtTransformRequest} data - data to generate from
|
|
74
|
+
* @returns {Promise<import('@scout9/admin').PmtTransformResponse>}
|
|
75
|
+
*/
|
|
76
|
+
/**
|
|
77
|
+
* @callback IdGeneratorFun
|
|
78
|
+
* @param {import('@scout9/admin').Message['role']} prefix
|
|
79
|
+
* @returns {string}
|
|
80
|
+
*/
|
|
81
|
+
/**
|
|
82
|
+
* @callback StatusCallback
|
|
83
|
+
* @param {string} message
|
|
84
|
+
* @param {'info' | 'warn' | 'error' | 'success' | undefined} [level]
|
|
85
|
+
* @param {string | undefined} [type]
|
|
86
|
+
* @param {any | undefined} [payload]
|
|
87
|
+
* @returns {void}
|
|
88
|
+
*/
|
|
89
|
+
/**
|
|
90
|
+
* @typedef {Object} CustomerSpiritCallbacks
|
|
91
|
+
* @property {ParseFun} parser
|
|
92
|
+
* @property {ContextualizerFun} contextualizer
|
|
93
|
+
* @property {WorkflowFun} workflow
|
|
94
|
+
* @property {GenerateFun} generator
|
|
95
|
+
* @property {TransformerFun} transformer
|
|
96
|
+
* @property {IdGeneratorFun} idGenerator
|
|
97
|
+
* @property {StatusCallback | undefined} [progress]
|
|
98
|
+
*/
|
|
99
|
+
var SpiritError = /*#__PURE__*/function (_Error) {
|
|
100
|
+
_rollupPluginBabelHelpers._inherits(SpiritError, _Error);
|
|
101
|
+
/**
|
|
102
|
+
* @param {string} message - Description of the error.
|
|
103
|
+
* @param {string} step - The step or phase in which the error occurred.
|
|
104
|
+
*/
|
|
105
|
+
function SpiritError(message, step) {
|
|
106
|
+
var _this;
|
|
107
|
+
_rollupPluginBabelHelpers._classCallCheck(this, SpiritError);
|
|
108
|
+
_this = _rollupPluginBabelHelpers._callSuper(this, SpiritError, [message]);
|
|
109
|
+
_this.name = _this.constructor.name;
|
|
110
|
+
_this.step = step;
|
|
7
111
|
|
|
112
|
+
// Ensures the stack trace starts from where this error was created
|
|
113
|
+
if (Error.captureStackTrace) {
|
|
114
|
+
Error.captureStackTrace(_rollupPluginBabelHelpers._assertThisInitialized(_this), _this.constructor);
|
|
115
|
+
}
|
|
116
|
+
return _this;
|
|
117
|
+
}
|
|
8
118
|
|
|
9
|
-
|
|
119
|
+
/**
|
|
120
|
+
*
|
|
121
|
+
* @param {unknown} err
|
|
122
|
+
* @param {string} step
|
|
123
|
+
* @returns {SpiritError}
|
|
124
|
+
*/
|
|
125
|
+
_rollupPluginBabelHelpers._createClass(SpiritError, null, [{
|
|
126
|
+
key: "fromError",
|
|
127
|
+
value: function fromError(err, step) {
|
|
128
|
+
if (err instanceof SpiritError) return err;
|
|
129
|
+
if (err instanceof Error) {
|
|
130
|
+
var wrapped = new SpiritError(err.message, step);
|
|
131
|
+
wrapped.stack = err.stack;
|
|
132
|
+
return wrapped;
|
|
133
|
+
}
|
|
134
|
+
// fallback for non-Error values
|
|
135
|
+
return new SpiritError(String(err), step);
|
|
136
|
+
}
|
|
137
|
+
}]);
|
|
138
|
+
return SpiritError;
|
|
139
|
+
}( /*#__PURE__*/_rollupPluginBabelHelpers._wrapNativeSuper(Error));
|
|
140
|
+
/**
|
|
141
|
+
* @typedef {Object} ConversationEvent
|
|
142
|
+
* @property {(Change<import('@scout9/app').Conversation> & {
|
|
143
|
+
* forwardNote?: string;
|
|
144
|
+
* forward?: import('@scout9/app').WorkflowResponseSlot['forward'];
|
|
145
|
+
* })} conversation
|
|
146
|
+
* @property {Change<Array<import('@scout9/admin').Message>>} messages
|
|
147
|
+
* @property {Change<any>} context
|
|
148
|
+
* @property {Change<import('@scout9/admin').Message>} message
|
|
149
|
+
* @property {Array<import('@scout9/app').Followup>} followup
|
|
150
|
+
* @property {Array<import('@scout9/app').EntityContextUpsert>} entityContextUpsert
|
|
151
|
+
*/
|
|
152
|
+
var Spirits = {
|
|
153
|
+
/**
|
|
154
|
+
* Customer message
|
|
155
|
+
* @param {ConversationData & CustomerSpiritCallbacks} input
|
|
156
|
+
* @param {(error: Error) => void} onError
|
|
157
|
+
* @returns {Promise<ConversationEvent>}
|
|
158
|
+
*/
|
|
159
|
+
customer: function () {
|
|
160
|
+
var _customer = _rollupPluginBabelHelpers._asyncToGenerator( /*#__PURE__*/_rollupPluginBabelHelpers._regeneratorRuntime().mark(function _callee2(input) {
|
|
161
|
+
var _recentUserMessage;
|
|
162
|
+
var onError,
|
|
163
|
+
customer,
|
|
164
|
+
config,
|
|
165
|
+
parser,
|
|
166
|
+
contextualizer,
|
|
167
|
+
workflow,
|
|
168
|
+
generator,
|
|
169
|
+
transformer,
|
|
170
|
+
idGenerator,
|
|
171
|
+
_input$progress,
|
|
172
|
+
progress,
|
|
173
|
+
messageBefore,
|
|
174
|
+
contextBefore,
|
|
175
|
+
messagesBefore,
|
|
176
|
+
conversationBefore,
|
|
177
|
+
conversation,
|
|
178
|
+
messages,
|
|
179
|
+
context,
|
|
180
|
+
message,
|
|
181
|
+
followup,
|
|
182
|
+
entityContextUpsert,
|
|
183
|
+
updateConversation,
|
|
184
|
+
updateContext,
|
|
185
|
+
userMessages,
|
|
186
|
+
recentUserMessage,
|
|
187
|
+
lockConversation,
|
|
188
|
+
incrementLockAttempt,
|
|
189
|
+
_addInstruction,
|
|
190
|
+
addInstruction,
|
|
191
|
+
onStatus,
|
|
192
|
+
wrapStep,
|
|
193
|
+
persona,
|
|
194
|
+
invalidRoles,
|
|
195
|
+
parsePayload,
|
|
196
|
+
index,
|
|
197
|
+
_message,
|
|
198
|
+
previousUserMessages,
|
|
199
|
+
oldKeyCount,
|
|
200
|
+
newKeyCount,
|
|
201
|
+
noNewContext,
|
|
202
|
+
_messages2,
|
|
203
|
+
newContextMessages,
|
|
204
|
+
_iterator,
|
|
205
|
+
_step,
|
|
206
|
+
_loop,
|
|
207
|
+
slots,
|
|
208
|
+
hasNoInstructions,
|
|
209
|
+
hasNoCustomMessage,
|
|
210
|
+
messagesToTransform,
|
|
211
|
+
previousLockAttempt,
|
|
212
|
+
resettedIntent,
|
|
213
|
+
_forward,
|
|
214
|
+
_forwardNote,
|
|
215
|
+
_tasks,
|
|
216
|
+
_iterator2,
|
|
217
|
+
_step2,
|
|
218
|
+
_step2$value,
|
|
219
|
+
forward,
|
|
220
|
+
forwardNote,
|
|
221
|
+
instructions,
|
|
222
|
+
removeInstructions,
|
|
223
|
+
manualMessage,
|
|
224
|
+
scheduled,
|
|
225
|
+
resetIntent,
|
|
226
|
+
secondsDelay,
|
|
227
|
+
contextUpsert,
|
|
228
|
+
anticipate,
|
|
229
|
+
slotFollowup,
|
|
230
|
+
slotEntityContextUpsert,
|
|
231
|
+
tasks,
|
|
232
|
+
_slots,
|
|
233
|
+
map,
|
|
234
|
+
i,
|
|
235
|
+
_anticipate$i,
|
|
236
|
+
keywords,
|
|
237
|
+
_slot,
|
|
238
|
+
slotId,
|
|
239
|
+
_tasks2,
|
|
240
|
+
_iterator5,
|
|
241
|
+
_step5,
|
|
242
|
+
instruction,
|
|
243
|
+
_iterator6,
|
|
244
|
+
_step6,
|
|
245
|
+
_loop2,
|
|
246
|
+
manualMessageObj,
|
|
247
|
+
now,
|
|
248
|
+
generatorInput,
|
|
249
|
+
generatorPayload,
|
|
250
|
+
_generatorPayload$err,
|
|
251
|
+
_generatorPayload$err2,
|
|
252
|
+
_generatorPayload$err3,
|
|
253
|
+
_generatorPayload$mes,
|
|
254
|
+
agentMessages,
|
|
255
|
+
lastAgentMessage,
|
|
256
|
+
addedMessages,
|
|
257
|
+
_iterator3,
|
|
258
|
+
_step3,
|
|
259
|
+
newMessage,
|
|
260
|
+
_iterator4,
|
|
261
|
+
_step4,
|
|
262
|
+
transformResponse,
|
|
263
|
+
_agentMessages,
|
|
264
|
+
_lastAgentMessage,
|
|
265
|
+
_args4 = arguments;
|
|
266
|
+
return _rollupPluginBabelHelpers._regeneratorRuntime().wrap(function _callee2$(_context4) {
|
|
267
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
268
|
+
case 0:
|
|
269
|
+
onError = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : function () {};
|
|
270
|
+
customer = input.customer, config = input.config, parser = input.parser, contextualizer = input.contextualizer, workflow = input.workflow, generator = input.generator, transformer = input.transformer, idGenerator = input.idGenerator, _input$progress = input.progress, progress = _input$progress === void 0 ? function (message, level, type, payload) {} : _input$progress, messageBefore = input.message, contextBefore = input.context, messagesBefore = input.messages, conversationBefore = input.conversation;
|
|
271
|
+
conversation = input.conversation, messages = input.messages, context = input.context, message = input.message; // Storing post process events here
|
|
272
|
+
followup = [];
|
|
273
|
+
entityContextUpsert = []; // 0. Setup Helpers
|
|
274
|
+
updateConversation = function updateConversation(previousConversation, conversationUpdates) {
|
|
275
|
+
progress('Update conversation', 'info', 'UPDATE_CONVERSATION', conversationUpdates);
|
|
276
|
+
return _rollupPluginBabelHelpers._objectSpread2(_rollupPluginBabelHelpers._objectSpread2({}, previousConversation), conversationUpdates);
|
|
277
|
+
};
|
|
278
|
+
updateContext = function updateContext(previousContext, newContext) {
|
|
279
|
+
progress('Update context', 'info', 'UPDATE_CONTEXT', newContext);
|
|
280
|
+
return _rollupPluginBabelHelpers._objectSpread2(_rollupPluginBabelHelpers._objectSpread2({}, previousContext), newContext);
|
|
281
|
+
};
|
|
282
|
+
userMessages = function userMessages(_messages) {
|
|
283
|
+
return _messages.filter(function (m) {
|
|
284
|
+
return m.role === 'customer' || m.role === 'user';
|
|
285
|
+
});
|
|
286
|
+
};
|
|
287
|
+
recentUserMessage = function recentUserMessage(_messages) {
|
|
288
|
+
var _userMessages = userMessages(_messages);
|
|
289
|
+
return _userMessages[_userMessages.length - 1];
|
|
290
|
+
};
|
|
291
|
+
lockConversation = function lockConversation(_conversation, reason) {
|
|
292
|
+
return updateConversation(_conversation, {
|
|
293
|
+
locked: true,
|
|
294
|
+
lockedReason: conversation.lockedReason || reason || 'Unknown'
|
|
295
|
+
});
|
|
296
|
+
};
|
|
297
|
+
incrementLockAttempt = function incrementLockAttempt(_conversation, _config) {
|
|
298
|
+
if (typeof _conversation.lockAttempts !== 'number') {
|
|
299
|
+
_conversation.lockAttempts = 0;
|
|
300
|
+
}
|
|
301
|
+
_conversation.lockAttempts++;
|
|
302
|
+
if (_conversation.lockAttempts > ((_config === null || _config === void 0 ? void 0 : _config.maxLockAttempts) || 3)) {
|
|
303
|
+
_conversation.locked = true;
|
|
304
|
+
_conversation.lockedReason = "Max lock attempts exceeded (".concat(_conversation.lockAttempts, " > ").concat((_config === null || _config === void 0 ? void 0 : _config.maxLockAttempts) || 3, ")");
|
|
305
|
+
}
|
|
306
|
+
progress('Incremented lock attempt', 'info', 'UPDATE_CONVERSATION', {
|
|
307
|
+
lockAttempts: _conversation.lockAttempts,
|
|
308
|
+
locked: _conversation.locked,
|
|
309
|
+
lockedReason: _conversation.lockedReason || ''
|
|
310
|
+
});
|
|
311
|
+
return _conversation;
|
|
312
|
+
};
|
|
313
|
+
_addInstruction = function _addInstruction(instruction, _messages, _conversation, _config, previousLockAttempt, id) {
|
|
314
|
+
var systemMessages = _messages.filter(function (m) {
|
|
315
|
+
return m.role === 'system';
|
|
316
|
+
});
|
|
317
|
+
var lastSystemMessage = systemMessages[systemMessages.length - 1];
|
|
318
|
+
var addedMessage = false;
|
|
319
|
+
var changedConversation = false;
|
|
320
|
+
|
|
321
|
+
// If instruction does not equal previous system message, add it, otherwise lock attempt
|
|
322
|
+
if (!lastSystemMessage || instruction !== lastSystemMessage.content) {
|
|
323
|
+
_messages.push({
|
|
324
|
+
id: id,
|
|
325
|
+
role: 'system',
|
|
326
|
+
content: instruction,
|
|
327
|
+
time: new Date().toISOString()
|
|
328
|
+
});
|
|
329
|
+
addedMessage = true;
|
|
330
|
+
} else {
|
|
331
|
+
// Handle repeated instruction
|
|
332
|
+
// Increment lock attempt if instructions are repeated and we haven't already incremented lock attempt (for example if a forward is provided)
|
|
333
|
+
if (previousLockAttempt === (conversation.lockAttempts || 0)) {
|
|
334
|
+
_conversation = incrementLockAttempt(_conversation, _config);
|
|
335
|
+
changedConversation = true;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return {
|
|
339
|
+
conversation: _conversation,
|
|
340
|
+
messages: _messages,
|
|
341
|
+
addedMessage: addedMessage,
|
|
342
|
+
changedConversation: changedConversation
|
|
343
|
+
};
|
|
344
|
+
};
|
|
345
|
+
addInstruction = function addInstruction(instruction, previousLockAttempt) {
|
|
346
|
+
var id = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : idGenerator('sys');
|
|
347
|
+
var _addInstruction2 = _addInstruction(instruction, messages, conversation, config, previousLockAttempt, id),
|
|
348
|
+
newConversation = _addInstruction2.conversation,
|
|
349
|
+
newMessages = _addInstruction2.messages,
|
|
350
|
+
addedMessage = _addInstruction2.addedMessage,
|
|
351
|
+
changedConversation = _addInstruction2.changedConversation;
|
|
352
|
+
conversation = newConversation;
|
|
353
|
+
messages = newMessages;
|
|
354
|
+
if (addedMessage) {
|
|
355
|
+
progress('Added instruction', 'info', 'ADD_MESSAGE', newMessages[newMessages.length - 1]);
|
|
356
|
+
}
|
|
357
|
+
if (changedConversation) {
|
|
358
|
+
progress('Updated conversation', 'info', 'UPDATE_CONVERSATION', newConversation);
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
onStatus = function onStatus(statusType) {
|
|
362
|
+
var completeOrError = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
363
|
+
progress("".concat(statusType, ": ").concat(completeOrError), 'info', 'STATUS', _rollupPluginBabelHelpers._defineProperty({}, statusType, completeOrError));
|
|
364
|
+
};
|
|
365
|
+
/**
|
|
366
|
+
* @param {Promise<any>} prom
|
|
367
|
+
* @param {string} step
|
|
368
|
+
*/
|
|
369
|
+
wrapStep = /*#__PURE__*/function () {
|
|
370
|
+
var _ref = _rollupPluginBabelHelpers._asyncToGenerator( /*#__PURE__*/_rollupPluginBabelHelpers._regeneratorRuntime().mark(function _callee(prom, step) {
|
|
371
|
+
var result;
|
|
372
|
+
return _rollupPluginBabelHelpers._regeneratorRuntime().wrap(function _callee$(_context) {
|
|
373
|
+
while (1) switch (_context.prev = _context.next) {
|
|
374
|
+
case 0:
|
|
375
|
+
_context.prev = 0;
|
|
376
|
+
_context.next = 3;
|
|
377
|
+
return prom;
|
|
378
|
+
case 3:
|
|
379
|
+
result = _context.sent;
|
|
380
|
+
onStatus(step);
|
|
381
|
+
return _context.abrupt("return", result);
|
|
382
|
+
case 8:
|
|
383
|
+
_context.prev = 8;
|
|
384
|
+
_context.t0 = _context["catch"](0);
|
|
385
|
+
onStatus(step, _context.t0.message || 'UNHANDLED ERROR');
|
|
386
|
+
throw SpiritError.fromError(_context.t0, step);
|
|
387
|
+
case 12:
|
|
388
|
+
case "end":
|
|
389
|
+
return _context.stop();
|
|
390
|
+
}
|
|
391
|
+
}, _callee, null, [[0, 8]]);
|
|
392
|
+
}));
|
|
393
|
+
return function wrapStep(_x2, _x3) {
|
|
394
|
+
return _ref.apply(this, arguments);
|
|
395
|
+
};
|
|
396
|
+
}(); // 1. Check inputs
|
|
397
|
+
if (conversation.$agent) {
|
|
398
|
+
_context4.next = 17;
|
|
399
|
+
break;
|
|
400
|
+
}
|
|
401
|
+
throw new Error("SpiritsError: No agent found in conversation, must define \".$agent\" in the conversation");
|
|
402
|
+
case 17:
|
|
403
|
+
persona = (config.persona || config.personas || config.agents).find(function (p) {
|
|
404
|
+
return p.id === conversation.$agent;
|
|
405
|
+
});
|
|
406
|
+
if (persona) {
|
|
407
|
+
_context4.next = 22;
|
|
408
|
+
break;
|
|
409
|
+
}
|
|
410
|
+
if (!(config.persona || config.personas || config.agents).some(function (a) {
|
|
411
|
+
return !a.id;
|
|
412
|
+
})) {
|
|
413
|
+
_context4.next = 21;
|
|
414
|
+
break;
|
|
415
|
+
}
|
|
416
|
+
throw new Error("SpiritsError: No persona found (\"".concat(conversation.$agent, "\") in provided config, some persona's did not contain an \"id\" (Internal Mapping Error)"));
|
|
417
|
+
case 21:
|
|
418
|
+
throw new Error("SpiritsError: No persona found (\"".concat(conversation.$agent, "\") in provided config"));
|
|
419
|
+
case 22:
|
|
420
|
+
if (messages.every(function (m) {
|
|
421
|
+
return !!m.id;
|
|
422
|
+
})) {
|
|
423
|
+
_context4.next = 24;
|
|
424
|
+
break;
|
|
425
|
+
}
|
|
426
|
+
throw new Error("SpiritsError: Every message must have an \".id\", ensure all messages have an id assigned before running");
|
|
427
|
+
case 24:
|
|
428
|
+
if (messages.every(function (m) {
|
|
429
|
+
return m.role === 'customer' || m.role === 'agent' || m.role === 'system' || m.role === 'tool';
|
|
430
|
+
})) {
|
|
431
|
+
_context4.next = 27;
|
|
432
|
+
break;
|
|
433
|
+
}
|
|
434
|
+
invalidRoles = messages.filter(function (m) {
|
|
435
|
+
return m.role !== 'customer' && m.role !== 'agent' && m.role !== 'system' && m.role !== 'tool';
|
|
436
|
+
});
|
|
437
|
+
throw new Error("SpiritsError: Every message must have a role of \"customer\", \"agent\", or \"system\". Got invalid roles: ".concat(invalidRoles.map(function (m) {
|
|
438
|
+
return m.role;
|
|
439
|
+
}).join(', ')));
|
|
440
|
+
case 27:
|
|
441
|
+
// if message is not in messages, then add it
|
|
442
|
+
if (!messages.find(function (m) {
|
|
443
|
+
return m.id === input.message.id;
|
|
444
|
+
})) {
|
|
445
|
+
messages.push(input.message);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// 2. Parse the message
|
|
449
|
+
progress('Parsing message', 'info', 'SET_PROCESSING', 'user');
|
|
450
|
+
_context4.next = 31;
|
|
451
|
+
return wrapStep(parser(message.content, 'en'), 'parse');
|
|
452
|
+
case 31:
|
|
453
|
+
parsePayload = _context4.sent;
|
|
454
|
+
if (parsePayload.intent) {
|
|
455
|
+
message.intent = parsePayload.intent;
|
|
456
|
+
}
|
|
457
|
+
if (typeof parsePayload.intentScore === 'number') {
|
|
458
|
+
message.intentScore = parsePayload.intentScore;
|
|
459
|
+
}
|
|
460
|
+
message.context = parsePayload.context;
|
|
461
|
+
message.entities = parsePayload.entities;
|
|
462
|
+
index = messages.findIndex(function (m) {
|
|
463
|
+
return m.content === message.content || m.id === message.id;
|
|
464
|
+
});
|
|
465
|
+
if (index === -1) {
|
|
466
|
+
_message = {
|
|
467
|
+
id: idGenerator('customer'),
|
|
468
|
+
role: 'customer',
|
|
469
|
+
content: message,
|
|
470
|
+
context: parsePayload.context,
|
|
471
|
+
entities: parsePayload.entities,
|
|
472
|
+
time: new Date().toISOString()
|
|
473
|
+
};
|
|
474
|
+
if (parsePayload.intent) {
|
|
475
|
+
_message.intent = parsePayload.intent;
|
|
476
|
+
}
|
|
477
|
+
if (typeof parsePayload.intentScore === 'number') {
|
|
478
|
+
_message.intentScore = parsePayload.intentScore;
|
|
479
|
+
}
|
|
480
|
+
message = _message;
|
|
481
|
+
messages.push(_message);
|
|
482
|
+
progress('Added message', 'info', 'ADD_MESSAGE', _message);
|
|
483
|
+
} else {
|
|
484
|
+
messages[index].context = parsePayload.context;
|
|
485
|
+
messages[index].entities = parsePayload.entities;
|
|
486
|
+
if (parsePayload.intent) {
|
|
487
|
+
messages[index].intent = parsePayload.intent;
|
|
488
|
+
}
|
|
489
|
+
if (typeof parsePayload.intentScore === 'number') {
|
|
490
|
+
messages[index].intentScore = parsePayload.intentScore;
|
|
491
|
+
}
|
|
492
|
+
message = messages[index];
|
|
493
|
+
progress('Parsed message', 'success', 'UPDATE_MESSAGE', message);
|
|
494
|
+
}
|
|
495
|
+
// If this is the first user message, then update conversations intent
|
|
496
|
+
previousUserMessages = messages.filter(function (m) {
|
|
497
|
+
return m.role === 'customer' && m.content !== message.content;
|
|
498
|
+
});
|
|
499
|
+
if (!conversation.intent || previousUserMessages.length === 0 && parsePayload.intent) {
|
|
500
|
+
conversation.intent = parsePayload.intent;
|
|
501
|
+
conversation.intentScore = (parsePayload === null || parsePayload === void 0 ? void 0 : parsePayload.intentScore) || 0;
|
|
502
|
+
progress('Updated conversation intent', 'info', 'UPDATE_CONVERSATION', {
|
|
503
|
+
intent: parsePayload.intent,
|
|
504
|
+
intentScore: (parsePayload === null || parsePayload === void 0 ? void 0 : parsePayload.intentScore) || 0
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
oldKeyCount = Object.keys(context).length;
|
|
508
|
+
context = updateContext(context, parsePayload.context);
|
|
509
|
+
newKeyCount = Object.keys(context).length;
|
|
510
|
+
if (!conversation.locked && newKeyCount > oldKeyCount) {
|
|
511
|
+
// Reset lock attempts
|
|
512
|
+
conversation.locked = false;
|
|
513
|
+
conversation.lockAttempts = 0;
|
|
514
|
+
conversation.lockedReason = '';
|
|
515
|
+
progress('Reset lock', 'info', 'UPDATE_CONVERSATION', {
|
|
516
|
+
locked: false,
|
|
517
|
+
lockAttempts: 0,
|
|
518
|
+
lockedReason: ''
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
noNewContext = Object.keys(parsePayload.context).length === 0; // upsert parse system messages
|
|
522
|
+
if (parsePayload.contextMessages.length) {
|
|
523
|
+
(_messages2 = messages).push.apply(_messages2, _rollupPluginBabelHelpers._toConsumableArray(parsePayload.contextMessages.reduce(function (accumulator, text) {
|
|
524
|
+
if (!messages.find(function (mes) {
|
|
525
|
+
return mes.content === text;
|
|
526
|
+
})) {
|
|
527
|
+
accumulator.push({
|
|
528
|
+
id: idGenerator('sys'),
|
|
529
|
+
role: 'system',
|
|
530
|
+
content: text,
|
|
531
|
+
time: new Date().toISOString()
|
|
532
|
+
});
|
|
533
|
+
} else {
|
|
534
|
+
progress("Already have system context, skipping", 'info');
|
|
535
|
+
}
|
|
536
|
+
return accumulator;
|
|
537
|
+
}, [])));
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// 3. Run the contextualizer
|
|
541
|
+
progress('Running contextualizer', 'info', 'SET_PROCESSING', 'system');
|
|
542
|
+
_context4.next = 49;
|
|
543
|
+
return wrapStep(contextualizer({
|
|
544
|
+
conversation: conversation,
|
|
545
|
+
messages: messages
|
|
546
|
+
}), 'contextualize');
|
|
547
|
+
case 49:
|
|
548
|
+
newContextMessages = _context4.sent;
|
|
549
|
+
_iterator = _rollupPluginBabelHelpers._createForOfIteratorHelper(newContextMessages);
|
|
550
|
+
_context4.prev = 51;
|
|
551
|
+
_loop = /*#__PURE__*/_rollupPluginBabelHelpers._regeneratorRuntime().mark(function _loop() {
|
|
552
|
+
var contextMessage;
|
|
553
|
+
return _rollupPluginBabelHelpers._regeneratorRuntime().wrap(function _loop$(_context2) {
|
|
554
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
555
|
+
case 0:
|
|
556
|
+
contextMessage = _step.value;
|
|
557
|
+
if (!messages.find(function (mes) {
|
|
558
|
+
return mes.content === contextMessage.content;
|
|
559
|
+
})) {
|
|
560
|
+
messages.push(contextMessage);
|
|
561
|
+
progress("Added context", 'info', 'ADD_MESSAGE', messages[messages.length - 1]);
|
|
562
|
+
} else {
|
|
563
|
+
progress("Already have system context, skipping", 'info');
|
|
564
|
+
}
|
|
565
|
+
case 2:
|
|
566
|
+
case "end":
|
|
567
|
+
return _context2.stop();
|
|
568
|
+
}
|
|
569
|
+
}, _loop);
|
|
570
|
+
});
|
|
571
|
+
_iterator.s();
|
|
572
|
+
case 54:
|
|
573
|
+
if ((_step = _iterator.n()).done) {
|
|
574
|
+
_context4.next = 58;
|
|
575
|
+
break;
|
|
576
|
+
}
|
|
577
|
+
return _context4.delegateYield(_loop(), "t0", 56);
|
|
578
|
+
case 56:
|
|
579
|
+
_context4.next = 54;
|
|
580
|
+
break;
|
|
581
|
+
case 58:
|
|
582
|
+
_context4.next = 63;
|
|
583
|
+
break;
|
|
584
|
+
case 60:
|
|
585
|
+
_context4.prev = 60;
|
|
586
|
+
_context4.t1 = _context4["catch"](51);
|
|
587
|
+
_iterator.e(_context4.t1);
|
|
588
|
+
case 63:
|
|
589
|
+
_context4.prev = 63;
|
|
590
|
+
_iterator.f();
|
|
591
|
+
return _context4.finish(63);
|
|
592
|
+
case 66:
|
|
593
|
+
// 4. Run the workflow
|
|
594
|
+
progress('Running workflow', 'info', 'SET_PROCESSING', 'system');
|
|
595
|
+
_context4.next = 69;
|
|
596
|
+
return wrapStep(workflow({
|
|
597
|
+
messages: messages,
|
|
598
|
+
conversation: conversation,
|
|
599
|
+
context: context,
|
|
600
|
+
message: message,
|
|
601
|
+
agent: persona,
|
|
602
|
+
customer: customer,
|
|
603
|
+
intent: {
|
|
604
|
+
current: ((_recentUserMessage = recentUserMessage(messages)) === null || _recentUserMessage === void 0 ? void 0 : _recentUserMessage.intent) || null,
|
|
605
|
+
flow: messages.map(function (m) {
|
|
606
|
+
return m.intent;
|
|
607
|
+
}).filter(Boolean),
|
|
608
|
+
initial: conversation.intent || null
|
|
609
|
+
},
|
|
610
|
+
stagnationCount: conversation.lockAttempts || 0
|
|
611
|
+
}), 'workflow').then(function (res) {
|
|
612
|
+
return Array.isArray(res) ? res : [res];
|
|
613
|
+
}).then(function (slots) {
|
|
614
|
+
return slots.reduce(function (accumulator, slot) {
|
|
615
|
+
if ('toJSON' in slot) {
|
|
616
|
+
var slotJson = slot.toJSON();
|
|
617
|
+
accumulator.push.apply(accumulator, _rollupPluginBabelHelpers._toConsumableArray(Array.isArray(slotJson) ? slotJson : [slotJson]));
|
|
618
|
+
} else {
|
|
619
|
+
accumulator.push(slot);
|
|
620
|
+
}
|
|
621
|
+
return accumulator;
|
|
622
|
+
}, []);
|
|
623
|
+
});
|
|
624
|
+
case 69:
|
|
625
|
+
slots = _context4.sent;
|
|
626
|
+
hasNoInstructions = slots.every(function (s) {
|
|
627
|
+
return !s.instructions || Array.isArray(s.instructions) && s.instructions.length === 0;
|
|
628
|
+
});
|
|
629
|
+
hasNoCustomMessage = slots.every(function (s) {
|
|
630
|
+
return !s.message;
|
|
631
|
+
});
|
|
632
|
+
messagesToTransform = slots.filter(function (s) {
|
|
633
|
+
return !!s.message && _rollupPluginBabelHelpers._typeof(s.message) === 'object' && !!s.message.transform;
|
|
634
|
+
});
|
|
635
|
+
previousLockAttempt = conversation.lockAttempts || 0; // Used to track
|
|
636
|
+
if (hasNoInstructions && noNewContext) {
|
|
637
|
+
conversation = incrementLockAttempt(conversation, config);
|
|
638
|
+
} else {
|
|
639
|
+
conversation.lockAttempts = 0;
|
|
640
|
+
conversation.locked = false;
|
|
641
|
+
conversation.lockedReason = '';
|
|
642
|
+
progress('Reset lock', 'info', 'UPDATE_CONVERSATION', {
|
|
643
|
+
lockAttempts: 0,
|
|
644
|
+
locked: false,
|
|
645
|
+
lockedReason: ''
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
resettedIntent = false;
|
|
649
|
+
/** @type {Array<string> | undefined} */
|
|
650
|
+
_iterator2 = _rollupPluginBabelHelpers._createForOfIteratorHelper(slots);
|
|
651
|
+
_context4.prev = 77;
|
|
652
|
+
_iterator2.s();
|
|
653
|
+
case 79:
|
|
654
|
+
if ((_step2 = _iterator2.n()).done) {
|
|
655
|
+
_context4.next = 150;
|
|
656
|
+
break;
|
|
657
|
+
}
|
|
658
|
+
_step2$value = _step2.value, forward = _step2$value.forward, forwardNote = _step2$value.forwardNote, instructions = _step2$value.instructions, removeInstructions = _step2$value.removeInstructions, manualMessage = _step2$value.message, scheduled = _step2$value.scheduled, resetIntent = _step2$value.resetIntent, secondsDelay = _step2$value.secondsDelay, contextUpsert = _step2$value.contextUpsert, anticipate = _step2$value.anticipate, slotFollowup = _step2$value.followup, slotEntityContextUpsert = _step2$value.entityContextUpsert, tasks = _step2$value.tasks;
|
|
659
|
+
if (!anticipate) {
|
|
660
|
+
_context4.next = 94;
|
|
661
|
+
break;
|
|
662
|
+
}
|
|
663
|
+
if (!Array.isArray(anticipate)) {
|
|
664
|
+
_context4.next = 89;
|
|
665
|
+
break;
|
|
666
|
+
}
|
|
667
|
+
// 'literal' anticipation
|
|
668
|
+
_slots = {};
|
|
669
|
+
map = [];
|
|
670
|
+
for (i = 0; i < anticipate.length; i++) {
|
|
671
|
+
_anticipate$i = anticipate[i], keywords = _anticipate$i.keywords, _slot = _rollupPluginBabelHelpers._objectWithoutProperties(_anticipate$i, _excluded);
|
|
672
|
+
slotId = "".concat(i);
|
|
673
|
+
_slots[slotId] = _slot;
|
|
674
|
+
map.push({
|
|
675
|
+
slot: slotId,
|
|
676
|
+
keywords: keywords
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
updateConversation(conversation, {
|
|
680
|
+
type: 'literal',
|
|
681
|
+
slots: _slots,
|
|
682
|
+
map: map
|
|
683
|
+
});
|
|
684
|
+
_context4.next = 94;
|
|
685
|
+
break;
|
|
686
|
+
case 89:
|
|
687
|
+
if (!('yes' in anticipate && 'no' in anticipate && 'did' in anticipate)) {
|
|
688
|
+
_context4.next = 93;
|
|
689
|
+
break;
|
|
690
|
+
}
|
|
691
|
+
// "did" anticipation
|
|
692
|
+
updateConversation(conversation, {
|
|
693
|
+
type: 'did',
|
|
694
|
+
slots: {
|
|
695
|
+
yes: anticipate.yes,
|
|
696
|
+
no: anticipate.no
|
|
697
|
+
},
|
|
698
|
+
did: anticipate.did
|
|
699
|
+
});
|
|
700
|
+
_context4.next = 94;
|
|
701
|
+
break;
|
|
702
|
+
case 93:
|
|
703
|
+
throw new Error("Invalid anticipate payload \"".concat(JSON.stringify(anticipate), "\""));
|
|
704
|
+
case 94:
|
|
705
|
+
// tasks from auto/manual ingress to execute
|
|
706
|
+
if (!!tasks && Array.isArray(tasks) && !!tasks.length) {
|
|
707
|
+
if (!_tasks) _tasks = [];
|
|
708
|
+
(_tasks2 = _tasks).push.apply(_tasks2, _rollupPluginBabelHelpers._toConsumableArray(tasks));
|
|
709
|
+
}
|
|
710
|
+
if (slotFollowup) {
|
|
711
|
+
followup.push(slotFollowup);
|
|
712
|
+
}
|
|
713
|
+
if (slotEntityContextUpsert && slotEntityContextUpsert.length) {
|
|
714
|
+
entityContextUpsert.push.apply(entityContextUpsert, _rollupPluginBabelHelpers._toConsumableArray(slotEntityContextUpsert));
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
// Forward to agent or other agent
|
|
718
|
+
if (forward) {
|
|
719
|
+
conversation = lockConversation(conversation, 'App instructed forward');
|
|
720
|
+
_forward = forward;
|
|
721
|
+
_forwardNote = forwardNote;
|
|
722
|
+
if (typeof forward === 'string') {
|
|
723
|
+
updateConversation(conversation, {
|
|
724
|
+
forwarded: forward
|
|
725
|
+
});
|
|
726
|
+
messages.push({
|
|
727
|
+
id: idGenerator('sys'),
|
|
728
|
+
role: 'system',
|
|
729
|
+
content: "forwarded to \"".concat(forward, "\""),
|
|
730
|
+
time: new Date().toISOString()
|
|
731
|
+
});
|
|
732
|
+
progress("Forwarded to \"".concat(forward, "\""), 'info', 'ADD_MESSAGE', messages[messages.length - 1]);
|
|
733
|
+
} else if (typeof forward === 'boolean') {
|
|
734
|
+
updateConversation(conversation, {
|
|
735
|
+
forwarded: conversation.$agent
|
|
736
|
+
});
|
|
737
|
+
messages.push({
|
|
738
|
+
id: idGenerator('sys'),
|
|
739
|
+
role: 'system',
|
|
740
|
+
content: "forwarded to \"".concat(forward, "\""),
|
|
741
|
+
time: new Date().toISOString()
|
|
742
|
+
});
|
|
743
|
+
progress("Forwarded to agent", 'info', 'ADD_MESSAGE', messages[messages.length - 1]);
|
|
744
|
+
} else {
|
|
745
|
+
messages.push({
|
|
746
|
+
id: idGenerator('sys'),
|
|
747
|
+
role: 'system',
|
|
748
|
+
content: "forwarded to \"".concat(forward.to, "\" ").concat(forward.mode ? ' (' + forward.mode + ')' : ''),
|
|
749
|
+
time: new Date().toISOString()
|
|
750
|
+
});
|
|
751
|
+
progress("Forwarded to \"".concat(forward.to, "\" ").concat(forward.mode ? ' (' + forward.mode + ')' : ''), 'info', 'ADD_MESSAGE', messages[messages.length - 1]);
|
|
752
|
+
updateConversation(conversation, {
|
|
753
|
+
forwarded: forward.to
|
|
754
|
+
});
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
// Insert instructions context
|
|
759
|
+
if (!instructions) {
|
|
760
|
+
_context4.next = 113;
|
|
761
|
+
break;
|
|
762
|
+
}
|
|
763
|
+
if (!(typeof instructions === 'string')) {
|
|
764
|
+
_context4.next = 103;
|
|
765
|
+
break;
|
|
766
|
+
}
|
|
767
|
+
addInstruction(instructions, previousLockAttempt);
|
|
768
|
+
_context4.next = 113;
|
|
769
|
+
break;
|
|
770
|
+
case 103:
|
|
771
|
+
if (!Array.isArray(instructions)) {
|
|
772
|
+
_context4.next = 108;
|
|
773
|
+
break;
|
|
774
|
+
}
|
|
775
|
+
_iterator5 = _rollupPluginBabelHelpers._createForOfIteratorHelper(instructions);
|
|
776
|
+
try {
|
|
777
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
778
|
+
instruction = _step5.value;
|
|
779
|
+
if (typeof instruction === 'string') {
|
|
780
|
+
addInstruction(instruction, previousLockAttempt);
|
|
781
|
+
} else {
|
|
782
|
+
addInstruction(instruction.content, previousLockAttempt, instruction.id);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
} catch (err) {
|
|
786
|
+
_iterator5.e(err);
|
|
787
|
+
} finally {
|
|
788
|
+
_iterator5.f();
|
|
789
|
+
}
|
|
790
|
+
_context4.next = 113;
|
|
791
|
+
break;
|
|
792
|
+
case 108:
|
|
793
|
+
if (!(_rollupPluginBabelHelpers._typeof(instructions) === 'object' && 'content' in instructions)) {
|
|
794
|
+
_context4.next = 112;
|
|
795
|
+
break;
|
|
796
|
+
}
|
|
797
|
+
addInstruction(instructions.content, previousLockAttempt, instructions.id);
|
|
798
|
+
_context4.next = 113;
|
|
799
|
+
break;
|
|
800
|
+
case 112:
|
|
801
|
+
throw new Error("SpiritsError: instructions must be a string or array or {content: \"<instruction>\"}, got: ".concat(JSON.stringify(instructions)));
|
|
802
|
+
case 113:
|
|
803
|
+
if (!removeInstructions) {
|
|
804
|
+
_context4.next = 130;
|
|
805
|
+
break;
|
|
806
|
+
}
|
|
807
|
+
_iterator6 = _rollupPluginBabelHelpers._createForOfIteratorHelper(removeInstructions);
|
|
808
|
+
_context4.prev = 115;
|
|
809
|
+
_loop2 = /*#__PURE__*/_rollupPluginBabelHelpers._regeneratorRuntime().mark(function _loop2() {
|
|
810
|
+
var instructionId, index;
|
|
811
|
+
return _rollupPluginBabelHelpers._regeneratorRuntime().wrap(function _loop2$(_context3) {
|
|
812
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
813
|
+
case 0:
|
|
814
|
+
instructionId = _step6.value;
|
|
815
|
+
index = messages.findIndex(function (m) {
|
|
816
|
+
return m.id === instructionId;
|
|
817
|
+
});
|
|
818
|
+
if (index > -1) {
|
|
819
|
+
messages.splice(index, 1);
|
|
820
|
+
progress('Remove instruction', 'info', 'REMOVE_MESSAGE', instructionId);
|
|
821
|
+
} else {
|
|
822
|
+
console.log("Instruction not found \"".concat(instructionId, "\", other ids: ").concat(messages.map(function (m) {
|
|
823
|
+
return "\"".concat(m.id, "\"");
|
|
824
|
+
}).join(', ')));
|
|
825
|
+
}
|
|
826
|
+
case 3:
|
|
827
|
+
case "end":
|
|
828
|
+
return _context3.stop();
|
|
829
|
+
}
|
|
830
|
+
}, _loop2);
|
|
831
|
+
});
|
|
832
|
+
_iterator6.s();
|
|
833
|
+
case 118:
|
|
834
|
+
if ((_step6 = _iterator6.n()).done) {
|
|
835
|
+
_context4.next = 122;
|
|
836
|
+
break;
|
|
837
|
+
}
|
|
838
|
+
return _context4.delegateYield(_loop2(), "t2", 120);
|
|
839
|
+
case 120:
|
|
840
|
+
_context4.next = 118;
|
|
841
|
+
break;
|
|
842
|
+
case 122:
|
|
843
|
+
_context4.next = 127;
|
|
844
|
+
break;
|
|
845
|
+
case 124:
|
|
846
|
+
_context4.prev = 124;
|
|
847
|
+
_context4.t3 = _context4["catch"](115);
|
|
848
|
+
_iterator6.e(_context4.t3);
|
|
849
|
+
case 127:
|
|
850
|
+
_context4.prev = 127;
|
|
851
|
+
_iterator6.f();
|
|
852
|
+
return _context4.finish(127);
|
|
853
|
+
case 130:
|
|
854
|
+
if (!manualMessage) {
|
|
855
|
+
_context4.next = 146;
|
|
856
|
+
break;
|
|
857
|
+
}
|
|
858
|
+
/** @type {import('@scout9/admin').Message} */
|
|
859
|
+
manualMessageObj = {
|
|
860
|
+
id: idGenerator('persona'),
|
|
861
|
+
role: 'agent',
|
|
862
|
+
// @TODO switch role to persona
|
|
863
|
+
content: '',
|
|
864
|
+
time: new Date().toISOString()
|
|
865
|
+
};
|
|
866
|
+
if (!(_rollupPluginBabelHelpers._typeof(manualMessage) === 'object')) {
|
|
867
|
+
_context4.next = 138;
|
|
868
|
+
break;
|
|
869
|
+
}
|
|
870
|
+
Object.assign(manualMessageObj, manualMessage);
|
|
871
|
+
manualMessageObj.role = 'agent';
|
|
872
|
+
manualMessageObj.time = new Date().toISOString();
|
|
873
|
+
_context4.next = 143;
|
|
874
|
+
break;
|
|
875
|
+
case 138:
|
|
876
|
+
if (!(typeof manualMessage === 'string')) {
|
|
877
|
+
_context4.next = 142;
|
|
878
|
+
break;
|
|
879
|
+
}
|
|
880
|
+
manualMessageObj.content = manualMessage;
|
|
881
|
+
_context4.next = 143;
|
|
882
|
+
break;
|
|
883
|
+
case 142:
|
|
884
|
+
throw new Error('Manual message must be of type "string" or "DirectMessage"');
|
|
885
|
+
case 143:
|
|
886
|
+
if (scheduled) {
|
|
887
|
+
manualMessageObj.time = new Date(scheduled * 1000).toISOString();
|
|
888
|
+
manualMessageObj.scheduled = manualMessageObj.time;
|
|
889
|
+
} else if (secondsDelay) {
|
|
890
|
+
now = new Date();
|
|
891
|
+
now.setSeconds(now.getSeconds() + secondsDelay);
|
|
892
|
+
manualMessageObj.time = now.toISOString();
|
|
893
|
+
manualMessageObj.delayInSeconds = secondsDelay;
|
|
894
|
+
}
|
|
895
|
+
messages.push(manualMessageObj);
|
|
896
|
+
progress('Added manual message', 'info', 'ADD_MESSAGE', messages[messages.length - 1]);
|
|
897
|
+
case 146:
|
|
898
|
+
if (contextUpsert) {
|
|
899
|
+
context = updateContext(context, contextUpsert);
|
|
900
|
+
progress('Upserted context', 'info', 'UPDATE_CONTEXT', contextUpsert);
|
|
901
|
+
}
|
|
902
|
+
if (resetIntent) {
|
|
903
|
+
resettedIntent = true;
|
|
904
|
+
}
|
|
905
|
+
case 148:
|
|
906
|
+
_context4.next = 79;
|
|
907
|
+
break;
|
|
908
|
+
case 150:
|
|
909
|
+
_context4.next = 155;
|
|
910
|
+
break;
|
|
911
|
+
case 152:
|
|
912
|
+
_context4.prev = 152;
|
|
913
|
+
_context4.t4 = _context4["catch"](77);
|
|
914
|
+
_iterator2.e(_context4.t4);
|
|
915
|
+
case 155:
|
|
916
|
+
_context4.prev = 155;
|
|
917
|
+
_iterator2.f();
|
|
918
|
+
return _context4.finish(155);
|
|
919
|
+
case 158:
|
|
920
|
+
if (resettedIntent && !_forward) {
|
|
921
|
+
conversation.intent = null;
|
|
922
|
+
conversation.intentScore = null;
|
|
923
|
+
conversation.locked = false;
|
|
924
|
+
conversation.lockedReason = '';
|
|
925
|
+
conversation.lockAttempts = 0;
|
|
926
|
+
progress('Reset conversation intent', 'info', 'UPDATE_CONVERSATION', {
|
|
927
|
+
intent: null,
|
|
928
|
+
intentScore: null,
|
|
929
|
+
locked: false,
|
|
930
|
+
lockAttempts: 0,
|
|
931
|
+
lockedReason: ''
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
// 5. Generate response
|
|
936
|
+
// If conversation previously locked, don't generate
|
|
937
|
+
if (input.conversation.locked) {
|
|
938
|
+
_context4.next = 215;
|
|
939
|
+
break;
|
|
940
|
+
}
|
|
941
|
+
if (!((!conversation.locked || !hasNoInstructions) && !!hasNoCustomMessage)) {
|
|
942
|
+
_context4.next = 178;
|
|
943
|
+
break;
|
|
944
|
+
}
|
|
945
|
+
_context4.prev = 161;
|
|
946
|
+
progress('Generating message', 'info', 'SET_PROCESSING', 'system');
|
|
947
|
+
|
|
948
|
+
/** @type {import('@scout9/admin').GenerateRequestOneOf1} */
|
|
949
|
+
generatorInput = {
|
|
950
|
+
messages: messages,
|
|
951
|
+
persona: persona,
|
|
952
|
+
context: context,
|
|
953
|
+
llm: config.llm,
|
|
954
|
+
pmt: config.pmt
|
|
955
|
+
};
|
|
956
|
+
if (!!_tasks && Array.isArray(_tasks) && !!_tasks.length) {
|
|
957
|
+
generatorInput.tasks = _tasks;
|
|
958
|
+
}
|
|
959
|
+
_context4.next = 167;
|
|
960
|
+
return wrapStep(generator(generatorInput), 'generate');
|
|
961
|
+
case 167:
|
|
962
|
+
generatorPayload = _context4.sent;
|
|
963
|
+
if (!generatorPayload.send) {
|
|
964
|
+
progress('Generated response', 'failed', undefined, {
|
|
965
|
+
error: ((_generatorPayload$err = generatorPayload.errors) === null || _generatorPayload$err === void 0 ? void 0 : _generatorPayload$err.join('\n\n')) || 'Unknown Reason'
|
|
966
|
+
});
|
|
967
|
+
console.error("Locking conversation, api returned send false: ".concat(generatorPayload.messages), ((_generatorPayload$err2 = generatorPayload.errors) === null || _generatorPayload$err2 === void 0 ? void 0 : _generatorPayload$err2.join('\n\n')) || generatorPayload.forwardNote || 'Unknown Reason');
|
|
968
|
+
conversation = lockConversation(conversation, 'API: ' + ((_generatorPayload$err3 = generatorPayload.errors) === null || _generatorPayload$err3 === void 0 ? void 0 : _generatorPayload$err3.join('\n\n')) || generatorPayload.forwardNote || 'Unknown Reason');
|
|
969
|
+
} else {
|
|
970
|
+
progress('Generated response', 'success', undefined, undefined);
|
|
971
|
+
// Check if already had message
|
|
972
|
+
agentMessages = messages.filter(function (m) {
|
|
973
|
+
return m.role === 'agent';
|
|
974
|
+
});
|
|
975
|
+
lastAgentMessage = agentMessages[agentMessages.length - 1]; // Build addedMessages from generatorPayload.messages
|
|
976
|
+
addedMessages = ((_generatorPayload$mes = generatorPayload === null || generatorPayload === void 0 ? void 0 : generatorPayload.messages) !== null && _generatorPayload$mes !== void 0 ? _generatorPayload$mes : []).map(function (message) {
|
|
977
|
+
// Normalize time → ISO string
|
|
978
|
+
var t = message.time;
|
|
979
|
+
var isoTime;
|
|
980
|
+
if (typeof t === "string") {
|
|
981
|
+
isoTime = t;
|
|
982
|
+
} else if (t instanceof Date) {
|
|
983
|
+
isoTime = t.toISOString();
|
|
984
|
+
} else if (t && typeof t.toDate === "function") {
|
|
985
|
+
// Firestore Timestamp
|
|
986
|
+
isoTime = t.toDate().toISOString();
|
|
987
|
+
} else {
|
|
988
|
+
progress("Message \"".concat(message.content, "\" wasn't given a usable timestamp (").concat(JSON.stringify(t), "), defaulting to now"));
|
|
989
|
+
isoTime = new Date().toISOString();
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
// Base fields we guarantee
|
|
993
|
+
var base = {
|
|
994
|
+
role: message.role,
|
|
995
|
+
content: message.content,
|
|
996
|
+
id: idGenerator(message.role),
|
|
997
|
+
time: isoTime
|
|
998
|
+
};
|
|
999
|
+
|
|
1000
|
+
// Copy any other non-nullish fields without overwriting base
|
|
1001
|
+
return Object.entries(message).reduce(function (acc, _ref2) {
|
|
1002
|
+
var _ref3 = _rollupPluginBabelHelpers._slicedToArray(_ref2, 2),
|
|
1003
|
+
key = _ref3[0],
|
|
1004
|
+
value = _ref3[1];
|
|
1005
|
+
if (!Object.prototype.hasOwnProperty.call(acc, key) && value != null) {
|
|
1006
|
+
acc[key] = value;
|
|
1007
|
+
}
|
|
1008
|
+
return acc;
|
|
1009
|
+
}, base);
|
|
1010
|
+
})
|
|
1011
|
+
// De-dupe by content (change the key if you want stricter uniqueness)
|
|
1012
|
+
.reduce(function (acc, msg) {
|
|
1013
|
+
var key = String(msg.content); // e.g. `${msg.role}::${msg.content}` for stronger uniqueness
|
|
1014
|
+
if (!acc.seen.has(key)) {
|
|
1015
|
+
acc.seen.add(key);
|
|
1016
|
+
acc.items.push(msg);
|
|
1017
|
+
}
|
|
1018
|
+
return acc;
|
|
1019
|
+
}, {
|
|
1020
|
+
seen: new Set(),
|
|
1021
|
+
items: []
|
|
1022
|
+
}).items;
|
|
1023
|
+
if (lastAgentMessage && lastAgentMessage.content && addedMessages.some(function (message) {
|
|
1024
|
+
return message.content === lastAgentMessage.content;
|
|
1025
|
+
})) {
|
|
1026
|
+
// Error should not have happened
|
|
1027
|
+
conversation = lockConversation(conversation, 'Duplicate message');
|
|
1028
|
+
} else {
|
|
1029
|
+
_iterator3 = _rollupPluginBabelHelpers._createForOfIteratorHelper(addedMessages);
|
|
1030
|
+
try {
|
|
1031
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
1032
|
+
newMessage = _step3.value;
|
|
1033
|
+
messages.push(newMessage);
|
|
1034
|
+
progress('Added agent message', 'info', 'ADD_MESSAGE', messages[messages.length - 1]);
|
|
1035
|
+
}
|
|
1036
|
+
} catch (err) {
|
|
1037
|
+
_iterator3.e(err);
|
|
1038
|
+
} finally {
|
|
1039
|
+
_iterator3.f();
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
// Check if conversation was marked for forward (generator message still allowed to be sent)
|
|
1044
|
+
if (generatorPayload.forward) {
|
|
1045
|
+
conversation = lockConversation(conversation, 'API: ' + generatorPayload.forwardNote || 'Forwarded by API');
|
|
1046
|
+
if (!_forward) {
|
|
1047
|
+
_forward = generatorPayload.forward;
|
|
1048
|
+
_forwardNote = generatorPayload.forwardNote;
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
_context4.next = 176;
|
|
1053
|
+
break;
|
|
1054
|
+
case 171:
|
|
1055
|
+
_context4.prev = 171;
|
|
1056
|
+
_context4.t5 = _context4["catch"](161);
|
|
1057
|
+
onError(_context4.t5);
|
|
1058
|
+
console.error("Spirits: Locking conversation, error generating response: ".concat(_context4.t5.message));
|
|
1059
|
+
conversation = lockConversation(conversation, 'API: ' + _context4.t5.message);
|
|
1060
|
+
case 176:
|
|
1061
|
+
_context4.next = 179;
|
|
1062
|
+
break;
|
|
1063
|
+
case 178:
|
|
1064
|
+
onStatus('generate', 'ignored');
|
|
1065
|
+
case 179:
|
|
1066
|
+
if (!(messagesToTransform.length && transformer)) {
|
|
1067
|
+
_context4.next = 212;
|
|
1068
|
+
break;
|
|
1069
|
+
}
|
|
1070
|
+
_context4.prev = 180;
|
|
1071
|
+
_iterator4 = _rollupPluginBabelHelpers._createForOfIteratorHelper(messagesToTransform);
|
|
1072
|
+
_context4.prev = 182;
|
|
1073
|
+
_iterator4.s();
|
|
1074
|
+
case 184:
|
|
1075
|
+
if ((_step4 = _iterator4.n()).done) {
|
|
1076
|
+
_context4.next = 195;
|
|
1077
|
+
break;
|
|
1078
|
+
}
|
|
1079
|
+
_step4.value;
|
|
1080
|
+
_context4.next = 188;
|
|
1081
|
+
return wrapStep(transformer({
|
|
1082
|
+
message: messagesToTransform,
|
|
1083
|
+
persona: persona,
|
|
1084
|
+
customer: customer.id,
|
|
1085
|
+
messages: messages,
|
|
1086
|
+
context: context
|
|
1087
|
+
}), 'transform');
|
|
1088
|
+
case 188:
|
|
1089
|
+
transformResponse = _context4.sent;
|
|
1090
|
+
progress('Generated response', 'success', undefined, undefined);
|
|
1091
|
+
// Check if already had message
|
|
1092
|
+
_agentMessages = messages.filter(function (m) {
|
|
1093
|
+
return m.role === 'agent';
|
|
1094
|
+
});
|
|
1095
|
+
_lastAgentMessage = _agentMessages[_agentMessages.length - 1];
|
|
1096
|
+
if (_lastAgentMessage && _lastAgentMessage.content === transformResponse.message) {
|
|
1097
|
+
// Error should not have happened
|
|
1098
|
+
conversation = lockConversation(conversation, 'Duplicate message');
|
|
1099
|
+
} else {
|
|
1100
|
+
messages.push({
|
|
1101
|
+
id: idGenerator('agent'),
|
|
1102
|
+
role: 'agent',
|
|
1103
|
+
content: transformResponse.message,
|
|
1104
|
+
time: new Date().toISOString()
|
|
1105
|
+
});
|
|
1106
|
+
progress('Added agent message', 'info', 'ADD_MESSAGE', messages[messages.length - 1]);
|
|
1107
|
+
}
|
|
1108
|
+
case 193:
|
|
1109
|
+
_context4.next = 184;
|
|
1110
|
+
break;
|
|
1111
|
+
case 195:
|
|
1112
|
+
_context4.next = 200;
|
|
1113
|
+
break;
|
|
1114
|
+
case 197:
|
|
1115
|
+
_context4.prev = 197;
|
|
1116
|
+
_context4.t6 = _context4["catch"](182);
|
|
1117
|
+
_iterator4.e(_context4.t6);
|
|
1118
|
+
case 200:
|
|
1119
|
+
_context4.prev = 200;
|
|
1120
|
+
_iterator4.f();
|
|
1121
|
+
return _context4.finish(200);
|
|
1122
|
+
case 203:
|
|
1123
|
+
_context4.next = 210;
|
|
1124
|
+
break;
|
|
1125
|
+
case 205:
|
|
1126
|
+
_context4.prev = 205;
|
|
1127
|
+
_context4.t7 = _context4["catch"](180);
|
|
1128
|
+
console.error("Locking conversation, error transforming response: ".concat(_context4.t7.message));
|
|
1129
|
+
conversation = lockConversation(conversation, 'API: ' + _context4.t7.message);
|
|
1130
|
+
onError(_context4.t7);
|
|
1131
|
+
case 210:
|
|
1132
|
+
_context4.next = 213;
|
|
1133
|
+
break;
|
|
1134
|
+
case 212:
|
|
1135
|
+
if (messagesToTransform.length) {
|
|
1136
|
+
console.warn("No transformer provided");
|
|
1137
|
+
onStatus('transform', 'ignored');
|
|
1138
|
+
}
|
|
1139
|
+
case 213:
|
|
1140
|
+
_context4.next = 217;
|
|
1141
|
+
break;
|
|
1142
|
+
case 215:
|
|
1143
|
+
onStatus('generate', 'ignored');
|
|
1144
|
+
onStatus('transform', 'ignored');
|
|
1145
|
+
case 217:
|
|
1146
|
+
progress('Parsing message', 'info', 'SET_PROCESSING', null);
|
|
1147
|
+
return _context4.abrupt("return", {
|
|
1148
|
+
conversation: {
|
|
1149
|
+
before: conversationBefore,
|
|
1150
|
+
after: conversation,
|
|
1151
|
+
forward: _forward || null,
|
|
1152
|
+
forwardNote: _forwardNote || ''
|
|
1153
|
+
},
|
|
1154
|
+
messages: {
|
|
1155
|
+
before: messagesBefore,
|
|
1156
|
+
after: messages
|
|
1157
|
+
},
|
|
1158
|
+
message: {
|
|
1159
|
+
before: messageBefore,
|
|
1160
|
+
after: message
|
|
1161
|
+
},
|
|
1162
|
+
context: {
|
|
1163
|
+
before: contextBefore,
|
|
1164
|
+
after: context
|
|
1165
|
+
},
|
|
1166
|
+
followup: followup,
|
|
1167
|
+
entityContextUpsert: entityContextUpsert
|
|
1168
|
+
});
|
|
1169
|
+
case 219:
|
|
1170
|
+
case "end":
|
|
1171
|
+
return _context4.stop();
|
|
1172
|
+
}
|
|
1173
|
+
}, _callee2, null, [[51, 60, 63, 66], [77, 152, 155, 158], [115, 124, 127, 130], [161, 171], [180, 205], [182, 197, 200, 203]]);
|
|
1174
|
+
}));
|
|
1175
|
+
function customer(_x) {
|
|
1176
|
+
return _customer.apply(this, arguments);
|
|
1177
|
+
}
|
|
1178
|
+
return customer;
|
|
1179
|
+
}()
|
|
1180
|
+
};
|
|
1181
|
+
|
|
1182
|
+
exports.Spirits = Spirits;
|