@websolutespa/llm-plugin-maxmeyer 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +159 -0
- package/dist/esm/__tests/example.test.js +9 -0
- package/dist/esm/__tests/example.test.js.map +1 -0
- package/dist/esm/blocks/Action/action.js +32 -0
- package/dist/esm/blocks/Action/action.js.map +1 -0
- package/dist/esm/blocks/Action/action.module.scss +5 -0
- package/dist/esm/blocks/ActionGroup/action-group.js +17 -0
- package/dist/esm/blocks/ActionGroup/action-group.js.map +1 -0
- package/dist/esm/blocks/ActionGroup/action-group.module.scss +8 -0
- package/dist/esm/blocks/AssistantMessage/assistant-message.js +18 -0
- package/dist/esm/blocks/AssistantMessage/assistant-message.js.map +1 -0
- package/dist/esm/blocks/CustomCard/custom-card.js +68 -0
- package/dist/esm/blocks/CustomCard/custom-card.js.map +1 -0
- package/dist/esm/blocks/CustomCard/custom-card.module.scss +64 -0
- package/dist/esm/blocks/CustomCardGroup/custom-card-group.js +65 -0
- package/dist/esm/blocks/CustomCardGroup/custom-card-group.js.map +1 -0
- package/dist/esm/blocks/CustomCardGroup/custom-card-group.module.scss +58 -0
- package/dist/esm/blocks/FormRecap/FormRecap.js +250 -0
- package/dist/esm/blocks/FormRecap/FormRecap.js.map +1 -0
- package/dist/esm/blocks/FormRecap/form-recap.module.scss +103 -0
- package/dist/esm/blocks/FormRecapError/FormRecapError.js +19 -0
- package/dist/esm/blocks/FormRecapError/FormRecapError.js.map +1 -0
- package/dist/esm/blocks/FormRecapError/form-recap-error.module.scss +7 -0
- package/dist/esm/blocks/FormRecapSuccess/FormRecapSuccess.js +19 -0
- package/dist/esm/blocks/FormRecapSuccess/FormRecapSuccess.js.map +1 -0
- package/dist/esm/blocks/FormRecapSuccess/form-recap-success.module.scss +7 -0
- package/dist/esm/blocks/FormRequest/FormRequest.js +36 -0
- package/dist/esm/blocks/FormRequest/FormRequest.js.map +1 -0
- package/dist/esm/blocks/FormRequest/form-request.module.scss +17 -0
- package/dist/esm/blocks/NotFound/not-found.js +15 -0
- package/dist/esm/blocks/NotFound/not-found.js.map +1 -0
- package/dist/esm/blocks/NotFound/not-found.module.scss +5 -0
- package/dist/esm/blocks/StreamError/StreamError.js +46 -0
- package/dist/esm/blocks/StreamError/StreamError.js.map +1 -0
- package/dist/esm/blocks/StreamError/_style.scss +34 -0
- package/dist/esm/blocks/UserMessage/user-message.js +22 -0
- package/dist/esm/blocks/UserMessage/user-message.js.map +1 -0
- package/dist/esm/blocks/UserMessage/user-message.module.scss +13 -0
- package/dist/esm/blocks/index.js +28 -0
- package/dist/esm/blocks/index.js.map +1 -0
- package/dist/esm/components/chat/Root/root.js +36 -0
- package/dist/esm/components/chat/Root/root.js.map +1 -0
- package/dist/esm/components/chat/Root/root.module.scss +58 -0
- package/dist/esm/components/chat/Thread/thread.js +40 -0
- package/dist/esm/components/chat/Thread/thread.js.map +1 -0
- package/dist/esm/components/chat/Thread/thread.module.scss +30 -0
- package/dist/esm/components/chat/index.js +8 -0
- package/dist/esm/components/chat/index.js.map +1 -0
- package/dist/esm/components/index.js +3 -0
- package/dist/esm/components/index.js.map +1 -0
- package/dist/esm/components/page/PageLoading/page-loading.js +32 -0
- package/dist/esm/components/page/PageLoading/page-loading.js.map +1 -0
- package/dist/esm/components/page/PageLoading/page-loading.module.scss +302 -0
- package/dist/esm/components/page/PageRoot/page-root.js +31 -0
- package/dist/esm/components/page/PageRoot/page-root.js.map +1 -0
- package/dist/esm/components/page/PageRoot/page-root.module.scss +24 -0
- package/dist/esm/components/page/PageStreamingIndicator/page-streaming-indicator.js +18 -0
- package/dist/esm/components/page/PageStreamingIndicator/page-streaming-indicator.js.map +1 -0
- package/dist/esm/components/page/PageStreamingIndicator/page-streaming-indicator.module.scss +38 -0
- package/dist/esm/components/page/PageTrigger/page-trigger.js +20 -0
- package/dist/esm/components/page/PageTrigger/page-trigger.js.map +1 -0
- package/dist/esm/components/page/PageTrigger/page-trigger.module.scss +16 -0
- package/dist/esm/components/page/index.js +12 -0
- package/dist/esm/components/page/index.js.map +1 -0
- package/dist/esm/global.d.js +2 -0
- package/dist/esm/global.d.js.map +1 -0
- package/dist/esm/index.js +12 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/llm.js +42 -0
- package/dist/esm/llm.js.map +1 -0
- package/dist/esm/mock/chat/app.js +76 -0
- package/dist/esm/mock/chat/app.js.map +1 -0
- package/dist/esm/mock/chat/theme.js +337 -0
- package/dist/esm/mock/chat/theme.js.map +1 -0
- package/dist/esm/mock/chat/thread.js +450 -0
- package/dist/esm/mock/chat/thread.js.map +1 -0
- package/dist/esm/mock/index.js +8 -0
- package/dist/esm/mock/index.js.map +1 -0
- package/dist/esm/mock/page/app.js +74 -0
- package/dist/esm/mock/page/app.js.map +1 -0
- package/dist/esm/mock/page/theme.js +337 -0
- package/dist/esm/mock/page/theme.js.map +1 -0
- package/dist/esm/mock/page/thread.js +756 -0
- package/dist/esm/mock/page/thread.js.map +1 -0
- package/dist/esm/plugin.js +21 -0
- package/dist/esm/plugin.js.map +1 -0
- package/dist/esm/scss/_base.scss +63 -0
- package/dist/esm/scss/_mixin.scss +10 -0
- package/dist/esm/scss/_reset.scss +63 -0
- package/dist/esm/scss/_thread.scss +35 -0
- package/dist/esm/scss/_typography.scss +19 -0
- package/dist/esm/scss/mixin/_breakpoint.scss +7 -0
- package/dist/esm/scss/mixin/_button.scss +64 -0
- package/dist/esm/scss/mixin/_container.scss +14 -0
- package/dist/esm/scss/mixin/_markdown.scss +180 -0
- package/dist/esm/scss/mixin/_scrollbar.scss +50 -0
- package/dist/esm/scss/mixin/_shadow.scss +19 -0
- package/dist/esm/scss/mixin/_size.scss +42 -0
- package/dist/esm/scss/mixin/_typography.scss +129 -0
- package/dist/esm/scss/mixin/_utils.scss +103 -0
- package/dist/esm/scss/mixin/_vars.scss +4 -0
- package/dist/esm/scss/style.scss +14 -0
- package/dist/index.css +5460 -0
- package/dist/index.css.map +1 -0
- package/dist/index.d.ts +78 -0
- package/dist/umd/index.js +48828 -0
- package/dist/umd/index.js.map +1 -0
- package/dist/umd/index.min.js +20 -0
- package/package.json +119 -0
package/CHANGELOG.md
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# @websolutespa/llm-plugin
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/js/%40websolutespa%2Fllm-plugin)
|
|
4
|
+
|
|
5
|
+
[](https://shields.io/)
|
|
6
|
+
|
|
7
|
+
LLM module of the [BOM Repository](https://github.com/websolutespa/bom) by [websolute](https://www.websolute.com/).
|
|
8
|
+
|
|
9
|
+
# Bom LLM Plugin
|
|
10
|
+
|
|
11
|
+
This plugin automatically adds UI components to manage LLM Chatbot by [websolute](https://www.websolute.com/).
|
|
12
|
+
|
|
13
|
+
### Requirements:
|
|
14
|
+
|
|
15
|
+
- You need a personal appKey and apiKey to use this plugin, for more info contact [websolute](https://www.websolute.com/contatti)
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
You can load the script directly via jsDelivr or installing via npm.
|
|
20
|
+
|
|
21
|
+
### Using jsDelivr
|
|
22
|
+
|
|
23
|
+
```html
|
|
24
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@websolutespa/llm-plugin@latest/dist/index.css">
|
|
25
|
+
<script type="module"
|
|
26
|
+
src="https://cdn.jsdelivr.net/npm/@websolutespa/llm-plugin@latest/dist/umd/index.min.js"></script>
|
|
27
|
+
<script type="module">
|
|
28
|
+
|
|
29
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
30
|
+
if ('llmDefault' in window) {
|
|
31
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
32
|
+
const options = {
|
|
33
|
+
endpoint: 'https://platform-ai-dev.ws-deploy-01.wslabs.it',
|
|
34
|
+
appKey: 'MY_APP_KEY',
|
|
35
|
+
apiKey: 'MY_API_KEY',
|
|
36
|
+
threadId: searchParams.get('llmThreadId'),
|
|
37
|
+
test: searchParams.get('mock') === 'true' ? llm.mock : undefined,
|
|
38
|
+
idleTime: 1000 * 60,
|
|
39
|
+
};
|
|
40
|
+
llmDefault(options);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
</script>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Using npm
|
|
48
|
+
|
|
49
|
+
Install library using npm.
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm i @websolutespa/llm-plugin --save
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Import css from node_modules.
|
|
56
|
+
|
|
57
|
+
```html
|
|
58
|
+
<link rel="stylesheet" href="node_modules/@websolutespa/llm-plugin/dist/umd/index.css">
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Import and consume plugin.
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
import { llmDefault } from '@websolutespa/llm-plugin';
|
|
65
|
+
|
|
66
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
67
|
+
if ('llmDefault' in window) {
|
|
68
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
69
|
+
const options = {
|
|
70
|
+
appKey: 'MY_APP_KEY',
|
|
71
|
+
apiKey: 'MY_API_KEY',
|
|
72
|
+
threadId: searchParams.get('llmThreadId'),
|
|
73
|
+
};
|
|
74
|
+
// returned instance
|
|
75
|
+
const llm = llmDefault(options);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Using imperatively.
|
|
81
|
+
|
|
82
|
+
```js
|
|
83
|
+
const options = {
|
|
84
|
+
appKey: 'MY_APP_KEY',
|
|
85
|
+
apiKey: 'MY_API_KEY',
|
|
86
|
+
imperative: true, // hide trigger button
|
|
87
|
+
};
|
|
88
|
+
const llm = llmDefault(options);
|
|
89
|
+
// using open command imperatively
|
|
90
|
+
setTimeout(() => {
|
|
91
|
+
llm.open();
|
|
92
|
+
}, 4000);
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Using embed tag.
|
|
96
|
+
|
|
97
|
+
```html
|
|
98
|
+
<llm-embed />
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Running test
|
|
102
|
+
|
|
103
|
+
Add parameter test = true.
|
|
104
|
+
|
|
105
|
+
```js
|
|
106
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
107
|
+
const options = {
|
|
108
|
+
appKey: 'MY_APP_KEY',
|
|
109
|
+
apiKey: 'MY_API_KEY',
|
|
110
|
+
threadId: searchParams.get('llmThreadId'),
|
|
111
|
+
test: true,
|
|
112
|
+
};
|
|
113
|
+
llmDefault(options);
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Decorate external url
|
|
117
|
+
|
|
118
|
+
You can decorate every json item from the knowledgeBase customizing its external url.
|
|
119
|
+
decorateUrl method can be a promise.
|
|
120
|
+
|
|
121
|
+
```js
|
|
122
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
123
|
+
const options = {
|
|
124
|
+
appKey: 'MY_APP_KEY',
|
|
125
|
+
apiKey: 'MY_API_KEY',
|
|
126
|
+
threadId: searchParams.get('llmThreadId'),
|
|
127
|
+
decorateUrl: (item) => {
|
|
128
|
+
switch (item.type) {
|
|
129
|
+
case 'event':
|
|
130
|
+
case 'eventItem':
|
|
131
|
+
return `https://acme.com/event?id=${item.id}`;
|
|
132
|
+
default:
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
llmDefault(options);
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Handling external actions
|
|
141
|
+
|
|
142
|
+
You can handle the click event of the generated cta action with the onAction handler.
|
|
143
|
+
|
|
144
|
+
```js
|
|
145
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
146
|
+
const options = {
|
|
147
|
+
appKey: 'MY_APP_KEY',
|
|
148
|
+
apiKey: 'MY_API_KEY',
|
|
149
|
+
threadId: searchParams.get('llmThreadId'),
|
|
150
|
+
onAction: (item) => {
|
|
151
|
+
console.log('onAction', item.id, item.title);
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
llmDefault(options);
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
##### *this library is for internal usage and not production ready*
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/__tests/example.test.ts"],"sourcesContent":["import '@testing-library/jest-dom';\n\ndescribe('Example', () => {\n it('passes', async () => {\n const value = 'test';\n expect(value).toEqual(value);\n });\n});\n"],"names":["describe","it","value","expect","toEqual"],"mappings":"AAAA,OAAO,4BAA4B;AAEnCA,SAAS,WAAW;IAClBC,GAAG,UAAU;QACX,MAAMC,QAAQ;QACdC,OAAOD,OAAOE,OAAO,CAACF;IACxB;AACF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { getClassNames } from '@websolutespa/bom-core';
|
|
3
|
+
import { useLabel } from '@websolutespa/bom-mixer-hooks';
|
|
4
|
+
import { IconLlmArrowRight } from '@websolutespa/bom-mixer-icons';
|
|
5
|
+
import { Cta, useLlm, useLlmView } from '@websolutespa/bom-mixer-llm';
|
|
6
|
+
import style from './action.module.scss';
|
|
7
|
+
export const Action = (props)=>{
|
|
8
|
+
const { item } = props;
|
|
9
|
+
const label = useLabel();
|
|
10
|
+
const { onAction } = useLlm((state)=>state.actions);
|
|
11
|
+
const { open } = useLlmView((state)=>state.actions);
|
|
12
|
+
const dismissable = useLlmView((state)=>state.dismissable);
|
|
13
|
+
const onAction_ = async (event)=>{
|
|
14
|
+
// console.log('Action.onAction', props.id);
|
|
15
|
+
const shouldClose = await onAction(item);
|
|
16
|
+
if (dismissable && shouldClose !== false) {
|
|
17
|
+
open();
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
const classNames = getClassNames(style.action, {
|
|
21
|
+
[`llm__action--${item.type}`]: !!item.type
|
|
22
|
+
});
|
|
23
|
+
return /*#__PURE__*/ _jsx(Cta, {
|
|
24
|
+
type: "button",
|
|
25
|
+
className: classNames,
|
|
26
|
+
label: item.title || label('llm.tellMeMore'),
|
|
27
|
+
icon: /*#__PURE__*/ _jsx(IconLlmArrowRight, {}),
|
|
28
|
+
onClick: onAction_
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=action.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/blocks/Action/action.tsx"],"sourcesContent":["import { getClassNames } from '@websolutespa/bom-core';\nimport { useLabel } from '@websolutespa/bom-mixer-hooks';\nimport { IconLlmArrowRight } from '@websolutespa/bom-mixer-icons';\nimport { Cta, LlmBlock, LlmChunkAction, LlmChunkActionItem, useLlm, useLlmView } from '@websolutespa/bom-mixer-llm';\nimport style from './action.module.scss';\n\nexport const Action: React.FC<LlmBlock<LlmChunkActionItem | LlmChunkAction>> = (props) => {\n const { item } = props;\n const label = useLabel();\n const { onAction } = useLlm(state => state.actions);\n const { open } = useLlmView(state => state.actions);\n const dismissable = useLlmView(state => state.dismissable);\n const onAction_ = async (event: React.MouseEvent) => {\n // console.log('Action.onAction', props.id);\n const shouldClose = await onAction(item);\n if (dismissable && shouldClose !== false) {\n open();\n }\n };\n const classNames = getClassNames(style.action, { [`llm__action--${item.type}`]: !!item.type });\n return (\n <Cta\n type=\"button\"\n className={classNames} label={item.title || label('llm.tellMeMore')}\n icon={<IconLlmArrowRight />}\n onClick={onAction_}\n />\n );\n};\n\n"],"names":["getClassNames","useLabel","IconLlmArrowRight","Cta","useLlm","useLlmView","style","Action","props","item","label","onAction","state","actions","open","dismissable","onAction_","event","shouldClose","classNames","action","type","className","title","icon","onClick"],"mappings":";AAAA,SAASA,aAAa,QAAQ,yBAAyB;AACvD,SAASC,QAAQ,QAAQ,gCAAgC;AACzD,SAASC,iBAAiB,QAAQ,gCAAgC;AAClE,SAASC,GAAG,EAAgDC,MAAM,EAAEC,UAAU,QAAQ,8BAA8B;AACpH,OAAOC,WAAW,uBAAuB;AAEzC,OAAO,MAAMC,SAAkE,CAACC;IAC9E,MAAM,EAAEC,IAAI,EAAE,GAAGD;IACjB,MAAME,QAAQT;IACd,MAAM,EAAEU,QAAQ,EAAE,GAAGP,OAAOQ,CAAAA,QAASA,MAAMC,OAAO;IAClD,MAAM,EAAEC,IAAI,EAAE,GAAGT,WAAWO,CAAAA,QAASA,MAAMC,OAAO;IAClD,MAAME,cAAcV,WAAWO,CAAAA,QAASA,MAAMG,WAAW;IACzD,MAAMC,YAAY,OAAOC;QACvB,4CAA4C;QAC5C,MAAMC,cAAc,MAAMP,SAASF;QACnC,IAAIM,eAAeG,gBAAgB,OAAO;YACxCJ;QACF;IACF;IACA,MAAMK,aAAanB,cAAcM,MAAMc,MAAM,EAAE;QAAE,CAAC,CAAC,aAAa,EAAEX,KAAKY,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAACZ,KAAKY,IAAI;IAAC;IAC5F,qBACE,KAAClB;QACCkB,MAAK;QACLC,WAAWH;QAAYT,OAAOD,KAAKc,KAAK,IAAIb,MAAM;QAClDc,oBAAM,KAACtB;QACPuB,SAAST;;AAGf,EAAE"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { getClassNames } from '@websolutespa/bom-core';
|
|
3
|
+
import { Action } from '../Action/action';
|
|
4
|
+
import style from './action-group.module.scss';
|
|
5
|
+
export const ActionGroup = (props)=>{
|
|
6
|
+
const { item } = props;
|
|
7
|
+
const classNames = getClassNames(style.actionGroup);
|
|
8
|
+
return /*#__PURE__*/ _jsx("div", {
|
|
9
|
+
className: classNames,
|
|
10
|
+
children: item.items.map((item, i)=>/*#__PURE__*/ _jsx(Action, {
|
|
11
|
+
...props,
|
|
12
|
+
item: item
|
|
13
|
+
}, i))
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=action-group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/blocks/ActionGroup/action-group.tsx"],"sourcesContent":["import { getClassNames } from '@websolutespa/bom-core';\nimport { LlmBlock, LlmChunkActionGroup } from '@websolutespa/bom-mixer-llm';\nimport { Action } from '../Action/action';\nimport style from './action-group.module.scss';\n\nexport const ActionGroup: React.FC<LlmBlock<LlmChunkActionGroup>> = (props) => {\n const { item } = props;\n const classNames = getClassNames(style.actionGroup);\n return (\n <div className={classNames}>\n {item.items.map((item, i) => (\n <Action key={i} {...props} item={item} />\n ))}\n </div>\n );\n};\n\n"],"names":["getClassNames","Action","style","ActionGroup","props","item","classNames","actionGroup","div","className","items","map","i"],"mappings":";AAAA,SAASA,aAAa,QAAQ,yBAAyB;AAEvD,SAASC,MAAM,QAAQ,mBAAmB;AAC1C,OAAOC,WAAW,6BAA6B;AAE/C,OAAO,MAAMC,cAAuD,CAACC;IACnE,MAAM,EAAEC,IAAI,EAAE,GAAGD;IACjB,MAAME,aAAaN,cAAcE,MAAMK,WAAW;IAClD,qBACE,KAACC;QAAIC,WAAWH;kBACbD,KAAKK,KAAK,CAACC,GAAG,CAAC,CAACN,MAAMO,kBACrB,KAACX;gBAAgB,GAAGG,KAAK;gBAAEC,MAAMA;eAApBO;;AAIrB,EAAE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Text } from '@websolutespa/bom-mixer-llm';
|
|
3
|
+
export const AssistantMessage = (props)=>{
|
|
4
|
+
const { text, chunkIndex, index } = props;
|
|
5
|
+
return /*#__PURE__*/ _jsx("div", {
|
|
6
|
+
className: "llm__row",
|
|
7
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
8
|
+
className: "llm__col --sm-10 --sm-9 --md-8 --lg-7 --xl-6",
|
|
9
|
+
children: /*#__PURE__*/ _jsx(Text, {
|
|
10
|
+
body: text,
|
|
11
|
+
chunkIndex: chunkIndex,
|
|
12
|
+
index: index
|
|
13
|
+
})
|
|
14
|
+
})
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=assistant-message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/blocks/AssistantMessage/assistant-message.tsx"],"sourcesContent":["import { LlmTextBlock, Text } from '@websolutespa/bom-mixer-llm';\n\nexport type AssistantMessageProps = LlmTextBlock<'assistant'>;\n\nexport const AssistantMessage: React.FC<AssistantMessageProps> = (props) => {\n const { text, chunkIndex, index } = props;\n return (\n <div className=\"llm__row\">\n <div className=\"llm__col --sm-10 --sm-9 --md-8 --lg-7 --xl-6\">\n <Text body={text} chunkIndex={chunkIndex} index={index} />\n </div>\n </div>\n );\n};\n\n"],"names":["Text","AssistantMessage","props","text","chunkIndex","index","div","className","body"],"mappings":";AAAA,SAAuBA,IAAI,QAAQ,8BAA8B;AAIjE,OAAO,MAAMC,mBAAoD,CAACC;IAChE,MAAM,EAAEC,IAAI,EAAEC,UAAU,EAAEC,KAAK,EAAE,GAAGH;IACpC,qBACE,KAACI;QAAIC,WAAU;kBACb,cAAA,KAACD;YAAIC,WAAU;sBACb,cAAA,KAACP;gBAAKQ,MAAML;gBAAMC,YAAYA;gBAAYC,OAAOA;;;;AAIzD,EAAE"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useLabel } from '@websolutespa/bom-mixer-hooks';
|
|
3
|
+
import { Cta, useLlmView } from '@websolutespa/bom-mixer-llm';
|
|
4
|
+
import style from './custom-card.module.scss';
|
|
5
|
+
export const CustomCard = (props)=>{
|
|
6
|
+
const { item } = props;
|
|
7
|
+
const label = useLabel();
|
|
8
|
+
const { send } = useLlmView((state)=>state.actions);
|
|
9
|
+
const onTellMeMore = async (event)=>{
|
|
10
|
+
const prompt = `${label('llm.tellMeMoreAbout')} ${item.title}`;
|
|
11
|
+
await send(prompt, (response)=>{
|
|
12
|
+
// console.log('Prompt.onChunk', response.chunks);
|
|
13
|
+
}, (response)=>{
|
|
14
|
+
// console.log('Prompt.onEnd', response);
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
const ariaLabel = label('llm.tellMeMore');
|
|
18
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
19
|
+
className: style.customCard,
|
|
20
|
+
children: [
|
|
21
|
+
item.media && /*#__PURE__*/ _jsx(_Fragment, {
|
|
22
|
+
children: item.href ? /*#__PURE__*/ _jsx("a", {
|
|
23
|
+
className: style.customCardMedia,
|
|
24
|
+
href: item.href,
|
|
25
|
+
target: "_blank",
|
|
26
|
+
rel: "noreferrer",
|
|
27
|
+
"aria-label": ariaLabel,
|
|
28
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
29
|
+
className: style.customCardAsset,
|
|
30
|
+
children: /*#__PURE__*/ _jsx("img", {
|
|
31
|
+
src: item.media.url,
|
|
32
|
+
alt: ""
|
|
33
|
+
})
|
|
34
|
+
})
|
|
35
|
+
}) : /*#__PURE__*/ _jsx("div", {
|
|
36
|
+
className: style.customCardMedia,
|
|
37
|
+
children: /*#__PURE__*/ _jsx("div", {
|
|
38
|
+
className: style.customCardAsset,
|
|
39
|
+
children: /*#__PURE__*/ _jsx("img", {
|
|
40
|
+
src: item.media.url,
|
|
41
|
+
alt: ""
|
|
42
|
+
})
|
|
43
|
+
})
|
|
44
|
+
})
|
|
45
|
+
}),
|
|
46
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
47
|
+
className: style.customCardContent,
|
|
48
|
+
children: [
|
|
49
|
+
item.title && /*#__PURE__*/ _jsx("div", {
|
|
50
|
+
className: style.customCardTitle,
|
|
51
|
+
dangerouslySetInnerHTML: {
|
|
52
|
+
__html: item.title
|
|
53
|
+
}
|
|
54
|
+
}),
|
|
55
|
+
/*#__PURE__*/ _jsx(Cta, {
|
|
56
|
+
url: item.href,
|
|
57
|
+
className: style.customCardCta,
|
|
58
|
+
type: "button",
|
|
59
|
+
label: label('llm.tellMeMore'),
|
|
60
|
+
onClick: onTellMeMore
|
|
61
|
+
})
|
|
62
|
+
]
|
|
63
|
+
})
|
|
64
|
+
]
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
//# sourceMappingURL=custom-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/blocks/CustomCard/custom-card.tsx"],"sourcesContent":["import { useLabel } from '@websolutespa/bom-mixer-hooks';\nimport { Cta, LlmBlock, useLlmView } from '@websolutespa/bom-mixer-llm';\nimport style from './custom-card.module.scss';\n\nexport type LlmChunkCustomCard = {\n type: 'customCard';\n id: string;\n title?: string;\n abstract?: string;\n media?: {\n type: 'image';\n url: string;\n };\n href?: string;\n};\n\nexport const CustomCard: React.FC<LlmBlock<LlmChunkCustomCard>> = (props) => {\n const { item } = props;\n const label = useLabel();\n const { send } = useLlmView(state => state.actions);\n const onTellMeMore = async (event: React.MouseEvent) => {\n const prompt = `${label('llm.tellMeMoreAbout')} ${item.title}`;\n await send(prompt, (response) => {\n // console.log('Prompt.onChunk', response.chunks);\n }, (response) => {\n // console.log('Prompt.onEnd', response);\n });\n };\n const ariaLabel = label('llm.tellMeMore');\n return (\n <div className={style.customCard}>\n {item.media && (\n <>\n {item.href ? (\n <a className={style.customCardMedia} href={item.href} target=\"_blank\" rel=\"noreferrer\" aria-label={ariaLabel}>\n <div className={style.customCardAsset}>\n <img src={item.media.url} alt=\"\" />\n </div>\n </a>\n ) : (\n <div className={style.customCardMedia}>\n <div className={style.customCardAsset}>\n <img src={item.media.url} alt=\"\" />\n </div>\n </div>\n )}\n </>\n )}\n <div className={style.customCardContent}>\n {item.title && (\n <div className={style.customCardTitle} dangerouslySetInnerHTML={{ __html: item.title }} />\n )}\n <Cta url={item.href} className={style.customCardCta} type=\"button\" label={label('llm.tellMeMore')} onClick={onTellMeMore} />\n </div>\n </div>\n );\n};\n\n"],"names":["useLabel","Cta","useLlmView","style","CustomCard","props","item","label","send","state","actions","onTellMeMore","event","prompt","title","response","ariaLabel","div","className","customCard","media","href","a","customCardMedia","target","rel","aria-label","customCardAsset","img","src","url","alt","customCardContent","customCardTitle","dangerouslySetInnerHTML","__html","customCardCta","type","onClick"],"mappings":";AAAA,SAASA,QAAQ,QAAQ,gCAAgC;AACzD,SAASC,GAAG,EAAYC,UAAU,QAAQ,8BAA8B;AACxE,OAAOC,WAAW,4BAA4B;AAc9C,OAAO,MAAMC,aAAqD,CAACC;IACjE,MAAM,EAAEC,IAAI,EAAE,GAAGD;IACjB,MAAME,QAAQP;IACd,MAAM,EAAEQ,IAAI,EAAE,GAAGN,WAAWO,CAAAA,QAASA,MAAMC,OAAO;IAClD,MAAMC,eAAe,OAAOC;QAC1B,MAAMC,SAAS,CAAC,EAAEN,MAAM,uBAAuB,CAAC,EAAED,KAAKQ,KAAK,CAAC,CAAC;QAC9D,MAAMN,KAAKK,QAAQ,CAACE;QAClB,kDAAkD;QACpD,GAAG,CAACA;QACF,yCAAyC;QAC3C;IACF;IACA,MAAMC,YAAYT,MAAM;IACxB,qBACE,MAACU;QAAIC,WAAWf,MAAMgB,UAAU;;YAC7Bb,KAAKc,KAAK,kBACT;0BACGd,KAAKe,IAAI,iBACR,KAACC;oBAAEJ,WAAWf,MAAMoB,eAAe;oBAAEF,MAAMf,KAAKe,IAAI;oBAAEG,QAAO;oBAASC,KAAI;oBAAaC,cAAYV;8BACjG,cAAA,KAACC;wBAAIC,WAAWf,MAAMwB,eAAe;kCACnC,cAAA,KAACC;4BAAIC,KAAKvB,KAAKc,KAAK,CAACU,GAAG;4BAAEC,KAAI;;;mCAIlC,KAACd;oBAAIC,WAAWf,MAAMoB,eAAe;8BACnC,cAAA,KAACN;wBAAIC,WAAWf,MAAMwB,eAAe;kCACnC,cAAA,KAACC;4BAAIC,KAAKvB,KAAKc,KAAK,CAACU,GAAG;4BAAEC,KAAI;;;;;0BAMxC,MAACd;gBAAIC,WAAWf,MAAM6B,iBAAiB;;oBACpC1B,KAAKQ,KAAK,kBACT,KAACG;wBAAIC,WAAWf,MAAM8B,eAAe;wBAAEC,yBAAyB;4BAAEC,QAAQ7B,KAAKQ,KAAK;wBAAC;;kCAEvF,KAACb;wBAAI6B,KAAKxB,KAAKe,IAAI;wBAAEH,WAAWf,MAAMiC,aAAa;wBAAEC,MAAK;wBAAS9B,OAAOA,MAAM;wBAAmB+B,SAAS3B;;;;;;AAIpH,EAAE"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
@import '../../scss/mixin';
|
|
2
|
+
|
|
3
|
+
.customCard {
|
|
4
|
+
max-width: 700px;
|
|
5
|
+
position: relative;
|
|
6
|
+
display: flex;
|
|
7
|
+
flex-direction: row;
|
|
8
|
+
overflow: hidden;
|
|
9
|
+
border-radius: 6px;
|
|
10
|
+
background: var(--llm-color-neutral-100);
|
|
11
|
+
box-shadow: 0 0 20px 0 rgba(0, 0, 0, 0.05);
|
|
12
|
+
padding: size(4) size(3);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.customCardMedia {
|
|
16
|
+
position: relative;
|
|
17
|
+
width: 200px;
|
|
18
|
+
flex-shrink: 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.customCardAsset {
|
|
22
|
+
display: flex;
|
|
23
|
+
justify-content: center;
|
|
24
|
+
align-items: center;
|
|
25
|
+
aspect-ratio: 1;
|
|
26
|
+
border-radius: 0;
|
|
27
|
+
overflow: hidden;
|
|
28
|
+
|
|
29
|
+
&>img {
|
|
30
|
+
width: 100%;
|
|
31
|
+
height: 100%;
|
|
32
|
+
object-fit: contain;
|
|
33
|
+
object-position: center;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.customCardContent {
|
|
38
|
+
position: relative;
|
|
39
|
+
display: flex;
|
|
40
|
+
flex-direction: column;
|
|
41
|
+
padding: 0 size(3) ;
|
|
42
|
+
gap: size(3);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.customCardTitle {
|
|
46
|
+
@include text(display5);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.customCardCta {
|
|
50
|
+
color: var(--llm-color-neutral-100) !important;
|
|
51
|
+
background: var(--llm-color-base-900) !important;
|
|
52
|
+
border-radius: 50px;
|
|
53
|
+
padding: 12px 16px !important;
|
|
54
|
+
width: fit-content;
|
|
55
|
+
line-height: 1 !important;
|
|
56
|
+
display: flex !important;
|
|
57
|
+
min-height: 0 !important;
|
|
58
|
+
margin-top: auto;
|
|
59
|
+
> span {
|
|
60
|
+
font-size: 16px !important;
|
|
61
|
+
letter-spacing: 0.02em !important;
|
|
62
|
+
line-height: 1 !important;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useWindowSize } from '@websolutespa/bom-mixer-hooks';
|
|
3
|
+
import { IconLlmArrowLeft, IconLlmArrowRight } from '@websolutespa/bom-mixer-icons';
|
|
4
|
+
import { clamp } from '@websolutespa/bom-mixer-llm';
|
|
5
|
+
import { useRef } from 'react';
|
|
6
|
+
import { Navigation } from 'swiper';
|
|
7
|
+
import { Swiper, SwiperSlide } from 'swiper/react';
|
|
8
|
+
import { CustomCard } from '../CustomCard/custom-card';
|
|
9
|
+
import style from './custom-card-group.module.scss';
|
|
10
|
+
export const CustomCardGroup = (props)=>{
|
|
11
|
+
const { item } = props;
|
|
12
|
+
useWindowSize();
|
|
13
|
+
const navigationPrevRef = useRef(null);
|
|
14
|
+
const navigationNextRef = useRef(null);
|
|
15
|
+
const swiperProps = {
|
|
16
|
+
modules: [
|
|
17
|
+
Navigation
|
|
18
|
+
],
|
|
19
|
+
spaceBetween: clamp(16, 24),
|
|
20
|
+
slidesPerView: 1.1,
|
|
21
|
+
watchOverflow: true,
|
|
22
|
+
navigation: {
|
|
23
|
+
prevEl: navigationPrevRef.current,
|
|
24
|
+
nextEl: navigationNextRef.current
|
|
25
|
+
},
|
|
26
|
+
breakpoints: {
|
|
27
|
+
630: {
|
|
28
|
+
slidesPerView: 1.5
|
|
29
|
+
},
|
|
30
|
+
768: {
|
|
31
|
+
slidesPerView: 2
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
return /*#__PURE__*/ _jsx("div", {
|
|
36
|
+
className: style.customCardGroup,
|
|
37
|
+
children: /*#__PURE__*/ _jsxs(Swiper, {
|
|
38
|
+
...swiperProps,
|
|
39
|
+
children: [
|
|
40
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
41
|
+
className: style.customCardGroupNav,
|
|
42
|
+
children: [
|
|
43
|
+
/*#__PURE__*/ _jsx("button", {
|
|
44
|
+
ref: navigationPrevRef,
|
|
45
|
+
children: /*#__PURE__*/ _jsx(IconLlmArrowLeft, {})
|
|
46
|
+
}),
|
|
47
|
+
/*#__PURE__*/ _jsx("button", {
|
|
48
|
+
ref: navigationNextRef,
|
|
49
|
+
children: /*#__PURE__*/ _jsx(IconLlmArrowRight, {})
|
|
50
|
+
})
|
|
51
|
+
]
|
|
52
|
+
}),
|
|
53
|
+
item.items.map((item, i)=>/*#__PURE__*/ _jsx(SwiperSlide, {
|
|
54
|
+
className: style.customCardGroupSlide,
|
|
55
|
+
children: /*#__PURE__*/ _jsx(CustomCard, {
|
|
56
|
+
...props,
|
|
57
|
+
item: item
|
|
58
|
+
})
|
|
59
|
+
}, i))
|
|
60
|
+
]
|
|
61
|
+
})
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
//# sourceMappingURL=custom-card-group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/blocks/CustomCardGroup/custom-card-group.tsx"],"sourcesContent":["import { useWindowSize } from '@websolutespa/bom-mixer-hooks';\nimport { IconLlmArrowLeft, IconLlmArrowRight } from '@websolutespa/bom-mixer-icons';\nimport { clamp, LlmBlock } from '@websolutespa/bom-mixer-llm';\nimport { useRef } from 'react';\nimport { Navigation } from 'swiper';\nimport { Swiper, SwiperSlide } from 'swiper/react';\nimport { CustomCard, LlmChunkCustomCard } from '../CustomCard/custom-card';\nimport style from './custom-card-group.module.scss';\n\nexport type LlmChunkCustomCardGroup = {\n type: 'customCardGroup';\n id: string;\n items: LlmChunkCustomCard[];\n};\n\nexport const CustomCardGroup: React.FC<LlmBlock<LlmChunkCustomCardGroup>> = (props) => {\n const { item } = props;\n\n useWindowSize();\n\n const navigationPrevRef = useRef(null);\n const navigationNextRef = useRef(null);\n const swiperProps = {\n modules: [Navigation],\n spaceBetween: clamp(16, 24),\n slidesPerView: 1.1,\n watchOverflow: true,\n navigation: {\n prevEl: navigationPrevRef.current,\n nextEl: navigationNextRef.current,\n },\n breakpoints: {\n 630: {\n slidesPerView: 1.5,\n },\n 768: {\n slidesPerView: 2,\n },\n\n },\n };\n\n return (\n <div className={style.customCardGroup}>\n <Swiper {...swiperProps}>\n <div className={style.customCardGroupNav}>\n <button ref={navigationPrevRef}><IconLlmArrowLeft /></button>\n <button ref={navigationNextRef}><IconLlmArrowRight /></button>\n </div>\n {item.items.map((item, i) => (\n <SwiperSlide key={i} className={style.customCardGroupSlide}>\n <CustomCard {...props} item={item} />\n </SwiperSlide>\n ))}\n </Swiper>\n </div>\n );\n};\n\n"],"names":["useWindowSize","IconLlmArrowLeft","IconLlmArrowRight","clamp","useRef","Navigation","Swiper","SwiperSlide","CustomCard","style","CustomCardGroup","props","item","navigationPrevRef","navigationNextRef","swiperProps","modules","spaceBetween","slidesPerView","watchOverflow","navigation","prevEl","current","nextEl","breakpoints","div","className","customCardGroup","customCardGroupNav","button","ref","items","map","i","customCardGroupSlide"],"mappings":";AAAA,SAASA,aAAa,QAAQ,gCAAgC;AAC9D,SAASC,gBAAgB,EAAEC,iBAAiB,QAAQ,gCAAgC;AACpF,SAASC,KAAK,QAAkB,8BAA8B;AAC9D,SAASC,MAAM,QAAQ,QAAQ;AAC/B,SAASC,UAAU,QAAQ,SAAS;AACpC,SAASC,MAAM,EAAEC,WAAW,QAAQ,eAAe;AACnD,SAASC,UAAU,QAA4B,4BAA4B;AAC3E,OAAOC,WAAW,kCAAkC;AAQpD,OAAO,MAAMC,kBAA+D,CAACC;IAC3E,MAAM,EAAEC,IAAI,EAAE,GAAGD;IAEjBX;IAEA,MAAMa,oBAAoBT,OAAO;IACjC,MAAMU,oBAAoBV,OAAO;IACjC,MAAMW,cAAc;QAClBC,SAAS;YAACX;SAAW;QACrBY,cAAcd,MAAM,IAAI;QACxBe,eAAe;QACfC,eAAe;QACfC,YAAY;YACVC,QAAQR,kBAAkBS,OAAO;YACjCC,QAAQT,kBAAkBQ,OAAO;QACnC;QACAE,aAAa;YACX,KAAK;gBACHN,eAAe;YACjB;YACA,KAAK;gBACHA,eAAe;YACjB;QAEF;IACF;IAEA,qBACE,KAACO;QAAIC,WAAWjB,MAAMkB,eAAe;kBACnC,cAAA,MAACrB;YAAQ,GAAGS,WAAW;;8BACrB,MAACU;oBAAIC,WAAWjB,MAAMmB,kBAAkB;;sCACtC,KAACC;4BAAOC,KAAKjB;sCAAmB,cAAA,KAACZ;;sCACjC,KAAC4B;4BAAOC,KAAKhB;sCAAmB,cAAA,KAACZ;;;;gBAElCU,KAAKmB,KAAK,CAACC,GAAG,CAAC,CAACpB,MAAMqB,kBACrB,KAAC1B;wBAAoBmB,WAAWjB,MAAMyB,oBAAoB;kCACxD,cAAA,KAAC1B;4BAAY,GAAGG,KAAK;4BAAEC,MAAMA;;uBADbqB;;;;AAO5B,EAAE"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
@import '../../scss/mixin';
|
|
2
|
+
|
|
3
|
+
.customCardGroup {
|
|
4
|
+
@include containerNegative();
|
|
5
|
+
|
|
6
|
+
:global(.swiper) {
|
|
7
|
+
position: relative;
|
|
8
|
+
overflow: visible;
|
|
9
|
+
padding-top: size(10);
|
|
10
|
+
padding-bottom: size(5);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
:global(.swiper-slide) {
|
|
14
|
+
height: auto;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.customCardGroupNav {
|
|
19
|
+
position: absolute;
|
|
20
|
+
top: 0;
|
|
21
|
+
left: 0;
|
|
22
|
+
color: var(--llm-color-foreground);
|
|
23
|
+
display: flex;
|
|
24
|
+
gap: size(3);
|
|
25
|
+
|
|
26
|
+
@include bp(md) {
|
|
27
|
+
right: 0;
|
|
28
|
+
left: auto;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
button {
|
|
32
|
+
color: currentColor;
|
|
33
|
+
pointer-events: auto;
|
|
34
|
+
cursor: pointer;
|
|
35
|
+
|
|
36
|
+
&.swiper-button-disabled {
|
|
37
|
+
opacity: 0.2;
|
|
38
|
+
cursor: pointer;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
&.swiper-button-lock {
|
|
42
|
+
display: none;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
svg {
|
|
46
|
+
width: 24px;
|
|
47
|
+
height: 24px;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.customCardGroupSlide {
|
|
53
|
+
height: auto;
|
|
54
|
+
|
|
55
|
+
:global(.customCard) {
|
|
56
|
+
height: 100%;
|
|
57
|
+
}
|
|
58
|
+
}
|