@scout9/app 1.0.0-alpha.0.1.99 → 1.0.0-alpha.0.2.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/{dev-1afc1e7b.cjs → dev-df823c44.cjs} +56 -39
- package/dist/{index-2aedbf12.cjs → index-7460cfee.cjs} +6 -6
- package/dist/index.cjs +3 -3
- package/dist/{multipart-parser-51d88fc4.cjs → multipart-parser-d080fdee.cjs} +3 -3
- package/dist/{spirits-43ce19cf.cjs → spirits-76855e30.cjs} +129 -75
- package/dist/spirits.cjs +1 -1
- package/dist/testing-tools.cjs +2 -2
- package/package.json +1 -1
- package/src/public.d.ts +58 -1
- package/src/runtime/schemas/conversation.js +35 -0
- package/src/runtime/schemas/index.js +1 -0
- package/src/runtime/schemas/macros.js +2 -2
- package/src/runtime/schemas/platform.js +2 -2
- package/src/runtime/schemas/workflow.js +39 -60
- package/src/testing-tools/spirits.js +46 -2
- package/types/index.d.ts +59 -1
- package/types/index.d.ts.map +2 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var spirits = require("./spirits-
|
|
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-
|
|
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
|
|
40771
|
-
|
|
40772
|
-
|
|
40773
|
-
|
|
40774
|
-
|
|
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
|
-
|
|
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-
|
|
4
|
-
var dev = require("./dev-
|
|
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-
|
|
29485
|
+
} = await Promise.resolve().then(function () { return require("./multipart-parser-d080fdee.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-
|
|
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-7460cfee.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-
|
|
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-7460cfee.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-
|
|
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-7460cfee.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);
|
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-
|
|
6
|
-
var dev = require("./dev-
|
|
7
|
-
require("./spirits-
|
|
5
|
+
var index = require("./index-7460cfee.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-
|
|
6
|
-
require("./spirits-
|
|
7
|
-
require("./dev-
|
|
5
|
+
var index = require("./index-7460cfee.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;
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
829
|
+
_context2.next = 27;
|
|
827
830
|
return parser(message.content, 'en');
|
|
828
|
-
case
|
|
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 =
|
|
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
|
|
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 =
|
|
941
|
+
_context2.prev = 50;
|
|
939
942
|
_iterator.s();
|
|
940
|
-
case
|
|
943
|
+
case 52:
|
|
941
944
|
if ((_step = _iterator.n()).done) {
|
|
942
|
-
_context2.next =
|
|
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
|
-
|
|
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 =
|
|
1042
|
+
_context2.next = 84;
|
|
990
1043
|
break;
|
|
991
1044
|
}
|
|
992
1045
|
if (!(typeof instructions === 'string')) {
|
|
993
|
-
_context2.next =
|
|
1046
|
+
_context2.next = 74;
|
|
994
1047
|
break;
|
|
995
1048
|
}
|
|
996
1049
|
addInstruction(instructions, previousLockAttempt);
|
|
997
|
-
_context2.next =
|
|
1050
|
+
_context2.next = 84;
|
|
998
1051
|
break;
|
|
999
|
-
case
|
|
1052
|
+
case 74:
|
|
1000
1053
|
if (!Array.isArray(instructions)) {
|
|
1001
|
-
_context2.next =
|
|
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 =
|
|
1072
|
+
_context2.next = 84;
|
|
1020
1073
|
break;
|
|
1021
|
-
case
|
|
1074
|
+
case 79:
|
|
1022
1075
|
if (!(_typeof(instructions) === 'object' && 'content' in instructions && 'id' in instructions)) {
|
|
1023
|
-
_context2.next =
|
|
1076
|
+
_context2.next = 83;
|
|
1024
1077
|
break;
|
|
1025
1078
|
}
|
|
1026
1079
|
addInstruction(instructions.content, previousLockAttempt, instructions.id);
|
|
1027
|
-
_context2.next =
|
|
1080
|
+
_context2.next = 84;
|
|
1028
1081
|
break;
|
|
1029
|
-
case
|
|
1082
|
+
case 83:
|
|
1030
1083
|
throw new Error('SpiritsError: instructions must be a string or array or {content: "", id: ""}');
|
|
1031
|
-
case
|
|
1084
|
+
case 84:
|
|
1032
1085
|
if (!removeInstructions) {
|
|
1033
|
-
_context2.next =
|
|
1086
|
+
_context2.next = 101;
|
|
1034
1087
|
break;
|
|
1035
1088
|
}
|
|
1036
1089
|
_iterator3 = _createForOfIteratorHelper(removeInstructions);
|
|
1037
|
-
_context2.prev =
|
|
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
|
|
1113
|
+
case 89:
|
|
1061
1114
|
if ((_step3 = _iterator3.n()).done) {
|
|
1062
|
-
_context2.next =
|
|
1115
|
+
_context2.next = 93;
|
|
1063
1116
|
break;
|
|
1064
1117
|
}
|
|
1065
|
-
return _context2.delegateYield(_loop(), "t0",
|
|
1066
|
-
case
|
|
1067
|
-
_context2.next =
|
|
1118
|
+
return _context2.delegateYield(_loop(), "t0", 91);
|
|
1119
|
+
case 91:
|
|
1120
|
+
_context2.next = 89;
|
|
1068
1121
|
break;
|
|
1069
|
-
case
|
|
1070
|
-
_context2.next =
|
|
1122
|
+
case 93:
|
|
1123
|
+
_context2.next = 98;
|
|
1071
1124
|
break;
|
|
1072
|
-
case
|
|
1073
|
-
_context2.prev =
|
|
1074
|
-
_context2.t1 = _context2["catch"](
|
|
1125
|
+
case 95:
|
|
1126
|
+
_context2.prev = 95;
|
|
1127
|
+
_context2.t1 = _context2["catch"](86);
|
|
1075
1128
|
_iterator3.e(_context2.t1);
|
|
1076
|
-
case
|
|
1077
|
-
_context2.prev =
|
|
1129
|
+
case 98:
|
|
1130
|
+
_context2.prev = 98;
|
|
1078
1131
|
_iterator3.f();
|
|
1079
|
-
return _context2.finish(
|
|
1080
|
-
case
|
|
1132
|
+
return _context2.finish(98);
|
|
1133
|
+
case 101:
|
|
1081
1134
|
if (!manualMessage) {
|
|
1082
|
-
_context2.next =
|
|
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 =
|
|
1145
|
+
_context2.next = 105;
|
|
1093
1146
|
break;
|
|
1094
1147
|
}
|
|
1095
1148
|
throw new Error('Manual message must be of type "string"');
|
|
1096
|
-
case
|
|
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
|
|
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
|
|
1117
|
-
_context2.next =
|
|
1169
|
+
case 110:
|
|
1170
|
+
_context2.next = 52;
|
|
1118
1171
|
break;
|
|
1119
|
-
case
|
|
1120
|
-
_context2.next =
|
|
1172
|
+
case 112:
|
|
1173
|
+
_context2.next = 117;
|
|
1121
1174
|
break;
|
|
1122
|
-
case
|
|
1123
|
-
_context2.prev =
|
|
1124
|
-
_context2.t2 = _context2["catch"](
|
|
1175
|
+
case 114:
|
|
1176
|
+
_context2.prev = 114;
|
|
1177
|
+
_context2.t2 = _context2["catch"](50);
|
|
1125
1178
|
_iterator.e(_context2.t2);
|
|
1126
|
-
case
|
|
1127
|
-
_context2.prev =
|
|
1179
|
+
case 117:
|
|
1180
|
+
_context2.prev = 117;
|
|
1128
1181
|
_iterator.f();
|
|
1129
|
-
return _context2.finish(
|
|
1130
|
-
case
|
|
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 =
|
|
1202
|
+
_context2.next = 135;
|
|
1150
1203
|
break;
|
|
1151
1204
|
}
|
|
1152
1205
|
if (!((!conversation.locked || !hasNoInstructions) && !!hasNoCustomMessage)) {
|
|
1153
|
-
_context2.next =
|
|
1206
|
+
_context2.next = 135;
|
|
1154
1207
|
break;
|
|
1155
1208
|
}
|
|
1156
|
-
_context2.prev =
|
|
1209
|
+
_context2.prev = 123;
|
|
1157
1210
|
progress('Parsing message', 'info', 'SET_PROCESSING', 'system');
|
|
1158
|
-
_context2.next =
|
|
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
|
|
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 =
|
|
1256
|
+
_context2.next = 135;
|
|
1204
1257
|
break;
|
|
1205
|
-
case
|
|
1206
|
-
_context2.prev =
|
|
1207
|
-
_context2.t3 = _context2["catch"](
|
|
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
|
|
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
|
|
1286
|
+
case 137:
|
|
1233
1287
|
case "end":
|
|
1234
1288
|
return _context2.stop();
|
|
1235
1289
|
}
|
|
1236
|
-
}, _callee, null, [[
|
|
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
package/dist/testing-tools.cjs
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var dev = require("./dev-
|
|
6
|
-
require("./spirits-
|
|
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
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,
|
|
7
|
+
* NOTE: This file was auto generated 7/10/2024, 3:30:35 PM
|
|
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
|
+
});
|
|
@@ -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,
|
|
7
|
+
* NOTE: This file was auto generated 7/10/2024, 3:30:35 PM
|
|
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
|
|
package/types/index.d.ts.map
CHANGED
|
@@ -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": ";;;;;;;;;;;;;;iBAoBgBA,GAAGA;;;;;;;iBAYHC,IAAIA;;;;iBAUJC,SAASA;;;;;;;;;;;cAYZC,aAAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAiDbC,QAAQA;;;;;;;;;;;;;;;;;;;;cAqBRC,OAAOA;;;;;;;;;;;;;;;;;cAkBPC,KAAKA;;;;aAINC,eAAeA;;;;;;;;;aASfC,eAAeA;;;;;;;;;;;;;aAafC,YAAYA;;;;;;;aAOZC,cAAcA;;;;;;;;;;;;;aAadC,oCAAoCA;;;;;;aAMpCC,kBAAkBA;;;;aAIlBC,WAAWA;;;;;;;;;;;;;;iBAgBPC,GAAGA;;;;;;;;;;;;;;;;;;iBAsBHC,OAAOA;aACXC,eAAeA;aACfC,aAAaA;;;aAGbC,kBAAkBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAyDlBC,KAAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAuDLC,mBAAmBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAyDnBC,MAAMA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAuDNC,GAAGA;;;;;;;aAOHC,GAAGA;;;;;aAKHC,cAAcA;;;;;;;;;aASdC,8BAA8BA;;;;;;;aAO9BC,mBAAmBA;;;;aAInBC,YAAYA
|
|
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
|
}
|