@scout9/app 1.0.0-alpha.0.1.99 → 1.0.0-alpha.0.2.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.
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var spirits = require("./spirits-43ce19cf.cjs");
3
+ var spirits = require("./spirits-76855e30.cjs");
4
4
  var require$$0$4 = require('util');
5
5
  var require$$0$3 = require('stream');
6
6
  var require$$1 = require('path');
@@ -39939,7 +39939,7 @@ function _loadUserPackageJson() {
39939
39939
  targetPkgUrl = isTest ? packageTestJsonUrl : packageJsonUrl;
39940
39940
  _context2.t0 = JSON;
39941
39941
  _context2.next = 10;
39942
- return fs__default["default"].readFile(new URL(targetPkgUrl, (typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('dev-1afc1e7b.js', document.baseURI).href))), 'utf-8');
39942
+ return fs__default["default"].readFile(new URL(targetPkgUrl, (typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('dev-df823c44.js', document.baseURI).href))), 'utf-8');
39943
39943
  case 10:
39944
39944
  _context2.t1 = _context2.sent;
39945
39945
  pkg = _context2.t0.parse.call(_context2.t0, _context2.t1);
@@ -40767,13 +40767,22 @@ z.object({
40767
40767
  bus: Bus
40768
40768
  });
40769
40769
 
40770
- var WorkflowConfigurationSchema = z.object({
40771
- entities: z.array(zId('Workflow Folder', z.string()), {
40772
- description: 'Workflow id association, used to handle route params'
40773
- }).min(1, 'Must have at least 1 entity').max(15, 'Cannot have more than 15 entity paths'),
40774
- entity: zId('Workflow Folder', z.string())
40770
+ var ConversationContext = z.record(z.string(), z.any());
40771
+ var ConversationAnticipateSchema = z.object({
40772
+ type: z["enum"](['did', 'literal', 'context'], {
40773
+ description: "Determines the runtime to address the next response"
40774
+ }),
40775
+ slots: z.record(z.string(), z.array(z.any())),
40776
+ did: z.string({
40777
+ description: 'For type \'did\''
40778
+ }).optional(),
40779
+ map: z.array(z.object({
40780
+ slot: z.string(),
40781
+ keywords: z.array(z.string())
40782
+ }), {
40783
+ description: 'For literal keywords, this map helps point which slot the keyword matches to'
40784
+ }).optional()
40775
40785
  });
40776
- var WorkflowsConfigurationSchema = z.array(WorkflowConfigurationSchema);
40777
40786
  var ConversationSchema = z.object({
40778
40787
  $agent: zId('Conversation Agent ID', z.string({
40779
40788
  description: 'Default agent assigned to the conversation(s)'
@@ -40814,34 +40823,10 @@ var ConversationSchema = z.object({
40814
40823
  }).optional().nullable(),
40815
40824
  intentScore: z.number({
40816
40825
  description: 'Confidence score of the assigned intent'
40817
- }).optional().nullable()
40818
- });
40819
- var IntentWorkflowEventSchema = z.object({
40820
- current: z.string().nullable(),
40821
- flow: z.array(z.string()),
40822
- initial: z.string().nullable()
40823
- });
40824
- var WorkflowEventSchema = z.object({
40825
- messages: z.array(MessageSchema),
40826
- conversation: ConversationSchema,
40827
- context: z.any(),
40828
- message: MessageSchema,
40829
- agent: AgentConfigurationSchema.omit({
40830
- transcripts: true,
40831
- audios: true,
40832
- includedLocations: true,
40833
- excludedLocations: true,
40834
- model: true,
40835
- context: true
40836
- }),
40837
- customer: CustomerSchema,
40838
- intent: IntentWorkflowEventSchema,
40839
- stagnationCount: z.number(),
40840
- note: z.string({
40841
- description: 'Any developer notes to provide'
40842
- }).optional()
40826
+ }).optional().nullable(),
40827
+ anticipate: ConversationAnticipateSchema.optional()
40843
40828
  });
40844
- var ConversationContext = z.record(z.string(), z.any());
40829
+
40845
40830
  var ForwardSchema = z.union([z["boolean"](), z.string(), z.object({
40846
40831
  to: z.string().optional(),
40847
40832
  mode: z["enum"](['after-reply', 'immediately']).optional(),
@@ -40916,6 +40901,38 @@ var FollowupSchema = z.union([FollowupBaseSchema.extend({
40916
40901
  }), FollowupBaseSchema.extend({
40917
40902
  instructions: InstructionSchema
40918
40903
  })]);
40904
+ var WorkflowConfigurationSchema = z.object({
40905
+ entities: z.array(zId('Workflow Folder', z.string()), {
40906
+ description: 'Workflow id association, used to handle route params'
40907
+ }).min(1, 'Must have at least 1 entity').max(15, 'Cannot have more than 15 entity paths'),
40908
+ entity: zId('Workflow Folder', z.string())
40909
+ });
40910
+ var WorkflowsConfigurationSchema = z.array(WorkflowConfigurationSchema);
40911
+ var IntentWorkflowEventSchema = z.object({
40912
+ current: z.string().nullable(),
40913
+ flow: z.array(z.string()),
40914
+ initial: z.string().nullable()
40915
+ });
40916
+ var WorkflowEventSchema = z.object({
40917
+ messages: z.array(MessageSchema),
40918
+ conversation: ConversationSchema,
40919
+ context: z.any(),
40920
+ message: MessageSchema,
40921
+ agent: AgentConfigurationSchema.omit({
40922
+ transcripts: true,
40923
+ audios: true,
40924
+ includedLocations: true,
40925
+ excludedLocations: true,
40926
+ model: true,
40927
+ context: true
40928
+ }),
40929
+ customer: CustomerSchema,
40930
+ intent: IntentWorkflowEventSchema,
40931
+ stagnationCount: z.number(),
40932
+ note: z.string({
40933
+ description: 'Any developer notes to provide'
40934
+ }).optional()
40935
+ });
40919
40936
 
40920
40937
  /**
40921
40938
  * The workflow response object slot
@@ -41530,8 +41547,8 @@ var Scout9ProjectBuildConfigSchema = Scout9ProjectConfigSchema.extend({
41530
41547
  * @property {Record<string, string>} params
41531
41548
  */
41532
41549
  var apiFunctionParamsSchema = z.object({
41533
- searchParams: z.record(z.union([z.string(), z.array(z.string())])),
41534
- params: z.record(z.string())
41550
+ searchParams: z.record(z.string(), z.union([z.string(), z.array(z.string())])),
41551
+ params: z.record(z.string(), z.string())
41535
41552
  });
41536
41553
 
41537
41554
  /**
@@ -41550,9 +41567,9 @@ z["function"]().args(apiFunctionParamsSchema).returns(z.promise(eventResponseSch
41550
41567
 
41551
41568
  var ContextExampleWithTrainingDataSchema = z.object({
41552
41569
  input: z.string(),
41553
- output: z.array(z.record(z.any()))
41570
+ output: z.array(z.record(z.string(), z.any()))
41554
41571
  });
41555
- z.union([z.array(ContextExampleWithTrainingDataSchema), z.array(z.record(z.any()))]);
41572
+ z.union([z.array(ContextExampleWithTrainingDataSchema), z.array(z.record(z.string(), z.any()))]);
41556
41573
 
41557
41574
  let FORCE_COLOR,
41558
41575
  NODE_DISABLE_COLORS,
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var spirits = require("./spirits-43ce19cf.cjs");
4
- var dev = require("./dev-1afc1e7b.cjs");
3
+ var spirits = require("./spirits-76855e30.cjs");
4
+ var dev = require("./dev-df823c44.cjs");
5
5
  var require$$0 = require('fs');
6
6
  var require$$2$1 = require('events');
7
7
  var require$$1 = require('path');
@@ -29482,7 +29482,7 @@ class Body {
29482
29482
  }
29483
29483
  const {
29484
29484
  toFormData
29485
- } = await Promise.resolve().then(function () { return require("./multipart-parser-51d88fc4.cjs"); });
29485
+ } = await Promise.resolve().then(function () { return require("./multipart-parser-50a82502.cjs"); });
29486
29486
  return toFormData(this.body, ct);
29487
29487
  }
29488
29488
 
@@ -41891,7 +41891,7 @@ function _loadUserPackageJson() {
41891
41891
  targetPkgUrl = isTest ? packageTestJsonUrl : packageJsonUrl;
41892
41892
  _context.t0 = JSON;
41893
41893
  _context.next = 10;
41894
- return fs__default["default"].readFile(new URL(targetPkgUrl, (typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('index-2aedbf12.js', document.baseURI).href))), 'utf-8');
41894
+ return fs__default["default"].readFile(new URL(targetPkgUrl, (typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('index-332067ab.js', document.baseURI).href))), 'utf-8');
41895
41895
  case 10:
41896
41896
  _context.t1 = _context.sent;
41897
41897
  pkg = _context.t0.parse.call(_context.t0, _context.t1);
@@ -43097,7 +43097,7 @@ var ProjectFiles = /*#__PURE__*/function () {
43097
43097
  return ProjectFiles;
43098
43098
  }();
43099
43099
 
43100
- var __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('index-2aedbf12.js', document.baseURI).href)));
43100
+ var __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('index-332067ab.js', document.baseURI).href)));
43101
43101
  var __dirname$1 = path__default["default"].dirname(__filename$1);
43102
43102
  function zipDirectory(source, out) {
43103
43103
  var archive = archiver$1('tar', {
@@ -43312,7 +43312,7 @@ function _buildApp() {
43312
43312
  case 11:
43313
43313
  _context4.t0 = JSON;
43314
43314
  _context4.next = 14;
43315
- return fs__default["default"].readFile(new URL(templatePackagePath, (typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('index-2aedbf12.js', document.baseURI).href))), 'utf-8');
43315
+ return fs__default["default"].readFile(new URL(templatePackagePath, (typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('index-332067ab.js', document.baseURI).href))), 'utf-8');
43316
43316
  case 14:
43317
43317
  _context4.t1 = _context4.sent;
43318
43318
  packageTemplate = _context4.t0.parse.call(_context4.t0, _context4.t1);
@@ -44046,7 +44046,6 @@ var Scout9Platform = {
44046
44046
  * @param {string} [params.cwd=process.cwd()] - the working directory
44047
44047
  * @param {string} [params.src='./src'] - the source directory
44048
44048
  * @param {string} [params.dest='/tmp/project'] - the destination directory
44049
- * @param {'development' | 'production'} [params.mode='production'] - the build mode
44050
44049
  * @param {boolean} [params.sync=true] - whether to sync the project after deploying
44051
44050
  * @returns {Promise<Scout9ProjectBuildConfig>}
44052
44051
  */
@@ -44072,7 +44071,7 @@ var Scout9Platform = {
44072
44071
  return spirits._regeneratorRuntime().wrap(function _callee2$(_context2) {
44073
44072
  while (1) switch (_context2.prev = _context2.next) {
44074
44073
  case 0:
44075
- _ref2 = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : {}, _ref2$cwd = _ref2.cwd, cwd = _ref2$cwd === void 0 ? process.cwd() : _ref2$cwd, _ref2$src = _ref2.src, src = _ref2$src === void 0 ? './src' : _ref2$src, _ref2$dest = _ref2.dest, dest = _ref2$dest === void 0 ? '/tmp/project' : _ref2$dest, _ref2.mode, _ref2$sync = _ref2.sync, sync$1 = _ref2$sync === void 0 ? true : _ref2$sync;
44074
+ _ref2 = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : {}, _ref2$cwd = _ref2.cwd, cwd = _ref2$cwd === void 0 ? process.cwd() : _ref2$cwd, _ref2$src = _ref2.src, src = _ref2$src === void 0 ? './src' : _ref2$src, _ref2$dest = _ref2.dest, dest = _ref2$dest === void 0 ? '/tmp/project' : _ref2$dest, _ref2$sync = _ref2.sync, sync$1 = _ref2$sync === void 0 ? true : _ref2$sync;
44076
44075
  logger = new dev.ProgressLogger();
44077
44076
  messages = [];
44078
44077
  _context2.prev = 3;
package/dist/index.cjs CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require("./index-2aedbf12.cjs");
6
- var dev = require("./dev-1afc1e7b.cjs");
7
- require("./spirits-43ce19cf.cjs");
5
+ var index = require("./index-332067ab.cjs");
6
+ var dev = require("./dev-df823c44.cjs");
7
+ require("./spirits-76855e30.cjs");
8
8
  require('fs');
9
9
  require('events');
10
10
  require('path');
@@ -2,9 +2,9 @@
2
2
 
3
3
  require('node:fs');
4
4
  require('node:path');
5
- var index = require("./index-2aedbf12.cjs");
6
- require("./spirits-43ce19cf.cjs");
7
- require("./dev-1afc1e7b.cjs");
5
+ var index = require("./index-332067ab.cjs");
6
+ require("./spirits-76855e30.cjs");
7
+ require("./dev-df823c44.cjs");
8
8
  require('util');
9
9
  require('stream');
10
10
  require('path');
@@ -572,6 +572,7 @@ function _classCheckPrivateStaticFieldDescriptor(descriptor, action) {
572
572
  }
573
573
  }
574
574
 
575
+ var _excluded = ["keywords"];
575
576
  /**
576
577
  * @typedef {Object} Document
577
578
  * @property {string} id
@@ -667,6 +668,7 @@ function _classCheckPrivateStaticFieldDescriptor(descriptor, action) {
667
668
  * @property {Change<Array<import('@scout9/app').Message>>} messages
668
669
  * @property {Change<any>} context
669
670
  * @property {Change<import('@scout9/app').Message>} message
671
+ * @property {Array<import('@scout9/app').Followup>} followup
670
672
  */
671
673
  var Spirits = {
672
674
  /**
@@ -677,12 +679,13 @@ var Spirits = {
677
679
  customer: function () {
678
680
  var _customer = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(input) {
679
681
  var _recentUserMessage;
680
- var customer, config, parser, workflow, generator, idGenerator, _input$progress, progress, messageBefore, contextBefore, messagesBefore, conversationBefore, conversation, messages, context, message, updateConversation, updateContext, userMessages, recentUserMessage, lockConversation, incrementLockAttempt, _addInstruction, addInstruction, persona, invalidRoles, parsePayload, index, _message, previousUserMessages, oldKeyCount, newKeyCount, noNewContext, slots, hasNoInstructions, hasNoCustomMessage, previousLockAttempt, resettedIntent, _forward, _forwardNote, _iterator, _step, _step$value, forward, forwardNote, instructions, removeInstructions, manualMessage, scheduled, resetIntent, secondsDelay, contextUpsert, _iterator2, _step2, instruction, _iterator3, _step3, _loop, manualMessageObj, now, generatorPayload, agentMessages, lastAgentMessage;
682
+ var customer, config, parser, workflow, generator, idGenerator, _input$progress, progress, messageBefore, contextBefore, messagesBefore, conversationBefore, conversation, messages, context, message, followup, updateConversation, updateContext, userMessages, recentUserMessage, lockConversation, incrementLockAttempt, _addInstruction, addInstruction, persona, invalidRoles, parsePayload, index, _message, previousUserMessages, oldKeyCount, newKeyCount, noNewContext, slots, hasNoInstructions, hasNoCustomMessage, previousLockAttempt, resettedIntent, _forward, _forwardNote, _iterator, _step, _step$value, forward, forwardNote, instructions, removeInstructions, manualMessage, scheduled, resetIntent, secondsDelay, contextUpsert, anticipate, slotFollowup, _slots, map, i, _anticipate$i, keywords, _slot, slotId, _iterator2, _step2, instruction, _iterator3, _step3, _loop, manualMessageObj, now, generatorPayload, agentMessages, lastAgentMessage;
681
683
  return _regeneratorRuntime().wrap(function _callee$(_context2) {
682
684
  while (1) switch (_context2.prev = _context2.next) {
683
685
  case 0:
684
686
  customer = input.customer, config = input.config, parser = input.parser, workflow = input.workflow, generator = input.generator, 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;
685
- conversation = input.conversation, messages = input.messages, context = input.context, message = input.message; // 0. Setup Helpers
687
+ conversation = input.conversation, messages = input.messages, context = input.context, message = input.message;
688
+ followup = []; // 0. Setup Helpers
686
689
  updateConversation = function updateConversation(previousConversation, conversationUpdates) {
687
690
  progress('Update conversation', 'info', 'UPDATE_CONVERSATION', conversationUpdates);
688
691
  return _objectSpread2(_objectSpread2({}, previousConversation), conversationUpdates);
@@ -771,40 +774,40 @@ var Spirits = {
771
774
  }
772
775
  }; // 1. Check inputs
773
776
  if (conversation.$agent) {
774
- _context2.next = 12;
777
+ _context2.next = 13;
775
778
  break;
776
779
  }
777
780
  throw new Error("SpiritsError: No agent found in conversation, must define \".$agent\" in the conversation");
778
- case 12:
781
+ case 13:
779
782
  persona = (config.persona || config.agents).find(function (p) {
780
783
  return p.id === conversation.$agent;
781
784
  });
782
785
  if (persona) {
783
- _context2.next = 17;
786
+ _context2.next = 18;
784
787
  break;
785
788
  }
786
789
  if (!(config.persona || config.agents).some(function (a) {
787
790
  return !a.id;
788
791
  })) {
789
- _context2.next = 16;
792
+ _context2.next = 17;
790
793
  break;
791
794
  }
792
795
  throw new Error("SpiritsError: No persona found (\"".concat(conversation.$agent, "\") in provided config, some persona's did not contain an \"id\" (Internal Mapping Error)"));
793
- case 16:
794
- throw new Error("SpiritsError: No persona found (\"".concat(conversation.$agent, "\") in provided config"));
795
796
  case 17:
797
+ throw new Error("SpiritsError: No persona found (\"".concat(conversation.$agent, "\") in provided config"));
798
+ case 18:
796
799
  if (messages.every(function (m) {
797
800
  return !!m.id;
798
801
  })) {
799
- _context2.next = 19;
802
+ _context2.next = 20;
800
803
  break;
801
804
  }
802
805
  throw new Error("SpiritsError: Every message must have an \".id\", ensure all messages have an id assigned before running");
803
- case 19:
806
+ case 20:
804
807
  if (messages.every(function (m) {
805
808
  return m.role === 'customer' || m.role === 'agent' || m.role === 'system';
806
809
  })) {
807
- _context2.next = 22;
810
+ _context2.next = 23;
808
811
  break;
809
812
  }
810
813
  invalidRoles = messages.filter(function (m) {
@@ -813,7 +816,7 @@ var Spirits = {
813
816
  throw new Error("SpiritsError: Every message must have a role of \"customer\", \"agent\", or \"system\". Got invalid roles: ".concat(invalidRoles.map(function (m) {
814
817
  return m.role;
815
818
  }).join(', ')));
816
- case 22:
819
+ case 23:
817
820
  // if message is not in messages, then add it
818
821
  if (!messages.find(function (m) {
819
822
  return m.id === input.message.id;
@@ -823,9 +826,9 @@ var Spirits = {
823
826
 
824
827
  // 2. Parse the message
825
828
  progress('Parsing message', 'info', 'SET_PROCESSING', 'user');
826
- _context2.next = 26;
829
+ _context2.next = 27;
827
830
  return parser(message.content, 'en');
828
- case 26:
831
+ case 27:
829
832
  parsePayload = _context2.sent;
830
833
  if (parsePayload.intent) {
831
834
  message.intent = parsePayload.intent;
@@ -893,7 +896,7 @@ var Spirits = {
893
896
  }
894
897
  noNewContext = Object.keys(parsePayload.context).length === 0; // 3. Run the workflow
895
898
  progress('Running workflow', 'info', 'SET_PROCESSING', 'system');
896
- _context2.next = 42;
899
+ _context2.next = 43;
897
900
  return workflow({
898
901
  messages: messages,
899
902
  conversation: conversation,
@@ -912,7 +915,7 @@ var Spirits = {
912
915
  }).then(function (res) {
913
916
  return Array.isArray(res) ? res : [res];
914
917
  });
915
- case 42:
918
+ case 43:
916
919
  slots = _context2.sent;
917
920
  hasNoInstructions = slots.every(function (s) {
918
921
  return !s.instructions || Array.isArray(s) && s.instructions.length === 0;
@@ -935,14 +938,64 @@ var Spirits = {
935
938
  }
936
939
  resettedIntent = false;
937
940
  _iterator = _createForOfIteratorHelper(slots);
938
- _context2.prev = 49;
941
+ _context2.prev = 50;
939
942
  _iterator.s();
940
- case 51:
943
+ case 52:
941
944
  if ((_step = _iterator.n()).done) {
942
- _context2.next = 97;
945
+ _context2.next = 112;
946
+ break;
947
+ }
948
+ _step$value = _step.value, forward = _step$value.forward, forwardNote = _step$value.forwardNote, instructions = _step$value.instructions, removeInstructions = _step$value.removeInstructions, manualMessage = _step$value.message, scheduled = _step$value.scheduled, resetIntent = _step$value.resetIntent, secondsDelay = _step$value.secondsDelay, contextUpsert = _step$value.contextUpsert, anticipate = _step$value.anticipate, slotFollowup = _step$value.followup;
949
+ if (!anticipate) {
950
+ _context2.next = 67;
951
+ break;
952
+ }
953
+ if (!Array.isArray(anticipate)) {
954
+ _context2.next = 62;
943
955
  break;
944
956
  }
945
- _step$value = _step.value, forward = _step$value.forward, forwardNote = _step$value.forwardNote, instructions = _step$value.instructions, removeInstructions = _step$value.removeInstructions, manualMessage = _step$value.message, scheduled = _step$value.scheduled, resetIntent = _step$value.resetIntent, secondsDelay = _step$value.secondsDelay, contextUpsert = _step$value.contextUpsert;
957
+ // 'literal' anticipation
958
+ _slots = {};
959
+ map = [];
960
+ for (i = 0; i < anticipate.length; i++) {
961
+ _anticipate$i = anticipate[i], keywords = _anticipate$i.keywords, _slot = _objectWithoutProperties(_anticipate$i, _excluded);
962
+ slotId = "".concat(i);
963
+ _slots[slotId] = _slot;
964
+ map.push({
965
+ slot: slotId,
966
+ keywords: keywords
967
+ });
968
+ }
969
+ updateConversation(conversation, {
970
+ type: 'literal',
971
+ slots: _slots,
972
+ map: map
973
+ });
974
+ _context2.next = 67;
975
+ break;
976
+ case 62:
977
+ if (!('yes' in anticipate && 'no' in anticipate && 'did' in anticipate)) {
978
+ _context2.next = 66;
979
+ break;
980
+ }
981
+ // "did" anticipation
982
+ updateConversation(conversation, {
983
+ type: 'did',
984
+ slots: {
985
+ yes: anticipate.yes,
986
+ no: anticipate.no
987
+ },
988
+ did: anticipate.did
989
+ });
990
+ _context2.next = 67;
991
+ break;
992
+ case 66:
993
+ throw new Error("Invalid anticipate payload \"".concat(JSON.stringify(anticipate), "\""));
994
+ case 67:
995
+ if (slotFollowup) {
996
+ followup.push(slotFollowup);
997
+ }
998
+
946
999
  // Forward to agent or other agent
947
1000
  if (forward) {
948
1001
  conversation = lockConversation(conversation, 'App instructed forward');
@@ -986,19 +1039,19 @@ var Spirits = {
986
1039
 
987
1040
  // Insert instructions context
988
1041
  if (!instructions) {
989
- _context2.next = 69;
1042
+ _context2.next = 84;
990
1043
  break;
991
1044
  }
992
1045
  if (!(typeof instructions === 'string')) {
993
- _context2.next = 59;
1046
+ _context2.next = 74;
994
1047
  break;
995
1048
  }
996
1049
  addInstruction(instructions, previousLockAttempt);
997
- _context2.next = 69;
1050
+ _context2.next = 84;
998
1051
  break;
999
- case 59:
1052
+ case 74:
1000
1053
  if (!Array.isArray(instructions)) {
1001
- _context2.next = 64;
1054
+ _context2.next = 79;
1002
1055
  break;
1003
1056
  }
1004
1057
  _iterator2 = _createForOfIteratorHelper(instructions);
@@ -1016,25 +1069,25 @@ var Spirits = {
1016
1069
  } finally {
1017
1070
  _iterator2.f();
1018
1071
  }
1019
- _context2.next = 69;
1072
+ _context2.next = 84;
1020
1073
  break;
1021
- case 64:
1074
+ case 79:
1022
1075
  if (!(_typeof(instructions) === 'object' && 'content' in instructions && 'id' in instructions)) {
1023
- _context2.next = 68;
1076
+ _context2.next = 83;
1024
1077
  break;
1025
1078
  }
1026
1079
  addInstruction(instructions.content, previousLockAttempt, instructions.id);
1027
- _context2.next = 69;
1080
+ _context2.next = 84;
1028
1081
  break;
1029
- case 68:
1082
+ case 83:
1030
1083
  throw new Error('SpiritsError: instructions must be a string or array or {content: "", id: ""}');
1031
- case 69:
1084
+ case 84:
1032
1085
  if (!removeInstructions) {
1033
- _context2.next = 86;
1086
+ _context2.next = 101;
1034
1087
  break;
1035
1088
  }
1036
1089
  _iterator3 = _createForOfIteratorHelper(removeInstructions);
1037
- _context2.prev = 71;
1090
+ _context2.prev = 86;
1038
1091
  _loop = /*#__PURE__*/_regeneratorRuntime().mark(function _loop() {
1039
1092
  var instructionId, index;
1040
1093
  return _regeneratorRuntime().wrap(function _loop$(_context) {
@@ -1057,29 +1110,29 @@ var Spirits = {
1057
1110
  }, _loop);
1058
1111
  });
1059
1112
  _iterator3.s();
1060
- case 74:
1113
+ case 89:
1061
1114
  if ((_step3 = _iterator3.n()).done) {
1062
- _context2.next = 78;
1115
+ _context2.next = 93;
1063
1116
  break;
1064
1117
  }
1065
- return _context2.delegateYield(_loop(), "t0", 76);
1066
- case 76:
1067
- _context2.next = 74;
1118
+ return _context2.delegateYield(_loop(), "t0", 91);
1119
+ case 91:
1120
+ _context2.next = 89;
1068
1121
  break;
1069
- case 78:
1070
- _context2.next = 83;
1122
+ case 93:
1123
+ _context2.next = 98;
1071
1124
  break;
1072
- case 80:
1073
- _context2.prev = 80;
1074
- _context2.t1 = _context2["catch"](71);
1125
+ case 95:
1126
+ _context2.prev = 95;
1127
+ _context2.t1 = _context2["catch"](86);
1075
1128
  _iterator3.e(_context2.t1);
1076
- case 83:
1077
- _context2.prev = 83;
1129
+ case 98:
1130
+ _context2.prev = 98;
1078
1131
  _iterator3.f();
1079
- return _context2.finish(83);
1080
- case 86:
1132
+ return _context2.finish(98);
1133
+ case 101:
1081
1134
  if (!manualMessage) {
1082
- _context2.next = 93;
1135
+ _context2.next = 108;
1083
1136
  break;
1084
1137
  }
1085
1138
  manualMessageObj = {
@@ -1089,11 +1142,11 @@ var Spirits = {
1089
1142
  time: new Date().toISOString()
1090
1143
  };
1091
1144
  if (!(typeof manualMessage !== 'string')) {
1092
- _context2.next = 90;
1145
+ _context2.next = 105;
1093
1146
  break;
1094
1147
  }
1095
1148
  throw new Error('Manual message must be of type "string"');
1096
- case 90:
1149
+ case 105:
1097
1150
  if (scheduled) {
1098
1151
  manualMessageObj.time = new Date(scheduled * 1000).toISOString();
1099
1152
  manualMessageObj.scheduled = manualMessageObj.time;
@@ -1105,7 +1158,7 @@ var Spirits = {
1105
1158
  }
1106
1159
  messages.push(manualMessageObj);
1107
1160
  progress('Added manual message', 'info', 'ADD_MESSAGE', messages[messages.length - 1]);
1108
- case 93:
1161
+ case 108:
1109
1162
  if (contextUpsert) {
1110
1163
  context = updateContext(context, contextUpsert);
1111
1164
  progress('Upserted context', 'info', 'UPDATE_CONTEXT', contextUpsert);
@@ -1113,21 +1166,21 @@ var Spirits = {
1113
1166
  if (resetIntent) {
1114
1167
  resettedIntent = true;
1115
1168
  }
1116
- case 95:
1117
- _context2.next = 51;
1169
+ case 110:
1170
+ _context2.next = 52;
1118
1171
  break;
1119
- case 97:
1120
- _context2.next = 102;
1172
+ case 112:
1173
+ _context2.next = 117;
1121
1174
  break;
1122
- case 99:
1123
- _context2.prev = 99;
1124
- _context2.t2 = _context2["catch"](49);
1175
+ case 114:
1176
+ _context2.prev = 114;
1177
+ _context2.t2 = _context2["catch"](50);
1125
1178
  _iterator.e(_context2.t2);
1126
- case 102:
1127
- _context2.prev = 102;
1179
+ case 117:
1180
+ _context2.prev = 117;
1128
1181
  _iterator.f();
1129
- return _context2.finish(102);
1130
- case 105:
1182
+ return _context2.finish(117);
1183
+ case 120:
1131
1184
  if (resettedIntent && !_forward) {
1132
1185
  conversation.intent = null;
1133
1186
  conversation.intentScore = null;
@@ -1146,16 +1199,16 @@ var Spirits = {
1146
1199
  // 4. Generate response
1147
1200
  // If conversation previously locked, don't generate
1148
1201
  if (input.conversation.locked) {
1149
- _context2.next = 120;
1202
+ _context2.next = 135;
1150
1203
  break;
1151
1204
  }
1152
1205
  if (!((!conversation.locked || !hasNoInstructions) && !!hasNoCustomMessage)) {
1153
- _context2.next = 120;
1206
+ _context2.next = 135;
1154
1207
  break;
1155
1208
  }
1156
- _context2.prev = 108;
1209
+ _context2.prev = 123;
1157
1210
  progress('Parsing message', 'info', 'SET_PROCESSING', 'system');
1158
- _context2.next = 112;
1211
+ _context2.next = 127;
1159
1212
  return generator({
1160
1213
  messages: messages,
1161
1214
  persona: persona,
@@ -1163,7 +1216,7 @@ var Spirits = {
1163
1216
  llm: config.llm,
1164
1217
  pmt: config.pmt
1165
1218
  });
1166
- case 112:
1219
+ case 127:
1167
1220
  generatorPayload = _context2.sent;
1168
1221
  if (!generatorPayload.send) {
1169
1222
  progress('Generated response', 'failed', undefined, {
@@ -1200,14 +1253,14 @@ var Spirits = {
1200
1253
  }
1201
1254
  }
1202
1255
  }
1203
- _context2.next = 120;
1256
+ _context2.next = 135;
1204
1257
  break;
1205
- case 116:
1206
- _context2.prev = 116;
1207
- _context2.t3 = _context2["catch"](108);
1258
+ case 131:
1259
+ _context2.prev = 131;
1260
+ _context2.t3 = _context2["catch"](123);
1208
1261
  console.error("Locking conversation, error generating response: ".concat(_context2.t3.message));
1209
1262
  conversation = lockConversation(conversation, 'API: ' + _context2.t3.message);
1210
- case 120:
1263
+ case 135:
1211
1264
  progress('Parsing message', 'info', 'SET_PROCESSING', null);
1212
1265
  return _context2.abrupt("return", {
1213
1266
  conversation: {
@@ -1227,13 +1280,14 @@ var Spirits = {
1227
1280
  context: {
1228
1281
  before: contextBefore,
1229
1282
  after: context
1230
- }
1283
+ },
1284
+ followup: followup
1231
1285
  });
1232
- case 122:
1286
+ case 137:
1233
1287
  case "end":
1234
1288
  return _context2.stop();
1235
1289
  }
1236
- }, _callee, null, [[49, 99, 102, 105], [71, 80, 83, 86], [108, 116]]);
1290
+ }, _callee, null, [[50, 114, 117, 120], [86, 95, 98, 101], [123, 131]]);
1237
1291
  }));
1238
1292
  function customer(_x) {
1239
1293
  return _customer.apply(this, arguments);
package/dist/spirits.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var spirits = require("./spirits-43ce19cf.cjs");
5
+ var spirits = require("./spirits-76855e30.cjs");
6
6
 
7
7
 
8
8
 
@@ -2,8 +2,8 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var dev = require("./dev-1afc1e7b.cjs");
6
- require("./spirits-43ce19cf.cjs");
5
+ var dev = require("./dev-df823c44.cjs");
6
+ require("./spirits-76855e30.cjs");
7
7
  require('util');
8
8
  require('stream');
9
9
  require('path');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scout9/app",
3
- "version": "1.0.0-alpha.0.1.99",
3
+ "version": "1.0.0-alpha.0.2.1",
4
4
  "description": "Build and deploy your Scout9 app for SMS auto replies",
5
5
  "publishConfig": {
6
6
  "access": "public"
package/src/cli.js CHANGED
@@ -84,7 +84,6 @@ prog
84
84
  prog
85
85
  .command('deploy')
86
86
  .describe('Deploy your scout9 app')
87
- .option('--mode', 'Specify a mode for loading environment variables', 'production')
88
87
  .option('--src', 'Project source code folder', 'src')
89
88
  .option('--sync, -s', 'Syncs project after deploying (overwriting code)', true)
90
89
  .option('--dest', 'Project local destination', './build')
package/src/platform.js CHANGED
@@ -52,7 +52,6 @@ export const Scout9Platform = {
52
52
  * @param {string} [params.cwd=process.cwd()] - the working directory
53
53
  * @param {string} [params.src='./src'] - the source directory
54
54
  * @param {string} [params.dest='/tmp/project'] - the destination directory
55
- * @param {'development' | 'production'} [params.mode='production'] - the build mode
56
55
  * @param {boolean} [params.sync=true] - whether to sync the project after deploying
57
56
  * @returns {Promise<Scout9ProjectBuildConfig>}
58
57
  */
@@ -61,7 +60,6 @@ export const Scout9Platform = {
61
60
  cwd = process.cwd(),
62
61
  src = './src',
63
62
  dest = '/tmp/project',
64
- mode = 'production',
65
63
  sync = true
66
64
  } = {}
67
65
  ) {
package/src/public.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  * Application platform for managing auto reply workflows from personal communication methods
5
5
  *
6
6
  *
7
- * NOTE: This file was auto generated 7/10/2024, 2:51:29 PM
7
+ * NOTE: This file was auto generated 8/17/2024, 8:45:07 AM
8
8
  * Do not edit the file manually.
9
9
  */
10
10
 
@@ -491,6 +491,21 @@ export type ContextExampleWithTrainingData = {
491
491
  }[];
492
492
  };
493
493
 
494
+ export type ConversationAnticipate = {
495
+ /** Determines the runtime to address the next response */
496
+ type: "did" | "literal" | "context";
497
+ slots: {
498
+ [x: string]: any[];
499
+ };
500
+ /** For type 'did' */
501
+ did?: string | undefined;
502
+ /** For literal keywords, this map helps point which slot the keyword matches to */
503
+ map?: {
504
+ slot: string;
505
+ keywords: string[];
506
+ }[] | undefined;
507
+ };
508
+
494
509
  export type ConversationContext = {
495
510
  [x: string]: any;
496
511
  };
@@ -524,6 +539,20 @@ export type Conversation = {
524
539
  intent?: (string | undefined) | null;
525
540
  /** Confidence score of the assigned intent */
526
541
  intentScore?: (number | undefined) | null;
542
+ anticipate?: {
543
+ /** Determines the runtime to address the next response */
544
+ type: "did" | "literal" | "context";
545
+ slots: {
546
+ [x: string]: any[];
547
+ };
548
+ /** For type 'did' */
549
+ did?: string | undefined;
550
+ /** For literal keywords, this map helps point which slot the keyword matches to */
551
+ map?: {
552
+ slot: string;
553
+ keywords: string[];
554
+ }[] | undefined;
555
+ } | undefined;
527
556
  };
528
557
 
529
558
  export type Customer = {
@@ -1243,6 +1272,20 @@ export type WorkflowEvent = {
1243
1272
  intent?: (string | undefined) | null;
1244
1273
  /** Confidence score of the assigned intent */
1245
1274
  intentScore?: (number | undefined) | null;
1275
+ anticipate?: {
1276
+ /** Determines the runtime to address the next response */
1277
+ type: "did" | "literal" | "context";
1278
+ slots: {
1279
+ [x: string]: any[];
1280
+ };
1281
+ /** For type 'did' */
1282
+ did?: string | undefined;
1283
+ /** For literal keywords, this map helps point which slot the keyword matches to */
1284
+ map?: {
1285
+ slot: string;
1286
+ keywords: string[];
1287
+ }[] | undefined;
1288
+ } | undefined;
1246
1289
  };
1247
1290
  context?: any;
1248
1291
  message: {
@@ -1373,6 +1416,20 @@ export type WorkflowFunction = (args_0: {
1373
1416
  intent?: (string | undefined) | null;
1374
1417
  /** Confidence score of the assigned intent */
1375
1418
  intentScore?: (number | undefined) | null;
1419
+ anticipate?: {
1420
+ /** Determines the runtime to address the next response */
1421
+ type: "did" | "literal" | "context";
1422
+ slots: {
1423
+ [x: string]: any[];
1424
+ };
1425
+ /** For type 'did' */
1426
+ did?: string | undefined;
1427
+ /** For literal keywords, this map helps point which slot the keyword matches to */
1428
+ map?: {
1429
+ slot: string;
1430
+ keywords: string[];
1431
+ }[] | undefined;
1432
+ } | undefined;
1376
1433
  };
1377
1434
  context?: any;
1378
1435
  message: {
@@ -0,0 +1,35 @@
1
+ import { z } from 'zod';
2
+ import { zId } from './utils.js';
3
+
4
+ export const ConversationContext = z.record(z.string(), z.any());
5
+
6
+ export const ConversationAnticipateSchema = z.object({
7
+ type: z.enum(['did', 'literal', 'context'], {description: "Determines the runtime to address the next response"}),
8
+ slots: z.record(z.string(), z.array(z.any())),
9
+ did: z.string({description: 'For type \'did\''}).optional(),
10
+ map: z.array(z.object({
11
+ slot: z.string(),
12
+ keywords: z.array(z.string())
13
+ }), {description: 'For literal keywords, this map helps point which slot the keyword matches to'}).optional()
14
+ });
15
+
16
+ export const ConversationSchema = z.object({
17
+ $agent: zId('Conversation Agent ID', z.string({description: 'Default agent assigned to the conversation(s)'})),
18
+ $customer: zId('Conversation Customer ID', z.string({description: 'Customer this conversation is with'})),
19
+ initialContexts: z.array(z.string(), {description: 'Initial contexts to load when starting the conversation'})
20
+ .optional(),
21
+ environment: z.enum(['phone', 'email', 'web']),
22
+ environmentProps: z.object({
23
+ subject: z.string({description: 'HTML Subject of the conversation'}).optional(),
24
+ platformEmailThreadId: z.string({description: 'Used to sync email messages with the conversation'}).optional()
25
+ }).optional(),
26
+ locked: z.boolean({description: 'Whether the conversation is locked or not'}).optional().nullable(),
27
+ lockedReason: z.string({description: 'Why this conversation was locked'}).optional().nullable(),
28
+ lockAttempts: z.number({description: 'Number attempts made until conversation is locked'}).optional().nullable(),
29
+ forwardedTo: z.string({description: 'What personaId/phone/email was forwarded'}).optional().nullable(),
30
+ forwarded: z.string({description: 'Datetime ISO 8601 timestamp when persona was forwarded'}).optional().nullable(),
31
+ forwardNote: z.string().optional().nullable(),
32
+ intent: z.string({description: 'Detected intent of conversation'}).optional().nullable(),
33
+ intentScore: z.number({description: 'Confidence score of the assigned intent'}).optional().nullable(),
34
+ anticipate: ConversationAnticipateSchema.optional()
35
+ });
@@ -5,5 +5,6 @@ export * from './entity.js';
5
5
  export * from './message.js';
6
6
  export * from './workflow.js';
7
7
  export * from './platform.js';
8
+ export * from './conversation.js';
8
9
  export * from './macros.js';
9
10
 
@@ -2,11 +2,11 @@ import { z } from "zod";
2
2
 
3
3
  export const ContextExampleWithTrainingDataSchema = z.object({
4
4
  input: z.string(),
5
- output: z.array(z.record(z.any())),
5
+ output: z.array(z.record(z.string(), z.any())),
6
6
  });
7
7
 
8
8
  export const ContextExampleSchema = z.union([
9
9
  z.array(ContextExampleWithTrainingDataSchema),
10
- z.array(z.record(z.any())),
10
+ z.array(z.record(z.string(), z.any())),
11
11
  ]);
12
12
 
@@ -8,8 +8,8 @@ import { eventResponseSchema } from './api.js';
8
8
  * @property {Record<string, string>} params
9
9
  */
10
10
  const apiFunctionParamsSchema = z.object({
11
- searchParams: z.record(z.union([z.string(), z.array(z.string())])),
12
- params: z.record(z.string())
11
+ searchParams: z.record(z.string(), z.union([z.string(), z.array(z.string())])),
12
+ params: z.record(z.string(), z.string())
13
13
  });
14
14
 
15
15
  /**
@@ -4,68 +4,9 @@ import { z } from 'zod';
4
4
  import { zId } from './utils.js';
5
5
  import { AgentConfigurationSchema, CustomerSchema } from './users.js';
6
6
  import { MessageSchema } from './message.js';
7
+ import { ConversationSchema, ConversationContext } from './conversation.js';
7
8
 
8
9
 
9
- export const WorkflowConfigurationSchema = z.object({
10
- entities: z.array(
11
- zId('Workflow Folder', z.string()),
12
- {description: 'Workflow id association, used to handle route params'}
13
- )
14
- .min(1, 'Must have at least 1 entity')
15
- .max(15, 'Cannot have more than 15 entity paths'),
16
- entity: zId('Workflow Folder', z.string())
17
- });
18
-
19
- export const WorkflowsConfigurationSchema = z.array(WorkflowConfigurationSchema);
20
-
21
-
22
- export const ConversationSchema = z.object({
23
- $agent: zId('Conversation Agent ID', z.string({description: 'Default agent assigned to the conversation(s)'})),
24
- $customer: zId('Conversation Customer ID', z.string({description: 'Customer this conversation is with'})),
25
- initialContexts: z.array(z.string(), {description: 'Initial contexts to load when starting the conversation'})
26
- .optional(),
27
- environment: z.enum(['phone', 'email', 'web']),
28
- environmentProps: z.object({
29
- subject: z.string({description: 'HTML Subject of the conversation'}).optional(),
30
- platformEmailThreadId: z.string({description: 'Used to sync email messages with the conversation'}).optional()
31
- }).optional(),
32
- locked: z.boolean({description: 'Whether the conversation is locked or not'}).optional().nullable(),
33
- lockedReason: z.string({description: 'Why this conversation was locked'}).optional().nullable(),
34
- lockAttempts: z.number({description: 'Number attempts made until conversation is locked'}).optional().nullable(),
35
- forwardedTo: z.string({description: 'What personaId/phone/email was forwarded'}).optional().nullable(),
36
- forwarded: z.string({description: 'Datetime ISO 8601 timestamp when persona was forwarded'}).optional().nullable(),
37
- forwardNote: z.string().optional().nullable(),
38
- intent: z.string({description: 'Detected intent of conversation'}).optional().nullable(),
39
- intentScore: z.number({description: 'Confidence score of the assigned intent'}).optional().nullable()
40
- });
41
-
42
- export const IntentWorkflowEventSchema = z.object({
43
- current: z.string().nullable(),
44
- flow: z.array(z.string()),
45
- initial: z.string().nullable()
46
- });
47
-
48
- export const WorkflowEventSchema = z.object({
49
- messages: z.array(MessageSchema),
50
- conversation: ConversationSchema,
51
- context: z.any(),
52
- message: MessageSchema,
53
- agent: AgentConfigurationSchema.omit({
54
- transcripts: true,
55
- audios: true,
56
- includedLocations: true,
57
- excludedLocations: true,
58
- model: true,
59
- context: true
60
- }),
61
- customer: CustomerSchema,
62
- intent: IntentWorkflowEventSchema,
63
- stagnationCount: z.number(),
64
- note: z.string({description: 'Any developer notes to provide'}).optional()
65
- });
66
-
67
- export const ConversationContext = z.record(z.string(), z.any());
68
-
69
10
  export const ForwardSchema = z.union([
70
11
  z.boolean(),
71
12
  z.string(),
@@ -160,6 +101,44 @@ export const FollowupSchema = z.union([
160
101
  })
161
102
  ]);
162
103
 
104
+
105
+ export const WorkflowConfigurationSchema = z.object({
106
+ entities: z.array(
107
+ zId('Workflow Folder', z.string()),
108
+ {description: 'Workflow id association, used to handle route params'}
109
+ )
110
+ .min(1, 'Must have at least 1 entity')
111
+ .max(15, 'Cannot have more than 15 entity paths'),
112
+ entity: zId('Workflow Folder', z.string())
113
+ });
114
+
115
+ export const WorkflowsConfigurationSchema = z.array(WorkflowConfigurationSchema);
116
+
117
+ export const IntentWorkflowEventSchema = z.object({
118
+ current: z.string().nullable(),
119
+ flow: z.array(z.string()),
120
+ initial: z.string().nullable()
121
+ });
122
+
123
+ export const WorkflowEventSchema = z.object({
124
+ messages: z.array(MessageSchema),
125
+ conversation: ConversationSchema,
126
+ context: z.any(),
127
+ message: MessageSchema,
128
+ agent: AgentConfigurationSchema.omit({
129
+ transcripts: true,
130
+ audios: true,
131
+ includedLocations: true,
132
+ excludedLocations: true,
133
+ model: true,
134
+ context: true
135
+ }),
136
+ customer: CustomerSchema,
137
+ intent: IntentWorkflowEventSchema,
138
+ stagnationCount: z.number(),
139
+ note: z.string({description: 'Any developer notes to provide'}).optional()
140
+ });
141
+
163
142
  /**
164
143
  * The workflow response object slot
165
144
  */
@@ -94,6 +94,7 @@
94
94
  * @property {Change<Array<import('@scout9/app').Message>>} messages
95
95
  * @property {Change<any>} context
96
96
  * @property {Change<import('@scout9/app').Message>} message
97
+ * @property {Array<import('@scout9/app').Followup>} followup
97
98
  */
98
99
  export const Spirits = {
99
100
 
@@ -118,6 +119,7 @@ export const Spirits = {
118
119
  conversation: conversationBefore
119
120
  } = input;
120
121
  let {conversation, messages, context, message} = input;
122
+ const followup = [];
121
123
 
122
124
  // 0. Setup Helpers
123
125
  const updateConversation = (previousConversation, conversationUpdates) => {
@@ -360,9 +362,50 @@ export const Spirits = {
360
362
  scheduled,
361
363
  resetIntent,
362
364
  secondsDelay,
363
- contextUpsert
365
+ contextUpsert,
366
+ anticipate,
367
+ followup: slotFollowup,
364
368
  } of slots) {
365
369
 
370
+ // Anticipate customer response
371
+ if (anticipate) {
372
+ if (Array.isArray(anticipate)) {
373
+ // 'literal' anticipation
374
+ const slots = {};
375
+ const map = [];
376
+ for (let i = 0; i < anticipate.length; i++) {
377
+ const {keywords, ..._slot} = anticipate[i];
378
+ const slotId = `${i}`;
379
+ slots[slotId] = _slot;
380
+ map.push({
381
+ slot: slotId,
382
+ keywords
383
+ });
384
+ }
385
+ updateConversation(conversation, {
386
+ type: 'literal',
387
+ slots,
388
+ map
389
+ });
390
+ } else if ('yes' in anticipate && 'no' in anticipate && 'did' in anticipate) {
391
+ // "did" anticipation
392
+ updateConversation(conversation, {
393
+ type: 'did',
394
+ slots: {
395
+ yes: anticipate.yes,
396
+ no: anticipate.no
397
+ },
398
+ did: anticipate.did,
399
+ });
400
+ } else {
401
+ throw new Error(`Invalid anticipate payload "${JSON.stringify(anticipate)}"`);
402
+ }
403
+ }
404
+
405
+ if (slotFollowup) {
406
+ followup.push(slotFollowup);
407
+ }
408
+
366
409
  // Forward to agent or other agent
367
410
  if (forward) {
368
411
  conversation = lockConversation(conversation, 'App instructed forward');
@@ -564,7 +607,8 @@ export const Spirits = {
564
607
  context: {
565
608
  before: contextBefore,
566
609
  after: context
567
- }
610
+ },
611
+ followup
568
612
  };
569
613
  }
570
614
  };
package/types/index.d.ts CHANGED
@@ -4,7 +4,7 @@ declare module '@scout9/app' {
4
4
  * Application platform for managing auto reply workflows from personal communication methods
5
5
  *
6
6
  *
7
- * NOTE: This file was auto generated 7/10/2024, 2:51:29 PM
7
+ * NOTE: This file was auto generated 8/17/2024, 8:45:07 AM
8
8
  * Do not edit the file manually.
9
9
  */
10
10
 
@@ -454,6 +454,21 @@ declare module '@scout9/app' {
454
454
  }[];
455
455
  };
456
456
 
457
+ export type ConversationAnticipate = {
458
+ /** Determines the runtime to address the next response */
459
+ type: "did" | "literal" | "context";
460
+ slots: {
461
+ [x: string]: any[];
462
+ };
463
+ /** For type 'did' */
464
+ did?: string | undefined;
465
+ /** For literal keywords, this map helps point which slot the keyword matches to */
466
+ map?: {
467
+ slot: string;
468
+ keywords: string[];
469
+ }[] | undefined;
470
+ };
471
+
457
472
  export type ConversationContext = {
458
473
  [x: string]: any;
459
474
  };
@@ -487,6 +502,20 @@ declare module '@scout9/app' {
487
502
  intent?: (string | undefined) | null;
488
503
  /** Confidence score of the assigned intent */
489
504
  intentScore?: (number | undefined) | null;
505
+ anticipate?: {
506
+ /** Determines the runtime to address the next response */
507
+ type: "did" | "literal" | "context";
508
+ slots: {
509
+ [x: string]: any[];
510
+ };
511
+ /** For type 'did' */
512
+ did?: string | undefined;
513
+ /** For literal keywords, this map helps point which slot the keyword matches to */
514
+ map?: {
515
+ slot: string;
516
+ keywords: string[];
517
+ }[] | undefined;
518
+ } | undefined;
490
519
  };
491
520
 
492
521
  export type Customer = {
@@ -1206,6 +1235,20 @@ declare module '@scout9/app' {
1206
1235
  intent?: (string | undefined) | null;
1207
1236
  /** Confidence score of the assigned intent */
1208
1237
  intentScore?: (number | undefined) | null;
1238
+ anticipate?: {
1239
+ /** Determines the runtime to address the next response */
1240
+ type: "did" | "literal" | "context";
1241
+ slots: {
1242
+ [x: string]: any[];
1243
+ };
1244
+ /** For type 'did' */
1245
+ did?: string | undefined;
1246
+ /** For literal keywords, this map helps point which slot the keyword matches to */
1247
+ map?: {
1248
+ slot: string;
1249
+ keywords: string[];
1250
+ }[] | undefined;
1251
+ } | undefined;
1209
1252
  };
1210
1253
  context?: any;
1211
1254
  message: {
@@ -1336,6 +1379,20 @@ declare module '@scout9/app' {
1336
1379
  intent?: (string | undefined) | null;
1337
1380
  /** Confidence score of the assigned intent */
1338
1381
  intentScore?: (number | undefined) | null;
1382
+ anticipate?: {
1383
+ /** Determines the runtime to address the next response */
1384
+ type: "did" | "literal" | "context";
1385
+ slots: {
1386
+ [x: string]: any[];
1387
+ };
1388
+ /** For type 'did' */
1389
+ did?: string | undefined;
1390
+ /** For literal keywords, this map helps point which slot the keyword matches to */
1391
+ map?: {
1392
+ slot: string;
1393
+ keywords: string[];
1394
+ }[] | undefined;
1395
+ } | undefined;
1339
1396
  };
1340
1397
  context?: any;
1341
1398
  message: {
@@ -3518,6 +3575,7 @@ declare module '@scout9/app/spirits' {
3518
3575
  messages: Change<Array<import('@scout9/app').Message>>;
3519
3576
  context: Change<any>;
3520
3577
  message: Change<import('@scout9/app').Message>;
3578
+ followup: Array<import('@scout9/app').Followup>;
3521
3579
  };
3522
3580
  }
3523
3581
 
@@ -28,6 +28,7 @@
28
28
  "Bus",
29
29
  "ContextExample",
30
30
  "ContextExampleWithTrainingData",
31
+ "ConversationAnticipate",
31
32
  "ConversationContext",
32
33
  "Conversation",
33
34
  "Customer",
@@ -83,5 +84,5 @@
83
84
  null,
84
85
  null
85
86
  ],
86
- "mappings": "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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA0mChBC,uBAAuBA;;;;;;;;;aASvBC,iCAAiCA;;;;;;;;;aASjCC,kCAAkCA;;;;;;;;;;;;;;aAclCC,gBAAgBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAsfhBC,wBAAwBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA+DxBC,oBAAoBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA4PpBC,sBAAsBA;;;;;;aAMtBC,WAAWA;;;;;;;;;;;;;;;;aAgBXC,iBAAiBA;;;;;;;;;;;;;;;;aAgBjBC,aAAaA;;;;;;;;;aASbC,cAAcA;;;;;;;;;;;;;;;;aAgBdC,gBAAgBA;;;;;;;;;;;;;;;;;;iBCnyGfC,eAAeA;iBAWfC,kBAAkBA;iBAgBlBC,iBAAiBA;iBAcjBC,sBAAsBA;iBAatBC,uBAAuBA;;;;;cC/CvBC,UAAUA"
87
+ "mappings": "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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAwnChBC,uBAAuBA;;;;;;;;;aASvBC,iCAAiCA;;;;;;;;;aASjCC,kCAAkCA;;;;;;;;;;;;;;aAclCC,gBAAgBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAsfhBC,wBAAwBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA+DxBC,oBAAoBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA4PpBC,sBAAsBA;;;;;;aAMtBC,WAAWA;;;;;;;;;;;;;;;;aAgBXC,iBAAiBA;;;;;;;;;;;;;;;;aAgBjBC,aAAaA;;;;;;;;;aASbC,cAAcA;;;;;;;;;;;;;;;;aAgBdC,gBAAgBA;;;;;;;;;;;;;;;;;;iBC51GfC,eAAeA;iBAWfC,kBAAkBA;iBAgBlBC,iBAAiBA;iBAcjBC,sBAAsBA;iBAatBC,uBAAuBA;;;;;cC/CvBC,UAAUA"
87
88
  }