@shuffleio/shuffle-mcps 0.0.65 → 0.0.66

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/dist/index.js CHANGED
@@ -1062,11 +1062,11 @@ __export(appsCache_exports, {
1062
1062
  fetchAppsViaApiConfig: () => fetchAppsViaApiConfig,
1063
1063
  invalidateAppsCache: () => invalidateAppsCache
1064
1064
  });
1065
- var TTL_MS2, ERROR_TTL_MS, cache2, cacheKey2, doFetch2, fetchApps, invalidateAppsCache, fetchAppsViaApiConfig;
1065
+ var TTL_MS3, ERROR_TTL_MS, cache2, cacheKey2, doFetch2, fetchApps, invalidateAppsCache, fetchAppsViaApiConfig;
1066
1066
  var init_appsCache = __esm({
1067
1067
  "../Shuffle-Core/appsCache.ts"() {
1068
1068
  init_api();
1069
- TTL_MS2 = 3e4;
1069
+ TTL_MS3 = 3e4;
1070
1070
  ERROR_TTL_MS = 3e4;
1071
1071
  cache2 = /* @__PURE__ */ new Map();
1072
1072
  cacheKey2 = (o) => `${o.baseUrl}|${o.path || "/api/v1/apps"}|${o.apiKey || ""}|${o.orgId || ""}`;
@@ -1088,7 +1088,7 @@ var init_appsCache = __esm({
1088
1088
  fetchApps = (opts) => {
1089
1089
  const key = cacheKey2(opts);
1090
1090
  const entry = cache2.get(key) || {};
1091
- if (entry.data && entry.fetchedAt && Date.now() - entry.fetchedAt < TTL_MS2) {
1091
+ if (entry.data && entry.fetchedAt && Date.now() - entry.fetchedAt < TTL_MS3) {
1092
1092
  return Promise.resolve(entry.data);
1093
1093
  }
1094
1094
  if (entry.promise) return entry.promise;
@@ -1096,7 +1096,7 @@ var init_appsCache = __esm({
1096
1096
  cache2.set(key, { data, fetchedAt: Date.now() });
1097
1097
  return data;
1098
1098
  }).catch(() => {
1099
- cache2.set(key, { data: [], fetchedAt: Date.now() - (TTL_MS2 - ERROR_TTL_MS) });
1099
+ cache2.set(key, { data: [], fetchedAt: Date.now() - (TTL_MS3 - ERROR_TTL_MS) });
1100
1100
  return [];
1101
1101
  });
1102
1102
  cache2.set(key, { ...entry, promise });
@@ -1257,7 +1257,7 @@ __export(index_exports, {
1257
1257
  setRuntimeOrgId: () => setRuntimeOrgId,
1258
1258
  setToastImpl: () => setToastImpl,
1259
1259
  shuffleFetch: () => shuffleFetch,
1260
- toast: () => toast,
1260
+ toast: () => toast2,
1261
1261
  useAgentPromptPrefix: () => useAgentPromptPrefix,
1262
1262
  useAppAuth: () => useAppAuth,
1263
1263
  useAppAuthFlow: () => useAppAuthFlow,
@@ -1860,6 +1860,89 @@ var acquireDatastoreSlot = (priority = false) => new Promise((resolve) => {
1860
1860
 
1861
1861
  // ../Shuffle-Core/datastore.ts
1862
1862
  init_api();
1863
+
1864
+ // ../Shuffle-Core/securityRulesGuard.ts
1865
+ var import_sonner = require("sonner");
1866
+ init_api();
1867
+ var GUARDED_CATEGORIES = /* @__PURE__ */ new Set([
1868
+ "shuffle-security_incidents",
1869
+ "shuffle-security_vulns"
1870
+ ]);
1871
+ var DEFAULT_RULE = "merge if always; deny if has_deleted_field";
1872
+ var NAME = "Security Rules";
1873
+ var DESCRIPTION = "Describes security rules that are validated BEFORE an update occurs. This is in order for bad writes to be avoided. Control: allow, deny, merge, overwrite. Logic: if, or, and. Functions: same_shape, is_superset, has_deleted_field";
1874
+ var TTL_MS = 5 * 60 * 1e3;
1875
+ var verifiedAt = /* @__PURE__ */ new Map();
1876
+ var inFlight = /* @__PURE__ */ new Map();
1877
+ var warned = /* @__PURE__ */ new Set();
1878
+ var buildUrl = (path, regionUrl) => regionUrl ? `${regionUrl.replace(/\/+$/, "")}${path}` : getApiUrl(path);
1879
+ var run = async (orgId, category, regionUrl) => {
1880
+ const headers = {
1881
+ "Content-Type": "application/json",
1882
+ ...getAuthHeader(orgId),
1883
+ "Org-Id": orgId
1884
+ };
1885
+ const res = await fetch(
1886
+ buildUrl(`/api/v1/orgs/${orgId}/list_cache?category=${encodeURIComponent(category)}&top=1`, regionUrl),
1887
+ { credentials: "include", headers }
1888
+ );
1889
+ if (!res.ok) throw new Error(`list_cache responded with ${res.status}`);
1890
+ const data = await res.json().catch(() => ({}));
1891
+ const cfg = data?.category_config || {};
1892
+ const automations = Array.isArray(cfg.automations) ? cfg.automations.map((a) => ({ ...a })) : [];
1893
+ const idx = automations.findIndex((a) => a.type === "security_rules" || a.name === NAME);
1894
+ const current = idx >= 0 ? automations[idx] : null;
1895
+ const currentRule = (current?.options || []).find((o) => o.key === "rule")?.value?.trim();
1896
+ if (current?.enabled && currentRule) return;
1897
+ if (current) {
1898
+ automations[idx] = {
1899
+ ...current,
1900
+ enabled: true,
1901
+ options: [{ key: "rule", value: currentRule || DEFAULT_RULE }]
1902
+ };
1903
+ } else {
1904
+ automations.push({
1905
+ name: NAME,
1906
+ description: DESCRIPTION,
1907
+ options: [{ key: "rule", value: DEFAULT_RULE }],
1908
+ icon: "",
1909
+ enabled: true
1910
+ });
1911
+ }
1912
+ const payload = { category, automations };
1913
+ if (cfg.settings) payload.settings = cfg.settings;
1914
+ const save = await fetch(buildUrl("/api/v2/datastore/automate", regionUrl), {
1915
+ method: "POST",
1916
+ credentials: "include",
1917
+ headers,
1918
+ body: JSON.stringify(payload)
1919
+ });
1920
+ if (!save.ok) throw new Error(`automate responded with ${save.status}`);
1921
+ console.log(`[securityRules] enabled Security Rules for ${category} on org ${orgId}`);
1922
+ };
1923
+ var ensureSecurityRulesForWrite = async (orgId, category, regionUrl) => {
1924
+ if (!orgId || !GUARDED_CATEGORIES.has(category)) return;
1925
+ const key = `${orgId}|${category}`;
1926
+ const last = verifiedAt.get(key);
1927
+ if (last && Date.now() - last < TTL_MS) return;
1928
+ let pending = inFlight.get(key);
1929
+ if (!pending) {
1930
+ pending = run(orgId, category, regionUrl).then(() => {
1931
+ verifiedAt.set(key, Date.now());
1932
+ warned.delete(key);
1933
+ }).catch((err) => {
1934
+ console.warn("[securityRules] could not verify Security Rules", err);
1935
+ if (!warned.has(key)) {
1936
+ warned.add(key);
1937
+ import_sonner.toast.warning("Security Rules are not turned on for this category. The change was saved without them.");
1938
+ }
1939
+ }).finally(() => inFlight.delete(key));
1940
+ inFlight.set(key, pending);
1941
+ }
1942
+ await pending;
1943
+ };
1944
+
1945
+ // ../Shuffle-Core/datastore.ts
1863
1946
  var isCircuitBreakerResponse = (res) => {
1864
1947
  if (!res) return false;
1865
1948
  if (res.headers?.get?.("X-Circuit-Breaker") === "open") return true;
@@ -2045,6 +2128,7 @@ var setDatastoreItem = async (key, value, category, overrideOrgId, options) => {
2045
2128
  if (!orgId) {
2046
2129
  return { success: false, error: "No organization ID found" };
2047
2130
  }
2131
+ await ensureSecurityRulesForWrite(orgId, category, options?.regionUrl);
2048
2132
  const rawKey = normalizeDatastoreKey(key);
2049
2133
  let serialized = serializeDatastoreValue(value);
2050
2134
  if (category === "shuffle-security_incidents" && byteLength(serialized) > DATASTORE_VALUE_SOFT_LIMIT_BYTES) {
@@ -2067,7 +2151,9 @@ var setDatastoreItem = async (key, value, category, overrideOrgId, options) => {
2067
2151
  value: v,
2068
2152
  category,
2069
2153
  org_id: orgId,
2070
- ...category === "shuffle-security_incidents" ? { ignore_security_rules: true } : {}
2154
+ // Full-object overwrite on manual saves; Security Rules are still
2155
+ // ensured enabled by ensureSecurityRulesForWrite above.
2156
+ ignore_security_rules: true
2071
2157
  }];
2072
2158
  const headers = {
2073
2159
  "Content-Type": "application/json",
@@ -2145,11 +2231,11 @@ var setDatastoreItems = async (items, category) => {
2145
2231
  if (!orgId) {
2146
2232
  return { success: false, error: "No organization ID found" };
2147
2233
  }
2234
+ await ensureSecurityRulesForWrite(orgId, category);
2148
2235
  const payload = items.map((item) => ({
2149
2236
  key: item.key,
2150
2237
  value: serializeDatastoreValue(item.value),
2151
- category,
2152
- ...category === "shuffle-security_incidents" ? { ignore_security_rules: true } : {}
2238
+ category
2153
2239
  }));
2154
2240
  const response = await fetch(getApiUrl("/api/v2/datastore"), {
2155
2241
  method: "POST",
@@ -2787,7 +2873,7 @@ if (typeof window !== "undefined") {
2787
2873
  }
2788
2874
 
2789
2875
  // ../Shuffle-Core/authenticatedApps.ts
2790
- var TTL_MS = 3e4;
2876
+ var TTL_MS2 = 3e4;
2791
2877
  var cache = /* @__PURE__ */ new Map();
2792
2878
  var cacheKey = (crossOrgId) => crossOrgId || "";
2793
2879
  var THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1e3;
@@ -2826,7 +2912,7 @@ var doFetch = async (crossOrgId) => {
2826
2912
  var fetchAuthenticatedApps = (crossOrgId) => {
2827
2913
  const key = cacheKey(crossOrgId);
2828
2914
  const entry = cache.get(key) || {};
2829
- if (entry.data && entry.fetchedAt && Date.now() - entry.fetchedAt < TTL_MS) {
2915
+ if (entry.data && entry.fetchedAt && Date.now() - entry.fetchedAt < TTL_MS2) {
2830
2916
  return Promise.resolve(entry.data);
2831
2917
  }
2832
2918
  if (entry.promise) return entry.promise;
@@ -4675,7 +4761,7 @@ base.success = (msg, opts) => _impl({ title: msg, description: opts?.description
4675
4761
  base.error = (msg, opts) => _impl({ title: msg, description: opts?.description, variant: "destructive" }, opts);
4676
4762
  base.info = (msg, opts) => _impl({ title: msg, description: opts?.description, variant: "info" }, opts);
4677
4763
  base.warning = (msg, opts) => _impl({ title: msg, description: opts?.description, variant: "warning" }, opts);
4678
- var toast = base;
4764
+ var toast2 = base;
4679
4765
 
4680
4766
  // ../Shuffle-Core/components/AuthStatusChip.tsx
4681
4767
  var import_material7 = require("@mui/material");
@@ -5960,12 +6046,12 @@ var AppAuthCard = ({
5960
6046
  setEditingLabel(false);
5961
6047
  invalidateAuthenticatedAppsCache();
5962
6048
  if (onRefreshAuth) await onRefreshAuth();
5963
- toast({ title: "Label updated", description: `Renamed to "${editLabelValue.trim()}"` });
6049
+ toast2({ title: "Label updated", description: `Renamed to "${editLabelValue.trim()}"` });
5964
6050
  } else {
5965
- toast({ title: "Failed to rename", description: "Could not update the authentication label", variant: "destructive" });
6051
+ toast2({ title: "Failed to rename", description: "Could not update the authentication label", variant: "destructive" });
5966
6052
  }
5967
6053
  } catch (err) {
5968
- toast({ title: "Error", description: "Failed to rename authentication", variant: "destructive" });
6054
+ toast2({ title: "Error", description: "Failed to rename authentication", variant: "destructive" });
5969
6055
  } finally {
5970
6056
  setSavingLabel(false);
5971
6057
  }
@@ -6334,7 +6420,7 @@ var AppAuthCard = ({
6334
6420
  ...prev,
6335
6421
  ...Object.fromEntries(missingUrl.map(({ key }) => [key, "A valid URL is required"]))
6336
6422
  }));
6337
- toast.error("URL is required", {
6423
+ toast2.error("URL is required", {
6338
6424
  description: `Set a valid URL for: ${missingUrl.map((m) => m.label).join(", ")}`
6339
6425
  });
6340
6426
  return;
@@ -6348,7 +6434,7 @@ var AppAuthCard = ({
6348
6434
  setUserHasSelected(false);
6349
6435
  setFieldErrors({});
6350
6436
  if (!suppressSaveToast) {
6351
- toast.success("Authentication saved", {
6437
+ toast2.success("Authentication saved", {
6352
6438
  description: `Your ${app2.name.replace(/_/g, " ")} credentials have been stored securely.`
6353
6439
  });
6354
6440
  }
@@ -8550,7 +8636,7 @@ var SingulActionsPreview = ({
8550
8636
  setCopied(true);
8551
8637
  setTimeout(() => setCopied(false), 2e3);
8552
8638
  } catch {
8553
- toast.error("Copy failed");
8639
+ toast2.error("Copy failed");
8554
8640
  }
8555
8641
  };
8556
8642
  const [playLoading, setPlayLoading] = (0, import_react11.useState)(false);
@@ -8611,14 +8697,14 @@ var SingulActionsPreview = ({
8611
8697
  }
8612
8698
  })();
8613
8699
  if (parsed?.success === false) {
8614
- toast.error(parsed.reason || "Run failed");
8700
+ toast2.error(parsed.reason || "Run failed");
8615
8701
  } else {
8616
- toast.success(`Ran ${selected?.name || lang}`);
8702
+ toast2.success(`Ran ${selected?.name || lang}`);
8617
8703
  }
8618
8704
  } catch (err) {
8619
8705
  const msg = err?.message || "Run failed";
8620
8706
  setPlayResult(msg);
8621
- toast.error(msg);
8707
+ toast2.error(msg);
8622
8708
  } finally {
8623
8709
  setPlayLoading(false);
8624
8710
  scrollToResponse();
@@ -9359,12 +9445,12 @@ var getSuggestionAppRequirements = (suggestion, limit = 3) => {
9359
9445
  var prettySuggestionAppName = (name) => name.replace(/[_-]+/g, " ").trim().split(/\s+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
9360
9446
 
9361
9447
  // safeHandler.ts
9362
- var import_sonner = require("sonner");
9448
+ var import_sonner2 = require("sonner");
9363
9449
  function safeHandler(label, fn) {
9364
9450
  return (...args) => {
9365
9451
  if (typeof fn !== "function") {
9366
9452
  console.error(`[safeHandler] "${label}" has no handler attached`);
9367
- import_sonner.toast.error(`${label} is not available right now`);
9453
+ import_sonner2.toast.error(`${label} is not available right now`);
9368
9454
  return void 0;
9369
9455
  }
9370
9456
  try {
@@ -9372,7 +9458,7 @@ function safeHandler(label, fn) {
9372
9458
  if (result && typeof result.catch === "function") {
9373
9459
  result.catch((err) => {
9374
9460
  console.error(`[safeHandler] "${label}" failed`, err);
9375
- import_sonner.toast.error(`${label} failed`, {
9461
+ import_sonner2.toast.error(`${label} failed`, {
9376
9462
  description: err instanceof Error ? err.message : String(err)
9377
9463
  });
9378
9464
  });
@@ -9380,7 +9466,7 @@ function safeHandler(label, fn) {
9380
9466
  return result;
9381
9467
  } catch (err) {
9382
9468
  console.error(`[safeHandler] "${label}" failed`, err);
9383
- import_sonner.toast.error(`${label} failed`, {
9469
+ import_sonner2.toast.error(`${label} failed`, {
9384
9470
  description: err instanceof Error ? err.message : String(err)
9385
9471
  });
9386
9472
  return void 0;
@@ -12083,14 +12169,14 @@ var deepParseJsonStrings2 = (obj, depth = 0) => {
12083
12169
  }
12084
12170
  return obj;
12085
12171
  };
12086
- var pickResultPayload = (run) => {
12087
- const results = Array.isArray(run.results) ? run.results : [];
12172
+ var pickResultPayload = (run2) => {
12173
+ const results = Array.isArray(run2.results) ? run2.results : [];
12088
12174
  const agentResult = results.find((r) => {
12089
12175
  const appName = String(r?.action?.app_name || r?.action?.label || "").toLowerCase();
12090
12176
  const appId = String(r?.action?.app_id || "").toLowerCase();
12091
12177
  return appId === "shuffle_agent" || appName.includes("ai agent");
12092
12178
  });
12093
- const payload = agentResult?.result || results.find((r) => typeof r?.result === "string" && r.result.trim())?.result || run.result;
12179
+ const payload = agentResult?.result || results.find((r) => typeof r?.result === "string" && r.result.trim())?.result || run2.result;
12094
12180
  if (typeof payload === "string") return payload;
12095
12181
  if (payload && typeof payload === "object") {
12096
12182
  try {
@@ -12101,10 +12187,10 @@ var pickResultPayload = (run) => {
12101
12187
  }
12102
12188
  return null;
12103
12189
  };
12104
- var parseRunResult = (run) => {
12105
- const firstResult = pickResultPayload(run);
12190
+ var parseRunResult = (run2) => {
12191
+ const firstResult = pickResultPayload(run2);
12106
12192
  if (!firstResult) {
12107
- const directPayload = run;
12193
+ const directPayload = run2;
12108
12194
  if (directPayload && typeof directPayload === "object" && (Array.isArray(directPayload.decisions) || directPayload.decision_string !== void 0)) {
12109
12195
  const deepParsed = deepParseJsonStrings2(directPayload);
12110
12196
  let raw = null;
@@ -12140,10 +12226,10 @@ var isDecisionStringParserFailure = (reason) => {
12140
12226
  const normalized = reason.toLowerCase();
12141
12227
  return normalized.includes("produced decisions") && normalized.includes("none could be executed");
12142
12228
  };
12143
- var getFailureInfo = (run) => {
12144
- const status = run.status?.toUpperCase();
12229
+ var getFailureInfo = (run2) => {
12230
+ const status = run2.status?.toUpperCase();
12145
12231
  if (status !== "FAILED" && status !== "ABORTED") return null;
12146
- const { parsed } = parseRunResult(run);
12232
+ const { parsed } = parseRunResult(run2);
12147
12233
  if (parsed && typeof parsed === "object") {
12148
12234
  if (parsed.success === false && parsed.reason) {
12149
12235
  if (isDecisionStringParserFailure(parsed.reason)) return null;
@@ -12202,8 +12288,8 @@ var isAiAuthText = (text2) => {
12202
12288
  }
12203
12289
  return checkChunk(trimmed);
12204
12290
  };
12205
- var hasOutputWarning = (run) => {
12206
- return diagnoseOutputWarning(run) !== null;
12291
+ var hasOutputWarning = (run2) => {
12292
+ return diagnoseOutputWarning(run2) !== null;
12207
12293
  };
12208
12294
  var diagnosisHasCtas = (diagnosis) => diagnosis?.kind === "token_limit" || diagnosis?.kind === "ai_auth" || Boolean(diagnosis?.isAiAuth);
12209
12295
  var collectEntries = (root2) => {
@@ -12234,15 +12320,15 @@ var trimEvidenceValue = (v, max = 180) => {
12234
12320
  };
12235
12321
  var TOKEN_LIMIT_PATTERN = /\b(ai[\s-]*token[\s-]*limit[\s-]*(is[\s-]*)?reach(ed)?|token[\s-]*limit[\s-]*(is[\s-]*)?reach(ed)?|context[\s-]*(window|length|limit)[\s-]*(is[\s-]*)?(reached|exceeded)|maximum[\s-]*context[\s-]*(window|length)?[\s-]*(is[\s-]*)?(reached|exceeded)|too[\s-]*many[\s-]*tokens|exceeds?[\s-]*(the[\s-]*)?(maximum[\s-]*)?(token|context))\b/;
12236
12322
  var isSentenceLike = (v) => /[a-z]/i.test(v) && v.trim().split(/\s+/).length > 1;
12237
- var hasProducedDecisions = (run, parsed) => {
12323
+ var hasProducedDecisions = (run2, parsed) => {
12238
12324
  const parsedDecisions = parsed && typeof parsed === "object" ? parsed.decisions : null;
12239
12325
  if (Array.isArray(parsedDecisions) && parsedDecisions.length > 0) return true;
12240
- const directDecisions = run?.decisions;
12326
+ const directDecisions = run2?.decisions;
12241
12327
  return Array.isArray(directDecisions) && directDecisions.length > 0;
12242
12328
  };
12243
- var diagnoseOutputWarning = (run) => {
12244
- const { parsed, raw } = parseRunResult(run);
12245
- const producedDecisions = hasProducedDecisions(run, parsed);
12329
+ var diagnoseOutputWarning = (run2) => {
12330
+ const { parsed, raw } = parseRunResult(run2);
12331
+ const producedDecisions = hasProducedDecisions(run2, parsed);
12246
12332
  const tokenLimitMatch = (() => {
12247
12333
  const candidates = [];
12248
12334
  if (parsed && typeof parsed === "object") {
@@ -12265,7 +12351,7 @@ var diagnoseOutputWarning = (run) => {
12265
12351
  evidence: [{ path: "(root)", value: evidenceValue }]
12266
12352
  };
12267
12353
  }
12268
- const isFinished = (run.status || "").toUpperCase() === "FINISHED";
12354
+ const isFinished = (run2.status || "").toUpperCase() === "FINISHED";
12269
12355
  const hasSuccessfulFinish = (() => {
12270
12356
  if (!parsed || typeof parsed !== "object") return false;
12271
12357
  if (parsed.error && String(parsed.error).trim().length > 0) return false;
@@ -12555,26 +12641,26 @@ var diagnoseOutputWarning = (run) => {
12555
12641
  }
12556
12642
  return null;
12557
12643
  };
12558
- var isAiAuthFailure = (run, extraText) => {
12559
- if (!run) return isAiAuthText(extraText);
12560
- const { parsed } = parseRunResult(run);
12561
- if (hasProducedDecisions(run, parsed)) return false;
12644
+ var isAiAuthFailure = (run2, extraText) => {
12645
+ if (!run2) return isAiAuthText(extraText);
12646
+ const { parsed } = parseRunResult(run2);
12647
+ if (hasProducedDecisions(run2, parsed)) return false;
12562
12648
  if (isAiAuthText(extraText)) return true;
12563
- const status = (run.status || "").toUpperCase();
12649
+ const status = (run2.status || "").toUpperCase();
12564
12650
  const isFinished = status === "FINISHED" || status === "SUCCESS";
12565
12651
  if (isFinished) {
12566
- const anyRun2 = run;
12652
+ const anyRun2 = run2;
12567
12653
  if (typeof anyRun2.error === "string" && isAiAuthText(anyRun2.error)) return true;
12568
12654
  return false;
12569
12655
  }
12570
- const diagnosis = diagnoseOutputWarning(run);
12656
+ const diagnosis = diagnoseOutputWarning(run2);
12571
12657
  if (diagnosis?.kind === "ai_auth" || diagnosis?.isAiAuth) return true;
12572
- const fail = getFailureInfo(run);
12658
+ const fail = getFailureInfo(run2);
12573
12659
  if (fail && isAiAuthText(fail.reason)) return true;
12574
- const anyRun = run;
12660
+ const anyRun = run2;
12575
12661
  if (typeof anyRun.error === "string" && isAiAuthText(anyRun.error)) return true;
12576
- if (Array.isArray(run.results)) {
12577
- for (const r of run.results) {
12662
+ if (Array.isArray(run2.results)) {
12663
+ for (const r of run2.results) {
12578
12664
  if (typeof r?.error === "string" && isAiAuthText(r.error)) return true;
12579
12665
  }
12580
12666
  }
@@ -12696,22 +12782,22 @@ var writeDismissed = (key) => {
12696
12782
  } catch {
12697
12783
  }
12698
12784
  };
12699
- var AgentRunDiagnosisBanner = ({ run, sx, onJumpToEvidence, onFocusContinue, executionId }) => {
12785
+ var AgentRunDiagnosisBanner = ({ run: run2, sx, onJumpToEvidence, onFocusContinue, executionId }) => {
12700
12786
  const dismissKey = (0, import_react16.useMemo)(() => {
12701
12787
  if (executionId) return executionId;
12702
- const fromRun = run?.execution_id;
12788
+ const fromRun = run2?.execution_id;
12703
12789
  return typeof fromRun === "string" && fromRun ? fromRun : null;
12704
- }, [executionId, run]);
12790
+ }, [executionId, run2]);
12705
12791
  const [dismissed, setDismissed] = (0, import_react16.useState)(() => readDismissed(dismissKey));
12706
12792
  (0, import_react16.useEffect)(() => {
12707
12793
  setDismissed(readDismissed(dismissKey));
12708
12794
  }, [dismissKey]);
12709
- if (!run || dismissed) return null;
12710
- const status = (run.status || "").toUpperCase();
12795
+ if (!run2 || dismissed) return null;
12796
+ const status = (run2.status || "").toUpperCase();
12711
12797
  const isFailed = status === "FAILED" || status === "ABORTED";
12712
- const failureInfo = isFailed ? getFailureInfo(run) : null;
12713
- const outputWarning = !isFailed && hasOutputWarning(run);
12714
- const diagnosis = outputWarning ? diagnoseOutputWarning(run) : null;
12798
+ const failureInfo = isFailed ? getFailureInfo(run2) : null;
12799
+ const outputWarning = !isFailed && hasOutputWarning(run2);
12800
+ const diagnosis = outputWarning ? diagnoseOutputWarning(run2) : null;
12715
12801
  if (!failureInfo && !diagnosis) return null;
12716
12802
  if (status === "FINISHED" && (diagnosis?.kind === "ai_auth" || diagnosis?.isAiAuth)) {
12717
12803
  return null;
@@ -12720,8 +12806,8 @@ var AgentRunDiagnosisBanner = ({ run, sx, onJumpToEvidence, onFocusContinue, exe
12720
12806
  const firstEvidence2 = diagnosis?.evidence?.[0] || null;
12721
12807
  const jumpDecisionIndex2 = firstEvidence2 ? extractDecisionIndex(firstEvidence2.path) : null;
12722
12808
  if (jumpDecisionIndex2 === null) return null;
12723
- const { parsed } = parseRunResult(run);
12724
- const decs = parsed?.decisions || run?.decisions;
12809
+ const { parsed } = parseRunResult(run2);
12810
+ const decs = parsed?.decisions || run2?.decisions;
12725
12811
  if (Array.isArray(decs) && decs[jumpDecisionIndex2]) {
12726
12812
  const d = decs[jumpDecisionIndex2];
12727
12813
  const action = String(d?.action || d?.details?.action || "").toLowerCase();
@@ -17294,7 +17380,7 @@ var AgentUI = ({
17294
17380
  const json = await resp.json();
17295
17381
  if (json.success === false) {
17296
17382
  setOptimisticContinue(null);
17297
- toast({ title: "Failed to submit", description: json.reason || "Try again later.", variant: "destructive" });
17383
+ toast2({ title: "Failed to submit", description: json.reason || "Try again later.", variant: "destructive" });
17298
17384
  } else {
17299
17385
  setQuestionAnswers({});
17300
17386
  setContinuationText("");
@@ -17304,7 +17390,7 @@ var AgentUI = ({
17304
17390
  }
17305
17391
  } catch (err) {
17306
17392
  setOptimisticContinue(null);
17307
- toast({ title: "Network error", description: String(err), variant: "destructive" });
17393
+ toast2({ title: "Network error", description: String(err), variant: "destructive" });
17308
17394
  } finally {
17309
17395
  setAgentRequestLoading(false);
17310
17396
  }
@@ -17467,7 +17553,7 @@ var AgentUI = ({
17467
17553
  };
17468
17554
  if (!execId || !wfId) {
17469
17555
  resetToStart();
17470
- toast({ title: "Run aborted", description: "The agent had not started yet \u2014 reset to Start." });
17556
+ toast2({ title: "Run aborted", description: "The agent had not started yet \u2014 reset to Start." });
17471
17557
  setAbortLoading(false);
17472
17558
  return;
17473
17559
  }
@@ -17485,14 +17571,14 @@ var AgentUI = ({
17485
17571
  );
17486
17572
  if (!resp.ok) {
17487
17573
  const txt = await resp.text().catch(() => "");
17488
- toast({ title: "Abort failed", description: txt || `HTTP ${resp.status}`, variant: "destructive" });
17574
+ toast2({ title: "Abort failed", description: txt || `HTTP ${resp.status}`, variant: "destructive" });
17489
17575
  setAbortLoading(false);
17490
17576
  return;
17491
17577
  }
17492
17578
  setTimeout(() => getExecution(execId, auth), 500);
17493
17579
  setTimeout(() => getExecution(execId, auth), 2500);
17494
17580
  } catch (err) {
17495
- toast({ title: "Network error", description: String(err), variant: "destructive" });
17581
+ toast2({ title: "Network error", description: String(err), variant: "destructive" });
17496
17582
  } finally {
17497
17583
  setAbortLoading(false);
17498
17584
  }
@@ -17518,16 +17604,16 @@ var AgentUI = ({
17518
17604
  }, [execution, agentActionResult, apiBaseUrl]);
17519
17605
  const rerunDecision = (0, import_react18.useCallback)(async (decision) => {
17520
17606
  if (!execution?.execution_id) {
17521
- toast({ title: "No execution loaded", description: "Cannot rerun this decision.", variant: "destructive" });
17607
+ toast2({ title: "No execution loaded", description: "Cannot rerun this decision.", variant: "destructive" });
17522
17608
  return;
17523
17609
  }
17524
17610
  if (!agentActionResult?.action) {
17525
- toast({ title: "Missing action context", description: "Could not locate the agent action node.", variant: "destructive" });
17611
+ toast2({ title: "Missing action context", description: "Could not locate the agent action node.", variant: "destructive" });
17526
17612
  return;
17527
17613
  }
17528
17614
  const decisionId = decision?.run_details?.id;
17529
17615
  if (!decisionId) {
17530
- toast({ title: "Missing decision id", description: "This decision cannot be rerun.", variant: "destructive" });
17616
+ toast2({ title: "Missing decision id", description: "This decision cannot be rerun.", variant: "destructive" });
17531
17617
  return;
17532
17618
  }
17533
17619
  const body = { ...agentActionResult.action };
@@ -17549,14 +17635,14 @@ var AgentUI = ({
17549
17635
  });
17550
17636
  const json = await resp.json().catch(() => ({}));
17551
17637
  if (json?.success === false) {
17552
- toast({ title: "Rerun failed", description: json.reason || "Try again later.", variant: "destructive" });
17638
+ toast2({ title: "Rerun failed", description: json.reason || "Try again later.", variant: "destructive" });
17553
17639
  setRerunningDecisionId(null);
17554
17640
  } else {
17555
17641
  setTimeout(() => getExecution(execution.execution_id, execution.authorization), 800);
17556
17642
  setTimeout(() => getExecution(execution.execution_id, execution.authorization), 5e3);
17557
17643
  }
17558
17644
  } catch (err) {
17559
- toast({ title: "Network error", description: String(err), variant: "destructive" });
17645
+ toast2({ title: "Network error", description: String(err), variant: "destructive" });
17560
17646
  setRerunningDecisionId(null);
17561
17647
  } finally {
17562
17648
  setAgentRequestLoading(false);
@@ -18651,15 +18737,15 @@ var AgentUI = ({
18651
18737
  setScheduleSteps((prev) => prev.map((p) => p.id === ev.id ? { ...p, state: ev.state, detail: ev.detail } : p));
18652
18738
  }
18653
18739
  });
18654
- toast({ title: "Schedule saved", description: "This prompt will now run on the selected schedule." });
18740
+ toast2({ title: "Schedule saved", description: "This prompt will now run on the selected schedule." });
18655
18741
  setScheduleAnchor(null);
18656
18742
  } else {
18657
- toast({ title: "Scheduling not configured", description: "No handler is wired up for scheduled runs in this view.", variant: "destructive" });
18743
+ toast2({ title: "Scheduling not configured", description: "No handler is wired up for scheduled runs in this view.", variant: "destructive" });
18658
18744
  setScheduleAnchor(null);
18659
18745
  }
18660
18746
  } catch (err) {
18661
18747
  console.error("[AgentUI] Schedule failed", err);
18662
- toast({ title: "Failed to save schedule", description: err instanceof Error ? err.message : String(err), variant: "destructive" });
18748
+ toast2({ title: "Failed to save schedule", description: err instanceof Error ? err.message : String(err), variant: "destructive" });
18663
18749
  } finally {
18664
18750
  setScheduleSaving(false);
18665
18751
  }
@@ -19832,7 +19918,7 @@ var AgentUI = ({
19832
19918
  if (!result?.success) {
19833
19919
  pendingLLMRef.current = null;
19834
19920
  setDetectedLLM(previous);
19835
- toast({
19921
+ toast2({
19836
19922
  title: "Could not change AI provider",
19837
19923
  description: `Failed to switch to ${opt.label}.`,
19838
19924
  variant: "destructive"
@@ -19842,7 +19928,7 @@ var AgentUI = ({
19842
19928
  } catch (err) {
19843
19929
  pendingLLMRef.current = null;
19844
19930
  setDetectedLLM(previous);
19845
- toast({
19931
+ toast2({
19846
19932
  title: "Could not change AI provider",
19847
19933
  description: err instanceof Error ? err.message : "Failed to switch provider.",
19848
19934
  variant: "destructive"
@@ -22374,7 +22460,7 @@ var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serv
22374
22460
  setSelectedPreset(rollback);
22375
22461
  rememberPreset(rollback);
22376
22462
  }
22377
- toast({
22463
+ toast2({
22378
22464
  title: "Could not change AI provider",
22379
22465
  description: "Failed to switch to Shuffle AI.",
22380
22466
  variant: "destructive"
@@ -22390,7 +22476,7 @@ var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serv
22390
22476
  setSelectedPreset(rollback);
22391
22477
  rememberPreset(rollback);
22392
22478
  }
22393
- toast({
22479
+ toast2({
22394
22480
  title: "Could not change AI provider",
22395
22481
  description: err instanceof Error ? err.message : "Failed to switch to Shuffle AI.",
22396
22482
  variant: "destructive"
@@ -22421,7 +22507,7 @@ var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serv
22421
22507
  setSelectedPreset(rollback);
22422
22508
  rememberPreset(rollback);
22423
22509
  }
22424
- toast({
22510
+ toast2({
22425
22511
  title: "Could not change AI provider",
22426
22512
  description: "Failed to switch to " + label + ".",
22427
22513
  variant: "destructive"
@@ -22437,7 +22523,7 @@ var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serv
22437
22523
  setSelectedPreset(rollback);
22438
22524
  rememberPreset(rollback);
22439
22525
  }
22440
- toast({
22526
+ toast2({
22441
22527
  title: "Could not change AI provider",
22442
22528
  description: err instanceof Error ? err.message : "Failed to switch active LLM provider.",
22443
22529
  variant: "destructive"
@@ -23342,11 +23428,11 @@ var STATUS_CONFIG = {
23342
23428
  WAITING: { icon: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react14.Clock, { size: 16 }), color: "hsl(var(--severity-info, 217 91% 60%))", label: "Waiting" },
23343
23429
  LIMIT_REACHED: { icon: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react15.AlertTriangle, { size: 16 }), color: "hsl(var(--severity-critical, 0 72% 55%))", label: "Limit reached" }
23344
23430
  };
23345
- var getEffectiveStatus = (run) => {
23346
- const raw = (run.status || "").toUpperCase();
23431
+ var getEffectiveStatus = (run2) => {
23432
+ const raw = (run2.status || "").toUpperCase();
23347
23433
  if (raw === "FINISHED" || raw === "SUCCESS" || raw === "FAILED" || raw === "ABORTED") {
23348
23434
  try {
23349
- const d = diagnoseOutputWarning(run);
23435
+ const d = diagnoseOutputWarning(run2);
23350
23436
  if (d?.kind === "token_limit") return "LIMIT_REACHED";
23351
23437
  } catch {
23352
23438
  }
@@ -23368,8 +23454,8 @@ var parseDatastoreTask = (arg) => {
23368
23454
  return { key, category };
23369
23455
  };
23370
23456
  var isAIAgentResult = (result) => String(result?.action?.app_name || "").trim().toLowerCase() === "ai agent";
23371
- var getAIAgentResultPayload = (run) => {
23372
- const results = Array.isArray(run.results) ? run.results : [];
23457
+ var getAIAgentResultPayload = (run2) => {
23458
+ const results = Array.isArray(run2.results) ? run2.results : [];
23373
23459
  const agentResult = results.find(isAIAgentResult);
23374
23460
  if (!agentResult || typeof agentResult !== "object" || !("result" in agentResult)) return null;
23375
23461
  return tryParseJson2(agentResult.result);
@@ -23385,16 +23471,16 @@ var getDirectAgentInput = (payload) => {
23385
23471
  }
23386
23472
  return null;
23387
23473
  };
23388
- var findDatastoreTaskInRun = (run) => {
23389
- const agentInput = getDirectAgentInput(getAIAgentResultPayload(run));
23474
+ var findDatastoreTaskInRun = (run2) => {
23475
+ const agentInput = getDirectAgentInput(getAIAgentResultPayload(run2));
23390
23476
  const agentHit = parseDatastoreTask(agentInput || void 0);
23391
23477
  if (agentHit) return agentHit;
23392
- const anyRun = run;
23478
+ const anyRun = run2;
23393
23479
  const candidates = [];
23394
23480
  if (typeof anyRun.original_input === "string") candidates.push(anyRun.original_input);
23395
23481
  if (typeof anyRun.input === "string") candidates.push(anyRun.input);
23396
- if (run.execution_argument) candidates.push(run.execution_argument);
23397
- if (run.result) candidates.push(run.result);
23482
+ if (run2.execution_argument) candidates.push(run2.execution_argument);
23483
+ if (run2.result) candidates.push(run2.result);
23398
23484
  if (Array.isArray(anyRun.results)) {
23399
23485
  try {
23400
23486
  candidates.push(JSON.stringify(anyRun.results));
@@ -23407,12 +23493,12 @@ var findDatastoreTaskInRun = (run) => {
23407
23493
  }
23408
23494
  return null;
23409
23495
  };
23410
- var classifyRunSource = (run) => {
23411
- const raw = (run.execution_source || "").trim();
23496
+ var classifyRunSource = (run2) => {
23497
+ const raw = (run2.execution_source || "").trim();
23412
23498
  const src = raw.toLowerCase();
23413
23499
  const sourceParts = raw.split("|");
23414
23500
  const fromSource = src.startsWith("datastore") && sourceParts.length > 2 ? { category: sourceParts[1].trim(), key: sourceParts[2].trim() } : null;
23415
- const ds = findDatastoreTaskInRun(run) || fromSource;
23501
+ const ds = findDatastoreTaskInRun(run2) || fromSource;
23416
23502
  if (ds || src.includes("datastore") || src.includes("enrichment") || src.includes("automation")) {
23417
23503
  return {
23418
23504
  kind: "datastore",
@@ -23472,18 +23558,18 @@ Click to open it in the Datastore.` : "Started by a datastore automation (e.g. e
23472
23558
  icon: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react14.Zap, { size: SOURCE_ICON_SIZE })
23473
23559
  };
23474
23560
  };
23475
- var getRunIconColor = (run) => {
23476
- const status = getEffectiveStatus(run);
23561
+ var getRunIconColor = (run2) => {
23562
+ const status = getEffectiveStatus(run2);
23477
23563
  if (status === "FINISHED" || status === "SUCCESS") return "hsl(var(--severity-low, 142 71% 45%))";
23478
23564
  if (status === "FAILED" || status === "ABORTED") return "hsl(var(--severity-critical, 0 72% 55%))";
23479
23565
  if (status === "LIMIT_REACHED") return "hsl(var(--severity-critical, 0 72% 55%))";
23480
23566
  if (status === "EXECUTING" || status === "RUNNING") return "hsl(var(--severity-medium, 38 92% 50%))";
23481
23567
  return "hsl(var(--primary, 24 100% 50%))";
23482
23568
  };
23483
- var formatDuration = (run) => {
23484
- if (run.started_at && run.completed_at) {
23485
- const start = Number(run.started_at);
23486
- const end = Number(run.completed_at);
23569
+ var formatDuration = (run2) => {
23570
+ if (run2.started_at && run2.completed_at) {
23571
+ const start = Number(run2.started_at);
23572
+ const end = Number(run2.completed_at);
23487
23573
  if (!isNaN(start) && !isNaN(end)) {
23488
23574
  const toMs = (n) => n > 1e12 ? n : n * 1e3;
23489
23575
  const ms = Math.max(0, toMs(end) - toMs(start));
@@ -23492,7 +23578,7 @@ var formatDuration = (run) => {
23492
23578
  return `${Math.floor(ms / 6e4)}m ${Math.floor(ms % 6e4 / 1e3)}s`;
23493
23579
  }
23494
23580
  }
23495
- if (run.duration) return `${run.duration.toFixed(2)}s`;
23581
+ if (run2.duration) return `${run2.duration.toFixed(2)}s`;
23496
23582
  return "";
23497
23583
  };
23498
23584
  var getTimeAgo = (dateStr) => {
@@ -23573,9 +23659,9 @@ var tryParseJson2 = (s) => {
23573
23659
  return trimmed;
23574
23660
  }
23575
23661
  };
23576
- var getRunPrompt = (run) => {
23577
- const anyRun = run;
23578
- const agentInput = getDirectAgentInput(getAIAgentResultPayload(run));
23662
+ var getRunPrompt = (run2) => {
23663
+ const anyRun = run2;
23664
+ const agentInput = getDirectAgentInput(getAIAgentResultPayload(run2));
23579
23665
  if (agentInput) return agentInput;
23580
23666
  const results = Array.isArray(anyRun.results) ? anyRun.results : null;
23581
23667
  if (results) {
@@ -23596,12 +23682,12 @@ var getRunPrompt = (run) => {
23596
23682
  if (typeof anyRun.input === "string" && anyRun.input.trim()) {
23597
23683
  return anyRun.input.trim();
23598
23684
  }
23599
- if (run.result) {
23600
- const hit = deepFindPrompt(tryParseJson2(run.result));
23685
+ if (run2.result) {
23686
+ const hit = deepFindPrompt(tryParseJson2(run2.result));
23601
23687
  if (hit) return hit;
23602
23688
  }
23603
- if (run.execution_argument) {
23604
- const parsed = tryParseJson2(run.execution_argument);
23689
+ if (run2.execution_argument) {
23690
+ const parsed = tryParseJson2(run2.execution_argument);
23605
23691
  const hit = deepFindPrompt(parsed);
23606
23692
  if (hit) return hit;
23607
23693
  if (typeof parsed === "string" && parsed.length < 240) return parsed;
@@ -23624,23 +23710,23 @@ var stripMarkdown = (input) => {
23624
23710
  s = s.replace(/\s+/g, " ").trim();
23625
23711
  return s;
23626
23712
  };
23627
- var getRunTitle = (run) => {
23628
- const prompt = getRunPrompt(run);
23713
+ var getRunTitle = (run2) => {
23714
+ const prompt = getRunPrompt(run2);
23629
23715
  if (prompt) {
23630
23716
  const oneLine = stripMarkdown(prompt);
23631
23717
  return oneLine.length > 80 ? oneLine.slice(0, 80) + "\u2026" : oneLine;
23632
23718
  }
23633
- if (run.workflow?.name) return stripMarkdown(run.workflow.name);
23634
- return `Execution ${run.execution_id?.slice(0, 8) || "\u2014"}`;
23719
+ if (run2.workflow?.name) return stripMarkdown(run2.workflow.name);
23720
+ return `Execution ${run2.execution_id?.slice(0, 8) || "\u2014"}`;
23635
23721
  };
23636
- var getDecisionCount = (run) => {
23637
- if (Array.isArray(run.decisions)) return run.decisions.length;
23722
+ var getDecisionCount = (run2) => {
23723
+ if (Array.isArray(run2.decisions)) return run2.decisions.length;
23638
23724
  return 0;
23639
23725
  };
23640
- var getRunSubtitle = (run) => {
23641
- if (run.result) {
23726
+ var getRunSubtitle = (run2) => {
23727
+ if (run2.result) {
23642
23728
  try {
23643
- const p = JSON.parse(run.result);
23729
+ const p = JSON.parse(run2.result);
23644
23730
  if (p.output && typeof p.output === "string") {
23645
23731
  const out = stripMarkdown(p.output);
23646
23732
  return out.length > 120 ? out.slice(0, 120) + "\u2026" : out;
@@ -23651,12 +23737,12 @@ var getRunSubtitle = (run) => {
23651
23737
  }
23652
23738
  if (p.message && typeof p.message === "string") return stripMarkdown(p.message);
23653
23739
  } catch {
23654
- if (run.result.length < 120) return stripMarkdown(run.result);
23740
+ if (run2.result.length < 120) return stripMarkdown(run2.result);
23655
23741
  }
23656
23742
  }
23657
- const status = getEffectiveStatus(run);
23743
+ const status = getEffectiveStatus(run2);
23658
23744
  const isRunning = status === "EXECUTING" || status === "RUNNING" || status === "WAITING";
23659
- return run.execution_source || (isRunning ? "Agent still running\u2026" : "Agent execution");
23745
+ return run2.execution_source || (isRunning ? "Agent still running\u2026" : "Agent execution");
23660
23746
  };
23661
23747
  var normalizeResultStatus = (s) => {
23662
23748
  const v = (s || "").toUpperCase();
@@ -23665,7 +23751,7 @@ var normalizeResultStatus = (s) => {
23665
23751
  if (v === "WAITING" || v === "SKIPPED") return "waiting";
23666
23752
  return "unknown";
23667
23753
  };
23668
- var getRunTools = (run) => {
23754
+ var getRunTools = (run2) => {
23669
23755
  const map = /* @__PURE__ */ new Map();
23670
23756
  const ids = /* @__PURE__ */ new Map();
23671
23757
  const skip = (s) => /^(ai\s*agent|shuffle\s*agent|shuffle_agent)$/i.test(s);
@@ -23679,7 +23765,7 @@ var getRunTools = (run) => {
23679
23765
  if (!prev || rank[next] > rank[prev]) map.set(s, next);
23680
23766
  if (id && !ids.has(s)) ids.set(s, id);
23681
23767
  };
23682
- const allowed = run.allowed_actions;
23768
+ const allowed = run2.allowed_actions;
23683
23769
  if (Array.isArray(allowed) && allowed.length > 0) {
23684
23770
  for (const entry of allowed) {
23685
23771
  if (typeof entry !== "string") continue;
@@ -23697,17 +23783,17 @@ var getRunTools = (run) => {
23697
23783
  const hit = known.get(normalize(name));
23698
23784
  if (hit) merge2(hit, status);
23699
23785
  };
23700
- (run.results || []).forEach((r) => {
23786
+ (run2.results || []).forEach((r) => {
23701
23787
  apply(r?.action?.app_name || r?.action?.label, normalizeResultStatus(r?.status));
23702
23788
  });
23703
- (run.decisions || []).forEach((d) => {
23789
+ (run2.decisions || []).forEach((d) => {
23704
23790
  if (typeof d?.tool === "string") apply(d.tool, normalizeResultStatus(d?.status));
23705
23791
  });
23706
23792
  } else {
23707
- (run.results || []).forEach((r) => {
23793
+ (run2.results || []).forEach((r) => {
23708
23794
  merge2(r?.action?.app_name || r?.action?.label, normalizeResultStatus(r?.status));
23709
23795
  });
23710
- (run.decisions || []).forEach((d) => {
23796
+ (run2.decisions || []).forEach((d) => {
23711
23797
  if (typeof d?.tool === "string") merge2(d.tool, normalizeResultStatus(d?.status));
23712
23798
  });
23713
23799
  }
@@ -23726,18 +23812,18 @@ var TOOL_STATUS_LABEL = {
23726
23812
  unknown: "used"
23727
23813
  };
23728
23814
  var normToolKey = (s) => s.toLowerCase().replace(/[\s_\-]+/g, "_");
23729
- var AgentRunRow = ({ run, onClick, sx, appIcons, onAppClick, apiKey, apiBaseUrl, orgId, abortingIds, onAbort }) => {
23815
+ var AgentRunRow = ({ run: run2, onClick, sx, appIcons, onAppClick, apiKey, apiBaseUrl, orgId, abortingIds, onAbort }) => {
23730
23816
  const navigate = (0, import_router_compat3.useNavigate)();
23731
- const statusKey = getEffectiveStatus(run);
23732
- const iconColor = getRunIconColor(run);
23733
- const duration = formatDuration(run);
23734
- const tools = getRunTools(run);
23735
- const decisionCount = getDecisionCount(run);
23736
- const attachmentCount = collectLlmImageAttachments(run).length;
23817
+ const statusKey = getEffectiveStatus(run2);
23818
+ const iconColor = getRunIconColor(run2);
23819
+ const duration = formatDuration(run2);
23820
+ const tools = getRunTools(run2);
23821
+ const decisionCount = getDecisionCount(run2);
23822
+ const attachmentCount = collectLlmImageAttachments(run2).length;
23737
23823
  const isRunning = statusKey === "EXECUTING" || statusKey === "RUNNING" || statusKey === "WAITING";
23738
- const isAborting = !!run.execution_id && !!abortingIds?.has(run.execution_id);
23739
- const wfId = run.workflow_id || run?.workflow?.id;
23740
- const canAbort = isRunning && !!run.execution_id && !!wfId && !isAborting;
23824
+ const isAborting = !!run2.execution_id && !!abortingIds?.has(run2.execution_id);
23825
+ const wfId = run2.workflow_id || run2?.workflow?.id;
23826
+ const canAbort = isRunning && !!run2.execution_id && !!wfId && !isAborting;
23741
23827
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
23742
23828
  import_material24.Box,
23743
23829
  {
@@ -23763,7 +23849,7 @@ var AgentRunRow = ({ run, onClick, sx, appIcons, onAppClick, apiKey, apiBaseUrl,
23763
23849
  ],
23764
23850
  children: [
23765
23851
  (() => {
23766
- const sourceInfo = classifyRunSource(run);
23852
+ const sourceInfo = classifyRunSource(run2);
23767
23853
  const dsLink = sourceInfo.kind === "datastore" && sourceInfo.datastoreKey && sourceInfo.datastoreCategory ? `https://shuffler.io/admin?tab=datastore&category=${encodeURIComponent(sourceInfo.datastoreCategory)}&key=${encodeURIComponent(sourceInfo.datastoreKey)}` : null;
23768
23854
  return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
23769
23855
  import_material24.Tooltip,
@@ -23813,7 +23899,7 @@ var AgentRunRow = ({ run, onClick, sx, appIcons, onAppClick, apiKey, apiBaseUrl,
23813
23899
  textOverflow: "ellipsis",
23814
23900
  whiteSpace: "nowrap"
23815
23901
  },
23816
- children: getRunTitle(run)
23902
+ children: getRunTitle(run2)
23817
23903
  }
23818
23904
  ) }),
23819
23905
  /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
@@ -23826,11 +23912,11 @@ var AgentRunRow = ({ run, onClick, sx, appIcons, onAppClick, apiKey, apiBaseUrl,
23826
23912
  textOverflow: "ellipsis",
23827
23913
  whiteSpace: "nowrap"
23828
23914
  },
23829
- children: getRunSubtitle(run)
23915
+ children: getRunSubtitle(run2)
23830
23916
  }
23831
23917
  ),
23832
23918
  /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_material24.Box, { sx: { display: "flex", alignItems: "center", gap: 1, mt: 0.5 }, children: [
23833
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material24.Typography, { sx: { fontSize: "0.72rem", color: "hsl(var(--muted-foreground))", opacity: 0.7 }, children: run.started_at ? getTimeAgo(run.started_at) : "\u2014" }),
23919
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material24.Typography, { sx: { fontSize: "0.72rem", color: "hsl(var(--muted-foreground))", opacity: 0.7 }, children: run2.started_at ? getTimeAgo(run2.started_at) : "\u2014" }),
23834
23920
  duration && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
23835
23921
  /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material24.Typography, { sx: { fontSize: "0.72rem", color: "hsl(var(--muted-foreground))", opacity: 0.4 }, children: "\xB7" }),
23836
23922
  /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material24.Typography, { sx: { fontSize: "0.72rem", color: "hsl(var(--muted-foreground))", opacity: 0.7 }, children: duration })
@@ -23931,7 +24017,7 @@ var AgentRunRow = ({ run, onClick, sx, appIcons, onAppClick, apiKey, apiBaseUrl,
23931
24017
  disabled: isAborting,
23932
24018
  onClick: (e) => {
23933
24019
  e.stopPropagation();
23934
- onAbort?.(run);
24020
+ onAbort?.(run2);
23935
24021
  },
23936
24022
  sx: {
23937
24023
  flexShrink: 0,
@@ -24043,11 +24129,11 @@ var AgentActivityList = ({
24043
24129
  }
24044
24130
  }, [workflowFilter, apiKey, apiBaseUrl, orgId]);
24045
24131
  const handleAbort = (0, import_react25.useCallback)(
24046
- async (run) => {
24047
- const eid = run.execution_id;
24048
- const wfId = run.workflow_id || run?.workflow?.id;
24132
+ async (run2) => {
24133
+ const eid = run2.execution_id;
24134
+ const wfId = run2.workflow_id || run2?.workflow?.id;
24049
24135
  if (!eid || !wfId) return;
24050
- const prevStatus = run.status;
24136
+ const prevStatus = run2.status;
24051
24137
  setAbortingIds((prev) => /* @__PURE__ */ new Set([...Array.from(prev), eid]));
24052
24138
  setAbortedIds((prev) => /* @__PURE__ */ new Set([...Array.from(prev), eid]));
24053
24139
  broadcastAgentAborted(eid);
@@ -24055,7 +24141,7 @@ var AgentActivityList = ({
24055
24141
  await abortAgentExecution({
24056
24142
  workflowId: wfId,
24057
24143
  executionId: eid,
24058
- authorization: run.authorization,
24144
+ authorization: run2.authorization,
24059
24145
  apiKey,
24060
24146
  apiBaseUrl,
24061
24147
  orgId
@@ -24072,7 +24158,7 @@ var AgentActivityList = ({
24072
24158
  setRuns(
24073
24159
  (prev) => prev.map((r) => r.execution_id === eid ? { ...r, status: prevStatus } : r)
24074
24160
  );
24075
- toast({
24161
+ toast2({
24076
24162
  title: "Abort failed",
24077
24163
  description: e instanceof Error ? e.message : "Failed to abort execution",
24078
24164
  variant: "destructive"
@@ -24568,18 +24654,18 @@ var AgentActivityList = ({
24568
24654
  }
24569
24655
  )
24570
24656
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_material24.Box, { sx: { display: "flex", flexDirection: "column", gap: 1.5 }, children: [
24571
- filteredRuns.map((run, idx) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
24657
+ filteredRuns.map((run2, idx) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
24572
24658
  AgentRunRow,
24573
24659
  {
24574
- run,
24660
+ run: run2,
24575
24661
  onClick: () => {
24576
- setLastOpenedAgentRun(run.execution_id);
24577
- setLastOpenedRunId(run.execution_id || null);
24578
- onRunClick?.(run);
24662
+ setLastOpenedAgentRun(run2.execution_id);
24663
+ setLastOpenedRunId(run2.execution_id || null);
24664
+ onRunClick?.(run2);
24579
24665
  },
24580
24666
  sx: [
24581
24667
  ...Array.isArray(rowSx) ? rowSx : rowSx ? [rowSx] : [],
24582
- ...run.execution_id && run.execution_id === lastOpenedRunId ? [{
24668
+ ...run2.execution_id && run2.execution_id === lastOpenedRunId ? [{
24583
24669
  borderColor: "hsl(var(--primary) / 0.55)",
24584
24670
  bgcolor: "hsl(var(--primary) / 0.06)"
24585
24671
  }] : []
@@ -24592,7 +24678,7 @@ var AgentActivityList = ({
24592
24678
  abortingIds,
24593
24679
  onAbort: handleAbort
24594
24680
  },
24595
- run.execution_id || idx
24681
+ run2.execution_id || idx
24596
24682
  )),
24597
24683
  hasMore && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_material24.Box, { sx: { display: "flex", justifyContent: "center", mt: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
24598
24684
  import_material24.Button,
@@ -24663,7 +24749,7 @@ var import_jsx_runtime31 = require("react/jsx-runtime");
24663
24749
  var AgentExecutionDrawer = ({
24664
24750
  open,
24665
24751
  onClose,
24666
- run,
24752
+ run: run2,
24667
24753
  width = 720,
24668
24754
  minWidth = 480,
24669
24755
  maxWidth = 960,
@@ -24688,16 +24774,16 @@ var AgentExecutionDrawer = ({
24688
24774
  const themeScope = useShuffleMcpTheme();
24689
24775
  const [bodyReady, setBodyReady] = (0, import_react26.useState)(false);
24690
24776
  (0, import_react26.useEffect)(() => {
24691
- if (!open || !run?.execution_id) {
24777
+ if (!open || !run2?.execution_id) {
24692
24778
  setBodyReady(false);
24693
24779
  return;
24694
24780
  }
24695
24781
  const raf = requestAnimationFrame(() => setBodyReady(true));
24696
24782
  return () => cancelAnimationFrame(raf);
24697
- }, [open, run?.execution_id]);
24698
- const statusKey = (run?.status || "").toUpperCase();
24783
+ }, [open, run2?.execution_id]);
24784
+ const statusKey = (run2?.status || "").toUpperCase();
24699
24785
  const cfg = STATUS_CONFIG[statusKey] || STATUS_CONFIG.WAITING;
24700
- const duration = run ? formatDuration(run) : "";
24786
+ const duration = run2 ? formatDuration(run2) : "";
24701
24787
  const drawerWidth = `min(${width}px, 100vw)`;
24702
24788
  const drawerMinWidth = `min(${minWidth}px, 100vw)`;
24703
24789
  const drawerMaxWidth = `min(${maxWidth}px, 100vw)`;
@@ -24787,16 +24873,16 @@ var AgentExecutionDrawer = ({
24787
24873
  textOverflow: "ellipsis",
24788
24874
  whiteSpace: "nowrap"
24789
24875
  },
24790
- children: run ? getRunTitle(run) : "Agent execution"
24876
+ children: run2 ? getRunTitle(run2) : "Agent execution"
24791
24877
  }
24792
24878
  ),
24793
- run && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material25.Box, { sx: { display: "flex", alignItems: "center", color: cfg.color, flexShrink: 0 }, children: cfg.icon })
24879
+ run2 && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material25.Box, { sx: { display: "flex", alignItems: "center", color: cfg.color, flexShrink: 0 }, children: cfg.icon })
24794
24880
  ] }),
24795
- run && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_material25.Box, { sx: { display: "flex", alignItems: "center", gap: 1, mt: 0.25 }, children: [
24881
+ run2 && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_material25.Box, { sx: { display: "flex", alignItems: "center", gap: 1, mt: 0.25 }, children: [
24796
24882
  /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material25.Typography, { sx: { fontSize: "0.72rem", color: "hsl(var(--muted-foreground))" }, children: cfg.label }),
24797
- run.started_at && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_jsx_runtime31.Fragment, { children: [
24883
+ run2.started_at && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_jsx_runtime31.Fragment, { children: [
24798
24884
  /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material25.Typography, { sx: { fontSize: "0.72rem", color: "hsl(var(--muted-foreground))", opacity: 0.4 }, children: "\xB7" }),
24799
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material25.Typography, { sx: { fontSize: "0.72rem", color: "hsl(var(--muted-foreground))" }, children: getTimeAgo(run.started_at) })
24885
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material25.Typography, { sx: { fontSize: "0.72rem", color: "hsl(var(--muted-foreground))" }, children: getTimeAgo(run2.started_at) })
24800
24886
  ] }),
24801
24887
  duration && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_jsx_runtime31.Fragment, { children: [
24802
24888
  /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material25.Typography, { sx: { fontSize: "0.72rem", color: "hsl(var(--muted-foreground))", opacity: 0.4 }, children: "\xB7" }),
@@ -24804,11 +24890,11 @@ var AgentExecutionDrawer = ({
24804
24890
  ] })
24805
24891
  ] })
24806
24892
  ] }),
24807
- run?.execution_id && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material25.Tooltip, { title: "Open in new tab", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
24893
+ run2?.execution_id && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material25.Tooltip, { title: "Open in new tab", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
24808
24894
  import_material25.IconButton,
24809
24895
  {
24810
24896
  component: "a",
24811
- href: `/agents?execution_id=${encodeURIComponent(run.execution_id)}${run.authorization ? `&authorization=${encodeURIComponent(run.authorization)}` : ""}`,
24897
+ href: `/agents?execution_id=${encodeURIComponent(run2.execution_id)}${run2.authorization ? `&authorization=${encodeURIComponent(run2.authorization)}` : ""}`,
24812
24898
  target: "_blank",
24813
24899
  rel: "noopener noreferrer",
24814
24900
  size: "small",
@@ -24836,7 +24922,7 @@ var AgentExecutionDrawer = ({
24836
24922
  ),
24837
24923
  /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_material25.Box, { sx: [{ flex: 1, overflowY: "auto", pt: 3 }, ...Array.isArray(bodySx) ? bodySx : bodySx ? [bodySx] : []], children: [
24838
24924
  topBanner,
24839
- run && !bodyReady ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material25.Box, { sx: { px: 3, display: "flex", flexDirection: "column", gap: 1.5 }, children: [0, 1, 2, 3].map((i) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
24925
+ run2 && !bodyReady ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material25.Box, { sx: { px: 3, display: "flex", flexDirection: "column", gap: 1.5 }, children: [0, 1, 2, 3].map((i) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
24840
24926
  import_material25.Box,
24841
24927
  {
24842
24928
  sx: {
@@ -24848,17 +24934,17 @@ var AgentExecutionDrawer = ({
24848
24934
  },
24849
24935
  i
24850
24936
  )) }) : null,
24851
- run && bodyReady ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
24937
+ run2 && bodyReady ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
24852
24938
  AgentUI_default,
24853
24939
  {
24854
24940
  initialExecution: {
24855
- execution_id: run.execution_id,
24856
- status: run.status,
24857
- started_at: run.started_at ? Number(run.started_at) : void 0,
24858
- completed_at: run.completed_at ? Number(run.completed_at) : void 0,
24859
- results: run.results,
24860
- workflow: run.workflow,
24861
- authorization: run.authorization
24941
+ execution_id: run2.execution_id,
24942
+ status: run2.status,
24943
+ started_at: run2.started_at ? Number(run2.started_at) : void 0,
24944
+ completed_at: run2.completed_at ? Number(run2.completed_at) : void 0,
24945
+ results: run2.results,
24946
+ workflow: run2.workflow,
24947
+ authorization: run2.authorization
24862
24948
  },
24863
24949
  readUrlParams: false,
24864
24950
  autoLoadApps: false,
@@ -24876,7 +24962,7 @@ var AgentExecutionDrawer = ({
24876
24962
  theme,
24877
24963
  colorMode
24878
24964
  },
24879
- run.execution_id
24965
+ run2.execution_id
24880
24966
  ) : null
24881
24967
  ] })
24882
24968
  ]
@@ -25054,10 +25140,10 @@ var AgentsView = ({
25054
25140
  editing.workflowId,
25055
25141
  { prompt: input, apps: apps.map((a) => ({ name: a.name, id: a.id })) }
25056
25142
  );
25057
- toast({ title: "Schedule updated", description: `Saved changes to "${editing.name}".` });
25143
+ toast2({ title: "Schedule updated", description: `Saved changes to "${editing.name}".` });
25058
25144
  setEditing(null);
25059
25145
  } catch (e) {
25060
- toast({
25146
+ toast2({
25061
25147
  title: "Failed to save changes",
25062
25148
  description: e instanceof Error ? e.message : String(e),
25063
25149
  variant: "destructive"
@@ -27216,14 +27302,19 @@ function buildPython(method, url, headers, body, maskAuth) {
27216
27302
  return lines.join("\n");
27217
27303
  }
27218
27304
  function buildHttp(method, url, headers, body, maskAuth) {
27219
- let parsed;
27305
+ let parsed = null;
27220
27306
  try {
27221
27307
  parsed = new URL(url);
27222
27308
  } catch {
27223
- parsed = new URL(url, "https://localhost");
27309
+ try {
27310
+ parsed = new URL(url, "https://localhost");
27311
+ } catch {
27312
+ parsed = null;
27313
+ }
27224
27314
  }
27225
- const lines = [`${(method || "GET").toUpperCase()} ${parsed.pathname}${parsed.search} HTTP/1.1`];
27226
- lines.push(`Host: ${parsed.host}`);
27315
+ const requestTarget = parsed ? `${parsed.pathname}${parsed.search}` : url || "/";
27316
+ const lines = [`${(method || "GET").toUpperCase()} ${requestTarget} HTTP/1.1`];
27317
+ lines.push(`Host: ${parsed?.host ?? url}`);
27227
27318
  for (const [key, value] of Object.entries(headers)) {
27228
27319
  if (key.toLowerCase() === "host") continue;
27229
27320
  const displayValue = maskAuth && key.toLowerCase() === "authorization" ? value.replace(/(Bearer\s+)(.{8}).*/, "$1$2\u2026") : value;
@@ -27356,10 +27447,10 @@ var ApiCallViewer = ({
27356
27447
  await navigator.clipboard.writeText(copyableSnippet);
27357
27448
  }
27358
27449
  setCopied(true);
27359
- toast.success("Copied to clipboard");
27450
+ toast2.success("Copied to clipboard");
27360
27451
  setTimeout(() => setCopied(false), 2e3);
27361
27452
  } catch {
27362
- toast.error("Copy failed");
27453
+ toast2.error("Copy failed");
27363
27454
  }
27364
27455
  }, [copyableSnippet]);
27365
27456
  const handleRun = (0, import_react33.useCallback)(async () => {
@@ -27415,16 +27506,16 @@ var ApiCallViewer = ({
27415
27506
  const isSuccess = res.ok && (!rawResult || typeof rawResult === "string" && !rawResult.includes('"success": false') || data?.success !== false);
27416
27507
  setResponseStatus(isSuccess ? `Status: ${res.status} OK` : `Status: ${res.status} Error`);
27417
27508
  if (isSuccess) {
27418
- toast.success(`Request completed in ${duration}ms`);
27509
+ toast2.success(`Request completed in ${duration}ms`);
27419
27510
  } else {
27420
- toast.error("Request finished with error");
27511
+ toast2.error("Request finished with error");
27421
27512
  }
27422
27513
  } catch (err) {
27423
27514
  setResponseDuration(Date.now() - start);
27424
27515
  setResponseStatus("Request Failed");
27425
27516
  setResponseOutput(err?.message || "Network error executing request");
27426
27517
  setParsedResponse(null);
27427
- toast.error("Failed to run request");
27518
+ toast2.error("Failed to run request");
27428
27519
  } finally {
27429
27520
  setIsRunning(false);
27430
27521
  }
@@ -27772,9 +27863,9 @@ var ApiCallViewer = ({
27772
27863
  if (typeof navigator !== "undefined" && navigator.clipboard?.writeText) {
27773
27864
  navigator.clipboard.writeText(responseOutput);
27774
27865
  }
27775
- toast.success("Response copied");
27866
+ toast2.success("Response copied");
27776
27867
  } catch {
27777
- toast.error("Copy failed");
27868
+ toast2.error("Copy failed");
27778
27869
  }
27779
27870
  },
27780
27871
  sx: {