wingbot 3.71.6 → 3.72.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/deploy.yml +2 -2
- package/.github/workflows/pullRequest.yml +2 -2
- package/package.json +4 -2
- package/src/Ai.js +44 -3
- package/src/AiMatching.js +66 -40
- package/src/BotAppSender.js +6 -4
- package/src/BuildRouter.js +2 -0
- package/src/LLM.js +183 -2
- package/src/LLMSession.js +90 -3
- package/src/Processor.js +1 -1
- package/src/Responder.js +143 -3
- package/src/ReturnSender.js +4 -4
- package/src/Tester.js +44 -2
- package/src/graphApi/GraphApi.js +31 -1
- package/src/graphApi/gqlRules.js +87 -0
- package/src/graphApi/schema.gql +15 -0
- package/src/resolvers/contextMessage.js +21 -4
- package/src/resolvers/message.js +43 -1
- package/src/resolvers/utils.js +14 -5
- package/src/testTools/PromptAssert.js +184 -0
- package/src/testTools/asserts.js +42 -4
- package/src/utils/customCondition.js +14 -1
- package/src/utils/getCondition.js +16 -4
- package/src/utils/getUpdate.js +4 -4
- package/src/utils/stateData.js +2 -0
|
@@ -8,30 +8,47 @@ const Router = require('../Router');
|
|
|
8
8
|
const Responder = require('../Responder');
|
|
9
9
|
const { getLanguageText } = require('./utils');
|
|
10
10
|
const compileWithState = require('../utils/compileWithState');
|
|
11
|
+
const LLM = require('../LLM');
|
|
11
12
|
|
|
12
13
|
/** @typedef {import('../BuildRouter').BotContext<any>} BotContext */
|
|
13
14
|
/** @typedef {import('../Router').Resolver<any>} Resolver */
|
|
14
15
|
/** @typedef {import('./utils').Translations} Translations */
|
|
16
|
+
/** @typedef {import('../LLM').EvaluationRule} EvaluationRule */
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @typedef {object} ContextMessageParams
|
|
20
|
+
* @property {Translations} context
|
|
21
|
+
* @property {string} [type]
|
|
22
|
+
* @property {EvaluationRule[]} [rules]
|
|
23
|
+
*/
|
|
15
24
|
|
|
16
25
|
/**
|
|
17
26
|
*
|
|
18
|
-
* @param {
|
|
19
|
-
* @param {Translations} params.context
|
|
20
|
-
* @param {string} [params.type]
|
|
27
|
+
* @param {ContextMessageParams} params
|
|
21
28
|
* @param {BotContext} context
|
|
22
29
|
* @returns {Resolver}
|
|
23
30
|
*/
|
|
24
31
|
// eslint-disable-next-line no-unused-vars
|
|
25
32
|
function contextMessage (params, context) {
|
|
26
33
|
|
|
34
|
+
const { rules = [] } = params;
|
|
35
|
+
const preprocessedRules = LLM.preprocessEvaluationRules(rules, context);
|
|
36
|
+
|
|
27
37
|
return async (req, res) => {
|
|
28
|
-
res.
|
|
38
|
+
res.llmAddInstructions((r) => {
|
|
29
39
|
const translated = getLanguageText(params.context, req.state.lang);
|
|
30
40
|
const translatedText = Array.isArray(translated) ? translated[0] : translated;
|
|
31
41
|
const statefulPrompt = compileWithState(req, r, translatedText);
|
|
32
42
|
return statefulPrompt;
|
|
33
43
|
}, params.type);
|
|
34
44
|
|
|
45
|
+
preprocessedRules.forEach((rule) => res.llmAddResultRule(
|
|
46
|
+
rule,
|
|
47
|
+
undefined,
|
|
48
|
+
undefined,
|
|
49
|
+
params.type
|
|
50
|
+
));
|
|
51
|
+
|
|
35
52
|
return Router.CONTINUE;
|
|
36
53
|
};
|
|
37
54
|
}
|
package/src/resolvers/message.js
CHANGED
|
@@ -23,8 +23,11 @@ const { vars, VAR_TYPES } = require('../utils/stateVariables');
|
|
|
23
23
|
const LLM = require('../LLM');
|
|
24
24
|
|
|
25
25
|
/** @typedef {import('../Responder').VoiceControl} VoiceControl */
|
|
26
|
+
/** @typedef {import('../BuildRouter').LinksMap} LinksMap */
|
|
26
27
|
/** @typedef {import('./utils').Translations} Translations */
|
|
27
28
|
/** @typedef {import('./utils').TextObject} TextObject */
|
|
29
|
+
/** @typedef {import('../utils/getCondition').ConditionDefinition} ConditionDefinition */
|
|
30
|
+
/** @typedef {import('../utils/getCondition').ConditionContext} ConditionContext */
|
|
28
31
|
/**
|
|
29
32
|
* Returns voice control props from params
|
|
30
33
|
*
|
|
@@ -68,6 +71,30 @@ function getVoiceControlFromParams (params, lang = null) {
|
|
|
68
71
|
return Object.keys(voiceControl).length > 0 ? voiceControl : null;
|
|
69
72
|
}
|
|
70
73
|
|
|
74
|
+
/**
|
|
75
|
+
* @typedef {object} QuickReplyData
|
|
76
|
+
* @prop {boolean} [isLocation]
|
|
77
|
+
* @prop {boolean} [isEmail]
|
|
78
|
+
* @prop {boolean} [isPhone]
|
|
79
|
+
* @prop {boolean} [trackAsNegative]
|
|
80
|
+
* @prop {string} [action]
|
|
81
|
+
* @prop {string} [targetRouteId]
|
|
82
|
+
* @prop {{l:string,t:string[]}[] | string} [title]
|
|
83
|
+
* @prop {object} [setState]
|
|
84
|
+
* @prop {string[]} [aiTags]
|
|
85
|
+
* @prop {{l:string,t:string[]}[] | string} [aiTitle]
|
|
86
|
+
*/
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @typedef {ConditionDefinition & QuickReplyData} QuickReply
|
|
90
|
+
*/
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
*
|
|
94
|
+
* @param {QuickReply[]} replies
|
|
95
|
+
* @param {LinksMap} linksMap
|
|
96
|
+
* @param {ConditionContext} context
|
|
97
|
+
*/
|
|
71
98
|
function parseReplies (replies, linksMap, context) {
|
|
72
99
|
return replies.map((reply) => {
|
|
73
100
|
|
|
@@ -314,8 +341,9 @@ function message (params, context = {}) {
|
|
|
314
341
|
/**
|
|
315
342
|
* @param {Request} req
|
|
316
343
|
* @param {Responder} res
|
|
344
|
+
* @param {Function } postBack
|
|
317
345
|
*/
|
|
318
|
-
return async (req, res) => {
|
|
346
|
+
return async (req, res, postBack) => {
|
|
319
347
|
if (condition === undefined) {
|
|
320
348
|
condition = getCondition(params, context, 'Message condition');
|
|
321
349
|
}
|
|
@@ -425,6 +453,20 @@ function message (params, context = {}) {
|
|
|
425
453
|
await session.systemPrompt(text)
|
|
426
454
|
.generate();
|
|
427
455
|
|
|
456
|
+
const evaluation = await res.llmEvaluate(session, params.llmContextType);
|
|
457
|
+
|
|
458
|
+
if (evaluation.discard) {
|
|
459
|
+
if (isLastMessage && !req.actionData()._resolverTag) {
|
|
460
|
+
res.finalMessageSent = true;
|
|
461
|
+
}
|
|
462
|
+
return ret;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
if (evaluation.action) {
|
|
466
|
+
postBack(evaluation.action);
|
|
467
|
+
return Router.END;
|
|
468
|
+
}
|
|
469
|
+
|
|
428
470
|
// if (!response.content) {
|
|
429
471
|
// // no response?
|
|
430
472
|
// }
|
package/src/resolvers/utils.js
CHANGED
|
@@ -31,17 +31,26 @@ const WEBVIEW_COMPACT = 'compact';
|
|
|
31
31
|
* @prop {string|null} p - purpose
|
|
32
32
|
*/
|
|
33
33
|
|
|
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
|
+
|
|
34
43
|
/**
|
|
35
44
|
* @typedef Translation
|
|
36
45
|
* @property {string|string[]} t - text alternatives
|
|
37
46
|
* @property {string | null} l - language
|
|
38
|
-
* @property {
|
|
39
|
-
* null = default + voice
|
|
40
|
-
* t = text
|
|
41
|
-
* v = voice
|
|
42
|
-
* s = ssml
|
|
47
|
+
* @property {Purpose | Purpose[]} [p] - purposes
|
|
43
48
|
*/
|
|
44
49
|
|
|
50
|
+
/**
|
|
51
|
+
* @param {string | string[] | Translation | Translation[]} translations
|
|
52
|
+
* @returns {translations is Translation[]}
|
|
53
|
+
*/
|
|
45
54
|
function isArrayOfObjects (translations) {
|
|
46
55
|
return Array.isArray(translations)
|
|
47
56
|
&& typeof translations[0] === 'object'
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author David Menger
|
|
3
|
+
*/
|
|
4
|
+
'use strict';
|
|
5
|
+
|
|
6
|
+
const assert = require('assert');
|
|
7
|
+
const asserts = require('./asserts');
|
|
8
|
+
|
|
9
|
+
const { ex } = asserts;
|
|
10
|
+
|
|
11
|
+
/** @typedef {import('../LLM').PromptInfo} PromptInfo */
|
|
12
|
+
/** @typedef {import('../LLM').LLMMessage} LLMMessage */
|
|
13
|
+
/** @typedef {import('../LLM').LLMRole} LLMRole */
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @class PromptAssert
|
|
17
|
+
*/
|
|
18
|
+
class PromptAssert {
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
*
|
|
22
|
+
* @param {PromptInfo[]} prompts
|
|
23
|
+
*/
|
|
24
|
+
constructor (prompts) {
|
|
25
|
+
this._prompts = prompts;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Check if recent instruction contains selected string
|
|
30
|
+
*
|
|
31
|
+
* @param {string} search
|
|
32
|
+
* @returns {this}
|
|
33
|
+
*/
|
|
34
|
+
instructionContains (search) {
|
|
35
|
+
const messages = this._flatPrompt((m) => m.role === 'system');
|
|
36
|
+
this._promptContains(search, messages, false, 'of role "system"');
|
|
37
|
+
return this;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Check if recent prompt input contains selected string
|
|
42
|
+
*
|
|
43
|
+
* @param {string} search
|
|
44
|
+
* @returns {this}
|
|
45
|
+
*/
|
|
46
|
+
promptContains (search) {
|
|
47
|
+
this._promptContains(search, this._flatPrompt());
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Check if recent results contains selected string
|
|
53
|
+
*
|
|
54
|
+
* @param {string} search
|
|
55
|
+
* @returns {this}
|
|
56
|
+
*/
|
|
57
|
+
resultContains (search) {
|
|
58
|
+
this._promptContains(search, this._flatResults());
|
|
59
|
+
return this;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
*
|
|
64
|
+
* @param {(value: LLMMessage, index: number, array: LLMMessage[]) => unknown} filter
|
|
65
|
+
* @returns {LLMMessage[]}
|
|
66
|
+
*/
|
|
67
|
+
_flatPrompt (filter = () => true) {
|
|
68
|
+
return this._prompts
|
|
69
|
+
.flatMap((prompt) => prompt.prompt
|
|
70
|
+
.filter(filter));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
*
|
|
75
|
+
* @returns {LLMMessage[]}
|
|
76
|
+
*/
|
|
77
|
+
_flatResults () {
|
|
78
|
+
return this._prompts
|
|
79
|
+
.map((prompt) => prompt.result);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
_promptContains (search, messages, notContains = false, addMessage = 'No LLM message found') {
|
|
83
|
+
if (messages.length === 0) {
|
|
84
|
+
PromptAssert.debug(this._prompts, true);
|
|
85
|
+
assert.fail(ex(`No LLM message ${addMessage}`, search));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const found = messages.some((m) => asserts.llmContains(m, search, false));
|
|
89
|
+
// console.log({ found, messages, notContains });
|
|
90
|
+
if (notContains === found) {
|
|
91
|
+
PromptAssert.debug(this._prompts, true);
|
|
92
|
+
assert.fail(ex(
|
|
93
|
+
`Text${notContains ? '' : ' not'} found in LLM messages ${addMessage}`,
|
|
94
|
+
search
|
|
95
|
+
));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
*
|
|
101
|
+
* @param {LLMMessage[]} prompt
|
|
102
|
+
* @returns {string}
|
|
103
|
+
*/
|
|
104
|
+
static promptStats (prompt) {
|
|
105
|
+
const stats = prompt.reduce((o, m) => Object.assign(o, {
|
|
106
|
+
[m.role]: (o[m.role] || 0) + 1
|
|
107
|
+
}), {
|
|
108
|
+
system: 0, assistant: 0, user: 0, tool: 0
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
return `[ ${Object.entries(stats).map(([k, v]) => `${k.toUpperCase()}: ${v}`).join(' ')} ]`;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
*
|
|
116
|
+
* @param {LLMRole} role
|
|
117
|
+
* @return {string}
|
|
118
|
+
*/
|
|
119
|
+
static _marker (role) {
|
|
120
|
+
switch (role) {
|
|
121
|
+
case 'user':
|
|
122
|
+
return '>';
|
|
123
|
+
case 'system':
|
|
124
|
+
return '*';
|
|
125
|
+
case 'assistant':
|
|
126
|
+
return '<';
|
|
127
|
+
default:
|
|
128
|
+
return '-';
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
static _content (msg, full) {
|
|
133
|
+
if (typeof msg.content !== 'string') {
|
|
134
|
+
return msg.content === null ? '<null>' : typeof msg.content;
|
|
135
|
+
}
|
|
136
|
+
const txt = msg.content.replace(/\n+/g, ' ').replace(/\s\s+/g, ' ');
|
|
137
|
+
return `'${txt.length <= 100 || full ? txt : `${txt.substring(0, 100)}...`}'`;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
*
|
|
142
|
+
* @param {PromptInfo[]} prompts
|
|
143
|
+
* @param {boolean} [full=false]
|
|
144
|
+
* @param {boolean} [silent=false]
|
|
145
|
+
* @returns {string[]}
|
|
146
|
+
*/
|
|
147
|
+
static debug (prompts, full = false, silent = false) {
|
|
148
|
+
let out;
|
|
149
|
+
if (prompts.length === 0) {
|
|
150
|
+
out = ['no LLM prompts occured'];
|
|
151
|
+
} else {
|
|
152
|
+
out = prompts.map((p, i) => {
|
|
153
|
+
const lastIndexOfUser = full
|
|
154
|
+
? 0
|
|
155
|
+
: p.prompt.reduce((li, m, c) => (m.role === 'user' ? c : li), 0);
|
|
156
|
+
|
|
157
|
+
const prompt = p.prompt.reduce((a, m, c) => {
|
|
158
|
+
if (['user', 'assistant'].includes(m.role) && c < lastIndexOfUser) {
|
|
159
|
+
const prev = a[a.length - 1];
|
|
160
|
+
if (prev === '...') {
|
|
161
|
+
return a;
|
|
162
|
+
}
|
|
163
|
+
return [...a, '...'];
|
|
164
|
+
}
|
|
165
|
+
return [...a, `${PromptAssert._marker(m.role)} ${PromptAssert._content(m, full)}`];
|
|
166
|
+
}, []);
|
|
167
|
+
|
|
168
|
+
return [
|
|
169
|
+
`${i + 1}) ${PromptAssert.promptStats(p.prompt)}`,
|
|
170
|
+
`${prompt.join('\n ')}`,
|
|
171
|
+
`# ${PromptAssert._content(p.result)}`
|
|
172
|
+
].join('\n ');
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
if (!silent) {
|
|
176
|
+
// eslint-disable-next-line no-console
|
|
177
|
+
console.log(...out);
|
|
178
|
+
}
|
|
179
|
+
return out;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
module.exports = PromptAssert;
|
package/src/testTools/asserts.js
CHANGED
|
@@ -7,6 +7,9 @@ const assert = require('assert');
|
|
|
7
7
|
const deepExtend = require('deep-extend');
|
|
8
8
|
const { actionMatches, parseActionPayload } = require('../utils');
|
|
9
9
|
|
|
10
|
+
/** @typedef {import('../LLM').PromptInfo} PromptInfo */
|
|
11
|
+
/** @typedef {import('../LLM').LLMMessage} LLMMessage */
|
|
12
|
+
|
|
10
13
|
/**
|
|
11
14
|
* Format message
|
|
12
15
|
*
|
|
@@ -29,9 +32,21 @@ function m (text, actual = null, expected = null) {
|
|
|
29
32
|
return `${text}${result}`;
|
|
30
33
|
}
|
|
31
34
|
|
|
32
|
-
function ex (message, expected, actual) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
function ex (message, expected, actual = null) {
|
|
36
|
+
let actuals;
|
|
37
|
+
if (Array.isArray(actual)) {
|
|
38
|
+
actuals = actual;
|
|
39
|
+
} else {
|
|
40
|
+
actuals = actual === null ? [] : [actual];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const msg = `${message}\n + expected: "${expected}"`;
|
|
44
|
+
|
|
45
|
+
if (actuals.length === 0) {
|
|
46
|
+
return msg;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return `${msg}\n - actual: ${actuals
|
|
35
50
|
.map((a) => `"${a}"`).join('\n ')}`;
|
|
36
51
|
}
|
|
37
52
|
|
|
@@ -144,6 +159,28 @@ function contains (response, search, message = 'Should contain a text') {
|
|
|
144
159
|
return true;
|
|
145
160
|
}
|
|
146
161
|
|
|
162
|
+
/**
|
|
163
|
+
*
|
|
164
|
+
* @param {LLMMessage} llmMsg
|
|
165
|
+
* @param {string} search
|
|
166
|
+
* @param {string|false} message
|
|
167
|
+
*/
|
|
168
|
+
function llmContains (llmMsg, search, message = 'Should contain a text') {
|
|
169
|
+
const text = llmMsg.content;
|
|
170
|
+
|
|
171
|
+
const typeIsText = typeof text === 'string';
|
|
172
|
+
if (message === false && !typeIsText) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
assert.ok(typeIsText, m(message, search, 'not a text message'));
|
|
176
|
+
const match = searchMatchesText(search, text);
|
|
177
|
+
if (message === false) {
|
|
178
|
+
return match;
|
|
179
|
+
}
|
|
180
|
+
assert.ok(match, m(message, text, search));
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
|
|
147
184
|
/**
|
|
148
185
|
* Checks quick response action
|
|
149
186
|
*
|
|
@@ -374,5 +411,6 @@ module.exports = {
|
|
|
374
411
|
quickReplyText,
|
|
375
412
|
getText,
|
|
376
413
|
parseActionPayload,
|
|
377
|
-
ex
|
|
414
|
+
ex,
|
|
415
|
+
llmContains
|
|
378
416
|
};
|
|
@@ -175,9 +175,22 @@ const compare = (variable, operator, value = undefined) => {
|
|
|
175
175
|
}
|
|
176
176
|
};
|
|
177
177
|
|
|
178
|
+
/** @typedef {'if'|'it'|'c'|'nc'|'mr'|'nmr'|'st'|'gt'|'set'|'get'|'eq'|'neq'} ConditionOperator */
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* @typedef {object} EditableConditionRule
|
|
182
|
+
* @prop {string} value
|
|
183
|
+
* @prop {ConditionOperator} operator
|
|
184
|
+
* @prop {string} variable
|
|
185
|
+
*/
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* @typedef {EditableConditionRule[][]} EditableCondition
|
|
189
|
+
*/
|
|
190
|
+
|
|
178
191
|
/**
|
|
179
192
|
*
|
|
180
|
-
* @param {
|
|
193
|
+
* @param {EditableCondition} condition
|
|
181
194
|
* @param {object} configuration
|
|
182
195
|
* @param {string} description
|
|
183
196
|
*/
|
|
@@ -7,11 +7,23 @@ const customCondition = require('./customCondition');
|
|
|
7
7
|
const customFn = require('./customFn');
|
|
8
8
|
|
|
9
9
|
/** @typedef {import('../BuildRouter').BotContext} BotContext */
|
|
10
|
+
/** @typedef {import('./customCondition').EditableCondition} EditableCondition */
|
|
11
|
+
|
|
12
|
+
// eslint-disable-next-line max-len
|
|
13
|
+
/** @typedef {Pick<BotContext,'configuration'|'allowForbiddenSnippetWords'|'linksMap'|'ai'>} ConditionContext */
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {object} ConditionDefinition
|
|
17
|
+
* @prop {boolean} [hasCondition]
|
|
18
|
+
* @prop {string} [conditionFn]
|
|
19
|
+
* @prop {boolean} [hasEditableCondition]
|
|
20
|
+
* @prop {EditableCondition} [editableCondition]
|
|
21
|
+
*/
|
|
10
22
|
|
|
11
23
|
/**
|
|
12
24
|
*
|
|
13
|
-
* @param {
|
|
14
|
-
* @param {
|
|
25
|
+
* @param {ConditionDefinition} params
|
|
26
|
+
* @param {ConditionContext} context
|
|
15
27
|
* @param {string} description
|
|
16
28
|
* @returns {Function}
|
|
17
29
|
*/
|
|
@@ -27,7 +39,7 @@ module.exports = function getCondition (params, context, description = '') {
|
|
|
27
39
|
editableCondition = []
|
|
28
40
|
} = params;
|
|
29
41
|
|
|
30
|
-
let condition
|
|
42
|
+
let condition;
|
|
31
43
|
|
|
32
44
|
if (hasCondition) {
|
|
33
45
|
if (hasEditableCondition) {
|
|
@@ -36,7 +48,7 @@ module.exports = function getCondition (params, context, description = '') {
|
|
|
36
48
|
condition = customFn(conditionFn, description, allowForbiddenSnippetWords);
|
|
37
49
|
}
|
|
38
50
|
} else {
|
|
39
|
-
condition =
|
|
51
|
+
condition = () => true;
|
|
40
52
|
}
|
|
41
53
|
return condition;
|
|
42
54
|
};
|
package/src/utils/getUpdate.js
CHANGED
|
@@ -88,7 +88,7 @@ function toArray (previousValue) {
|
|
|
88
88
|
const ENTITY_HBS_REGEXP = /^\s*\{\{\[?@([^@[\]{}\s]+)(\])?\}\}\s*$/;
|
|
89
89
|
const VARIABLE_HBS_REGEXP = /^\s*\{\{\[?([^$@[\]{}\s]+)\]?\}\}\s*$/;
|
|
90
90
|
|
|
91
|
-
function getSetState (setState, req, res = null,
|
|
91
|
+
function getSetState (setState, req, res = null, stateOverride = null, configuration = null) {
|
|
92
92
|
if (!setState) {
|
|
93
93
|
return {};
|
|
94
94
|
}
|
|
@@ -96,7 +96,7 @@ function getSetState (setState, req, res = null, useState = null, configuration
|
|
|
96
96
|
.filter((k) => k !== '_');
|
|
97
97
|
|
|
98
98
|
let obj = {};
|
|
99
|
-
let state = stateData(req, res, configuration,
|
|
99
|
+
let state = stateData(req, res, configuration, stateOverride);
|
|
100
100
|
|
|
101
101
|
keys.forEach((k) => {
|
|
102
102
|
const val = setState[k];
|
|
@@ -166,8 +166,8 @@ function getSetState (setState, req, res = null, useState = null, configuration
|
|
|
166
166
|
if (entity && (!rear || req.entities.some((e) => e.entity === entity))) {
|
|
167
167
|
values = req.entities.filter((e) => e.entity === entity)
|
|
168
168
|
.map((e) => e.value);
|
|
169
|
-
if (values.length === 0 &&
|
|
170
|
-
values = [
|
|
169
|
+
if (values.length === 0 && stateOverride && stateOverride[`@${entity}`]) {
|
|
170
|
+
values = [stateOverride[`@${entity}`]];
|
|
171
171
|
}
|
|
172
172
|
} else if (variable) {
|
|
173
173
|
values = toArray(getValue(variable, state));
|
package/src/utils/stateData.js
CHANGED
|
@@ -16,6 +16,7 @@ const { dateToISO8601String, zeroHourDate } = require('./datetime');
|
|
|
16
16
|
* @prop {object} [configuration]
|
|
17
17
|
* @prop {Function} text
|
|
18
18
|
* @prop {Function} [actionData]
|
|
19
|
+
* @prop {Function} [isConfidentInput]
|
|
19
20
|
*/
|
|
20
21
|
|
|
21
22
|
/**
|
|
@@ -68,6 +69,7 @@ module.exports = function stateData (
|
|
|
68
69
|
$today,
|
|
69
70
|
$tomorrow,
|
|
70
71
|
$yesterday,
|
|
72
|
+
$llmResult: res?.llm?.lastResult?.content,
|
|
71
73
|
// yes - res because of circular dependency
|
|
72
74
|
...(res && req && req.actionData()),
|
|
73
75
|
...(res ? res.data : {}),
|