@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.
Files changed (134) hide show
  1. package/README.md +214 -0
  2. package/dist/ai-assistant.plugin.d.ts +18 -0
  3. package/dist/ai-assistant.plugin.d.ts.map +1 -0
  4. package/dist/ai-assistant.plugin.js +86 -0
  5. package/dist/ai-assistant.plugin.js.map +1 -0
  6. package/dist/api/ai-assistant.resolver.d.ts +11 -0
  7. package/dist/api/ai-assistant.resolver.d.ts.map +1 -0
  8. package/dist/api/ai-assistant.resolver.js +43 -0
  9. package/dist/api/ai-assistant.resolver.js.map +1 -0
  10. package/dist/api/schema-extensions.d.ts +3 -0
  11. package/dist/api/schema-extensions.d.ts.map +1 -0
  12. package/dist/api/schema-extensions.js +15 -0
  13. package/dist/api/schema-extensions.js.map +1 -0
  14. package/dist/constants.d.ts +41 -0
  15. package/dist/constants.d.ts.map +1 -0
  16. package/dist/constants.js +24 -0
  17. package/dist/constants.js.map +1 -0
  18. package/dist/controllers/admin-chat.controller.d.ts +21 -0
  19. package/dist/controllers/admin-chat.controller.d.ts.map +1 -0
  20. package/dist/controllers/admin-chat.controller.js +64 -0
  21. package/dist/controllers/admin-chat.controller.js.map +1 -0
  22. package/dist/controllers/ai-assistant.controller.d.ts +96 -0
  23. package/dist/controllers/ai-assistant.controller.d.ts.map +1 -0
  24. package/dist/controllers/ai-assistant.controller.js +272 -0
  25. package/dist/controllers/ai-assistant.controller.js.map +1 -0
  26. package/dist/entities/collection-embedding.entity.d.ts +13 -0
  27. package/dist/entities/collection-embedding.entity.d.ts.map +1 -0
  28. package/dist/entities/collection-embedding.entity.js +43 -0
  29. package/dist/entities/collection-embedding.entity.js.map +1 -0
  30. package/dist/entities/product-embedding.entity.d.ts +14 -0
  31. package/dist/entities/product-embedding.entity.d.ts.map +1 -0
  32. package/dist/entities/product-embedding.entity.js +44 -0
  33. package/dist/entities/product-embedding.entity.js.map +1 -0
  34. package/dist/entities/variant-embedding.entity.d.ts +13 -0
  35. package/dist/entities/variant-embedding.entity.d.ts.map +1 -0
  36. package/dist/entities/variant-embedding.entity.js +43 -0
  37. package/dist/entities/variant-embedding.entity.js.map +1 -0
  38. package/dist/handlers/collection-embedding-handler.d.ts +18 -0
  39. package/dist/handlers/collection-embedding-handler.d.ts.map +1 -0
  40. package/dist/handlers/collection-embedding-handler.js +90 -0
  41. package/dist/handlers/collection-embedding-handler.js.map +1 -0
  42. package/dist/handlers/product-embedding-handler.d.ts +20 -0
  43. package/dist/handlers/product-embedding-handler.d.ts.map +1 -0
  44. package/dist/handlers/product-embedding-handler.js +96 -0
  45. package/dist/handlers/product-embedding-handler.js.map +1 -0
  46. package/dist/handlers/variant-embedding-handler.d.ts +19 -0
  47. package/dist/handlers/variant-embedding-handler.d.ts.map +1 -0
  48. package/dist/handlers/variant-embedding-handler.js +101 -0
  49. package/dist/handlers/variant-embedding-handler.js.map +1 -0
  50. package/dist/index.d.ts +23 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +33 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/services/admin-ai-chat.service.d.ts +40 -0
  55. package/dist/services/admin-ai-chat.service.d.ts.map +1 -0
  56. package/dist/services/admin-ai-chat.service.js +201 -0
  57. package/dist/services/admin-ai-chat.service.js.map +1 -0
  58. package/dist/services/admin-system-prompt.d.ts +2 -0
  59. package/dist/services/admin-system-prompt.d.ts.map +1 -0
  60. package/dist/services/admin-system-prompt.js +44 -0
  61. package/dist/services/admin-system-prompt.js.map +1 -0
  62. package/dist/services/admin-tools/admin-collection-tools.d.ts +15 -0
  63. package/dist/services/admin-tools/admin-collection-tools.d.ts.map +1 -0
  64. package/dist/services/admin-tools/admin-collection-tools.js +48 -0
  65. package/dist/services/admin-tools/admin-collection-tools.js.map +1 -0
  66. package/dist/services/admin-tools/admin-customer-tools.d.ts +15 -0
  67. package/dist/services/admin-tools/admin-customer-tools.d.ts.map +1 -0
  68. package/dist/services/admin-tools/admin-customer-tools.js +56 -0
  69. package/dist/services/admin-tools/admin-customer-tools.js.map +1 -0
  70. package/dist/services/admin-tools/admin-order-tools.d.ts +16 -0
  71. package/dist/services/admin-tools/admin-order-tools.d.ts.map +1 -0
  72. package/dist/services/admin-tools/admin-order-tools.js +69 -0
  73. package/dist/services/admin-tools/admin-order-tools.js.map +1 -0
  74. package/dist/services/admin-tools/admin-product-tools.d.ts +29 -0
  75. package/dist/services/admin-tools/admin-product-tools.d.ts.map +1 -0
  76. package/dist/services/admin-tools/admin-product-tools.js +139 -0
  77. package/dist/services/admin-tools/admin-product-tools.js.map +1 -0
  78. package/dist/services/ai-chat.service.d.ts +42 -0
  79. package/dist/services/ai-chat.service.d.ts.map +1 -0
  80. package/dist/services/ai-chat.service.js +308 -0
  81. package/dist/services/ai-chat.service.js.map +1 -0
  82. package/dist/services/chat-result-mapper.d.ts +17 -0
  83. package/dist/services/chat-result-mapper.d.ts.map +1 -0
  84. package/dist/services/chat-result-mapper.js +176 -0
  85. package/dist/services/chat-result-mapper.js.map +1 -0
  86. package/dist/services/collection-embedding.service.d.ts +14 -0
  87. package/dist/services/collection-embedding.service.d.ts.map +1 -0
  88. package/dist/services/collection-embedding.service.js +67 -0
  89. package/dist/services/collection-embedding.service.js.map +1 -0
  90. package/dist/services/conversation-cache.service.d.ts +47 -0
  91. package/dist/services/conversation-cache.service.d.ts.map +1 -0
  92. package/dist/services/conversation-cache.service.js +87 -0
  93. package/dist/services/conversation-cache.service.js.map +1 -0
  94. package/dist/services/embed-all-job.service.d.ts +28 -0
  95. package/dist/services/embed-all-job.service.d.ts.map +1 -0
  96. package/dist/services/embed-all-job.service.js +151 -0
  97. package/dist/services/embed-all-job.service.js.map +1 -0
  98. package/dist/services/embedding.service.d.ts +21 -0
  99. package/dist/services/embedding.service.d.ts.map +1 -0
  100. package/dist/services/embedding.service.js +58 -0
  101. package/dist/services/embedding.service.js.map +1 -0
  102. package/dist/services/product-embedding.service.d.ts +19 -0
  103. package/dist/services/product-embedding.service.d.ts.map +1 -0
  104. package/dist/services/product-embedding.service.js +78 -0
  105. package/dist/services/product-embedding.service.js.map +1 -0
  106. package/dist/services/system-prompt.d.ts +2 -0
  107. package/dist/services/system-prompt.d.ts.map +1 -0
  108. package/dist/services/system-prompt.js +107 -0
  109. package/dist/services/system-prompt.js.map +1 -0
  110. package/dist/services/tools/cart-tools.d.ts +14 -0
  111. package/dist/services/tools/cart-tools.d.ts.map +1 -0
  112. package/dist/services/tools/cart-tools.js +168 -0
  113. package/dist/services/tools/cart-tools.js.map +1 -0
  114. package/dist/services/tools/checkout-tools.d.ts +37 -0
  115. package/dist/services/tools/checkout-tools.d.ts.map +1 -0
  116. package/dist/services/tools/checkout-tools.js +228 -0
  117. package/dist/services/tools/checkout-tools.js.map +1 -0
  118. package/dist/services/tools/order-tools.d.ts +15 -0
  119. package/dist/services/tools/order-tools.d.ts.map +1 -0
  120. package/dist/services/tools/order-tools.js +105 -0
  121. package/dist/services/tools/order-tools.js.map +1 -0
  122. package/dist/services/tools/search-tools.d.ts +21 -0
  123. package/dist/services/tools/search-tools.d.ts.map +1 -0
  124. package/dist/services/tools/search-tools.js +214 -0
  125. package/dist/services/tools/search-tools.js.map +1 -0
  126. package/dist/services/types.d.ts +118 -0
  127. package/dist/services/types.d.ts.map +1 -0
  128. package/dist/services/types.js +3 -0
  129. package/dist/services/types.js.map +1 -0
  130. package/dist/services/variant-embedding.service.d.ts +14 -0
  131. package/dist/services/variant-embedding.service.d.ts.map +1 -0
  132. package/dist/services/variant-embedding.service.js +59 -0
  133. package/dist/services/variant-embedding.service.js.map +1 -0
  134. package/package.json +57 -0
@@ -0,0 +1,96 @@
1
+ import { Request, Response } from 'express';
2
+ import { RequestContextService, CustomerService, SessionService, ConfigService } from '@vendure/core';
3
+ import { AiChatService, AiChatProduct, AiChatCollection, AddToCartAction, AiChatOrder, AiActiveOrder, SetShippingAddressAction, SetBillingAddressAction, SetShippingMethodAction } from '../services/ai-chat.service';
4
+ import { ConversationCacheService } from '../services/conversation-cache.service';
5
+ import { type AiAssistantPluginOptions } from '../constants';
6
+ export type { AiChatProduct, AiChatCollection, AddToCartAction, AiChatOrder, AiChatOrderLine, AiActiveOrder, AiCartLine, SetShippingAddressAction, SetBillingAddressAction, SetShippingMethodAction, } from '../services/ai-chat.service';
7
+ export interface AiChatRequest {
8
+ /** Direct message (simple format) */
9
+ message?: string;
10
+ /** Conversation history from the frontend for multi-turn context (simple format) */
11
+ history?: Array<{
12
+ role: 'user' | 'assistant';
13
+ content: string;
14
+ }>;
15
+ /** AI SDK UIMessage array (sent by DefaultChatTransport / useChat()) */
16
+ messages?: Array<{
17
+ role: string;
18
+ content?: string;
19
+ parts?: Array<{
20
+ type: string;
21
+ text?: string;
22
+ [key: string]: unknown;
23
+ }>;
24
+ [key: string]: unknown;
25
+ }>;
26
+ /**
27
+ * Conversation ID for server-side history caching.
28
+ * When provided, the server fetches conversation history from its cache
29
+ * instead of requiring the full history in every request.
30
+ * Generated by the frontend (UUID) when the chat widget mounts.
31
+ */
32
+ conversationId?: string;
33
+ }
34
+ export interface AiChatResponse {
35
+ message: string;
36
+ products: AiChatProduct[];
37
+ collections: AiChatCollection[];
38
+ addToCartAction?: AddToCartAction;
39
+ orders?: AiChatOrder[];
40
+ activeOrder?: AiActiveOrder;
41
+ setShippingAddressAction?: SetShippingAddressAction;
42
+ setBillingAddressAction?: SetBillingAddressAction;
43
+ setShippingMethodAction?: SetShippingMethodAction;
44
+ }
45
+ /**
46
+ * REST endpoints for the AI shopping assistant.
47
+ * - POST /ai-assistant/chat — non-streaming JSON response (backward compatible)
48
+ * - POST /ai-assistant/stream — streaming response using Vercel AI SDK data stream protocol
49
+ */
50
+ export declare class AiAssistantController {
51
+ private options;
52
+ private requestContextService;
53
+ private customerService;
54
+ private sessionService;
55
+ private configService;
56
+ private aiChatService;
57
+ private conversationCacheService;
58
+ private readonly logger;
59
+ private readonly cacheEnabled;
60
+ constructor(options: AiAssistantPluginOptions, requestContextService: RequestContextService, customerService: CustomerService, sessionService: SessionService, configService: ConfigService, aiChatService: AiChatService, conversationCacheService: ConversationCacheService);
61
+ /**
62
+ * Helper: extract user message and conversation history from the request body.
63
+ * Supports two formats:
64
+ * 1. Simple: { message: "hello", history: [{role, content}] }
65
+ * 2. AI SDK: { messages: [UIMessage, ...] } (sent by DefaultChatTransport / useChat())
66
+ */
67
+ private extractMessageAndHistory;
68
+ /** Extract plain text from a UIMessage (handles both parts and content) */
69
+ private getTextFromUIMessage;
70
+ /** Extract assistant text + tool result summaries for conversation context */
71
+ private getAssistantTextWithToolContext;
72
+ /**
73
+ * Resolve conversation history: prefer server-side cache when conversationId
74
+ * is present, otherwise fall back to the history sent in the request body.
75
+ */
76
+ private resolveHistory;
77
+ /**
78
+ * Helper: extract auth context from request
79
+ */
80
+ private resolveAuthContext;
81
+ /**
82
+ * Non-streaming endpoint (backward compatible).
83
+ * Returns the full JSON response after all tool calls complete.
84
+ */
85
+ chat(body: AiChatRequest, req: Request): Promise<AiChatResponse>;
86
+ /**
87
+ * Streaming endpoint.
88
+ * Returns a Vercel AI SDK–compatible data stream.
89
+ * The frontend can consume this with useChat() from @ai-sdk/react.
90
+ *
91
+ * Structured data (products, collections, cart, orders, actions) is sent
92
+ * as data stream annotations (custom JSON messages) alongside the text stream.
93
+ */
94
+ stream(body: AiChatRequest, req: Request, res: Response): Promise<void>;
95
+ }
96
+ //# sourceMappingURL=ai-assistant.controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-assistant.controller.d.ts","sourceRoot":"","sources":["../../src/controllers/ai-assistant.controller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,272 @@
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 AiAssistantController_1;
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.AiAssistantController = void 0;
17
+ const common_1 = require("@nestjs/common");
18
+ const core_1 = require("@vendure/core");
19
+ const ai_chat_service_1 = require("../services/ai-chat.service");
20
+ const conversation_cache_service_1 = require("../services/conversation-cache.service");
21
+ const constants_1 = require("../constants");
22
+ /**
23
+ * REST endpoints for the AI shopping assistant.
24
+ * - POST /ai-assistant/chat — non-streaming JSON response (backward compatible)
25
+ * - POST /ai-assistant/stream — streaming response using Vercel AI SDK data stream protocol
26
+ */
27
+ let AiAssistantController = AiAssistantController_1 = class AiAssistantController {
28
+ constructor(options, requestContextService, customerService, sessionService, configService, aiChatService, conversationCacheService) {
29
+ this.options = options;
30
+ this.requestContextService = requestContextService;
31
+ this.customerService = customerService;
32
+ this.sessionService = sessionService;
33
+ this.configService = configService;
34
+ this.aiChatService = aiChatService;
35
+ this.conversationCacheService = conversationCacheService;
36
+ this.logger = new common_1.Logger(AiAssistantController_1.name);
37
+ this.cacheEnabled = options.enableConversationCache !== false;
38
+ this.logger.log(`Conversation cache: ${this.cacheEnabled ? 'enabled' : 'disabled'}`);
39
+ }
40
+ /**
41
+ * Helper: extract user message and conversation history from the request body.
42
+ * Supports two formats:
43
+ * 1. Simple: { message: "hello", history: [{role, content}] }
44
+ * 2. AI SDK: { messages: [UIMessage, ...] } (sent by DefaultChatTransport / useChat())
45
+ */
46
+ extractMessageAndHistory(body) {
47
+ var _a, _b;
48
+ // AI SDK format: messages array with parts
49
+ if (body.messages && Array.isArray(body.messages) && body.messages.length > 0) {
50
+ const msgs = body.messages;
51
+ const lastUserMsg = [...msgs].reverse().find(m => m.role === 'user');
52
+ const message = lastUserMsg ? this.getTextFromUIMessage(lastUserMsg) : '';
53
+ const lastUserIndex = msgs.lastIndexOf(lastUserMsg);
54
+ const historyMsgs = lastUserIndex > 0 ? msgs.slice(0, lastUserIndex) : [];
55
+ const history = historyMsgs
56
+ .filter(m => m.role === 'user' || m.role === 'assistant')
57
+ .map(m => ({
58
+ role: m.role,
59
+ content: m.role === 'assistant'
60
+ ? this.getAssistantTextWithToolContext(m)
61
+ : this.getTextFromUIMessage(m),
62
+ }))
63
+ .filter(m => m.content.length > 0);
64
+ return { message: message.trim(), history };
65
+ }
66
+ // Simple format: { message, history }
67
+ return {
68
+ message: ((_a = body.message) !== null && _a !== void 0 ? _a : '').trim(),
69
+ history: ((_b = body.history) !== null && _b !== void 0 ? _b : []).map(msg => ({
70
+ role: msg.role,
71
+ content: msg.content,
72
+ })),
73
+ };
74
+ }
75
+ /** Extract plain text from a UIMessage (handles both parts and content) */
76
+ getTextFromUIMessage(msg) {
77
+ if (Array.isArray(msg.parts)) {
78
+ return msg.parts
79
+ .filter(p => p.type === 'text' && typeof p.text === 'string')
80
+ .map(p => p.text)
81
+ .join('');
82
+ }
83
+ if (typeof msg.content === 'string') {
84
+ return msg.content;
85
+ }
86
+ return '';
87
+ }
88
+ /** Extract assistant text + tool result summaries for conversation context */
89
+ getAssistantTextWithToolContext(msg) {
90
+ if (!Array.isArray(msg.parts)) {
91
+ return typeof msg.content === 'string' ? msg.content : '';
92
+ }
93
+ const parts = [];
94
+ for (const p of msg.parts) {
95
+ if (p.type === 'text' && typeof p.text === 'string') {
96
+ parts.push(p.text);
97
+ }
98
+ if (typeof p.type === 'string' && p.state === 'output-available' && p.output) {
99
+ const output = p.output;
100
+ if (typeof output.summary === 'string') {
101
+ parts.push(`[Tool result: ${output.summary}]`);
102
+ }
103
+ }
104
+ }
105
+ return parts.join('\n');
106
+ }
107
+ /**
108
+ * Resolve conversation history: prefer server-side cache when conversationId
109
+ * is present, otherwise fall back to the history sent in the request body.
110
+ */
111
+ async resolveHistory(body) {
112
+ var _a;
113
+ const { message, history: bodyHistory } = this.extractMessageAndHistory(body);
114
+ const conversationId = body.conversationId;
115
+ if (this.cacheEnabled && conversationId) {
116
+ // Fetch history from server-side cache
117
+ const cached = await this.conversationCacheService.getHistory(conversationId);
118
+ const history = (_a = cached === null || cached === void 0 ? void 0 : cached.messages) !== null && _a !== void 0 ? _a : [];
119
+ this.logger.log(`[CACHE] Conversation ${conversationId}: ${history.length} cached messages (skipped ${bodyHistory.length} from request body)`);
120
+ return { message, history, conversationId };
121
+ }
122
+ // Cache disabled or no conversationId — fall back to history from request body
123
+ return { message, history: bodyHistory };
124
+ }
125
+ /**
126
+ * Helper: extract auth context from request
127
+ */
128
+ async resolveAuthContext(req) {
129
+ var _a, _b, _c;
130
+ const authHeader = req.get('Authorization');
131
+ const tokenMatch = authHeader === null || authHeader === void 0 ? void 0 : authHeader.trim().match(/^bearer\s(.+)$/i);
132
+ const sessionToken = tokenMatch === null || tokenMatch === void 0 ? void 0 : tokenMatch[1];
133
+ this.logger.log(`[AUTH] Session token present: ${!!sessionToken}`);
134
+ let session;
135
+ if (sessionToken) {
136
+ session = await this.sessionService.getSessionFromToken(sessionToken);
137
+ this.logger.log(`[AUTH] Session found: ${!!session}, userId: ${(_b = (_a = session === null || session === void 0 ? void 0 : session.user) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : 'NONE'}`);
138
+ }
139
+ const ctx = await this.requestContextService.fromRequest(req, undefined, undefined, session);
140
+ this.logger.log(`[AUTH] ctx.activeUserId: ${(_c = ctx.activeUserId) !== null && _c !== void 0 ? _c : 'NONE'}`);
141
+ let customerId;
142
+ if (ctx.activeUserId) {
143
+ const customer = await this.customerService.findOneByUserId(ctx, ctx.activeUserId);
144
+ customerId = customer === null || customer === void 0 ? void 0 : customer.id;
145
+ this.logger.log(`[AUTH] customerId: ${customerId !== null && customerId !== void 0 ? customerId : 'NONE'}`);
146
+ }
147
+ return { ctx, customerId };
148
+ }
149
+ /**
150
+ * Non-streaming endpoint (backward compatible).
151
+ * Returns the full JSON response after all tool calls complete.
152
+ */
153
+ async chat(body, req) {
154
+ const { ctx, customerId } = await this.resolveAuthContext(req);
155
+ const { message: query, history, conversationId } = await this.resolveHistory(body);
156
+ if (!query) {
157
+ return {
158
+ message: 'Hi! I\'m your shopping assistant. How can I help you today? You can ask me about products, collections, your orders, or anything about our store.',
159
+ products: [],
160
+ collections: [],
161
+ };
162
+ }
163
+ const result = await this.aiChatService.chat(ctx, query, history, customerId);
164
+ // Cache the new turn if conversationId is present
165
+ if (conversationId) {
166
+ await this.conversationCacheService.appendMessages(conversationId, query, result.message, customerId);
167
+ }
168
+ return {
169
+ message: result.message,
170
+ products: result.products,
171
+ collections: result.collections,
172
+ addToCartAction: result.addToCartAction,
173
+ orders: result.orders,
174
+ activeOrder: result.activeOrder,
175
+ setShippingAddressAction: result.setShippingAddressAction,
176
+ setBillingAddressAction: result.setBillingAddressAction,
177
+ setShippingMethodAction: result.setShippingMethodAction,
178
+ };
179
+ }
180
+ /**
181
+ * Streaming endpoint.
182
+ * Returns a Vercel AI SDK–compatible data stream.
183
+ * The frontend can consume this with useChat() from @ai-sdk/react.
184
+ *
185
+ * Structured data (products, collections, cart, orders, actions) is sent
186
+ * as data stream annotations (custom JSON messages) alongside the text stream.
187
+ */
188
+ async stream(body, req, res) {
189
+ var _a;
190
+ const { ctx, customerId } = await this.resolveAuthContext(req);
191
+ const { message: query, history, conversationId } = await this.resolveHistory(body);
192
+ if (!query) {
193
+ res.setHeader('Content-Type', 'application/json');
194
+ res.status(200).json({
195
+ message: 'Hi! I\'m your shopping assistant. How can I help you today?',
196
+ products: [],
197
+ collections: [],
198
+ });
199
+ return;
200
+ }
201
+ const streamResult = this.aiChatService.streamChat(ctx, query, history, customerId);
202
+ // Use the AI SDK's toUIMessageStreamResponse for useChat() compatibility
203
+ const streamResponse = streamResult.toUIMessageStreamResponse();
204
+ // Forward status and headers
205
+ res.status((_a = streamResponse.status) !== null && _a !== void 0 ? _a : 200);
206
+ streamResponse.headers.forEach((value, key) => {
207
+ res.setHeader(key, value);
208
+ });
209
+ // Pipe the body stream to the express response
210
+ if (streamResponse.body) {
211
+ const reader = streamResponse.body.getReader();
212
+ try {
213
+ while (true) {
214
+ const { done, value } = await reader.read();
215
+ if (done)
216
+ break;
217
+ res.write(value);
218
+ }
219
+ }
220
+ catch (e) {
221
+ this.logger.error(`Stream error: ${e}`);
222
+ }
223
+ finally {
224
+ res.end();
225
+ }
226
+ }
227
+ else {
228
+ res.end();
229
+ }
230
+ // Cache the new conversation turn after the stream completes.
231
+ // We await the full text from the streamResult (which is already
232
+ // consumed by the stream pipe above, so .text resolves immediately).
233
+ if (conversationId) {
234
+ try {
235
+ const fullText = await streamResult.text;
236
+ await this.conversationCacheService.appendMessages(conversationId, query, fullText, customerId);
237
+ }
238
+ catch (e) {
239
+ this.logger.error(`Failed to cache conversation turn: ${e}`);
240
+ }
241
+ }
242
+ }
243
+ };
244
+ exports.AiAssistantController = AiAssistantController;
245
+ __decorate([
246
+ (0, common_1.Post)('chat'),
247
+ __param(0, (0, common_1.Body)()),
248
+ __param(1, (0, common_1.Req)()),
249
+ __metadata("design:type", Function),
250
+ __metadata("design:paramtypes", [Object, Object]),
251
+ __metadata("design:returntype", Promise)
252
+ ], AiAssistantController.prototype, "chat", null);
253
+ __decorate([
254
+ (0, common_1.Post)('stream'),
255
+ __param(0, (0, common_1.Body)()),
256
+ __param(1, (0, common_1.Req)()),
257
+ __param(2, (0, common_1.Res)()),
258
+ __metadata("design:type", Function),
259
+ __metadata("design:paramtypes", [Object, Object, Object]),
260
+ __metadata("design:returntype", Promise)
261
+ ], AiAssistantController.prototype, "stream", null);
262
+ exports.AiAssistantController = AiAssistantController = AiAssistantController_1 = __decorate([
263
+ (0, common_1.Controller)('ai-assistant'),
264
+ __param(0, (0, common_1.Inject)(constants_1.AI_ASSISTANT_OPTIONS)),
265
+ __metadata("design:paramtypes", [Object, core_1.RequestContextService,
266
+ core_1.CustomerService,
267
+ core_1.SessionService,
268
+ core_1.ConfigService,
269
+ ai_chat_service_1.AiChatService,
270
+ conversation_cache_service_1.ConversationCacheService])
271
+ ], AiAssistantController);
272
+ //# sourceMappingURL=ai-assistant.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-assistant.controller.js","sourceRoot":"","sources":["../../src/controllers/ai-assistant.controller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { DeepPartial } from '@vendure/common/lib/shared-types';
2
+ import { Collection, VendureEntity } from '@vendure/core';
3
+ /**
4
+ * Stores vector embedding for a Collection (name, description) for semantic search.
5
+ * Embedding column is declared so TypeORM schema sync does not suggest dropping it; read/write via raw SQL.
6
+ */
7
+ export declare class CollectionEmbedding extends VendureEntity {
8
+ constructor(input?: DeepPartial<CollectionEmbedding>);
9
+ collection: Collection;
10
+ collectionId: number;
11
+ embedding?: string;
12
+ }
13
+ //# sourceMappingURL=collection-embedding.entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection-embedding.entity.d.ts","sourceRoot":"","sources":["../../src/entities/collection-embedding.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAE/D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG1D;;;GAGG;AACH,qBACa,mBAAoB,SAAQ,aAAa;gBACtC,KAAK,CAAC,EAAE,WAAW,CAAC,mBAAmB,CAAC;IAMpD,UAAU,EAAE,UAAU,CAAC;IAGvB,YAAY,EAAE,MAAM,CAAC;IAGrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
@@ -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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.CollectionEmbedding = void 0;
13
+ const typeorm_1 = require("typeorm");
14
+ const core_1 = require("@vendure/core");
15
+ const constants_1 = require("../constants");
16
+ /**
17
+ * Stores vector embedding for a Collection (name, description) for semantic search.
18
+ * Embedding column is declared so TypeORM schema sync does not suggest dropping it; read/write via raw SQL.
19
+ */
20
+ let CollectionEmbedding = class CollectionEmbedding extends core_1.VendureEntity {
21
+ constructor(input) {
22
+ super(input);
23
+ }
24
+ };
25
+ exports.CollectionEmbedding = CollectionEmbedding;
26
+ __decorate([
27
+ (0, typeorm_1.ManyToOne)(() => core_1.Collection, { onDelete: 'CASCADE' }),
28
+ (0, typeorm_1.JoinColumn)(),
29
+ __metadata("design:type", core_1.Collection)
30
+ ], CollectionEmbedding.prototype, "collection", void 0);
31
+ __decorate([
32
+ (0, typeorm_1.Column)(),
33
+ __metadata("design:type", Number)
34
+ ], CollectionEmbedding.prototype, "collectionId", void 0);
35
+ __decorate([
36
+ (0, typeorm_1.Column)({ type: 'vector', length: constants_1.EMBEDDING_DIMENSIONS, select: false, nullable: true }),
37
+ __metadata("design:type", String)
38
+ ], CollectionEmbedding.prototype, "embedding", void 0);
39
+ exports.CollectionEmbedding = CollectionEmbedding = __decorate([
40
+ (0, typeorm_1.Entity)('collection_embedding'),
41
+ __metadata("design:paramtypes", [Object])
42
+ ], CollectionEmbedding);
43
+ //# sourceMappingURL=collection-embedding.entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection-embedding.entity.js","sourceRoot":"","sources":["../../src/entities/collection-embedding.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,qCAAgE;AAChE,wCAA0D;AAC1D,4CAAoD;AAEpD;;;GAGG;AAEI,IAAM,mBAAmB,GAAzB,MAAM,mBAAoB,SAAQ,oBAAa;IAClD,YAAY,KAAwC;QAChD,KAAK,CAAC,KAAK,CAAC,CAAC;IACjB,CAAC;CAWJ,CAAA;AAdY,kDAAmB;AAO5B;IAFC,IAAA,mBAAS,EAAC,GAAG,EAAE,CAAC,iBAAU,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;IACpD,IAAA,oBAAU,GAAE;8BACD,iBAAU;uDAAC;AAGvB;IADC,IAAA,gBAAM,GAAE;;yDACY;AAGrB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,gCAAoB,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;sDACrE;8BAbV,mBAAmB;IAD/B,IAAA,gBAAM,EAAC,sBAAsB,CAAC;;GAClB,mBAAmB,CAc/B"}
@@ -0,0 +1,14 @@
1
+ import { DeepPartial } from '@vendure/common/lib/shared-types';
2
+ import { Product, VendureEntity } from '@vendure/core';
3
+ /**
4
+ * Stores vector embedding for a Product (name + description) for semantic search.
5
+ * Embedding column is declared so TypeORM schema sync (synchronize: false) does not suggest dropping it;
6
+ * actual read/write is via raw SQL in ProductEmbeddingService.
7
+ */
8
+ export declare class ProductEmbedding extends VendureEntity {
9
+ constructor(input?: DeepPartial<ProductEmbedding>);
10
+ product: Product;
11
+ productId: number;
12
+ embedding?: string;
13
+ }
14
+ //# sourceMappingURL=product-embedding.entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-embedding.entity.d.ts","sourceRoot":"","sources":["../../src/entities/product-embedding.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAE/D,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGvD;;;;GAIG;AACH,qBACa,gBAAiB,SAAQ,aAAa;gBACnC,KAAK,CAAC,EAAE,WAAW,CAAC,gBAAgB,CAAC;IAMjD,OAAO,EAAE,OAAO,CAAC;IAGjB,SAAS,EAAE,MAAM,CAAC;IAGlB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
@@ -0,0 +1,44 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ProductEmbedding = void 0;
13
+ const typeorm_1 = require("typeorm");
14
+ const core_1 = require("@vendure/core");
15
+ const constants_1 = require("../constants");
16
+ /**
17
+ * Stores vector embedding for a Product (name + description) for semantic search.
18
+ * Embedding column is declared so TypeORM schema sync (synchronize: false) does not suggest dropping it;
19
+ * actual read/write is via raw SQL in ProductEmbeddingService.
20
+ */
21
+ let ProductEmbedding = class ProductEmbedding extends core_1.VendureEntity {
22
+ constructor(input) {
23
+ super(input);
24
+ }
25
+ };
26
+ exports.ProductEmbedding = ProductEmbedding;
27
+ __decorate([
28
+ (0, typeorm_1.ManyToOne)(() => core_1.Product, { onDelete: 'CASCADE' }),
29
+ (0, typeorm_1.JoinColumn)(),
30
+ __metadata("design:type", core_1.Product)
31
+ ], ProductEmbedding.prototype, "product", void 0);
32
+ __decorate([
33
+ (0, typeorm_1.Column)(),
34
+ __metadata("design:type", Number)
35
+ ], ProductEmbedding.prototype, "productId", void 0);
36
+ __decorate([
37
+ (0, typeorm_1.Column)({ type: 'vector', length: constants_1.EMBEDDING_DIMENSIONS, select: false, nullable: true }),
38
+ __metadata("design:type", String)
39
+ ], ProductEmbedding.prototype, "embedding", void 0);
40
+ exports.ProductEmbedding = ProductEmbedding = __decorate([
41
+ (0, typeorm_1.Entity)('product_embedding'),
42
+ __metadata("design:paramtypes", [Object])
43
+ ], ProductEmbedding);
44
+ //# sourceMappingURL=product-embedding.entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-embedding.entity.js","sourceRoot":"","sources":["../../src/entities/product-embedding.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,qCAAgE;AAChE,wCAAuD;AACvD,4CAAoD;AAEpD;;;;GAIG;AAEI,IAAM,gBAAgB,GAAtB,MAAM,gBAAiB,SAAQ,oBAAa;IAC/C,YAAY,KAAqC;QAC7C,KAAK,CAAC,KAAK,CAAC,CAAC;IACjB,CAAC;CAWJ,CAAA;AAdY,4CAAgB;AAOzB;IAFC,IAAA,mBAAS,EAAC,GAAG,EAAE,CAAC,cAAO,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;IACjD,IAAA,oBAAU,GAAE;8BACJ,cAAO;iDAAC;AAGjB;IADC,IAAA,gBAAM,GAAE;;mDACS;AAGlB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,gCAAoB,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;mDACrE;2BAbV,gBAAgB;IAD5B,IAAA,gBAAM,EAAC,mBAAmB,CAAC;;GACf,gBAAgB,CAc5B"}
@@ -0,0 +1,13 @@
1
+ import { DeepPartial } from '@vendure/common/lib/shared-types';
2
+ import { ProductVariant, VendureEntity } from '@vendure/core';
3
+ /**
4
+ * Stores vector embedding for a ProductVariant (name, sku, product name) for semantic search.
5
+ * Embedding column is declared so TypeORM schema sync does not suggest dropping it; read/write via raw SQL.
6
+ */
7
+ export declare class VariantEmbedding extends VendureEntity {
8
+ constructor(input?: DeepPartial<VariantEmbedding>);
9
+ productVariant: ProductVariant;
10
+ productVariantId: number;
11
+ embedding?: string;
12
+ }
13
+ //# sourceMappingURL=variant-embedding.entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variant-embedding.entity.d.ts","sourceRoot":"","sources":["../../src/entities/variant-embedding.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAE/D,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG9D;;;GAGG;AACH,qBACa,gBAAiB,SAAQ,aAAa;gBACnC,KAAK,CAAC,EAAE,WAAW,CAAC,gBAAgB,CAAC;IAMjD,cAAc,EAAE,cAAc,CAAC;IAG/B,gBAAgB,EAAE,MAAM,CAAC;IAGzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
@@ -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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.VariantEmbedding = void 0;
13
+ const typeorm_1 = require("typeorm");
14
+ const core_1 = require("@vendure/core");
15
+ const constants_1 = require("../constants");
16
+ /**
17
+ * Stores vector embedding for a ProductVariant (name, sku, product name) for semantic search.
18
+ * Embedding column is declared so TypeORM schema sync does not suggest dropping it; read/write via raw SQL.
19
+ */
20
+ let VariantEmbedding = class VariantEmbedding extends core_1.VendureEntity {
21
+ constructor(input) {
22
+ super(input);
23
+ }
24
+ };
25
+ exports.VariantEmbedding = VariantEmbedding;
26
+ __decorate([
27
+ (0, typeorm_1.ManyToOne)(() => core_1.ProductVariant, { onDelete: 'CASCADE' }),
28
+ (0, typeorm_1.JoinColumn)(),
29
+ __metadata("design:type", core_1.ProductVariant)
30
+ ], VariantEmbedding.prototype, "productVariant", void 0);
31
+ __decorate([
32
+ (0, typeorm_1.Column)(),
33
+ __metadata("design:type", Number)
34
+ ], VariantEmbedding.prototype, "productVariantId", void 0);
35
+ __decorate([
36
+ (0, typeorm_1.Column)({ type: 'vector', length: constants_1.EMBEDDING_DIMENSIONS, select: false, nullable: true }),
37
+ __metadata("design:type", String)
38
+ ], VariantEmbedding.prototype, "embedding", void 0);
39
+ exports.VariantEmbedding = VariantEmbedding = __decorate([
40
+ (0, typeorm_1.Entity)('variant_embedding'),
41
+ __metadata("design:paramtypes", [Object])
42
+ ], VariantEmbedding);
43
+ //# sourceMappingURL=variant-embedding.entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variant-embedding.entity.js","sourceRoot":"","sources":["../../src/entities/variant-embedding.entity.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,qCAAgE;AAChE,wCAA8D;AAC9D,4CAAoD;AAEpD;;;GAGG;AAEI,IAAM,gBAAgB,GAAtB,MAAM,gBAAiB,SAAQ,oBAAa;IAC/C,YAAY,KAAqC;QAC7C,KAAK,CAAC,KAAK,CAAC,CAAC;IACjB,CAAC;CAWJ,CAAA;AAdY,4CAAgB;AAOzB;IAFC,IAAA,mBAAS,EAAC,GAAG,EAAE,CAAC,qBAAc,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;IACxD,IAAA,oBAAU,GAAE;8BACG,qBAAc;wDAAC;AAG/B;IADC,IAAA,gBAAM,GAAE;;0DACgB;AAGzB;IADC,IAAA,gBAAM,EAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,gCAAoB,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;mDACrE;2BAbV,gBAAgB;IAD5B,IAAA,gBAAM,EAAC,mBAAmB,CAAC;;GACf,gBAAgB,CAc5B"}
@@ -0,0 +1,18 @@
1
+ import { OnModuleInit } from '@nestjs/common';
2
+ import { EventBus, TransactionalConnection } from '@vendure/core';
3
+ import { EmbeddingService } from '../services/embedding.service';
4
+ import { CollectionEmbeddingService } from '../services/collection-embedding.service';
5
+ /**
6
+ * Subscribes to Collection created/updated/deleted; keeps CollectionEmbedding in sync.
7
+ */
8
+ export declare class CollectionEmbeddingHandler implements OnModuleInit {
9
+ private eventBus;
10
+ private connection;
11
+ private embeddingService;
12
+ private collectionEmbeddingService;
13
+ constructor(eventBus: EventBus, connection: TransactionalConnection, embeddingService: EmbeddingService, collectionEmbeddingService: CollectionEmbeddingService);
14
+ onModuleInit(): void;
15
+ private getCollectionId;
16
+ private embedCollection;
17
+ }
18
+ //# sourceMappingURL=collection-embedding-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection-embedding-handler.d.ts","sourceRoot":"","sources":["../../src/handlers/collection-embedding-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EACH,QAAQ,EAER,uBAAuB,EAE1B,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,0CAA0C,CAAC;AAEtF;;GAEG;AACH,qBACa,0BAA2B,YAAW,YAAY;IAEvD,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,0BAA0B;gBAH1B,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,uBAAuB,EACnC,gBAAgB,EAAE,gBAAgB,EAClC,0BAA0B,EAAE,0BAA0B;IAGlE,YAAY;IAkCZ,OAAO,CAAC,eAAe;YAMT,eAAe;CAqBhC"}