@rahul_vendure/ai-chat-plugin 0.1.0
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 +214 -0
- package/dist/ai-assistant.plugin.d.ts +18 -0
- package/dist/ai-assistant.plugin.d.ts.map +1 -0
- package/dist/ai-assistant.plugin.js +86 -0
- package/dist/ai-assistant.plugin.js.map +1 -0
- package/dist/api/ai-assistant.resolver.d.ts +11 -0
- package/dist/api/ai-assistant.resolver.d.ts.map +1 -0
- package/dist/api/ai-assistant.resolver.js +43 -0
- package/dist/api/ai-assistant.resolver.js.map +1 -0
- package/dist/api/schema-extensions.d.ts +3 -0
- package/dist/api/schema-extensions.d.ts.map +1 -0
- package/dist/api/schema-extensions.js +15 -0
- package/dist/api/schema-extensions.js.map +1 -0
- package/dist/constants.d.ts +41 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +24 -0
- package/dist/constants.js.map +1 -0
- package/dist/controllers/admin-chat.controller.d.ts +21 -0
- package/dist/controllers/admin-chat.controller.d.ts.map +1 -0
- package/dist/controllers/admin-chat.controller.js +64 -0
- package/dist/controllers/admin-chat.controller.js.map +1 -0
- package/dist/controllers/ai-assistant.controller.d.ts +96 -0
- package/dist/controllers/ai-assistant.controller.d.ts.map +1 -0
- package/dist/controllers/ai-assistant.controller.js +272 -0
- package/dist/controllers/ai-assistant.controller.js.map +1 -0
- package/dist/entities/collection-embedding.entity.d.ts +13 -0
- package/dist/entities/collection-embedding.entity.d.ts.map +1 -0
- package/dist/entities/collection-embedding.entity.js +43 -0
- package/dist/entities/collection-embedding.entity.js.map +1 -0
- package/dist/entities/product-embedding.entity.d.ts +14 -0
- package/dist/entities/product-embedding.entity.d.ts.map +1 -0
- package/dist/entities/product-embedding.entity.js +44 -0
- package/dist/entities/product-embedding.entity.js.map +1 -0
- package/dist/entities/variant-embedding.entity.d.ts +13 -0
- package/dist/entities/variant-embedding.entity.d.ts.map +1 -0
- package/dist/entities/variant-embedding.entity.js +43 -0
- package/dist/entities/variant-embedding.entity.js.map +1 -0
- package/dist/handlers/collection-embedding-handler.d.ts +18 -0
- package/dist/handlers/collection-embedding-handler.d.ts.map +1 -0
- package/dist/handlers/collection-embedding-handler.js +90 -0
- package/dist/handlers/collection-embedding-handler.js.map +1 -0
- package/dist/handlers/product-embedding-handler.d.ts +20 -0
- package/dist/handlers/product-embedding-handler.d.ts.map +1 -0
- package/dist/handlers/product-embedding-handler.js +96 -0
- package/dist/handlers/product-embedding-handler.js.map +1 -0
- package/dist/handlers/variant-embedding-handler.d.ts +19 -0
- package/dist/handlers/variant-embedding-handler.d.ts.map +1 -0
- package/dist/handlers/variant-embedding-handler.js +101 -0
- package/dist/handlers/variant-embedding-handler.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/services/admin-ai-chat.service.d.ts +40 -0
- package/dist/services/admin-ai-chat.service.d.ts.map +1 -0
- package/dist/services/admin-ai-chat.service.js +201 -0
- package/dist/services/admin-ai-chat.service.js.map +1 -0
- package/dist/services/admin-system-prompt.d.ts +2 -0
- package/dist/services/admin-system-prompt.d.ts.map +1 -0
- package/dist/services/admin-system-prompt.js +44 -0
- package/dist/services/admin-system-prompt.js.map +1 -0
- package/dist/services/admin-tools/admin-collection-tools.d.ts +15 -0
- package/dist/services/admin-tools/admin-collection-tools.d.ts.map +1 -0
- package/dist/services/admin-tools/admin-collection-tools.js +48 -0
- package/dist/services/admin-tools/admin-collection-tools.js.map +1 -0
- package/dist/services/admin-tools/admin-customer-tools.d.ts +15 -0
- package/dist/services/admin-tools/admin-customer-tools.d.ts.map +1 -0
- package/dist/services/admin-tools/admin-customer-tools.js +56 -0
- package/dist/services/admin-tools/admin-customer-tools.js.map +1 -0
- package/dist/services/admin-tools/admin-order-tools.d.ts +16 -0
- package/dist/services/admin-tools/admin-order-tools.d.ts.map +1 -0
- package/dist/services/admin-tools/admin-order-tools.js +69 -0
- package/dist/services/admin-tools/admin-order-tools.js.map +1 -0
- package/dist/services/admin-tools/admin-product-tools.d.ts +29 -0
- package/dist/services/admin-tools/admin-product-tools.d.ts.map +1 -0
- package/dist/services/admin-tools/admin-product-tools.js +139 -0
- package/dist/services/admin-tools/admin-product-tools.js.map +1 -0
- package/dist/services/ai-chat.service.d.ts +42 -0
- package/dist/services/ai-chat.service.d.ts.map +1 -0
- package/dist/services/ai-chat.service.js +308 -0
- package/dist/services/ai-chat.service.js.map +1 -0
- package/dist/services/chat-result-mapper.d.ts +17 -0
- package/dist/services/chat-result-mapper.d.ts.map +1 -0
- package/dist/services/chat-result-mapper.js +176 -0
- package/dist/services/chat-result-mapper.js.map +1 -0
- package/dist/services/collection-embedding.service.d.ts +14 -0
- package/dist/services/collection-embedding.service.d.ts.map +1 -0
- package/dist/services/collection-embedding.service.js +67 -0
- package/dist/services/collection-embedding.service.js.map +1 -0
- package/dist/services/conversation-cache.service.d.ts +47 -0
- package/dist/services/conversation-cache.service.d.ts.map +1 -0
- package/dist/services/conversation-cache.service.js +87 -0
- package/dist/services/conversation-cache.service.js.map +1 -0
- package/dist/services/embed-all-job.service.d.ts +28 -0
- package/dist/services/embed-all-job.service.d.ts.map +1 -0
- package/dist/services/embed-all-job.service.js +151 -0
- package/dist/services/embed-all-job.service.js.map +1 -0
- package/dist/services/embedding.service.d.ts +21 -0
- package/dist/services/embedding.service.d.ts.map +1 -0
- package/dist/services/embedding.service.js +58 -0
- package/dist/services/embedding.service.js.map +1 -0
- package/dist/services/product-embedding.service.d.ts +19 -0
- package/dist/services/product-embedding.service.d.ts.map +1 -0
- package/dist/services/product-embedding.service.js +78 -0
- package/dist/services/product-embedding.service.js.map +1 -0
- package/dist/services/system-prompt.d.ts +2 -0
- package/dist/services/system-prompt.d.ts.map +1 -0
- package/dist/services/system-prompt.js +107 -0
- package/dist/services/system-prompt.js.map +1 -0
- package/dist/services/tools/cart-tools.d.ts +14 -0
- package/dist/services/tools/cart-tools.d.ts.map +1 -0
- package/dist/services/tools/cart-tools.js +168 -0
- package/dist/services/tools/cart-tools.js.map +1 -0
- package/dist/services/tools/checkout-tools.d.ts +37 -0
- package/dist/services/tools/checkout-tools.d.ts.map +1 -0
- package/dist/services/tools/checkout-tools.js +228 -0
- package/dist/services/tools/checkout-tools.js.map +1 -0
- package/dist/services/tools/order-tools.d.ts +15 -0
- package/dist/services/tools/order-tools.d.ts.map +1 -0
- package/dist/services/tools/order-tools.js +105 -0
- package/dist/services/tools/order-tools.js.map +1 -0
- package/dist/services/tools/search-tools.d.ts +21 -0
- package/dist/services/tools/search-tools.d.ts.map +1 -0
- package/dist/services/tools/search-tools.js +214 -0
- package/dist/services/tools/search-tools.js.map +1 -0
- package/dist/services/types.d.ts +118 -0
- package/dist/services/types.d.ts.map +1 -0
- package/dist/services/types.js +3 -0
- package/dist/services/types.js.map +1 -0
- package/dist/services/variant-embedding.service.d.ts +14 -0
- package/dist/services/variant-embedding.service.d.ts.map +1 -0
- package/dist/services/variant-embedding.service.js +59 -0
- package/dist/services/variant-embedding.service.js.map +1 -0
- package/package.json +57 -0
package/README.md
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# @rahul_vendure/ai-chat-plugin
|
|
2
|
+
|
|
3
|
+
AI-powered shopping assistant plugin for [Vendure](https://www.vendure.io/) e-commerce. Adds an LLM-driven chat endpoint to your Vendure server with product search, vector search, cart management, order tracking, and checkout assistance.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **LLM Chat** — GPT-4o-mini powered shopping assistant via Vercel AI SDK
|
|
8
|
+
- **14 Built-in Tools** — search, vector search, collections, price filter, add-to-cart, cart view/adjust, order history/tracking, checkout (addresses, shipping)
|
|
9
|
+
- **Streaming** — Real-time streaming responses via `POST /ai-assistant/stream` (compatible with `useChat()` from `@ai-sdk/react`)
|
|
10
|
+
- **Non-streaming** — JSON response via `POST /ai-assistant/chat`
|
|
11
|
+
- **Vector Search** — pgvector-powered semantic search over products and collections
|
|
12
|
+
- **Auto-Embedding** — Automatic embedding generation on product/variant/collection create/update/delete
|
|
13
|
+
- **Bulk Embedding** — Admin GraphQL mutation `triggerEmbedAll` to embed all existing catalog data
|
|
14
|
+
- **Self-Managing Schema** — Automatically creates pgvector extension and embedding columns
|
|
15
|
+
|
|
16
|
+
## Requirements
|
|
17
|
+
|
|
18
|
+
- Vendure `>=3.0.0`
|
|
19
|
+
- PostgreSQL with [pgvector](https://github.com/pgvector/pgvector) extension
|
|
20
|
+
- OpenAI API key
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install @rahul_vendure/ai-chat-plugin
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Setup
|
|
29
|
+
|
|
30
|
+
### 1. Add the plugin to your Vendure config
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
// vendure-config.ts
|
|
34
|
+
import { AiAssistantPlugin } from '@rahul_vendure/ai-chat-plugin';
|
|
35
|
+
|
|
36
|
+
export const config: VendureConfig = {
|
|
37
|
+
// CORS — allow your storefront origin so the browser can call /ai-assistant/stream directly
|
|
38
|
+
apiOptions: {
|
|
39
|
+
cors: {
|
|
40
|
+
origin: ['http://localhost:3001', 'https://my-storefront.com'],
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
plugins: [
|
|
44
|
+
// ... other plugins
|
|
45
|
+
AiAssistantPlugin.init({
|
|
46
|
+
openaiApiKey: process.env.OPENAI_API_KEY!,
|
|
47
|
+
embeddingModel: 'text-embedding-3-small', // optional, this is the default
|
|
48
|
+
assetBaseUrl: 'https://my-vendure.com/assets/', // optional, auto-detected in dev
|
|
49
|
+
}),
|
|
50
|
+
],
|
|
51
|
+
};
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 2. Embed your catalog
|
|
55
|
+
|
|
56
|
+
After starting the server, run the `triggerEmbedAll` mutation from the Admin API (GraphiQL at `/admin-api`):
|
|
57
|
+
|
|
58
|
+
```graphql
|
|
59
|
+
mutation {
|
|
60
|
+
triggerEmbedAll {
|
|
61
|
+
jobId
|
|
62
|
+
message
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
This generates vector embeddings for all products, variants, and collections in the background. You only need to run this once — after that, embeddings are automatically kept in sync on create/update/delete.
|
|
68
|
+
|
|
69
|
+
### 3. Add the frontend
|
|
70
|
+
|
|
71
|
+
Use the companion package [`@rahul_vendure/ai-chat-react`](../ai-chat-react) for a drop-in React chat UI:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npm install @rahul_vendure/ai-chat-react ai @ai-sdk/react
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
<VendureAiChat vendureUrl="https://my-vendure.com" />
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
See the [`@rahul_vendure/ai-chat-react` README](../ai-chat-react) for full docs.
|
|
82
|
+
|
|
83
|
+
## Configuration Options
|
|
84
|
+
|
|
85
|
+
| Option | Type | Required | Default | Description |
|
|
86
|
+
|--------|------|----------|---------|-------------|
|
|
87
|
+
| `openaiApiKey` | `string` | Yes | — | Your OpenAI API key |
|
|
88
|
+
| `embeddingModel` | `string` | No | `'text-embedding-3-small'` | OpenAI embedding model to use |
|
|
89
|
+
| `assetBaseUrl` | `string` | No | Auto-detected | Base URL for product images (e.g. `https://my-vendure.com/assets/`) |
|
|
90
|
+
|
|
91
|
+
## API Endpoints
|
|
92
|
+
|
|
93
|
+
### `POST /ai-assistant/stream`
|
|
94
|
+
|
|
95
|
+
Streaming endpoint compatible with the Vercel AI SDK `useChat()` hook. Returns a [UI Message Stream](https://sdk.vercel.ai/docs/ai-sdk-ui/stream-protocol#ui-message-stream-protocol) response.
|
|
96
|
+
|
|
97
|
+
The `@rahul_vendure/ai-chat-react` package connects to this endpoint automatically — you don't need to call it manually.
|
|
98
|
+
|
|
99
|
+
**Request:**
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"message": "Show me laptops under $1000",
|
|
103
|
+
"history": [
|
|
104
|
+
{ "role": "user", "content": "Hi" },
|
|
105
|
+
{ "role": "assistant", "content": "Hello! How can I help?" }
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Auth:** Pass a Bearer token in the `Authorization` header for logged-in user features (cart, orders).
|
|
111
|
+
|
|
112
|
+
### `POST /ai-assistant/chat`
|
|
113
|
+
|
|
114
|
+
Non-streaming endpoint. Returns the full response as JSON after all tool calls complete.
|
|
115
|
+
|
|
116
|
+
**Response:**
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"message": "Here are some laptops I found!",
|
|
120
|
+
"products": [
|
|
121
|
+
{ "id": "1", "name": "Gaming Laptop", "slug": "gaming-laptop", "price": 89900, "image": "https://...", "variantId": "42" }
|
|
122
|
+
],
|
|
123
|
+
"collections": [],
|
|
124
|
+
"addToCartAction": null,
|
|
125
|
+
"activeOrder": null
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## CORS
|
|
130
|
+
|
|
131
|
+
The React frontend connects **directly** to the Vendure server from the browser (no proxy needed). You must configure CORS to allow your storefront origin:
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
export const config: VendureConfig = {
|
|
135
|
+
apiOptions: {
|
|
136
|
+
cors: {
|
|
137
|
+
origin: ['https://my-storefront.com'],
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
> In development, Vendure allows all origins by default, so no CORS config is needed for `localhost`.
|
|
144
|
+
|
|
145
|
+
## Tools
|
|
146
|
+
|
|
147
|
+
The AI assistant has 14 built-in tools:
|
|
148
|
+
|
|
149
|
+
| Tool | Description |
|
|
150
|
+
|------|-------------|
|
|
151
|
+
| `searchProducts` | Keyword search using Vendure's fulltext search index |
|
|
152
|
+
| `vectorSearch` | Semantic/intent-based search using pgvector embeddings |
|
|
153
|
+
| `getCollections` | List product collections/categories |
|
|
154
|
+
| `filterByPrice` | Filter products by price range |
|
|
155
|
+
| `addToCart` | Add a product variant to the customer's cart |
|
|
156
|
+
| `getActiveOrder` | Get the current cart with all line items |
|
|
157
|
+
| `adjustOrderLine` | Change quantity or remove items from cart |
|
|
158
|
+
| `getOrderHistory` | List past orders for the customer |
|
|
159
|
+
| `trackOrder` | Get order status and tracking information |
|
|
160
|
+
| `getAvailableCountries` | List countries for shipping/billing |
|
|
161
|
+
| `getEligibleShippingMethods` | Get shipping options for active order |
|
|
162
|
+
| `setShippingAddress` | Set shipping address on active order |
|
|
163
|
+
| `setBillingAddress` | Set billing address on active order |
|
|
164
|
+
| `setShippingMethod` | Set shipping method on active order |
|
|
165
|
+
|
|
166
|
+
## Entities
|
|
167
|
+
|
|
168
|
+
The plugin adds three entities to your database:
|
|
169
|
+
|
|
170
|
+
- `product_embedding` — Vector embeddings for products
|
|
171
|
+
- `variant_embedding` — Vector embeddings for product variants
|
|
172
|
+
- `collection_embedding` — Vector embeddings for collections
|
|
173
|
+
|
|
174
|
+
These are automatically managed. The plugin creates the pgvector extension and embedding columns on startup.
|
|
175
|
+
|
|
176
|
+
## Admin Dashboard AI Chat
|
|
177
|
+
|
|
178
|
+
The plugin also includes a built-in admin chat endpoint at `POST /admin-ai-chat/chat` with admin-specific tools:
|
|
179
|
+
|
|
180
|
+
| Tool | Description |
|
|
181
|
+
|------|-------------|
|
|
182
|
+
| `searchProducts` | Keyword search with admin details (stock levels, enabled status, variant count) |
|
|
183
|
+
| `vectorSearch` | Semantic search for products by intent |
|
|
184
|
+
| `getProductDetails` | Full product details with all variants, SKUs, stock |
|
|
185
|
+
| `searchOrders` | Search orders by code, customer, or state |
|
|
186
|
+
| `searchCustomers` | Search customers by name/email with order stats |
|
|
187
|
+
| `getCollections` | List/search collections with product counts |
|
|
188
|
+
|
|
189
|
+
To add the admin chat UI to your Vendure dashboard, install the companion package:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
npm install @rahul_vendure/ai-chat-dashboard
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
See the [`@rahul_vendure/ai-chat-dashboard` README](https://www.npmjs.com/package/@rahul_vendure/ai-chat-dashboard) for setup instructions.
|
|
196
|
+
|
|
197
|
+
## Exported Services
|
|
198
|
+
|
|
199
|
+
For advanced use cases, you can inject these services in your own plugins:
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
import {
|
|
203
|
+
AiChatService, // Storefront chat service
|
|
204
|
+
AdminAiChatService, // Admin dashboard chat service
|
|
205
|
+
EmbeddingService,
|
|
206
|
+
ProductEmbeddingService,
|
|
207
|
+
VariantEmbeddingService,
|
|
208
|
+
CollectionEmbeddingService,
|
|
209
|
+
} from '@rahul_vendure/ai-chat-plugin';
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## License
|
|
213
|
+
|
|
214
|
+
MIT
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { OnApplicationBootstrap } from '@nestjs/common';
|
|
2
|
+
import { EventBus } from '@vendure/core';
|
|
3
|
+
import { ProductEmbeddingHandler } from './handlers/product-embedding-handler';
|
|
4
|
+
import { VariantEmbeddingHandler } from './handlers/variant-embedding-handler';
|
|
5
|
+
import { CollectionEmbeddingHandler } from './handlers/collection-embedding-handler';
|
|
6
|
+
import { type AiAssistantPluginOptions } from './constants';
|
|
7
|
+
export type { AiAssistantPluginOptions } from './constants';
|
|
8
|
+
export declare class AiAssistantPlugin implements OnApplicationBootstrap {
|
|
9
|
+
private eventBus;
|
|
10
|
+
private productHandler;
|
|
11
|
+
private variantHandler;
|
|
12
|
+
private collectionHandler;
|
|
13
|
+
static options: AiAssistantPluginOptions;
|
|
14
|
+
static init(options: AiAssistantPluginOptions): typeof AiAssistantPlugin;
|
|
15
|
+
constructor(eventBus: EventBus, productHandler: ProductEmbeddingHandler, variantHandler: VariantEmbeddingHandler, collectionHandler: CollectionEmbeddingHandler);
|
|
16
|
+
onApplicationBootstrap(): void;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=ai-assistant.plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-assistant.plugin.d.ts","sourceRoot":"","sources":["../src/ai-assistant.plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAqC,MAAM,eAAe,CAAC;AAU5E,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAC/E,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAC/E,OAAO,EAAE,0BAA0B,EAAE,MAAM,yCAAyC,CAAC;AAMrF,OAAO,EAAwB,KAAK,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAGlF,YAAY,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAO5D,qBAwBa,iBAAkB,YAAW,sBAAsB;IASxD,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,iBAAiB;IAX7B,MAAM,CAAC,OAAO,EAAE,wBAAwB,CAAC;IAEzC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,iBAAiB;gBAM5D,QAAQ,EAAE,QAAQ,EAClB,cAAc,EAAE,uBAAuB,EACvC,cAAc,EAAE,uBAAuB,EACvC,iBAAiB,EAAE,0BAA0B;IAGzD,sBAAsB;CAKzB"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var AiAssistantPlugin_1;
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.AiAssistantPlugin = void 0;
|
|
14
|
+
const core_1 = require("@vendure/core");
|
|
15
|
+
const product_embedding_entity_1 = require("./entities/product-embedding.entity");
|
|
16
|
+
const variant_embedding_entity_1 = require("./entities/variant-embedding.entity");
|
|
17
|
+
const collection_embedding_entity_1 = require("./entities/collection-embedding.entity");
|
|
18
|
+
const embedding_service_1 = require("./services/embedding.service");
|
|
19
|
+
const product_embedding_service_1 = require("./services/product-embedding.service");
|
|
20
|
+
const variant_embedding_service_1 = require("./services/variant-embedding.service");
|
|
21
|
+
const collection_embedding_service_1 = require("./services/collection-embedding.service");
|
|
22
|
+
const ai_chat_service_1 = require("./services/ai-chat.service");
|
|
23
|
+
const conversation_cache_service_1 = require("./services/conversation-cache.service");
|
|
24
|
+
const product_embedding_handler_1 = require("./handlers/product-embedding-handler");
|
|
25
|
+
const variant_embedding_handler_1 = require("./handlers/variant-embedding-handler");
|
|
26
|
+
const collection_embedding_handler_1 = require("./handlers/collection-embedding-handler");
|
|
27
|
+
const embed_all_job_service_1 = require("./services/embed-all-job.service");
|
|
28
|
+
const ai_assistant_resolver_1 = require("./api/ai-assistant.resolver");
|
|
29
|
+
const ai_assistant_controller_1 = require("./controllers/ai-assistant.controller");
|
|
30
|
+
const admin_chat_controller_1 = require("./controllers/admin-chat.controller");
|
|
31
|
+
const admin_ai_chat_service_1 = require("./services/admin-ai-chat.service");
|
|
32
|
+
const constants_1 = require("./constants");
|
|
33
|
+
const schema_extensions_1 = require("./api/schema-extensions");
|
|
34
|
+
const defaultOptions = {
|
|
35
|
+
embeddingModel: 'text-embedding-3-small',
|
|
36
|
+
enableConversationCache: true,
|
|
37
|
+
};
|
|
38
|
+
let AiAssistantPlugin = AiAssistantPlugin_1 = class AiAssistantPlugin {
|
|
39
|
+
static init(options) {
|
|
40
|
+
this.options = { ...defaultOptions, ...options };
|
|
41
|
+
return AiAssistantPlugin_1;
|
|
42
|
+
}
|
|
43
|
+
constructor(eventBus, productHandler, variantHandler, collectionHandler) {
|
|
44
|
+
this.eventBus = eventBus;
|
|
45
|
+
this.productHandler = productHandler;
|
|
46
|
+
this.variantHandler = variantHandler;
|
|
47
|
+
this.collectionHandler = collectionHandler;
|
|
48
|
+
}
|
|
49
|
+
onApplicationBootstrap() {
|
|
50
|
+
void this.productHandler;
|
|
51
|
+
void this.variantHandler;
|
|
52
|
+
void this.collectionHandler;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
exports.AiAssistantPlugin = AiAssistantPlugin;
|
|
56
|
+
exports.AiAssistantPlugin = AiAssistantPlugin = AiAssistantPlugin_1 = __decorate([
|
|
57
|
+
(0, core_1.VendurePlugin)({
|
|
58
|
+
imports: [core_1.PluginCommonModule],
|
|
59
|
+
entities: [product_embedding_entity_1.ProductEmbedding, variant_embedding_entity_1.VariantEmbedding, collection_embedding_entity_1.CollectionEmbedding],
|
|
60
|
+
adminApiExtensions: {
|
|
61
|
+
schema: () => schema_extensions_1.embedAllSchemaExtension,
|
|
62
|
+
resolvers: [ai_assistant_resolver_1.AiAssistantResolver],
|
|
63
|
+
},
|
|
64
|
+
controllers: [ai_assistant_controller_1.AiAssistantController, admin_chat_controller_1.AdminChatController],
|
|
65
|
+
providers: [
|
|
66
|
+
{ provide: constants_1.AI_ASSISTANT_OPTIONS, useFactory: () => AiAssistantPlugin.options },
|
|
67
|
+
embedding_service_1.EmbeddingService,
|
|
68
|
+
product_embedding_service_1.ProductEmbeddingService,
|
|
69
|
+
variant_embedding_service_1.VariantEmbeddingService,
|
|
70
|
+
collection_embedding_service_1.CollectionEmbeddingService,
|
|
71
|
+
ai_chat_service_1.AiChatService,
|
|
72
|
+
admin_ai_chat_service_1.AdminAiChatService,
|
|
73
|
+
conversation_cache_service_1.ConversationCacheService,
|
|
74
|
+
product_embedding_handler_1.ProductEmbeddingHandler,
|
|
75
|
+
variant_embedding_handler_1.VariantEmbeddingHandler,
|
|
76
|
+
collection_embedding_handler_1.CollectionEmbeddingHandler,
|
|
77
|
+
embed_all_job_service_1.EmbedAllJobService,
|
|
78
|
+
],
|
|
79
|
+
compatibility: '^3.0.0',
|
|
80
|
+
}),
|
|
81
|
+
__metadata("design:paramtypes", [core_1.EventBus,
|
|
82
|
+
product_embedding_handler_1.ProductEmbeddingHandler,
|
|
83
|
+
variant_embedding_handler_1.VariantEmbeddingHandler,
|
|
84
|
+
collection_embedding_handler_1.CollectionEmbeddingHandler])
|
|
85
|
+
], AiAssistantPlugin);
|
|
86
|
+
//# sourceMappingURL=ai-assistant.plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-assistant.plugin.js","sourceRoot":"","sources":["../src/ai-assistant.plugin.ts"],"names":[],"mappings":";;;;;;;;;;;;;AACA,wCAA4E;AAC5E,kFAAuE;AACvE,kFAAuE;AACvE,wFAA6E;AAC7E,oEAAgE;AAChE,oFAA+E;AAC/E,oFAA+E;AAC/E,0FAAqF;AACrF,gEAA2D;AAC3D,sFAAiF;AACjF,oFAA+E;AAC/E,oFAA+E;AAC/E,0FAAqF;AACrF,4EAAsE;AACtE,uEAAkE;AAClE,mFAA8E;AAC9E,+EAA0E;AAC1E,4EAAsE;AACtE,2CAAkF;AAClF,+DAAkE;AAIlE,MAAM,cAAc,GAA2F;IAC3G,cAAc,EAAE,wBAAwB;IACxC,uBAAuB,EAAE,IAAI;CAChC,CAAC;AA0BK,IAAM,iBAAiB,yBAAvB,MAAM,iBAAiB;IAG1B,MAAM,CAAC,IAAI,CAAC,OAAiC;QACzC,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,OAAO,EAAE,CAAC;QACjD,OAAO,mBAAiB,CAAC;IAC7B,CAAC;IAED,YACY,QAAkB,EAClB,cAAuC,EACvC,cAAuC,EACvC,iBAA6C;QAH7C,aAAQ,GAAR,QAAQ,CAAU;QAClB,mBAAc,GAAd,cAAc,CAAyB;QACvC,mBAAc,GAAd,cAAc,CAAyB;QACvC,sBAAiB,GAAjB,iBAAiB,CAA4B;IACtD,CAAC;IAEJ,sBAAsB;QAClB,KAAK,IAAI,CAAC,cAAc,CAAC;QACzB,KAAK,IAAI,CAAC,cAAc,CAAC;QACzB,KAAK,IAAI,CAAC,iBAAiB,CAAC;IAChC,CAAC;CACJ,CAAA;AApBY,8CAAiB;4BAAjB,iBAAiB;IAxB7B,IAAA,oBAAa,EAAC;QACX,OAAO,EAAE,CAAC,yBAAkB,CAAC;QAC7B,QAAQ,EAAE,CAAC,2CAAgB,EAAE,2CAAgB,EAAE,iDAAmB,CAAC;QACnE,kBAAkB,EAAE;YAChB,MAAM,EAAE,GAAG,EAAE,CAAC,2CAAuB;YACrC,SAAS,EAAE,CAAC,2CAAmB,CAAC;SACnC;QACD,WAAW,EAAE,CAAC,+CAAqB,EAAE,2CAAmB,CAAC;QACzD,SAAS,EAAE;YACP,EAAE,OAAO,EAAE,gCAAoB,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,OAAO,EAAE;YAC9E,oCAAgB;YAChB,mDAAuB;YACvB,mDAAuB;YACvB,yDAA0B;YAC1B,+BAAa;YACb,0CAAkB;YAClB,qDAAwB;YACxB,mDAAuB;YACvB,mDAAuB;YACvB,yDAA0B;YAC1B,0CAAkB;SACrB;QACD,aAAa,EAAE,QAAQ;KAC1B,CAAC;qCAUwB,eAAQ;QACF,mDAAuB;QACvB,mDAAuB;QACpB,yDAA0B;GAZhD,iBAAiB,CAoB7B"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { RequestContext } from '@vendure/core';
|
|
2
|
+
import { EmbedAllJobService } from '../services/embed-all-job.service';
|
|
3
|
+
export declare class AiAssistantResolver {
|
|
4
|
+
private embedAllJobService;
|
|
5
|
+
constructor(embedAllJobService: EmbedAllJobService);
|
|
6
|
+
triggerEmbedAll(ctx: RequestContext): Promise<{
|
|
7
|
+
jobId: string;
|
|
8
|
+
message: string;
|
|
9
|
+
}>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=ai-assistant.resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-assistant.resolver.d.ts","sourceRoot":"","sources":["../../src/api/ai-assistant.resolver.ts"],"names":[],"mappings":"AACA,OAAO,EAAO,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAEvE,qBACa,mBAAmB;IAChB,OAAO,CAAC,kBAAkB;gBAAlB,kBAAkB,EAAE,kBAAkB;IAGpD,eAAe,CAAQ,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC;QACvD,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;KACnB,CAAC;CAQL"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.AiAssistantResolver = void 0;
|
|
16
|
+
const graphql_1 = require("@nestjs/graphql");
|
|
17
|
+
const core_1 = require("@vendure/core");
|
|
18
|
+
const embed_all_job_service_1 = require("../services/embed-all-job.service");
|
|
19
|
+
let AiAssistantResolver = class AiAssistantResolver {
|
|
20
|
+
constructor(embedAllJobService) {
|
|
21
|
+
this.embedAllJobService = embedAllJobService;
|
|
22
|
+
}
|
|
23
|
+
async triggerEmbedAll(ctx) {
|
|
24
|
+
const { jobId } = await this.embedAllJobService.enqueue();
|
|
25
|
+
return {
|
|
26
|
+
jobId,
|
|
27
|
+
message: 'Embed-all job enqueued. Products, variants, and collections will be embedded in the background.',
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
exports.AiAssistantResolver = AiAssistantResolver;
|
|
32
|
+
__decorate([
|
|
33
|
+
(0, graphql_1.Mutation)(),
|
|
34
|
+
__param(0, (0, core_1.Ctx)()),
|
|
35
|
+
__metadata("design:type", Function),
|
|
36
|
+
__metadata("design:paramtypes", [core_1.RequestContext]),
|
|
37
|
+
__metadata("design:returntype", Promise)
|
|
38
|
+
], AiAssistantResolver.prototype, "triggerEmbedAll", null);
|
|
39
|
+
exports.AiAssistantResolver = AiAssistantResolver = __decorate([
|
|
40
|
+
(0, graphql_1.Resolver)(),
|
|
41
|
+
__metadata("design:paramtypes", [embed_all_job_service_1.EmbedAllJobService])
|
|
42
|
+
], AiAssistantResolver);
|
|
43
|
+
//# sourceMappingURL=ai-assistant.resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-assistant.resolver.js","sourceRoot":"","sources":["../../src/api/ai-assistant.resolver.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,6CAAqD;AACrD,wCAAoD;AACpD,6EAAuE;AAGhE,IAAM,mBAAmB,GAAzB,MAAM,mBAAmB;IAC5B,YAAoB,kBAAsC;QAAtC,uBAAkB,GAAlB,kBAAkB,CAAoB;IAAG,CAAC;IAGxD,AAAN,KAAK,CAAC,eAAe,CAAQ,GAAmB;QAI5C,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,CAAC;QAC1D,OAAO;YACH,KAAK;YACL,OAAO,EACH,iGAAiG;SACxG,CAAC;IACN,CAAC;CACJ,CAAA;AAfY,kDAAmB;AAItB;IADL,IAAA,kBAAQ,GAAE;IACY,WAAA,IAAA,UAAG,GAAE,CAAA;;qCAAM,qBAAc;;0DAU/C;8BAdQ,mBAAmB;IAD/B,IAAA,kBAAQ,GAAE;qCAEiC,0CAAkB;GADjD,mBAAmB,CAe/B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-extensions.d.ts","sourceRoot":"","sources":["../../src/api/schema-extensions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,eAAO,MAAM,uBAAuB,EAAE,YASpC,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.embedAllSchemaExtension = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
exports.embedAllSchemaExtension = (0, graphql_1.parse)(`
|
|
6
|
+
type EmbedAllResult {
|
|
7
|
+
jobId: ID!
|
|
8
|
+
message: String!
|
|
9
|
+
}
|
|
10
|
+
extend type Mutation {
|
|
11
|
+
"""Enqueue a background job to embed all products, variants, and collections."""
|
|
12
|
+
triggerEmbedAll: EmbedAllResult!
|
|
13
|
+
}
|
|
14
|
+
`);
|
|
15
|
+
//# sourceMappingURL=schema-extensions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-extensions.js","sourceRoot":"","sources":["../../src/api/schema-extensions.ts"],"names":[],"mappings":";;;AAAA,qCAAgC;AAGnB,QAAA,uBAAuB,GAAiB,IAAA,eAAK,EAAC;;;;;;;;;CAS1D,CAAC,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export declare const AI_ASSISTANT_OPTIONS: unique symbol;
|
|
2
|
+
export declare const EMBEDDING_DIMENSIONS = 1536;
|
|
3
|
+
export declare const EMBED_ALL_QUEUE_NAME = "embed-all";
|
|
4
|
+
/** Min cosine similarity (1 - distance) to consider a product relevant. Lower = more results (e.g. short queries like "laptops"). */
|
|
5
|
+
export declare const SIMILARITY_THRESHOLD = 0.28;
|
|
6
|
+
/** When first pass returns 0, we fallback to top-N without threshold. Only use fallback if best score >= this (avoids returning irrelevant results e.g. "private jets"). */
|
|
7
|
+
export declare const FALLBACK_MIN_SCORE = 0.25;
|
|
8
|
+
/** Max number of products to return in chat; only those above SIMILARITY_THRESHOLD are included. */
|
|
9
|
+
export declare const MAX_CHAT_PRODUCTS = 5;
|
|
10
|
+
/** Max number of Vendure collections to return in chat (e.g. "electronics", "sports"). */
|
|
11
|
+
export declare const MAX_CHAT_COLLECTIONS = 3;
|
|
12
|
+
/**
|
|
13
|
+
* Format a price in the smallest currency unit (cents) to a human-readable dollar string.
|
|
14
|
+
* Used in tool result summaries so the LLM sees formatted prices (e.g. "$42.63")
|
|
15
|
+
* instead of raw cent values that it might misinterpret.
|
|
16
|
+
*/
|
|
17
|
+
export declare function formatPrice(cents: number): string;
|
|
18
|
+
export interface AiAssistantPluginOptions {
|
|
19
|
+
openaiApiKey: string;
|
|
20
|
+
embeddingModel?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Base URL for product asset images. Should match your AssetServerPlugin's
|
|
23
|
+
* public URL including the route, e.g. "https://my-vendure.com/assets/".
|
|
24
|
+
* If not set, will be auto-detected from apiOptions (works for dev).
|
|
25
|
+
*/
|
|
26
|
+
assetBaseUrl?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Whether to cache conversation history server-side using Vendure's CacheService.
|
|
29
|
+
*
|
|
30
|
+
* When enabled, the frontend sends a `conversationId` with each request and the
|
|
31
|
+
* server stores/retrieves conversation history from cache instead of requiring
|
|
32
|
+
* the full message array in every request.
|
|
33
|
+
*
|
|
34
|
+
* Requires `DefaultCachePlugin` or `RedisCachePlugin` to be configured for
|
|
35
|
+
* persistence across server restarts. Falls back to in-memory cache otherwise.
|
|
36
|
+
*
|
|
37
|
+
* @default true
|
|
38
|
+
*/
|
|
39
|
+
enableConversationCache?: boolean;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,eAAiC,CAAC;AACnE,eAAO,MAAM,oBAAoB,OAAO,CAAC;AACzC,eAAO,MAAM,oBAAoB,cAAc,CAAC;AAEhD,qIAAqI;AACrI,eAAO,MAAM,oBAAoB,OAAO,CAAC;AACzC,4KAA4K;AAC5K,eAAO,MAAM,kBAAkB,OAAO,CAAC;AACvC,oGAAoG;AACpG,eAAO,MAAM,iBAAiB,IAAI,CAAC;AACnC,0FAA0F;AAC1F,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAEtC;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,MAAM,WAAW,wBAAwB;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;;;;;OAWG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACrC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MAX_CHAT_COLLECTIONS = exports.MAX_CHAT_PRODUCTS = exports.FALLBACK_MIN_SCORE = exports.SIMILARITY_THRESHOLD = exports.EMBED_ALL_QUEUE_NAME = exports.EMBEDDING_DIMENSIONS = exports.AI_ASSISTANT_OPTIONS = void 0;
|
|
4
|
+
exports.formatPrice = formatPrice;
|
|
5
|
+
exports.AI_ASSISTANT_OPTIONS = Symbol('AI_ASSISTANT_OPTIONS');
|
|
6
|
+
exports.EMBEDDING_DIMENSIONS = 1536; // text-embedding-3-small
|
|
7
|
+
exports.EMBED_ALL_QUEUE_NAME = 'embed-all';
|
|
8
|
+
/** Min cosine similarity (1 - distance) to consider a product relevant. Lower = more results (e.g. short queries like "laptops"). */
|
|
9
|
+
exports.SIMILARITY_THRESHOLD = 0.28;
|
|
10
|
+
/** When first pass returns 0, we fallback to top-N without threshold. Only use fallback if best score >= this (avoids returning irrelevant results e.g. "private jets"). */
|
|
11
|
+
exports.FALLBACK_MIN_SCORE = 0.25;
|
|
12
|
+
/** Max number of products to return in chat; only those above SIMILARITY_THRESHOLD are included. */
|
|
13
|
+
exports.MAX_CHAT_PRODUCTS = 5;
|
|
14
|
+
/** Max number of Vendure collections to return in chat (e.g. "electronics", "sports"). */
|
|
15
|
+
exports.MAX_CHAT_COLLECTIONS = 3;
|
|
16
|
+
/**
|
|
17
|
+
* Format a price in the smallest currency unit (cents) to a human-readable dollar string.
|
|
18
|
+
* Used in tool result summaries so the LLM sees formatted prices (e.g. "$42.63")
|
|
19
|
+
* instead of raw cent values that it might misinterpret.
|
|
20
|
+
*/
|
|
21
|
+
function formatPrice(cents) {
|
|
22
|
+
return `$${(cents / 100).toFixed(2)}`;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAkBA,kCAEC;AApBY,QAAA,oBAAoB,GAAG,MAAM,CAAC,sBAAsB,CAAC,CAAC;AACtD,QAAA,oBAAoB,GAAG,IAAI,CAAC,CAAC,yBAAyB;AACtD,QAAA,oBAAoB,GAAG,WAAW,CAAC;AAEhD,qIAAqI;AACxH,QAAA,oBAAoB,GAAG,IAAI,CAAC;AACzC,4KAA4K;AAC/J,QAAA,kBAAkB,GAAG,IAAI,CAAC;AACvC,oGAAoG;AACvF,QAAA,iBAAiB,GAAG,CAAC,CAAC;AACnC,0FAA0F;AAC7E,QAAA,oBAAoB,GAAG,CAAC,CAAC;AAEtC;;;;GAIG;AACH,SAAgB,WAAW,CAAC,KAAa;IACrC,OAAO,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Request } from 'express';
|
|
2
|
+
import { RequestContextService, SessionService } from '@vendure/core';
|
|
3
|
+
import { AdminAiChatService, AdminChatResult } from '../services/admin-ai-chat.service';
|
|
4
|
+
export interface AdminChatRequest {
|
|
5
|
+
message: string;
|
|
6
|
+
history?: Array<{
|
|
7
|
+
role: 'user' | 'assistant';
|
|
8
|
+
content: string;
|
|
9
|
+
}>;
|
|
10
|
+
}
|
|
11
|
+
export interface AdminChatResponse extends AdminChatResult {
|
|
12
|
+
}
|
|
13
|
+
export declare class AdminChatController {
|
|
14
|
+
private adminAiChatService;
|
|
15
|
+
private requestContextService;
|
|
16
|
+
private sessionService;
|
|
17
|
+
private readonly logger;
|
|
18
|
+
constructor(adminAiChatService: AdminAiChatService, requestContextService: RequestContextService, sessionService: SessionService);
|
|
19
|
+
chat(body: AdminChatRequest, req: Request): Promise<AdminChatResponse>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=admin-chat.controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-chat.controller.d.ts","sourceRoot":"","sources":["../../src/controllers/admin-chat.controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAExF,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpE;AAED,MAAM,WAAW,iBAAkB,SAAQ,eAAe;CAAG;AAE7D,qBACa,mBAAmB;IAIxB,OAAO,CAAC,kBAAkB;IAC1B,OAAO,CAAC,qBAAqB;IAC7B,OAAO,CAAC,cAAc;IAL1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwC;gBAGnD,kBAAkB,EAAE,kBAAkB,EACtC,qBAAqB,EAAE,qBAAqB,EAC5C,cAAc,EAAE,cAAc;IAIpC,IAAI,CAAS,IAAI,EAAE,gBAAgB,EAAS,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAwB9F"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var AdminChatController_1;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.AdminChatController = void 0;
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const core_1 = require("@vendure/core");
|
|
19
|
+
const admin_ai_chat_service_1 = require("../services/admin-ai-chat.service");
|
|
20
|
+
let AdminChatController = AdminChatController_1 = class AdminChatController {
|
|
21
|
+
constructor(adminAiChatService, requestContextService, sessionService) {
|
|
22
|
+
this.adminAiChatService = adminAiChatService;
|
|
23
|
+
this.requestContextService = requestContextService;
|
|
24
|
+
this.sessionService = sessionService;
|
|
25
|
+
this.logger = new common_1.Logger(AdminChatController_1.name);
|
|
26
|
+
}
|
|
27
|
+
async chat(body, req) {
|
|
28
|
+
var _a, _b;
|
|
29
|
+
const authHeader = req.get('Authorization');
|
|
30
|
+
const tokenMatch = authHeader === null || authHeader === void 0 ? void 0 : authHeader.trim().match(/^bearer\s(.+)$/i);
|
|
31
|
+
const sessionToken = tokenMatch === null || tokenMatch === void 0 ? void 0 : tokenMatch[1];
|
|
32
|
+
let session;
|
|
33
|
+
if (sessionToken) {
|
|
34
|
+
session = await this.sessionService.getSessionFromToken(sessionToken);
|
|
35
|
+
}
|
|
36
|
+
const ctx = await this.requestContextService.fromRequest(req, undefined, undefined, session);
|
|
37
|
+
const message = ((_a = body.message) !== null && _a !== void 0 ? _a : '').trim();
|
|
38
|
+
const history = (_b = body.history) !== null && _b !== void 0 ? _b : [];
|
|
39
|
+
if (!message) {
|
|
40
|
+
return {
|
|
41
|
+
message: "Hi! I'm your store admin assistant. I can help you look up products, orders, customers, and collections. What would you like to know?",
|
|
42
|
+
products: [],
|
|
43
|
+
collections: [],
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return this.adminAiChatService.chat(ctx, message, history);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
exports.AdminChatController = AdminChatController;
|
|
50
|
+
__decorate([
|
|
51
|
+
(0, common_1.Post)('chat'),
|
|
52
|
+
__param(0, (0, common_1.Body)()),
|
|
53
|
+
__param(1, (0, common_1.Req)()),
|
|
54
|
+
__metadata("design:type", Function),
|
|
55
|
+
__metadata("design:paramtypes", [Object, Object]),
|
|
56
|
+
__metadata("design:returntype", Promise)
|
|
57
|
+
], AdminChatController.prototype, "chat", null);
|
|
58
|
+
exports.AdminChatController = AdminChatController = AdminChatController_1 = __decorate([
|
|
59
|
+
(0, common_1.Controller)('admin-ai-chat'),
|
|
60
|
+
__metadata("design:paramtypes", [admin_ai_chat_service_1.AdminAiChatService,
|
|
61
|
+
core_1.RequestContextService,
|
|
62
|
+
core_1.SessionService])
|
|
63
|
+
], AdminChatController);
|
|
64
|
+
//# sourceMappingURL=admin-chat.controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-chat.controller.js","sourceRoot":"","sources":["../../src/controllers/admin-chat.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAqE;AAErE,wCAAsE;AACtE,6EAAwF;AAUjF,IAAM,mBAAmB,2BAAzB,MAAM,mBAAmB;IAG5B,YACY,kBAAsC,EACtC,qBAA4C,EAC5C,cAA8B;QAF9B,uBAAkB,GAAlB,kBAAkB,CAAoB;QACtC,0BAAqB,GAArB,qBAAqB,CAAuB;QAC5C,mBAAc,GAAd,cAAc,CAAgB;QALzB,WAAM,GAAG,IAAI,eAAM,CAAC,qBAAmB,CAAC,IAAI,CAAC,CAAC;IAM5D,CAAC;IAGE,AAAN,KAAK,CAAC,IAAI,CAAS,IAAsB,EAAS,GAAY;;QAC1D,MAAM,UAAU,GAAG,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAC5C,MAAM,UAAU,GAAG,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,IAAI,GAAG,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAC/D,MAAM,YAAY,GAAG,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAG,CAAC,CAAC,CAAC;QAErC,IAAI,OAAO,CAAC;QACZ,IAAI,YAAY,EAAE,CAAC;YACf,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,mBAAmB,CAAC,YAAY,CAAC,CAAC;QAC1E,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,WAAW,CAAC,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAC7F,MAAM,OAAO,GAAG,CAAC,MAAA,IAAI,CAAC,OAAO,mCAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5C,MAAM,OAAO,GAAG,MAAA,IAAI,CAAC,OAAO,mCAAI,EAAE,CAAC;QAEnC,IAAI,CAAC,OAAO,EAAE,CAAC;YACX,OAAO;gBACH,OAAO,EAAE,uIAAuI;gBAChJ,QAAQ,EAAE,EAAE;gBACZ,WAAW,EAAE,EAAE;aAClB,CAAC;QACN,CAAC;QAED,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC/D,CAAC;CACJ,CAAA;AAlCY,kDAAmB;AAUtB;IADL,IAAA,aAAI,EAAC,MAAM,CAAC;IACD,WAAA,IAAA,aAAI,GAAE,CAAA;IAA0B,WAAA,IAAA,YAAG,GAAE,CAAA;;;;+CAuBhD;8BAjCQ,mBAAmB;IAD/B,IAAA,mBAAU,EAAC,eAAe,CAAC;qCAKQ,0CAAkB;QACf,4BAAqB;QAC5B,qBAAc;GANjC,mBAAmB,CAkC/B"}
|