wingbot 3.76.4-alpha.14 → 3.76.4-alpha.16

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wingbot",
3
- "version": "3.76.4-alpha.14",
3
+ "version": "3.76.4-alpha.16",
4
4
  "description": "Enterprise Messaging Bot Conversation Engine",
5
5
  "main": "index.js",
6
6
  "type": "commonjs",
@@ -0,0 +1,85 @@
1
+ /*
2
+ * @author David Menger
3
+ */
4
+ 'use strict';
5
+
6
+ /**
7
+ * null = text+voice
8
+ * t = text only
9
+ * v = voice only
10
+ * s = ssml
11
+ *
12
+ * @typedef {"t"|"v"|"s"|null} Purpose
13
+ */
14
+
15
+ /**
16
+ * @typedef Translation
17
+ * @property {string|string[]} t - text alternatives
18
+ * @property {string | null} l - language
19
+ * @property {Purpose | Purpose[]} [p] - purposes
20
+ */
21
+
22
+ /**
23
+ * @typedef {Translation[] | Translation | string[] | string} Translations
24
+ */
25
+
26
+ /**
27
+ * @param {string | string[] | Translation | Translation[]} translations
28
+ * @returns {translations is Translation[]}
29
+ */
30
+ function isArrayOfObjects (translations) {
31
+ return Array.isArray(translations)
32
+ && typeof translations[0] === 'object'
33
+ && translations[0] !== null;
34
+ }
35
+
36
+ function isTextObjectEmpty (text) {
37
+ if (!text || !text.t) {
38
+ return true;
39
+ }
40
+ if (Array.isArray(text.t)) {
41
+ return !text.t.some((t) => !!t);
42
+ }
43
+ return false;
44
+ }
45
+
46
+ /**
47
+ * @param {Translations} translations
48
+ * @param {string} [lang]
49
+ * @param {boolean} [disableDefaulting] - it will try to find translation for other language
50
+ * @returns {null|string|string[]}
51
+ */
52
+ function getLanguageText (translations, lang = null, disableDefaulting = false) {
53
+ let foundText;
54
+
55
+ if (isArrayOfObjects(translations)) {
56
+ if (lang) {
57
+ // @ts-ignore
58
+ foundText = translations.find((t) => t.l === lang);
59
+ } else if (disableDefaulting) {
60
+ // @ts-ignore
61
+ [foundText] = translations;
62
+ }
63
+ if (isTextObjectEmpty(foundText) && !disableDefaulting) {
64
+ // @ts-ignore
65
+ foundText = translations.find((t) => !isTextObjectEmpty(t));
66
+ }
67
+ foundText = foundText ? foundText.t : null;
68
+ } else {
69
+ foundText = translations;
70
+ }
71
+ if (Array.isArray(foundText)) {
72
+ foundText = foundText.filter((f) => !!f);
73
+
74
+ if (foundText.length === 0) {
75
+ return '';
76
+ }
77
+ }
78
+ return foundText || '';
79
+ }
80
+
81
+ module.exports = {
82
+ getLanguageText,
83
+ isTextObjectEmpty,
84
+ isArrayOfObjects
85
+ };
@@ -6,6 +6,7 @@
6
6
  const hbs = require('./hbs');
7
7
  const stateData = require('../utils/stateData');
8
8
  const getCondition = require('../utils/getCondition');
9
+ const { isTextObjectEmpty, getLanguageText } = require('./languageText');
9
10
 
10
11
  const ASPECT_SQUARE = 'square';
11
12
  const ASPECT_HORISONTAL = 'horisontal';
@@ -20,10 +21,6 @@ const WEBVIEW_FULL = 'full';
20
21
  const WEBVIEW_TALL = 'tall';
21
22
  const WEBVIEW_COMPACT = 'compact';
22
23
 
23
- /**
24
- * @typedef {Translation[] | Translation | string[] | string} Translations
25
- */
26
-
27
24
  /**
28
25
  * @typedef {object} TextObject
29
26
  * @prop {string} t - text
@@ -31,76 +28,10 @@ const WEBVIEW_COMPACT = 'compact';
31
28
  * @prop {string|null} p - purpose
32
29
  */
33
30
 
34
- /**
35
- * null = text+voice
36
- * t = text only
37
- * v = voice only
38
- * s = ssml
39
- *
40
- * @typedef {"t"|"v"|"s"|null} Purpose
41
- */
42
-
43
- /**
44
- * @typedef Translation
45
- * @property {string|string[]} t - text alternatives
46
- * @property {string | null} l - language
47
- * @property {Purpose | Purpose[]} [p] - purposes
48
- */
49
-
50
- /**
51
- * @param {string | string[] | Translation | Translation[]} translations
52
- * @returns {translations is Translation[]}
53
- */
54
- function isArrayOfObjects (translations) {
55
- return Array.isArray(translations)
56
- && typeof translations[0] === 'object'
57
- && translations[0] !== null;
58
- }
59
-
60
- function isTextObjectEmpty (text) {
61
- if (!text || !text.t) {
62
- return true;
63
- }
64
- if (Array.isArray(text.t)) {
65
- return !text.t.some((t) => !!t);
66
- }
67
- return false;
68
- }
69
-
70
- /**
71
- * @param {Translations} translations
72
- * @param {string} [lang]
73
- * @param {boolean} [disableDefaulting] - it will try to find translation for other language
74
- * @returns {null|string|string[]}
75
- */
76
- function getLanguageText (translations, lang = null, disableDefaulting = false) {
77
- let foundText;
78
-
79
- if (isArrayOfObjects(translations)) {
80
- if (lang) {
81
- // @ts-ignore
82
- foundText = translations.find((t) => t.l === lang);
83
- } else if (disableDefaulting) {
84
- // @ts-ignore
85
- [foundText] = translations;
86
- }
87
- if (isTextObjectEmpty(foundText) && !disableDefaulting) {
88
- // @ts-ignore
89
- foundText = translations.find((t) => !isTextObjectEmpty(t));
90
- }
91
- foundText = foundText ? foundText.t : null;
92
- } else {
93
- foundText = translations;
94
- }
95
- if (Array.isArray(foundText)) {
96
- foundText = foundText.filter((f) => !!f);
31
+ /** @typedef {import('./languageText').Translation} Translation */
32
+ /** @typedef {import('./languageText').Translations} Translations */
33
+ /** @typedef {import('./languageText').Purpose} Purpose */
97
34
 
98
- if (foundText.length === 0) {
99
- return '';
100
- }
101
- }
102
- return foundText || '';
103
- }
104
35
  /**
105
36
  *
106
37
  * @param {Translations} translations
@@ -16,13 +16,19 @@ function extractText (payload) {
16
16
  return payload.message.text;
17
17
  }
18
18
 
19
- // button message
20
- if (payload.message && payload.message.attachment
21
- && payload.message.attachment.type === 'template'
22
- && payload.message.attachment.payload
23
- && payload.message.attachment.payload.text) {
24
-
25
- return payload.message.attachment.payload.text;
19
+ // button message — the orchestrator normalizes a singular `attachment` into
20
+ // a plural `attachments` array before persisting, so accept both shapes;
21
+ // otherwise template messages (e.g. button templates) logged via the
22
+ // orchestrator drop out of the transcript entirely.
23
+ const attachment = payload.message
24
+ && (payload.message.attachment
25
+ || (Array.isArray(payload.message.attachments) && payload.message.attachments[0]));
26
+ if (attachment
27
+ && attachment.type === 'template'
28
+ && attachment.payload
29
+ && attachment.payload.text) {
30
+
31
+ return attachment.payload.text;
26
32
  }
27
33
 
28
34
  if (!payload.postback) {
@@ -10,17 +10,41 @@ try {
10
10
  } catch (er) {
11
11
  handlebars = { compile: (text) => () => text };
12
12
  }
13
+ const { getLanguageText } = require('../resolvers/languageText');
13
14
  const stateData = require('./stateData');
14
15
 
16
+ /** @typedef {import('../resolvers/languageText').Translation} Translation */
17
+
15
18
  /** @typedef {import('../Request')} Request */
16
19
  /** @typedef {import('../Responder')} Responder */
17
20
 
21
+ function compileAndRenderOut (template, req, res, data) {
22
+ if (!template) {
23
+ return '';
24
+ }
25
+ if (typeof template !== 'string') {
26
+ return `${template}`;
27
+ }
28
+ if (!template.includes('{{')) {
29
+ return template;
30
+ }
31
+
32
+ const useData = data || stateData(req, res);
33
+ let result = template;
34
+ let hasHandlebars = true;
35
+ for (let i = 0; i < 10 && hasHandlebars; i++) {
36
+ result = handlebars.compile(result)(useData);
37
+ hasHandlebars = template.includes('{{');
38
+ }
39
+ return result;
40
+ }
41
+
18
42
  /**
19
43
  * Utility, which helps to render handlebars syntax with all variables within conversations state
20
44
  *
21
45
  * @param {Request} req
22
46
  * @param {Responder} res
23
- * @param {string} template
47
+ * @param {string|Translation[]} template
24
48
  * @param {object} forcedData
25
49
  * @returns {string}
26
50
  * @example
@@ -39,15 +63,15 @@ function compileWithState (req, res, template, forcedData = null) {
39
63
  if (!template) {
40
64
  return '';
41
65
  }
42
- if (typeof template !== 'string') {
43
- return `${template}`;
44
- }
45
- const data = forcedData || stateData(req, res);
46
- let result = template;
47
- for (let i = 0; i < 10 && result.includes('{{'); i++) {
48
- result = handlebars.compile(result)(data);
66
+ let tpl;
67
+ let data;
68
+ if (Array.isArray(template)) {
69
+ data = stateData(req, res);
70
+ tpl = getLanguageText(template, data.lang);
71
+ } else {
72
+ tpl = template;
49
73
  }
50
- return result;
74
+ return compileAndRenderOut(tpl, req, res, forcedData || data);
51
75
  }
52
76
 
53
77
  module.exports = compileWithState;
@@ -1,11 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(npx mocha:*)",
5
- "Bash(npx tsc *)",
6
- "Bash(npm test *)",
7
- "Bash(node -e \"const p = require\\('./bot/plugins/BTMLLM'\\); console.log\\('factory type:', typeof p\\); console.log\\('factory name:', p.name\\);\")",
8
- "Bash(grep -n \"prompt\\\\`\\\\|tagged\\\\|render\\\\|compile\\\\|hbs\" /Users/ondrejveres/Wingbot/wingbot-llm/src/prompt.js)"
9
- ]
10
- }
11
- }