@miso.ai/client-sdk-ui 1.12.0 → 1.12.1-beta.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.
Files changed (43) hide show
  1. package/dist/cjs/actor/view.js +10 -0
  2. package/dist/cjs/asset/svgs.js +9 -4
  3. package/dist/cjs/constants.js +2 -1
  4. package/dist/cjs/defaults/ask/phrases.js +3 -2
  5. package/dist/cjs/defaults/ask/templates.js +23 -1
  6. package/dist/cjs/defaults/hybrid-search/answer-box.js +1 -1
  7. package/dist/cjs/element/index.js +17 -8
  8. package/dist/cjs/element/role/index.js +7 -0
  9. package/dist/cjs/element/role/miso-reasoning.js +20 -0
  10. package/dist/cjs/element/util/index.js +20 -0
  11. package/dist/cjs/element/util/miso-collapsible.js +52 -0
  12. package/dist/cjs/element/util/miso-utility.js +83 -0
  13. package/dist/cjs/element/util/utils.js +12 -0
  14. package/dist/cjs/element/utils.js +10 -0
  15. package/dist/cjs/layout/container/container.js +1 -1
  16. package/dist/cjs/layout/text/typewriter/index.js +7 -6
  17. package/dist/cjs/version.js +1 -1
  18. package/dist/cjs/workflow/answer-based.js +5 -1
  19. package/dist/cjs/workflow/ask.js +25 -0
  20. package/dist/cjs/workflow/processors.js +31 -0
  21. package/package.json +2 -2
  22. package/src/actor/view.js +9 -0
  23. package/src/asset/svgs.js +6 -4
  24. package/src/constants.js +2 -0
  25. package/src/defaults/ask/phrases.js +2 -0
  26. package/src/defaults/ask/templates.js +27 -0
  27. package/src/defaults/hybrid-search/answer-box.js +1 -1
  28. package/src/element/index.js +1 -1
  29. package/src/element/role/index.js +1 -0
  30. package/src/element/role/miso-reasoning.js +16 -0
  31. package/src/element/util/index.js +2 -0
  32. package/src/element/util/miso-collapsible.js +49 -0
  33. package/src/element/util/miso-utility.js +69 -0
  34. package/src/element/util/utils.js +3 -0
  35. package/src/element/utils.js +10 -0
  36. package/src/layout/container/container.js +1 -1
  37. package/src/layout/text/typewriter/index.js +2 -3
  38. package/src/version.js +1 -1
  39. package/src/workflow/answer-based.js +5 -1
  40. package/src/workflow/ask.js +21 -1
  41. package/src/workflow/processors.js +16 -0
  42. /package/dist/cjs/element/{miso-banner.js → util/miso-banner.js} +0 -0
  43. /package/src/element/{miso-banner.js → util/miso-banner.js} +0 -0
@@ -9,6 +9,7 @@ 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");
12
13
  const _excluded = ["value", "error", "status", "meta"];
13
14
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
15
  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); }
@@ -193,6 +194,15 @@ class ViewActor {
193
194
  silent
194
195
  });
195
196
  }
197
+ triggerAction(data) {
198
+ const {
199
+ element
200
+ } = this;
201
+ if (!element) {
202
+ return;
203
+ }
204
+ (0, _utils.triggerMisoAction)(element, data);
205
+ }
196
206
  _sliceData(data) {
197
207
  const {
198
208
  value,
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.TRIANGLE_EQ = exports.TRIANGLE = exports.SEND = exports.SEARCH = exports.ICON_NAMES = exports.CHEVRON_NEGATIVE = exports.CHEVRON = void 0;
6
+ exports.TRIANGLE_EQ = exports.TRIANGLE = exports.SEND = exports.SEARCH = exports.ICON_NAMES = exports.CHEVRON_NEGATIVE = exports.CHEVRON = exports.BULB = void 0;
7
7
  exports.getIcon = getIcon;
8
8
  var _version = _interopRequireDefault(require("../version.js"));
9
9
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -21,7 +21,8 @@ const ICON_NAME = {
21
21
  TRIANGLE: 'triangle',
22
22
  TRIANGLE_EQ: 'triangle-eq',
23
23
  CHEVRON: 'chevron',
24
- CHEVRON_NEGATIVE: 'chevron-negative'
24
+ CHEVRON_NEGATIVE: 'chevron-negative',
25
+ BULB: 'bulb'
25
26
  };
26
27
 
27
28
  // CC0 SVGs
@@ -33,7 +34,10 @@ const ICON_TRIANGLE = `<symbol id="${PREFIX}-${ICON_NAME.TRIANGLE}" viewBox="-5
33
34
  const ICON_TRIANGLE_EQ = `<symbol id="${PREFIX}-${ICON_NAME.TRIANGLE_EQ}" viewBox="-100 -100 200 200"><path d="M12.99 -77.5A15 15,0,0,0,-12.99 -77.5L-73.61 27.5A15 15,0,0,0,-60.62 50L60.62 50A15 15,0,0,0,73.61 27.5L12.99 -77.5Z"/></symbol>`;
34
35
  const ICON_CHEVRON = `<symbol id="${PREFIX}-${ICON_NAME.CHEVRON}" viewBox="-100 -100 200 200"><path d="M10.61 -43.94A15 15,0,0,0,-10.61 -43.94L-60.61 6.06A15 15,0,0,0,-39.39 27.27L0 -12.12L39.39 27.27A15 15,0,0,0,60.61 6.06L10.61 -43.94Z"/></symbol>`;
35
36
  const ICON_CHEVRON_NEGATIVE = `<symbol id="${PREFIX}-${ICON_NAME.CHEVRON_NEGATIVE}" viewBox="-100 -100 200 200"><path d="M100 100V-200H-200V200H200ZM-10.61 -43.94A15 15,0,0,1,10.61 -43.94L60.61 6.06A15 15,0,0,1,39.39 27.27L0 -12.12L-39.39 27.27A15 15,0,0,1,-60.61 6.06L-10.61 -43.94Z"/></symbol>`;
36
- const ICONS = [ICON_SEND, ICON_SEARCH, ICON_TRIANGLE, ICON_TRIANGLE_EQ, ICON_CHEVRON, ICON_CHEVRON_NEGATIVE];
37
+
38
+ // from Bootstrap Icons (MIT)
39
+ const ICON_BULB = `<symbol id="${PREFIX}-${ICON_NAME.BULB}" viewBox="0 0 16 16"><path d="M2 6a6 6 0 1 1 10.174 4.31c-.203.196-.359.4-.453.619l-.762 1.769A.5.5 0 0 1 10.5 13a.5.5 0 0 1 0 1 .5.5 0 0 1 0 1l-.224.447a1 1 0 0 1-.894.553H6.618a1 1 0 0 1-.894-.553L5.5 15a.5.5 0 0 1 0-1 .5.5 0 0 1 0-1 .5.5 0 0 1-.46-.302l-.761-1.77a2 2 0 0 0-.453-.618A5.98 5.98 0 0 1 2 6m6-5a5 5 0 0 0-3.479 8.592c.263.254.514.564.676.941L5.83 12h4.342l.632-1.467c.162-.377.413-.687.676-.941A5 5 0 0 0 8 1"/></symbol>`;
40
+ const ICONS = [ICON_SEND, ICON_SEARCH, ICON_TRIANGLE, ICON_TRIANGLE_EQ, ICON_CHEVRON, ICON_CHEVRON_NEGATIVE, ICON_BULB];
37
41
  const SPRITES_SVG = `<svg id="${ID}" style="display:none;">${ICONS.join('')}</svg>`;
38
42
  let loaded = false;
39
43
  function loadSvgSprites() {
@@ -56,4 +60,5 @@ const SEARCH = exports.SEARCH = _icon(ICON_NAME.SEARCH);
56
60
  const TRIANGLE = exports.TRIANGLE = _icon(ICON_NAME.TRIANGLE);
57
61
  const TRIANGLE_EQ = exports.TRIANGLE_EQ = _icon(ICON_NAME.TRIANGLE_EQ);
58
62
  const CHEVRON = exports.CHEVRON = _icon(ICON_NAME.CHEVRON);
59
- const CHEVRON_NEGATIVE = exports.CHEVRON_NEGATIVE = _icon(ICON_NAME.CHEVRON_NEGATIVE);
63
+ const CHEVRON_NEGATIVE = exports.CHEVRON_NEGATIVE = _icon(ICON_NAME.CHEVRON_NEGATIVE);
64
+ const BULB = exports.BULB = _icon(ICON_NAME.BULB);
@@ -25,6 +25,7 @@ const ROLE = exports.ROLE = Object.freeze({
25
25
  ITEMS: 'items',
26
26
  QUESTION: 'question',
27
27
  ANSWER: 'answer',
28
+ REASONING: 'reasoning',
28
29
  IMAGES: 'images',
29
30
  SOURCES: 'sources',
30
31
  RELATED_RESOURCES: 'related_resources',
@@ -38,7 +39,7 @@ const ROLE = exports.ROLE = Object.freeze({
38
39
  SORT: 'sort',
39
40
  ERROR: 'error'
40
41
  });
41
- const DATA_ROLE_SET = new Set([ROLE.PRODUCTS, ROLE.CATEGORIES, ROLE.ATTRIBUTES, ROLE.RESULTS, ROLE.ITEMS, ROLE.QUESTION, ROLE.ANSWER, ROLE.IMAGES, ROLE.SOURCES, ROLE.RELATED_RESOURCES, ROLE.QUERY_SUGGESTIONS, ROLE.RELATED_QUESTIONS, ROLE.AFFILIATION, ROLE.FACETS, ROLE.TOTAL]);
42
+ const DATA_ROLE_SET = new Set([ROLE.PRODUCTS, ROLE.CATEGORIES, ROLE.ATTRIBUTES, ROLE.RESULTS, ROLE.ITEMS, ROLE.QUESTION, ROLE.ANSWER, ROLE.REASONING, ROLE.IMAGES, ROLE.SOURCES, ROLE.RELATED_RESOURCES, ROLE.QUERY_SUGGESTIONS, ROLE.RELATED_QUESTIONS, ROLE.AFFILIATION, ROLE.FACETS, ROLE.TOTAL]);
42
43
  function isDataRole(role) {
43
44
  return DATA_ROLE_SET.has(role);
44
45
  }
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.sources = exports.relatedResources = exports.question = exports.querySuggestions = void 0;
6
+ exports.thoughts = exports.sources = exports.relatedResources = exports.question = exports.querySuggestions = void 0;
7
7
  /**
8
8
  * The phrase displayed right before <miso-question>
9
9
  */
@@ -22,4 +22,5 @@ const querySuggestions = exports.querySuggestions = 'Related questions you can e
22
22
  /**
23
23
  * The phrase displayed right before <miso-related-resources>
24
24
  */
25
- const relatedResources = exports.relatedResources = 'Go beyond, and learn more about this topic';
25
+ const relatedResources = exports.relatedResources = 'Go beyond, and learn more about this topic';
26
+ const thoughts = exports.thoughts = 'Thoughts';
@@ -10,6 +10,7 @@ exports.sections = void 0;
10
10
  var _commons = require("@miso.ai/commons");
11
11
  var CONSTANTS = _interopRequireWildcard(require("./constants.js"));
12
12
  var DEFAULT_PHRASES = _interopRequireWildcard(require("./phrases.js"));
13
+ var _svgs = require("../../asset/svgs.js");
13
14
  var _templates = require("../common/templates.js");
14
15
  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); }
15
16
  class Sections extends _templates.Sections {
@@ -34,7 +35,28 @@ class Sections extends _templates.Sections {
34
35
  return container(options, {
35
36
  name: 'answer',
36
37
  visibleWhen: 'ready'
37
- }, [options.parentQuestionId ? '<hr>' : '', ...this.question(options), '<miso-answer></miso-answer>', '<miso-feedback></miso-feedback>']);
38
+ }, [options.parentQuestionId ? '<hr>' : '', ...this.question(options), this.reasoning(options), '<miso-answer></miso-answer>', '<miso-feedback></miso-feedback>']);
39
+ }
40
+ reasoning({
41
+ phrases,
42
+ reasoning: options = {}
43
+ } = {}) {
44
+ const {
45
+ element,
46
+ phraseText
47
+ } = this._helpers;
48
+ const classes = [];
49
+ options.hide !== false && classes.push('hidden');
50
+ options.expand && classes.push('expanded');
51
+ return element('miso-collapsible', {
52
+ classes,
53
+ 'data-role': 'reasoning-container'
54
+ }, [element('div', {
55
+ classes: ['miso-collapsible__header'],
56
+ 'data-role': 'toggle-expand'
57
+ }, [`<div class="miso-collapsible__icon">${options.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
+ classes: ['miso-collapsible__body']
59
+ }, ['<miso-reasoning></miso-reasoning>'])]);
38
60
  }
39
61
  sources(options) {
40
62
  const {
@@ -116,7 +116,7 @@ const GETTERS = {
116
116
  };
117
117
  const METHODS = {
118
118
  toggleOpen: ['toggle', CLASS_OPEN],
119
- open: ['open', CLASS_OPEN],
119
+ open: ['add', CLASS_OPEN],
120
120
  close: ['remove', CLASS_OPEN],
121
121
  toggleHidden: ['toggle', CLASS_SHOWN],
122
122
  show: ['add', CLASS_SHOWN],
@@ -3,12 +3,11 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- Object.defineProperty(exports, "MisoBannerElement", {
7
- enumerable: true,
8
- get: function () {
9
- return _misoBanner.default;
10
- }
11
- });
6
+ var _exportNames = {
7
+ containers: true,
8
+ roles: true,
9
+ combos: true
10
+ };
12
11
  exports.roles = exports.containers = exports.combos = void 0;
13
12
  var containers = _interopRequireWildcard(require("./container/index.js"));
14
13
  exports.containers = containers;
@@ -16,6 +15,16 @@ var roles = _interopRequireWildcard(require("./role/index.js"));
16
15
  exports.roles = roles;
17
16
  var combos = _interopRequireWildcard(require("./combo/index.js"));
18
17
  exports.combos = combos;
19
- var _misoBanner = _interopRequireDefault(require("./miso-banner.js"));
20
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
18
+ var _index4 = require("./util/index.js");
19
+ Object.keys(_index4).forEach(function (key) {
20
+ if (key === "default" || key === "__esModule") return;
21
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
22
+ if (key in exports && exports[key] === _index4[key]) return;
23
+ Object.defineProperty(exports, key, {
24
+ enumerable: true,
25
+ get: function () {
26
+ return _index4[key];
27
+ }
28
+ });
29
+ });
21
30
  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); }
@@ -75,6 +75,12 @@ Object.defineProperty(exports, "MisoQuestionElement", {
75
75
  return _misoQuestion.default;
76
76
  }
77
77
  });
78
+ Object.defineProperty(exports, "MisoReasoningElement", {
79
+ enumerable: true,
80
+ get: function () {
81
+ return _misoReasoning.default;
82
+ }
83
+ });
78
84
  Object.defineProperty(exports, "MisoRelatedQuestionsElement", {
79
85
  enumerable: true,
80
86
  get: function () {
@@ -125,6 +131,7 @@ var _misoResults = _interopRequireDefault(require("./miso-results.js"));
125
131
  var _misoProducts = _interopRequireDefault(require("./miso-products.js"));
126
132
  var _misoQuestion = _interopRequireDefault(require("./miso-question.js"));
127
133
  var _misoAnswer = _interopRequireDefault(require("./miso-answer.js"));
134
+ var _misoReasoning = _interopRequireDefault(require("./miso-reasoning.js"));
128
135
  var _misoSources = _interopRequireDefault(require("./miso-sources.js"));
129
136
  var _misoImages = _interopRequireDefault(require("./miso-images.js"));
130
137
  var _misoRelatedResources = _interopRequireDefault(require("./miso-related-resources.js"));
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _misoComponent = _interopRequireDefault(require("./miso-component.js"));
8
+ var _constants = require("../../constants.js");
9
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
+ class MisoReasoningElement extends _misoComponent.default {
11
+ constructor() {
12
+ super({
13
+ role: _constants.ROLE.REASONING
14
+ });
15
+ }
16
+ static get tagName() {
17
+ return 'miso-reasoning';
18
+ }
19
+ }
20
+ exports.default = MisoReasoningElement;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "MisoBannerElement", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _misoBanner.default;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "MisoCollapsibleElement", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _misoCollapsible.default;
16
+ }
17
+ });
18
+ var _misoBanner = _interopRequireDefault(require("./miso-banner.js"));
19
+ var _misoCollapsible = _interopRequireDefault(require("./miso-collapsible.js"));
20
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _misoUtility = _interopRequireDefault(require("./miso-utility.js"));
8
+ var _utils = require("../utils.js");
9
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
+ const TAG_NAME = 'miso-collapsible';
11
+ const STATUS_EXPANDED = 'expanded';
12
+ const STATUS_HIDDEN = 'hidden';
13
+ const ACTIONS = {
14
+ expand: ['add', STATUS_EXPANDED],
15
+ collapse: ['remove', STATUS_EXPANDED],
16
+ hide: ['add', STATUS_HIDDEN],
17
+ show: ['remove', STATUS_HIDDEN]
18
+ };
19
+ const CLICKABLES = [{
20
+ role: 'expand',
21
+ action: 'expand'
22
+ }, {
23
+ role: 'collapse',
24
+ action: 'collapse'
25
+ }, {
26
+ role: 'toggle-expand',
27
+ action: 'toggleExpand'
28
+ }];
29
+ class MisoCollapsibleElement extends _misoUtility.default {
30
+ static get tagName() {
31
+ return TAG_NAME;
32
+ }
33
+ constructor() {
34
+ super({
35
+ actions: Object.keys(ACTIONS),
36
+ clickables: CLICKABLES
37
+ });
38
+ }
39
+
40
+ // lifecycle //
41
+ toggleExpand() {
42
+ this.expanded ? this.collapse() : this.expand();
43
+ }
44
+ }
45
+ exports.default = MisoCollapsibleElement;
46
+ (0, _utils.defineStatusGetters)(MisoCollapsibleElement.prototype, [STATUS_EXPANDED, STATUS_HIDDEN]);
47
+ for (const [method, [action, status]] of Object.entries(ACTIONS)) {
48
+ MisoCollapsibleElement.prototype[method] = function () {
49
+ this.classList[action](status);
50
+ this[`_${method}`] && this[`_${method}`]();
51
+ };
52
+ }
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ class MisoUtilityElement extends HTMLElement {
8
+ constructor({
9
+ actions = [],
10
+ clickables = []
11
+ } = {}) {
12
+ super();
13
+ this._actions = actions;
14
+ this._clickables = clickables;
15
+ this._unsubscribes = [];
16
+ }
17
+
18
+ // lifecycle //
19
+ async connectedCallback() {
20
+ const handleAction = event => this._handleAction(event);
21
+ const handleClick = event => this._handleClick(event);
22
+ this.addEventListener('miso:action', handleAction);
23
+ this.addEventListener('click', handleClick);
24
+ this._unsubscribes = [...this._unsubscribes, () => this.removeEventListener('miso:action', handleAction), () => this.removeEventListener('click', handleClick)];
25
+ }
26
+ disconnectedCallback() {
27
+ for (const unsubscribe of this._unsubscribes) {
28
+ unsubscribe();
29
+ }
30
+ this._unsubscribes = [];
31
+ }
32
+ _handleAction(event) {
33
+ const {
34
+ target,
35
+ name
36
+ } = event.detail || {};
37
+ if (!name || !target || !this.matches(target)) {
38
+ return;
39
+ }
40
+ if (!this._actions.includes(name)) {
41
+ return;
42
+ }
43
+ if (this._doAction({
44
+ name
45
+ })) {
46
+ event.stopPropagation();
47
+ }
48
+ }
49
+ _doAction(args) {
50
+ const {
51
+ name
52
+ } = args;
53
+ this[name](args);
54
+ return true;
55
+ }
56
+ _handleClick(event) {
57
+ const {
58
+ target,
59
+ button
60
+ } = event;
61
+ if (button !== 0) {
62
+ return; // only left click
63
+ }
64
+ for (let {
65
+ role,
66
+ selector,
67
+ action
68
+ } of this._clickables) {
69
+ selector = selector || `[data-role="${role}"]`;
70
+ if (!selector) {
71
+ continue;
72
+ }
73
+ if (target.closest(selector)) {
74
+ this._doAction({
75
+ name: action
76
+ });
77
+ event.stopPropagation();
78
+ return;
79
+ }
80
+ }
81
+ }
82
+ }
83
+ exports.default = MisoUtilityElement;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.triggerMisoAction = triggerMisoAction;
7
+ function triggerMisoAction(element, data) {
8
+ element.dispatchEvent(new CustomEvent('miso:action', {
9
+ bubbles: true,
10
+ detail: data
11
+ }));
12
+ }
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.applyCoerce = applyCoerce;
7
+ exports.defineStatusGetters = defineStatusGetters;
7
8
  exports.getClient = getClient;
8
9
  exports.getContainer = getContainer;
9
10
  exports.getMisoClient = getMisoClient;
@@ -84,4 +85,13 @@ function coerceDefault(str) {
84
85
  return num;
85
86
  }
86
87
  return str;
88
+ }
89
+ function defineStatusGetters(prototype, statuses) {
90
+ for (const status of statuses) {
91
+ Object.defineProperty(prototype, status, {
92
+ get() {
93
+ return this.classList.contains(status);
94
+ }
95
+ });
96
+ }
87
97
  }
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  var _constants = require("../../constants.js");
8
8
  var _raf = _interopRequireDefault(require("../raf.js"));
9
- var _misoBanner = _interopRequireDefault(require("../../element/miso-banner.js"));
9
+ var _misoBanner = _interopRequireDefault(require("../../element/util/miso-banner.js"));
10
10
  var _viewables = _interopRequireDefault(require("../../util/viewables.js"));
11
11
  const _excluded = ["logo"];
12
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -119,17 +119,18 @@ class TypewriterLayout extends _progressive.default {
119
119
  }) {
120
120
  const prev = this._prevState;
121
121
  const {
122
- value = '',
123
- meta,
122
+ value: {
123
+ value = '',
124
+ stage,
125
+ finished
126
+ } = {},
124
127
  session,
125
- status,
126
- ongoing
128
+ status
127
129
  } = state;
128
- const stage = meta && meta.answer_stage || 'result';
129
130
  const sameSession = (0, _utils.fromSameSession)(prev, state);
130
131
  const sameStreak = sameSession && stage === prev.stage;
131
132
  const streak = !prev ? 0 : sameStreak ? prev.streak : prev.streak + 1;
132
- const doneAt = sameSession && prev && prev.doneAt || (status === _constants.STATUS.READY && !ongoing ? Date.now() : undefined);
133
+ const doneAt = sameSession && prev && prev.doneAt || (status === _constants.STATUS.READY && finished ? Date.now() : undefined);
133
134
  const done = doneAt !== undefined;
134
135
  return this._prevState = Object.freeze((0, _commons.trimObj)({
135
136
  session,
@@ -4,4 +4,4 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _default = exports.default = '1.12.0';
7
+ var _default = exports.default = '1.12.1-beta.1';
@@ -81,7 +81,11 @@ const DEFAULT_OPTIONS = Object.freeze(Object.assign({}, _base.default.DEFAULT_OP
81
81
  }));
82
82
  const ROLES_OPTIONS = (0, _index4.mergeRolesOptions)(_base.default.ROLES_OPTIONS, {
83
83
  main: _constants.ROLE.ANSWER,
84
- members: Object.keys(DEFAULT_LAYOUTS)
84
+ members: Object.keys(DEFAULT_LAYOUTS),
85
+ mappings: {
86
+ [_constants.ROLE.ANSWER]: _processors.mappingAnswerData,
87
+ [_constants.ROLE.REASONING]: _processors.mappingReasoningData
88
+ }
85
89
  });
86
90
  class AnswerBasedWorkflow extends _base.default {
87
91
  // constructor //
@@ -26,6 +26,7 @@ const DEFAULT_LAYOUTS = Object.freeze(Object.assign({}, _answerBased.default.DEF
26
26
  buttonIcon: 'send'
27
27
  }
28
28
  }],
29
+ [_constants.ROLE.REASONING]: _index2.TypewriterLayout.type,
29
30
  [_constants.ROLE.RELATED_RESOURCES]: [_index2.ListLayout.type, {
30
31
  incremental: true,
31
32
  itemType: 'article'
@@ -149,6 +150,30 @@ class Ask extends _answerBased.default {
149
150
  return payload;
150
151
  }
151
152
 
153
+ // data //
154
+ _updateData(data) {
155
+ super._updateData(data);
156
+ this._triggerReasoningShowIfNecessary(data);
157
+ }
158
+ _triggerReasoningShowIfNecessary({
159
+ session,
160
+ value
161
+ } = {}) {
162
+ if (!value || !value.reasoning) {
163
+ return;
164
+ }
165
+ const context = this._getSessionContext(session);
166
+ if (context.reasoningShown) {
167
+ return;
168
+ }
169
+ context.reasoningShown = true;
170
+ const view = this._views.get(_constants.ROLE.REASONING);
171
+ view && view.triggerAction({
172
+ name: 'show',
173
+ target: '[data-role="reasoning-container"]'
174
+ });
175
+ }
176
+
152
177
  // interactions //
153
178
  _writeAskPropertiesToInteraction(payload, args) {
154
179
  const root_question_id = this.rootQuestionId;
@@ -6,6 +6,8 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.buildBaseInteraction = buildBaseInteraction;
7
7
  exports.concatItemsFromMoreResponse = concatItemsFromMoreResponse;
8
8
  exports.getRevision = getRevision;
9
+ exports.mappingAnswerData = mappingAnswerData;
10
+ exports.mappingReasoningData = mappingReasoningData;
9
11
  exports.mappingSortData = mappingSortData;
10
12
  exports.mergeInteraction = mergeInteraction;
11
13
  exports.retainFacetCountsInData = retainFacetCountsInData;
@@ -49,6 +51,35 @@ function mappingSortData(_, {
49
51
  });
50
52
  });
51
53
  }
54
+ function mappingAnswerData(data) {
55
+ if (!data || !data.value) {
56
+ return data;
57
+ }
58
+ const {
59
+ answer = '',
60
+ answer_stage,
61
+ finished
62
+ } = data.value;
63
+ return Object.freeze({
64
+ value: answer,
65
+ stage: answer_stage,
66
+ finished: !!finished
67
+ });
68
+ }
69
+ function mappingReasoningData(data) {
70
+ if (!data || !data.value) {
71
+ return data;
72
+ }
73
+ const {
74
+ reasoning = '',
75
+ reasoning_finished
76
+ } = data.value;
77
+ return Object.freeze({
78
+ value: reasoning,
79
+ stage: 'reasoning',
80
+ finished: !!reasoning_finished
81
+ });
82
+ }
52
83
  function findDefaultSortOption(options) {
53
84
  for (const option of options) {
54
85
  if (option.default) {
package/package.json CHANGED
@@ -26,7 +26,7 @@
26
26
  "url": "https://github.com/MisoAI/miso-client-js-sdk/issues"
27
27
  },
28
28
  "dependencies": {
29
- "@miso.ai/commons": "1.12.0"
29
+ "@miso.ai/commons": "1.12.1-beta.1"
30
30
  },
31
- "version": "1.12.0"
31
+ "version": "1.12.1-beta.1"
32
32
  }
package/src/actor/view.js CHANGED
@@ -3,6 +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
7
 
7
8
  function statesEqual(a, b) {
8
9
  return a === b || (a && b &&
@@ -159,6 +160,14 @@ export default class ViewActor {
159
160
  this.hub.update(fields.view(role), state, { silent });
160
161
  }
161
162
 
163
+ triggerAction(data) {
164
+ const { element } = this;
165
+ if (!element) {
166
+ return;
167
+ }
168
+ triggerMisoAction(element, data);
169
+ }
170
+
162
171
  _sliceData(data) {
163
172
  const { value, error, status, meta, ...rest } = data;
164
173
  const sliced = {
package/src/asset/svgs.js CHANGED
@@ -17,6 +17,7 @@ const ICON_NAME = {
17
17
  TRIANGLE_EQ: 'triangle-eq',
18
18
  CHEVRON: 'chevron',
19
19
  CHEVRON_NEGATIVE: 'chevron-negative',
20
+ BULB: 'bulb',
20
21
  };
21
22
 
22
23
  // CC0 SVGs
@@ -25,14 +26,14 @@ const ICON_SEARCH = `<symbol id="${PREFIX}-${ICON_NAME.SEARCH}" viewBox="0 0 24
25
26
 
26
27
  // Custom SVGs
27
28
  const ICON_TRIANGLE = `<symbol id="${PREFIX}-${ICON_NAME.TRIANGLE}" viewBox="-5 -5 105 105"><path d="${trianglePath(5)}"/></symbol>`;
28
-
29
29
  const ICON_TRIANGLE_EQ = `<symbol id="${PREFIX}-${ICON_NAME.TRIANGLE_EQ}" viewBox="-100 -100 200 200"><path d="M12.99 -77.5A15 15,0,0,0,-12.99 -77.5L-73.61 27.5A15 15,0,0,0,-60.62 50L60.62 50A15 15,0,0,0,73.61 27.5L12.99 -77.5Z"/></symbol>`;
30
-
31
30
  const ICON_CHEVRON = `<symbol id="${PREFIX}-${ICON_NAME.CHEVRON}" viewBox="-100 -100 200 200"><path d="M10.61 -43.94A15 15,0,0,0,-10.61 -43.94L-60.61 6.06A15 15,0,0,0,-39.39 27.27L0 -12.12L39.39 27.27A15 15,0,0,0,60.61 6.06L10.61 -43.94Z"/></symbol>`;
32
-
33
31
  const ICON_CHEVRON_NEGATIVE = `<symbol id="${PREFIX}-${ICON_NAME.CHEVRON_NEGATIVE}" viewBox="-100 -100 200 200"><path d="M100 100V-200H-200V200H200ZM-10.61 -43.94A15 15,0,0,1,10.61 -43.94L60.61 6.06A15 15,0,0,1,39.39 27.27L0 -12.12L-39.39 27.27A15 15,0,0,1,-60.61 6.06L-10.61 -43.94Z"/></symbol>`;
34
32
 
35
- const ICONS = [ICON_SEND, ICON_SEARCH, ICON_TRIANGLE, ICON_TRIANGLE_EQ, ICON_CHEVRON, ICON_CHEVRON_NEGATIVE];
33
+ // from Bootstrap Icons (MIT)
34
+ const ICON_BULB = `<symbol id="${PREFIX}-${ICON_NAME.BULB}" viewBox="0 0 16 16"><path d="M2 6a6 6 0 1 1 10.174 4.31c-.203.196-.359.4-.453.619l-.762 1.769A.5.5 0 0 1 10.5 13a.5.5 0 0 1 0 1 .5.5 0 0 1 0 1l-.224.447a1 1 0 0 1-.894.553H6.618a1 1 0 0 1-.894-.553L5.5 15a.5.5 0 0 1 0-1 .5.5 0 0 1 0-1 .5.5 0 0 1-.46-.302l-.761-1.77a2 2 0 0 0-.453-.618A5.98 5.98 0 0 1 2 6m6-5a5 5 0 0 0-3.479 8.592c.263.254.514.564.676.941L5.83 12h4.342l.632-1.467c.162-.377.413-.687.676-.941A5 5 0 0 0 8 1"/></symbol>`;
35
+
36
+ const ICONS = [ICON_SEND, ICON_SEARCH, ICON_TRIANGLE, ICON_TRIANGLE_EQ, ICON_CHEVRON, ICON_CHEVRON_NEGATIVE, ICON_BULB];
36
37
 
37
38
  const SPRITES_SVG = `<svg id="${ID}" style="display:none;">${ICONS.join('')}</svg>`;
38
39
 
@@ -64,3 +65,4 @@ export const TRIANGLE = _icon(ICON_NAME.TRIANGLE);
64
65
  export const TRIANGLE_EQ = _icon(ICON_NAME.TRIANGLE_EQ);
65
66
  export const CHEVRON = _icon(ICON_NAME.CHEVRON);
66
67
  export const CHEVRON_NEGATIVE = _icon(ICON_NAME.CHEVRON_NEGATIVE);
68
+ export const BULB = _icon(ICON_NAME.BULB);
package/src/constants.js CHANGED
@@ -15,6 +15,7 @@ export const ROLE = Object.freeze({
15
15
  ITEMS: 'items',
16
16
  QUESTION: 'question',
17
17
  ANSWER: 'answer',
18
+ REASONING: 'reasoning',
18
19
  IMAGES: 'images',
19
20
  SOURCES: 'sources',
20
21
  RELATED_RESOURCES: 'related_resources',
@@ -37,6 +38,7 @@ const DATA_ROLE_SET = new Set([
37
38
  ROLE.ITEMS,
38
39
  ROLE.QUESTION,
39
40
  ROLE.ANSWER,
41
+ ROLE.REASONING,
40
42
  ROLE.IMAGES,
41
43
  ROLE.SOURCES,
42
44
  ROLE.RELATED_RESOURCES,
@@ -17,3 +17,5 @@ export const querySuggestions = 'Related questions you can explore';
17
17
  * The phrase displayed right before <miso-related-resources>
18
18
  */
19
19
  export const relatedResources = 'Go beyond, and learn more about this topic';
20
+
21
+ export const thoughts = 'Thoughts';
@@ -1,6 +1,7 @@
1
1
  import { externalize } from '@miso.ai/commons';
2
2
  import * as CONSTANTS from './constants.js';
3
3
  import * as DEFAULT_PHRASES from './phrases.js';
4
+ import { CHEVRON, BULB } from '../../asset/svgs.js';
4
5
  import { Helpers, Sections as _Sections } from '../common/templates.js';
5
6
 
6
7
  class Sections extends _Sections {
@@ -22,11 +23,37 @@ class Sections extends _Sections {
22
23
  return container(options, { name: 'answer', visibleWhen: 'ready' }, [
23
24
  options.parentQuestionId ? '<hr>' : '',
24
25
  ...this.question(options),
26
+ this.reasoning(options),
25
27
  '<miso-answer></miso-answer>',
26
28
  '<miso-feedback></miso-feedback>',
27
29
  ]);
28
30
  }
29
31
 
32
+ reasoning({ phrases, reasoning: options = {} } = {}) {
33
+ const { element, phraseText } = this._helpers;
34
+ const classes = [];
35
+ options.hide !== false && classes.push('hidden');
36
+ options.expand && classes.push('expanded');
37
+ return element('miso-collapsible', {
38
+ classes,
39
+ 'data-role': 'reasoning-container',
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'],
51
+ }, [
52
+ '<miso-reasoning></miso-reasoning>',
53
+ ]),
54
+ ]);
55
+ }
56
+
30
57
  sources(options) {
31
58
  const { container, phrase } = this._helpers;
32
59
  return container(options, { name: 'sources', visibleWhen: 'nonempty' }, [
@@ -111,7 +111,7 @@ const GETTERS = {
111
111
 
112
112
  const METHODS = {
113
113
  toggleOpen: ['toggle', CLASS_OPEN],
114
- open: ['open', CLASS_OPEN],
114
+ open: ['add', CLASS_OPEN],
115
115
  close: ['remove', CLASS_OPEN],
116
116
  toggleHidden: ['toggle', CLASS_SHOWN],
117
117
  show: ['add', CLASS_SHOWN],
@@ -4,4 +4,4 @@ import * as combos from './combo/index.js';
4
4
 
5
5
  export { containers, roles, combos };
6
6
 
7
- export { default as MisoBannerElement } from './miso-banner.js';
7
+ export * from './util/index.js';
@@ -6,6 +6,7 @@ export { default as MisoResultsElement } from './miso-results.js';
6
6
  export { default as MisoProductsElement } from './miso-products.js';
7
7
  export { default as MisoQuestionElement } from './miso-question.js';
8
8
  export { default as MisoAnswerElement } from './miso-answer.js';
9
+ export { default as MisoReasoningElement } from './miso-reasoning.js';
9
10
  export { default as MisoSourcesElement } from './miso-sources.js';
10
11
  export { default as MisoImagesElement } from './miso-images.js';
11
12
  export { default as MisoRelatedResourcesElement } from './miso-related-resources.js';
@@ -0,0 +1,16 @@
1
+ import MisoComponentElement from './miso-component.js';
2
+ import { ROLE } from '../../constants.js';
3
+
4
+ export default class MisoReasoningElement extends MisoComponentElement {
5
+
6
+ constructor() {
7
+ super({
8
+ role: ROLE.REASONING,
9
+ });
10
+ }
11
+
12
+ static get tagName() {
13
+ return 'miso-reasoning';
14
+ }
15
+
16
+ }
@@ -0,0 +1,2 @@
1
+ export { default as MisoBannerElement } from './miso-banner.js';
2
+ export { default as MisoCollapsibleElement } from './miso-collapsible.js';
@@ -0,0 +1,49 @@
1
+ import MisoUtilityElement from './miso-utility.js';
2
+ import { defineStatusGetters } from '../utils.js';
3
+
4
+ const TAG_NAME = 'miso-collapsible';
5
+
6
+ const STATUS_EXPANDED = 'expanded';
7
+ const STATUS_HIDDEN = 'hidden';
8
+
9
+ const ACTIONS = {
10
+ expand: ['add', STATUS_EXPANDED],
11
+ collapse: ['remove', STATUS_EXPANDED],
12
+ hide: ['add', STATUS_HIDDEN],
13
+ show: ['remove', STATUS_HIDDEN],
14
+ };
15
+
16
+ const CLICKABLES = [
17
+ { role: 'expand', action: 'expand' },
18
+ { role: 'collapse', action: 'collapse' },
19
+ { role: 'toggle-expand', action: 'toggleExpand' },
20
+ ];
21
+
22
+ export default class MisoCollapsibleElement extends MisoUtilityElement {
23
+
24
+ static get tagName() {
25
+ return TAG_NAME;
26
+ }
27
+
28
+ constructor() {
29
+ super({
30
+ actions: Object.keys(ACTIONS),
31
+ clickables: CLICKABLES,
32
+ });
33
+ }
34
+
35
+ // lifecycle //
36
+ toggleExpand() {
37
+ this.expanded ? this.collapse() : this.expand();
38
+ }
39
+
40
+ }
41
+
42
+ defineStatusGetters(MisoCollapsibleElement.prototype, [STATUS_EXPANDED, STATUS_HIDDEN]);
43
+
44
+ for (const [method, [action, status]] of Object.entries(ACTIONS)) {
45
+ MisoCollapsibleElement.prototype[method] = function() {
46
+ this.classList[action](status);
47
+ this[`_${method}`] && this[`_${method}`]();
48
+ };
49
+ }
@@ -0,0 +1,69 @@
1
+ export default class MisoUtilityElement extends HTMLElement {
2
+
3
+ constructor({ actions = [], clickables = [] } = {}) {
4
+ super();
5
+ this._actions = actions;
6
+ this._clickables = clickables;
7
+ this._unsubscribes = [];
8
+ }
9
+
10
+ // lifecycle //
11
+ async connectedCallback() {
12
+ const handleAction = event => this._handleAction(event);
13
+ const handleClick = event => this._handleClick(event);
14
+
15
+ this.addEventListener('miso:action', handleAction);
16
+ this.addEventListener('click', handleClick);
17
+
18
+ this._unsubscribes = [
19
+ ...this._unsubscribes,
20
+ () => this.removeEventListener('miso:action', handleAction),
21
+ () => this.removeEventListener('click', handleClick),
22
+ ];
23
+ }
24
+
25
+ disconnectedCallback() {
26
+ for (const unsubscribe of this._unsubscribes) {
27
+ unsubscribe();
28
+ }
29
+ this._unsubscribes = [];
30
+ }
31
+
32
+ _handleAction(event) {
33
+ const { target, name } = event.detail || {};
34
+ if (!name || !target || !this.matches(target)) {
35
+ return;
36
+ }
37
+ if (!this._actions.includes(name)) {
38
+ return;
39
+ }
40
+ if (this._doAction({ name })) {
41
+ event.stopPropagation();
42
+ }
43
+ }
44
+
45
+ _doAction(args) {
46
+ const { name } = args;
47
+ this[name](args);
48
+ return true;
49
+ }
50
+
51
+ _handleClick(event) {
52
+ const { target, button } = event;
53
+ if (button !== 0) {
54
+ return; // only left click
55
+ }
56
+ for (let { role, selector, action } of this._clickables) {
57
+ selector = selector || `[data-role="${role}"]`;
58
+ if (!selector) {
59
+ continue;
60
+ }
61
+ if (target.closest(selector)) {
62
+ this._doAction({ name: action });
63
+ event.stopPropagation();
64
+ return;
65
+ }
66
+ }
67
+ }
68
+
69
+ }
@@ -0,0 +1,3 @@
1
+ export function triggerMisoAction(element, data) {
2
+ element.dispatchEvent(new CustomEvent('miso:action', { bubbles: true, detail: data }));
3
+ }
@@ -83,3 +83,13 @@ function coerceDefault(str) {
83
83
  }
84
84
  return str;
85
85
  }
86
+
87
+ export function defineStatusGetters(prototype, statuses) {
88
+ for (const status of statuses) {
89
+ Object.defineProperty(prototype, status, {
90
+ get() {
91
+ return this.classList.contains(status);
92
+ },
93
+ });
94
+ }
95
+ }
@@ -1,6 +1,6 @@
1
1
  import { ROLE, STATUS } from '../../constants.js';
2
2
  import RafLayout from '../raf.js';
3
- import MisoBannerElement from '../../element/miso-banner.js';
3
+ import MisoBannerElement from '../../element/util/miso-banner.js';
4
4
  import Viewables from '../../util/viewables.js';
5
5
 
6
6
  const TYPE = 'container';
@@ -107,13 +107,12 @@ export default class TypewriterLayout extends ProgressiveLayout {
107
107
 
108
108
  _preprocess({ state }) {
109
109
  const prev = this._prevState;
110
- const { value = '', meta, session, status, ongoing } = state;
111
- const stage = meta && meta.answer_stage || 'result';
110
+ const { value: { value = '', stage, finished } = {}, session, status } = state;
112
111
  const sameSession = fromSameSession(prev, state);
113
112
  const sameStreak = sameSession && (stage === prev.stage);
114
113
  const streak = !prev ? 0 : sameStreak ? prev.streak : prev.streak + 1;
115
114
 
116
- const doneAt = (sameSession && prev && prev.doneAt) || (status === STATUS.READY && !ongoing ? Date.now() : undefined);
115
+ const doneAt = (sameSession && prev && prev.doneAt) || (status === STATUS.READY && finished ? Date.now() : undefined);
117
116
  const done = doneAt !== undefined;
118
117
 
119
118
  return this._prevState = Object.freeze(trimObj({
package/src/version.js CHANGED
@@ -1 +1 @@
1
- export default '1.12.0';
1
+ export default '1.12.1-beta.1';
@@ -5,7 +5,7 @@ import { ROLE, STATUS, ORGANIC_QUESTION_SOURCE } from '../constants.js';
5
5
  import { SearchBoxLayout, TextLayout, ListLayout, GalleryLayout, TypewriterLayout, FeedbackLayout, AffiliationLayout } from '../layout/index.js';
6
6
  import { processData as processAffiliationData } from '../affiliation/index.js';
7
7
  import { mergeRolesOptions, autoQuery as autoQueryFn, DEFAULT_AUTO_QUERY_PARAM, DEFAULT_TRACKER_OPTIONS } from './options/index.js';
8
- import { writeAnswerStageToMeta, writeEventTargetToInteraction, mergeInteraction } from './processors.js';
8
+ import { mappingAnswerData, mappingReasoningData, writeAnswerStageToMeta, writeEventTargetToInteraction, mergeInteraction } from './processors.js';
9
9
  import { enableUseLink } from './use-link.js';
10
10
  import { isTracked, markAsTracked } from '../util/trackers.js';
11
11
 
@@ -65,6 +65,10 @@ const DEFAULT_OPTIONS = Object.freeze({
65
65
  const ROLES_OPTIONS = mergeRolesOptions(Workflow.ROLES_OPTIONS, {
66
66
  main: ROLE.ANSWER,
67
67
  members: Object.keys(DEFAULT_LAYOUTS),
68
+ mappings: {
69
+ [ROLE.ANSWER]: mappingAnswerData,
70
+ [ROLE.REASONING]: mappingReasoningData,
71
+ },
68
72
  });
69
73
 
70
74
  export default class AnswerBasedWorkflow extends Workflow {
@@ -2,7 +2,7 @@ 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
4
  import { ROLE, ORGANIC_QUESTION_SOURCE } from '../constants.js';
5
- import { OptionListLayout, ListLayout, SearchBoxLayout } from '../layout/index.js';
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
8
 
@@ -18,6 +18,7 @@ const DEFAULT_API_OPTIONS = Object.freeze({
18
18
  const DEFAULT_LAYOUTS = Object.freeze({
19
19
  ...AnswerBasedWorkflow.DEFAULT_LAYOUTS,
20
20
  [ROLE.QUERY]: [SearchBoxLayout.type, { templates: { buttonIcon: 'send' } }],
21
+ [ROLE.REASONING]: TypewriterLayout.type,
21
22
  [ROLE.RELATED_RESOURCES]: [ListLayout.type, { incremental: true, itemType: 'article' }],
22
23
  [ROLE.QUERY_SUGGESTIONS]: OptionListLayout.type,
23
24
  });
@@ -130,6 +131,25 @@ export default class Ask extends AnswerBasedWorkflow {
130
131
  return payload;
131
132
  }
132
133
 
134
+ // data //
135
+ _updateData(data) {
136
+ super._updateData(data);
137
+ this._triggerReasoningShowIfNecessary(data);
138
+ }
139
+
140
+ _triggerReasoningShowIfNecessary({ session, value } = {}) {
141
+ if (!value || !value.reasoning) {
142
+ return;
143
+ }
144
+ const context = this._getSessionContext(session);
145
+ if (context.reasoningShown) {
146
+ return;
147
+ }
148
+ context.reasoningShown = true;
149
+ const view = this._views.get(ROLE.REASONING);
150
+ view && view.triggerAction({ name: 'show', target: '[data-role="reasoning-container"]' });
151
+ }
152
+
133
153
  // interactions //
134
154
  _writeAskPropertiesToInteraction(payload, args) {
135
155
  const root_question_id = this.rootQuestionId;
@@ -22,6 +22,22 @@ export function mappingSortData(_, { hub, workflowOptions = {} } = {}) {
22
22
  });
23
23
  }
24
24
 
25
+ export function mappingAnswerData(data) {
26
+ if (!data || !data.value) {
27
+ return data;
28
+ }
29
+ const { answer = '', answer_stage, finished } = data.value;
30
+ return Object.freeze({ value: answer, stage: answer_stage, finished: !!finished });
31
+ }
32
+
33
+ export function mappingReasoningData(data) {
34
+ if (!data || !data.value) {
35
+ return data;
36
+ }
37
+ const { reasoning = '', reasoning_finished } = data.value;
38
+ return Object.freeze({ value: reasoning, stage: 'reasoning', finished: !!reasoning_finished });
39
+ }
40
+
25
41
  function findDefaultSortOption(options) {
26
42
  for (const option of options) {
27
43
  if (option.default) {