@websolutespa/bom-llm 0.0.56 → 0.0.57

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @websolutespa/bom-llm
2
2
 
3
+ ## 0.0.57
4
+
5
+ ### Patch Changes
6
+
7
+ - Added: Action, LlmChunkAction, onAction handler
8
+
3
9
  ## 0.0.56
4
10
 
5
11
  ### Patch Changes
package/README.md CHANGED
@@ -131,6 +131,23 @@ decorateUrl method can be a promise.
131
131
  bomLlm(options);
132
132
  ```
133
133
 
134
+ ### Handling external actions
135
+
136
+ You can handle the click event of the generated cta action with the onAction handler.
137
+
138
+ ```js
139
+ const searchParams = new URLSearchParams(window.location.search);
140
+ const options = {
141
+ appKey: 'MY_APP_KEY',
142
+ apiKey: 'MY_API_KEY',
143
+ threadId: searchParams.get('llmThreadId'),
144
+ onAction: (item) => {
145
+ console.log('onAction', item.id, item.title);
146
+ },
147
+ };
148
+ bomLlm(options);
149
+ ```
150
+
134
151
  ### Supported types
135
152
 
136
153
  Currently available types are:
package/dist/index.d.ts CHANGED
@@ -4,6 +4,11 @@ type DeepPartial<T> = T extends object ? {
4
4
  type LlmItem = Record<string, any> & {
5
5
  type: string;
6
6
  };
7
+ type LlmAction = Record<string, any> & {
8
+ type: 'action' | 'actionItem';
9
+ id: string | number;
10
+ title: string;
11
+ };
7
12
  type LlmTheme = any;
8
13
  type IMedia = Record<string, unknown> & {
9
14
  abstract?: string;
@@ -86,6 +91,7 @@ type LlmMock = {
86
91
  };
87
92
  type LlmTest = undefined | boolean | DeepPartial<LlmMock>;
88
93
  type LlmDecorateUrl = (item: LlmItem) => (string | void) | Promise<string | void>;
94
+ type LlmOnAction = (item: LlmAction) => (void) | Promise<boolean | void>;
89
95
  type LlmViewOptions = {
90
96
  threadId?: string;
91
97
  preview?: boolean;
@@ -99,6 +105,7 @@ type LlmOptions = {
99
105
  apiKey: string;
100
106
  appKey: string;
101
107
  decorateUrl?: LlmDecorateUrl;
108
+ onAction?: LlmOnAction;
102
109
  test?: LlmTest;
103
110
  customTheme?: Partial<LlmTheme>;
104
111
  locale?: string;
@@ -934,7 +934,7 @@ llm-embed {
934
934
  .llm .llm__header-wrapper {
935
935
  display: flex;
936
936
  justify-content: space-between;
937
- padding: 0 var(--llm-size-5, 2.5rem);
937
+ padding: 0 min(var(--llm-size-5, 2.5rem), clamp(20px * var(--s, 1), 20px * var(--s, 1) + (var(--u, 1vw) * 100 - 375px) / 1545 * 90 * var(--s, 1), 110px * var(--s, 1)));
938
938
  align-items: center;
939
939
  height: 70px;
940
940
  z-index: 2;
@@ -1241,6 +1241,16 @@ llm-embed {
1241
1241
  .llm .llm__intro-blob > div {
1242
1242
  height: 100%;
1243
1243
  }
1244
+ .llm.-chat .llm__intro-blob {
1245
+ width: 50px;
1246
+ height: 50px;
1247
+ }
1248
+ @media (min-width: 1440px) {
1249
+ .llm.-chat .llm__intro-blob {
1250
+ width: 60px;
1251
+ height: 60px;
1252
+ }
1253
+ }
1244
1254
  @media (min-width: 1024px) {
1245
1255
  .llm .llm__intro-wrapper {
1246
1256
  justify-content: space-between;
@@ -1252,6 +1262,9 @@ llm-embed {
1252
1262
  gap: var(--llm-size-5, 2.5rem);
1253
1263
  color: var(--llm-color-title-foreground);
1254
1264
  }
1265
+ .llm.-chat .llm__intro-text {
1266
+ gap: var(--llm-size-3, 1.5rem);
1267
+ }
1255
1268
  .llm .llm__intro-hints {
1256
1269
  margin-top: var(--llm-size-5, 2.5rem);
1257
1270
  }
@@ -1260,6 +1273,9 @@ llm-embed {
1260
1273
  margin-top: 0;
1261
1274
  }
1262
1275
  }
1276
+ .llm.-chat .llm__intro-hints {
1277
+ margin-top: var(--llm-size-3, 1.5rem);
1278
+ }
1263
1279
  .llm .llm__customIntro {
1264
1280
  position: absolute;
1265
1281
  top: 0;
@@ -1286,7 +1302,7 @@ llm-embed {
1286
1302
  }
1287
1303
  }
1288
1304
  .llm .llm__hints .swiper-wrapper {
1289
- padding: 1px 0;
1305
+ padding: 4px 0;
1290
1306
  }
1291
1307
  .llm .llm__hints .swiper-slide {
1292
1308
  height: auto;
@@ -1357,6 +1373,7 @@ llm-embed {
1357
1373
  }
1358
1374
  .llm .llm__hint-title.column {
1359
1375
  flex-direction: column;
1376
+ width: 100%;
1360
1377
  }
1361
1378
  .llm .llm__hint-title i {
1362
1379
  flex-shrink: 0;
@@ -1369,6 +1386,7 @@ llm-embed {
1369
1386
  fill: currentColor;
1370
1387
  }
1371
1388
  .llm .llm__hint-body {
1389
+ width: 100%;
1372
1390
  line-height: 140%;
1373
1391
  }
1374
1392
 
@@ -2049,6 +2067,21 @@ llm-embed {
2049
2067
  border-radius: 12px;
2050
2068
  padding: var(--llm-size-3, 1.5rem) var(--llm-size-4, 2rem);
2051
2069
  }
2070
+ .llm.-chat .llm__message--user .llm__text {
2071
+ display: flex;
2072
+ flex-direction: column;
2073
+ }
2074
+ .llm.-chat .llm__message--user .llm__text .llm__text-body {
2075
+ align-self: flex-end;
2076
+ padding: 0.5em 0;
2077
+ padding: var(--llm-pill-padding, 8px);
2078
+ border: var(--llm-pill-border);
2079
+ border-radius: var(--llm-pill-border-radius);
2080
+ background: var(--llm-pill-background);
2081
+ color: var(--llm-pill-foreground);
2082
+ font-family: var(--llm-pill-font-family);
2083
+ text-align: right;
2084
+ }
2052
2085
  .llm .llm__message--assistant .llm__inner--text:first-child .llm__text .llm__text-body, .llm .llm__message--assistant .llm__inner--text:first-child .llm__text .llm__text-body > p, .llm .llm__message--assistant .llm__inner--text:first-child .llm__text .llm__text-body > h2,
2053
2086
  .llm .llm__message--assistant .llm__inner--string:first-child .llm__text .llm__text-body,
2054
2087
  .llm .llm__message--assistant .llm__inner--string:first-child .llm__text .llm__text-body > p,
@@ -4368,6 +4401,13 @@ llm-embed {
4368
4401
  transform: rotate(90deg);
4369
4402
  }
4370
4403
 
4404
+ .llm .llm__actions {
4405
+ display: flex;
4406
+ gap: var(--llm-size-4, 2rem);
4407
+ padding-top: var(--llm-size-2, 1rem);
4408
+ margin-top: auto;
4409
+ }
4410
+
4371
4411
  /**
4372
4412
  * Swiper 8.4.7
4373
4413
  * Most modern mobile touch slider and framework with hardware accelerated transitions
package/dist/umd/index.js CHANGED
@@ -18016,13 +18016,12 @@
18016
18016
  error: "#ff4848"
18017
18017
  };
18018
18018
  var border = "1px solid var(--llm-color-neutral-200)";
18019
- var main = {
18020
- background: "var(--llm-color-background)",
18021
- foreground: "var(--llm-color-foreground)"
18022
- };
18023
- var canvas = {
18024
- opacity: 0.8,
18025
- enabled: true
18019
+ var trigger$1 = {
18020
+ position: "bottom",
18021
+ size: "60px",
18022
+ background: "var(--llm-color-base-200)",
18023
+ foreground: "var(--llm-color-base-100)",
18024
+ boxShadow: "var(--llm-shadow-md)"
18026
18025
  };
18027
18026
  var chat = {
18028
18027
  top: "auto",
@@ -18034,12 +18033,13 @@
18034
18033
  borderRadius: "8px",
18035
18034
  boxShadow: "var(--llm-shadow-sm)"
18036
18035
  };
18037
- var trigger$1 = {
18038
- position: "bottom",
18039
- size: "60px",
18040
- background: "var(--llm-color-base-200)",
18041
- foreground: "var(--llm-color-base-100)",
18042
- boxShadow: "var(--llm-shadow-md)"
18036
+ var main = {
18037
+ background: "var(--llm-color-background)",
18038
+ foreground: "var(--llm-color-foreground)"
18039
+ };
18040
+ var canvas = {
18041
+ opacity: 0.8,
18042
+ enabled: true
18043
18043
  };
18044
18044
  var popup = {
18045
18045
  maxWidth: "210px",
@@ -18159,10 +18159,10 @@
18159
18159
  typography: typography,
18160
18160
  color: color,
18161
18161
  border: border,
18162
+ trigger: trigger$1,
18163
+ chat: chat,
18162
18164
  main: main,
18163
18165
  canvas: canvas,
18164
- chat: chat,
18165
- trigger: trigger$1,
18166
18166
  popup: popup,
18167
18167
  triggerCta: triggerCta,
18168
18168
  hint: hint,
@@ -19188,7 +19188,9 @@ ${Object.entries(vars).map(_ref2 => {
19188
19188
  return chunk.type === 'string';
19189
19189
  }
19190
19190
 
19191
- // cards
19191
+ // media
19192
+
19193
+ // actions
19192
19194
 
19193
19195
  // cards
19194
19196
 
@@ -19352,6 +19354,17 @@ ${Object.entries(vars).map(_ref2 => {
19352
19354
  // response = { ...response, ...rest };
19353
19355
  }
19354
19356
  break;
19357
+ case 'action':
19358
+ case 'actionItem':
19359
+ if (lastMessage && lastMessage.type === 'actionGroup') {
19360
+ lastMessage.items.push(x);
19361
+ } else {
19362
+ chunkItems.push({
19363
+ type: 'actionGroup',
19364
+ items: [x]
19365
+ });
19366
+ }
19367
+ break;
19355
19368
  case 'cardItem':
19356
19369
  if (lastMessage && lastMessage.type === 'cardGroup') {
19357
19370
  lastMessage.items.push(x);
@@ -22973,6 +22986,7 @@ ${Object.entries(vars).map(_ref2 => {
22973
22986
  apiKey,
22974
22987
  threadId,
22975
22988
  decorateUrl,
22989
+ onAction,
22976
22990
  endpoint,
22977
22991
  storage,
22978
22992
  test,
@@ -23303,10 +23317,16 @@ ${Object.entries(vars).map(_ref2 => {
23303
23317
  decorateUrl: async (item, defaultUrl) => {
23304
23318
  let url;
23305
23319
  if (typeof decorateUrl === 'function') {
23306
- url = await decorateUrl(item);
23320
+ url = (await decorateUrl(item)) || undefined;
23307
23321
  }
23308
23322
  return url || defaultUrl || '#';
23309
23323
  },
23324
+ onAction: async item => {
23325
+ if (typeof onAction === 'function') {
23326
+ return await onAction(item);
23327
+ }
23328
+ return;
23329
+ },
23310
23330
  clear: () => set(state => ({
23311
23331
  messages: []
23312
23332
  }))
@@ -30714,6 +30734,70 @@ void main(void) {
30714
30734
  });
30715
30735
  }
30716
30736
 
30737
+ const Cta = props => {
30738
+ const onClick = event => {
30739
+ if (typeof props.onClick === 'function') {
30740
+ props.onClick(event);
30741
+ }
30742
+ };
30743
+ const bg = props.type == 'button' || props.type == 'submit' ? /*#__PURE__*/jsxRuntimeExports.jsx(Canvas, {}) : '';
30744
+ const icon = props.icon || (props.type == 'text' ? /*#__PURE__*/jsxRuntimeExports.jsx(IconLlmArrowRight, {}) : '');
30745
+ const classNames = getClassNames('llm__cta', `llm__cta--${props.type}`, props.className);
30746
+ return props.url ? /*#__PURE__*/jsxRuntimeExports.jsxs("a", {
30747
+ className: classNames,
30748
+ href: props.url,
30749
+ target: props.target,
30750
+ children: [bg, /*#__PURE__*/jsxRuntimeExports.jsx("span", {
30751
+ children: props.label
30752
+ }), icon]
30753
+ }) : /*#__PURE__*/jsxRuntimeExports.jsxs("button", {
30754
+ className: classNames,
30755
+ onClick: onClick,
30756
+ type: props.type == 'button' || props.type == 'submit' ? props.type : undefined,
30757
+ children: [bg, /*#__PURE__*/jsxRuntimeExports.jsx("span", {
30758
+ children: props.label
30759
+ }), icon]
30760
+ });
30761
+ };
30762
+
30763
+ const Action = props => {
30764
+ const label = useLabel();
30765
+ const {
30766
+ onAction
30767
+ } = useLlm(state => state.actions);
30768
+ const {
30769
+ open
30770
+ } = useLlmView(state => state.actions);
30771
+ const dismissable = useLlmView(state => state.dismissable);
30772
+ const onAction_ = async event => {
30773
+ // console.log('Action.onAction', props.id);
30774
+ const shouldClose = await onAction(props);
30775
+ if (dismissable && shouldClose !== false) {
30776
+ open();
30777
+ }
30778
+ };
30779
+ const classNames = getClassNames('llm__action', {
30780
+ [`llm__action--${props.type}`]: !!props.type
30781
+ });
30782
+ return /*#__PURE__*/jsxRuntimeExports.jsx(Cta, {
30783
+ type: "button",
30784
+ className: classNames,
30785
+ label: props.title || label('llm.tellMeMore'),
30786
+ icon: /*#__PURE__*/jsxRuntimeExports.jsx(IconLlmArrowRight, {}),
30787
+ onClick: onAction_
30788
+ });
30789
+ };
30790
+
30791
+ const ActionGroup = props => {
30792
+ const classNames = getClassNames('llm__actions');
30793
+ return /*#__PURE__*/jsxRuntimeExports.jsx("div", {
30794
+ className: classNames,
30795
+ children: props.items.map((item, i) => /*#__PURE__*/jsxRuntimeExports.jsx(Action, {
30796
+ ...item
30797
+ }, i))
30798
+ });
30799
+ };
30800
+
30717
30801
  const Dialog = _ref => {
30718
30802
  let {
30719
30803
  children,
@@ -31131,32 +31215,6 @@ void main(void) {
31131
31215
  });
31132
31216
  };
31133
31217
 
31134
- const Cta = props => {
31135
- const onClick = event => {
31136
- if (typeof props.onClick === 'function') {
31137
- props.onClick(event);
31138
- }
31139
- };
31140
- const bg = props.type == 'button' || props.type == 'submit' ? /*#__PURE__*/jsxRuntimeExports.jsx(Canvas, {}) : '';
31141
- const icon = props.type == 'text' ? /*#__PURE__*/jsxRuntimeExports.jsx(IconLlmArrowRight, {}) : '';
31142
- const classNames = getClassNames('llm__cta', `llm__cta--${props.type}`);
31143
- return props.url ? /*#__PURE__*/jsxRuntimeExports.jsxs("a", {
31144
- className: classNames,
31145
- href: props.url,
31146
- target: props.target,
31147
- children: [bg, /*#__PURE__*/jsxRuntimeExports.jsx("span", {
31148
- children: props.label
31149
- }), icon]
31150
- }) : /*#__PURE__*/jsxRuntimeExports.jsxs("button", {
31151
- className: classNames,
31152
- onClick: onClick,
31153
- type: props.type == 'button' || props.type == 'submit' ? props.type : undefined,
31154
- children: [bg, /*#__PURE__*/jsxRuntimeExports.jsx("span", {
31155
- children: props.label
31156
- }), icon]
31157
- });
31158
- };
31159
-
31160
31218
  const Event = props => {
31161
31219
  const label = useLabel();
31162
31220
  const {
@@ -33679,6 +33737,19 @@ void main(void) {
33679
33737
  ...item
33680
33738
  });
33681
33739
  }
33740
+ case 'action':
33741
+ case 'actionItem':
33742
+ {
33743
+ return /*#__PURE__*/jsxRuntimeExports.jsx(Action, {
33744
+ ...item
33745
+ });
33746
+ }
33747
+ case 'actionGroup':
33748
+ {
33749
+ return /*#__PURE__*/jsxRuntimeExports.jsx(ActionGroup, {
33750
+ ...item
33751
+ });
33752
+ }
33682
33753
  case 'card':
33683
33754
  case 'cardItem':
33684
33755
  {