@runpod/mcp-server 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -219,15 +219,27 @@ function mapPodUpdateToV2(params) {
219
219
  ...compact({ name: params.name })
220
220
  };
221
221
  }
222
- function nestedOrUndefined(obj) {
223
- const c = compact(obj);
224
- return Object.keys(c).length ? c : void 0;
222
+ var DEFAULT_ENDPOINT_TYPE = "QUEUE";
223
+ var DEFAULT_SCALER_VALUE = 4;
224
+ function defaultScalerType(endpointType) {
225
+ return endpointType === "LOAD_BALANCER" ? "REQUEST_COUNT" : "QUEUE_DELAY";
226
+ }
227
+ function endpointScaling(scalerType, value) {
228
+ return scalerType === "REQUEST_COUNT" ? { type: "REQUEST_COUNT", requestCount: value } : { type: "QUEUE_DELAY", queueDelay: value };
225
229
  }
226
230
  function endpointGpuConfig(pools, count) {
227
231
  if (!pools?.length) return void 0;
228
232
  return compact({ pools, count });
229
233
  }
230
- function mapEndpointToV2(params) {
234
+ function endpointWorkers(params) {
235
+ const workers = compact({
236
+ min: params.workersMin,
237
+ max: params.workersMax,
238
+ idleTimeout: params.idleTimeout
239
+ });
240
+ return Object.keys(workers).length ? workers : void 0;
241
+ }
242
+ function endpointCommonToV2(params) {
231
243
  return compact({
232
244
  name: params.name,
233
245
  image: params.imageName,
@@ -237,23 +249,33 @@ function mapEndpointToV2(params) {
237
249
  env: params.env,
238
250
  registry: params.containerRegistryAuthId,
239
251
  gpu: endpointGpuConfig(params.gpuPoolIds, params.gpuCount),
240
- workers: nestedOrUndefined({
241
- min: params.workersMin,
242
- max: params.workersMax
243
- }),
244
- scaling: nestedOrUndefined({
245
- type: params.scalerType,
246
- value: params.scalerValue,
247
- idleTimeout: params.idleTimeout
248
- }),
252
+ workers: endpointWorkers(params),
249
253
  dataCenterIds: params.dataCenterIds?.length ? params.dataCenterIds : void 0,
250
254
  networkVolumes: params.networkVolumeIds?.length ? params.networkVolumeIds : void 0,
251
255
  timeout: params.executionTimeoutMs,
252
256
  flashboot: params.flashboot
253
257
  });
254
258
  }
255
- var mapEndpointCreateToV2 = mapEndpointToV2;
256
- var mapEndpointUpdateToV2 = mapEndpointToV2;
259
+ function mapEndpointCreateToV2(params) {
260
+ const endpointType = params.endpointType ?? DEFAULT_ENDPOINT_TYPE;
261
+ return compact({
262
+ ...endpointCommonToV2(params),
263
+ type: endpointType,
264
+ scaling: endpointScaling(
265
+ params.scalerType ?? defaultScalerType(endpointType),
266
+ params.scalerValue ?? DEFAULT_SCALER_VALUE
267
+ )
268
+ });
269
+ }
270
+ function mapEndpointUpdateToV2(params) {
271
+ return compact({
272
+ ...endpointCommonToV2(params),
273
+ scaling: params.scalerType ? endpointScaling(
274
+ params.scalerType,
275
+ params.scalerValue ?? DEFAULT_SCALER_VALUE
276
+ ) : void 0
277
+ });
278
+ }
257
279
  function mapNetworkVolumeCreateToV2(params) {
258
280
  return compact({
259
281
  name: params.name,
@@ -508,7 +530,7 @@ function resolveBackend(opts) {
508
530
  }
509
531
 
510
532
  // src/tools/runtime.ts
511
- var MCP_SERVER_VERSION = true ? "3.0.0" : "dev";
533
+ var MCP_SERVER_VERSION = true ? "3.1.0" : "dev";
512
534
  var SESSION_ID = randomUUID();
513
535
  function trackingHeaders(server, ctx) {
514
536
  const info = server.server.getClientVersion();
@@ -1894,11 +1916,22 @@ function registerPodTools(server, rt) {
1894
1916
 
1895
1917
  // src/tools/endpoints.ts
1896
1918
  import { z as z8 } from "zod";
1919
+ var MIN_QUEUE_DELAY = 0.5;
1920
+ var MIN_REQUEST_COUNT = 1;
1921
+ var MIN_IDLE_TIMEOUT = 1;
1922
+ var MAX_IDLE_TIMEOUT = 3600;
1923
+ function scalerValueError(scalerType, scalerValue) {
1924
+ if (scalerType !== "REQUEST_COUNT" || scalerValue === void 0) return;
1925
+ if (!Number.isInteger(scalerValue) || scalerValue < MIN_REQUEST_COUNT) {
1926
+ return `REQUEST_COUNT scales on whole in-flight requests per worker, so scalerValue must be an integer >= ${MIN_REQUEST_COUNT} (got ${scalerValue}). For a fractional target use scalerType QUEUE_DELAY, which takes seconds >= ${MIN_QUEUE_DELAY}.`;
1927
+ }
1928
+ return;
1929
+ }
1897
1930
  function registerEndpointTools(server, rt) {
1898
1931
  const { jsonReply: jsonReply2, callRestUrl, backendFor } = rt;
1899
1932
  server.tool(
1900
1933
  "list-endpoints",
1901
- "List your Serverless endpoints, optionally expanding template and worker details (v1 only). Paginated via limit/cursor.",
1934
+ "List your Serverless endpoints, optionally expanding template and worker details (v1 only). Paginated via limit/cursor. On v2 each endpoint carries its request routing in `type` and the URLs to call it in `requestUrls`.",
1902
1935
  {
1903
1936
  ...listPaginationParams,
1904
1937
  includeTemplate: z8.boolean().optional().describe("Include template information (v1 only)"),
@@ -1933,7 +1966,7 @@ function registerEndpointTools(server, rt) {
1933
1966
  );
1934
1967
  server.tool(
1935
1968
  "get-endpoint",
1936
- "Get one Serverless endpoint by id, optionally expanding template and worker details (v1 only).",
1969
+ "Get one Serverless endpoint by id, optionally expanding template and worker details (v1 only). On v2 the reply carries `type` (queue-based vs load-balancing routing) and `requestUrls` \u2014 the run/runsync/status/... URLs for a queue endpoint, or the base + health URLs for a load-balancing one. Read those rather than constructing endpoint URLs by hand.",
1937
1970
  {
1938
1971
  endpointId: z8.string().describe("ID of the endpoint to retrieve"),
1939
1972
  includeTemplate: z8.boolean().optional().describe("Include template information (v1 only)"),
@@ -1965,11 +1998,14 @@ function registerEndpointTools(server, rt) {
1965
1998
  );
1966
1999
  server.tool(
1967
2000
  "create-endpoint",
1968
- "Create a Serverless endpoint. On v2 (default), pass an inline config: imageName + gpuPoolIds (GPU pool names from list-gpu-types \u2014 the `pool` field, e.g. AMPERE_80/ADA_24) plus optional workers/scaling/disk/env. On v1, pass a templateId instead. Worker min/max set autoscaling bounds (min 0 = scale to zero).",
2001
+ "Create a Serverless endpoint. On v2 (default), pass an inline config: imageName + gpuPoolIds (GPU pool names from list-gpu-types \u2014 the `pool` field, e.g. AMPERE_80/ADA_24) plus optional workers/scaling/disk/env. On v1, pass a templateId instead. Worker min/max set autoscaling bounds (min 0 = scale to zero). Use endpointType to pick queue-based (default) or load-balancing request routing; the response `requestUrls` carries the URLs to call the endpoint with.",
1969
2002
  {
1970
2003
  name: z8.string().optional().describe("Name for the endpoint"),
1971
2004
  // --- v2 inline-config fields ---
1972
2005
  imageName: z8.string().optional().describe("Docker image (v2). Required on v2 instead of a templateId."),
2006
+ endpointType: z8.enum(["QUEUE", "LOAD_BALANCER"]).optional().describe(
2007
+ "How requests reach the workers (v2). QUEUE (default) = submit jobs through the managed queue (run/runsync/status/...). LOAD_BALANCER = send HTTP requests straight to worker-defined paths, and forces scalerType REQUEST_COUNT. Fixed at creation \u2014 update-endpoint cannot change it."
2008
+ ),
1973
2009
  gpuPoolIds: z8.array(z8.string()).optional().describe(
1974
2010
  'GPU pool names (v2, required). The `pool` field from list-gpu-types, e.g. ["AMPERE_80"]. NOT GPU type ids.'
1975
2011
  ),
@@ -1989,9 +2025,15 @@ function registerEndpointTools(server, rt) {
1989
2025
  // --- shared autoscaling fields ---
1990
2026
  workersMin: z8.number().optional().describe("Minimum number of workers"),
1991
2027
  workersMax: z8.number().optional().describe("Maximum number of workers"),
1992
- scalerType: z8.enum(["QUEUE_DELAY", "REQUEST_COUNT"]).optional().describe("Autoscaler type"),
1993
- scalerValue: z8.number().optional().describe("Autoscaler target value"),
1994
- idleTimeout: z8.number().optional().describe("Idle timeout in seconds before scaling a worker down"),
2028
+ scalerType: z8.enum(["QUEUE_DELAY", "REQUEST_COUNT"]).optional().describe(
2029
+ "Autoscaler signal. QUEUE_DELAY scales on how long requests wait in the queue (queue endpoints only); REQUEST_COUNT scales on in-flight requests per worker. Defaults to QUEUE_DELAY for QUEUE endpoints and REQUEST_COUNT for LOAD_BALANCER ones."
2030
+ ),
2031
+ scalerValue: z8.number().min(MIN_QUEUE_DELAY).optional().describe(
2032
+ "Autoscaler target for the chosen scalerType \u2014 seconds of queue delay (min 0.5) or in-flight requests per worker (integer, min 1). Defaults to 4."
2033
+ ),
2034
+ idleTimeout: z8.number().int().min(MIN_IDLE_TIMEOUT).max(MAX_IDLE_TIMEOUT).optional().describe(
2035
+ "Idle timeout in seconds before scaling a worker down (1-3600). Does not apply to QUEUE endpoints scaling on REQUEST_COUNT."
2036
+ ),
1995
2037
  dataCenterIds: z8.array(z8.string()).optional().describe("List of preferred data centers")
1996
2038
  },
1997
2039
  { title: "Create endpoint", ...WRITE },
@@ -2016,6 +2058,19 @@ function registerEndpointTools(server, rt) {
2016
2058
  status: 400
2017
2059
  });
2018
2060
  }
2061
+ if (params.endpointType === "LOAD_BALANCER" && params.scalerType === "QUEUE_DELAY") {
2062
+ return jsonReply2({
2063
+ error: "LOAD_BALANCER endpoints have no request queue, so they cannot scale on QUEUE_DELAY. Use scalerType REQUEST_COUNT (the default for this endpoint type), or create a QUEUE endpoint instead.",
2064
+ status: 400
2065
+ });
2066
+ }
2067
+ const scalerError = scalerValueError(
2068
+ params.scalerType ?? (params.endpointType === "LOAD_BALANCER" ? "REQUEST_COUNT" : void 0),
2069
+ params.scalerValue
2070
+ );
2071
+ if (scalerError) {
2072
+ return jsonReply2({ error: scalerError, status: 400 });
2073
+ }
2019
2074
  const body = backend.mapCreate(params);
2020
2075
  const result2 = await callRestUrl(
2021
2076
  `${backend.base}${backend.list}`,
@@ -2053,15 +2108,21 @@ function registerEndpointTools(server, rt) {
2053
2108
  );
2054
2109
  server.tool(
2055
2110
  "update-endpoint",
2056
- "Update a Serverless endpoint's config. On v2 you can change image/disk/env/ports/registry/workers/scaling/networkVolumes/timeout/flashboot; on v1, scaling fields (worker min/max, idle timeout, scaler type/value, name). Only provided fields change.",
2111
+ "Update a Serverless endpoint's config. On v2 you can change image/disk/env/ports/registry/workers/scaling/networkVolumes/timeout/flashboot; on v1, scaling fields (worker min/max, idle timeout, scaler type/value, name). Only provided fields change. An endpoint's request routing (queue vs load balancer) is fixed at creation and cannot be changed here \u2014 recreate the endpoint instead.",
2057
2112
  {
2058
2113
  endpointId: z8.string().describe("ID of the endpoint to update"),
2059
2114
  name: z8.string().optional().describe("New name for the endpoint"),
2060
2115
  workersMin: z8.number().optional().describe("New minimum number of workers"),
2061
2116
  workersMax: z8.number().optional().describe("New maximum number of workers"),
2062
- idleTimeout: z8.number().optional().describe("New idle timeout in seconds"),
2063
- scalerType: z8.enum(["QUEUE_DELAY", "REQUEST_COUNT"]).optional().describe("Scaler type"),
2064
- scalerValue: z8.number().optional().describe("Scaler value"),
2117
+ idleTimeout: z8.number().int().min(MIN_IDLE_TIMEOUT).max(MAX_IDLE_TIMEOUT).optional().describe(
2118
+ "New idle timeout in seconds (1-3600). Does not apply to queue endpoints scaling on REQUEST_COUNT."
2119
+ ),
2120
+ scalerType: z8.enum(["QUEUE_DELAY", "REQUEST_COUNT"]).optional().describe(
2121
+ "New autoscaler signal. Switchable on queue endpoints; load-balancing endpoints only accept REQUEST_COUNT."
2122
+ ),
2123
+ scalerValue: z8.number().min(MIN_QUEUE_DELAY).optional().describe(
2124
+ "New autoscaler target \u2014 seconds of queue delay (min 0.5) or in-flight requests per worker (integer, min 1). Applies to the endpoint's current scalerType unless you also pass a new one."
2125
+ ),
2065
2126
  // --- v2-only inline-config fields ---
2066
2127
  imageName: z8.string().optional().describe("New Docker image (v2)"),
2067
2128
  gpuPoolIds: z8.array(z8.string()).optional().describe('New GPU pool names (v2), e.g. ["AMPERE_80"]'),
@@ -2079,13 +2140,28 @@ function registerEndpointTools(server, rt) {
2079
2140
  async (params) => {
2080
2141
  const { endpointId, ...updateParams } = params;
2081
2142
  const backend = backendFor("endpoints");
2082
- const body = backend.mapUpdate(updateParams);
2083
- const result = await callRestUrl(
2084
- `${backend.base}${backend.get(endpointId)}`,
2085
- "PATCH",
2086
- body
2143
+ const url = `${backend.base}${backend.get(endpointId)}`;
2144
+ if (backend.version !== "v2") {
2145
+ const body2 = backend.mapUpdate(updateParams);
2146
+ return jsonReply2(await callRestUrl(url, "PATCH", body2));
2147
+ }
2148
+ let scalerType = updateParams.scalerType;
2149
+ if (scalerType === void 0 && updateParams.scalerValue !== void 0) {
2150
+ const current = await callRestUrl(url);
2151
+ scalerType = current?.scaling?.type === "REQUEST_COUNT" ? "REQUEST_COUNT" : "QUEUE_DELAY";
2152
+ }
2153
+ const scalerError = scalerValueError(
2154
+ scalerType,
2155
+ updateParams.scalerValue
2087
2156
  );
2088
- return jsonReply2(result);
2157
+ if (scalerError) {
2158
+ return jsonReply2({ error: scalerError, status: 400 });
2159
+ }
2160
+ const body = backend.mapUpdate({
2161
+ ...updateParams,
2162
+ scalerType
2163
+ });
2164
+ return jsonReply2(await callRestUrl(url, "PATCH", body));
2089
2165
  }
2090
2166
  );
2091
2167
  server.tool(
@@ -2133,7 +2209,7 @@ function registerEndpointTools(server, rt) {
2133
2209
  );
2134
2210
  server.tool(
2135
2211
  "list-endpoint-workers",
2136
- "List the workers backing a Serverless endpoint, with their status and an aggregate summary. v2-only \u2014 returns a 501 notice on the v1 API. Paginated via limit/cursor.",
2212
+ "List the workers backing a Serverless endpoint, with their status and an aggregate summary. v2-only \u2014 returns a 501 notice on the v1 API. An UNHEALTHY worker usually means the container is crash-looping (repeated starts that exit before the handler runs) \u2014 jobs on the endpoint will sit IN_QUEUE even though this is a worker failure, not a capacity shortage; inspect it with stream-worker-logs. Zero workers while jobs queue means the endpoint is waiting for GPU capacity. Paginated via limit/cursor.",
2137
2213
  {
2138
2214
  ...listPaginationParams,
2139
2215
  endpointId: z8.string().describe("ID of the Serverless endpoint whose workers to list")
@@ -2159,7 +2235,7 @@ function registerEndpointTools(server, rt) {
2159
2235
  );
2160
2236
  server.tool(
2161
2237
  "stream-worker-logs",
2162
- "Fetch a bounded snapshot of a serverless worker's live logs (container and/or system) via Server-Sent Events. v2-only \u2014 returns a 501 notice on the v1 API. Get the workerId from list-endpoint-workers. Reads for up to maxWaitMs (default 5s) and returns the collected log lines; use `tail` to backfill recent lines first. Large output is truncated (see the `truncated` flag).",
2238
+ "Fetch a bounded snapshot of a serverless worker's live logs (container and/or system) via Server-Sent Events. v2-only \u2014 returns a 501 notice on the v1 API. Get the workerId from list-endpoint-workers. Use this to diagnose UNHEALTHY workers: repeated `start container` system lines with no container output is the crash-loop signature (the container exits before the handler runs). Reads for up to maxWaitMs (default 5s) and returns the collected log lines; use `tail` to backfill recent lines first. Large output is truncated (see the `truncated` flag).",
2163
2239
  {
2164
2240
  endpointId: z8.string().describe("ID of the Serverless endpoint the worker belongs to"),
2165
2241
  workerId: z8.string().describe(
@@ -2182,8 +2258,67 @@ function registerEndpointTools(server, rt) {
2182
2258
 
2183
2259
  // src/tools/jobs.ts
2184
2260
  import { z as z9 } from "zod";
2261
+ var DIAGNOSIS_TTL_MS = 15e3;
2262
+ var MAX_DIAGNOSIS_ENTRIES = 500;
2263
+ var diagnosisCache = /* @__PURE__ */ new Map();
2185
2264
  function registerJobTools(server, rt) {
2186
- const { jsonReply: jsonReply2, serverlessRequest } = rt;
2265
+ const { jsonReply: jsonReply2, serverlessRequest, backendFor, callRestUrl } = rt;
2266
+ async function diagnoseQueuedJob(endpointId) {
2267
+ const cached = diagnosisCache.get(endpointId);
2268
+ if (cached && cached.expiresAt > Date.now()) {
2269
+ return cached.value;
2270
+ }
2271
+ diagnosisCache.delete(endpointId);
2272
+ try {
2273
+ const backend = backendFor("workers");
2274
+ if (backend.version !== "v2") return null;
2275
+ const raw = await callRestUrl(
2276
+ `${backend.base}/serverless/${endpointId}/workers`
2277
+ );
2278
+ const summary = raw?.summary;
2279
+ const workers = raw?.workers ?? [];
2280
+ if (!summary) return null;
2281
+ const remember = (value) => {
2282
+ if (diagnosisCache.size >= MAX_DIAGNOSIS_ENTRIES) {
2283
+ const oldest = diagnosisCache.keys().next().value;
2284
+ if (oldest !== void 0) diagnosisCache.delete(oldest);
2285
+ }
2286
+ diagnosisCache.set(endpointId, {
2287
+ value,
2288
+ expiresAt: Date.now() + DIAGNOSIS_TTL_MS
2289
+ });
2290
+ return value;
2291
+ };
2292
+ if ((summary.unhealthy ?? 0) > 0) {
2293
+ const badIds = workers.filter((w) => w.status === "UNHEALTHY").map((w) => w.id).join(", ");
2294
+ return remember({
2295
+ workerHealth: summary,
2296
+ hint: `${summary.unhealthy} of ${summary.total} worker(s) on this endpoint are UNHEALTHY \u2014 the container is likely crash-looping (repeated starts that exit before the handler runs). The job can stay IN_QUEUE indefinitely; this is a worker failure, NOT a capacity shortage. Inspect the logs with stream-worker-logs${badIds ? ` (workerId: ${badIds})` : ""}.`
2297
+ });
2298
+ }
2299
+ if ((summary.total ?? 0) === 0) {
2300
+ return remember({
2301
+ workerHealth: summary,
2302
+ hint: "No workers are scheduled for this endpoint yet \u2014 it may simply be scaling up from zero (normal for the first seconds of a cold start), or it is waiting for GPU capacity / its GPU-CUDA constraints exclude the currently-available hosts. If this persists, check availability with list-gpu-types or widen the gpuIds/CUDA settings."
2303
+ });
2304
+ }
2305
+ if ((summary.throttled ?? 0) > 0 && (summary.running ?? 0) === 0) {
2306
+ return remember({
2307
+ workerHealth: summary,
2308
+ hint: "Workers exist but are throttled \u2014 the hosts are at capacity right now; the job should start when capacity frees up."
2309
+ });
2310
+ }
2311
+ if ((summary.initializing ?? 0) > 0) {
2312
+ return remember({
2313
+ workerHealth: summary,
2314
+ hint: "A worker is initializing \u2014 likely a cold start (image pull / model load); the job should start soon."
2315
+ });
2316
+ }
2317
+ return remember({ workerHealth: summary, hint: "" });
2318
+ } catch {
2319
+ return null;
2320
+ }
2321
+ }
2187
2322
  const endpointIdSchema = z9.string().regex(/^[a-zA-Z0-9_-]+$/, "Invalid endpoint ID format");
2188
2323
  const jobIdSchema = z9.string().regex(/^[a-zA-Z0-9_-]+$/, "Invalid job ID format");
2189
2324
  const inputSchema = z9.record(z9.unknown()).describe(
@@ -2257,7 +2392,7 @@ function registerJobTools(server, rt) {
2257
2392
  );
2258
2393
  server.tool(
2259
2394
  "get-job-status",
2260
- "Check the status of an asynchronous Serverless job. Returns the current status and output when complete. Job statuses: IN_QUEUE, IN_PROGRESS, COMPLETED, FAILED, CANCELLED, TIMED_OUT.",
2395
+ "Check the status of an asynchronous Serverless job. Returns the current status and output when complete. Job statuses: IN_QUEUE, IN_PROGRESS, COMPLETED, FAILED, CANCELLED, TIMED_OUT. IMPORTANT: a job stuck IN_QUEUE does not necessarily mean a capacity shortage \u2014 a worker may have spun up and crash-looped (the platform marks it UNHEALTHY while the job stays queued). When the job is IN_QUEUE this tool attaches a workerHealth summary and a hint; to dig deeper, call list-endpoint-workers (look for UNHEALTHY) and stream-worker-logs.",
2261
2396
  {
2262
2397
  endpointId: endpointIdSchema.describe(
2263
2398
  "ID of the Serverless endpoint the job belongs to"
@@ -2270,6 +2405,16 @@ function registerJobTools(server, rt) {
2270
2405
  params.endpointId,
2271
2406
  `/status/${params.jobId}`
2272
2407
  );
2408
+ if (result && typeof result === "object" && result.status === "IN_QUEUE") {
2409
+ const diagnosis = await diagnoseQueuedJob(params.endpointId);
2410
+ if (diagnosis) {
2411
+ return jsonReply2({
2412
+ ...result,
2413
+ workerHealth: diagnosis.workerHealth,
2414
+ ...diagnosis.hint ? { hint: diagnosis.hint } : {}
2415
+ });
2416
+ }
2417
+ }
2273
2418
  return jsonReply2(result);
2274
2419
  }
2275
2420
  );
@@ -2371,7 +2516,7 @@ function registerJobTools(server, rt) {
2371
2516
  );
2372
2517
  server.tool(
2373
2518
  "endpoint-health",
2374
- "Get the health and operational status of a Serverless endpoint, including worker counts and job statistics.",
2519
+ "Get the health and operational status of a Serverless endpoint, including worker counts and job statistics. Use this when jobs are stuck IN_QUEUE: unhealthy workers mean a crash-looping container (a worker failure \u2014 inspect with stream-worker-logs), while zero workers means the endpoint is waiting for GPU capacity.",
2375
2520
  {
2376
2521
  endpointId: endpointIdSchema.describe(
2377
2522
  "ID of the Serverless endpoint to check health for"
@@ -2875,4 +3020,4 @@ export {
2875
3020
  restVersionSummary,
2876
3021
  registerTools
2877
3022
  };
2878
- //# sourceMappingURL=chunk-GTBCNGHE.mjs.map
3023
+ //# sourceMappingURL=chunk-OM6RHPQC.mjs.map