@wix/mcp 1.0.5 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin.js +1 -1
- package/build/bin.js +665 -82
- package/build/bin.js.map +7 -0
- package/build/chunk-QGIZNLF4.js +8179 -0
- package/build/chunk-QGIZNLF4.js.map +7 -0
- package/build/index.js +201 -6
- package/build/index.js.map +7 -0
- package/build/panorama.d.ts +2 -0
- package/build/wix-mcp-server.d.ts +4 -1
- package/package.json +8 -5
- package/build/api-call/index.js +0 -124
- package/build/cli-tools/cli.js +0 -338
- package/build/cli-tools/utils.js +0 -25
- package/build/docs/docs.js +0 -448
- package/build/docs/long-content.js +0 -1
- package/build/docs/semanticSearch.js +0 -108
- package/build/docs/semanticSearch.test.js +0 -459
- package/build/interactive-command-tools/eventually.js +0 -15
- package/build/interactive-command-tools/handleStdout.js +0 -75
- package/build/interactive-command-tools/interactive-command-utils.js +0 -75
- package/build/logger.js +0 -61
- package/build/resources/docs.js +0 -45
- package/build/sentry.js +0 -10
- package/build/support/index.js +0 -32
- package/build/tool-utils.js +0 -29
- package/build/tool-utils.spec.js +0 -119
- package/build/wix-mcp-server.js +0 -51
package/build/docs/docs.js
DELETED
|
@@ -1,448 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import { runSemanticSearchAndFormat } from './semanticSearch.js';
|
|
3
|
-
import { logger } from '../logger.js';
|
|
4
|
-
import { captureException } from '@sentry/node';
|
|
5
|
-
export const VALID_DOCS_TOOLS = [
|
|
6
|
-
'WDS',
|
|
7
|
-
'REST',
|
|
8
|
-
'SDK',
|
|
9
|
-
'BUILD_APPS',
|
|
10
|
-
'WIX_HEADLESS',
|
|
11
|
-
'BUSINESS_SOLUTIONS'
|
|
12
|
-
];
|
|
13
|
-
export const addDocsTools = (server, allowedTools = [
|
|
14
|
-
'WDS',
|
|
15
|
-
'REST',
|
|
16
|
-
'SDK',
|
|
17
|
-
'BUILD_APPS',
|
|
18
|
-
'WIX_HEADLESS',
|
|
19
|
-
'BUSINESS_SOLUTIONS'
|
|
20
|
-
]) => {
|
|
21
|
-
// WDS Documentation
|
|
22
|
-
if (allowedTools.includes('WDS')) {
|
|
23
|
-
server.tool('SearchWixWDSDocumentation', [
|
|
24
|
-
'Searches the Wix Design System Documentation for components and patterns.',
|
|
25
|
-
'Use this tool when you need to understand or implement UI components and design patterns in a Wix project.',
|
|
26
|
-
'Search for specific component names, patterns, or UI requirements.',
|
|
27
|
-
"If you can't find what you need, try to rephrase your search term or use bigger maxResults value."
|
|
28
|
-
].join('\n'), {
|
|
29
|
-
searchTerm: z
|
|
30
|
-
.string()
|
|
31
|
-
.describe('The search term to search for in the Wix Design System Documentation'),
|
|
32
|
-
maxResults: z
|
|
33
|
-
.number()
|
|
34
|
-
.describe('The maximum number of results to return, default is 5, max is 15')
|
|
35
|
-
.min(1)
|
|
36
|
-
.max(15)
|
|
37
|
-
.optional()
|
|
38
|
-
.default(10)
|
|
39
|
-
}, async ({ searchTerm, maxResults }) => {
|
|
40
|
-
try {
|
|
41
|
-
logger.log(`Searching for ${searchTerm} in Wix WDS`);
|
|
42
|
-
const result = await runSemanticSearchAndFormat({
|
|
43
|
-
toolName: 'WDS',
|
|
44
|
-
toolParams: {
|
|
45
|
-
searchTerm: searchTerm
|
|
46
|
-
},
|
|
47
|
-
maxResults: Math.max(1, Math.min(maxResults ?? 5, 15))
|
|
48
|
-
});
|
|
49
|
-
return {
|
|
50
|
-
content: [
|
|
51
|
-
{
|
|
52
|
-
type: 'text',
|
|
53
|
-
text: result
|
|
54
|
-
}
|
|
55
|
-
]
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
catch (error) {
|
|
59
|
-
// panorama.errorMonitor().reportError(error);
|
|
60
|
-
captureException(error, {
|
|
61
|
-
tags: {
|
|
62
|
-
componentId: 'SearchWixWDSDocumentation',
|
|
63
|
-
toolName: 'SearchWixWDSDocumentation'
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
logger.error(`Error searching for ${searchTerm} in Wix WDS: ${error}`);
|
|
67
|
-
return {
|
|
68
|
-
isError: true,
|
|
69
|
-
content: [{ type: 'text', text: 'Error: ' + error.message }]
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
// REST Documentation
|
|
75
|
-
if (allowedTools.includes('REST')) {
|
|
76
|
-
server.tool('SearchWixRESTDocumentation', [
|
|
77
|
-
'Searches the official Wix REST API documentation.',
|
|
78
|
-
'Use this tool whenever you need to to interact with the Wix platform via HTTP requests.',
|
|
79
|
-
"Specify the API endpoint, resource, or action you need information about (e.g., 'get site details endpoint', 'create data collection', 'update product API', 'REST authentication').",
|
|
80
|
-
"If you can't find what you need, try to rephrase your search term or use bigger maxResults value."
|
|
81
|
-
].join('\n'), {
|
|
82
|
-
searchTerm: z
|
|
83
|
-
.string()
|
|
84
|
-
.describe('The search term to search for in the Wix REST API Documentation'),
|
|
85
|
-
maxResults: z
|
|
86
|
-
.number()
|
|
87
|
-
.describe('The maximum number of results to return, default is 5, max is 15')
|
|
88
|
-
.min(1)
|
|
89
|
-
.max(15)
|
|
90
|
-
.optional()
|
|
91
|
-
.default(10)
|
|
92
|
-
}, async ({ searchTerm, maxResults }) => {
|
|
93
|
-
try {
|
|
94
|
-
logger.log(`Searching for ${searchTerm} in Wix REST API`);
|
|
95
|
-
const result = await runSemanticSearchAndFormat({
|
|
96
|
-
toolName: 'REST',
|
|
97
|
-
toolParams: {
|
|
98
|
-
searchTerm: searchTerm
|
|
99
|
-
},
|
|
100
|
-
maxResults: Math.max(1, Math.min(maxResults ?? 5, 15)),
|
|
101
|
-
linesInEachResult: 15
|
|
102
|
-
});
|
|
103
|
-
return {
|
|
104
|
-
content: [
|
|
105
|
-
{
|
|
106
|
-
type: 'text',
|
|
107
|
-
text: result
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
type: 'text',
|
|
111
|
-
text: 'Next, you MUST use the ReadFullDocsArticle tool if you want to read the full documentation for a specific article or method.'
|
|
112
|
-
}
|
|
113
|
-
]
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
catch (error) {
|
|
117
|
-
// panorama.errorMonitor().reportError(error);
|
|
118
|
-
captureException(error, {
|
|
119
|
-
tags: {
|
|
120
|
-
componentId: 'SearchWixRESTDocumentation',
|
|
121
|
-
toolName: 'SearchWixRESTDocumentation'
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
logger.error(`Error searching for ${searchTerm} in Wix REST API: ${error}`);
|
|
125
|
-
return {
|
|
126
|
-
isError: true,
|
|
127
|
-
content: [{ type: 'text', text: 'Error: ' + error.message }]
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
if (allowedTools.includes('BUSINESS_SOLUTIONS')) {
|
|
133
|
-
server.tool('WixBusinessFlowsDocumentation', [
|
|
134
|
-
'This tool provides step-by-step recipes for setting up complex Wix business solutions that involve multiple API calls.',
|
|
135
|
-
'It excels at guiding the creation of features like booking systems with payments.',
|
|
136
|
-
'For example, it can guide the setup of a service in Wix Bookings where customers can pay using Wix Payments, such as creating a bookable yoga class',
|
|
137
|
-
'It searches the Wix Business Solutions documentation for these integrated workflows involving services, bookings, payments, stores, blogs, and more.',
|
|
138
|
-
'This tool returns a list of articles that are potentially relevant to the input search term.',
|
|
139
|
-
'**IMPORTANT NOTES:**',
|
|
140
|
-
'1. Before attempting to implement a multi step API calls on Wix, YOU MUST TRY THIS TOOL FIRST.',
|
|
141
|
-
'2. Out of the returned list of articles that you will receive, you MUST select the most relevant one and use the ReadFullDocsArticle tool to fetch it.'
|
|
142
|
-
].join('\n'), {
|
|
143
|
-
searchTerm: z
|
|
144
|
-
.string()
|
|
145
|
-
.describe('The search term for the required sample flow (e.g. "setup a new business")'),
|
|
146
|
-
maxResults: z
|
|
147
|
-
.number()
|
|
148
|
-
.describe('The maximum number of results to return, default is 5, max is 15')
|
|
149
|
-
.min(1)
|
|
150
|
-
.max(15)
|
|
151
|
-
.optional()
|
|
152
|
-
.default(5)
|
|
153
|
-
}, async ({ searchTerm, maxResults }) => {
|
|
154
|
-
try {
|
|
155
|
-
logger.log(`Searching for ${searchTerm} in Wix Sample Flows`);
|
|
156
|
-
const result = await runSemanticSearchAndFormat({
|
|
157
|
-
toolName: 'BUSINESS_SOLUTIONS',
|
|
158
|
-
toolParams: {
|
|
159
|
-
searchTerm: '**RECIPE**: Business Recipes - full setup flow for::: ' +
|
|
160
|
-
searchTerm
|
|
161
|
-
},
|
|
162
|
-
maxResults: Math.max(1, Math.min(maxResults ?? 5, 15))
|
|
163
|
-
});
|
|
164
|
-
return {
|
|
165
|
-
content: [
|
|
166
|
-
{
|
|
167
|
-
type: 'text',
|
|
168
|
-
text: result
|
|
169
|
-
},
|
|
170
|
-
{
|
|
171
|
-
type: 'text',
|
|
172
|
-
text: `Out of the included list of articles, you **MUST** select the one that is most relevant to the user's request and use the ReadFullDocsArticle tool to fetch it.`
|
|
173
|
-
}
|
|
174
|
-
]
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
catch (error) {
|
|
178
|
-
// panorama.errorMonitor().reportError(error);
|
|
179
|
-
captureException(error, {
|
|
180
|
-
tags: {
|
|
181
|
-
componentId: 'SearchWixSampleFlowsDocumentation',
|
|
182
|
-
toolName: 'SearchWixSampleFlowsDocumentation'
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
|
-
logger.error(`Error searching for ${searchTerm} in Wix Sample Flows: ${error}`);
|
|
186
|
-
return {
|
|
187
|
-
isError: true,
|
|
188
|
-
content: [{ type: 'text', text: 'Error: ' + error.message }]
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
// SDK Documentation
|
|
194
|
-
if (allowedTools.includes('SDK')) {
|
|
195
|
-
server.tool('SearchWixSDKDocumentation', [
|
|
196
|
-
'Searches the official Wix javascript SDK documentation.',
|
|
197
|
-
'Use this tool whenever you need to write or modify Wix related SDK code.',
|
|
198
|
-
"Specify the SDK module, function, or feature you need information about (e.g., 'how to query all items from a data collection?', 'how to use wix-stores-backend', 'authentication methods in the SDK').",
|
|
199
|
-
"If you can't find what you need, try to rephrase your search term or use bigger maxResults value."
|
|
200
|
-
].join('\n'), {
|
|
201
|
-
searchTerm: z
|
|
202
|
-
.string()
|
|
203
|
-
.describe('The search term to search for in the Wix SDK Documentation'),
|
|
204
|
-
maxResults: z
|
|
205
|
-
.number()
|
|
206
|
-
.describe('The maximum number of results to return, default is 5, max is 15')
|
|
207
|
-
.min(1)
|
|
208
|
-
.max(15)
|
|
209
|
-
.optional()
|
|
210
|
-
.default(5)
|
|
211
|
-
}, async ({ searchTerm, maxResults }) => {
|
|
212
|
-
try {
|
|
213
|
-
logger.log(`Searching for ${searchTerm} in Wix SDK`);
|
|
214
|
-
// panorama
|
|
215
|
-
// .transaction('SearchWixSDKDocumentation')
|
|
216
|
-
// .start({ maxResults });
|
|
217
|
-
const result = await runSemanticSearchAndFormat({
|
|
218
|
-
toolName: 'SDK',
|
|
219
|
-
toolParams: {
|
|
220
|
-
searchTerm: searchTerm
|
|
221
|
-
},
|
|
222
|
-
maxResults: Math.max(1, Math.min(maxResults ?? 5, 15)),
|
|
223
|
-
linesInEachResult: 15
|
|
224
|
-
});
|
|
225
|
-
// panorama
|
|
226
|
-
// .transaction('SearchWixSDKDocumentation')
|
|
227
|
-
// .finish({ maxResults });
|
|
228
|
-
return {
|
|
229
|
-
content: [
|
|
230
|
-
{
|
|
231
|
-
type: 'text',
|
|
232
|
-
text: result
|
|
233
|
-
},
|
|
234
|
-
{
|
|
235
|
-
type: 'text',
|
|
236
|
-
text: 'Next, you MUST use ReadFullDocsArticle tool if you want to read full documentation for a specific article or method.'
|
|
237
|
-
}
|
|
238
|
-
]
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
|
-
catch (error) {
|
|
242
|
-
// panorama.errorMonitor().reportError(error);
|
|
243
|
-
captureException(error, {
|
|
244
|
-
tags: {
|
|
245
|
-
componentId: 'SearchWixSDKDocumentation',
|
|
246
|
-
toolName: 'SearchWixSDKDocumentation'
|
|
247
|
-
}
|
|
248
|
-
});
|
|
249
|
-
logger.error(`Error searching for ${searchTerm} in Wix SDK: ${error}`);
|
|
250
|
-
return {
|
|
251
|
-
isError: true,
|
|
252
|
-
content: [{ type: 'text', text: 'Error: ' + error.message }]
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
// Build Apps Documentation
|
|
258
|
-
if (allowedTools.includes('BUILD_APPS')) {
|
|
259
|
-
server.tool('SearchBuildAppsDocumentation', [
|
|
260
|
-
'Searches the official Build Apps documentation.',
|
|
261
|
-
'Use this tool when you need to understand or implement Wix CLI applications related code.',
|
|
262
|
-
'The search term should be a specific Wix CLI command or specific topic related to Wix CLI applications or its ecosystem (e.g. deployment, creating new extensions etc).',
|
|
263
|
-
"If you can't find what you need, try to rephrase your search term or use bigger maxResults value."
|
|
264
|
-
].join('\n'), {
|
|
265
|
-
searchTerm: z
|
|
266
|
-
.string()
|
|
267
|
-
.describe('The search term to search for in the Build Apps Documentation'),
|
|
268
|
-
maxResults: z
|
|
269
|
-
.number()
|
|
270
|
-
.describe('The maximum number of results to return, default is 5, max is 15')
|
|
271
|
-
.min(1)
|
|
272
|
-
.max(15)
|
|
273
|
-
.optional()
|
|
274
|
-
.default(5)
|
|
275
|
-
}, async ({ searchTerm, maxResults }) => {
|
|
276
|
-
try {
|
|
277
|
-
logger.log(`Searching for ${searchTerm} in Build Apps`);
|
|
278
|
-
const result = await runSemanticSearchAndFormat({
|
|
279
|
-
toolName: 'BUILD_APPS',
|
|
280
|
-
toolParams: {
|
|
281
|
-
searchTerm: `wix cli docs for ${searchTerm}`
|
|
282
|
-
},
|
|
283
|
-
maxResults: Math.max(1, Math.min(maxResults ?? 5, 15))
|
|
284
|
-
});
|
|
285
|
-
return {
|
|
286
|
-
content: [
|
|
287
|
-
{
|
|
288
|
-
type: 'text',
|
|
289
|
-
text: result
|
|
290
|
-
}
|
|
291
|
-
]
|
|
292
|
-
};
|
|
293
|
-
}
|
|
294
|
-
catch (error) {
|
|
295
|
-
// panorama.errorMonitor().reportError(error);
|
|
296
|
-
captureException(error, {
|
|
297
|
-
tags: {
|
|
298
|
-
componentId: 'SearchBuildAppsDocumentation',
|
|
299
|
-
toolName: 'SearchBuildAppsDocumentation'
|
|
300
|
-
}
|
|
301
|
-
});
|
|
302
|
-
logger.error(`Error searching for ${searchTerm} in Build Apps: ${error}`);
|
|
303
|
-
return {
|
|
304
|
-
content: [{ type: 'text', text: 'Error: ' + error.message }]
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
// Wix Headless Documentation
|
|
310
|
-
if (allowedTools.includes('WIX_HEADLESS')) {
|
|
311
|
-
server.tool('SearchWixHeadlessDocumentation', [
|
|
312
|
-
'Searches the official Wix Headless Documentation.',
|
|
313
|
-
'Use this tool when you need to understand or implement Headless related code.',
|
|
314
|
-
'The search term should be a specific Wix Headless topic or feature you need information about.',
|
|
315
|
-
"If you can't find what you need, try to rephrase your search term or use bigger maxResults value."
|
|
316
|
-
].join('\n'), {
|
|
317
|
-
searchTerm: z
|
|
318
|
-
.string()
|
|
319
|
-
.describe('The search term to search for in the Headless Documentation'),
|
|
320
|
-
maxResults: z
|
|
321
|
-
.number()
|
|
322
|
-
.describe('The maximum number of results to return, default is 5, max is 15')
|
|
323
|
-
.min(1)
|
|
324
|
-
.max(15)
|
|
325
|
-
.optional()
|
|
326
|
-
.default(5)
|
|
327
|
-
}, async ({ searchTerm, maxResults }) => {
|
|
328
|
-
try {
|
|
329
|
-
logger.log(`Searching for ${searchTerm} in Headless`);
|
|
330
|
-
const result = await runSemanticSearchAndFormat({
|
|
331
|
-
toolName: 'WIX_HEADLESS',
|
|
332
|
-
toolParams: {
|
|
333
|
-
searchTerm: searchTerm
|
|
334
|
-
},
|
|
335
|
-
maxResults: Math.max(1, Math.min(maxResults ?? 5, 15))
|
|
336
|
-
});
|
|
337
|
-
return {
|
|
338
|
-
content: [
|
|
339
|
-
{
|
|
340
|
-
type: 'text',
|
|
341
|
-
text: result
|
|
342
|
-
}
|
|
343
|
-
]
|
|
344
|
-
};
|
|
345
|
-
}
|
|
346
|
-
catch (error) {
|
|
347
|
-
// panorama.errorMonitor().reportError(error);
|
|
348
|
-
captureException(error, {
|
|
349
|
-
tags: {
|
|
350
|
-
componentId: 'SearchWixHeadlessDocumentation',
|
|
351
|
-
toolName: 'SearchWixHeadlessDocumentation'
|
|
352
|
-
}
|
|
353
|
-
});
|
|
354
|
-
logger.error(`Error searching for ${searchTerm} in Wix Headless: ${error}`);
|
|
355
|
-
return {
|
|
356
|
-
content: [{ type: 'text', text: 'Error: ' + error.message }]
|
|
357
|
-
};
|
|
358
|
-
}
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
|
-
server.tool('ReadFullDocsArticle', [
|
|
362
|
-
'Fetches the full Wix docs article or method article.',
|
|
363
|
-
'Use this tool when you read a summary of a docs article or method article, you have the docs url and want to read the full article.'
|
|
364
|
-
].join('\n'), {
|
|
365
|
-
articleUrl: z
|
|
366
|
-
.string()
|
|
367
|
-
.describe('The URL of the docs article or method article to fetch. Should be something like https://dev.wix.com/docs/.../.../...')
|
|
368
|
-
}, async ({ articleUrl }) => {
|
|
369
|
-
try {
|
|
370
|
-
const articleContent = await fetchArticleContent(articleUrl, 'article');
|
|
371
|
-
if (!articleContent) {
|
|
372
|
-
throw new Error('Article content is empty');
|
|
373
|
-
}
|
|
374
|
-
return {
|
|
375
|
-
content: [
|
|
376
|
-
{
|
|
377
|
-
type: 'text',
|
|
378
|
-
text: articleContent
|
|
379
|
-
},
|
|
380
|
-
{
|
|
381
|
-
type: 'text',
|
|
382
|
-
text: [
|
|
383
|
-
'---',
|
|
384
|
-
'Next, if you are dealing with a method - you MUST call ReadFullDocsMethodSchema tool - it will give you the full request schema for the method.'
|
|
385
|
-
].join('\n')
|
|
386
|
-
}
|
|
387
|
-
]
|
|
388
|
-
};
|
|
389
|
-
}
|
|
390
|
-
catch (error) {
|
|
391
|
-
logger.error(`Error fetching article content or method schema for ${articleUrl}: ${error}`);
|
|
392
|
-
return {
|
|
393
|
-
content: [
|
|
394
|
-
{
|
|
395
|
-
type: 'text',
|
|
396
|
-
text: 'Could not fetch article content, you should try completing the task without it.'
|
|
397
|
-
}
|
|
398
|
-
]
|
|
399
|
-
};
|
|
400
|
-
}
|
|
401
|
-
});
|
|
402
|
-
server.tool('ReadFullDocsMethodSchema', [
|
|
403
|
-
'Fetches the full method schema for a given method. Always use it before calling the method.',
|
|
404
|
-
'This will give you the entire request/response schema with all the fields and their descriptions.'
|
|
405
|
-
].join('\n'), {
|
|
406
|
-
articleUrl: z
|
|
407
|
-
.string()
|
|
408
|
-
.describe('The URL of the documentation to fetch. Should be something like https://dev.wix.com/docs/.../.../...')
|
|
409
|
-
}, async ({ articleUrl }) => {
|
|
410
|
-
try {
|
|
411
|
-
const articleContent = await fetchArticleContent(articleUrl, 'methodSchema');
|
|
412
|
-
if (!articleContent) {
|
|
413
|
-
throw new Error('Method schema is empty');
|
|
414
|
-
}
|
|
415
|
-
return {
|
|
416
|
-
content: [
|
|
417
|
-
{
|
|
418
|
-
type: 'text',
|
|
419
|
-
text: articleContent
|
|
420
|
-
}
|
|
421
|
-
]
|
|
422
|
-
};
|
|
423
|
-
}
|
|
424
|
-
catch (error) {
|
|
425
|
-
logger.error(`Error fetching method schema for ${articleUrl}: ${error}`);
|
|
426
|
-
return {
|
|
427
|
-
content: [
|
|
428
|
-
{
|
|
429
|
-
type: 'text',
|
|
430
|
-
text: 'Could not fetch method schema, you should try completing the task without it.'
|
|
431
|
-
}
|
|
432
|
-
]
|
|
433
|
-
};
|
|
434
|
-
}
|
|
435
|
-
});
|
|
436
|
-
};
|
|
437
|
-
async function fetchArticleContent(articleUrl, mode) {
|
|
438
|
-
// https://dev.wix.com/digor/api/get-article-content?articleUrl=https://dev.wix.com/docs/rest/business-solutions/blog/draft-posts/create-draft-post&schema=true
|
|
439
|
-
const url = new URL(`https://dev.wix.com/digor/api/get-article-content`);
|
|
440
|
-
url.searchParams.set('articleUrl', articleUrl);
|
|
441
|
-
const schema = mode === 'methodSchema' ? 'true' : 'false';
|
|
442
|
-
url.searchParams.set('schema', schema);
|
|
443
|
-
logger.log(`Fetching resource from docs ${url.toString()}`);
|
|
444
|
-
const response = await fetch(url.toString());
|
|
445
|
-
const data = await response.json();
|
|
446
|
-
logger.log(`Fetched resource from docs: ${data.articleContent}`);
|
|
447
|
-
return data.articleContent;
|
|
448
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const LONG_KB_CONTENT = "# Method name:\n\ncrm.contacts.queryContacts(options: QueryContactsOptions)\n\n# Method Link:\n\nhttps://dev.wix.com/docs/sdk/backend-modules/crm/contacts/query-contacts\n\n# Method Description:\n\nCreates a query to retrieve a list of contacts.\n\nThe `queryContacts()` function builds a query to retrieve a list of contacts and returns a `ContactsQueryBuilder` object.\n\nThe returned object contains the query definition, which is typically used to run the query using the `find()` function.\n\nYou can refine the query by chaining `ContactsQueryBuilder` functions onto the query. `ContactsQueryBuilder` functions enable you to sort, filter, and control the results `queryContacts()` returns.\n\n`queryContacts()` runs with these `ContactsQueryBuilder` defaults, which you can override:\n\n- `skip(0)`\n- `limit(50)`\n- `descending(\"_createdDate\")`\n\nThe functions that are chained to `queryContacts()` are applied in the order they are called. For example, if you apply `ascending('info.company')` and then `descending('info.name.last')`, the results are sorted first by the company name, and then, if there are multiple results with the same company, the items are sorted by last name.\n\n\n|PROPERTY\t|SUPPORTED FILTERS & SORTING\t\n|:---:|:---:|\n|`_id`|[`eq()`](/contacts-query-builder/eq),[`ne()`](/contacts-query-builder/ne),[`in()`](/contacts-query-builder/in),[`exists()`](/contacts-query-builder/exists)|\n|`_createdDate`|[`eq()`](/contacts-query-builder/eq),[`ne()`](/contacts-query-builder/ne),[`gt()`](/contacts-query-builder/gt),[`lt()`](/contacts-query-builder/lt),[`ge()`](/contacts-query-builder/ge),[`le()`](/contacts-query-builder/le),[`ascending()`](/contacts-query-builder/ascending),[`descending()`](/contacts-query-builder/descending)|\n|`_updatedDate`|[`eq()`](/contacts-query-builder/eq),[`ne()`](/contacts-query-builder/ne),[`gt()`](/contacts-query-builder/gt),[`lt()`](/contacts-query-builder/lt),[`ge()`](/contacts-query-builder/ge),[`le()`](/contacts-query-builder/le)|\n|`lastActivity.activityDate`|[`eq()`](/contacts-query-builder/eq),[`ne()`](/contacts-query-builder/ne),[`gt()`](/contacts-query-builder/gt),[`lt()`](/contacts-query-builder/lt),[`ge()`](/contacts-query-builder/ge),[`le()`](/contacts-query-builder/le),[`ascending()`](/contacts-query-builder/ascending),[`descending()`](/contacts-query-builder/descending)|\n|`primaryInfo.email`|[`eq()`](/contacts-query-builder/eq),[`ne()`](/contacts-query-builder/ne),[`in()`](/contacts-query-builder/in),[`exists()`](/contacts-query-builder/exists),[`startsWith()`](/contacts-query-builder/starts-with),[`ascending()`](/contacts-query-builder/ascending),[`descending()`](/contacts-query-builder/descending)|\n|`primaryInfo.phone`|[`eq()`](/contacts-query-builder/eq),[`ne()`](/contacts-query-builder/ne),[`in()`](/contacts-query-builder/in),[`exists()`](/contacts-query-builder/exists),[`startsWith()`](/contacts-query-builder/starts-with)|\n|`info.name.first`|[`eq()`](/contacts-query-builder/eq),[`ne()`](/contacts-query-builder/ne),[`in()`](/contacts-query-builder/in),[`exists()`](/contacts-query-builder/exists),[`startsWith()`](/contacts-query-builder/starts-with),[`ascending()`](/contacts-query-builder/ascending),[`descending()`](/contacts-query-builder/descending)|\n|`info.name.last`|[`eq()`](/contacts-query-builder/eq),[`ne()`](/contacts-query-builder/ne),[`in()`](/contacts-query-builder/in),[`exists()`](/contacts-query-builder/exists),[`startsWith()`](/contacts-query-builder/starts-with),[`ascending()`](/contacts-query-builder/ascending),[`descending()`](/contacts-query-builder/descending)|\n|`info.company`|[`eq()`](/contacts-query-builder/eq),[`ne()`](/contacts-query-builder/ne),[`in()`](/contacts-query-builder/in),[`exists()`](/contacts-query-builder/exists),[`startsWith()`](/contacts-query-builder/starts-with),[`ascending()`](/contacts-query-builder/ascending),[`descending()`](/contacts-query-builder/descending)|\n|`info.jobTitle`|[`eq()`](/contacts-query-builder/eq),[`ne()`](/contacts-query-builder/ne),[`in()`](/contacts-query-builder/in),[`exists()`](/contacts-query-builder/exists),[`startsWith()`](/contacts-query-builder/starts-with),[`ascending()`](/contacts-query-builder/ascending),[`descending()`](/contacts-query-builder/descending)|\n|`info.birthdate`|[`eq()`](/contacts-query-builder/eq),[`ne()`](/contacts-query-builder/ne),[`ascending()`](/contacts-query-builder/ascending),[`descending()`](/contacts-query-builder/descending)|\n|`info.locale`|[`eq()`](/contacts-query-builder/eq),[`ne()`](/contacts-query-builder/ne),[`in()`](/contacts-query-builder/in),[`exists()`](/contacts-query-builder/exists)|\n\n# Method Permissions:\n\n- Manage Events\n- Read Contacts\n- Read Members and Contacts - all read permissions\n- Manage Restaurants - all permissions\n- Manage Contacts\n- Set Up Automations\n- Manage Members and Contacts - all permissions\n\n# Method Permissions Scopes IDs:\n\n- SCOPE.EVENTS.MANAGE-EVENTS\n- SCOPE.DC-CONTACTS.READ-CONTACTS\n- SCOPE.DC-CONTACTS-MEGA.READ-MEMBERS-CONTACTS\n- SCOPE.RESTAURANTS.MEGA-SCOPES\n- SCOPE.DC-CONTACTS.MANAGE-CONTACTS\n- SCOPE.CRM.SETUP-AUTOMATIONS\n- SCOPE.DC-CONTACTS-MEGA.MANAGE-MEMBERS-CONTACTS\n\n# Method Schema Summary:\n\n# API Method Summary: `queryContacts`\n\n## Method Signature\n```javascript\ncrm.contacts.queryContacts(options)\n```\n\n## Description\nThe `queryContacts()` method creates a query to retrieve a list of contacts and returns a `ContactsQueryBuilder` object. This object allows for further refinement of the query through chaining methods to sort, filter, and control the results. The default settings for the query are:\n- `skip(0)`\n- `limit(50)`\n- `descending(\"_createdDate\")`\n\n## Parameters\n- **options**: `QueryContactsOptions`\n - Description: Options for querying contacts.\n\n## Return Type\n- **REFERENCE<ContactsQueryBuilder>**: The method returns a `ContactsQueryBuilder` object that can be used to refine the query further.\n\n## Supported Filters & Sorting\nThe following properties can be used for filtering and sorting, along with their supported functions:\n\n| Property | Supported Functions |\n|------------------------------|---------------------------------------------------------------------------------------------------------|\n| `_id` | `eq()`, `ne()`, `in()`, `exists()` |\n| `_createdDate` | `eq()`, `ne()`, `gt()`, `lt()`, `ge()`, `le()`, `ascending()`, `descending()` |\n| `_updatedDate` | `eq()`, `ne()`, `gt()`, `lt()`, `ge()`, `le()` |\n| `lastActivity.activityDate` | `eq()`, `ne()`, `gt()`, `lt()`, `ge()`, `le()`, `ascending()`, `descending()` |\n| `primaryInfo.email` | `eq()`, `ne()`, `in()`, `exists()`, `startsWith()`, `ascending()`, `descending()` |\n| `primaryInfo.phone` | `eq()`, `ne()`, `in()`, `exists()`, `startsWith()` |\n| `info.name.first` | `eq()`, `ne()`, `in()`, `exists()`, `startsWith()`, `ascending()`, `descending()` |\n| `info.name.last` | `eq()`, `ne()`, `in()`, `exists()`, `startsWith()`, `ascending()`, `descending()` |\n| `info.company` | `eq()`, `ne()`, `in()`, `exists()`, `startsWith()`, `ascending()`, `descending()` |\n| `info.jobTitle` | `eq()`, `ne()`, `in()`, `exists()`, `startsWith()`, `ascending()`, `descending()` |\n| `info.birthdate` | `eq()`, `ne()`, `ascending()`, `descending()` |\n| `info.locale` | `eq()`, `ne()`, `in()`, `exists()` |\n\n## Enum Properties\nThe following properties have limited allowed values (enums):\n\n- **lastActivity.activityType**: \n - Valid values: `ARENA_NEW_LEAD`, `BOOKINGS_APPOINTMENT`, `CASHIER_BUTTON_PURCHASE`, `CONTACT_CREATED`, `CONTACT_MERGED`, `ECOM_CART_ABANDON`, `ECOM_CHECKOUT_BUYER`, `ECOM_PURCHASE`, `EVENTS_RSVP`, `FORM_SUBMITTED`, `GENERAL`, `HOTELS_CANCEL`, `HOTELS_CONFIRMATION`, `HOTELS_PURCHASE`, `HOTELS_RESERVATION`, `INBOX_FORM_SUBMITTED`, `INBOX_MESSAGE_FROM_CUSTOMER`, `INBOX_MESSAGE_TO_CUSTOMER`, `INBOX_PAYMENT_REQUEST_PAID`, `INVOICE_OVERDUE`, `INVOICE_PAY`, `MEMBER_LOGIN`, `MEMBER_REGISTER`, `MEMBER_STATUS_CHANGED`, `NEWSLETTER_SUBSCRIPTION_FORM_SUBMITTED`, `NEWSLETTER_SUBSCRIPTION_NOT_SET`, `NEWSLETTER_SUBSCRIPTION_PENDING`, `NEWSLETTER_SUBSCRIPTION_SUBSCRIBE`, `NEWSLETTER_SUBSCRIPTION_UNSUBSCRIBE`, `PHONE_SUBSCRIPTION_NOT_SET`, `PHONE_SUBSCRIPTION_PENDING`, `PHONE_SUBSCRIPTION_SUBSCRIBE`, `PHONE_SUBSCRIPTION_UNSUBSCRIBE`, `PRICE_QUOTE_ACCEPT`, `PRICE_QUOTE_EXPIRE`, `RESTAURANTS_ORDER`, `RESTAURANTS_RESERVATION`, `SHOUTOUT_CLICK`, `SHOUTOUT_OPEN`, `VIDEO_PURCHASE`, `VIDEO_RENT`\n\n- **primaryEmail.deliverabilityStatus**: \n - Valid values: `BOUNCED`, `INACTIVE`, `NOT_SET`, `SPAM_COMPLAINT`, `VALID`\n\n- **primaryEmail.subscriptionStatus**: \n - Valid values: `NOT_SET`, `NO_SUBSCRIPTION_STATUS`, `PENDING`, `SUBSCRIBED`, `UNSUBSCRIBED`\n\n- **primaryPhone.subscriptionStatus**: \n - Valid values: `NOT_SET`, `NO_SUBSCRIPTION_STATUS`\n\n- **info.emails.items[].tag**: \n - Valid values: `HOME`, `MAIN`, `UNTAGGED`, `WORK`\n\n- **info.phones.items[].tag**: \n - Valid values: `FAX`, `HOME`, `MAIN`, `MOBILE`, `UNTAGGED`, `WORK`\n\n- **items[].info.addresses.items[].tag**: \n - Valid values: `BILLING`, `HOME`, `SHIPPING`, `UNTAGGED`, `WORK`\n\n**Note**: Ensure to use the correct enum values when filtering or sorting based on these properties. \n\n## Possible Errors\nThe following errors may occur when using this method:\n- **400 INVALID_ARGUMENT**: Various application codes indicating unsupported filter value types, unsupported filter values, unsupported filter operators, unsupported filter fields, malformed filters, illegal limits, or unsupported sort fields.\n\n# Method Code Examples:\n\n## queryContacts\n\n```javascript\nimport { contacts } from '@wix/crm';\n\nasync function queryContacts() {\n const { items } = await contacts.queryContacts().find();\n};\n```\n\n\n\n## default\n\n```javascript\ntry {\n const { items } = await contacts.queryContacts().find();\n return items;\n } catch (error) {\n console.error(error);\n throw error;\n }\n````";
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { logger } from '../logger.js';
|
|
2
|
-
export const MAX_CONTENT_LENGTH = 10000;
|
|
3
|
-
export const DEFAULT_MAX_RESULTS = 10;
|
|
4
|
-
const runSemanticSearch = async (toolName, toolParams, maxResults = 20, rerank = false) => {
|
|
5
|
-
const startTime = new Date().getTime();
|
|
6
|
-
const url = new URL(`https://www.wixapis.com/mcp-docs-search/v1/search?maxResults=${maxResults}&rerank=${rerank}`);
|
|
7
|
-
if (toolName === 'SDK') {
|
|
8
|
-
url.searchParams.append('kbName', 'SDK_SCHEMAS_KB_ID');
|
|
9
|
-
url.searchParams.append('kbName', 'SDK_DOCS_KB_ID');
|
|
10
|
-
}
|
|
11
|
-
else if (toolName === 'REST' || toolName === 'BUSINESS_SOLUTIONS') {
|
|
12
|
-
if (toolName === 'REST') {
|
|
13
|
-
url.searchParams.append('kbName', 'REST_METHODS_KB_ID');
|
|
14
|
-
}
|
|
15
|
-
url.searchParams.append('kbName', 'REST_DOCS_KB_ID');
|
|
16
|
-
url.searchParams.append('kbName', 'MCP_REST_RECIPES_KB_ID');
|
|
17
|
-
}
|
|
18
|
-
else if (toolName === 'WDS') {
|
|
19
|
-
url.searchParams.append('kbName', 'WDS_DOCS_KB_ID');
|
|
20
|
-
}
|
|
21
|
-
else if (toolName === 'BUILD_APPS') {
|
|
22
|
-
url.searchParams.append('kbName', 'BUILD_APPS_KB_ID');
|
|
23
|
-
}
|
|
24
|
-
else if (toolName === 'WIX_HEADLESS') {
|
|
25
|
-
url.searchParams.append('kbName', 'HEADLESS_KB_ID');
|
|
26
|
-
}
|
|
27
|
-
for (const [key, value] of Object.entries(toolParams)) {
|
|
28
|
-
url.searchParams.append(key, value);
|
|
29
|
-
}
|
|
30
|
-
logger.log('Running RAG search', url.toString());
|
|
31
|
-
const response = await fetch(url.toString(), {
|
|
32
|
-
headers: {
|
|
33
|
-
'Content-Type': 'application/json',
|
|
34
|
-
'x-time-budget': '180000',
|
|
35
|
-
'x-wix-time-budget': '180000'
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
if (!response.ok) {
|
|
39
|
-
logger.error(`Failed to run rag search: ${response.statusText}`);
|
|
40
|
-
throw new Error(`Failed to run rag search: ${response.statusText}`);
|
|
41
|
-
}
|
|
42
|
-
const data = await response.json();
|
|
43
|
-
const endTime = new Date().getTime();
|
|
44
|
-
const timeTaskFormatted = (endTime - startTime) / 1000;
|
|
45
|
-
logger.log('Ran RAG search successfully with params', JSON.stringify(toolParams), timeTaskFormatted, typeof data);
|
|
46
|
-
return data?.results;
|
|
47
|
-
};
|
|
48
|
-
const getContentFromChunkedContent = (chunkedContent) => {
|
|
49
|
-
let content = '';
|
|
50
|
-
for (const chunk of chunkedContent) {
|
|
51
|
-
if (content.length + chunk.length > MAX_CONTENT_LENGTH) {
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
54
|
-
content += '\n\n---\n\n' + chunk;
|
|
55
|
-
}
|
|
56
|
-
return content;
|
|
57
|
-
};
|
|
58
|
-
const formatResultsContent = (resultsFromKbs, maxResults, linesInEachResult = undefined) => {
|
|
59
|
-
// First, take the results from all KBs and sort them by overallMatchScore
|
|
60
|
-
const allResults = Object.entries(resultsFromKbs)
|
|
61
|
-
.map(([, { results }]) => results)
|
|
62
|
-
.flat();
|
|
63
|
-
if (allResults.length === 0) {
|
|
64
|
-
throw new Error('No result from search');
|
|
65
|
-
}
|
|
66
|
-
const sortedResults = allResults.sort((a, b) => b.scoresInfo.overallMatchScore - a.scoresInfo.overallMatchScore);
|
|
67
|
-
// Take the top maxResults results
|
|
68
|
-
const topResults = sortedResults.slice(0, maxResults);
|
|
69
|
-
// Concatenate the content of the top results
|
|
70
|
-
const concatenatedContent = topResults
|
|
71
|
-
.map((result) => {
|
|
72
|
-
let newContent = result.entry.content;
|
|
73
|
-
if (linesInEachResult) {
|
|
74
|
-
const totalLines = newContent.split('\n').length;
|
|
75
|
-
const linesToTake = Math.min(linesInEachResult, totalLines);
|
|
76
|
-
newContent = newContent.split('\n').slice(0, linesToTake).join('\n');
|
|
77
|
-
const moreLines = totalLines - linesToTake;
|
|
78
|
-
const moreLinesText = moreLines > 0 ? `\n\n... ${moreLines} more lines ...` : '';
|
|
79
|
-
newContent = `${newContent}${moreLinesText}`;
|
|
80
|
-
}
|
|
81
|
-
return {
|
|
82
|
-
...result,
|
|
83
|
-
entry: {
|
|
84
|
-
...result.entry,
|
|
85
|
-
content: newContent
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
})
|
|
89
|
-
.map((result) => {
|
|
90
|
-
const content = result.entry.content;
|
|
91
|
-
const chunkedContent = result.entry.chunkedContent;
|
|
92
|
-
if (content.length > MAX_CONTENT_LENGTH) {
|
|
93
|
-
logger.log(`Content is too long, using chunked content`, {
|
|
94
|
-
contentLength: content.length,
|
|
95
|
-
chunkedContentLength: chunkedContent.length
|
|
96
|
-
});
|
|
97
|
-
return getContentFromChunkedContent(chunkedContent);
|
|
98
|
-
}
|
|
99
|
-
return content;
|
|
100
|
-
})
|
|
101
|
-
.join('\n\n---\n\n');
|
|
102
|
-
return concatenatedContent;
|
|
103
|
-
};
|
|
104
|
-
export const runSemanticSearchAndFormat = async ({ toolName, toolParams, maxResults = DEFAULT_MAX_RESULTS, rerank, linesInEachResult }) => {
|
|
105
|
-
const results = await runSemanticSearch(toolName, toolParams, maxResults, rerank);
|
|
106
|
-
const maxResultsToUse = Math.min(maxResults, DEFAULT_MAX_RESULTS);
|
|
107
|
-
return formatResultsContent(results, maxResultsToUse, linesInEachResult);
|
|
108
|
-
};
|