@scout9/app 1.0.0-alpha.0.8.9 → 1.0.0-alpha.0.9.1

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/spirits.cjs CHANGED
@@ -2,14 +2,13 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var _rollupPluginBabelHelpers = require("./_rollupPluginBabelHelpers-606d8129.cjs");
5
+ var _rollupPluginBabelHelpers = require("./_rollupPluginBabelHelpers-9c73c95c.cjs");
6
6
 
7
7
  var _excluded = ["keywords"];
8
8
  /**
9
9
  * @typedef {Object} Document
10
10
  * @property {string} id
11
11
  */
12
-
13
12
  /**
14
13
  * Represents a change with before and after states of a given type.
15
14
  * @template Type The type of the before and after properties.
@@ -17,7 +16,6 @@ var _excluded = ["keywords"];
17
16
  * @property {Type} before - The state before the change.
18
17
  * @property {Type} after - The state after the change.
19
18
  */
20
-
21
19
  /**
22
20
  * @typedef {Object} ConversationData
23
21
  * @property {import('@scout9/app').Scout9ProjectBuildConfig} config - used to define generation and extract persona metadata
@@ -28,7 +26,6 @@ var _excluded = ["keywords"];
28
26
  * @property {import('@scout9/app').ConversationProgress} progress - progress checklist for manual/auto ingress workflows
29
27
  * @property {any} context - event context
30
28
  */
31
-
32
29
  /**
33
30
  * @typedef {Object} ParseOutput
34
31
  * @property {Array<import('@scout9/admin').Message>} messages
@@ -36,7 +33,6 @@ var _excluded = ["keywords"];
36
33
  * @property {import('@scout9/admin').Message} message
37
34
  * @property {any} context
38
35
  */
39
-
40
36
  /**
41
37
  * @typedef {Object} WorkflowOutput
42
38
  * @property {Array<import('@scout9/app').WorkflowResponseSlot>} slots
@@ -44,7 +40,6 @@ var _excluded = ["keywords"];
44
40
  * @property {import('@scout9/app').Conversation} conversation
45
41
  * @property {any} context
46
42
  */
47
-
48
43
  /**
49
44
  * @typedef {Object} GenerateOutput
50
45
  * @property {import('@scout9/admin').GenerateResponse | undefined} generate
@@ -52,44 +47,37 @@ var _excluded = ["keywords"];
52
47
  * @property {import('@scout9/app').Conversation} conversation
53
48
  * @property {any} context
54
49
  */
55
-
56
50
  /**
57
51
  * @callback ParseFun
58
52
  * @param {string} message - message to send
59
53
  * @param {string | undefined} language - language to parse in, defaults to "en" for english
60
54
  * @returns {Promise<import('@scout9/admin').ParseResponse>}
61
55
  */
62
-
63
56
  /**
64
57
  * @callback ContextualizerFun
65
58
  * @param {Pick<import('@scout9/app').WorkflowEvent, 'messages' | 'conversation'>} args - message to send
66
59
  * @returns {Promise<import('@scout9/app').WorkflowEvent['messages']>}
67
60
  */
68
-
69
61
  /**
70
62
  * @callback WorkflowFun
71
63
  * @param {import('@scout9/app').WorkflowEvent} event - conversation data
72
64
  * @returns {Promise<import('@scout9/app').WorkflowResponse>}
73
65
  */
74
-
75
66
  /**
76
67
  * @callback GenerateFun
77
68
  * @param {import('@scout9/admin').GenerateRequestOneOf1} data - data to generate from
78
69
  * @returns {Promise<import('@scout9/admin').GenerateResponse>}
79
70
  */
80
-
81
71
  /**
82
72
  * @callback TransformerFun
83
73
  * @param {import('@scout9/admin').PmtTransformRequest} data - data to generate from
84
74
  * @returns {Promise<import('@scout9/admin').PmtTransformResponse>}
85
75
  */
86
-
87
76
  /**
88
77
  * @callback IdGeneratorFun
89
78
  * @param {import('@scout9/admin').Message['role']} prefix
90
79
  * @returns {string}
91
80
  */
92
-
93
81
  /**
94
82
  * @callback StatusCallback
95
83
  * @param {string} message
@@ -98,7 +86,6 @@ var _excluded = ["keywords"];
98
86
  * @param {any | undefined} [payload]
99
87
  * @returns {void}
100
88
  */
101
-
102
89
  /**
103
90
  * @typedef {Object} CustomerSpiritCallbacks
104
91
  * @property {ParseFun} parser
@@ -109,7 +96,47 @@ var _excluded = ["keywords"];
109
96
  * @property {IdGeneratorFun} idGenerator
110
97
  * @property {StatusCallback | undefined} [progress]
111
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;
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
+ }
112
118
 
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));
113
140
  /**
114
141
  * @typedef {Object} ConversationEvent
115
142
  * @property {(Change<import('@scout9/app').Conversation> & {
@@ -130,7 +157,7 @@ var Spirits = {
130
157
  * @returns {Promise<ConversationEvent>}
131
158
  */
132
159
  customer: function () {
133
- var _customer = _rollupPluginBabelHelpers._asyncToGenerator( /*#__PURE__*/_rollupPluginBabelHelpers._regeneratorRuntime().mark(function _callee(input) {
160
+ var _customer = _rollupPluginBabelHelpers._asyncToGenerator( /*#__PURE__*/_rollupPluginBabelHelpers._regeneratorRuntime().mark(function _callee2(input) {
134
161
  var _recentUserMessage;
135
162
  var onError,
136
163
  customer,
@@ -161,6 +188,8 @@ var Spirits = {
161
188
  incrementLockAttempt,
162
189
  _addInstruction,
163
190
  addInstruction,
191
+ onStatus,
192
+ wrapStep,
164
193
  persona,
165
194
  invalidRoles,
166
195
  parsePayload,
@@ -208,11 +237,11 @@ var Spirits = {
208
237
  _slot,
209
238
  slotId,
210
239
  _tasks2,
240
+ _iterator4,
241
+ _step4,
242
+ instruction,
211
243
  _iterator5,
212
244
  _step5,
213
- instruction,
214
- _iterator6,
215
- _step6,
216
245
  _loop2,
217
246
  manualMessageObj,
218
247
  now,
@@ -228,16 +257,14 @@ var Spirits = {
228
257
  _iterator3,
229
258
  _step3,
230
259
  newMessage,
231
- _iterator4,
232
- _step4,
233
260
  transformResponse,
234
261
  _agentMessages,
235
262
  _lastAgentMessage,
236
- _args3 = arguments;
237
- return _rollupPluginBabelHelpers._regeneratorRuntime().wrap(function _callee$(_context3) {
238
- while (1) switch (_context3.prev = _context3.next) {
263
+ _args4 = arguments;
264
+ return _rollupPluginBabelHelpers._regeneratorRuntime().wrap(function _callee2$(_context4) {
265
+ while (1) switch (_context4.prev = _context4.next) {
239
266
  case 0:
240
- onError = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : function () {};
267
+ onError = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : function () {};
241
268
  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;
242
269
  conversation = input.conversation, messages = input.messages, context = input.context, message = input.message; // Storing post process events here
243
270
  followup = [];
@@ -328,42 +355,78 @@ var Spirits = {
328
355
  if (changedConversation) {
329
356
  progress('Updated conversation', 'info', 'UPDATE_CONVERSATION', newConversation);
330
357
  }
331
- }; // 1. Check inputs
358
+ };
359
+ onStatus = function onStatus(statusType) {
360
+ var completeOrError = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
361
+ progress("".concat(statusType, ": ").concat(completeOrError), 'info', 'STATUS', _rollupPluginBabelHelpers._defineProperty({}, statusType, completeOrError));
362
+ };
363
+ /**
364
+ * @param {Promise<any>} prom
365
+ * @param {string} step
366
+ */
367
+ wrapStep = /*#__PURE__*/function () {
368
+ var _ref = _rollupPluginBabelHelpers._asyncToGenerator( /*#__PURE__*/_rollupPluginBabelHelpers._regeneratorRuntime().mark(function _callee(prom, step) {
369
+ var result;
370
+ return _rollupPluginBabelHelpers._regeneratorRuntime().wrap(function _callee$(_context) {
371
+ while (1) switch (_context.prev = _context.next) {
372
+ case 0:
373
+ _context.prev = 0;
374
+ _context.next = 3;
375
+ return prom;
376
+ case 3:
377
+ result = _context.sent;
378
+ onStatus(step);
379
+ return _context.abrupt("return", result);
380
+ case 8:
381
+ _context.prev = 8;
382
+ _context.t0 = _context["catch"](0);
383
+ onStatus(step, _context.t0.message || 'UNHANDLED ERROR');
384
+ throw SpiritError.fromError(_context.t0, step);
385
+ case 12:
386
+ case "end":
387
+ return _context.stop();
388
+ }
389
+ }, _callee, null, [[0, 8]]);
390
+ }));
391
+ return function wrapStep(_x2, _x3) {
392
+ return _ref.apply(this, arguments);
393
+ };
394
+ }(); // 1. Check inputs
332
395
  if (conversation.$agent) {
333
- _context3.next = 15;
396
+ _context4.next = 17;
334
397
  break;
335
398
  }
336
399
  throw new Error("SpiritsError: No agent found in conversation, must define \".$agent\" in the conversation");
337
- case 15:
400
+ case 17:
338
401
  persona = (config.persona || config.personas || config.agents).find(function (p) {
339
402
  return p.id === conversation.$agent;
340
403
  });
341
404
  if (persona) {
342
- _context3.next = 20;
405
+ _context4.next = 22;
343
406
  break;
344
407
  }
345
408
  if (!(config.persona || config.personas || config.agents).some(function (a) {
346
409
  return !a.id;
347
410
  })) {
348
- _context3.next = 19;
411
+ _context4.next = 21;
349
412
  break;
350
413
  }
351
414
  throw new Error("SpiritsError: No persona found (\"".concat(conversation.$agent, "\") in provided config, some persona's did not contain an \"id\" (Internal Mapping Error)"));
352
- case 19:
415
+ case 21:
353
416
  throw new Error("SpiritsError: No persona found (\"".concat(conversation.$agent, "\") in provided config"));
354
- case 20:
417
+ case 22:
355
418
  if (messages.every(function (m) {
356
419
  return !!m.id;
357
420
  })) {
358
- _context3.next = 22;
421
+ _context4.next = 24;
359
422
  break;
360
423
  }
361
424
  throw new Error("SpiritsError: Every message must have an \".id\", ensure all messages have an id assigned before running");
362
- case 22:
425
+ case 24:
363
426
  if (messages.every(function (m) {
364
427
  return m.role === 'customer' || m.role === 'agent' || m.role === 'system' || m.role === 'tool';
365
428
  })) {
366
- _context3.next = 25;
429
+ _context4.next = 27;
367
430
  break;
368
431
  }
369
432
  invalidRoles = messages.filter(function (m) {
@@ -372,7 +435,7 @@ var Spirits = {
372
435
  throw new Error("SpiritsError: Every message must have a role of \"customer\", \"agent\", or \"system\". Got invalid roles: ".concat(invalidRoles.map(function (m) {
373
436
  return m.role;
374
437
  }).join(', ')));
375
- case 25:
438
+ case 27:
376
439
  // if message is not in messages, then add it
377
440
  if (!messages.find(function (m) {
378
441
  return m.id === input.message.id;
@@ -382,10 +445,10 @@ var Spirits = {
382
445
 
383
446
  // 2. Parse the message
384
447
  progress('Parsing message', 'info', 'SET_PROCESSING', 'user');
385
- _context3.next = 29;
386
- return parser(message.content, 'en');
387
- case 29:
388
- parsePayload = _context3.sent;
448
+ _context4.next = 31;
449
+ return wrapStep(parser(message.content, 'en'), 'parse');
450
+ case 31:
451
+ parsePayload = _context4.sent;
389
452
  if (parsePayload.intent) {
390
453
  message.intent = parsePayload.intent;
391
454
  }
@@ -474,19 +537,19 @@ var Spirits = {
474
537
 
475
538
  // 3. Run the contextualizer
476
539
  progress('Running contextualizer', 'info', 'SET_PROCESSING', 'system');
477
- _context3.next = 47;
478
- return contextualizer({
540
+ _context4.next = 49;
541
+ return wrapStep(contextualizer({
479
542
  conversation: conversation,
480
543
  messages: messages
481
- });
482
- case 47:
483
- newContextMessages = _context3.sent;
544
+ }), 'contextualize');
545
+ case 49:
546
+ newContextMessages = _context4.sent;
484
547
  _iterator = _rollupPluginBabelHelpers._createForOfIteratorHelper(newContextMessages);
485
- _context3.prev = 49;
548
+ _context4.prev = 51;
486
549
  _loop = /*#__PURE__*/_rollupPluginBabelHelpers._regeneratorRuntime().mark(function _loop() {
487
550
  var contextMessage;
488
- return _rollupPluginBabelHelpers._regeneratorRuntime().wrap(function _loop$(_context) {
489
- while (1) switch (_context.prev = _context.next) {
551
+ return _rollupPluginBabelHelpers._regeneratorRuntime().wrap(function _loop$(_context2) {
552
+ while (1) switch (_context2.prev = _context2.next) {
490
553
  case 0:
491
554
  contextMessage = _step.value;
492
555
  if (!messages.find(function (mes) {
@@ -499,36 +562,36 @@ var Spirits = {
499
562
  }
500
563
  case 2:
501
564
  case "end":
502
- return _context.stop();
565
+ return _context2.stop();
503
566
  }
504
567
  }, _loop);
505
568
  });
506
569
  _iterator.s();
507
- case 52:
570
+ case 54:
508
571
  if ((_step = _iterator.n()).done) {
509
- _context3.next = 56;
572
+ _context4.next = 58;
510
573
  break;
511
574
  }
512
- return _context3.delegateYield(_loop(), "t0", 54);
513
- case 54:
514
- _context3.next = 52;
515
- break;
575
+ return _context4.delegateYield(_loop(), "t0", 56);
516
576
  case 56:
517
- _context3.next = 61;
577
+ _context4.next = 54;
518
578
  break;
519
579
  case 58:
520
- _context3.prev = 58;
521
- _context3.t1 = _context3["catch"](49);
522
- _iterator.e(_context3.t1);
523
- case 61:
524
- _context3.prev = 61;
580
+ _context4.next = 63;
581
+ break;
582
+ case 60:
583
+ _context4.prev = 60;
584
+ _context4.t1 = _context4["catch"](51);
585
+ _iterator.e(_context4.t1);
586
+ case 63:
587
+ _context4.prev = 63;
525
588
  _iterator.f();
526
- return _context3.finish(61);
527
- case 64:
589
+ return _context4.finish(63);
590
+ case 66:
528
591
  // 4. Run the workflow
529
592
  progress('Running workflow', 'info', 'SET_PROCESSING', 'system');
530
- _context3.next = 67;
531
- return workflow({
593
+ _context4.next = 69;
594
+ return wrapStep(workflow({
532
595
  messages: messages,
533
596
  conversation: conversation,
534
597
  context: context,
@@ -543,7 +606,7 @@ var Spirits = {
543
606
  initial: conversation.intent || null
544
607
  },
545
608
  stagnationCount: conversation.lockAttempts || 0
546
- }).then(function (res) {
609
+ }), 'workflow').then(function (res) {
547
610
  return Array.isArray(res) ? res : [res];
548
611
  }).then(function (slots) {
549
612
  return slots.reduce(function (accumulator, slot) {
@@ -556,8 +619,8 @@ var Spirits = {
556
619
  return accumulator;
557
620
  }, []);
558
621
  });
559
- case 67:
560
- slots = _context3.sent;
622
+ case 69:
623
+ slots = _context4.sent;
561
624
  hasNoInstructions = slots.every(function (s) {
562
625
  return !s.instructions || Array.isArray(s.instructions) && s.instructions.length === 0;
563
626
  });
@@ -583,20 +646,20 @@ var Spirits = {
583
646
  resettedIntent = false;
584
647
  /** @type {Array<string> | undefined} */
585
648
  _iterator2 = _rollupPluginBabelHelpers._createForOfIteratorHelper(slots);
586
- _context3.prev = 75;
649
+ _context4.prev = 77;
587
650
  _iterator2.s();
588
- case 77:
651
+ case 79:
589
652
  if ((_step2 = _iterator2.n()).done) {
590
- _context3.next = 148;
653
+ _context4.next = 150;
591
654
  break;
592
655
  }
593
656
  _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;
594
657
  if (!anticipate) {
595
- _context3.next = 92;
658
+ _context4.next = 94;
596
659
  break;
597
660
  }
598
661
  if (!Array.isArray(anticipate)) {
599
- _context3.next = 87;
662
+ _context4.next = 89;
600
663
  break;
601
664
  }
602
665
  // 'literal' anticipation
@@ -616,11 +679,11 @@ var Spirits = {
616
679
  slots: _slots,
617
680
  map: map
618
681
  });
619
- _context3.next = 92;
682
+ _context4.next = 94;
620
683
  break;
621
- case 87:
684
+ case 89:
622
685
  if (!('yes' in anticipate && 'no' in anticipate && 'did' in anticipate)) {
623
- _context3.next = 91;
686
+ _context4.next = 93;
624
687
  break;
625
688
  }
626
689
  // "did" anticipation
@@ -632,11 +695,11 @@ var Spirits = {
632
695
  },
633
696
  did: anticipate.did
634
697
  });
635
- _context3.next = 92;
698
+ _context4.next = 94;
636
699
  break;
637
- case 91:
700
+ case 93:
638
701
  throw new Error("Invalid anticipate payload \"".concat(JSON.stringify(anticipate), "\""));
639
- case 92:
702
+ case 94:
640
703
  // tasks from auto/manual ingress to execute
641
704
  if (!!tasks && Array.isArray(tasks) && !!tasks.length) {
642
705
  if (!_tasks) _tasks = [];
@@ -692,25 +755,25 @@ var Spirits = {
692
755
 
693
756
  // Insert instructions context
694
757
  if (!instructions) {
695
- _context3.next = 111;
758
+ _context4.next = 113;
696
759
  break;
697
760
  }
698
761
  if (!(typeof instructions === 'string')) {
699
- _context3.next = 101;
762
+ _context4.next = 103;
700
763
  break;
701
764
  }
702
765
  addInstruction(instructions, previousLockAttempt);
703
- _context3.next = 111;
766
+ _context4.next = 113;
704
767
  break;
705
- case 101:
768
+ case 103:
706
769
  if (!Array.isArray(instructions)) {
707
- _context3.next = 106;
770
+ _context4.next = 108;
708
771
  break;
709
772
  }
710
- _iterator5 = _rollupPluginBabelHelpers._createForOfIteratorHelper(instructions);
773
+ _iterator4 = _rollupPluginBabelHelpers._createForOfIteratorHelper(instructions);
711
774
  try {
712
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
713
- instruction = _step5.value;
775
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
776
+ instruction = _step4.value;
714
777
  if (typeof instruction === 'string') {
715
778
  addInstruction(instruction, previousLockAttempt);
716
779
  } else {
@@ -718,35 +781,35 @@ var Spirits = {
718
781
  }
719
782
  }
720
783
  } catch (err) {
721
- _iterator5.e(err);
784
+ _iterator4.e(err);
722
785
  } finally {
723
- _iterator5.f();
786
+ _iterator4.f();
724
787
  }
725
- _context3.next = 111;
788
+ _context4.next = 113;
726
789
  break;
727
- case 106:
790
+ case 108:
728
791
  if (!(_rollupPluginBabelHelpers._typeof(instructions) === 'object' && 'content' in instructions)) {
729
- _context3.next = 110;
792
+ _context4.next = 112;
730
793
  break;
731
794
  }
732
795
  addInstruction(instructions.content, previousLockAttempt, instructions.id);
733
- _context3.next = 111;
796
+ _context4.next = 113;
734
797
  break;
735
- case 110:
798
+ case 112:
736
799
  throw new Error("SpiritsError: instructions must be a string or array or {content: \"<instruction>\"}, got: ".concat(JSON.stringify(instructions)));
737
- case 111:
800
+ case 113:
738
801
  if (!removeInstructions) {
739
- _context3.next = 128;
802
+ _context4.next = 130;
740
803
  break;
741
804
  }
742
- _iterator6 = _rollupPluginBabelHelpers._createForOfIteratorHelper(removeInstructions);
743
- _context3.prev = 113;
805
+ _iterator5 = _rollupPluginBabelHelpers._createForOfIteratorHelper(removeInstructions);
806
+ _context4.prev = 115;
744
807
  _loop2 = /*#__PURE__*/_rollupPluginBabelHelpers._regeneratorRuntime().mark(function _loop2() {
745
808
  var instructionId, index;
746
- return _rollupPluginBabelHelpers._regeneratorRuntime().wrap(function _loop2$(_context2) {
747
- while (1) switch (_context2.prev = _context2.next) {
809
+ return _rollupPluginBabelHelpers._regeneratorRuntime().wrap(function _loop2$(_context3) {
810
+ while (1) switch (_context3.prev = _context3.next) {
748
811
  case 0:
749
- instructionId = _step6.value;
812
+ instructionId = _step5.value;
750
813
  index = messages.findIndex(function (m) {
751
814
  return m.id === instructionId;
752
815
  });
@@ -760,34 +823,34 @@ var Spirits = {
760
823
  }
761
824
  case 3:
762
825
  case "end":
763
- return _context2.stop();
826
+ return _context3.stop();
764
827
  }
765
828
  }, _loop2);
766
829
  });
767
- _iterator6.s();
768
- case 116:
769
- if ((_step6 = _iterator6.n()).done) {
770
- _context3.next = 120;
830
+ _iterator5.s();
831
+ case 118:
832
+ if ((_step5 = _iterator5.n()).done) {
833
+ _context4.next = 122;
771
834
  break;
772
835
  }
773
- return _context3.delegateYield(_loop2(), "t2", 118);
774
- case 118:
775
- _context3.next = 116;
776
- break;
836
+ return _context4.delegateYield(_loop2(), "t2", 120);
777
837
  case 120:
778
- _context3.next = 125;
838
+ _context4.next = 118;
779
839
  break;
780
840
  case 122:
781
- _context3.prev = 122;
782
- _context3.t3 = _context3["catch"](113);
783
- _iterator6.e(_context3.t3);
784
- case 125:
785
- _context3.prev = 125;
786
- _iterator6.f();
787
- return _context3.finish(125);
788
- case 128:
841
+ _context4.next = 127;
842
+ break;
843
+ case 124:
844
+ _context4.prev = 124;
845
+ _context4.t3 = _context4["catch"](115);
846
+ _iterator5.e(_context4.t3);
847
+ case 127:
848
+ _context4.prev = 127;
849
+ _iterator5.f();
850
+ return _context4.finish(127);
851
+ case 130:
789
852
  if (!manualMessage) {
790
- _context3.next = 144;
853
+ _context4.next = 146;
791
854
  break;
792
855
  }
793
856
  /** @type {import('@scout9/admin').Message} */
@@ -799,25 +862,25 @@ var Spirits = {
799
862
  time: new Date().toISOString()
800
863
  };
801
864
  if (!(_rollupPluginBabelHelpers._typeof(manualMessage) === 'object')) {
802
- _context3.next = 136;
865
+ _context4.next = 138;
803
866
  break;
804
867
  }
805
868
  Object.assign(manualMessageObj, manualMessage);
806
869
  manualMessageObj.role = 'agent';
807
870
  manualMessageObj.time = new Date().toISOString();
808
- _context3.next = 141;
871
+ _context4.next = 143;
809
872
  break;
810
- case 136:
873
+ case 138:
811
874
  if (!(typeof manualMessage === 'string')) {
812
- _context3.next = 140;
875
+ _context4.next = 142;
813
876
  break;
814
877
  }
815
878
  manualMessageObj.content = manualMessage;
816
- _context3.next = 141;
879
+ _context4.next = 143;
817
880
  break;
818
- case 140:
881
+ case 142:
819
882
  throw new Error('Manual message must be of type "string" or "DirectMessage"');
820
- case 141:
883
+ case 143:
821
884
  if (scheduled) {
822
885
  manualMessageObj.time = new Date(scheduled * 1000).toISOString();
823
886
  manualMessageObj.scheduled = manualMessageObj.time;
@@ -829,7 +892,7 @@ var Spirits = {
829
892
  }
830
893
  messages.push(manualMessageObj);
831
894
  progress('Added manual message', 'info', 'ADD_MESSAGE', messages[messages.length - 1]);
832
- case 144:
895
+ case 146:
833
896
  if (contextUpsert) {
834
897
  context = updateContext(context, contextUpsert);
835
898
  progress('Upserted context', 'info', 'UPDATE_CONTEXT', contextUpsert);
@@ -837,21 +900,21 @@ var Spirits = {
837
900
  if (resetIntent) {
838
901
  resettedIntent = true;
839
902
  }
840
- case 146:
841
- _context3.next = 77;
842
- break;
843
903
  case 148:
844
- _context3.next = 153;
904
+ _context4.next = 79;
845
905
  break;
846
906
  case 150:
847
- _context3.prev = 150;
848
- _context3.t4 = _context3["catch"](75);
849
- _iterator2.e(_context3.t4);
850
- case 153:
851
- _context3.prev = 153;
907
+ _context4.next = 155;
908
+ break;
909
+ case 152:
910
+ _context4.prev = 152;
911
+ _context4.t4 = _context4["catch"](77);
912
+ _iterator2.e(_context4.t4);
913
+ case 155:
914
+ _context4.prev = 155;
852
915
  _iterator2.f();
853
- return _context3.finish(153);
854
- case 156:
916
+ return _context4.finish(155);
917
+ case 158:
855
918
  if (resettedIntent && !_forward) {
856
919
  conversation.intent = null;
857
920
  conversation.intentScore = null;
@@ -870,14 +933,14 @@ var Spirits = {
870
933
  // 5. Generate response
871
934
  // If conversation previously locked, don't generate
872
935
  if (input.conversation.locked) {
873
- _context3.next = 208;
936
+ _context4.next = 200;
874
937
  break;
875
938
  }
876
939
  if (!((!conversation.locked || !hasNoInstructions) && !!hasNoCustomMessage)) {
877
- _context3.next = 174;
940
+ _context4.next = 178;
878
941
  break;
879
942
  }
880
- _context3.prev = 159;
943
+ _context4.prev = 161;
881
944
  progress('Generating message', 'info', 'SET_PROCESSING', 'system');
882
945
 
883
946
  /** @type {import('@scout9/admin').GenerateRequestOneOf1} */
@@ -891,10 +954,10 @@ var Spirits = {
891
954
  if (!!_tasks && Array.isArray(_tasks) && !!_tasks.length) {
892
955
  generatorInput.tasks = _tasks;
893
956
  }
894
- _context3.next = 165;
895
- return generator(generatorInput);
896
- case 165:
897
- generatorPayload = _context3.sent;
957
+ _context4.next = 167;
958
+ return wrapStep(generator(generatorInput), 'generate');
959
+ case 167:
960
+ generatorPayload = _context4.sent;
898
961
  if (!generatorPayload.send) {
899
962
  progress('Generated response', 'failed', undefined, {
900
963
  error: ((_generatorPayload$err = generatorPayload.errors) === null || _generatorPayload$err === void 0 ? void 0 : _generatorPayload$err.join('\n\n')) || 'Unknown Reason'
@@ -933,10 +996,10 @@ var Spirits = {
933
996
  };
934
997
 
935
998
  // Copy any other non-nullish fields without overwriting base
936
- return Object.entries(message).reduce(function (acc, _ref) {
937
- var _ref2 = _rollupPluginBabelHelpers._slicedToArray(_ref, 2),
938
- key = _ref2[0],
939
- value = _ref2[1];
999
+ return Object.entries(message).reduce(function (acc, _ref2) {
1000
+ var _ref3 = _rollupPluginBabelHelpers._slicedToArray(_ref2, 2),
1001
+ key = _ref3[0],
1002
+ value = _ref3[1];
940
1003
  if (!Object.prototype.hasOwnProperty.call(acc, key) && value != null) {
941
1004
  acc[key] = value;
942
1005
  }
@@ -945,10 +1008,12 @@ var Spirits = {
945
1008
  })
946
1009
  // De-dupe by content (change the key if you want stricter uniqueness)
947
1010
  .reduce(function (acc, msg) {
948
- var key = String(msg.content); // e.g. `${msg.role}::${msg.content}` for stronger uniqueness
1011
+ var key = String(msg.content || msg.tool_calls ? JSON.stringify(msg.tool_calls) : ''); // e.g. `${msg.role}::${msg.content}` for stronger uniqueness
949
1012
  if (!acc.seen.has(key)) {
950
1013
  acc.seen.add(key);
951
1014
  acc.items.push(msg);
1015
+ } else {
1016
+ console.warn("Duplicate message removed: ".concat(JSON.stringify(msg)));
952
1017
  }
953
1018
  return acc;
954
1019
  }, {
@@ -984,39 +1049,35 @@ var Spirits = {
984
1049
  }
985
1050
  }
986
1051
  }
987
- _context3.next = 174;
1052
+ _context4.next = 176;
988
1053
  break;
989
- case 169:
990
- _context3.prev = 169;
991
- _context3.t5 = _context3["catch"](159);
992
- onError(_context3.t5);
993
- console.error("Spirits: Locking conversation, error generating response: ".concat(_context3.t5.message));
994
- conversation = lockConversation(conversation, 'API: ' + _context3.t5.message);
995
- case 174:
996
- if (!(messagesToTransform.length && transformer)) {
997
- _context3.next = 207;
998
- break;
999
- }
1000
- _context3.prev = 175;
1001
- _iterator4 = _rollupPluginBabelHelpers._createForOfIteratorHelper(messagesToTransform);
1002
- _context3.prev = 177;
1003
- _iterator4.s();
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');
1004
1065
  case 179:
1005
- if ((_step4 = _iterator4.n()).done) {
1006
- _context3.next = 190;
1066
+ if (!(messagesToTransform.length && transformer)) {
1067
+ _context4.next = 197;
1007
1068
  break;
1008
1069
  }
1009
- _step4.value;
1010
- _context3.next = 183;
1011
- return transformer({
1070
+ _context4.prev = 180;
1071
+ _context4.next = 183;
1072
+ return wrapStep(transformer({
1012
1073
  message: messagesToTransform,
1013
1074
  persona: persona,
1014
1075
  customer: customer.id,
1015
1076
  messages: messages,
1016
1077
  context: context
1017
- });
1078
+ }), 'transform');
1018
1079
  case 183:
1019
- transformResponse = _context3.sent;
1080
+ transformResponse = _context4.sent;
1020
1081
  progress('Generated response', 'success', undefined, undefined);
1021
1082
  // Check if already had message
1022
1083
  _agentMessages = messages.filter(function (m) {
@@ -1035,39 +1096,33 @@ var Spirits = {
1035
1096
  });
1036
1097
  progress('Added agent message', 'info', 'ADD_MESSAGE', messages[messages.length - 1]);
1037
1098
  }
1038
- case 188:
1039
- _context3.next = 179;
1099
+
1100
+ // }
1101
+ _context4.next = 195;
1040
1102
  break;
1041
1103
  case 190:
1042
- _context3.next = 195;
1043
- break;
1044
- case 192:
1045
- _context3.prev = 192;
1046
- _context3.t6 = _context3["catch"](177);
1047
- _iterator4.e(_context3.t6);
1104
+ _context4.prev = 190;
1105
+ _context4.t6 = _context4["catch"](180);
1106
+ console.error("Locking conversation, error transforming response: ".concat(_context4.t6.message));
1107
+ conversation = lockConversation(conversation, 'API: ' + _context4.t6.message);
1108
+ onError(_context4.t6);
1048
1109
  case 195:
1049
- _context3.prev = 195;
1050
- _iterator4.f();
1051
- return _context3.finish(195);
1052
- case 198:
1053
- _context3.next = 205;
1054
- break;
1055
- case 200:
1056
- _context3.prev = 200;
1057
- _context3.t7 = _context3["catch"](175);
1058
- console.error("Locking conversation, error transforming response: ".concat(_context3.t7.message));
1059
- conversation = lockConversation(conversation, 'API: ' + _context3.t7.message);
1060
- onError(_context3.t7);
1061
- case 205:
1062
- _context3.next = 208;
1110
+ _context4.next = 198;
1063
1111
  break;
1064
- case 207:
1112
+ case 197:
1065
1113
  if (messagesToTransform.length) {
1066
1114
  console.warn("No transformer provided");
1115
+ onStatus('transform', 'ignored');
1067
1116
  }
1068
- case 208:
1117
+ case 198:
1118
+ _context4.next = 202;
1119
+ break;
1120
+ case 200:
1121
+ onStatus('generate', 'ignored');
1122
+ onStatus('transform', 'ignored');
1123
+ case 202:
1069
1124
  progress('Parsing message', 'info', 'SET_PROCESSING', null);
1070
- return _context3.abrupt("return", {
1125
+ return _context4.abrupt("return", {
1071
1126
  conversation: {
1072
1127
  before: conversationBefore,
1073
1128
  after: conversation,
@@ -1089,11 +1144,11 @@ var Spirits = {
1089
1144
  followup: followup,
1090
1145
  entityContextUpsert: entityContextUpsert
1091
1146
  });
1092
- case 210:
1147
+ case 204:
1093
1148
  case "end":
1094
- return _context3.stop();
1149
+ return _context4.stop();
1095
1150
  }
1096
- }, _callee, null, [[49, 58, 61, 64], [75, 150, 153, 156], [113, 122, 125, 128], [159, 169], [175, 200], [177, 192, 195, 198]]);
1151
+ }, _callee2, null, [[51, 60, 63, 66], [77, 152, 155, 158], [115, 124, 127, 130], [161, 171], [180, 190]]);
1097
1152
  }));
1098
1153
  function customer(_x) {
1099
1154
  return _customer.apply(this, arguments);