aov-agent 1.0.0 → 1.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/README.md +250 -1
- package/dist/agent-ui/components/Assistant/AgentButton/AgentButton.js +28 -0
- package/dist/agent-ui/components/Assistant/AgentButton/AgentButton.scss +40 -0
- package/dist/agent-ui/components/Assistant/Assistant.js +73 -0
- package/dist/agent-ui/components/Assistant/Assistant.scss +3 -0
- package/dist/agent-ui/components/Assistant/AssistantWidget/AssistantWidget.js +187 -0
- package/dist/agent-ui/components/Assistant/AssistantWidget/AssistantWidget.scss +211 -0
- package/dist/agent-ui/components/Assistant/AssistantWidget/components/CampaignRendered.js +30 -0
- package/dist/agent-ui/components/Assistant/AssistantWidget/components/ListChat.js +129 -0
- package/dist/agent-ui/components/Assistant/Markdown/MarkdownText.js +228 -0
- package/dist/agent-ui/components/Assistant/Markdown/MarkdownText.scss +222 -0
- package/dist/agent-ui/components/Assistant/Markdown/MathRenderer.js +46 -0
- package/dist/agent-ui/components/Assistant/Suggestions/Suggestions.js +62 -0
- package/dist/agent-ui/components/Assistant/Suggestions/Suggestions.scss +22 -0
- package/dist/agent-ui/components/Assistant/ThreadProvider.js +482 -0
- package/dist/agent-ui/components/Assistant/ToolResult/CardTool.js +41 -0
- package/dist/agent-ui/components/Assistant/ToolResult/ToolResult.js +20 -0
- package/dist/agent-ui/components/ResizableModal/ResizableModal.js +262 -0
- package/dist/agent-ui/components/ResizableModal/ResizableModal.scss +117 -0
- package/dist/agent-ui/contexts/AgentContext.js +39 -0
- package/dist/agent-ui/contexts/SuggestionsContext.js +64 -0
- package/dist/agent-ui/contexts/ThreadContext.js +60 -0
- package/dist/agent-ui/hooks/useFetchApi.js +238 -0
- package/dist/agent-ui/hooks/useStreamApi.js +127 -0
- package/dist/agent-ui/index.js +1 -0
- package/dist/agent-ui/services/errorService.js +39 -0
- package/dist/agent-ui/utils/api.js +164 -0
- package/package.json +26 -9
- package/dist/index.js +0 -7
- package/types/index.d.ts +0 -5
package/README.md
CHANGED
|
@@ -1 +1,250 @@
|
|
|
1
|
-
|
|
1
|
+
# AOV AI Agent
|
|
2
|
+
|
|
3
|
+
A React-based AI chat assistant library for Shopify applications, providing a seamless AI-powered support experience.
|
|
4
|
+
|
|
5
|
+
## 🏗️ Project Structure
|
|
6
|
+
|
|
7
|
+
This project follows Avada's monorepo structure as defined in [CLAUDE.md](./CLAUDE.md):
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
aov-ai-agent/
|
|
11
|
+
├── packages/
|
|
12
|
+
│ └── ui/ # Frontend React UI package
|
|
13
|
+
│ ├── src/
|
|
14
|
+
│ │ ├── components/ # Reusable React components
|
|
15
|
+
│ │ ├── contexts/ # React contexts
|
|
16
|
+
│ │ ├── hooks/ # Custom React hooks
|
|
17
|
+
│ │ ├── services/ # API services
|
|
18
|
+
│ │ ├── utils/ # Utility functions
|
|
19
|
+
│ │ └── index.js # Main export
|
|
20
|
+
│ ├── .babelrc # Babel config for UI
|
|
21
|
+
│ ├── .gitignore # UI specific ignores
|
|
22
|
+
│ ├── package.json # UI package metadata
|
|
23
|
+
│ └── README.md # UI package documentation
|
|
24
|
+
├── dist/
|
|
25
|
+
│ └── agent-ui/ # Compiled UI output
|
|
26
|
+
├── types/ # TypeScript type definitions
|
|
27
|
+
├── .babelrc # Root Babel configuration
|
|
28
|
+
├── package.json # Root package configuration (monorepo)
|
|
29
|
+
└── CLAUDE.md # Coding standards and guidelines
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 📦 Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install aov-agent
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Install peer dependencies:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install react react-dom react-redux @shopify/polaris @shopify/polaris-icons
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## 🚀 Usage
|
|
45
|
+
|
|
46
|
+
### Import UI Components
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
// ✅ Import from agent-ui subpath
|
|
50
|
+
import { Assistant } from "aov-agent/agent-ui";
|
|
51
|
+
|
|
52
|
+
function App() {
|
|
53
|
+
return (
|
|
54
|
+
<Assistant
|
|
55
|
+
shop={{
|
|
56
|
+
id: "shop-123",
|
|
57
|
+
showAgentChat: true,
|
|
58
|
+
}}
|
|
59
|
+
apiUrl="/api/chat/message"
|
|
60
|
+
/>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Required Peer Dependencies
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"react": "^18.2.0",
|
|
70
|
+
"react-dom": "^18.2.0",
|
|
71
|
+
"react-redux": "^9.2.0",
|
|
72
|
+
"@shopify/polaris": "^13.9.5",
|
|
73
|
+
"@shopify/polaris-icons": "^9.3.1"
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## ✨ Features
|
|
78
|
+
|
|
79
|
+
- **AI-Powered Chat Interface**: Streaming chat with AI assistant
|
|
80
|
+
- **Thread Management**: Create, edit, delete, and switch between chat threads
|
|
81
|
+
- **AI Suggestions**: Contextual suggestions for quick actions
|
|
82
|
+
- **Tool Execution**: Support for AI tool calls and results
|
|
83
|
+
- **Markdown Support**: Rich text formatting with math equations (KaTeX)
|
|
84
|
+
- **Resizable Modal**: Draggable and resizable chat window
|
|
85
|
+
- **Shopify Polaris UI**: Built with Shopify's design system
|
|
86
|
+
- **PropTypes Validation**: Runtime type checking for components
|
|
87
|
+
- **SSE Streaming**: Real-time streaming responses
|
|
88
|
+
|
|
89
|
+
## 🛠️ Development
|
|
90
|
+
|
|
91
|
+
### Build
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
npm run build
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Compiles source code from `packages/ui/src/` to `dist/agent-ui/` using Babel.
|
|
98
|
+
|
|
99
|
+
### Watch Mode
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npm run build:watch
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Automatically rebuilds on file changes.
|
|
106
|
+
|
|
107
|
+
## 📚 Documentation
|
|
108
|
+
|
|
109
|
+
See [CLAUDE.md](./CLAUDE.md) for:
|
|
110
|
+
|
|
111
|
+
- Coding standards and conventions
|
|
112
|
+
- Project structure guidelines
|
|
113
|
+
- React component patterns
|
|
114
|
+
- API integration guidelines
|
|
115
|
+
- Error handling best practices
|
|
116
|
+
|
|
117
|
+
See [packages/ui/README.md](./packages/ui/README.md) for:
|
|
118
|
+
|
|
119
|
+
- Detailed component documentation
|
|
120
|
+
- Hook usage examples
|
|
121
|
+
- Context API reference
|
|
122
|
+
|
|
123
|
+
## 🏛️ Architecture
|
|
124
|
+
|
|
125
|
+
### Components
|
|
126
|
+
|
|
127
|
+
- **Assistant**: Main container with provider wrappers
|
|
128
|
+
- **AssistantWidget**: Chat UI with thread list and composer
|
|
129
|
+
- **ThreadProvider**: Manages thread state and streaming runtime
|
|
130
|
+
- **ResizableModal**: Draggable modal container
|
|
131
|
+
|
|
132
|
+
### Contexts
|
|
133
|
+
|
|
134
|
+
- **AgentContext**: Agent visibility state
|
|
135
|
+
- **SuggestionsContext**: AI suggestions management
|
|
136
|
+
- **ThreadContext**: Thread list and CRUD operations
|
|
137
|
+
|
|
138
|
+
### Hooks
|
|
139
|
+
|
|
140
|
+
- **useFetchApi**: Data fetching with pagination
|
|
141
|
+
- **useStreamApi**: SSE streaming API calls
|
|
142
|
+
- **useThreadAutoScrollFix**: Auto-scroll behavior
|
|
143
|
+
|
|
144
|
+
## 🎨 Tech Stack
|
|
145
|
+
|
|
146
|
+
- React 18.2
|
|
147
|
+
- Shopify Polaris 13.9
|
|
148
|
+
- @assistant-ui/react
|
|
149
|
+
- Redux for state management
|
|
150
|
+
- KaTeX for math rendering
|
|
151
|
+
- PropTypes for validation
|
|
152
|
+
|
|
153
|
+
## 📝 Code Standards
|
|
154
|
+
|
|
155
|
+
This project follows Avada's coding standards:
|
|
156
|
+
|
|
157
|
+
- ✅ ES6+ features (import/export, async/await, arrow functions)
|
|
158
|
+
- ✅ camelCase for functions/variables
|
|
159
|
+
- ✅ PascalCase for components/classes
|
|
160
|
+
- ✅ JSDoc documentation
|
|
161
|
+
- ✅ PropTypes validation
|
|
162
|
+
- ✅ Early returns (no nested conditions)
|
|
163
|
+
- ✅ Structured error handling
|
|
164
|
+
|
|
165
|
+
## 🤝 Contributing
|
|
166
|
+
|
|
167
|
+
Follow the guidelines in [CLAUDE.md](./CLAUDE.md) for:
|
|
168
|
+
|
|
169
|
+
- Naming conventions
|
|
170
|
+
- Function design patterns
|
|
171
|
+
- React component structure
|
|
172
|
+
- Documentation requirements
|
|
173
|
+
- Error handling patterns
|
|
174
|
+
|
|
175
|
+
## 📦 Publishing to NPM
|
|
176
|
+
|
|
177
|
+
This package is designed to be published to NPM for use in other projects.
|
|
178
|
+
|
|
179
|
+
### Build and Publish
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
# 1. Install dependencies
|
|
183
|
+
npm install
|
|
184
|
+
|
|
185
|
+
# 2. Clean and build (works on Windows & Linux)
|
|
186
|
+
npm run clean
|
|
187
|
+
npm run build
|
|
188
|
+
|
|
189
|
+
# 3. Verify build output
|
|
190
|
+
# On Linux/Mac:
|
|
191
|
+
ls -la dist/agent-ui/
|
|
192
|
+
# On Windows:
|
|
193
|
+
dir dist\agent-ui\
|
|
194
|
+
|
|
195
|
+
# 4. Test locally (optional)
|
|
196
|
+
npm link
|
|
197
|
+
|
|
198
|
+
# 5. Publish to NPM
|
|
199
|
+
npm publish
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Note:** The `clean` script uses `rimraf` which works cross-platform (Windows, Linux, Mac).
|
|
203
|
+
|
|
204
|
+
### Package Structure
|
|
205
|
+
|
|
206
|
+
When published, the package structure will be:
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
aov-agent/
|
|
210
|
+
├── dist/
|
|
211
|
+
│ └── agent-ui/ # UI components
|
|
212
|
+
│ ├── components/
|
|
213
|
+
│ ├── contexts/
|
|
214
|
+
│ ├── hooks/
|
|
215
|
+
│ ├── services/
|
|
216
|
+
│ ├── utils/
|
|
217
|
+
│ └── index.js
|
|
218
|
+
└── package.json
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Import Paths
|
|
222
|
+
|
|
223
|
+
```javascript
|
|
224
|
+
// UI Components
|
|
225
|
+
import { Assistant } from "aov-agent/agent-ui";
|
|
226
|
+
|
|
227
|
+
// Future packages (coming soon)
|
|
228
|
+
// import { ... } from 'aov-agent/assets';
|
|
229
|
+
// import { ... } from 'aov-agent/functions';
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## 📦 Monorepo Structure
|
|
233
|
+
|
|
234
|
+
This is a monorepo containing multiple packages:
|
|
235
|
+
|
|
236
|
+
- **`packages/ui/`** - UI components (published as `aov-agent/agent-ui`)
|
|
237
|
+
- **`packages/assets/`** - Frontend assets (coming soon)
|
|
238
|
+
- **`packages/functions/`** - Backend functions (coming soon)
|
|
239
|
+
|
|
240
|
+
Each package can be developed, built, and tested independently.
|
|
241
|
+
|
|
242
|
+
## 📄 License
|
|
243
|
+
|
|
244
|
+
ISC
|
|
245
|
+
|
|
246
|
+
## 🔗 Links
|
|
247
|
+
|
|
248
|
+
- Repository: https://gitlab.com/avada/aov-ai-agent
|
|
249
|
+
- Issues: https://gitlab.com/avada/aov-ai-agent/issues
|
|
250
|
+
- NPM: https://www.npmjs.com/package/aov-agent
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import { Icon } from "@shopify/polaris";
|
|
4
|
+
import { MagicIcon } from "@shopify/polaris-icons";
|
|
5
|
+
import "./AgentButton.scss";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* AgentButton - Floating button to trigger AI assistant
|
|
9
|
+
*
|
|
10
|
+
* @param {Function} onClick - Click handler to open assistant
|
|
11
|
+
* @returns {React.ReactElement} Agent button component
|
|
12
|
+
*/
|
|
13
|
+
var AgentButton = function AgentButton(_ref) {
|
|
14
|
+
var onClick = _ref.onClick;
|
|
15
|
+
return /*#__PURE__*/React.createElement("button", {
|
|
16
|
+
type: "button",
|
|
17
|
+
onClick: onClick,
|
|
18
|
+
className: "aov-agent-button",
|
|
19
|
+
"aria-label": "Open AI Assistant"
|
|
20
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
21
|
+
source: MagicIcon,
|
|
22
|
+
tone: "magic"
|
|
23
|
+
}));
|
|
24
|
+
};
|
|
25
|
+
AgentButton.propTypes = {
|
|
26
|
+
onClick: PropTypes.func.isRequired
|
|
27
|
+
};
|
|
28
|
+
export default AgentButton;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
.aov-agent-button {
|
|
2
|
+
position: fixed;
|
|
3
|
+
bottom: 20px;
|
|
4
|
+
left: 20px;
|
|
5
|
+
z-index: 380;
|
|
6
|
+
min-width: 40px;
|
|
7
|
+
min-height: 40px;
|
|
8
|
+
padding: 2px;
|
|
9
|
+
border: none;
|
|
10
|
+
border-radius: 50%;
|
|
11
|
+
display: flex;
|
|
12
|
+
align-items: center;
|
|
13
|
+
justify-content: center;
|
|
14
|
+
cursor: pointer;
|
|
15
|
+
background: #fff;
|
|
16
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08),
|
|
17
|
+
0 4px 12px rgba(0, 0, 0, 0.08);
|
|
18
|
+
transition: all 0.2s ease;
|
|
19
|
+
|
|
20
|
+
&:hover {
|
|
21
|
+
transform: translateY(-1px);
|
|
22
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12),
|
|
23
|
+
0 8px 16px rgba(0, 0, 0, 0.12);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
&:active {
|
|
27
|
+
transform: translateY(0);
|
|
28
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
&:focus {
|
|
32
|
+
outline: 2px solid #007bff;
|
|
33
|
+
outline-offset: 2px;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
&:focus:not(:focus-visible) {
|
|
37
|
+
outline: none;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import React, { useContext } from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import { AgentProvider, AgentContext } from "../../contexts/AgentContext.js";
|
|
4
|
+
import { SuggestionsProvider } from "../../contexts/SuggestionsContext.js";
|
|
5
|
+
import AgentButton from "./AgentButton/AgentButton.js";
|
|
6
|
+
import ThreadProvider from "./ThreadProvider.js";
|
|
7
|
+
import AssistantWidget from "./AssistantWidget/AssistantWidget.js";
|
|
8
|
+
import ResizableModal from "../ResizableModal/ResizableModal.js";
|
|
9
|
+
import "./Assistant.scss";
|
|
10
|
+
var AssistantCore = function AssistantCore(_ref) {
|
|
11
|
+
var shop = _ref.shop,
|
|
12
|
+
apiUrl = _ref.apiUrl;
|
|
13
|
+
var _useContext = useContext(AgentContext),
|
|
14
|
+
openAgent = _useContext.openAgent,
|
|
15
|
+
setOpenAgent = _useContext.setOpenAgent;
|
|
16
|
+
if (!(shop !== null && shop !== void 0 && shop.showAgentChat)) return null;
|
|
17
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
18
|
+
className: "aov-assistant-core"
|
|
19
|
+
}, /*#__PURE__*/React.createElement(AgentButton, {
|
|
20
|
+
onClick: function onClick() {
|
|
21
|
+
return setOpenAgent(true);
|
|
22
|
+
}
|
|
23
|
+
}), /*#__PURE__*/React.createElement(ResizableModal, {
|
|
24
|
+
open: openAgent,
|
|
25
|
+
onClose: function onClose() {
|
|
26
|
+
return setOpenAgent(false);
|
|
27
|
+
},
|
|
28
|
+
accessibilityLabel: "Mavi"
|
|
29
|
+
}, /*#__PURE__*/React.createElement(SuggestionsProvider, null, /*#__PURE__*/React.createElement(ThreadProvider, {
|
|
30
|
+
shop: shop,
|
|
31
|
+
apiUrl: apiUrl
|
|
32
|
+
}, /*#__PURE__*/React.createElement(AssistantWidget, {
|
|
33
|
+
shop: shop,
|
|
34
|
+
onClose: function onClose() {
|
|
35
|
+
return setOpenAgent(false);
|
|
36
|
+
}
|
|
37
|
+
})))));
|
|
38
|
+
};
|
|
39
|
+
AssistantCore.propTypes = {
|
|
40
|
+
shop: PropTypes.shape({
|
|
41
|
+
showAgentChat: PropTypes.bool,
|
|
42
|
+
id: PropTypes.string
|
|
43
|
+
}),
|
|
44
|
+
apiUrl: PropTypes.string
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Assistant - Main AI assistant component with chat interface
|
|
49
|
+
*
|
|
50
|
+
* @param {Object} shop - Shop data object
|
|
51
|
+
* @param {boolean} shop.showAgentChat - Whether to show the agent chat
|
|
52
|
+
* @param {string} shop.id - Shop identifier
|
|
53
|
+
* @param {string} apiUrl - API endpoint URL for chat
|
|
54
|
+
* @returns {React.ReactElement} Assistant component
|
|
55
|
+
*/
|
|
56
|
+
export var Assistant = function Assistant(_ref2) {
|
|
57
|
+
var shop = _ref2.shop,
|
|
58
|
+
apiUrl = _ref2.apiUrl;
|
|
59
|
+
return /*#__PURE__*/React.createElement(AgentProvider, null, /*#__PURE__*/React.createElement(AssistantCore, {
|
|
60
|
+
shop: shop || {
|
|
61
|
+
showAgentChat: true
|
|
62
|
+
},
|
|
63
|
+
apiUrl: apiUrl
|
|
64
|
+
}));
|
|
65
|
+
};
|
|
66
|
+
Assistant.propTypes = {
|
|
67
|
+
shop: PropTypes.shape({
|
|
68
|
+
showAgentChat: PropTypes.bool,
|
|
69
|
+
id: PropTypes.string
|
|
70
|
+
}),
|
|
71
|
+
apiUrl: PropTypes.string
|
|
72
|
+
};
|
|
73
|
+
export default Assistant;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
2
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
3
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
4
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
5
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
6
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
7
|
+
import React, { useCallback, useState, useContext, useMemo } from "react";
|
|
8
|
+
import PropTypes from "prop-types";
|
|
9
|
+
import { Box, Button, InlineStack, Popover, Spinner } from "@shopify/polaris";
|
|
10
|
+
import { ComposeIcon, XIcon } from "@shopify/polaris-icons";
|
|
11
|
+
import { connect } from "react-redux";
|
|
12
|
+
import { ThreadContext } from "../../../contexts/ThreadContext.js";
|
|
13
|
+
import { Composer, Thread, ThreadWelcome } from "@assistant-ui/react-ui";
|
|
14
|
+
import { MarkdownText } from "../Markdown/MarkdownText.js";
|
|
15
|
+
import MathRenderer from "../Markdown/MathRenderer.js";
|
|
16
|
+
import { useThreadAutoScrollFix } from "../ThreadProvider.js";
|
|
17
|
+
import Suggestions from "../Suggestions/Suggestions.js";
|
|
18
|
+
import "@assistant-ui/react-markdown/styles/dot.css";
|
|
19
|
+
import ToolResult from "../ToolResult/ToolResult.js";
|
|
20
|
+
import ListChat from "./components/ListChat.js";
|
|
21
|
+
import "./AssistantWidget.scss";
|
|
22
|
+
var AssistantText = /*#__PURE__*/React.memo(function AssistantText(props) {
|
|
23
|
+
try {
|
|
24
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
25
|
+
className: "assistant-markdown-text"
|
|
26
|
+
}, /*#__PURE__*/React.createElement(MathRenderer, null, /*#__PURE__*/React.createElement(MarkdownText, props)));
|
|
27
|
+
} catch (err) {
|
|
28
|
+
console.error("Error rendering markdown text:", err);
|
|
29
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
30
|
+
className: "assistant-markdown-text"
|
|
31
|
+
}, props.children);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
var AssistantTool = /*#__PURE__*/React.memo(function AssistantTool(props) {
|
|
35
|
+
try {
|
|
36
|
+
return /*#__PURE__*/React.createElement(ToolResult, props);
|
|
37
|
+
} catch (err) {
|
|
38
|
+
console.error("Error rendering tool result:", err);
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
var AssistantWidget = function AssistantWidget(_ref) {
|
|
43
|
+
var shop = _ref.shop,
|
|
44
|
+
onClose = _ref.onClose;
|
|
45
|
+
var _useContext = useContext(ThreadContext),
|
|
46
|
+
threads = _useContext.threads,
|
|
47
|
+
loadingThreads = _useContext.loadingThreads,
|
|
48
|
+
getThread = _useContext.getThread,
|
|
49
|
+
loadingMessages = _useContext.loadingMessages,
|
|
50
|
+
thread = _useContext.thread,
|
|
51
|
+
_setThread = _useContext.setThread,
|
|
52
|
+
resetThread = _useContext.resetThread,
|
|
53
|
+
updateThread = _useContext.updateThread,
|
|
54
|
+
deleteThread = _useContext.deleteThread;
|
|
55
|
+
var _useThreadAutoScrollF = useThreadAutoScrollFix(),
|
|
56
|
+
autoScroll = _useThreadAutoScrollF.autoScroll,
|
|
57
|
+
handleScroll = _useThreadAutoScrollF.handleScroll;
|
|
58
|
+
var _useState = useState(false),
|
|
59
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
60
|
+
popoverActive = _useState2[0],
|
|
61
|
+
setPopoverActive = _useState2[1];
|
|
62
|
+
var togglePopoverActive = useCallback(function () {
|
|
63
|
+
return setPopoverActive(function (popoverActive) {
|
|
64
|
+
return !popoverActive;
|
|
65
|
+
});
|
|
66
|
+
}, []);
|
|
67
|
+
var activator = /*#__PURE__*/React.createElement(Box, {
|
|
68
|
+
width: "fit-content"
|
|
69
|
+
}, /*#__PURE__*/React.createElement(Button, {
|
|
70
|
+
onClick: togglePopoverActive,
|
|
71
|
+
disclosure: true,
|
|
72
|
+
variant: "monochromePlain"
|
|
73
|
+
}, /*#__PURE__*/React.createElement(Box, {
|
|
74
|
+
width: "fit-content",
|
|
75
|
+
minWidth: "60px"
|
|
76
|
+
}, thread && "title" in thread ? thread.title : "New chat")));
|
|
77
|
+
var assistantComponents = useMemo(function () {
|
|
78
|
+
return {
|
|
79
|
+
Text: AssistantText,
|
|
80
|
+
ToolFallback: AssistantTool
|
|
81
|
+
};
|
|
82
|
+
}, []);
|
|
83
|
+
var welcomeSuggestions = ["How do I create my first Buy X Get Y campaign?", "How do I set a spending threshold for free gifts?", "How do I customize the Pop-up for my campaign?", "How do I check campaign performance and reports?"];
|
|
84
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
85
|
+
className: "AOV-Sidekick__Container"
|
|
86
|
+
}, /*#__PURE__*/React.createElement(Box, {
|
|
87
|
+
paddingBlockStart: "300",
|
|
88
|
+
paddingBlockEnd: "050",
|
|
89
|
+
paddingInlineStart: "200",
|
|
90
|
+
paddingInlineEnd: "300"
|
|
91
|
+
}, /*#__PURE__*/React.createElement(InlineStack, {
|
|
92
|
+
align: "space-between",
|
|
93
|
+
blockAlign: "center",
|
|
94
|
+
gap: "100",
|
|
95
|
+
wrap: false
|
|
96
|
+
}, loadingThreads ? /*#__PURE__*/React.createElement(Spinner, {
|
|
97
|
+
size: "small"
|
|
98
|
+
}) : /*#__PURE__*/React.createElement(Box, {
|
|
99
|
+
width: "calc(100% - 120px)"
|
|
100
|
+
}, /*#__PURE__*/React.createElement(Popover, {
|
|
101
|
+
active: popoverActive,
|
|
102
|
+
activator: activator,
|
|
103
|
+
onClose: togglePopoverActive,
|
|
104
|
+
preferredAlignment: "start"
|
|
105
|
+
}, /*#__PURE__*/React.createElement(ListChat, {
|
|
106
|
+
threads: threads,
|
|
107
|
+
setThread: function setThread(thread) {
|
|
108
|
+
_setThread(thread);
|
|
109
|
+
togglePopoverActive();
|
|
110
|
+
if ("id" in thread) {
|
|
111
|
+
getThread(thread.id);
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
updateThread: updateThread,
|
|
115
|
+
deleteThread: deleteThread
|
|
116
|
+
}))), /*#__PURE__*/React.createElement(Box, {
|
|
117
|
+
minWidth: "45px"
|
|
118
|
+
}, /*#__PURE__*/React.createElement(InlineStack, {
|
|
119
|
+
wrap: false,
|
|
120
|
+
blockAlign: "center",
|
|
121
|
+
gap: "100"
|
|
122
|
+
}, /*#__PURE__*/React.createElement(Button, {
|
|
123
|
+
icon: ComposeIcon,
|
|
124
|
+
variant: "monochromePlain",
|
|
125
|
+
onClick: function onClick() {
|
|
126
|
+
_setThread({});
|
|
127
|
+
resetThread();
|
|
128
|
+
}
|
|
129
|
+
}), /*#__PURE__*/React.createElement(Button, {
|
|
130
|
+
icon: XIcon,
|
|
131
|
+
variant: "monochromePlain",
|
|
132
|
+
onClick: onClose
|
|
133
|
+
}))))), /*#__PURE__*/React.createElement(Thread.Root, {
|
|
134
|
+
config: {
|
|
135
|
+
welcome: {
|
|
136
|
+
message: "Hi! I'm Mavi, AOV Free Gift Assistant. I'm here to help you."
|
|
137
|
+
},
|
|
138
|
+
assistantAvatar: {
|
|
139
|
+
src: "",
|
|
140
|
+
// TODO: Add avatar path
|
|
141
|
+
alt: "Mavi"
|
|
142
|
+
},
|
|
143
|
+
assistantMessage: {
|
|
144
|
+
allowEdit: false,
|
|
145
|
+
components: assistantComponents
|
|
146
|
+
},
|
|
147
|
+
userMessage: {
|
|
148
|
+
allowEdit: false
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}, /*#__PURE__*/React.createElement(Thread.Viewport, {
|
|
152
|
+
autoScroll: autoScroll,
|
|
153
|
+
onScroll: handleScroll
|
|
154
|
+
}, loadingMessages ? /*#__PURE__*/React.createElement("div", {
|
|
155
|
+
className: "AOV-Sidekick__Loading"
|
|
156
|
+
}, /*#__PURE__*/React.createElement(Spinner, {
|
|
157
|
+
size: "small"
|
|
158
|
+
})) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ThreadWelcome.Root, null, /*#__PURE__*/React.createElement(ThreadWelcome.Center, null, /*#__PURE__*/React.createElement(ThreadWelcome.Avatar, {
|
|
159
|
+
size: "large"
|
|
160
|
+
}), /*#__PURE__*/React.createElement(ThreadWelcome.Message, null)), /*#__PURE__*/React.createElement("div", {
|
|
161
|
+
className: "aui-thread-welcome-suggestion-container"
|
|
162
|
+
}, welcomeSuggestions.map(function (prompt, index) {
|
|
163
|
+
return /*#__PURE__*/React.createElement(ThreadWelcome.Suggestion, {
|
|
164
|
+
key: index,
|
|
165
|
+
suggestion: {
|
|
166
|
+
prompt: prompt
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}))), /*#__PURE__*/React.createElement(Thread.Messages, null))), /*#__PURE__*/React.createElement(Thread.ViewportFooter, null, /*#__PURE__*/React.createElement(Suggestions, null), /*#__PURE__*/React.createElement(Composer.Root, null, /*#__PURE__*/React.createElement(Composer.Input, {
|
|
170
|
+
autoFocus: true,
|
|
171
|
+
placeholder: "Ask anything ..."
|
|
172
|
+
}), /*#__PURE__*/React.createElement(Composer.Action, null)))));
|
|
173
|
+
};
|
|
174
|
+
AssistantWidget.propTypes = {
|
|
175
|
+
shop: PropTypes.shape({
|
|
176
|
+
id: PropTypes.string,
|
|
177
|
+
showAgentChat: PropTypes.bool
|
|
178
|
+
}),
|
|
179
|
+
onClose: PropTypes.func.isRequired
|
|
180
|
+
};
|
|
181
|
+
var mapStateToProps = function mapStateToProps(state) {
|
|
182
|
+
var _state$shop;
|
|
183
|
+
return {
|
|
184
|
+
shop: (_state$shop = state.shop) === null || _state$shop === void 0 ? void 0 : _state$shop.activeShop
|
|
185
|
+
};
|
|
186
|
+
};
|
|
187
|
+
export default connect(mapStateToProps)(AssistantWidget);
|