@scout9/app 1.0.0-alpha.0.3.1 → 1.0.0-alpha.0.3.3

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,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var spirits = require("./spirits-76855e30.cjs");
4
- var dev = require("./dev-73437873.cjs");
5
- var macros = require("./macros-44f1f872.cjs");
3
+ var spirits = require("./spirits-bf93b875.cjs");
4
+ var dev = require("./dev-f7215614.cjs");
5
+ var macros = require("./macros-5be965e9.cjs");
6
6
  var require$$0 = require('fs');
7
7
  var require$$2$1 = require('events');
8
8
  var require$$1 = require('path');
@@ -29483,7 +29483,7 @@ class Body {
29483
29483
  }
29484
29484
  const {
29485
29485
  toFormData
29486
- } = await Promise.resolve().then(function () { return require("./multipart-parser-12c1b026.cjs"); });
29486
+ } = await Promise.resolve().then(function () { return require("./multipart-parser-734db7f7.cjs"); });
29487
29487
  return toFormData(this.body, ct);
29488
29488
  }
29489
29489
 
@@ -41892,7 +41892,7 @@ function _loadUserPackageJson() {
41892
41892
  targetPkgUrl = isTest ? packageTestJsonUrl : packageJsonUrl;
41893
41893
  _context.t0 = JSON;
41894
41894
  _context.next = 10;
41895
- 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-78f40e9a.js', document.baseURI).href))), 'utf-8');
41895
+ 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-c6c0a761.js', document.baseURI).href))), 'utf-8');
41896
41896
  case 10:
41897
41897
  _context.t1 = _context.sent;
41898
41898
  pkg = _context.t0.parse.call(_context.t0, _context.t1);
@@ -43098,7 +43098,7 @@ var ProjectFiles = /*#__PURE__*/function () {
43098
43098
  return ProjectFiles;
43099
43099
  }();
43100
43100
 
43101
- 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-78f40e9a.js', document.baseURI).href)));
43101
+ 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-c6c0a761.js', document.baseURI).href)));
43102
43102
  var __dirname$1 = path__default["default"].dirname(__filename$1);
43103
43103
  function zipDirectory(source, out) {
43104
43104
  var archive = archiver$1('tar', {
@@ -43313,7 +43313,7 @@ function _buildApp() {
43313
43313
  case 11:
43314
43314
  _context4.t0 = JSON;
43315
43315
  _context4.next = 14;
43316
- 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-78f40e9a.js', document.baseURI).href))), 'utf-8');
43316
+ 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-c6c0a761.js', document.baseURI).href))), 'utf-8');
43317
43317
  case 14:
43318
43318
  _context4.t1 = _context4.sent;
43319
43319
  packageTemplate = _context4.t0.parse.call(_context4.t0, _context4.t1);
@@ -44428,10 +44428,26 @@ var Scout9Platform = {
44428
44428
  method = request.method;
44429
44429
  var status = response.status,
44430
44430
  data = response.data;
44431
- console.error(dev.$.red(dev.$.bold("".concat(method, " ").concat(path, " Scout9 ApiError (").concat(status, ")")) + ': ' + JSON.stringify(data)));
44432
- throw new Error(JSON.stringify(data));
44431
+ switch (path) {
44432
+ case '/v1-parse':
44433
+ console.error(dev.$.red(JSON.stringify(data)));
44434
+ break;
44435
+ default:
44436
+ console.error(dev.$.red(dev.$.bold("".concat(method, " ").concat(path, " Scout9 ApiError (").concat(status, ")")) + ': ' + JSON.stringify(data)));
44437
+ }
44438
+ break;
44433
44439
  case 'SyntaxError':
44434
- throw error;
44440
+ var message = error.message,
44441
+ cause = error.cause;
44442
+ if (cause) {
44443
+ try {
44444
+ message += "\nCause: ".concat(JSON.stringify(cause));
44445
+ } catch (e) {
44446
+ //
44447
+ }
44448
+ }
44449
+ console.error(dev.$.red(dev.$.bold('SyntaxError') + ": ".concat(message)));
44450
+ break;
44435
44451
  case 'ZodError':
44436
44452
  dev.logUserValidationError(error, error.source || 'src/index.js|ts');
44437
44453
  break;
package/dist/index.cjs CHANGED
@@ -2,10 +2,10 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require("./index-78f40e9a.cjs");
6
- var dev = require("./dev-73437873.cjs");
7
- require("./spirits-76855e30.cjs");
8
- require("./macros-44f1f872.cjs");
5
+ var index = require("./index-c6c0a761.cjs");
6
+ var dev = require("./dev-f7215614.cjs");
7
+ require("./spirits-bf93b875.cjs");
8
+ require("./macros-5be965e9.cjs");
9
9
  require('fs');
10
10
  require('events');
11
11
  require('path');
@@ -4131,7 +4131,7 @@ var PersonasConfigurationSchema = z.array(PersonaConfigurationSchema);
4131
4131
  var AgentsSchema = z.array(AgentSchema);
4132
4132
  var PersonasSchema = z.array(PersonaSchema);
4133
4133
 
4134
- var ConversationContext = z.record(z.string(), z.any());
4134
+ var ConversationContext = z.record(z.union([z.string(), z.number(), z["boolean"](), z["null"](), z.array(z.union([z.string(), z.number(), z["boolean"](), z["null"]()]))]));
4135
4135
  var ConversationAnticipateSchema = z.object({
4136
4136
  type: z["enum"](['did', 'literal', 'context'], {
4137
4137
  description: "Determines the runtime to address the next response"
@@ -2,9 +2,9 @@
2
2
 
3
3
  require('node:fs');
4
4
  require('node:path');
5
- var index = require("./index-78f40e9a.cjs");
6
- require("./spirits-76855e30.cjs");
7
- require("./dev-73437873.cjs");
5
+ var index = require("./index-c6c0a761.cjs");
6
+ require("./spirits-bf93b875.cjs");
7
+ require("./dev-f7215614.cjs");
8
8
  require('util');
9
9
  require('stream');
10
10
  require('path');
@@ -25,7 +25,7 @@ require('node:stream');
25
25
  require('node:string_decoder');
26
26
  require('node:readline');
27
27
  require('node:process');
28
- require("./macros-44f1f872.cjs");
28
+ require("./macros-5be965e9.cjs");
29
29
  require('node:os');
30
30
  require('fs/promises');
31
31
  require('constants');
package/dist/schemas.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var macros = require("./macros-44f1f872.cjs");
5
+ var macros = require("./macros-5be965e9.cjs");
6
6
 
7
7
 
8
8
 
@@ -779,14 +779,14 @@ var Spirits = {
779
779
  }
780
780
  throw new Error("SpiritsError: No agent found in conversation, must define \".$agent\" in the conversation");
781
781
  case 13:
782
- persona = (config.persona || config.agents).find(function (p) {
782
+ persona = (config.persona || config.personas || config.agents).find(function (p) {
783
783
  return p.id === conversation.$agent;
784
784
  });
785
785
  if (persona) {
786
786
  _context2.next = 18;
787
787
  break;
788
788
  }
789
- if (!(config.persona || config.agents).some(function (a) {
789
+ if (!(config.persona || config.personas || config.agents).some(function (a) {
790
790
  return !a.id;
791
791
  })) {
792
792
  _context2.next = 17;
@@ -914,11 +914,21 @@ var Spirits = {
914
914
  stagnationCount: conversation.lockAttempts || 0
915
915
  }).then(function (res) {
916
916
  return Array.isArray(res) ? res : [res];
917
+ }).then(function (slots) {
918
+ return slots.reduce(function (accumulator, slot) {
919
+ if ('toJSON' in slot) {
920
+ var slotJson = slot.toJSON();
921
+ accumulator.push.apply(accumulator, _toConsumableArray(Array.isArray(slotJson) ? slotJson : [slotJson]));
922
+ } else {
923
+ accumulator.push(slot);
924
+ }
925
+ return accumulator;
926
+ }, []);
917
927
  });
918
928
  case 43:
919
929
  slots = _context2.sent;
920
930
  hasNoInstructions = slots.every(function (s) {
921
- return !s.instructions || Array.isArray(s) && s.instructions.length === 0;
931
+ return !s.instructions || Array.isArray(s.instructions) && s.instructions.length === 0;
922
932
  });
923
933
  hasNoCustomMessage = slots.every(function (s) {
924
934
  return !s.message;
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-76855e30.cjs");
5
+ var spirits = require("./spirits-bf93b875.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-73437873.cjs");
6
- require("./spirits-76855e30.cjs");
5
+ var dev = require("./dev-f7215614.cjs");
6
+ require("./spirits-bf93b875.cjs");
7
7
  require('util');
8
8
  require('stream');
9
9
  require('path');
@@ -26,7 +26,7 @@ require('node:stream');
26
26
  require('node:string_decoder');
27
27
  require('node:readline');
28
28
  require('node:process');
29
- require("./macros-44f1f872.cjs");
29
+ require("./macros-5be965e9.cjs");
30
30
  require('node:os');
31
31
  require('fs/promises');
32
32
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scout9/app",
3
- "version": "1.0.0-alpha.0.3.1",
3
+ "version": "1.0.0-alpha.0.3.3",
4
4
  "description": "Build and deploy your Scout9 app for SMS auto replies",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -112,7 +112,7 @@ const handleError = (e, res = undefined) => {
112
112
  const handleZodError = ({error, res = undefined, code = 500, status, name, bodyLabel = 'Provided Input', body = undefined, action = ''}) => {
113
113
  res?.writeHead?.(code, {'Content-Type': 'application/json'});
114
114
  if (error instanceof ZodError) {
115
- const formattedErrors = JSON.stringify(error.errors, null, 2);
115
+ const formattedErrors = JSON.stringify(error.format(), null, 2);
116
116
  res?.end?.(JSON.stringify({
117
117
  status,
118
118
  errors: formattedErrors
@@ -224,7 +224,14 @@ app.post(dev ? '/dev/workflow' : '/', async (req, res) => {
224
224
  }
225
225
  let response;
226
226
  try {
227
- response = await projectApp(workflowEvent);
227
+ response = await projectApp(workflowEvent)
228
+ .then((response) => {
229
+ if ('toJSON' in response) {
230
+ return response.toJSON();
231
+ } else {
232
+ return response;
233
+ }
234
+ })
228
235
  } catch (error) {
229
236
  error.message = `Workflow Template Runtime Error: ` + error.message;
230
237
  handleError(error, res);
@@ -356,13 +363,13 @@ async function runEntityApi(req, res) {
356
363
  const response = await api({
357
364
  params,
358
365
  searchParams: req?.query || {}, body: req?.body || undefined,
359
- id: params.id
366
+ id: params?.id
360
367
  });
361
368
  if (response instanceof EventResponse || !!response.body) {
362
369
  const data = response.body ?? response.data();
363
370
  res.writeHead(response.status || 200, {'Content-Type': 'application/json'});
364
371
  res.end(JSON.stringify(data));
365
- console.log(`${req.method} EntityApi.${params.id}:`);
372
+ console.log(`${req.method} EntityApi.${lastSegment}:`);
366
373
  console.log(colors.grey(JSON.stringify(data)));
367
374
  } else {
368
375
  throw new Error(`Invalid response: not an EventResponse`);
package/src/platform.js CHANGED
@@ -219,10 +219,25 @@ export const Scout9Platform = {
219
219
  const {request, response} = error;
220
220
  const { path, method } = request;
221
221
  const {status, data} = response;
222
- console.error(colors.red(colors.bold(`${method} ${path} Scout9 ApiError (${status})`) + ': ' + JSON.stringify(data)));
223
- throw new Error(JSON.stringify(data));
222
+ switch (path) {
223
+ case '/v1-parse':
224
+ console.error(colors.red(JSON.stringify(data)));
225
+ break;
226
+ default:
227
+ console.error(colors.red(colors.bold(`${method} ${path} Scout9 ApiError (${status})`) + ': ' + JSON.stringify(data)));
228
+ }
229
+ break;
224
230
  case 'SyntaxError':
225
- throw error;
231
+ let {message, cause} = error;
232
+ if (cause) {
233
+ try {
234
+ message += `\nCause: ${JSON.stringify(cause)}`;
235
+ } catch (e) {
236
+ //
237
+ }
238
+ }
239
+ console.error(colors.red(colors.bold('SyntaxError') + `: ${message}`));
240
+ break;
226
241
  case 'ZodError':
227
242
  logUserValidationError(error, error.source || 'src/index.js|ts');
228
243
  break;
package/src/public.d.ts CHANGED
@@ -106,6 +106,9 @@ export const instruct: (message: string, options?: OptionsInstruct) => EventMacr
106
106
  *
107
107
  * Calling this method will lock the conversation and prevent auto replies from being sent to the user.
108
108
  *
109
+ * @example - basic forward
110
+ * forward()
111
+ *
109
112
  * @example - end of workflow
110
113
  * forward("User wants 1 cheese pizza ready for pick");
111
114
  *
@@ -117,7 +120,7 @@ export const instruct: (message: string, options?: OptionsInstruct) => EventMacr
117
120
  *
118
121
  * @type {(message: string, options?: OptionsForward) => EventMacros}
119
122
  */
120
- export const forward: (message: string, options?: OptionsForward) => EventMacros;
123
+ export const forward: (message?: string, options?: OptionsForward) => EventMacros;
121
124
  /**
122
125
  * Manual message to send to the customer from the workflow.
123
126
  *
@@ -177,6 +180,8 @@ export type OptionsForward = {
177
180
  * - another phone or email to forward to instead of owner
178
181
  */
179
182
  to?: string;
183
+
184
+ resetIntent?: boolean;
180
185
  };
181
186
  /**
182
187
  * - Extends `WorkflowResponseSlotBase` to include keywords.
@@ -214,8 +219,7 @@ export type ContextExampleWithTrainingData = {
214
219
  output: Record<string, any>[];
215
220
  }
216
221
 
217
-
218
- export type ConversationContext = Record<string, any>;
222
+ export type ConversationContext = Record<string, string | number | boolean | null | Array<string | number | boolean | null>>;
219
223
 
220
224
  export type ContextExamples = (ContextExampleWithTrainingData | ConversationContext)[];
221
225
  export type ContextOutput = Record<string, any>;
@@ -525,7 +529,15 @@ export type Scout9ProjectConfig = {
525
529
  };
526
530
 
527
531
  export type Scout9ProjectBuildConfig = Scout9ProjectConfig & {
528
- agents: Agent[];
532
+ agents: AgentsConfiguration;
533
+ /**
534
+ * @deprecated use agents
535
+ */
536
+ personas?: AgentsConfiguration;
537
+ /**
538
+ * @deprecated use agents
539
+ */
540
+ persona?: AgentsConfiguration;
529
541
  entities: EntityRootProjectConfiguration[];
530
542
  workflows: WorkflowConfiguration[];
531
543
  };
@@ -576,7 +588,7 @@ export type WorkflowResponseSlot = WorkflowResponseSlotBase & {
576
588
  anticipate?: Anticipate | undefined;
577
589
  };
578
590
 
579
- export type WorkflowResponse = WorkflowResponseSlot | WorkflowResponseSlot[];
591
+ export type WorkflowResponse = EventMacros | WorkflowResponseSlot | (WorkflowResponseSlot | EventMacros)[];
580
592
 
581
593
  export type WorkflowFunction = (event: WorkflowEvent) => WorkflowResponse | Promise<WorkflowResponse>;
582
594
 
@@ -268,12 +268,13 @@ function EventMacrosFactory() {
268
268
  },
269
269
  /**
270
270
  * Returns event payload
271
+ * @param {boolean} flush - if true, will reset the data payload
271
272
  * @return {Array<WorkflowResponseSlot>}
272
273
  */
273
274
  toJSON(flush = true) {
274
275
  if (flush) {
275
276
  const copy = [...slots];
276
- slots =[];
277
+ slots = [];
277
278
  return copy;
278
279
  } else {
279
280
  return slots;
@@ -1,7 +1,17 @@
1
1
  import { z } from 'zod';
2
2
  import { zId } from './utils.js';
3
3
 
4
- export const ConversationContext = z.record(z.string(), z.any());
4
+ export const ConversationContext = z.record(
5
+ z.union([
6
+ z.string(),
7
+ z.number(),
8
+ z.boolean(),
9
+ z.null(),
10
+ z.array(
11
+ z.union([z.string(), z.number(), z.boolean(), z.null()])
12
+ )
13
+ ])
14
+ );
5
15
 
6
16
  export const ConversationAnticipateSchema = z.object({
7
17
  type: z.enum(['did', 'literal', 'context'], {description: "Determines the runtime to address the next response"}),
@@ -1,5 +1,5 @@
1
1
  import { Configuration, Scout9Api } from '@scout9/admin';
2
- import {grey, italic, bgWhite, black} from 'kleur/colors';
2
+ import { grey, italic, bgWhite, black } from 'kleur/colors';
3
3
  import { createMockConversation, createMockWorkflowEvent } from './mocks.js';
4
4
  import { loadConfig } from '../core/config/index.js';
5
5
  import { requireProjectFile } from '../utils/index.js';
@@ -33,7 +33,7 @@ export class Scout9Test {
33
33
  messages;
34
34
 
35
35
  /**
36
- * @type {any}
36
+ * @type {import('@scout9/app').ConversationContext}
37
37
  */
38
38
  context;
39
39
 
@@ -158,7 +158,7 @@ export class Scout9Test {
158
158
 
159
159
  // Load app configuration (if not already loaded or override true)
160
160
  if (override || !this._project) {
161
- this._project = await loadConfig({cwd: this._cwd, src: this._src, mode: this._mode})
161
+ this._project = await loadConfig({cwd: this._cwd, src: this._src, mode: this._mode});
162
162
  }
163
163
 
164
164
  if (override || !this._api) {
@@ -205,7 +205,7 @@ export class Scout9Test {
205
205
  const typeStdout = type ? italic(bgWhite(' ' + black(type) + ' ')) : '';
206
206
  const messageStdout = grey(message);
207
207
  (console.hasOwnProperty(level) ? console[level] : console.log)(`\t${typeStdout ? typeStdout + ' ' : ''}${messageStdout}`);
208
- }
208
+ };
209
209
 
210
210
  // If custom logger provided, use it, otherwise use default logger
211
211
  let progressInput = typeof progress === 'function' ? progress : defaultProgressLogger;
@@ -215,10 +215,14 @@ export class Scout9Test {
215
215
  if (!!progress) {
216
216
  progressInput = defaultProgressLogger; // use default logger
217
217
  } else {
218
- progressInput = () => {}; // use no-op
218
+ progressInput = () => {
219
+ }; // use no-op
219
220
  }
220
221
  }
221
222
 
223
+ /**
224
+ * @type {import('@scout9/app').Message}
225
+ */
222
226
  const _message = {
223
227
  id: 'user_mock_' + Math.random().toString(36).slice(2, 11),
224
228
  role: 'customer',
@@ -268,7 +272,7 @@ export class Scout9Test {
268
272
  console.error(`Invalid forward result`, result.conversation.forward);
269
273
  this.conversation.forwardedTo = 'Invalid Forward';
270
274
  }
271
- this.conversation.forwarded = new Date().toString();
275
+ this.conversation.forwarded = new Date().toISOString();
272
276
  this.conversation.forwardNote = result.conversation.forwardNote || '';
273
277
  this.conversation.locked = true;
274
278
  this.conversation.lockedReason = result.conversation.forwardNote ?? ('Forwarded to ' + this.conversation.forwardedTo);
@@ -353,6 +357,16 @@ export class Scout9Test {
353
357
  }).then((_res => _res.data));
354
358
  }
355
359
 
360
+ /**
361
+ * @param {Partial<import('@scout9/app').ConversationContext>} ctx
362
+ */
363
+ set context(ctx) {
364
+ this.context = {
365
+ ...this.context,
366
+ ...ctx
367
+ };
368
+ }
369
+
356
370
  /**
357
371
  * @private
358
372
  */
@@ -235,9 +235,9 @@ export const Spirits = {
235
235
  if (!conversation.$agent) {
236
236
  throw new Error(`SpiritsError: No agent found in conversation, must define ".$agent" in the conversation`);
237
237
  }
238
- const persona = (config.persona || config.agents).find(p => p.id === conversation.$agent);
238
+ const persona = (config.persona || config.personas || config.agents).find(p => p.id === conversation.$agent);
239
239
  if (!persona) {
240
- if ((config.persona || config.agents).some(a => !a.id)) {
240
+ if ((config.persona || config.personas || config.agents).some(a => !a.id)) {
241
241
  throw new Error(`SpiritsError: No persona found ("${conversation.$agent}") in provided config, some persona's did not contain an "id" (Internal Mapping Error)`);
242
242
  }
243
243
  throw new Error(`SpiritsError: No persona found ("${conversation.$agent}") in provided config`);
@@ -322,6 +322,7 @@ export const Spirits = {
322
322
 
323
323
  // 3. Run the workflow
324
324
  progress('Running workflow', 'info', 'SET_PROCESSING', 'system');
325
+
325
326
  const slots = await workflow({
326
327
  messages,
327
328
  conversation,
@@ -335,8 +336,18 @@ export const Spirits = {
335
336
  initial: conversation.intent || null
336
337
  },
337
338
  stagnationCount: conversation.lockAttempts || 0
338
- }).then((res) => Array.isArray(res) ? res : [res]);
339
- const hasNoInstructions = slots.every(s => !s.instructions || (Array.isArray(s) && s.instructions.length === 0));
339
+ })
340
+ .then((res) => Array.isArray(res) ? res : [res])
341
+ .then((slots) => slots.reduce((accumulator, slot) => {
342
+ if ('toJSON' in slot) {
343
+ const slotJson = slot.toJSON();
344
+ accumulator.push(...(Array.isArray(slotJson) ? slotJson : [slotJson]));
345
+ } else {
346
+ accumulator.push(slot);
347
+ }
348
+ return accumulator;
349
+ }, []));
350
+ const hasNoInstructions = slots.every(s => !s.instructions || (Array.isArray(s.instructions) && s.instructions.length === 0));
340
351
  const hasNoCustomMessage = slots.every(s => !s.message);
341
352
  const previousLockAttempt = conversation.lockAttempts || 0; // Used to track
342
353