@wix/mcp 1.0.92 → 1.0.93

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.
@@ -30371,9 +30371,12 @@ var runSemanticSearch = async (toolName, toolParams, maxResults = 20, rerank = f
30371
30371
  );
30372
30372
  return data?.results;
30373
30373
  };
30374
- var runPlatformizedSemanticSearch = async (toolName, searchTerm, maxResults = 20, linesInEachResult) => {
30374
+ var runPlatformizedSemanticSearch = async (toolName, searchTerm, maxResults = 20, linesInEachResult, extraDocumentTypes) => {
30375
30375
  const startTime = Date.now();
30376
- logger2.log(`[SemanticSearch/v2] Tool: ${toolName}, Query: "${searchTerm}"`);
30376
+ const documentTypes = extraDocumentTypes?.length ? [toolName, ...extraDocumentTypes] : void 0;
30377
+ logger2.log(
30378
+ `[SemanticSearch/v2] Tool: ${documentTypes ? documentTypes.join("+") : toolName}, Query: "${searchTerm}"`
30379
+ );
30377
30380
  const response = await fetch(
30378
30381
  "https://www.wixapis.com/mcp-docs-search/v1/docs/search/markdown",
30379
30382
  {
@@ -30384,7 +30387,7 @@ var runPlatformizedSemanticSearch = async (toolName, searchTerm, maxResults = 20
30384
30387
  },
30385
30388
  body: JSON.stringify({
30386
30389
  search_term: searchTerm,
30387
- document_type: toolName,
30390
+ ...documentTypes ? { document_types: documentTypes } : { document_type: toolName },
30388
30391
  maximum_results: maxResults,
30389
30392
  lines_in_each_result: linesInEachResult
30390
30393
  })
@@ -30413,14 +30416,16 @@ var runSemanticSearchAndFormat = async ({
30413
30416
  maxResults = DEFAULT_MAX_RESULTS,
30414
30417
  rerank,
30415
30418
  linesInEachResult,
30416
- usePlatformizedSearch = true
30419
+ usePlatformizedSearch = true,
30420
+ extraDocumentTypes
30417
30421
  }) => {
30418
30422
  if (usePlatformizedSearch) {
30419
30423
  return runPlatformizedSemanticSearch(
30420
30424
  toolName,
30421
30425
  toolParams.searchTerm,
30422
30426
  maxResults,
30423
- linesInEachResult
30427
+ linesInEachResult,
30428
+ extraDocumentTypes
30424
30429
  );
30425
30430
  } else {
30426
30431
  const results = await runSemanticSearch(
@@ -31109,13 +31114,14 @@ var ACCOUNT_SITE_EXECUTE_SCOPE = dedent_default`
31109
31114
  unzip(input: string | Uint8Array): Promise<Array<{ path: string; bytes: Uint8Array; text(): string }>>;
31110
31115
  };
31111
31116
  declare const siteId: string | undefined;
31112
- // Files from the ExecuteWixAPI \`files\` param. Text entries have \`content\`;
31113
- // an entry tagged \`=== FILE: <path> base64 ===\` has encoding:'base64' and
31114
- // base64 \`content\` (a binary file — image, font).
31117
+ // Files from the ExecuteWixAPI \`files\` param, followed by the resolved
31118
+ // \`attachments\`. Text entries have \`content\`; an entry tagged
31119
+ // \`=== FILE: <path> base64 ===\` — and every attachment, path = its file name —
31120
+ // has encoding:'base64' and base64 \`content\`.
31115
31121
  declare const files: Array<{ path: string; content: string; encoding?: "base64" }>;
31116
31122
  \`\`\`
31117
31123
 
31118
- FILE UPLOADS: put every file in the \`files\` param (never inline in \`code\`). Text goes raw; a small binary (icon, logo, font) rides as a \`base64\`-tagged entry — large images/video are referenced by URL (\`<img src="https://...">\`), not bundled. \`wix.multipart()\` turns the whole set into one upload body (bytes, so binary is safe):
31124
+ FILE UPLOADS: files never go inline in \`code\`; two params feed the \`files\` global. \`attachments\` takes files attached in the chat or created in your file sandbox, of any type and size up to 10 MB per call (a zip of a whole site, HTML, images, PDFs): pass the files themselves, all in one call, and the platform resolves each into \`{ download_url, file_id, file_name?, mime_type? }\` — the bytes are fetched for you and arrive as base64 entries named by file name. The \`files\` param takes content you have as text here: text goes raw; a small binary (icon, logo, font) rides as a \`base64\`-tagged entry — large images/video are referenced by URL (\`<img src="https://...">\`), not bundled. \`wix.multipart()\` turns the whole set into one upload body (bytes, so binary is safe):
31119
31125
  \`\`\`javascript
31120
31126
  // files param:
31121
31127
  // === FILE: index.html ===
@@ -31130,6 +31136,12 @@ var ACCOUNT_SITE_EXECUTE_SCOPE = dedent_default`
31130
31136
  return res.data;
31131
31137
  }
31132
31138
  \`\`\`
31139
+ A site zip passed through \`attachments\` is one base64 entry; unzip it and upload the entries:
31140
+ \`\`\`javascript
31141
+ // attachments: [site.zip] → files = [{ path: "site.zip", content: "<base64>", encoding: "base64" }]
31142
+ const entries = await wix.unzip(files[0].content); // [{ path, bytes, text() }]
31143
+ const mp = wix.multipart(entries);
31144
+ \`\`\`
31133
31145
  DOWNLOAD + EDIT + RE-UPLOAD: fetch the zip as base64, \`wix.unzip()\` it, edit text via \`entry.text()\`, keep binary as bytes, and hand the entries back to \`wix.multipart()\`:
31134
31146
  \`\`\`javascript
31135
31147
  const r = await wix.request({ scope: "account", method: "GET", responseType: "base64", url: zipUrl });
@@ -31334,12 +31346,12 @@ function buildToolDescriptions(includeReadme, includeImageUploadGuidance = true)
31334
31346
  NEVER call this tool with a missing, empty, or guessed siteId — ask first instead.
31335
31347
 
31336
31348
  Parameters — provide image input via image and/or imageUrls, OR imageBase64:
31337
- • image (array): chat file ATTACHMENTS. Each item is an object with download_url and file_id (both required), plus optional file_name and mime_type. Pass ALL attachments in one call.
31349
+ • image (array): chat file ATTACHMENTS — files the user attached, or files you created in your own file sandbox. Each item is an object with download_url and file_id (both required), plus optional file_name and mime_type. Pass ALL attachments in one call.
31338
31350
  • imageUrls (array): plain public image URLs the user pasted or other tools produced (no file_id). Pass ALL URLs in one call. Can be combined with image.
31339
31351
  • imageBase64 (string): base64-encoded image + mimeType. One image at a time. Do NOT combine with image/imageUrls.
31340
31352
 
31341
31353
  Delivering the bytes — this is where uploads most often fail:
31342
- • NEVER pass a local or sandbox file path (e.g. /mnt/..., /home/user/..., /Users/...) in any field — the server cannot reach your filesystem. Use a public http(s) URL (imageUrls) or the complete base64 (imageBase64).
31354
+ • Pass a file as a file, in image: the platform resolves it into download_url and file_id before it reaches this tool — this includes files you created in your sandbox. This server does not share your filesystem, so a bare path string (e.g. /mnt/..., /home/user/..., /Users/...) is not a file. Without a file to pass, use a public http(s) URL (imageUrls) or the complete base64 (imageBase64).
31343
31355
  • imageBase64 must be the WHOLE file, not truncated. For large images prefer imageUrls, since long base64 is easily cut off and will be rejected as unreadable.
31344
31356
  `,
31345
31357
  SupportAndFeedback: dedent_default`
@@ -32591,7 +32603,7 @@ var paramDescriptions = {
32591
32603
  },
32592
32604
  SearchWixRESTDocumentation: {
32593
32605
  searchTerm: `The search term to look up in the Wix REST API Documentation \u2014 a natural-language description of the endpoint, resource, or action you need across any Wix domain (Stores, eCommerce, Bookings, CRM, Members, CMS, Events, Blog, Forms, Media, site settings, etc.), e.g. "create a catalog item with inventory", "book a service", "update data collection items". Match the wording to how many entities you will act on: a plural term ("update products") surfaces the resource's bulk methods, which a singular term ("update a product") ranks lower or leaves out. Results are ranked by relevance, so describe the goal rather than guessing an exact API name.`,
32594
- maxResults: "The maximum number of results to return, default is 10, max is 15",
32606
+ maxResults: "The maximum number of results to return (1\u201317, default 17). Results mix REST API documentation with matching recipes and skills.",
32595
32607
  reason: "One sentence describing the original user request and the task you are trying to accomplish with this search."
32596
32608
  },
32597
32609
  WixBusinessFlowsDocumentation: {
@@ -32612,7 +32624,7 @@ var paramDescriptions = {
32612
32624
  },
32613
32625
  SearchWixHeadlessDocumentation: {
32614
32626
  searchTerm: "The search term to search for in the Headless Documentation",
32615
- maxResults: "The maximum number of results to return, default is 10, max is 15"
32627
+ maxResults: "The maximum number of results to return (1\u201317, default 17). Results mix Headless documentation with matching recipes and skills."
32616
32628
  },
32617
32629
  SearchWixVeloDocumentation: {
32618
32630
  searchTerm: "The search term to search for in the Velo Documentation",
@@ -32640,7 +32652,7 @@ var paramDescriptions = {
32640
32652
  },
32641
32653
  UploadImageToWixSite: {
32642
32654
  siteId: "The ID (UUID) of the Wix site to upload to. REQUIRED. If the user has not clearly specified which site, ASK them which site to upload to (or use ListWixSites to help them pick) BEFORE calling this tool. NEVER call this tool with a missing, empty, placeholder, or guessed siteId \u2014 ask first instead.",
32643
- image: "Array of file ATTACHMENTS the user uploaded in the chat. Each item requires download_url and file_id, and may optionally include file_name and mime_type \u2014 attached files are automatically resolved to these fields by the platform, so just include them here. For plain image URLs the user pasted, use imageUrls instead. ALWAYS pass ALL attachments together in a single call \u2014 NEVER call this tool once per image. Do NOT use together with imageBase64.",
32655
+ image: "Array of file ATTACHMENTS: files the user uploaded in the chat, or files you created in your own file sandbox. Each item requires download_url and file_id, and may optionally include file_name and mime_type \u2014 the platform resolves a file passed here into these fields automatically, so just include the files. For plain image URLs the user pasted, use imageUrls instead. ALWAYS pass ALL attachments together in a single call \u2014 NEVER call this tool once per image. Do NOT use together with imageBase64.",
32644
32656
  imageUrls: "Array of publicly accessible image URLs (e.g. links the user pasted or URLs produced by other tools). Use this for plain URLs that are NOT chat attachments \u2014 no file_id is needed. ALWAYS pass ALL URLs together in a single call. Can be combined with image; do NOT use together with imageBase64.",
32645
32657
  imageBase64: 'Base64-encoded image data. Use when the client can read a file and encode it as base64. May include a data URL prefix (e.g. "data:image/jpeg;base64,...") or be raw base64. Do NOT use together with image.',
32646
32658
  mimeType: 'MIME type of the image (e.g. "image/jpeg", "image/png", "image/webp"). Required when imageBase64 does not include a data URL prefix.',
@@ -33310,7 +33322,7 @@ var addDocsTools = (server, allowedTools = [
33310
33322
  const d2 = desc("SearchWixRESTDocumentation");
33311
33323
  return {
33312
33324
  searchTerm: external_exports.string().describe(d2.searchTerm),
33313
- maxResults: external_exports.number().describe(d2.maxResults).min(1).max(15).optional().default(15),
33325
+ maxResults: external_exports.number().describe(d2.maxResults).min(1).max(17).optional().default(17),
33314
33326
  reason: external_exports.string().describe(d2.reason)
33315
33327
  };
33316
33328
  })(),
@@ -33325,9 +33337,12 @@ var addDocsTools = (server, allowedTools = [
33325
33337
  toolParams: {
33326
33338
  searchTerm
33327
33339
  },
33328
- maxResults: Math.max(1, Math.min(maxResults ?? 15, 15)),
33340
+ maxResults: Math.max(1, Math.min(maxResults ?? 17, 17)),
33329
33341
  linesInEachResult: 30,
33330
- usePlatformizedSearch
33342
+ usePlatformizedSearch,
33343
+ // Merge recipes/skills into the REST ranking — they live in a
33344
+ // separate corpus the REST document_type doesn't cover on its own.
33345
+ extraDocumentTypes: ["SKILLS"]
33331
33346
  });
33332
33347
  const grounding = result.includes(QUERY_CAPABILITY_MARKER) ? [
33333
33348
  REST_SEARCH_API_GROUNDING_REMINDER,
@@ -33590,7 +33605,7 @@ var addDocsTools = (server, allowedTools = [
33590
33605
  const d2 = desc("SearchWixHeadlessDocumentation");
33591
33606
  return {
33592
33607
  searchTerm: external_exports.string().describe(d2.searchTerm),
33593
- maxResults: external_exports.number().describe(d2.maxResults).min(1).max(15).optional().default(15)
33608
+ maxResults: external_exports.number().describe(d2.maxResults).min(1).max(17).optional().default(17)
33594
33609
  };
33595
33610
  })(),
33596
33611
  { readOnlyHint: true, destructiveHint: false, openWorldHint: false },
@@ -33602,8 +33617,11 @@ var addDocsTools = (server, allowedTools = [
33602
33617
  toolParams: {
33603
33618
  searchTerm
33604
33619
  },
33605
- maxResults: Math.max(1, Math.min(maxResults ?? 15, 15)),
33606
- usePlatformizedSearch
33620
+ maxResults: Math.max(1, Math.min(maxResults ?? 17, 17)),
33621
+ usePlatformizedSearch,
33622
+ // Merge recipes/skills into the headless ranking — same separate
33623
+ // corpus the WIX_HEADLESS document_type doesn't cover on its own.
33624
+ extraDocumentTypes: ["SKILLS"]
33607
33625
  });
33608
33626
  return {
33609
33627
  content: [
@@ -46886,6 +46904,189 @@ ${text.slice(0, 2e3)}`
46886
46904
  );
46887
46905
  }
46888
46906
 
46907
+ // src/code-mode/attachments.ts
46908
+ var MAX_ATTACHMENTS_BYTES = 10 * 1024 * 1024;
46909
+ var MAX_REDIRECTS = 4;
46910
+ var OAI_USERCONTENT_HOST = /^[a-z0-9-]+\.oaiusercontent\.com$/;
46911
+ var OAI_BLOB_ACCOUNTS = new Set(
46912
+ [
46913
+ "australiaeast",
46914
+ "brazilsouth",
46915
+ "cacentral",
46916
+ "centralindia",
46917
+ "centralus",
46918
+ "centralusdr",
46919
+ "denmarkeast",
46920
+ "eastus",
46921
+ "eastus2",
46922
+ "indiasocentral",
46923
+ "italynorth",
46924
+ "japaneast",
46925
+ "koreacentral",
46926
+ "northcentralus",
46927
+ "northeu",
46928
+ "nznorth",
46929
+ "polandcentral",
46930
+ "seasia",
46931
+ "southcentralus",
46932
+ "southeastus3",
46933
+ "ukwest",
46934
+ "westcentralus",
46935
+ "westus",
46936
+ "westus2",
46937
+ "westus3"
46938
+ ].map((region) => `oaisdmntpr${region}.blob.core.windows.net`)
46939
+ );
46940
+ function isAllowedAttachmentHost(hostname2) {
46941
+ const h2 = hostname2.toLowerCase();
46942
+ return OAI_USERCONTENT_HOST.test(h2) || OAI_BLOB_ACCOUNTS.has(h2);
46943
+ }
46944
+ function checkAttachmentUrl(url) {
46945
+ if (url.protocol !== "https:") return "is not an https URL";
46946
+ if (url.port) return "uses a non-default port";
46947
+ if (!isAllowedAttachmentHost(url.hostname)) {
46948
+ return `host "${url.hostname}" is not a ChatGPT file host`;
46949
+ }
46950
+ return void 0;
46951
+ }
46952
+ var AttachmentError = class extends Error {
46953
+ };
46954
+ function attachmentPath(a2, url) {
46955
+ let fromUrl = "";
46956
+ try {
46957
+ fromUrl = decodeURIComponent(
46958
+ url.pathname.split("/").filter(Boolean).pop() ?? ""
46959
+ );
46960
+ } catch {
46961
+ fromUrl = "";
46962
+ }
46963
+ const raw = (a2.file_name?.trim() || fromUrl || a2.file_id).replace(/\\/g, "/");
46964
+ const segments = raw.split("/").filter((s2) => s2 && s2 !== "." && s2 !== "..");
46965
+ return segments.join("/") || a2.file_id;
46966
+ }
46967
+ function toBase64(bytes2) {
46968
+ let binary = "";
46969
+ const chunk = 32768;
46970
+ for (let i = 0; i < bytes2.length; i += chunk) {
46971
+ binary += String.fromCharCode(...bytes2.subarray(i, i + chunk));
46972
+ }
46973
+ return btoa(binary);
46974
+ }
46975
+ async function fetchAllowed(start, fetchImpl, label) {
46976
+ let url = start;
46977
+ for (let hop = 0; ; hop++) {
46978
+ const res = await fetchImpl(url.toString(), { redirect: "manual" });
46979
+ const location = res.headers.get("location");
46980
+ const isRedirect = res.status >= 300 && res.status < 400 && location;
46981
+ if (!isRedirect) return res;
46982
+ await res.body?.cancel().catch(() => void 0);
46983
+ if (hop >= MAX_REDIRECTS) {
46984
+ throw new AttachmentError(`${label}: too many redirects.`);
46985
+ }
46986
+ let next;
46987
+ try {
46988
+ next = new URL(location, url);
46989
+ } catch {
46990
+ throw new AttachmentError(`${label}: redirect to an invalid URL.`);
46991
+ }
46992
+ const problem = checkAttachmentUrl(next);
46993
+ if (problem) {
46994
+ throw new AttachmentError(
46995
+ `${label}: the download redirected to a URL that ${problem}; refused.`
46996
+ );
46997
+ }
46998
+ url = next;
46999
+ }
47000
+ }
47001
+ async function readWithin(res, budget, overBudget) {
47002
+ const declared = Number(res.headers.get("content-length") ?? 0);
47003
+ if (declared > budget) throw overBudget();
47004
+ if (!res.body) {
47005
+ const bytes2 = new Uint8Array(await res.arrayBuffer());
47006
+ if (bytes2.byteLength > budget) throw overBudget();
47007
+ return bytes2;
47008
+ }
47009
+ const reader = res.body.getReader();
47010
+ const chunks = [];
47011
+ let total = 0;
47012
+ for (; ; ) {
47013
+ const { done, value } = await reader.read();
47014
+ if (done) break;
47015
+ total += value.byteLength;
47016
+ if (total > budget) {
47017
+ await reader.cancel().catch(() => void 0);
47018
+ throw overBudget();
47019
+ }
47020
+ chunks.push(value);
47021
+ }
47022
+ const out = new Uint8Array(total);
47023
+ let offset = 0;
47024
+ for (const c of chunks) {
47025
+ out.set(c, offset);
47026
+ offset += c.byteLength;
47027
+ }
47028
+ return out;
47029
+ }
47030
+ async function resolveAttachments(attachments, fetchImpl = fetch) {
47031
+ if (!Array.isArray(attachments) || attachments.length === 0) return [];
47032
+ const items = [];
47033
+ attachments.forEach((raw, i) => {
47034
+ const a2 = typeof raw === "object" && raw;
47035
+ const downloadUrl = a2 && typeof a2.download_url === "string" ? a2.download_url : "";
47036
+ let url;
47037
+ try {
47038
+ url = /^https?:\/\//i.test(downloadUrl) ? new URL(downloadUrl) : void 0;
47039
+ } catch {
47040
+ url = void 0;
47041
+ }
47042
+ if (!a2 || !url) {
47043
+ throw new AttachmentError(
47044
+ `attachments[${i}] was not resolved to a download URL (got ${JSON.stringify(
47045
+ typeof raw === "string" ? raw : (a2 && a2.download_url) ?? raw
47046
+ )}). The platform did not hydrate this attachment; retry once, and if it still arrives like this put the file in the \`files\` bundle instead (\`=== FILE: <path> base64 ===\` for binary).`
47047
+ );
47048
+ }
47049
+ const problem = checkAttachmentUrl(url);
47050
+ if (problem) {
47051
+ throw new AttachmentError(
47052
+ `attachments[${i}].download_url ${problem}. Only platform-resolved attachments are accepted here; for any other URL fetch it in \`code\` via wix.request or put the bytes in the \`files\` bundle.`
47053
+ );
47054
+ }
47055
+ items.push({ a: a2, url });
47056
+ });
47057
+ let remaining = MAX_ATTACHMENTS_BYTES;
47058
+ const out = [];
47059
+ for (const [i, { a: a2, url }] of items.entries()) {
47060
+ const path = attachmentPath(a2, url);
47061
+ const label = `attachments[${i}] (${path})`;
47062
+ let res;
47063
+ try {
47064
+ res = await fetchAllowed(url, fetchImpl, label);
47065
+ } catch (e) {
47066
+ if (e instanceof AttachmentError) throw e;
47067
+ throw new AttachmentError(
47068
+ `${label}: download failed (${e.message}).`
47069
+ );
47070
+ }
47071
+ if (!res.ok) {
47072
+ await res.body?.cancel().catch(() => void 0);
47073
+ throw new AttachmentError(
47074
+ `${label}: download returned HTTP ${res.status}. The download_url may have expired; attach the file again.`
47075
+ );
47076
+ }
47077
+ const bytes2 = await readWithin(
47078
+ res,
47079
+ remaining,
47080
+ () => new AttachmentError(
47081
+ `${label} pushes the attachments past ${MAX_ATTACHMENTS_BYTES} bytes in total for this call; split the upload across calls.`
47082
+ )
47083
+ );
47084
+ remaining -= bytes2.byteLength;
47085
+ out.push({ path, content: toBase64(bytes2), encoding: "base64" });
47086
+ }
47087
+ return out;
47088
+ }
47089
+
46889
47090
  // src/code-mode/validation.ts
46890
47091
  var EXECUTE_FUNCTION_EXPRESSION_HINT = 'ExecuteWixAPI code must be a function expression, not a script body. Pass code like: async () => { const response = await wix.request({ scope: "site", method: "GET", url: "https://www.wixapis.com/..." }); return response.data; }. Do not write top-level const/await/return outside the function and do not invoke the function yourself.';
46891
47092
  function validateExecuteCode(code) {
@@ -47118,7 +47319,7 @@ function addExecuteTool(server, options) {
47118
47319
  } = options;
47119
47320
  const executeUrl = `${codeModeBaseUrl}/api/code-mode/execute`;
47120
47321
  const d2 = desc("ExecuteWixAPI");
47121
- server.tool(
47322
+ const registered = server.tool(
47122
47323
  EXECUTE_TOOL_NAME,
47123
47324
  toolDescriptions?.[EXECUTE_TOOL_NAME] ?? defaultToolDescriptions.ExecuteWixAPI,
47124
47325
  {
@@ -47147,6 +47348,20 @@ function addExecuteTool(server, options) {
47147
47348
  'Use base64 entries for small assets (icons, logos, fonts) and for files you downloaded and are re-uploading; large images/video go in by URL (`<img src="https://...">`), not in the bundle. A file containing a line exactly like the delimiter is not supported.'
47148
47349
  ].join(" ")
47149
47350
  ),
47351
+ // ChatGPT file attachments (`openai/fileParams`). Item shape must match
47352
+ // OpenAI's file schema: download_url + file_id required, the rest optional.
47353
+ // Declaring it is what makes the platform hand us a download URL instead
47354
+ // of a sandbox path. Resolved host-side into base64 `files` entries.
47355
+ attachments: external_exports.array(
47356
+ external_exports.object({
47357
+ download_url: external_exports.string(),
47358
+ file_id: external_exports.string(),
47359
+ file_name: external_exports.string().optional(),
47360
+ mime_type: external_exports.string().optional()
47361
+ })
47362
+ ).optional().describe(
47363
+ 'Files attached in this chat, or files you created in your own file sandbox (any type: a zip of a site, HTML, images, PDFs). Pass the files themselves and the platform resolves each into { download_url, file_id, file_name?, mime_type? }; the bytes are fetched here and appended to the `files` global as { path, content, encoding: "base64" } entries (path = file_name), so `wix.multipart()` and `wix.unzip()` work on them unchanged. Prefer this over base64 in `files` whenever you have a file handle. Up to 10 MB per call.'
47364
+ ),
47150
47365
  // Visitor mode takes an agent-supplied token and pins the site; account/site
47151
47366
  // mode lets the agent pick the site.
47152
47367
  ...visitor ? {
@@ -47161,7 +47376,15 @@ function addExecuteTool(server, options) {
47161
47376
  },
47162
47377
  { readOnlyHint: false, destructiveHint: true, openWorldHint: false },
47163
47378
  async (rawArgs, extra) => {
47164
- const { code, reason, hasMutations, sourceDocUrls, visitorToken, files } = rawArgs;
47379
+ const {
47380
+ code,
47381
+ reason,
47382
+ hasMutations,
47383
+ sourceDocUrls,
47384
+ visitorToken,
47385
+ files,
47386
+ attachments
47387
+ } = rawArgs;
47165
47388
  const siteId = visitor ? visitor.siteId : rawArgs.siteId;
47166
47389
  logger2.log(
47167
47390
  `[ExecuteWixAPI]${visitor ? " (visitor)" : ""} Executing code (${code.length} chars), siteId=${siteId ?? "none"}, hasMutations=${hasMutations}, sourceDocUrls=${JSON.stringify(sourceDocUrls)}, reason="${reason}"`
@@ -47173,6 +47396,13 @@ function addExecuteTool(server, options) {
47173
47396
  );
47174
47397
  return executeTextResult(validation.error);
47175
47398
  }
47399
+ let attachmentFiles = [];
47400
+ try {
47401
+ attachmentFiles = await resolveAttachments(attachments);
47402
+ } catch (e) {
47403
+ if (e instanceof AttachmentError) return executeErrorResult(e.message);
47404
+ throw e;
47405
+ }
47176
47406
  const accountHeaders = await authStrategy?.getAccountAuthHeaders();
47177
47407
  const siteAuthContext = !visitor && authStrategy?.getSiteAuthContext ? await authStrategy.getSiteAuthContext() : void 0;
47178
47408
  let siteHeaders;
@@ -47207,7 +47437,8 @@ function addExecuteTool(server, options) {
47207
47437
  accountToken: visitor ? visitorToken : accountHeaders?.Authorization,
47208
47438
  accountId: accountHeaders?.["wix-account-id"],
47209
47439
  siteAuthContext,
47210
- ...files ? { files } : {}
47440
+ ...files ? { files } : {},
47441
+ ...attachmentFiles.length ? { attachmentFiles } : {}
47211
47442
  },
47212
47443
  visitor ? visitorToken : accountHeaders?.Authorization ?? siteHeaders?.Authorization,
47213
47444
  codeModeFetch
@@ -47238,6 +47469,9 @@ function addExecuteTool(server, options) {
47238
47469
  }
47239
47470
  }
47240
47471
  );
47472
+ registered?.update?.({
47473
+ _meta: { ...registered._meta, "openai/fileParams": ["attachments"] }
47474
+ });
47241
47475
  }
47242
47476
 
47243
47477
  // src/toolkit.ts