aov-agent 1.0.0 → 1.0.6

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 (39) hide show
  1. package/README.md +313 -1
  2. package/dist/agent-ui/components/Assistant/AgentButton/AgentButton.js +28 -0
  3. package/dist/agent-ui/components/Assistant/AgentButton/AgentButton.scss +40 -0
  4. package/dist/agent-ui/components/Assistant/Assistant.js +68 -0
  5. package/dist/agent-ui/components/Assistant/Assistant.scss +3 -0
  6. package/dist/agent-ui/components/Assistant/AssistantWidget/AssistantWidget.js +193 -0
  7. package/dist/agent-ui/components/Assistant/AssistantWidget/AssistantWidget.scss +205 -0
  8. package/dist/agent-ui/components/Assistant/AssistantWidget/components/CampaignRendered.js +30 -0
  9. package/dist/agent-ui/components/Assistant/AssistantWidget/components/ListChat.js +129 -0
  10. package/dist/agent-ui/components/Assistant/Markdown/MarkdownText.js +228 -0
  11. package/dist/agent-ui/components/Assistant/Markdown/MarkdownText.scss +222 -0
  12. package/dist/agent-ui/components/Assistant/Markdown/MathRenderer.js +52 -0
  13. package/dist/agent-ui/components/Assistant/Suggestions/Suggestions.js +62 -0
  14. package/dist/agent-ui/components/Assistant/Suggestions/Suggestions.scss +22 -0
  15. package/dist/agent-ui/components/Assistant/ThreadProvider.js +481 -0
  16. package/dist/agent-ui/components/Assistant/ToolResult/CardTool.js +98 -0
  17. package/dist/agent-ui/components/Assistant/ToolResult/CardTool.scss +12 -0
  18. package/dist/agent-ui/components/Assistant/ToolResult/ToolResult.js +44 -0
  19. package/dist/agent-ui/components/CopyToClipboard/CopyToClipboard.js +43 -0
  20. package/dist/agent-ui/components/CopyToClipboard/index.js +2 -0
  21. package/dist/agent-ui/components/ResizableModal/ResizableModal.js +262 -0
  22. package/dist/agent-ui/components/ResizableModal/ResizableModal.scss +117 -0
  23. package/dist/agent-ui/const/appName.js +6 -0
  24. package/dist/agent-ui/const/option.js +9 -0
  25. package/dist/agent-ui/const/toolName.js +6 -0
  26. package/dist/agent-ui/contexts/AgentContext.js +54 -0
  27. package/dist/agent-ui/contexts/SuggestionsContext.js +64 -0
  28. package/dist/agent-ui/contexts/ThreadContext.js +60 -0
  29. package/dist/agent-ui/helpers/copyToClipboard.js +33 -0
  30. package/dist/agent-ui/helpers/formatQuery.js +15 -0
  31. package/dist/agent-ui/hooks/useFetchApi.js +238 -0
  32. package/dist/agent-ui/hooks/useStreamApi.js +127 -0
  33. package/dist/agent-ui/index.js +1 -0
  34. package/dist/agent-ui/resources/assistant-avatar.svg +51 -0
  35. package/dist/agent-ui/services/errorService.js +39 -0
  36. package/dist/agent-ui/utils/api.js +164 -0
  37. package/package.json +44 -9
  38. package/dist/index.js +0 -7
  39. package/types/index.d.ts +0 -5
package/README.md CHANGED
@@ -1 +1,313 @@
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/app/`** - Next.js 15 application (Frontend + Backend API Routes + Firestore)
237
+ - **`packages/ui/`** - AI Assistant UI components (published as `aov-agent/agent-ui`)
238
+
239
+ Each package can be developed, built, and tested independently.
240
+
241
+ ### 🚀 Quick Start for Development
242
+
243
+ ```bash
244
+ # Install all dependencies
245
+ npm install
246
+
247
+ # Run Next.js development server
248
+ npm run dev
249
+
250
+ # App: http://localhost:3000
251
+ # API: http://localhost:3000/api
252
+ ```
253
+
254
+ ### Project Structure
255
+
256
+ ```
257
+ /aov-ai-agent/
258
+ ├── packages/
259
+ │ ├── app/ # Next.js 15 App (Frontend + Backend API)
260
+ │ │ ├── app/ # App Router
261
+ │ │ │ ├── api/ # API Routes (Firestore backend)
262
+ │ │ │ ├── layout.tsx
263
+ │ │ │ ├── page.tsx
264
+ │ │ │ └── globals.css
265
+ │ │ ├── components/ui/ # shadcn/ui components
266
+ │ │ ├── lib/ # Utilities & Firestore client
267
+ │ │ ├── repositories/ # Firestore repositories
268
+ │ │ ├── services/ # Business logic
269
+ │ │ └── package.json
270
+ │ └── ui/ # AI Assistant UI Components (publishable)
271
+ │ └── src/
272
+ │ └── components/
273
+ ```
274
+
275
+ ### Stack
276
+
277
+ - **Frontend**: Next.js 15 + React 19 + TypeScript
278
+ - **Styling**: Tailwind CSS + shadcn/ui
279
+ - **Backend**: Next.js API Routes
280
+ - **Database**: Google Cloud Firestore
281
+ - **Validation**: Zod
282
+ - **Icons**: Lucide React
283
+
284
+ ### Setup Firebase
285
+
286
+ Create `packages/app/.env.local`:
287
+
288
+ ```bash
289
+ GOOGLE_APPLICATION_CREDENTIALS=/path/to/your/serviceAccount.json
290
+ FIREBASE_PROJECT_ID=your-project-id
291
+ NODE_ENV=development
292
+ ```
293
+
294
+ Download your Firebase service account key from [Firebase Console](https://console.firebase.google.com/) → Project Settings → Service Accounts.
295
+
296
+ ### API Endpoints
297
+
298
+ - `GET /api/health` - Health check
299
+ - `GET /api/todos` - Get all todos
300
+ - `POST /api/todos` - Create todo
301
+ - `GET /api/todos/:id` - Get single todo
302
+ - `PATCH /api/todos/:id` - Update todo
303
+ - `DELETE /api/todos/:id` - Delete todo
304
+
305
+ ## 📄 License
306
+
307
+ ISC
308
+
309
+ ## 🔗 Links
310
+
311
+ - Repository: https://gitlab.com/avada/aov-ai-agent
312
+ - Issues: https://gitlab.com/avada/aov-ai-agent/issues
313
+ - 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,68 @@
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() {
11
+ var _useContext = useContext(AgentContext),
12
+ openAgent = _useContext.openAgent,
13
+ setOpenAgent = _useContext.setOpenAgent;
14
+ return /*#__PURE__*/React.createElement("div", {
15
+ className: "aov-assistant-core"
16
+ }, /*#__PURE__*/React.createElement(AgentButton, {
17
+ onClick: function onClick() {
18
+ return setOpenAgent(true);
19
+ }
20
+ }), /*#__PURE__*/React.createElement(ResizableModal, {
21
+ open: openAgent,
22
+ onClose: function onClose() {
23
+ return setOpenAgent(false);
24
+ },
25
+ accessibilityLabel: "Mavi"
26
+ }, /*#__PURE__*/React.createElement(SuggestionsProvider, null, /*#__PURE__*/React.createElement(ThreadProvider, null, /*#__PURE__*/React.createElement(AssistantWidget, {
27
+ onClose: function onClose() {
28
+ return setOpenAgent(false);
29
+ }
30
+ })))));
31
+ };
32
+
33
+ /**
34
+ * Assistant - Main AI assistant component with chat interface
35
+ *
36
+ * @param {Object} shop - Shop data object
37
+ * @param {boolean} shop.showAgentChat - Whether to show the agent chat
38
+ * @param {string} shop.id - Shop identifier
39
+ * @param {string} apiUrl - API endpoint URL for chat
40
+ * @param {string} appName - Application name
41
+ * @param {Object} customToolRenderers - Custom renderers for tools
42
+ * @returns {React.ReactElement} Assistant component
43
+ */
44
+ export var Assistant = function Assistant(_ref) {
45
+ var shop = _ref.shop,
46
+ apiUrl = _ref.apiUrl,
47
+ appName = _ref.appName,
48
+ customToolRenderers = _ref.customToolRenderers;
49
+ if (!shop.showAgentChat) return null;
50
+ return /*#__PURE__*/React.createElement(AgentProvider, {
51
+ contextValue: {
52
+ appName: appName,
53
+ shop: shop,
54
+ apiUrl: apiUrl,
55
+ customToolRenderers: customToolRenderers
56
+ }
57
+ }, /*#__PURE__*/React.createElement(AssistantCore, null));
58
+ };
59
+ Assistant.propTypes = {
60
+ shop: PropTypes.shape({
61
+ showAgentChat: PropTypes.bool,
62
+ id: PropTypes.string
63
+ }),
64
+ apiUrl: PropTypes.string,
65
+ appName: PropTypes.string,
66
+ customToolRenderers: PropTypes.object
67
+ };
68
+ export default Assistant;
@@ -0,0 +1,3 @@
1
+ .aov-assistant-core {
2
+ position: relative;
3
+ }
@@ -0,0 +1,193 @@
1
+ var _excluded = ["shop"];
2
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
3
+ 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."); }
4
+ 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; } }
5
+ 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; }
6
+ 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; } }
7
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
8
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
9
+ function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
10
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
11
+ import React, { useCallback, useState, useContext, useMemo } from "react";
12
+ import PropTypes from "prop-types";
13
+ import { Box, Button, InlineStack, Popover, Spinner, Text } from "@shopify/polaris";
14
+ import { ComposeIcon, XIcon } from "@shopify/polaris-icons";
15
+ import { ThreadContext } from "../../../contexts/ThreadContext.js";
16
+ import { Composer, Thread, ThreadWelcome } from "@assistant-ui/react-ui";
17
+ import { MarkdownText } from "../Markdown/MarkdownText.js";
18
+ import MathRenderer from "../Markdown/MathRenderer.js";
19
+ import { useThreadAutoScrollFix } from "../ThreadProvider.js";
20
+ import Suggestions from "../Suggestions/Suggestions.js";
21
+ import "@assistant-ui/react-markdown/styles/dot.css";
22
+ import ToolResult from "../ToolResult/ToolResult.js";
23
+ import ListChat from "./components/ListChat.js";
24
+ import "./AssistantWidget.scss";
25
+ import Avatar from "../../../resources/assistant-avatar.svg";
26
+ import { welcomeSuggestions } from "../../../const/option";
27
+ import { AgentContext } from "../../../contexts/AgentContext.js";
28
+ var AssistantText = /*#__PURE__*/React.memo(function AssistantText(props) {
29
+ try {
30
+ return /*#__PURE__*/React.createElement("div", {
31
+ className: "assistant-markdown-text"
32
+ }, /*#__PURE__*/React.createElement(MathRenderer, null, /*#__PURE__*/React.createElement(MarkdownText, props)));
33
+ } catch (err) {
34
+ console.error("Error rendering markdown text:", err);
35
+ return /*#__PURE__*/React.createElement("div", {
36
+ className: "assistant-markdown-text"
37
+ }, props.children);
38
+ }
39
+ });
40
+ var AssistantTool = /*#__PURE__*/React.memo(function AssistantTool(_ref) {
41
+ var shop = _ref.shop,
42
+ props = _objectWithoutProperties(_ref, _excluded);
43
+ try {
44
+ return /*#__PURE__*/React.createElement(ToolResult, _extends({}, props, {
45
+ shop: shop
46
+ }));
47
+ } catch (err) {
48
+ console.error("Error rendering tool result:", err);
49
+ return null;
50
+ }
51
+ });
52
+ var AssistantWidget = function AssistantWidget(_ref2) {
53
+ var onClose = _ref2.onClose;
54
+ var _useContext = useContext(AgentContext),
55
+ appName = _useContext.appName,
56
+ shop = _useContext.shop;
57
+ var _useContext2 = useContext(ThreadContext),
58
+ threads = _useContext2.threads,
59
+ loadingThreads = _useContext2.loadingThreads,
60
+ getThread = _useContext2.getThread,
61
+ loadingMessages = _useContext2.loadingMessages,
62
+ thread = _useContext2.thread,
63
+ _setThread = _useContext2.setThread,
64
+ resetThread = _useContext2.resetThread,
65
+ updateThread = _useContext2.updateThread,
66
+ deleteThread = _useContext2.deleteThread;
67
+ var _useThreadAutoScrollF = useThreadAutoScrollFix(),
68
+ autoScroll = _useThreadAutoScrollF.autoScroll,
69
+ handleScroll = _useThreadAutoScrollF.handleScroll;
70
+ var _useState = useState(false),
71
+ _useState2 = _slicedToArray(_useState, 2),
72
+ popoverActive = _useState2[0],
73
+ setPopoverActive = _useState2[1];
74
+ var togglePopoverActive = useCallback(function () {
75
+ return setPopoverActive(function (popoverActive) {
76
+ return !popoverActive;
77
+ });
78
+ }, []);
79
+ var activator = /*#__PURE__*/React.createElement(Box, {
80
+ width: "fit-content"
81
+ }, /*#__PURE__*/React.createElement(Button, {
82
+ onClick: togglePopoverActive,
83
+ disclosure: true,
84
+ variant: "monochromePlain"
85
+ }, /*#__PURE__*/React.createElement(Box, {
86
+ width: "fit-content",
87
+ minWidth: "60px"
88
+ }, /*#__PURE__*/React.createElement(Text, {
89
+ truncate: true
90
+ }, thread && "title" in thread ? thread.title : "New chat"))));
91
+ var assistantComponents = useMemo(function () {
92
+ return {
93
+ Text: AssistantText,
94
+ ToolFallback: function ToolFallback(props) {
95
+ return /*#__PURE__*/React.createElement(AssistantTool, _extends({
96
+ shop: shop
97
+ }, props));
98
+ }
99
+ };
100
+ }, [shop]);
101
+ return /*#__PURE__*/React.createElement("div", {
102
+ className: "AOV-Sidekick__Container"
103
+ }, /*#__PURE__*/React.createElement(Box, {
104
+ paddingBlockStart: "300",
105
+ paddingBlockEnd: "200",
106
+ paddingInlineStart: "200",
107
+ paddingInlineEnd: "300"
108
+ }, /*#__PURE__*/React.createElement(InlineStack, {
109
+ align: "space-between",
110
+ blockAlign: "center",
111
+ gap: "100",
112
+ wrap: false
113
+ }, loadingThreads ? /*#__PURE__*/React.createElement(Spinner, {
114
+ size: "small"
115
+ }) : /*#__PURE__*/React.createElement(Box, {
116
+ width: "calc(100% - 120px)"
117
+ }, /*#__PURE__*/React.createElement(Popover, {
118
+ active: popoverActive,
119
+ activator: activator,
120
+ onClose: togglePopoverActive,
121
+ preferredAlignment: "start"
122
+ }, /*#__PURE__*/React.createElement(ListChat, {
123
+ threads: threads,
124
+ setThread: function setThread(thread) {
125
+ _setThread(thread);
126
+ togglePopoverActive();
127
+ if ("id" in thread) {
128
+ getThread(thread.id);
129
+ }
130
+ },
131
+ updateThread: updateThread,
132
+ deleteThread: deleteThread
133
+ }))), /*#__PURE__*/React.createElement(Box, {
134
+ minWidth: "45px"
135
+ }, /*#__PURE__*/React.createElement(InlineStack, {
136
+ wrap: false,
137
+ blockAlign: "center",
138
+ gap: "100"
139
+ }, /*#__PURE__*/React.createElement(Button, {
140
+ icon: ComposeIcon,
141
+ variant: "monochromePlain",
142
+ onClick: function onClick() {
143
+ _setThread({});
144
+ resetThread();
145
+ }
146
+ }), /*#__PURE__*/React.createElement(Button, {
147
+ icon: XIcon,
148
+ variant: "monochromePlain",
149
+ onClick: onClose
150
+ }))))), /*#__PURE__*/React.createElement(Thread.Root, {
151
+ config: {
152
+ welcome: {
153
+ message: "Hi! I'm Mavi, AOV Free Gift Assistant. I'm here to help you."
154
+ },
155
+ assistantAvatar: {
156
+ src: Avatar,
157
+ alt: "Mavi"
158
+ },
159
+ assistantMessage: {
160
+ allowEdit: false,
161
+ components: assistantComponents
162
+ },
163
+ userMessage: {
164
+ allowEdit: false
165
+ }
166
+ }
167
+ }, /*#__PURE__*/React.createElement(Thread.Viewport, {
168
+ autoScroll: autoScroll,
169
+ onScroll: handleScroll
170
+ }, loadingMessages ? /*#__PURE__*/React.createElement("div", {
171
+ className: "AOV-Sidekick__Loading"
172
+ }, /*#__PURE__*/React.createElement(Spinner, {
173
+ size: "small"
174
+ })) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ThreadWelcome.Root, null, /*#__PURE__*/React.createElement(ThreadWelcome.Center, null, /*#__PURE__*/React.createElement(ThreadWelcome.Avatar, {
175
+ size: "large"
176
+ }), /*#__PURE__*/React.createElement(ThreadWelcome.Message, null)), /*#__PURE__*/React.createElement("div", {
177
+ className: "aui-thread-welcome-suggestion-container"
178
+ }, welcomeSuggestions(appName).map(function (prompt, index) {
179
+ return /*#__PURE__*/React.createElement(ThreadWelcome.Suggestion, {
180
+ key: index,
181
+ suggestion: {
182
+ prompt: prompt
183
+ }
184
+ });
185
+ }))), /*#__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, {
186
+ autoFocus: true,
187
+ placeholder: "Ask anything ..."
188
+ }), /*#__PURE__*/React.createElement(Composer.Action, null)))));
189
+ };
190
+ AssistantWidget.propTypes = {
191
+ onClose: PropTypes.func.isRequired
192
+ };
193
+ export default AssistantWidget;