@rahul_vendure/ai-chat-plugin 0.1.7 → 0.2.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 (105) hide show
  1. package/LICENSE +14 -0
  2. package/README.md +1 -1
  3. package/dist/ai-assistant.plugin.d.ts.map +1 -1
  4. package/dist/ai-assistant.plugin.js +4 -1
  5. package/dist/ai-assistant.plugin.js.map +1 -1
  6. package/dist/api/ai-assistant.resolver.d.ts +2 -4
  7. package/dist/api/ai-assistant.resolver.d.ts.map +1 -1
  8. package/dist/api/ai-assistant.resolver.js.map +1 -1
  9. package/dist/constants.d.ts +13 -0
  10. package/dist/constants.d.ts.map +1 -1
  11. package/dist/controllers/admin-chat.controller.d.ts +19 -2
  12. package/dist/controllers/admin-chat.controller.d.ts.map +1 -1
  13. package/dist/controllers/admin-chat.controller.js +107 -7
  14. package/dist/controllers/admin-chat.controller.js.map +1 -1
  15. package/dist/entities/ai-chat-session.entity.d.ts +27 -0
  16. package/dist/entities/ai-chat-session.entity.d.ts.map +1 -0
  17. package/dist/entities/ai-chat-session.entity.js +72 -0
  18. package/dist/entities/ai-chat-session.entity.js.map +1 -0
  19. package/dist/generated/graphql.d.ts +59 -0
  20. package/dist/generated/graphql.d.ts.map +1 -0
  21. package/dist/generated/graphql.js +3 -0
  22. package/dist/generated/graphql.js.map +1 -0
  23. package/dist/index.d.ts +6 -1
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +5 -1
  26. package/dist/index.js.map +1 -1
  27. package/dist/services/admin-ai-chat.service.d.ts +35 -4
  28. package/dist/services/admin-ai-chat.service.d.ts.map +1 -1
  29. package/dist/services/admin-ai-chat.service.js +263 -186
  30. package/dist/services/admin-ai-chat.service.js.map +1 -1
  31. package/dist/services/admin-system-prompt.d.ts +1 -1
  32. package/dist/services/admin-system-prompt.d.ts.map +1 -1
  33. package/dist/services/admin-system-prompt.js +100 -62
  34. package/dist/services/admin-system-prompt.js.map +1 -1
  35. package/dist/services/admin-tools/admin-asset-tools.d.ts +21 -0
  36. package/dist/services/admin-tools/admin-asset-tools.d.ts.map +1 -0
  37. package/dist/services/admin-tools/admin-asset-tools.js +74 -0
  38. package/dist/services/admin-tools/admin-asset-tools.js.map +1 -0
  39. package/dist/services/admin-tools/admin-collection-tools.d.ts +33 -2
  40. package/dist/services/admin-tools/admin-collection-tools.d.ts.map +1 -1
  41. package/dist/services/admin-tools/admin-collection-tools.js +101 -1
  42. package/dist/services/admin-tools/admin-collection-tools.js.map +1 -1
  43. package/dist/services/admin-tools/admin-country-tools.d.ts +17 -2
  44. package/dist/services/admin-tools/admin-country-tools.d.ts.map +1 -1
  45. package/dist/services/admin-tools/admin-country-tools.js +69 -1
  46. package/dist/services/admin-tools/admin-country-tools.js.map +1 -1
  47. package/dist/services/admin-tools/admin-customer-group-tools.d.ts +35 -0
  48. package/dist/services/admin-tools/admin-customer-group-tools.d.ts.map +1 -0
  49. package/dist/services/admin-tools/admin-customer-group-tools.js +116 -0
  50. package/dist/services/admin-tools/admin-customer-group-tools.js.map +1 -0
  51. package/dist/services/admin-tools/admin-customer-tools.d.ts +44 -3
  52. package/dist/services/admin-tools/admin-customer-tools.d.ts.map +1 -1
  53. package/dist/services/admin-tools/admin-customer-tools.js +237 -11
  54. package/dist/services/admin-tools/admin-customer-tools.js.map +1 -1
  55. package/dist/services/admin-tools/admin-facet-tools.d.ts +39 -2
  56. package/dist/services/admin-tools/admin-facet-tools.d.ts.map +1 -1
  57. package/dist/services/admin-tools/admin-facet-tools.js +179 -1
  58. package/dist/services/admin-tools/admin-facet-tools.js.map +1 -1
  59. package/dist/services/admin-tools/admin-order-tools.d.ts +4 -0
  60. package/dist/services/admin-tools/admin-order-tools.d.ts.map +1 -1
  61. package/dist/services/admin-tools/admin-order-tools.js +154 -0
  62. package/dist/services/admin-tools/admin-order-tools.js.map +1 -1
  63. package/dist/services/admin-tools/admin-payment-tools.d.ts +24 -2
  64. package/dist/services/admin-tools/admin-payment-tools.d.ts.map +1 -1
  65. package/dist/services/admin-tools/admin-payment-tools.js +92 -1
  66. package/dist/services/admin-tools/admin-payment-tools.js.map +1 -1
  67. package/dist/services/admin-tools/admin-product-tools.d.ts +55 -3
  68. package/dist/services/admin-tools/admin-product-tools.d.ts.map +1 -1
  69. package/dist/services/admin-tools/admin-product-tools.js +235 -9
  70. package/dist/services/admin-tools/admin-product-tools.js.map +1 -1
  71. package/dist/services/admin-tools/admin-promotion-tools.d.ts +34 -2
  72. package/dist/services/admin-tools/admin-promotion-tools.d.ts.map +1 -1
  73. package/dist/services/admin-tools/admin-promotion-tools.js +117 -1
  74. package/dist/services/admin-tools/admin-promotion-tools.js.map +1 -1
  75. package/dist/services/admin-tools/admin-settings-tools.d.ts +42 -2
  76. package/dist/services/admin-tools/admin-settings-tools.d.ts.map +1 -1
  77. package/dist/services/admin-tools/admin-settings-tools.js +235 -1
  78. package/dist/services/admin-tools/admin-settings-tools.js.map +1 -1
  79. package/dist/services/admin-tools/admin-shipping-tools.d.ts +23 -2
  80. package/dist/services/admin-tools/admin-shipping-tools.d.ts.map +1 -1
  81. package/dist/services/admin-tools/admin-shipping-tools.js +99 -1
  82. package/dist/services/admin-tools/admin-shipping-tools.js.map +1 -1
  83. package/dist/services/admin-tools/admin-staff-tools.d.ts +38 -2
  84. package/dist/services/admin-tools/admin-staff-tools.d.ts.map +1 -1
  85. package/dist/services/admin-tools/admin-staff-tools.js +142 -1
  86. package/dist/services/admin-tools/admin-staff-tools.js.map +1 -1
  87. package/dist/services/admin-tools/admin-stock-location-tools.d.ts +29 -0
  88. package/dist/services/admin-tools/admin-stock-location-tools.d.ts.map +1 -0
  89. package/dist/services/admin-tools/admin-stock-location-tools.js +102 -0
  90. package/dist/services/admin-tools/admin-stock-location-tools.js.map +1 -0
  91. package/dist/services/admin-tools/admin-tax-tools.d.ts +55 -2
  92. package/dist/services/admin-tools/admin-tax-tools.d.ts.map +1 -1
  93. package/dist/services/admin-tools/admin-tax-tools.js +184 -1
  94. package/dist/services/admin-tools/admin-tax-tools.js.map +1 -1
  95. package/dist/services/ai-chat-history.service.d.ts +32 -0
  96. package/dist/services/ai-chat-history.service.d.ts.map +1 -0
  97. package/dist/services/ai-chat-history.service.js +102 -0
  98. package/dist/services/ai-chat-history.service.js.map +1 -0
  99. package/dist/services/ai-chat.service.d.ts +5 -2
  100. package/dist/services/ai-chat.service.d.ts.map +1 -1
  101. package/dist/services/ai-chat.service.js +62 -4
  102. package/dist/services/ai-chat.service.js.map +1 -1
  103. package/dist/services/types.d.ts +7 -0
  104. package/dist/services/types.d.ts.map +1 -1
  105. package/package.json +9 -3
@@ -18,6 +18,7 @@ const common_1 = require("@nestjs/common");
18
18
  const core_1 = require("@nestjs/core");
19
19
  const ai_1 = require("ai");
20
20
  const openai_1 = require("@ai-sdk/openai");
21
+ const azure_1 = require("@ai-sdk/azure");
21
22
  const zod_1 = require("zod");
22
23
  const core_2 = require("@vendure/core");
23
24
  const constants_1 = require("../constants");
@@ -37,9 +38,12 @@ const admin_settings_tools_1 = require("./admin-tools/admin-settings-tools");
37
38
  const admin_staff_tools_1 = require("./admin-tools/admin-staff-tools");
38
39
  const admin_promotion_tools_1 = require("./admin-tools/admin-promotion-tools");
39
40
  const admin_country_tools_1 = require("./admin-tools/admin-country-tools");
41
+ const admin_asset_tools_1 = require("./admin-tools/admin-asset-tools");
42
+ const admin_customer_group_tools_1 = require("./admin-tools/admin-customer-group-tools");
43
+ const admin_stock_location_tools_1 = require("./admin-tools/admin-stock-location-tools");
40
44
  const admin_system_prompt_1 = require("./admin-system-prompt");
41
45
  let AdminAiChatService = AdminAiChatService_1 = class AdminAiChatService {
42
- constructor(options, connection, moduleRef, configService, embeddingService, productEmbeddingService, collectionEmbeddingService) {
46
+ constructor(options, connection, moduleRef, configService, embeddingService, productEmbeddingService, collectionEmbeddingService, productService, productVariantService, productOptionGroupService, productOptionService, taxCategoryService, customerService, collectionService, facetService, facetValueService, shippingMethodService, paymentMethodService, taxRateService, zoneService, countryService, administratorService, roleService, channelService, sellerService, globalSettingsService, promotionService, assetService, customerGroupService, stockLocationService) {
43
47
  this.options = options;
44
48
  this.connection = connection;
45
49
  this.moduleRef = moduleRef;
@@ -47,12 +51,43 @@ let AdminAiChatService = AdminAiChatService_1 = class AdminAiChatService {
47
51
  this.embeddingService = embeddingService;
48
52
  this.productEmbeddingService = productEmbeddingService;
49
53
  this.collectionEmbeddingService = collectionEmbeddingService;
54
+ this.productService = productService;
55
+ this.productVariantService = productVariantService;
56
+ this.productOptionGroupService = productOptionGroupService;
57
+ this.productOptionService = productOptionService;
58
+ this.taxCategoryService = taxCategoryService;
59
+ this.customerService = customerService;
60
+ this.collectionService = collectionService;
61
+ this.facetService = facetService;
62
+ this.facetValueService = facetValueService;
63
+ this.shippingMethodService = shippingMethodService;
64
+ this.paymentMethodService = paymentMethodService;
65
+ this.taxRateService = taxRateService;
66
+ this.zoneService = zoneService;
67
+ this.countryService = countryService;
68
+ this.administratorService = administratorService;
69
+ this.roleService = roleService;
70
+ this.channelService = channelService;
71
+ this.sellerService = sellerService;
72
+ this.globalSettingsService = globalSettingsService;
73
+ this.promotionService = promotionService;
74
+ this.assetService = assetService;
75
+ this.customerGroupService = customerGroupService;
76
+ this.stockLocationService = stockLocationService;
50
77
  this.logger = new common_1.Logger(AdminAiChatService_1.name);
78
+ this.azure = null;
79
+ this.azureDeploymentName = '';
51
80
  this.assetUrlPrefix = '';
52
81
  this.openai = (0, openai_1.createOpenAI)({ apiKey: options.openaiApiKey });
82
+ if (options.azureOpenai) {
83
+ this.azure = (0, azure_1.createAzure)({
84
+ apiKey: options.azureOpenai.apiKey,
85
+ resourceName: options.azureOpenai.resourceName,
86
+ });
87
+ this.azureDeploymentName = options.azureOpenai.deploymentName;
88
+ }
53
89
  }
54
90
  async onModuleInit() {
55
- // Resolve FulltextSearchService
56
91
  try {
57
92
  // eslint-disable-next-line @typescript-eslint/no-require-imports
58
93
  const mod = require('@vendure/core/dist/plugin/default-search-plugin/fulltext-search.service');
@@ -62,11 +97,8 @@ let AdminAiChatService = AdminAiChatService_1 = class AdminAiChatService {
62
97
  catch {
63
98
  this.logger.warn('FulltextSearchService not available for admin chat');
64
99
  }
65
- // Resolve asset URL prefix
66
100
  if (this.options.assetBaseUrl) {
67
- this.assetUrlPrefix = this.options.assetBaseUrl.endsWith('/')
68
- ? this.options.assetBaseUrl
69
- : this.options.assetBaseUrl + '/';
101
+ this.assetUrlPrefix = this.options.assetBaseUrl.endsWith('/') ? this.options.assetBaseUrl : this.options.assetBaseUrl + '/';
70
102
  }
71
103
  else {
72
104
  try {
@@ -79,198 +111,211 @@ let AdminAiChatService = AdminAiChatService_1 = class AdminAiChatService {
79
111
  this.assetUrlPrefix = '/assets/';
80
112
  }
81
113
  }
82
- // Initialize helpers
83
114
  this.mapper = new chat_result_mapper_1.ChatResultMapper(this.connection, this.assetUrlPrefix);
84
- this.productTools = new admin_product_tools_1.AdminProductTools(this.connection, this.mapper, this.fulltextSearchService, this.embeddingService, this.productEmbeddingService, this.collectionEmbeddingService);
115
+ this.productTools = new admin_product_tools_1.AdminProductTools(this.connection, this.mapper, this.fulltextSearchService, this.embeddingService, this.productEmbeddingService, this.collectionEmbeddingService, this.productService, this.productVariantService, this.productOptionGroupService, this.productOptionService, this.taxCategoryService);
85
116
  this.orderTools = new admin_order_tools_1.AdminOrderTools(this.connection, this.mapper);
86
- this.customerTools = new admin_customer_tools_1.AdminCustomerTools(this.connection);
87
- this.collectionTools = new admin_collection_tools_1.AdminCollectionTools(this.connection);
88
- this.shippingTools = new admin_shipping_tools_1.AdminShippingTools(this.connection);
89
- this.paymentTools = new admin_payment_tools_1.AdminPaymentTools(this.connection);
90
- this.taxTools = new admin_tax_tools_1.AdminTaxTools(this.connection);
91
- this.facetTools = new admin_facet_tools_1.AdminFacetTools(this.connection);
92
- this.settingsTools = new admin_settings_tools_1.AdminSettingsTools(this.connection);
93
- this.staffTools = new admin_staff_tools_1.AdminStaffTools(this.connection);
94
- this.promotionTools = new admin_promotion_tools_1.AdminPromotionTools(this.connection);
95
- this.countryTools = new admin_country_tools_1.AdminCountryTools(this.connection);
117
+ this.customerTools = new admin_customer_tools_1.AdminCustomerTools(this.connection, this.customerService);
118
+ this.collectionTools = new admin_collection_tools_1.AdminCollectionTools(this.connection, this.collectionService);
119
+ this.shippingTools = new admin_shipping_tools_1.AdminShippingTools(this.connection, this.shippingMethodService);
120
+ this.paymentTools = new admin_payment_tools_1.AdminPaymentTools(this.connection, this.paymentMethodService);
121
+ this.taxTools = new admin_tax_tools_1.AdminTaxTools(this.connection, this.taxCategoryService, this.taxRateService, this.zoneService);
122
+ this.facetTools = new admin_facet_tools_1.AdminFacetTools(this.connection, this.facetService, this.facetValueService);
123
+ this.settingsTools = new admin_settings_tools_1.AdminSettingsTools(this.connection, this.globalSettingsService, this.channelService, this.sellerService);
124
+ this.staffTools = new admin_staff_tools_1.AdminStaffTools(this.connection, this.administratorService, this.roleService);
125
+ this.promotionTools = new admin_promotion_tools_1.AdminPromotionTools(this.connection, this.promotionService);
126
+ this.countryTools = new admin_country_tools_1.AdminCountryTools(this.connection, this.countryService);
127
+ this.assetTools = new admin_asset_tools_1.AdminAssetTools(this.connection, this.assetService);
128
+ this.customerGroupTools = new admin_customer_group_tools_1.AdminCustomerGroupTools(this.connection, this.customerGroupService);
129
+ this.stockLocationTools = new admin_stock_location_tools_1.AdminStockLocationTools(this.connection, this.stockLocationService);
96
130
  }
97
131
  buildTools(ctx) {
98
132
  return {
99
- searchProducts: (0, ai_1.tool)({
100
- description: 'Search products by keyword. Returns product cards with images, prices, stock levels, and admin details.',
101
- inputSchema: zod_1.z.object({
102
- query: zod_1.z.string().describe('Search term or product name'),
103
- take: zod_1.z.number().optional().describe('Number of results (default 10, max 25)'),
104
- includeDisabled: zod_1.z.boolean().optional().describe('Include disabled products (default false)'),
105
- }),
106
- execute: async (args) => this.productTools.searchProducts(ctx, args),
107
- }),
108
- vectorSearch: (0, ai_1.tool)({
109
- description: 'Semantic/intent-based product search. Use for vague queries like "products for developers", "gaming accessories", "gifts for photographers". Falls back to this when keyword search returns no results.',
110
- inputSchema: zod_1.z.object({
111
- query: zod_1.z.string().describe('The semantic search query'),
112
- }),
113
- execute: async (args) => this.productTools.vectorSearch(ctx, args),
114
- }),
115
- getProductDetails: (0, ai_1.tool)({
116
- description: 'Get full details for a specific product including all variants with stock levels, prices, and SKUs.',
117
- inputSchema: zod_1.z.object({
118
- productId: zod_1.z.string().optional().describe('Product ID'),
119
- slug: zod_1.z.string().optional().describe('Product slug'),
120
- }),
121
- execute: async (args) => this.productTools.getProductDetails(ctx, args),
122
- }),
123
- searchOrders: (0, ai_1.tool)({
124
- description: 'Search orders across the store. Can filter by order code, customer name/email, or order state.',
125
- inputSchema: zod_1.z.object({
126
- orderCode: zod_1.z.string().optional().describe('Order code to search for (partial match)'),
127
- customerName: zod_1.z.string().optional().describe('Customer name or email to filter by'),
128
- state: zod_1.z.string().optional().describe('Order state filter (e.g. PaymentSettled, Shipped, Delivered)'),
129
- take: zod_1.z.number().optional().describe('Number of results (default 10, max 25)'),
130
- }),
131
- execute: async (args) => this.orderTools.searchOrders(ctx, args),
132
- }),
133
- searchCustomers: (0, ai_1.tool)({
134
- description: 'Search customers by name or email. Returns customer details including order count and total spent.',
135
- inputSchema: zod_1.z.object({
136
- query: zod_1.z.string().describe('Customer name or email to search for'),
137
- take: zod_1.z.number().optional().describe('Number of results (default 10, max 25)'),
138
- }),
139
- execute: async (args) => this.customerTools.searchCustomers(ctx, args),
140
- }),
141
- getCollections: (0, ai_1.tool)({
142
- description: 'List or search product collections/categories with product counts.',
143
- inputSchema: zod_1.z.object({
144
- query: zod_1.z.string().optional().describe('Optional search term to filter collections'),
145
- take: zod_1.z.number().optional().describe('Number of results (default 20, max 50)'),
146
- }),
147
- execute: async (args) => this.collectionTools.getCollections(ctx, args),
148
- }),
149
- getShippingMethods: (0, ai_1.tool)({
150
- description: 'List all shipping methods configured in the store. Shows code, fulfillment handler, and channel assignments.',
151
- inputSchema: zod_1.z.object({
152
- query: zod_1.z.string().optional().describe('Optional search term to filter by name or code'),
153
- take: zod_1.z.number().optional().describe('Number of results (default 20, max 50)'),
154
- includeDeleted: zod_1.z.boolean().optional().describe('Include soft-deleted shipping methods (default false)'),
155
- }),
156
- execute: async (args) => this.shippingTools.getShippingMethods(ctx, args),
157
- }),
158
- getPaymentMethods: (0, ai_1.tool)({
159
- description: 'List all payment methods configured in the store. Shows handler, enabled status, and channel assignments.',
160
- inputSchema: zod_1.z.object({
161
- query: zod_1.z.string().optional().describe('Optional search term to filter by name or code'),
162
- take: zod_1.z.number().optional().describe('Number of results (default 20, max 50)'),
163
- }),
164
- execute: async (args) => this.paymentTools.getPaymentMethods(ctx, args),
165
- }),
166
- getTaxRates: (0, ai_1.tool)({
167
- description: 'List tax rates with their categories and zones. Shows rate percentage, enabled status, and associated zone/category.',
168
- inputSchema: zod_1.z.object({
169
- query: zod_1.z.string().optional().describe('Optional search term to filter by name, category, or zone'),
170
- take: zod_1.z.number().optional().describe('Number of results (default 30, max 100)'),
171
- }),
172
- execute: async (args) => this.taxTools.getTaxRates(ctx, args),
173
- }),
174
- getTaxCategories: (0, ai_1.tool)({
175
- description: 'List tax categories (e.g. Standard, Reduced, Zero-rated).',
176
- inputSchema: zod_1.z.object({
177
- query: zod_1.z.string().optional().describe('Optional search term to filter by name'),
178
- take: zod_1.z.number().optional().describe('Number of results (default 30, max 50)'),
179
- }),
180
- execute: async (args) => this.taxTools.getTaxCategories(ctx, args),
181
- }),
182
- getZones: (0, ai_1.tool)({
183
- description: 'List tax/shipping zones with their member countries/regions.',
184
- inputSchema: zod_1.z.object({
185
- query: zod_1.z.string().optional().describe('Optional search term to filter by zone name'),
186
- take: zod_1.z.number().optional().describe('Number of results (default 30, max 50)'),
187
- }),
188
- execute: async (args) => this.taxTools.getZones(ctx, args),
189
- }),
190
- getFacets: (0, ai_1.tool)({
191
- description: 'List product facets (attributes like Color, Size, Brand) with their values. Useful for understanding product categorization.',
192
- inputSchema: zod_1.z.object({
193
- query: zod_1.z.string().optional().describe('Optional search term to filter by facet name or code'),
194
- take: zod_1.z.number().optional().describe('Number of results (default 20, max 50)'),
195
- }),
196
- execute: async (args) => this.facetTools.getFacets(ctx, args),
197
- }),
198
- getFacetValues: (0, ai_1.tool)({
199
- description: 'List facet values, optionally filtered by facet ID. E.g. for a "Color" facet: Red, Blue, Green.',
200
- inputSchema: zod_1.z.object({
201
- facetId: zod_1.z.string().optional().describe('Filter values to a specific facet by ID'),
202
- query: zod_1.z.string().optional().describe('Optional search term to filter by value name or code'),
203
- take: zod_1.z.number().optional().describe('Number of results (default 30, max 100)'),
204
- }),
205
- execute: async (args) => this.facetTools.getFacetValues(ctx, args),
206
- }),
207
- getGlobalSettings: (0, ai_1.tool)({
208
- description: 'Get global store settings including inventory tracking, out-of-stock threshold, and available languages.',
209
- inputSchema: zod_1.z.object({}),
210
- execute: async () => this.settingsTools.getGlobalSettings(ctx),
211
- }),
212
- getChannels: (0, ai_1.tool)({
213
- description: 'List all sales channels with their currency, language, tax zone, shipping zone, and seller configuration.',
214
- inputSchema: zod_1.z.object({
215
- query: zod_1.z.string().optional().describe('Optional search term to filter by channel code or description'),
216
- take: zod_1.z.number().optional().describe('Number of results (default 20, max 50)'),
217
- }),
218
- execute: async (args) => this.settingsTools.getChannels(ctx, args),
219
- }),
220
- getSellers: (0, ai_1.tool)({
221
- description: 'List sellers (marketplace vendors) in the store.',
222
- inputSchema: zod_1.z.object({
223
- query: zod_1.z.string().optional().describe('Optional search term to filter by seller name'),
224
- take: zod_1.z.number().optional().describe('Number of results (default 20, max 50)'),
225
- }),
226
- execute: async (args) => this.settingsTools.getSellers(ctx, args),
227
- }),
228
- getAdministrators: (0, ai_1.tool)({
229
- description: 'List admin users with their roles and email addresses.',
230
- inputSchema: zod_1.z.object({
231
- query: zod_1.z.string().optional().describe('Optional search term to filter by name or email'),
232
- take: zod_1.z.number().optional().describe('Number of results (default 20, max 50)'),
233
- }),
234
- execute: async (args) => this.staffTools.getAdministrators(ctx, args),
235
- }),
236
- getRoles: (0, ai_1.tool)({
237
- description: 'List admin roles with their permissions and channel assignments.',
133
+ // ── Products (read) ──
134
+ searchProducts: (0, ai_1.tool)({ description: 'Search products by keyword, or list all products if no query given. Returns product cards.', inputSchema: zod_1.z.object({ query: zod_1.z.string().optional().describe('Search term. Omit to list all products.'), take: zod_1.z.number().optional(), includeDisabled: zod_1.z.boolean().optional() }), execute: async (a) => this.productTools.searchProducts(ctx, a) }),
135
+ vectorSearch: (0, ai_1.tool)({ description: 'Semantic product search for vague queries like "gifts for dad".', inputSchema: zod_1.z.object({ query: zod_1.z.string() }), execute: async (a) => this.productTools.vectorSearch(ctx, a) }),
136
+ getProductDetails: (0, ai_1.tool)({ description: 'Get full product details by ID or slug including all variants.', inputSchema: zod_1.z.object({ productId: zod_1.z.string().optional(), slug: zod_1.z.string().optional() }), execute: async (a) => this.productTools.getProductDetails(ctx, a) }),
137
+ // ── Products (write) ──
138
+ createProduct: (0, ai_1.tool)({ description: 'Create a simple product without variants. Use createProductWithVariants for full creation.', inputSchema: zod_1.z.object({ name: zod_1.z.string(), slug: zod_1.z.string().optional(), description: zod_1.z.string().optional(), enabled: zod_1.z.boolean().optional() }), execute: async (a) => this.productTools.createProduct(ctx, a) }),
139
+ updateProduct: (0, ai_1.tool)({ description: 'Update a product name, slug, description, or enabled status.', inputSchema: zod_1.z.object({ productId: zod_1.z.string(), name: zod_1.z.string().optional(), slug: zod_1.z.string().optional(), description: zod_1.z.string().optional(), enabled: zod_1.z.boolean().optional() }), execute: async (a) => this.productTools.updateProduct(ctx, a) }),
140
+ deleteProduct: (0, ai_1.tool)({ description: 'Soft-delete a product by ID.', inputSchema: zod_1.z.object({ productId: zod_1.z.string() }), execute: async (a) => this.productTools.deleteProduct(ctx, a) }),
141
+ createProductWithVariants: (0, ai_1.tool)({ description: 'Create a complete product with option groups and variants. Each variant needs unique option values. Prices in cents.', inputSchema: zod_1.z.object({ name: zod_1.z.string(), slug: zod_1.z.string().optional(), description: zod_1.z.string().optional(), enabled: zod_1.z.boolean().optional(), optionGroups: zod_1.z.array(zod_1.z.object({ name: zod_1.z.string(), values: zod_1.z.array(zod_1.z.string()) })).optional().describe('Option groups like Color, Size'), variants: zod_1.z.array(zod_1.z.object({ name: zod_1.z.string(), sku: zod_1.z.string(), price: zod_1.z.number().describe('Price in cents'), stockOnHand: zod_1.z.number().optional(), optionValues: zod_1.z.array(zod_1.z.string()).optional().describe('Option values matching the option groups') })) }), execute: async (a) => this.productTools.createProductWithVariants(ctx, a) }),
142
+ updateProductVariant: (0, ai_1.tool)({ description: 'Update a variant price (cents), SKU, stock, or enabled status.', inputSchema: zod_1.z.object({ variantId: zod_1.z.string(), price: zod_1.z.number().optional(), sku: zod_1.z.string().optional(), stockOnHand: zod_1.z.number().optional(), enabled: zod_1.z.boolean().optional() }), execute: async (a) => this.productTools.updateProductVariant(ctx, a) }),
143
+ deleteProductVariant: (0, ai_1.tool)({ description: 'Soft-delete a product variant.', inputSchema: zod_1.z.object({ variantId: zod_1.z.string() }), execute: async (a) => this.productTools.deleteProductVariant(ctx, a) }),
144
+ // ── Orders (read) ──
145
+ searchOrders: (0, ai_1.tool)({ description: 'Search orders by code, customer name/email, or state.', inputSchema: zod_1.z.object({ orderCode: zod_1.z.string().optional(), customerName: zod_1.z.string().optional(), state: zod_1.z.string().optional(), take: zod_1.z.number().optional() }), execute: async (a) => this.orderTools.searchOrders(ctx, a) }),
146
+ getOrderDetails: (0, ai_1.tool)({ description: 'Get full order details including lines, payments, fulfillments, addresses.', inputSchema: zod_1.z.object({ orderId: zod_1.z.string().optional(), orderCode: zod_1.z.string().optional() }), execute: async (a) => this.orderTools.getOrderDetails(ctx, a) }),
147
+ // ── Customers (read) ──
148
+ searchCustomers: (0, ai_1.tool)({ description: 'Search customers by name or email, or list all customers if no query given.', inputSchema: zod_1.z.object({ query: zod_1.z.string().optional().describe('Search term. Omit to list all customers.'), take: zod_1.z.number().optional() }), execute: async (a) => this.customerTools.searchCustomers(ctx, a) }),
149
+ getCustomerDetails: (0, ai_1.tool)({ description: 'Get full customer details: addresses, orders, groups.', inputSchema: zod_1.z.object({ customerId: zod_1.z.string() }), execute: async (a) => this.customerTools.getCustomerDetails(ctx, a) }),
150
+ // ── Customers (write) ──
151
+ createCustomer: (0, ai_1.tool)({ description: 'Create a new customer.', inputSchema: zod_1.z.object({ firstName: zod_1.z.string(), lastName: zod_1.z.string(), emailAddress: zod_1.z.string(), phoneNumber: zod_1.z.string().optional(), title: zod_1.z.string().optional() }), execute: async (a) => this.customerTools.createCustomer(ctx, a) }),
152
+ updateCustomer: (0, ai_1.tool)({ description: 'Update customer details.', inputSchema: zod_1.z.object({ customerId: zod_1.z.string(), firstName: zod_1.z.string().optional(), lastName: zod_1.z.string().optional(), emailAddress: zod_1.z.string().optional(), phoneNumber: zod_1.z.string().optional() }), execute: async (a) => this.customerTools.updateCustomer(ctx, a) }),
153
+ deleteCustomer: (0, ai_1.tool)({ description: 'Soft-delete a customer.', inputSchema: zod_1.z.object({ customerId: zod_1.z.string() }), execute: async (a) => this.customerTools.deleteCustomer(ctx, a) }),
154
+ createCustomerAddress: (0, ai_1.tool)({ description: 'Create an address for a customer.', inputSchema: zod_1.z.object({ customerId: zod_1.z.string(), fullName: zod_1.z.string(), streetLine1: zod_1.z.string(), streetLine2: zod_1.z.string().optional(), city: zod_1.z.string(), province: zod_1.z.string(), postalCode: zod_1.z.string(), countryCode: zod_1.z.string(), phoneNumber: zod_1.z.string().optional(), company: zod_1.z.string().optional(), defaultShippingAddress: zod_1.z.boolean().optional(), defaultBillingAddress: zod_1.z.boolean().optional() }), execute: async (a) => this.customerTools.createCustomerAddress(ctx, a) }),
155
+ addNoteToCustomer: (0, ai_1.tool)({ description: 'Add a note to customer history.', inputSchema: zod_1.z.object({ customerId: zod_1.z.string(), note: zod_1.z.string(), isPublic: zod_1.z.boolean().optional() }), execute: async (a) => this.customerTools.addNoteToCustomer(ctx, a) }),
156
+ // ── Collections (read + write) ──
157
+ getCollections: (0, ai_1.tool)({ description: 'List or search collections.', inputSchema: zod_1.z.object({ query: zod_1.z.string().optional(), take: zod_1.z.number().optional() }), execute: async (a) => this.collectionTools.getCollections(ctx, a) }),
158
+ createCollection: (0, ai_1.tool)({ description: 'Create a new collection. Filters define which products are included (e.g. facet-value-filter).', inputSchema: zod_1.z.object({ name: zod_1.z.string(), slug: zod_1.z.string().optional(), description: zod_1.z.string().optional(), parentId: zod_1.z.string().optional(), isPrivate: zod_1.z.boolean().optional(), filters: zod_1.z.array(zod_1.z.object({ code: zod_1.z.string(), args: zod_1.z.record(zod_1.z.string(), zod_1.z.string()) })).optional() }), execute: async (a) => this.collectionTools.createCollection(ctx, a) }),
159
+ updateCollection: (0, ai_1.tool)({ description: 'Update a collection.', inputSchema: zod_1.z.object({ collectionId: zod_1.z.string(), name: zod_1.z.string().optional(), slug: zod_1.z.string().optional(), description: zod_1.z.string().optional(), isPrivate: zod_1.z.boolean().optional() }), execute: async (a) => this.collectionTools.updateCollection(ctx, a) }),
160
+ deleteCollection: (0, ai_1.tool)({ description: 'Delete a collection and its descendants.', inputSchema: zod_1.z.object({ collectionId: zod_1.z.string() }), execute: async (a) => this.collectionTools.deleteCollection(ctx, a) }),
161
+ moveCollection: (0, ai_1.tool)({ description: 'Move a collection to a different parent.', inputSchema: zod_1.z.object({ collectionId: zod_1.z.string(), parentId: zod_1.z.string(), index: zod_1.z.number() }), execute: async (a) => this.collectionTools.moveCollection(ctx, a) }),
162
+ // ── Facets (read + write) ──
163
+ getFacets: (0, ai_1.tool)({ description: 'List facets with values.', inputSchema: zod_1.z.object({ query: zod_1.z.string().optional(), take: zod_1.z.number().optional() }), execute: async (a) => this.facetTools.getFacets(ctx, a) }),
164
+ getFacetValues: (0, ai_1.tool)({ description: 'List facet values, optionally by facet ID.', inputSchema: zod_1.z.object({ facetId: zod_1.z.string().optional(), query: zod_1.z.string().optional(), take: zod_1.z.number().optional() }), execute: async (a) => this.facetTools.getFacetValues(ctx, a) }),
165
+ createFacet: (0, ai_1.tool)({ description: 'Create a new facet with optional initial values.', inputSchema: zod_1.z.object({ name: zod_1.z.string(), code: zod_1.z.string(), isPrivate: zod_1.z.boolean().optional(), values: zod_1.z.array(zod_1.z.object({ name: zod_1.z.string(), code: zod_1.z.string() })).optional() }), execute: async (a) => this.facetTools.createFacet(ctx, a) }),
166
+ updateFacet: (0, ai_1.tool)({ description: 'Update a facet name, code, or privacy.', inputSchema: zod_1.z.object({ facetId: zod_1.z.string(), name: zod_1.z.string().optional(), code: zod_1.z.string().optional(), isPrivate: zod_1.z.boolean().optional() }), execute: async (a) => this.facetTools.updateFacet(ctx, a) }),
167
+ deleteFacet: (0, ai_1.tool)({ description: 'Delete a facet. Use force=true to delete even if in use.', inputSchema: zod_1.z.object({ facetId: zod_1.z.string(), force: zod_1.z.boolean().optional() }), execute: async (a) => this.facetTools.deleteFacet(ctx, a) }),
168
+ createFacetValues: (0, ai_1.tool)({ description: 'Add values to an existing facet.', inputSchema: zod_1.z.object({ facetId: zod_1.z.string(), values: zod_1.z.array(zod_1.z.object({ name: zod_1.z.string(), code: zod_1.z.string() })) }), execute: async (a) => this.facetTools.createFacetValues(ctx, a) }),
169
+ updateFacetValue: (0, ai_1.tool)({ description: 'Update a facet value name or code.', inputSchema: zod_1.z.object({ facetValueId: zod_1.z.string(), name: zod_1.z.string().optional(), code: zod_1.z.string().optional() }), execute: async (a) => this.facetTools.updateFacetValue(ctx, a) }),
170
+ deleteFacetValues: (0, ai_1.tool)({ description: 'Delete facet values by IDs.', inputSchema: zod_1.z.object({ facetValueIds: zod_1.z.array(zod_1.z.string()), force: zod_1.z.boolean().optional() }), execute: async (a) => this.facetTools.deleteFacetValues(ctx, a) }),
171
+ // ── Shipping Methods ──
172
+ getShippingMethods: (0, ai_1.tool)({ description: 'List shipping methods.', inputSchema: zod_1.z.object({ query: zod_1.z.string().optional(), take: zod_1.z.number().optional(), includeDeleted: zod_1.z.boolean().optional() }), execute: async (a) => this.shippingTools.getShippingMethods(ctx, a) }),
173
+ createShippingMethod: (0, ai_1.tool)({ description: 'Create a shipping method.', inputSchema: zod_1.z.object({ name: zod_1.z.string(), code: zod_1.z.string(), description: zod_1.z.string().optional(), fulfillmentHandler: zod_1.z.string().describe('e.g. manual-fulfillment') }), execute: async (a) => this.shippingTools.createShippingMethod(ctx, a) }),
174
+ updateShippingMethod: (0, ai_1.tool)({ description: 'Update a shipping method.', inputSchema: zod_1.z.object({ shippingMethodId: zod_1.z.string(), name: zod_1.z.string().optional(), code: zod_1.z.string().optional(), description: zod_1.z.string().optional() }), execute: async (a) => this.shippingTools.updateShippingMethod(ctx, a) }),
175
+ deleteShippingMethod: (0, ai_1.tool)({ description: 'Soft-delete a shipping method.', inputSchema: zod_1.z.object({ shippingMethodId: zod_1.z.string() }), execute: async (a) => this.shippingTools.deleteShippingMethod(ctx, a) }),
176
+ // ── Payment Methods ──
177
+ getPaymentMethods: (0, ai_1.tool)({ description: 'List payment methods.', inputSchema: zod_1.z.object({ query: zod_1.z.string().optional(), take: zod_1.z.number().optional() }), execute: async (a) => this.paymentTools.getPaymentMethods(ctx, a) }),
178
+ createPaymentMethod: (0, ai_1.tool)({ description: 'Create a payment method.', inputSchema: zod_1.z.object({ name: zod_1.z.string(), code: zod_1.z.string(), description: zod_1.z.string().optional(), enabled: zod_1.z.boolean().optional(), handlerCode: zod_1.z.string().describe('e.g. dummy-payment-handler') }), execute: async (a) => this.paymentTools.createPaymentMethod(ctx, a) }),
179
+ updatePaymentMethod: (0, ai_1.tool)({ description: 'Update a payment method.', inputSchema: zod_1.z.object({ paymentMethodId: zod_1.z.string(), name: zod_1.z.string().optional(), code: zod_1.z.string().optional(), description: zod_1.z.string().optional(), enabled: zod_1.z.boolean().optional() }), execute: async (a) => this.paymentTools.updatePaymentMethod(ctx, a) }),
180
+ deletePaymentMethod: (0, ai_1.tool)({ description: 'Delete a payment method.', inputSchema: zod_1.z.object({ paymentMethodId: zod_1.z.string(), force: zod_1.z.boolean().optional() }), execute: async (a) => this.paymentTools.deletePaymentMethod(ctx, a) }),
181
+ // ── Tax ──
182
+ getTaxRates: (0, ai_1.tool)({ description: 'List tax rates.', inputSchema: zod_1.z.object({ query: zod_1.z.string().optional(), take: zod_1.z.number().optional() }), execute: async (a) => this.taxTools.getTaxRates(ctx, a) }),
183
+ getTaxCategories: (0, ai_1.tool)({ description: 'List tax categories.', inputSchema: zod_1.z.object({ query: zod_1.z.string().optional(), take: zod_1.z.number().optional() }), execute: async (a) => this.taxTools.getTaxCategories(ctx, a) }),
184
+ getZones: (0, ai_1.tool)({ description: 'List zones with member countries.', inputSchema: zod_1.z.object({ query: zod_1.z.string().optional(), take: zod_1.z.number().optional() }), execute: async (a) => this.taxTools.getZones(ctx, a) }),
185
+ createTaxCategory: (0, ai_1.tool)({ description: 'Create a tax category.', inputSchema: zod_1.z.object({ name: zod_1.z.string(), isDefault: zod_1.z.boolean().optional() }), execute: async (a) => this.taxTools.createTaxCategory(ctx, a) }),
186
+ updateTaxCategory: (0, ai_1.tool)({ description: 'Update a tax category.', inputSchema: zod_1.z.object({ taxCategoryId: zod_1.z.string(), name: zod_1.z.string().optional(), isDefault: zod_1.z.boolean().optional() }), execute: async (a) => this.taxTools.updateTaxCategory(ctx, a) }),
187
+ deleteTaxCategory: (0, ai_1.tool)({ description: 'Delete a tax category.', inputSchema: zod_1.z.object({ taxCategoryId: zod_1.z.string() }), execute: async (a) => this.taxTools.deleteTaxCategory(ctx, a) }),
188
+ createTaxRate: (0, ai_1.tool)({ description: 'Create a tax rate. Value is percentage (e.g. 20 for 20%).', inputSchema: zod_1.z.object({ name: zod_1.z.string(), value: zod_1.z.number(), enabled: zod_1.z.boolean().optional(), categoryId: zod_1.z.string(), zoneId: zod_1.z.string(), customerGroupId: zod_1.z.string().optional() }), execute: async (a) => this.taxTools.createTaxRate(ctx, a) }),
189
+ updateTaxRate: (0, ai_1.tool)({ description: 'Update a tax rate.', inputSchema: zod_1.z.object({ taxRateId: zod_1.z.string(), name: zod_1.z.string().optional(), value: zod_1.z.number().optional(), enabled: zod_1.z.boolean().optional() }), execute: async (a) => this.taxTools.updateTaxRate(ctx, a) }),
190
+ deleteTaxRate: (0, ai_1.tool)({ description: 'Delete a tax rate.', inputSchema: zod_1.z.object({ taxRateId: zod_1.z.string() }), execute: async (a) => this.taxTools.deleteTaxRate(ctx, a) }),
191
+ createZone: (0, ai_1.tool)({ description: 'Create a zone with optional country member IDs.', inputSchema: zod_1.z.object({ name: zod_1.z.string(), memberIds: zod_1.z.array(zod_1.z.string()).optional() }), execute: async (a) => this.taxTools.createZone(ctx, a) }),
192
+ updateZone: (0, ai_1.tool)({ description: 'Update a zone name.', inputSchema: zod_1.z.object({ zoneId: zod_1.z.string(), name: zod_1.z.string().optional() }), execute: async (a) => this.taxTools.updateZone(ctx, a) }),
193
+ deleteZone: (0, ai_1.tool)({ description: 'Delete a zone.', inputSchema: zod_1.z.object({ zoneId: zod_1.z.string() }), execute: async (a) => this.taxTools.deleteZone(ctx, a) }),
194
+ addMembersToZone: (0, ai_1.tool)({ description: 'Add countries to a zone.', inputSchema: zod_1.z.object({ zoneId: zod_1.z.string(), memberIds: zod_1.z.array(zod_1.z.string()) }), execute: async (a) => this.taxTools.addMembersToZone(ctx, a) }),
195
+ removeMembersFromZone: (0, ai_1.tool)({ description: 'Remove countries from a zone.', inputSchema: zod_1.z.object({ zoneId: zod_1.z.string(), memberIds: zod_1.z.array(zod_1.z.string()) }), execute: async (a) => this.taxTools.removeMembersFromZone(ctx, a) }),
196
+ // ── Countries ──
197
+ getCountries: (0, ai_1.tool)({ description: 'List countries.', inputSchema: zod_1.z.object({ query: zod_1.z.string().optional(), enabledOnly: zod_1.z.boolean().optional(), take: zod_1.z.number().optional() }), execute: async (a) => this.countryTools.getCountries(ctx, a) }),
198
+ createCountry: (0, ai_1.tool)({ description: 'Create a country with ISO code.', inputSchema: zod_1.z.object({ code: zod_1.z.string().describe('ISO 2-letter code'), name: zod_1.z.string(), enabled: zod_1.z.boolean().optional() }), execute: async (a) => this.countryTools.createCountry(ctx, a) }),
199
+ updateCountry: (0, ai_1.tool)({ description: 'Update a country.', inputSchema: zod_1.z.object({ countryId: zod_1.z.string(), name: zod_1.z.string().optional(), code: zod_1.z.string().optional(), enabled: zod_1.z.boolean().optional() }), execute: async (a) => this.countryTools.updateCountry(ctx, a) }),
200
+ deleteCountry: (0, ai_1.tool)({ description: 'Delete a country.', inputSchema: zod_1.z.object({ countryId: zod_1.z.string() }), execute: async (a) => this.countryTools.deleteCountry(ctx, a) }),
201
+ // ── Administrators & Roles ──
202
+ getAdministrators: (0, ai_1.tool)({ description: 'List admin users.', inputSchema: zod_1.z.object({ query: zod_1.z.string().optional(), take: zod_1.z.number().optional() }), execute: async (a) => this.staffTools.getAdministrators(ctx, a) }),
203
+ getRoles: (0, ai_1.tool)({ description: 'List admin roles with permissions.', inputSchema: zod_1.z.object({ query: zod_1.z.string().optional(), take: zod_1.z.number().optional() }), execute: async (a) => this.staffTools.getRoles(ctx, a) }),
204
+ createAdministrator: (0, ai_1.tool)({ description: 'Create a new admin user.', inputSchema: zod_1.z.object({ firstName: zod_1.z.string(), lastName: zod_1.z.string(), emailAddress: zod_1.z.string(), password: zod_1.z.string(), roleIds: zod_1.z.array(zod_1.z.string()) }), execute: async (a) => this.staffTools.createAdministrator(ctx, a) }),
205
+ updateAdministrator: (0, ai_1.tool)({ description: 'Update an admin user.', inputSchema: zod_1.z.object({ administratorId: zod_1.z.string(), firstName: zod_1.z.string().optional(), lastName: zod_1.z.string().optional(), emailAddress: zod_1.z.string().optional(), password: zod_1.z.string().optional(), roleIds: zod_1.z.array(zod_1.z.string()).optional() }), execute: async (a) => this.staffTools.updateAdministrator(ctx, a) }),
206
+ deleteAdministrator: (0, ai_1.tool)({ description: 'Soft-delete an admin user.', inputSchema: zod_1.z.object({ administratorId: zod_1.z.string() }), execute: async (a) => this.staffTools.deleteAdministrator(ctx, a) }),
207
+ createRole: (0, ai_1.tool)({ description: 'Create a role with permissions. Valid permissions follow the pattern: Read/Create/Update/Delete + Entity (e.g. ReadProduct, CreateOrder, UpdateCustomer, DeleteCollection). Also: SuperAdmin, Authenticated, Owner, Public. Full list includes: ReadProduct, CreateProduct, UpdateProduct, DeleteProduct, ReadOrder, CreateOrder, UpdateOrder, DeleteOrder, ReadCustomer, CreateCustomer, UpdateCustomer, DeleteCustomer, ReadCatalog, CreateCatalog, UpdateCatalog, DeleteCatalog, ReadCollection, CreateCollection, etc.', inputSchema: zod_1.z.object({ code: zod_1.z.string(), description: zod_1.z.string(), permissions: zod_1.z.array(zod_1.z.string()).describe('e.g. ["ReadProduct","CreateProduct","ReadOrder","UpdateOrder"]'), channelIds: zod_1.z.array(zod_1.z.string()).optional() }), execute: async (a) => this.staffTools.createRole(ctx, a) }),
208
+ updateRole: (0, ai_1.tool)({ description: 'Update a role.', inputSchema: zod_1.z.object({ roleId: zod_1.z.string(), code: zod_1.z.string().optional(), description: zod_1.z.string().optional(), permissions: zod_1.z.array(zod_1.z.string()).optional() }), execute: async (a) => this.staffTools.updateRole(ctx, a) }),
209
+ deleteRole: (0, ai_1.tool)({ description: 'Delete a role.', inputSchema: zod_1.z.object({ roleId: zod_1.z.string() }), execute: async (a) => this.staffTools.deleteRole(ctx, a) }),
210
+ // ── Settings, Channels, Sellers ──
211
+ getStoreOverview: (0, ai_1.tool)({ description: 'Get a quick overview of the store: total counts for products, variants, orders, customers, collections, shipping methods, payment methods, tax rates, promotions, facets, and administrators. Use this when the user asks for a store summary or "how many products/customers/orders do we have".', inputSchema: zod_1.z.object({}), execute: async () => this.settingsTools.getStoreOverview(ctx) }),
212
+ getGlobalSettings: (0, ai_1.tool)({ description: 'Get global store settings.', inputSchema: zod_1.z.object({}), execute: async () => this.settingsTools.getGlobalSettings(ctx) }),
213
+ updateGlobalSettings: (0, ai_1.tool)({ description: 'Update global settings like inventory tracking.', inputSchema: zod_1.z.object({ trackInventory: zod_1.z.boolean().optional(), outOfStockThreshold: zod_1.z.number().optional(), availableLanguages: zod_1.z.array(zod_1.z.string()).optional() }), execute: async (a) => this.settingsTools.updateGlobalSettings(ctx, a) }),
214
+ getChannels: (0, ai_1.tool)({ description: 'List sales channels.', inputSchema: zod_1.z.object({ query: zod_1.z.string().optional(), take: zod_1.z.number().optional() }), execute: async (a) => this.settingsTools.getChannels(ctx, a) }),
215
+ createChannel: (0, ai_1.tool)({ description: 'Create a sales channel.', inputSchema: zod_1.z.object({ code: zod_1.z.string(), token: zod_1.z.string(), defaultLanguageCode: zod_1.z.string(), defaultCurrencyCode: zod_1.z.string(), pricesIncludeTax: zod_1.z.boolean() }), execute: async (a) => this.settingsTools.createChannel(ctx, a) }),
216
+ updateChannel: (0, ai_1.tool)({ description: 'Update a channel.', inputSchema: zod_1.z.object({ channelId: zod_1.z.string(), code: zod_1.z.string().optional(), defaultLanguageCode: zod_1.z.string().optional(), defaultCurrencyCode: zod_1.z.string().optional(), pricesIncludeTax: zod_1.z.boolean().optional() }), execute: async (a) => this.settingsTools.updateChannel(ctx, a) }),
217
+ deleteChannel: (0, ai_1.tool)({ description: 'Delete a channel.', inputSchema: zod_1.z.object({ channelId: zod_1.z.string() }), execute: async (a) => this.settingsTools.deleteChannel(ctx, a) }),
218
+ getSellers: (0, ai_1.tool)({ description: 'List sellers.', inputSchema: zod_1.z.object({ query: zod_1.z.string().optional(), take: zod_1.z.number().optional() }), execute: async (a) => this.settingsTools.getSellers(ctx, a) }),
219
+ createSeller: (0, ai_1.tool)({ description: 'Create a seller.', inputSchema: zod_1.z.object({ name: zod_1.z.string() }), execute: async (a) => this.settingsTools.createSeller(ctx, a) }),
220
+ updateSeller: (0, ai_1.tool)({ description: 'Update a seller.', inputSchema: zod_1.z.object({ sellerId: zod_1.z.string(), name: zod_1.z.string().optional() }), execute: async (a) => this.settingsTools.updateSeller(ctx, a) }),
221
+ deleteSeller: (0, ai_1.tool)({ description: 'Delete a seller.', inputSchema: zod_1.z.object({ sellerId: zod_1.z.string() }), execute: async (a) => this.settingsTools.deleteSeller(ctx, a) }),
222
+ // ── Promotions ──
223
+ getPromotions: (0, ai_1.tool)({ description: 'List promotions/discounts.', inputSchema: zod_1.z.object({ query: zod_1.z.string().optional(), activeOnly: zod_1.z.boolean().optional(), take: zod_1.z.number().optional() }), execute: async (a) => this.promotionTools.getPromotions(ctx, a) }),
224
+ getPromotionConditionsAndActions: (0, ai_1.tool)({ description: 'List all available promotion condition and action codes with their argument formats. ALWAYS call this before creating a promotion to get the correct codes and argument formats.', inputSchema: zod_1.z.object({}), execute: async () => this.promotionTools.getPromotionConditionsAndActions(ctx) }),
225
+ createPromotion: (0, ai_1.tool)({ description: 'Create a promotion. IMPORTANT: Call getPromotionConditionsAndActions first to get valid codes. Conditions: minimum_order_amount, customer_group, contains_products, at_least_n_with_facets, buy_x_get_y_free. Actions: order_percentage_discount, order_fixed_discount, products_percentage_discount, free_shipping, buy_x_get_y_free. All arg values must be strings.', inputSchema: zod_1.z.object({ name: zod_1.z.string(), enabled: zod_1.z.boolean().optional(), couponCode: zod_1.z.string().optional(), startsAt: zod_1.z.string().optional(), endsAt: zod_1.z.string().optional(), perCustomerUsageLimit: zod_1.z.number().optional(), usageLimit: zod_1.z.number().optional(), conditions: zod_1.z.array(zod_1.z.object({ code: zod_1.z.string(), args: zod_1.z.record(zod_1.z.string(), zod_1.z.string()) })).optional(), actions: zod_1.z.array(zod_1.z.object({ code: zod_1.z.string(), args: zod_1.z.record(zod_1.z.string(), zod_1.z.string()) })).optional() }), execute: async (a) => this.promotionTools.createPromotion(ctx, a) }),
226
+ updatePromotion: (0, ai_1.tool)({ description: 'Update a promotion.', inputSchema: zod_1.z.object({ promotionId: zod_1.z.string(), name: zod_1.z.string().optional(), enabled: zod_1.z.boolean().optional(), couponCode: zod_1.z.string().optional() }), execute: async (a) => this.promotionTools.updatePromotion(ctx, a) }),
227
+ deletePromotion: (0, ai_1.tool)({ description: 'Soft-delete a promotion.', inputSchema: zod_1.z.object({ promotionId: zod_1.z.string() }), execute: async (a) => this.promotionTools.deletePromotion(ctx, a) }),
228
+ // ── Assets ──
229
+ getAssets: (0, ai_1.tool)({ description: 'List assets (images, files). Filter by name or tags.', inputSchema: zod_1.z.object({ query: zod_1.z.string().optional(), tags: zod_1.z.array(zod_1.z.string()).optional(), take: zod_1.z.number().optional() }), execute: async (a) => this.assetTools.getAssets(ctx, a) }),
230
+ deleteAsset: (0, ai_1.tool)({ description: 'Delete an asset. Use force=true to delete even if assigned.', inputSchema: zod_1.z.object({ assetId: zod_1.z.string(), force: zod_1.z.boolean().optional() }), execute: async (a) => this.assetTools.deleteAsset(ctx, a) }),
231
+ // ── Customer Groups ──
232
+ getCustomerGroups: (0, ai_1.tool)({ description: 'List customer groups with member counts.', inputSchema: zod_1.z.object({ query: zod_1.z.string().optional(), take: zod_1.z.number().optional() }), execute: async (a) => this.customerGroupTools.getCustomerGroups(ctx, a) }),
233
+ createCustomerGroup: (0, ai_1.tool)({ description: 'Create a customer group.', inputSchema: zod_1.z.object({ name: zod_1.z.string(), customerIds: zod_1.z.array(zod_1.z.string()).optional() }), execute: async (a) => this.customerGroupTools.createCustomerGroup(ctx, a) }),
234
+ updateCustomerGroup: (0, ai_1.tool)({ description: 'Rename a customer group.', inputSchema: zod_1.z.object({ customerGroupId: zod_1.z.string(), name: zod_1.z.string().optional() }), execute: async (a) => this.customerGroupTools.updateCustomerGroup(ctx, a) }),
235
+ deleteCustomerGroup: (0, ai_1.tool)({ description: 'Delete a customer group.', inputSchema: zod_1.z.object({ customerGroupId: zod_1.z.string() }), execute: async (a) => this.customerGroupTools.deleteCustomerGroup(ctx, a) }),
236
+ addCustomersToGroup: (0, ai_1.tool)({ description: 'Add customers to a group.', inputSchema: zod_1.z.object({ customerGroupId: zod_1.z.string(), customerIds: zod_1.z.array(zod_1.z.string()) }), execute: async (a) => this.customerGroupTools.addCustomersToGroup(ctx, a) }),
237
+ removeCustomersFromGroup: (0, ai_1.tool)({ description: 'Remove customers from a group.', inputSchema: zod_1.z.object({ customerGroupId: zod_1.z.string(), customerIds: zod_1.z.array(zod_1.z.string()) }), execute: async (a) => this.customerGroupTools.removeCustomersFromGroup(ctx, a) }),
238
+ // ── Stock Locations ──
239
+ getStockLocations: (0, ai_1.tool)({ description: 'List stock/warehouse locations.', inputSchema: zod_1.z.object({ query: zod_1.z.string().optional(), take: zod_1.z.number().optional() }), execute: async (a) => this.stockLocationTools.getStockLocations(ctx, a) }),
240
+ createStockLocation: (0, ai_1.tool)({ description: 'Create a stock location.', inputSchema: zod_1.z.object({ name: zod_1.z.string(), description: zod_1.z.string().optional() }), execute: async (a) => this.stockLocationTools.createStockLocation(ctx, a) }),
241
+ updateStockLocation: (0, ai_1.tool)({ description: 'Update a stock location.', inputSchema: zod_1.z.object({ stockLocationId: zod_1.z.string(), name: zod_1.z.string().optional(), description: zod_1.z.string().optional() }), execute: async (a) => this.stockLocationTools.updateStockLocation(ctx, a) }),
242
+ deleteStockLocation: (0, ai_1.tool)({ description: 'Delete a stock location. Optionally transfer stock to another location.', inputSchema: zod_1.z.object({ stockLocationId: zod_1.z.string(), transferToLocationId: zod_1.z.string().optional() }), execute: async (a) => this.stockLocationTools.deleteStockLocation(ctx, a) }),
243
+ // ── Navigation ──
244
+ navigateToPage: (0, ai_1.tool)({
245
+ description: `Navigate the admin user to a dashboard page. Use this when the user asks to "go to", "open", "show me", "take me to", or "navigate to" a page.
246
+ IMPORTANT: Paths must NOT include /dashboard prefix. All routes are relative, flat paths.
247
+ Available pages:
248
+ - / — Dashboard home
249
+ - /products Products list
250
+ - /products/{id} Product detail (need product ID)
251
+ - /orders — Orders list
252
+ - /orders/{id} Order detail (need order ID)
253
+ - /customers — Customers list
254
+ - /customers/{id} — Customer detail (need customer ID)
255
+ - /collections Collections list
256
+ - /facets — Facets list
257
+ - /assets Assets list
258
+ - /option-groups Option groups
259
+ - /promotions — Promotions list
260
+ - /shipping-methods Shipping methods
261
+ - /payment-methods — Payment methods
262
+ - /tax-categories — Tax categories
263
+ - /tax-rates Tax rates
264
+ - /zones — Zones
265
+ - /countries Countries
266
+ - /channels Channels
267
+ - /administrators — Administrators
268
+ - /roles Roles
269
+ - /global-settings — Global settings
270
+ - /sellers — Sellers
271
+ - /stock-locations Stock locations
272
+ - /customer-groups — Customer groups
273
+ - /extensions/pages — Page Builder
274
+ - /extensions/ai-chat — AI Chat (full view)
275
+ - /extensions/ai-dashboard — AI Dashboard
276
+ If the user asks to go to a specific entity (e.g. "go to product Laptop"), first search for it to get the ID, then navigate to /products/{id}.`,
238
277
  inputSchema: zod_1.z.object({
239
- query: zod_1.z.string().optional().describe('Optional search term to filter by role code or description'),
240
- take: zod_1.z.number().optional().describe('Number of results (default 20, max 50)'),
278
+ path: zod_1.z.string().describe('The relative path to navigate to, e.g. /products do NOT include /dashboard prefix'),
279
+ reason: zod_1.z.string().optional().describe('Brief reason for navigating'),
241
280
  }),
242
- execute: async (args) => this.staffTools.getRoles(ctx, args),
243
- }),
244
- getPromotions: (0, ai_1.tool)({
245
- description: 'List promotions/discounts with their coupon codes, conditions, actions, and date ranges.',
246
- inputSchema: zod_1.z.object({
247
- query: zod_1.z.string().optional().describe('Optional search term to filter by name or coupon code'),
248
- activeOnly: zod_1.z.boolean().optional().describe('Only show currently active promotions (default false)'),
249
- take: zod_1.z.number().optional().describe('Number of results (default 20, max 50)'),
250
- }),
251
- execute: async (args) => this.promotionTools.getPromotions(ctx, args),
252
- }),
253
- getCountries: (0, ai_1.tool)({
254
- description: 'List countries configured in the store with their codes and enabled status.',
255
- inputSchema: zod_1.z.object({
256
- query: zod_1.z.string().optional().describe('Optional search term to filter by country name or code'),
257
- enabledOnly: zod_1.z.boolean().optional().describe('Only show enabled countries (default false)'),
258
- take: zod_1.z.number().optional().describe('Number of results (default 30, max 100)'),
259
- }),
260
- execute: async (args) => this.countryTools.getCountries(ctx, args),
281
+ execute: async (a) => { var _a; return ({ navigateTo: a.path, reason: (_a = a.reason) !== null && _a !== void 0 ? _a : 'Navigating as requested' }); },
261
282
  }),
262
283
  };
263
284
  }
264
- async chat(ctx, userMessage, conversationHistory = []) {
265
- var _a, _b, _c, _d;
285
+ async chat(ctx, userMessage, conversationHistory = [], currentPage) {
286
+ let systemPrompt = admin_system_prompt_1.ADMIN_SYSTEM_PROMPT;
287
+ if (currentPage) {
288
+ systemPrompt += `\n\n## Current context\nThe admin user is currently viewing: ${currentPage}`;
289
+ }
266
290
  const messages = [
267
- { role: 'system', content: admin_system_prompt_1.ADMIN_SYSTEM_PROMPT },
291
+ { role: 'system', content: systemPrompt },
268
292
  ...conversationHistory,
269
293
  { role: 'user', content: userMessage },
270
294
  ];
271
295
  const tools = this.buildTools(ctx);
296
+ // Try OpenAI first, fall back to Azure if available
297
+ try {
298
+ return await this.runChat(this.openai('gpt-4o-mini'), messages, tools);
299
+ }
300
+ catch (primaryError) {
301
+ this.logger.error(`Primary OpenAI failed: ${primaryError}`);
302
+ if (this.azure) {
303
+ this.logger.log('Falling back to Azure OpenAI...');
304
+ try {
305
+ return await this.runChat(this.azure(this.azureDeploymentName), messages, tools);
306
+ }
307
+ catch (fallbackError) {
308
+ this.logger.error(`Azure fallback also failed: ${fallbackError}`);
309
+ throw fallbackError;
310
+ }
311
+ }
312
+ throw primaryError;
313
+ }
314
+ }
315
+ async runChat(model, messages, tools) {
316
+ var _a, _b, _c, _d, _e, _f, _g;
272
317
  const result = (0, ai_1.streamText)({
273
- model: this.openai('gpt-4o-mini'),
318
+ model,
274
319
  messages,
275
320
  tools,
276
321
  stopWhen: (0, ai_1.stepCountIs)(5),
@@ -279,7 +324,7 @@ let AdminAiChatService = AdminAiChatService_1 = class AdminAiChatService {
279
324
  onStepFinish: (step) => {
280
325
  if (step.toolResults && step.toolResults.length > 0) {
281
326
  for (const tr of step.toolResults) {
282
- this.logger.debug(`Admin tool "${tr.toolName}" completed`);
327
+ this.logger.log(`Admin tool "${tr.toolName}" completed`);
283
328
  }
284
329
  }
285
330
  },
@@ -287,11 +332,11 @@ let AdminAiChatService = AdminAiChatService_1 = class AdminAiChatService {
287
332
  this.logger.error(`Admin chat streamText error: ${event.error}`);
288
333
  },
289
334
  });
290
- const text = await result.text;
291
- const steps = await result.steps;
335
+ const [text, steps, usage] = await Promise.all([result.text, result.steps, result.usage]);
292
336
  let allProducts = [];
293
337
  let allCollections = [];
294
338
  let allOrders = [];
339
+ let navigateTo;
295
340
  for (const step of steps) {
296
341
  for (const toolResult of step.toolResults) {
297
342
  const data = (_a = toolResult.output) !== null && _a !== void 0 ? _a : toolResult.result;
@@ -306,6 +351,9 @@ let AdminAiChatService = AdminAiChatService_1 = class AdminAiChatService {
306
351
  if (((_d = data.orders) === null || _d === void 0 ? void 0 : _d.length) > 0) {
307
352
  allOrders = data.orders;
308
353
  }
354
+ if (data.navigateTo) {
355
+ navigateTo = data.navigateTo;
356
+ }
309
357
  }
310
358
  }
311
359
  return {
@@ -313,6 +361,12 @@ let AdminAiChatService = AdminAiChatService_1 = class AdminAiChatService {
313
361
  products: allProducts.slice(0, constants_1.MAX_CHAT_PRODUCTS),
314
362
  collections: allCollections.slice(0, 5),
315
363
  orders: allOrders.length > 0 ? allOrders : undefined,
364
+ navigateTo,
365
+ usage: {
366
+ inputTokens: (_e = usage.inputTokens) !== null && _e !== void 0 ? _e : 0,
367
+ outputTokens: (_f = usage.outputTokens) !== null && _f !== void 0 ? _f : 0,
368
+ totalTokens: (_g = usage.totalTokens) !== null && _g !== void 0 ? _g : 0,
369
+ },
316
370
  };
317
371
  }
318
372
  };
@@ -325,6 +379,29 @@ exports.AdminAiChatService = AdminAiChatService = AdminAiChatService_1 = __decor
325
379
  core_2.ConfigService,
326
380
  embedding_service_1.EmbeddingService,
327
381
  product_embedding_service_1.ProductEmbeddingService,
328
- collection_embedding_service_1.CollectionEmbeddingService])
382
+ collection_embedding_service_1.CollectionEmbeddingService,
383
+ core_2.ProductService,
384
+ core_2.ProductVariantService,
385
+ core_2.ProductOptionGroupService,
386
+ core_2.ProductOptionService,
387
+ core_2.TaxCategoryService,
388
+ core_2.CustomerService,
389
+ core_2.CollectionService,
390
+ core_2.FacetService,
391
+ core_2.FacetValueService,
392
+ core_2.ShippingMethodService,
393
+ core_2.PaymentMethodService,
394
+ core_2.TaxRateService,
395
+ core_2.ZoneService,
396
+ core_2.CountryService,
397
+ core_2.AdministratorService,
398
+ core_2.RoleService,
399
+ core_2.ChannelService,
400
+ core_2.SellerService,
401
+ core_2.GlobalSettingsService,
402
+ core_2.PromotionService,
403
+ core_2.AssetService,
404
+ core_2.CustomerGroupService,
405
+ core_2.StockLocationService])
329
406
  ], AdminAiChatService);
330
407
  //# sourceMappingURL=admin-ai-chat.service.js.map