@miso.ai/client-sdk-ui 1.12.1-beta.1 → 1.12.1-beta.2
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/cjs/actor/fields.js +0 -4
- package/dist/cjs/actor/view.js +36 -24
- package/dist/cjs/actor/views.js +2 -14
- package/dist/cjs/defaults/ask/templates.js +29 -11
- package/dist/cjs/layout/input/option-list.js +2 -9
- package/dist/cjs/layout/text/typewriter/index.js +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/workflow/ask.js +45 -26
- package/dist/cjs/workflow/base.js +1 -2
- package/dist/cjs/workflow/hybrid-search-views.js +0 -1
- package/dist/cjs/workflow/processors.js +20 -9
- package/package.json +2 -2
- package/src/actor/fields.js +0 -4
- package/src/actor/view.js +31 -17
- package/src/actor/views.js +2 -12
- package/src/defaults/ask/templates.js +36 -23
- package/src/layout/input/option-list.js +1 -8
- package/src/layout/text/typewriter/index.js +1 -1
- package/src/version.js +1 -1
- package/src/workflow/ask.js +46 -18
- package/src/workflow/base.js +2 -2
- package/src/workflow/hybrid-search-views.js +0 -1
- package/src/workflow/processors.js +16 -9
package/dist/cjs/actor/fields.js
CHANGED
|
@@ -14,15 +14,11 @@ exports.query = query;
|
|
|
14
14
|
exports.request = request;
|
|
15
15
|
exports.response = response;
|
|
16
16
|
exports.session = session;
|
|
17
|
-
exports.suggestions = suggestions;
|
|
18
17
|
exports.tracker = tracker;
|
|
19
18
|
exports.view = view;
|
|
20
19
|
function session() {
|
|
21
20
|
return 'session';
|
|
22
21
|
}
|
|
23
|
-
function suggestions() {
|
|
24
|
-
return 'suggestions';
|
|
25
|
-
}
|
|
26
22
|
function completions() {
|
|
27
23
|
return 'completions';
|
|
28
24
|
}
|
package/dist/cjs/actor/view.js
CHANGED
|
@@ -9,25 +9,32 @@ var _constants = require("../constants.js");
|
|
|
9
9
|
var fields = _interopRequireWildcard(require("./fields.js"));
|
|
10
10
|
var _proxy = _interopRequireDefault(require("../util/proxy.js"));
|
|
11
11
|
var _tracker = _interopRequireDefault(require("./tracker.js"));
|
|
12
|
-
var _utils = require("../element/util/utils.js");
|
|
13
12
|
const _excluded = ["value", "error", "status", "meta"];
|
|
14
13
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
15
14
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
16
15
|
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
16
|
+
//import { triggerMisoAction } from '../element/util/utils.js';
|
|
17
|
+
|
|
17
18
|
function statesEqual(a, b) {
|
|
18
19
|
return a === b || a && b && a.status === b.status && a.error === b.error && a.value === b.value &&
|
|
19
20
|
// skip deep equals
|
|
20
|
-
a.ongoing === b.ongoing &&
|
|
21
|
+
a.ongoing === b.ongoing && stateEmptyness(a) === stateEmptyness(b) &&
|
|
22
|
+
// TODO: ad-hoc
|
|
23
|
+
sessionEquals(a.session, b.session);
|
|
21
24
|
}
|
|
22
25
|
function sessionEquals(a, b) {
|
|
23
26
|
return a === b || a && b && a.uuid === b.uuid;
|
|
24
27
|
}
|
|
28
|
+
function stateEmptyness(data) {
|
|
29
|
+
return data && data.meta && data.meta.empty;
|
|
30
|
+
}
|
|
25
31
|
class ViewActor {
|
|
26
32
|
constructor(views, role) {
|
|
27
33
|
this._events = new _commons.EventEmitter({
|
|
28
34
|
target: this
|
|
29
35
|
});
|
|
30
36
|
this._views = views;
|
|
37
|
+
// TODO: we should pull this up to views, for the results are also used in judging container emptyness
|
|
31
38
|
this._mapping = asMappingFunction((views._roles.mappings || {})[role] || role);
|
|
32
39
|
(0, _commons.defineValues)(this, {
|
|
33
40
|
role,
|
|
@@ -113,6 +120,9 @@ class ViewActor {
|
|
|
113
120
|
}
|
|
114
121
|
return this._tracker;
|
|
115
122
|
}
|
|
123
|
+
get workflow() {
|
|
124
|
+
return this._views._workflow;
|
|
125
|
+
}
|
|
116
126
|
get workflowOptions() {
|
|
117
127
|
return this._views._options.resolved;
|
|
118
128
|
}
|
|
@@ -162,7 +172,7 @@ class ViewActor {
|
|
|
162
172
|
request,
|
|
163
173
|
meta,
|
|
164
174
|
data: value
|
|
165
|
-
}, getDataEmptyness(data));
|
|
175
|
+
}, getDataEmptyness(this.role, data));
|
|
166
176
|
|
|
167
177
|
// render
|
|
168
178
|
const notifyUpdate = (state = {}, options) => {
|
|
@@ -194,15 +204,17 @@ class ViewActor {
|
|
|
194
204
|
silent
|
|
195
205
|
});
|
|
196
206
|
}
|
|
207
|
+
|
|
208
|
+
/*
|
|
197
209
|
triggerAction(data) {
|
|
198
|
-
const {
|
|
199
|
-
element
|
|
200
|
-
} = this;
|
|
210
|
+
const { element } = this;
|
|
201
211
|
if (!element) {
|
|
202
212
|
return;
|
|
203
213
|
}
|
|
204
|
-
|
|
214
|
+
triggerMisoAction(element, data);
|
|
205
215
|
}
|
|
216
|
+
*/
|
|
217
|
+
|
|
206
218
|
_sliceData(data) {
|
|
207
219
|
const {
|
|
208
220
|
value,
|
|
@@ -219,12 +231,12 @@ class ViewActor {
|
|
|
219
231
|
if (this.role === _constants.ROLE.CONTAINER) {
|
|
220
232
|
// pass empty/nonempty information
|
|
221
233
|
sliced.meta = Object.assign({}, meta, {
|
|
222
|
-
empty: this._isContainerEmpty(
|
|
234
|
+
empty: this._isContainerEmpty(data)
|
|
223
235
|
});
|
|
224
236
|
}
|
|
225
237
|
return (0, _commons.trimObj)(sliced);
|
|
226
238
|
}
|
|
227
|
-
_isContainerEmpty(
|
|
239
|
+
_isContainerEmpty(data) {
|
|
228
240
|
const {
|
|
229
241
|
element
|
|
230
242
|
} = this;
|
|
@@ -239,14 +251,10 @@ class ViewActor {
|
|
|
239
251
|
if (!(0, _constants.isDataRole)(role)) {
|
|
240
252
|
continue;
|
|
241
253
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
const data = this.hub.states[fields.suggestions()];
|
|
247
|
-
sliced = data && data.value;
|
|
248
|
-
}
|
|
249
|
-
if (sliced && sliced.length !== 0) {
|
|
254
|
+
// respect data mapping
|
|
255
|
+
const mapping = asMappingFunction((this._views._roles.mappings || {})[role] || role);
|
|
256
|
+
const sliced = mapping(data, this); // TODO: the view passed in should be the view of the role, not container role
|
|
257
|
+
if (!isDateValueEmpty(role, sliced)) {
|
|
250
258
|
return false;
|
|
251
259
|
}
|
|
252
260
|
}
|
|
@@ -289,17 +297,21 @@ function asMappingFunction(fn) {
|
|
|
289
297
|
throw new Error(`Invalid mapping function: ${fn}`);
|
|
290
298
|
}
|
|
291
299
|
}
|
|
292
|
-
function getDataEmptyness(data) {
|
|
300
|
+
function getDataEmptyness(role, data) {
|
|
293
301
|
return isDataStatusRelevantToEmptyness(data) ? {
|
|
294
|
-
empty: !!isDateValueEmpty(data)
|
|
302
|
+
empty: !!isDateValueEmpty(role, data && data.value)
|
|
295
303
|
} : {};
|
|
296
304
|
}
|
|
297
305
|
function isDataStatusRelevantToEmptyness(data) {
|
|
298
306
|
return data.status === _constants.STATUS.READY && !data.ongoing;
|
|
299
307
|
}
|
|
300
|
-
function isDateValueEmpty(
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
308
|
+
function isDateValueEmpty(role, value) {
|
|
309
|
+
// TODO: ad-hoc
|
|
310
|
+
switch (role) {
|
|
311
|
+
case _constants.ROLE.ANSWER:
|
|
312
|
+
case _constants.ROLE.REASONING:
|
|
313
|
+
return !value || !value.value;
|
|
314
|
+
default:
|
|
315
|
+
return value === undefined || (Array.isArray(value) || typeof value === 'string') && !value.length;
|
|
316
|
+
}
|
|
305
317
|
}
|
package/dist/cjs/actor/views.js
CHANGED
|
@@ -22,7 +22,8 @@ class ViewsActor {
|
|
|
22
22
|
options
|
|
23
23
|
}) {
|
|
24
24
|
this._hub = hub;
|
|
25
|
-
this.
|
|
25
|
+
this._workflow = workflow;
|
|
26
|
+
this._workflowName = workflow._name;
|
|
26
27
|
this._extensions = extensions;
|
|
27
28
|
this._layoutFactory = layouts;
|
|
28
29
|
this._options = options;
|
|
@@ -189,19 +190,6 @@ class ViewsActor {
|
|
|
189
190
|
data = this._getData(data);
|
|
190
191
|
// container first
|
|
191
192
|
let views = this._getViews(true);
|
|
192
|
-
if (!force && data._inst) {
|
|
193
|
-
const {
|
|
194
|
-
includes,
|
|
195
|
-
excludes
|
|
196
|
-
} = data._inst;
|
|
197
|
-
if (includes) {
|
|
198
|
-
// always include containers
|
|
199
|
-
views = views.filter(view => view.role === _constants.ROLE.CONTAINER || includes.includes(view.role));
|
|
200
|
-
}
|
|
201
|
-
if (excludes) {
|
|
202
|
-
views = views.filter(view => !excludes.includes(view.role));
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
193
|
await Promise.all(views.map(view => view.refresh({
|
|
206
194
|
force,
|
|
207
195
|
data
|
|
@@ -23,11 +23,24 @@ class Sections extends _templates.Sections {
|
|
|
23
23
|
const {
|
|
24
24
|
container
|
|
25
25
|
} = this._helpers;
|
|
26
|
-
return [
|
|
26
|
+
return [this.question(options), this.reasoning(options), this.answer(options), this.affiliation(options), this.sources(options), container(options, {
|
|
27
27
|
name: 'bottom-spacing',
|
|
28
28
|
visibleWhen: 'ongoing'
|
|
29
29
|
})];
|
|
30
30
|
}
|
|
31
|
+
question(options) {
|
|
32
|
+
const {
|
|
33
|
+
container,
|
|
34
|
+
phrase
|
|
35
|
+
} = this._helpers;
|
|
36
|
+
return container(options, {
|
|
37
|
+
name: 'question',
|
|
38
|
+
visibleWhen: 'ready'
|
|
39
|
+
}, [options.parentQuestionId ? '<hr>' : '', phrase(options, {
|
|
40
|
+
name: 'question',
|
|
41
|
+
tag: 'div'
|
|
42
|
+
}), '<miso-question></miso-question>']);
|
|
43
|
+
}
|
|
31
44
|
answer(options) {
|
|
32
45
|
const {
|
|
33
46
|
container
|
|
@@ -35,28 +48,33 @@ class Sections extends _templates.Sections {
|
|
|
35
48
|
return container(options, {
|
|
36
49
|
name: 'answer',
|
|
37
50
|
visibleWhen: 'ready'
|
|
38
|
-
}, [
|
|
51
|
+
}, ['<miso-answer></miso-answer>', '<miso-feedback></miso-feedback>']);
|
|
39
52
|
}
|
|
40
|
-
reasoning({
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
53
|
+
reasoning(options = {}) {
|
|
54
|
+
const {
|
|
55
|
+
phrases,
|
|
56
|
+
reasoning: reasoningOptions = {}
|
|
57
|
+
} = options;
|
|
44
58
|
const {
|
|
59
|
+
container,
|
|
45
60
|
element,
|
|
46
61
|
phraseText
|
|
47
62
|
} = this._helpers;
|
|
48
63
|
const classes = [];
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return
|
|
64
|
+
//reasoningOptions.hide !== false && classes.push('hidden');
|
|
65
|
+
reasoningOptions.expand && classes.push('expanded');
|
|
66
|
+
return container(options, {
|
|
67
|
+
name: 'reasoning',
|
|
68
|
+
visibleWhen: 'nonempty'
|
|
69
|
+
}, [element('miso-collapsible', {
|
|
52
70
|
classes,
|
|
53
71
|
'data-role': 'reasoning-container'
|
|
54
72
|
}, [element('div', {
|
|
55
73
|
classes: ['miso-collapsible__header'],
|
|
56
74
|
'data-role': 'toggle-expand'
|
|
57
|
-
}, [`<div class="miso-collapsible__icon">${
|
|
75
|
+
}, [`<div class="miso-collapsible__icon">${reasoningOptions.icon || _svgs.BULB}</div>`, `<div class="miso-collapsible__title" data-role="title">${phraseText(phrases, 'thoughts')}</div>`, `<div class="miso-collapsible__toggle">${_svgs.CHEVRON}</div>`]), element('div', {
|
|
58
76
|
classes: ['miso-collapsible__body']
|
|
59
|
-
}, ['<miso-reasoning></miso-reasoning>'])]);
|
|
77
|
+
}, ['<miso-reasoning></miso-reasoning>'])])]);
|
|
60
78
|
}
|
|
61
79
|
sources(options) {
|
|
62
80
|
const {
|
|
@@ -77,16 +77,9 @@ class OptionListLayout extends _template.default {
|
|
|
77
77
|
}
|
|
78
78
|
initialize(view) {
|
|
79
79
|
const {
|
|
80
|
-
proxyElement
|
|
81
|
-
hub
|
|
80
|
+
proxyElement
|
|
82
81
|
} = view;
|
|
83
|
-
this._unsubscribes = [...this._unsubscribes, proxyElement.on('click', e => this._handleClick(e))
|
|
84
|
-
];
|
|
85
|
-
}
|
|
86
|
-
_preprocess() {
|
|
87
|
-
return super._preprocess({
|
|
88
|
-
state: this._view.hub.states[_index.fields.suggestions()] // TODO: use data mapping
|
|
89
|
-
});
|
|
82
|
+
this._unsubscribes = [...this._unsubscribes, proxyElement.on('click', e => this._handleClick(e))];
|
|
90
83
|
}
|
|
91
84
|
_render(element, data, controls) {
|
|
92
85
|
super._render(element, data, controls);
|
|
@@ -130,7 +130,7 @@ class TypewriterLayout extends _progressive.default {
|
|
|
130
130
|
const sameSession = (0, _utils.fromSameSession)(prev, state);
|
|
131
131
|
const sameStreak = sameSession && stage === prev.stage;
|
|
132
132
|
const streak = !prev ? 0 : sameStreak ? prev.streak : prev.streak + 1;
|
|
133
|
-
const doneAt = sameSession && prev && prev.doneAt || (status === _constants.STATUS.READY && finished ?
|
|
133
|
+
const doneAt = sameSession && prev && prev.doneAt || (status === _constants.STATUS.READY && finished ? performance.now() : undefined);
|
|
134
134
|
const done = doneAt !== undefined;
|
|
135
135
|
return this._prevState = Object.freeze((0, _commons.trimObj)({
|
|
136
136
|
session,
|
package/dist/cjs/version.js
CHANGED
package/dist/cjs/workflow/ask.js
CHANGED
|
@@ -47,7 +47,10 @@ const DEFAULT_OPTIONS = Object.freeze(Object.assign({}, _answerBased.default.DEF
|
|
|
47
47
|
trackers: DEFAULT_TRACKERS
|
|
48
48
|
}));
|
|
49
49
|
const ROLES_OPTIONS = (0, _index3.mergeRolesOptions)(_answerBased.default.ROLES_OPTIONS, {
|
|
50
|
-
members: Object.keys(DEFAULT_LAYOUTS)
|
|
50
|
+
members: Object.keys(DEFAULT_LAYOUTS),
|
|
51
|
+
mappings: {
|
|
52
|
+
[_constants.ROLE.QUERY_SUGGESTIONS]: _processors.mappingSuggestionsData
|
|
53
|
+
}
|
|
51
54
|
});
|
|
52
55
|
class Ask extends _answerBased.default {
|
|
53
56
|
constructor(context, parentQuestionId) {
|
|
@@ -69,24 +72,8 @@ class Ask extends _answerBased.default {
|
|
|
69
72
|
});
|
|
70
73
|
}
|
|
71
74
|
_initSubscriptions(args) {
|
|
72
|
-
this._setSuggestedQuestions();
|
|
73
75
|
super._initSubscriptions(args);
|
|
74
|
-
|
|
75
|
-
_setSuggestedQuestions() {
|
|
76
|
-
const {
|
|
77
|
-
previous
|
|
78
|
-
} = this;
|
|
79
|
-
if (!previous) {
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
// TODO: write question_source from payload._meta, so we don't need to write it to session.meta
|
|
83
|
-
const values = previous.states[_index.fields.data()].value;
|
|
84
|
-
const value = values.suggested_followup_questions || values.followup_questions || [];
|
|
85
|
-
this._hub.update(_index.fields.suggestions(), {
|
|
86
|
-
value: value.map(text => ({
|
|
87
|
-
text
|
|
88
|
-
}))
|
|
89
|
-
});
|
|
76
|
+
this._unsubscribes = [...this._unsubscribes, this._hub.on(_index.fields.view(_constants.ROLE.REASONING), state => this._onReasoningViewUpdate(state))];
|
|
90
77
|
}
|
|
91
78
|
_initSession(args) {
|
|
92
79
|
// register at context
|
|
@@ -153,25 +140,52 @@ class Ask extends _answerBased.default {
|
|
|
153
140
|
// data //
|
|
154
141
|
_updateData(data) {
|
|
155
142
|
super._updateData(data);
|
|
156
|
-
this.
|
|
143
|
+
this._triggerSuggestionsRefreshIfNecessary();
|
|
144
|
+
this._showReasoningContainerIfNecessary(data);
|
|
145
|
+
}
|
|
146
|
+
_triggerSuggestionsRefreshIfNecessary() {
|
|
147
|
+
const {
|
|
148
|
+
next
|
|
149
|
+
} = this;
|
|
150
|
+
if (!next) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
const view = next._views.get(_constants.ROLE.QUERY_SUGGESTIONS);
|
|
154
|
+
view && view.refresh();
|
|
157
155
|
}
|
|
158
|
-
|
|
156
|
+
_showReasoningContainerIfNecessary({
|
|
159
157
|
session,
|
|
160
158
|
value
|
|
161
159
|
} = {}) {
|
|
162
160
|
if (!value || !value.reasoning) {
|
|
163
161
|
return;
|
|
164
162
|
}
|
|
163
|
+
// TODO: shall we solve this issue with container?
|
|
164
|
+
// TODO: shall we just look up on the miso-collapse element?
|
|
165
165
|
const context = this._getSessionContext(session);
|
|
166
166
|
if (context.reasoningShown) {
|
|
167
167
|
return;
|
|
168
168
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
169
|
+
const element = this._getReasoningContainerElement();
|
|
170
|
+
if (!element) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (typeof element.show === 'function') {
|
|
174
|
+
element.show();
|
|
175
|
+
context.reasoningShown = true;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// view //
|
|
180
|
+
_onReasoningViewUpdate({
|
|
181
|
+
status,
|
|
182
|
+
ongoing
|
|
183
|
+
}) {
|
|
184
|
+
if (status !== _constants.STATUS.READY || ongoing) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
const element = this._getReasoningContainerElement();
|
|
188
|
+
element && element.classList.add('done');
|
|
175
189
|
}
|
|
176
190
|
|
|
177
191
|
// interactions //
|
|
@@ -219,6 +233,11 @@ class Ask extends _answerBased.default {
|
|
|
219
233
|
this._questionId = undefined;
|
|
220
234
|
}
|
|
221
235
|
}
|
|
236
|
+
_getReasoningContainerElement() {
|
|
237
|
+
const view = this._views.get(_constants.ROLE.REASONING);
|
|
238
|
+
const element = view && view.element;
|
|
239
|
+
return element && element.closest('[data-role="reasoning-container"]');
|
|
240
|
+
}
|
|
222
241
|
|
|
223
242
|
// destroy //
|
|
224
243
|
_destroy(options) {
|
|
@@ -63,7 +63,6 @@ class Workflow extends _commons.Component {
|
|
|
63
63
|
}
|
|
64
64
|
_initProperties() {}
|
|
65
65
|
_initActors({
|
|
66
|
-
name,
|
|
67
66
|
roles
|
|
68
67
|
}) {
|
|
69
68
|
const hub = this._hub;
|
|
@@ -81,7 +80,7 @@ class Workflow extends _commons.Component {
|
|
|
81
80
|
layouts,
|
|
82
81
|
roles,
|
|
83
82
|
options,
|
|
84
|
-
workflow:
|
|
83
|
+
workflow: this
|
|
85
84
|
});
|
|
86
85
|
this._interactions = new _index.InteractionsActor(hub, {
|
|
87
86
|
client,
|
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
var _constants = require("../constants.js");
|
|
8
7
|
var _hybridSearchResults = _interopRequireDefault(require("./hybrid-search-results.js"));
|
|
9
8
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
9
|
function getSubworkflowByRole(role) {
|
|
@@ -9,6 +9,7 @@ exports.getRevision = getRevision;
|
|
|
9
9
|
exports.mappingAnswerData = mappingAnswerData;
|
|
10
10
|
exports.mappingReasoningData = mappingReasoningData;
|
|
11
11
|
exports.mappingSortData = mappingSortData;
|
|
12
|
+
exports.mappingSuggestionsData = mappingSuggestionsData;
|
|
12
13
|
exports.mergeInteraction = mergeInteraction;
|
|
13
14
|
exports.retainFacetCountsInData = retainFacetCountsInData;
|
|
14
15
|
exports.writeAffiliationInfoToInteraction = writeAffiliationInfoToInteraction;
|
|
@@ -51,9 +52,17 @@ function mappingSortData(_, {
|
|
|
51
52
|
});
|
|
52
53
|
});
|
|
53
54
|
}
|
|
55
|
+
function findDefaultSortOption(options) {
|
|
56
|
+
for (const option of options) {
|
|
57
|
+
if (option.default) {
|
|
58
|
+
return option;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return options[0];
|
|
62
|
+
}
|
|
54
63
|
function mappingAnswerData(data) {
|
|
55
64
|
if (!data || !data.value) {
|
|
56
|
-
return
|
|
65
|
+
return undefined;
|
|
57
66
|
}
|
|
58
67
|
const {
|
|
59
68
|
answer = '',
|
|
@@ -68,7 +77,7 @@ function mappingAnswerData(data) {
|
|
|
68
77
|
}
|
|
69
78
|
function mappingReasoningData(data) {
|
|
70
79
|
if (!data || !data.value) {
|
|
71
|
-
return
|
|
80
|
+
return undefined;
|
|
72
81
|
}
|
|
73
82
|
const {
|
|
74
83
|
reasoning = '',
|
|
@@ -80,13 +89,15 @@ function mappingReasoningData(data) {
|
|
|
80
89
|
finished: !!reasoning_finished
|
|
81
90
|
});
|
|
82
91
|
}
|
|
83
|
-
function
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return
|
|
92
|
+
function mappingSuggestionsData(_, {
|
|
93
|
+
workflow
|
|
94
|
+
} = {}) {
|
|
95
|
+
const previous = workflow.previous;
|
|
96
|
+
const values = previous && previous.states[_index.fields.data()].value;
|
|
97
|
+
const value = values && (values.suggested_followup_questions || values.followup_questions || []);
|
|
98
|
+
return value && value.map(text => ({
|
|
99
|
+
text
|
|
100
|
+
}));
|
|
90
101
|
}
|
|
91
102
|
|
|
92
103
|
// data //
|
package/package.json
CHANGED
package/src/actor/fields.js
CHANGED
package/src/actor/view.js
CHANGED
|
@@ -3,7 +3,7 @@ import { STATUS, ROLE, isDataRole } from '../constants.js';
|
|
|
3
3
|
import * as fields from './fields.js';
|
|
4
4
|
import ProxyElement from '../util/proxy.js';
|
|
5
5
|
import Tracker from './tracker.js';
|
|
6
|
-
import { triggerMisoAction } from '../element/util/utils.js';
|
|
6
|
+
//import { triggerMisoAction } from '../element/util/utils.js';
|
|
7
7
|
|
|
8
8
|
function statesEqual(a, b) {
|
|
9
9
|
return a === b || (a && b &&
|
|
@@ -11,6 +11,7 @@ function statesEqual(a, b) {
|
|
|
11
11
|
a.error === b.error &&
|
|
12
12
|
a.value === b.value && // skip deep equals
|
|
13
13
|
a.ongoing === b.ongoing &&
|
|
14
|
+
stateEmptyness(a) === stateEmptyness(b) && // TODO: ad-hoc
|
|
14
15
|
sessionEquals(a.session, b.session));
|
|
15
16
|
}
|
|
16
17
|
|
|
@@ -18,11 +19,16 @@ function sessionEquals(a, b) {
|
|
|
18
19
|
return a === b || (a && b && a.uuid === b.uuid);
|
|
19
20
|
}
|
|
20
21
|
|
|
22
|
+
function stateEmptyness(data) {
|
|
23
|
+
return data && data.meta && data.meta.empty;
|
|
24
|
+
}
|
|
25
|
+
|
|
21
26
|
export default class ViewActor {
|
|
22
27
|
|
|
23
28
|
constructor(views, role) {
|
|
24
29
|
this._events = new EventEmitter({ target: this });
|
|
25
30
|
this._views = views;
|
|
31
|
+
// TODO: we should pull this up to views, for the results are also used in judging container emptyness
|
|
26
32
|
this._mapping = asMappingFunction((views._roles.mappings || {})[role] || role);
|
|
27
33
|
|
|
28
34
|
defineValues(this, {
|
|
@@ -103,6 +109,10 @@ export default class ViewActor {
|
|
|
103
109
|
}
|
|
104
110
|
return this._tracker;
|
|
105
111
|
}
|
|
112
|
+
|
|
113
|
+
get workflow() {
|
|
114
|
+
return this._views._workflow;
|
|
115
|
+
}
|
|
106
116
|
|
|
107
117
|
get workflowOptions() {
|
|
108
118
|
return this._views._options.resolved;
|
|
@@ -138,7 +148,7 @@ export default class ViewActor {
|
|
|
138
148
|
}
|
|
139
149
|
|
|
140
150
|
const { session, status, ongoing, request, meta, value } = data;
|
|
141
|
-
const baseState = { session, status, ongoing, request, meta, data: value, ...getDataEmptyness(data) };
|
|
151
|
+
const baseState = { session, status, ongoing, request, meta, data: value, ...getDataEmptyness(this.role, data) };
|
|
142
152
|
|
|
143
153
|
// render
|
|
144
154
|
const notifyUpdate = (state = {}, options) => {
|
|
@@ -160,6 +170,7 @@ export default class ViewActor {
|
|
|
160
170
|
this.hub.update(fields.view(role), state, { silent });
|
|
161
171
|
}
|
|
162
172
|
|
|
173
|
+
/*
|
|
163
174
|
triggerAction(data) {
|
|
164
175
|
const { element } = this;
|
|
165
176
|
if (!element) {
|
|
@@ -167,6 +178,7 @@ export default class ViewActor {
|
|
|
167
178
|
}
|
|
168
179
|
triggerMisoAction(element, data);
|
|
169
180
|
}
|
|
181
|
+
*/
|
|
170
182
|
|
|
171
183
|
_sliceData(data) {
|
|
172
184
|
const { value, error, status, meta, ...rest } = data;
|
|
@@ -181,13 +193,13 @@ export default class ViewActor {
|
|
|
181
193
|
// pass empty/nonempty information
|
|
182
194
|
sliced.meta = {
|
|
183
195
|
...meta,
|
|
184
|
-
empty: this._isContainerEmpty(
|
|
196
|
+
empty: this._isContainerEmpty(data),
|
|
185
197
|
};
|
|
186
198
|
}
|
|
187
199
|
return trimObj(sliced);
|
|
188
200
|
}
|
|
189
201
|
|
|
190
|
-
_isContainerEmpty(
|
|
202
|
+
_isContainerEmpty(data) {
|
|
191
203
|
const { element } = this;
|
|
192
204
|
if (!element) {
|
|
193
205
|
return false;
|
|
@@ -198,14 +210,10 @@ export default class ViewActor {
|
|
|
198
210
|
if (!isDataRole(role)) {
|
|
199
211
|
continue;
|
|
200
212
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
const data = this.hub.states[fields.suggestions()];
|
|
206
|
-
sliced = data && data.value;
|
|
207
|
-
}
|
|
208
|
-
if (sliced && sliced.length !== 0) {
|
|
213
|
+
// respect data mapping
|
|
214
|
+
const mapping = asMappingFunction((this._views._roles.mappings || {})[role] || role);
|
|
215
|
+
const sliced = mapping(data, this); // TODO: the view passed in should be the view of the role, not container role
|
|
216
|
+
if (!isDateValueEmpty(role, sliced)) {
|
|
209
217
|
return false;
|
|
210
218
|
}
|
|
211
219
|
}
|
|
@@ -257,15 +265,21 @@ function asMappingFunction(fn) {
|
|
|
257
265
|
}
|
|
258
266
|
}
|
|
259
267
|
|
|
260
|
-
function getDataEmptyness(data) {
|
|
261
|
-
return isDataStatusRelevantToEmptyness(data) ? { empty: !!isDateValueEmpty(data) } : {};
|
|
268
|
+
function getDataEmptyness(role, data) {
|
|
269
|
+
return isDataStatusRelevantToEmptyness(data) ? { empty: !!isDateValueEmpty(role, data && data.value) } : {};
|
|
262
270
|
}
|
|
263
271
|
|
|
264
272
|
function isDataStatusRelevantToEmptyness(data) {
|
|
265
273
|
return data.status === STATUS.READY && !data.ongoing;
|
|
266
274
|
}
|
|
267
275
|
|
|
268
|
-
function isDateValueEmpty(
|
|
269
|
-
|
|
270
|
-
|
|
276
|
+
function isDateValueEmpty(role, value) {
|
|
277
|
+
// TODO: ad-hoc
|
|
278
|
+
switch (role) {
|
|
279
|
+
case ROLE.ANSWER:
|
|
280
|
+
case ROLE.REASONING:
|
|
281
|
+
return !value || !value.value;
|
|
282
|
+
default:
|
|
283
|
+
return value === undefined || ((Array.isArray(value) || typeof value === 'string') && !value.length);
|
|
284
|
+
}
|
|
271
285
|
}
|
package/src/actor/views.js
CHANGED
|
@@ -16,7 +16,8 @@ export default class ViewsActor {
|
|
|
16
16
|
options,
|
|
17
17
|
}) {
|
|
18
18
|
this._hub = hub;
|
|
19
|
-
this.
|
|
19
|
+
this._workflow = workflow;
|
|
20
|
+
this._workflowName = workflow._name;
|
|
20
21
|
this._extensions = extensions;
|
|
21
22
|
this._layoutFactory = layouts;
|
|
22
23
|
this._options = options;
|
|
@@ -193,17 +194,6 @@ export default class ViewsActor {
|
|
|
193
194
|
// container first
|
|
194
195
|
let views = this._getViews(true);
|
|
195
196
|
|
|
196
|
-
if (!force && data._inst) {
|
|
197
|
-
const { includes, excludes } = data._inst;
|
|
198
|
-
if (includes) {
|
|
199
|
-
// always include containers
|
|
200
|
-
views = views.filter(view => view.role === ROLE.CONTAINER || includes.includes(view.role));
|
|
201
|
-
}
|
|
202
|
-
if (excludes) {
|
|
203
|
-
views = views.filter(view => !excludes.includes(view.role));
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
197
|
await Promise.all(views.map(view => view.refresh({ force, data })));
|
|
208
198
|
}
|
|
209
199
|
|
|
@@ -13,43 +13,56 @@ class Sections extends _Sections {
|
|
|
13
13
|
answerGroup(options) {
|
|
14
14
|
const { container } = this._helpers;
|
|
15
15
|
return [
|
|
16
|
-
|
|
16
|
+
this.question(options),
|
|
17
|
+
this.reasoning(options),
|
|
18
|
+
this.answer(options),
|
|
19
|
+
this.affiliation(options),
|
|
20
|
+
this.sources(options),
|
|
17
21
|
container(options, { name: 'bottom-spacing', visibleWhen: 'ongoing' }),
|
|
18
22
|
];
|
|
19
23
|
}
|
|
20
24
|
|
|
25
|
+
question(options) {
|
|
26
|
+
const { container, phrase } = this._helpers;
|
|
27
|
+
return container(options, { name: 'question', visibleWhen: 'ready' }, [
|
|
28
|
+
options.parentQuestionId ? '<hr>' : '',
|
|
29
|
+
phrase(options, { name: 'question', tag: 'div' }),
|
|
30
|
+
'<miso-question></miso-question>',
|
|
31
|
+
]);
|
|
32
|
+
}
|
|
33
|
+
|
|
21
34
|
answer(options) {
|
|
22
35
|
const { container } = this._helpers;
|
|
23
36
|
return container(options, { name: 'answer', visibleWhen: 'ready' }, [
|
|
24
|
-
options.parentQuestionId ? '<hr>' : '',
|
|
25
|
-
...this.question(options),
|
|
26
|
-
this.reasoning(options),
|
|
27
37
|
'<miso-answer></miso-answer>',
|
|
28
38
|
'<miso-feedback></miso-feedback>',
|
|
29
39
|
]);
|
|
30
40
|
}
|
|
31
41
|
|
|
32
|
-
reasoning(
|
|
33
|
-
const {
|
|
42
|
+
reasoning(options = {}) {
|
|
43
|
+
const { phrases, reasoning: reasoningOptions = {} } = options;
|
|
44
|
+
const { container, element, phraseText } = this._helpers;
|
|
34
45
|
const classes = [];
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
element('div', {
|
|
42
|
-
classes: ['miso-collapsible__header'],
|
|
43
|
-
'data-role': 'toggle-expand',
|
|
44
|
-
}, [
|
|
45
|
-
`<div class="miso-collapsible__icon">${options.icon || BULB}</div>`,
|
|
46
|
-
`<div class="miso-collapsible__title" data-role="title">${phraseText(phrases, 'thoughts')}</div>`,
|
|
47
|
-
`<div class="miso-collapsible__toggle">${CHEVRON}</div>`,
|
|
48
|
-
]),
|
|
49
|
-
element('div', {
|
|
50
|
-
classes: ['miso-collapsible__body'],
|
|
46
|
+
//reasoningOptions.hide !== false && classes.push('hidden');
|
|
47
|
+
reasoningOptions.expand && classes.push('expanded');
|
|
48
|
+
return container(options, { name: 'reasoning', visibleWhen: 'nonempty' }, [
|
|
49
|
+
element('miso-collapsible', {
|
|
50
|
+
classes,
|
|
51
|
+
'data-role': 'reasoning-container',
|
|
51
52
|
}, [
|
|
52
|
-
'
|
|
53
|
+
element('div', {
|
|
54
|
+
classes: ['miso-collapsible__header'],
|
|
55
|
+
'data-role': 'toggle-expand',
|
|
56
|
+
}, [
|
|
57
|
+
`<div class="miso-collapsible__icon">${reasoningOptions.icon || BULB}</div>`,
|
|
58
|
+
`<div class="miso-collapsible__title" data-role="title">${phraseText(phrases, 'thoughts')}</div>`,
|
|
59
|
+
`<div class="miso-collapsible__toggle">${CHEVRON}</div>`,
|
|
60
|
+
]),
|
|
61
|
+
element('div', {
|
|
62
|
+
classes: ['miso-collapsible__body'],
|
|
63
|
+
}, [
|
|
64
|
+
'<miso-reasoning></miso-reasoning>',
|
|
65
|
+
]),
|
|
53
66
|
]),
|
|
54
67
|
]);
|
|
55
68
|
}
|
|
@@ -63,20 +63,13 @@ export default class OptionListLayout extends TemplateBasedLayout {
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
initialize(view) {
|
|
66
|
-
const { proxyElement
|
|
66
|
+
const { proxyElement } = view;
|
|
67
67
|
this._unsubscribes = [
|
|
68
68
|
...this._unsubscribes,
|
|
69
69
|
proxyElement.on('click', (e) => this._handleClick(e)),
|
|
70
|
-
hub.on(fields.suggestions(), () => this._handleInput()), // TODO: use data mapping
|
|
71
70
|
];
|
|
72
71
|
}
|
|
73
72
|
|
|
74
|
-
_preprocess() {
|
|
75
|
-
return super._preprocess({
|
|
76
|
-
state: this._view.hub.states[fields.suggestions()], // TODO: use data mapping
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
|
|
80
73
|
_render(element, data, controls) {
|
|
81
74
|
super._render(element, data, controls);
|
|
82
75
|
const { state } = data;
|
|
@@ -112,7 +112,7 @@ export default class TypewriterLayout extends ProgressiveLayout {
|
|
|
112
112
|
const sameStreak = sameSession && (stage === prev.stage);
|
|
113
113
|
const streak = !prev ? 0 : sameStreak ? prev.streak : prev.streak + 1;
|
|
114
114
|
|
|
115
|
-
const doneAt = (sameSession && prev && prev.doneAt) || (status === STATUS.READY && finished ?
|
|
115
|
+
const doneAt = (sameSession && prev && prev.doneAt) || (status === STATUS.READY && finished ? performance.now() : undefined);
|
|
116
116
|
const done = doneAt !== undefined;
|
|
117
117
|
|
|
118
118
|
return this._prevState = Object.freeze(trimObj({
|
package/src/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default '1.12.1-beta.
|
|
1
|
+
export default '1.12.1-beta.2';
|
package/src/workflow/ask.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { defineValues, trimObj, API } from '@miso.ai/commons';
|
|
2
2
|
import AnswerBasedWorkflow from './answer-based.js';
|
|
3
3
|
import { fields } from '../actor/index.js';
|
|
4
|
-
import { ROLE, ORGANIC_QUESTION_SOURCE } from '../constants.js';
|
|
4
|
+
import { ROLE, STATUS, ORGANIC_QUESTION_SOURCE } from '../constants.js';
|
|
5
5
|
import { OptionListLayout, ListLayout, SearchBoxLayout, TypewriterLayout } from '../layout/index.js';
|
|
6
6
|
import { mergeInteraction } from './processors.js';
|
|
7
7
|
import { mergeRolesOptions, DEFAULT_TRACKER_OPTIONS } from './options/index.js';
|
|
8
|
+
import { mappingSuggestionsData } from './processors.js';
|
|
8
9
|
|
|
9
10
|
const DEFAULT_API_OPTIONS = Object.freeze({
|
|
10
11
|
...AnswerBasedWorkflow.DEFAULT_API_OPTIONS,
|
|
@@ -44,6 +45,9 @@ const DEFAULT_OPTIONS = Object.freeze({
|
|
|
44
45
|
|
|
45
46
|
const ROLES_OPTIONS = mergeRolesOptions(AnswerBasedWorkflow.ROLES_OPTIONS, {
|
|
46
47
|
members: Object.keys(DEFAULT_LAYOUTS),
|
|
48
|
+
mappings: {
|
|
49
|
+
[ROLE.QUERY_SUGGESTIONS]: mappingSuggestionsData,
|
|
50
|
+
},
|
|
47
51
|
});
|
|
48
52
|
|
|
49
53
|
export default class Ask extends AnswerBasedWorkflow {
|
|
@@ -65,19 +69,11 @@ export default class Ask extends AnswerBasedWorkflow {
|
|
|
65
69
|
}
|
|
66
70
|
|
|
67
71
|
_initSubscriptions(args) {
|
|
68
|
-
this._setSuggestedQuestions();
|
|
69
72
|
super._initSubscriptions(args);
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
if (!previous) {
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
// TODO: write question_source from payload._meta, so we don't need to write it to session.meta
|
|
78
|
-
const values = previous.states[fields.data()].value;
|
|
79
|
-
const value = values.suggested_followup_questions || values.followup_questions || [];
|
|
80
|
-
this._hub.update(fields.suggestions(), { value: value.map(text => ({ text })) });
|
|
73
|
+
this._unsubscribes = [
|
|
74
|
+
...this._unsubscribes,
|
|
75
|
+
this._hub.on(fields.view(ROLE.REASONING), state => this._onReasoningViewUpdate(state)),
|
|
76
|
+
];
|
|
81
77
|
}
|
|
82
78
|
|
|
83
79
|
_initSession(args) {
|
|
@@ -134,20 +130,46 @@ export default class Ask extends AnswerBasedWorkflow {
|
|
|
134
130
|
// data //
|
|
135
131
|
_updateData(data) {
|
|
136
132
|
super._updateData(data);
|
|
137
|
-
this.
|
|
133
|
+
this._triggerSuggestionsRefreshIfNecessary();
|
|
134
|
+
this._showReasoningContainerIfNecessary(data);
|
|
138
135
|
}
|
|
139
136
|
|
|
140
|
-
|
|
137
|
+
_triggerSuggestionsRefreshIfNecessary() {
|
|
138
|
+
const { next } = this;
|
|
139
|
+
if (!next) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const view = next._views.get(ROLE.QUERY_SUGGESTIONS);
|
|
143
|
+
view && view.refresh();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
_showReasoningContainerIfNecessary({ session, value } = {}) {
|
|
141
147
|
if (!value || !value.reasoning) {
|
|
142
148
|
return;
|
|
143
149
|
}
|
|
150
|
+
// TODO: shall we solve this issue with container?
|
|
151
|
+
// TODO: shall we just look up on the miso-collapse element?
|
|
144
152
|
const context = this._getSessionContext(session);
|
|
145
153
|
if (context.reasoningShown) {
|
|
146
154
|
return;
|
|
147
155
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
156
|
+
const element = this._getReasoningContainerElement();
|
|
157
|
+
if (!element) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
if (typeof element.show === 'function') {
|
|
161
|
+
element.show();
|
|
162
|
+
context.reasoningShown = true;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// view //
|
|
167
|
+
_onReasoningViewUpdate({ status, ongoing }) {
|
|
168
|
+
if (status !== STATUS.READY || ongoing) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const element = this._getReasoningContainerElement();
|
|
172
|
+
element && element.classList.add('done');
|
|
151
173
|
}
|
|
152
174
|
|
|
153
175
|
// interactions //
|
|
@@ -197,6 +219,12 @@ export default class Ask extends AnswerBasedWorkflow {
|
|
|
197
219
|
}
|
|
198
220
|
}
|
|
199
221
|
|
|
222
|
+
_getReasoningContainerElement() {
|
|
223
|
+
const view = this._views.get(ROLE.REASONING);
|
|
224
|
+
const element = view && view.element;
|
|
225
|
+
return element && element.closest('[data-role="reasoning-container"]');
|
|
226
|
+
}
|
|
227
|
+
|
|
200
228
|
// destroy //
|
|
201
229
|
_destroy(options) {
|
|
202
230
|
const { parentQuestionId, questionId } = this;
|
package/src/workflow/base.js
CHANGED
|
@@ -60,7 +60,7 @@ export default class Workflow extends Component {
|
|
|
60
60
|
|
|
61
61
|
_initProperties() {}
|
|
62
62
|
|
|
63
|
-
_initActors({
|
|
63
|
+
_initActors({ roles }) {
|
|
64
64
|
const hub = this._hub;
|
|
65
65
|
const client = this._client;
|
|
66
66
|
const options = this._options;
|
|
@@ -69,7 +69,7 @@ export default class Workflow extends Component {
|
|
|
69
69
|
|
|
70
70
|
this._sessions = new SessionMaker(hub);
|
|
71
71
|
this._data = new DataActor(hub, { source: sources.api(client), options });
|
|
72
|
-
this._views = new ViewsActor(hub, { extensions, layouts, roles, options, workflow:
|
|
72
|
+
this._views = new ViewsActor(hub, { extensions, layouts, roles, options, workflow: this });
|
|
73
73
|
this._interactions = new InteractionsActor(hub, { client, options });
|
|
74
74
|
}
|
|
75
75
|
|
|
@@ -22,9 +22,18 @@ export function mappingSortData(_, { hub, workflowOptions = {} } = {}) {
|
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
function findDefaultSortOption(options) {
|
|
26
|
+
for (const option of options) {
|
|
27
|
+
if (option.default) {
|
|
28
|
+
return option;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return options[0];
|
|
32
|
+
}
|
|
33
|
+
|
|
25
34
|
export function mappingAnswerData(data) {
|
|
26
35
|
if (!data || !data.value) {
|
|
27
|
-
return
|
|
36
|
+
return undefined;
|
|
28
37
|
}
|
|
29
38
|
const { answer = '', answer_stage, finished } = data.value;
|
|
30
39
|
return Object.freeze({ value: answer, stage: answer_stage, finished: !!finished });
|
|
@@ -32,19 +41,17 @@ export function mappingAnswerData(data) {
|
|
|
32
41
|
|
|
33
42
|
export function mappingReasoningData(data) {
|
|
34
43
|
if (!data || !data.value) {
|
|
35
|
-
return
|
|
44
|
+
return undefined;
|
|
36
45
|
}
|
|
37
46
|
const { reasoning = '', reasoning_finished } = data.value;
|
|
38
47
|
return Object.freeze({ value: reasoning, stage: 'reasoning', finished: !!reasoning_finished });
|
|
39
48
|
}
|
|
40
49
|
|
|
41
|
-
function
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
return options[0];
|
|
50
|
+
export function mappingSuggestionsData(_, { workflow } = {}) {
|
|
51
|
+
const previous = workflow.previous;
|
|
52
|
+
const values = previous && previous.states[fields.data()].value;
|
|
53
|
+
const value = values && (values.suggested_followup_questions || values.followup_questions || []);
|
|
54
|
+
return value && value.map(text => ({ text }));
|
|
48
55
|
}
|
|
49
56
|
|
|
50
57
|
// data //
|