@shuffleio/shuffle-mcps 0.0.5 → 0.0.6

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.cjs CHANGED
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  var index_exports = {};
31
31
  __export(index_exports, {
32
32
  API_CONFIG: () => API_CONFIG,
33
+ AgentUI: () => AgentUI_default,
33
34
  AppAuthSection: () => AppAuthSection,
34
35
  AppDetailDrawer: () => AppDetailDrawer,
35
36
  AppDetailProvider: () => AppDetailProvider,
@@ -55,11 +56,35 @@ module.exports = __toCommonJS(index_exports);
55
56
  // ShuffleMCP.tsx
56
57
  var import_react9 = __toESM(require("react"), 1);
57
58
  var import_algoliasearch = require("algoliasearch");
59
+ var import_material9 = require("@mui/material");
58
60
 
59
61
  // AppDetailDrawer.tsx
60
62
  var import_react8 = require("react");
61
- var import_sonner2 = require("sonner");
62
- var import_lucide_react = require("lucide-react");
63
+
64
+ // toast.ts
65
+ var defaultImpl = (arg, opts) => {
66
+ const isObj = typeof arg === "object" && arg !== null;
67
+ const title = isObj ? arg.title : arg;
68
+ const description = isObj ? arg.description : opts?.description;
69
+ const variant = (isObj ? arg.variant : void 0) || "default";
70
+ const msg = [title, description].filter(Boolean).join(" \u2014 ");
71
+ if (variant === "destructive" || variant === "error") console.error("[toast]", msg);
72
+ else if (variant === "warning") console.warn("[toast]", msg);
73
+ else console.log("[toast]", msg);
74
+ };
75
+ var _impl = defaultImpl;
76
+ function setToastImpl(fn) {
77
+ _impl = fn;
78
+ }
79
+ var base = ((arg, opts) => _impl(arg, opts));
80
+ base.success = (msg, opts) => _impl({ title: msg, description: opts?.description, variant: "success" }, opts);
81
+ base.error = (msg, opts) => _impl({ title: msg, description: opts?.description, variant: "destructive" }, opts);
82
+ base.info = (msg, opts) => _impl({ title: msg, description: opts?.description, variant: "info" }, opts);
83
+ base.warning = (msg, opts) => _impl({ title: msg, description: opts?.description, variant: "warning" }, opts);
84
+ var toast = base;
85
+
86
+ // AppDetailDrawer.tsx
87
+ var import_lucide_react2 = require("lucide-react");
63
88
 
64
89
  // api.ts
65
90
  var import_meta = {};
@@ -381,6 +406,7 @@ var import_react3 = require("react");
381
406
  var import_react2 = require("react");
382
407
  var import_material = require("@mui/material");
383
408
  var import_Add = __toESM(require("@mui/icons-material/Add"), 1);
409
+ var import_react_router_dom = require("react-router-dom");
384
410
 
385
411
  // authenticatedApps.ts
386
412
  var TTL_MS = 3e4;
@@ -829,7 +855,7 @@ var IntegrationStatus = ({ collapsed, filterApps, onAddClick, iconSize = 26, onD
829
855
  color: "hsl(var(--muted-foreground))",
830
856
  cursor: "pointer",
831
857
  "&:hover": {
832
- backgroundColor: "hsl(var(--accent))"
858
+ backgroundColor: "hsl(var(--muted))"
833
859
  }
834
860
  },
835
861
  children: [
@@ -850,7 +876,7 @@ var IntegrationStatus = ({ collapsed, filterApps, onAddClick, iconSize = 26, onD
850
876
  color: "hsl(var(--muted-foreground))",
851
877
  cursor: "pointer",
852
878
  "&:hover": {
853
- backgroundColor: "hsl(var(--accent))"
879
+ backgroundColor: "hsl(var(--muted))"
854
880
  }
855
881
  },
856
882
  children: "\u2212"
@@ -878,8 +904,8 @@ var IntegrationStatus = ({ collapsed, filterApps, onAddClick, iconSize = 26, onD
878
904
  import_material.IconButton,
879
905
  {
880
906
  size: "small",
881
- component: "a",
882
- href: "/onboarding",
907
+ component: import_react_router_dom.Link,
908
+ to: "/onboarding",
883
909
  sx: {
884
910
  width: 26,
885
911
  height: 26,
@@ -1276,19 +1302,6 @@ var import_framer_motion3 = require("framer-motion");
1276
1302
 
1277
1303
  // AppAuthConfig.tsx
1278
1304
  var import_react4 = require("react");
1279
-
1280
- // toast.ts
1281
- var _impl = ({ title, description, variant }) => {
1282
- const msg = [title, description].filter(Boolean).join(" \u2014 ");
1283
- if (variant === "destructive") console.error("[toast]", msg);
1284
- else console.log("[toast]", msg);
1285
- };
1286
- function setToastImpl(fn) {
1287
- _impl = fn;
1288
- }
1289
- var toast = (arg) => _impl(arg);
1290
-
1291
- // AppAuthConfig.tsx
1292
1305
  var import_material3 = require("@mui/material");
1293
1306
  var import_framer_motion2 = require("framer-motion");
1294
1307
  var import_ExpandMore = __toESM(require("@mui/icons-material/ExpandMore"), 1);
@@ -3609,9 +3622,11 @@ function TryMcpSection({ appName, appIcon, appId, categories }) {
3609
3622
 
3610
3623
  // SingulActionsPreview.tsx
3611
3624
  var import_react6 = require("react");
3612
- var import_sonner = require("sonner");
3613
3625
  var import_material7 = require("@mui/material");
3614
3626
  var import_PlayArrow = __toESM(require("@mui/icons-material/PlayArrow"), 1);
3627
+ var import_ContentCopy = __toESM(require("@mui/icons-material/ContentCopy"), 1);
3628
+ var import_Check = __toESM(require("@mui/icons-material/Check"), 1);
3629
+ var import_lucide_react = require("lucide-react");
3615
3630
  var import_jsx_runtime9 = require("react/jsx-runtime");
3616
3631
  var import_react7 = require("react");
3617
3632
  var ACTION_DEFAULT_FIELDS = {
@@ -3867,14 +3882,16 @@ var SingulActionsPreview = ({
3867
3882
  const handleCopy = async () => {
3868
3883
  try {
3869
3884
  await navigator.clipboard.writeText(snippet);
3870
- import_sonner.toast.success("Copied snippet");
3885
+ setCopied(true);
3886
+ setTimeout(() => setCopied(false), 2e3);
3871
3887
  } catch {
3872
- import_sonner.toast.error("Copy failed");
3888
+ toast.error("Copy failed");
3873
3889
  }
3874
3890
  };
3875
3891
  const [playLoading, setPlayLoading] = (0, import_react6.useState)(false);
3876
3892
  const [playResult, setPlayResult] = (0, import_react6.useState)(null);
3877
3893
  const responseRef = (0, import_react6.useRef)(null);
3894
+ const [copied, setCopied] = (0, import_react6.useState)(false);
3878
3895
  const scrollToResponse = () => {
3879
3896
  requestAnimationFrame(() => {
3880
3897
  responseRef.current?.scrollIntoView({ behavior: "smooth", block: "nearest" });
@@ -3929,14 +3946,14 @@ var SingulActionsPreview = ({
3929
3946
  }
3930
3947
  })();
3931
3948
  if (parsed?.success === false) {
3932
- import_sonner.toast.error(parsed.reason || "Run failed");
3949
+ toast.error(parsed.reason || "Run failed");
3933
3950
  } else {
3934
- import_sonner.toast.success(`Ran ${selected?.name || lang}`);
3951
+ toast.success(`Ran ${selected?.name || lang}`);
3935
3952
  }
3936
3953
  } catch (err) {
3937
3954
  const msg = err?.message || "Run failed";
3938
3955
  setPlayResult(msg);
3939
- import_sonner.toast.error(msg);
3956
+ toast.error(msg);
3940
3957
  } finally {
3941
3958
  setPlayLoading(false);
3942
3959
  scrollToResponse();
@@ -3981,86 +3998,54 @@ var SingulActionsPreview = ({
3981
3998
  },
3982
3999
  children: [
3983
4000
  isDisabled ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material7.Typography, { sx: { fontSize: "0.75rem", color: "hsl(var(--muted-foreground))", fontStyle: "italic", textAlign: "center", py: 1 }, children: "No category detected for this app" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
3984
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_material7.Box, { sx: { display: "flex", gap: 1, mb: 1.5, alignItems: "center" }, children: [
3985
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
3986
- import_material7.Autocomplete,
3987
- {
3988
- size: "small",
3989
- disableClearable: true,
3990
- options: sortedActions,
3991
- value: selected ?? sortedActions[0],
3992
- onChange: (_, v) => v && handleSelect(v),
3993
- groupBy: (o) => o.category,
3994
- getOptionLabel: (o) => o?.label ?? "",
3995
- isOptionEqualToValue: (a, b) => a?.name === b?.name && a?.category === b?.category,
3996
- renderOption: (props, option) => /* @__PURE__ */ (0, import_react7.createElement)("li", { ...props, key: `${option.category}-${option.name}` }, /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_material7.Box, { sx: { display: "flex", flexDirection: "column" }, children: [
3997
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material7.Typography, { sx: { fontSize: "0.78rem", color: "hsl(var(--foreground))" }, children: option.label }),
3998
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material7.Typography, { sx: { fontFamily: "'JetBrains Mono', monospace", fontSize: "0.65rem", color: "hsl(var(--muted-foreground))" }, children: option.name })
3999
- ] })),
4000
- sx: {
4001
- flex: 1,
4002
- "& .MuiOutlinedInput-root": {
4001
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material7.Box, { sx: { display: "flex", gap: 1, mb: 1.5, alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4002
+ import_material7.Autocomplete,
4003
+ {
4004
+ size: "small",
4005
+ disableClearable: true,
4006
+ options: sortedActions,
4007
+ value: selected ?? sortedActions[0],
4008
+ onChange: (_, v) => v && handleSelect(v),
4009
+ groupBy: (o) => o.category,
4010
+ getOptionLabel: (o) => o?.label ?? "",
4011
+ isOptionEqualToValue: (a, b) => a?.name === b?.name && a?.category === b?.category,
4012
+ renderOption: (props, option) => /* @__PURE__ */ (0, import_react7.createElement)("li", { ...props, key: `${option.category}-${option.name}` }, /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_material7.Box, { sx: { display: "flex", flexDirection: "column" }, children: [
4013
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material7.Typography, { sx: { fontSize: "0.78rem", color: "hsl(var(--foreground))" }, children: option.label }),
4014
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material7.Typography, { sx: { fontFamily: "'JetBrains Mono', monospace", fontSize: "0.65rem", color: "hsl(var(--muted-foreground))" }, children: option.name })
4015
+ ] })),
4016
+ sx: {
4017
+ flex: 1,
4018
+ "& .MuiOutlinedInput-root": {
4019
+ backgroundColor: "hsl(var(--card))",
4020
+ fontFamily: "'JetBrains Mono', monospace",
4021
+ fontSize: "0.75rem",
4022
+ color: "hsl(var(--foreground))",
4023
+ "& fieldset": { borderColor: "hsl(var(--border))" },
4024
+ "&:hover fieldset": { borderColor: "hsl(var(--primary))" },
4025
+ "&.Mui-focused fieldset": { borderColor: "hsl(var(--primary))" }
4026
+ }
4027
+ },
4028
+ slotProps: {
4029
+ paper: {
4030
+ sx: {
4003
4031
  backgroundColor: "hsl(var(--card))",
4004
- fontFamily: "'JetBrains Mono', monospace",
4005
- fontSize: "0.75rem",
4006
4032
  color: "hsl(var(--foreground))",
4007
- "& fieldset": { borderColor: "hsl(var(--border))" },
4008
- "&:hover fieldset": { borderColor: "hsl(var(--primary))" },
4009
- "&.Mui-focused fieldset": { borderColor: "hsl(var(--primary))" }
4010
- }
4011
- },
4012
- slotProps: {
4013
- paper: {
4014
- sx: {
4015
- backgroundColor: "hsl(var(--card))",
4016
- color: "hsl(var(--foreground))",
4017
- border: "1px solid hsl(var(--border))",
4018
- "& .MuiAutocomplete-groupLabel": {
4019
- backgroundColor: "hsl(var(--muted) / 0.6)",
4020
- color: "hsl(var(--muted-foreground))",
4021
- fontSize: "0.65rem",
4022
- fontWeight: 600,
4023
- textTransform: "uppercase",
4024
- letterSpacing: 0.6,
4025
- lineHeight: "24px"
4026
- }
4027
- }
4028
- }
4029
- },
4030
- renderInput: (params) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material7.TextField, { ...params, placeholder: "Select action" })
4031
- }
4032
- ),
4033
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4034
- import_material7.ToggleButtonGroup,
4035
- {
4036
- size: "small",
4037
- exclusive: true,
4038
- value: lang,
4039
- onChange: (_, v) => v && setLang(v),
4040
- sx: {
4041
- "& .MuiToggleButton-root": {
4042
- height: 36,
4043
- px: 1.5,
4044
- fontSize: "0.7rem",
4045
- textTransform: "none",
4046
- fontFamily: "'JetBrains Mono', monospace",
4047
- color: "hsl(var(--muted-foreground))",
4048
4033
  border: "1px solid hsl(var(--border))",
4049
- "&.Mui-selected": {
4050
- backgroundColor: "hsl(var(--primary) / 0.15)",
4051
- color: "hsl(var(--primary))",
4052
- borderColor: "hsl(var(--primary))",
4053
- "&:hover": { backgroundColor: "hsl(var(--primary) / 0.2)" }
4034
+ "& .MuiAutocomplete-groupLabel": {
4035
+ backgroundColor: "hsl(var(--muted) / 0.6)",
4036
+ color: "hsl(var(--muted-foreground))",
4037
+ fontSize: "0.65rem",
4038
+ fontWeight: 600,
4039
+ textTransform: "uppercase",
4040
+ letterSpacing: 0.6,
4041
+ lineHeight: "24px"
4054
4042
  }
4055
4043
  }
4056
- },
4057
- children: [
4058
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material7.ToggleButton, { value: "curl", children: "curl" }),
4059
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material7.ToggleButton, { value: "python", children: "python" })
4060
- ]
4061
- }
4062
- )
4063
- ] }),
4044
+ }
4045
+ },
4046
+ renderInput: (params) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material7.TextField, { ...params, placeholder: "Select action" })
4047
+ }
4048
+ ) }),
4064
4049
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4065
4050
  import_material7.Box,
4066
4051
  {
@@ -4079,82 +4064,95 @@ var SingulActionsPreview = ({
4079
4064
  sx: {
4080
4065
  display: "flex",
4081
4066
  alignItems: "center",
4082
- justifyContent: "space-between",
4083
- px: 1.25,
4084
- py: 0.75,
4067
+ gap: 1,
4068
+ px: 2,
4069
+ py: 1,
4085
4070
  borderBottom: "1px solid hsl(var(--border))",
4086
- backgroundColor: "hsl(var(--muted) / 0.4)"
4071
+ backgroundColor: "hsl(var(--card))"
4087
4072
  },
4088
4073
  children: [
4089
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_material7.Box, { sx: { display: "flex", alignItems: "center", gap: 0.75 }, children: [
4090
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_material7.Box, { sx: { display: "flex", gap: 0.4 }, children: [
4091
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material7.Box, { sx: { width: 8, height: 8, borderRadius: "50%", backgroundColor: "hsl(0 70% 60% / 0.6)" } }),
4092
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material7.Box, { sx: { width: 8, height: 8, borderRadius: "50%", backgroundColor: "hsl(40 80% 60% / 0.6)" } }),
4093
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material7.Box, { sx: { width: 8, height: 8, borderRadius: "50%", backgroundColor: "hsl(140 60% 55% / 0.6)" } })
4094
- ] }),
4095
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4096
- import_material7.Typography,
4097
- {
4098
- sx: {
4099
- ml: 1,
4100
- fontFamily: "'JetBrains Mono', monospace",
4101
- fontSize: "0.65rem",
4102
- color: "hsl(var(--muted-foreground))",
4103
- letterSpacing: 0.4
4104
- },
4105
- children: [
4106
- lang === "python" ? "singul.py" : "request.sh",
4107
- selected ? ` \xB7 ${selected.name}` : ""
4108
- ]
4109
- }
4110
- )
4111
- ] }),
4112
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_material7.Box, { sx: { display: "flex", gap: 0.75 }, children: [
4113
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4114
- import_material7.Button,
4115
- {
4116
- size: "small",
4117
- onClick: handleCopy,
4118
- sx: {
4119
- height: 26,
4120
- minWidth: 0,
4121
- px: 1.25,
4122
- fontSize: "0.65rem",
4123
- textTransform: "none",
4124
- color: "hsl(var(--muted-foreground))",
4125
- backgroundColor: "hsl(var(--card))",
4126
- border: "1px solid hsl(var(--border))",
4127
- "&:hover": { backgroundColor: "hsl(var(--muted))", color: "hsl(var(--foreground))" }
4128
- },
4129
- children: "Copy"
4074
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react.Code2, { size: 14, style: { color: "hsl(var(--muted-foreground))" } }),
4075
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4076
+ import_material7.Typography,
4077
+ {
4078
+ sx: {
4079
+ fontSize: "0.7rem",
4080
+ fontWeight: 600,
4081
+ color: "hsl(var(--muted-foreground))",
4082
+ textTransform: "uppercase",
4083
+ letterSpacing: "0.05em"
4084
+ },
4085
+ children: "Action"
4086
+ }
4087
+ ),
4088
+ selected && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4089
+ import_material7.Chip,
4090
+ {
4091
+ label: selected.name,
4092
+ size: "small",
4093
+ sx: {
4094
+ height: 18,
4095
+ fontSize: "0.6rem",
4096
+ fontWeight: 700,
4097
+ fontFamily: "'JetBrains Mono', monospace",
4098
+ bgcolor: "hsla(var(--severity-medium) / 0.15)",
4099
+ color: "hsl(var(--severity-medium))",
4100
+ "& .MuiChip-label": { px: 0.75 }
4130
4101
  }
4131
- ),
4132
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4133
- import_material7.Button,
4134
- {
4135
- size: "small",
4136
- onClick: handlePlay,
4137
- disabled: playLoading,
4138
- startIcon: !playLoading && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_PlayArrow.default, { sx: { fontSize: 14 } }),
4139
- sx: {
4140
- height: 26,
4141
- minWidth: 0,
4142
- px: 1.5,
4143
- fontSize: "0.65rem",
4144
- fontWeight: 600,
4145
- textTransform: "none",
4146
- color: "hsl(var(--primary-foreground))",
4147
- backgroundColor: "hsl(var(--primary))",
4148
- border: "1px solid hsl(var(--primary))",
4149
- boxShadow: "0 0 12px -2px hsl(var(--primary) / 0.6)",
4150
- "& .MuiButton-startIcon": { mr: 0.5 },
4151
- "&:hover": { backgroundColor: "hsl(var(--primary) / 0.9)", boxShadow: "0 0 16px -2px hsl(var(--primary) / 0.7)" },
4152
- "&.Mui-disabled": { color: "hsl(var(--primary-foreground) / 0.7)", backgroundColor: "hsl(var(--primary) / 0.45)", boxShadow: "none", borderColor: "hsl(var(--primary) / 0.45)" }
4102
+ }
4103
+ ),
4104
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material7.Box, { sx: { flex: 1 } }),
4105
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material7.Box, { sx: { display: "flex", gap: 0.5 }, children: ["curl", "python"].map((m) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4106
+ import_material7.Chip,
4107
+ {
4108
+ label: m === "curl" ? "cURL" : "Python",
4109
+ icon: m === "curl" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react.Terminal, { size: 12 }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react.Code2, { size: 12 }),
4110
+ size: "small",
4111
+ onClick: () => setLang(m),
4112
+ sx: {
4113
+ height: 22,
4114
+ fontSize: "0.6rem",
4115
+ fontWeight: 600,
4116
+ cursor: "pointer",
4117
+ bgcolor: lang === m ? "hsl(var(--primary) / 0.12)" : "transparent",
4118
+ color: lang === m ? "hsl(var(--primary))" : "hsl(var(--muted-foreground))",
4119
+ border: lang === m ? "1px solid hsl(var(--primary) / 0.3)" : "1px solid transparent",
4120
+ "& .MuiChip-icon": {
4121
+ color: lang === m ? "hsl(var(--primary))" : "hsl(var(--muted-foreground))"
4153
4122
  },
4154
- children: playLoading ? "Running\u2026" : "Play"
4123
+ "&:hover": {
4124
+ bgcolor: lang === m ? "hsl(var(--primary) / 0.15)" : "hsl(var(--muted))"
4125
+ }
4155
4126
  }
4156
- )
4157
- ] })
4127
+ },
4128
+ m
4129
+ )) }),
4130
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material7.Tooltip, { title: copied ? "Copied!" : "Copy", arrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_material7.IconButton, { size: "small", onClick: handleCopy, sx: { color: "hsl(var(--muted-foreground))" }, children: copied ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_Check.default, { sx: { fontSize: 14 } }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ContentCopy.default, { sx: { fontSize: 14 } }) }) }),
4131
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4132
+ import_material7.Button,
4133
+ {
4134
+ size: "small",
4135
+ onClick: handlePlay,
4136
+ disabled: playLoading,
4137
+ startIcon: !playLoading && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_PlayArrow.default, { sx: { fontSize: 14 } }),
4138
+ sx: {
4139
+ height: 26,
4140
+ minWidth: 0,
4141
+ px: 1.5,
4142
+ fontSize: "0.65rem",
4143
+ fontWeight: 600,
4144
+ textTransform: "none",
4145
+ color: "hsl(var(--primary-foreground))",
4146
+ backgroundColor: "hsl(var(--primary))",
4147
+ border: "1px solid hsl(var(--primary))",
4148
+ boxShadow: "0 0 12px -2px hsl(var(--primary) / 0.6)",
4149
+ "& .MuiButton-startIcon": { mr: 0.5 },
4150
+ "&:hover": { backgroundColor: "hsl(var(--primary) / 0.9)", boxShadow: "0 0 16px -2px hsl(var(--primary) / 0.7)" },
4151
+ "&.Mui-disabled": { color: "hsl(var(--primary-foreground) / 0.7)", backgroundColor: "hsl(var(--primary) / 0.45)", boxShadow: "none", borderColor: "hsl(var(--primary) / 0.45)" }
4152
+ },
4153
+ children: playLoading ? "Running\u2026" : "Play"
4154
+ }
4155
+ )
4158
4156
  ]
4159
4157
  }
4160
4158
  ),
@@ -4279,6 +4277,7 @@ function AppDetailDrawer({
4279
4277
  open,
4280
4278
  onClose,
4281
4279
  appName,
4280
+ appId,
4282
4281
  anchor = "right",
4283
4282
  width = 520,
4284
4283
  onRefresh,
@@ -4309,33 +4308,35 @@ function AppDetailDrawer({
4309
4308
  setAppLoading(true);
4310
4309
  setAppInfo(null);
4311
4310
  setIsActivated(null);
4312
- setResolvedAlgoliaId(null);
4311
+ setResolvedAlgoliaId(appId || null);
4313
4312
  refreshAuth();
4314
4313
  const normalizedName = appName.toLowerCase().replace(/[\s_\-]+/g, "_");
4315
4314
  const searchName = appName.replace(/_/g, " ");
4316
4315
  (async () => {
4317
- let algoliaId = null;
4318
- try {
4319
- const { algoliasearch: algoliasearch2 } = await import("algoliasearch");
4320
- const client = algoliasearch2("JNSS5CFDZZ", "33e4e3564f4f060e96e0531957bed552");
4321
- const res = await client.search({
4322
- requests: [{ indexName: "appsearch", query: searchName, hitsPerPage: 10 }]
4323
- });
4324
- const hits = res?.results?.[0]?.hits || [];
4325
- const match = hits.find(
4326
- (h) => h.name?.toLowerCase().replace(/[\s_\-]+/g, "_") === normalizedName
4327
- ) || (hits.length > 0 ? hits[0] : null);
4328
- if (match) {
4329
- algoliaId = match.objectID;
4330
- setResolvedAlgoliaId(algoliaId);
4331
- setAppInfo({
4332
- name: match.name || searchName,
4333
- description: match.description || "",
4334
- large_image: match.image_url || "",
4335
- categories: match.categories || []
4316
+ let algoliaId = appId || null;
4317
+ if (!algoliaId) {
4318
+ try {
4319
+ const { algoliasearch: algoliasearch2 } = await import("algoliasearch");
4320
+ const client = algoliasearch2("JNSS5CFDZZ", "33e4e3564f4f060e96e0531957bed552");
4321
+ const res = await client.search({
4322
+ requests: [{ indexName: "appsearch", query: searchName, hitsPerPage: 10 }]
4336
4323
  });
4324
+ const hits = res?.results?.[0]?.hits || [];
4325
+ const match = hits.find(
4326
+ (h) => h.name?.toLowerCase().replace(/[\s_\-]+/g, "_") === normalizedName
4327
+ ) || (hits.length > 0 ? hits[0] : null);
4328
+ if (match) {
4329
+ algoliaId = match.objectID;
4330
+ setResolvedAlgoliaId(algoliaId);
4331
+ setAppInfo({
4332
+ name: match.name || searchName,
4333
+ description: match.description || "",
4334
+ large_image: match.image_url || "",
4335
+ categories: match.categories || []
4336
+ });
4337
+ }
4338
+ } catch {
4337
4339
  }
4338
- } catch {
4339
4340
  }
4340
4341
  let appsList = null;
4341
4342
  if (API_CONFIG.apiKey) {
@@ -4399,7 +4400,7 @@ function AppDetailDrawer({
4399
4400
  });
4400
4401
  setAppLoading(false);
4401
4402
  })();
4402
- }, [open, appName]);
4403
+ }, [open, appName, appId]);
4403
4404
  (0, import_react8.useEffect)(() => {
4404
4405
  if (!open || !appName || !isAuthenticated) {
4405
4406
  setIncidentStats(null);
@@ -4491,22 +4492,22 @@ function AppDetailDrawer({
4491
4492
  });
4492
4493
  if (!res.ok) throw new Error("Deactivate failed");
4493
4494
  setActivatedAppId(null);
4494
- import_sonner2.toast.success(`${displayName} deactivated`);
4495
+ toast.success(`${displayName} deactivated`);
4495
4496
  } else {
4496
- const appId = resolvedAlgoliaId;
4497
- if (!appId) throw new Error("App ID not resolved yet");
4498
- const activateRes = await fetch(getApiUrl(`/api/v1/apps/${appId}/activate`), {
4497
+ const appId2 = resolvedAlgoliaId;
4498
+ if (!appId2) throw new Error("App ID not resolved yet");
4499
+ const activateRes = await fetch(getApiUrl(`/api/v1/apps/${appId2}/activate`), {
4499
4500
  method: "GET",
4500
4501
  credentials: "include",
4501
4502
  headers: { ...getAuthHeader() }
4502
4503
  });
4503
4504
  if (!activateRes.ok) throw new Error(`Activate failed (${activateRes.status})`);
4504
- setActivatedAppId(appId);
4505
- import_sonner2.toast.success(`${displayName} activated`);
4505
+ setActivatedAppId(appId2);
4506
+ toast.success(`${displayName} activated`);
4506
4507
  }
4507
4508
  } catch (err) {
4508
4509
  console.error("[Activate] Error:", err);
4509
- import_sonner2.toast.error(err?.message || "Activation failed");
4510
+ toast.error(err?.message || "Activation failed");
4510
4511
  setIsActivated(wasActivated);
4511
4512
  setActivatedAppId(prevAppId);
4512
4513
  } finally {
@@ -4607,14 +4608,14 @@ function AppDetailDrawer({
4607
4608
  bgcolor: "hsl(var(--muted) / 0.3)"
4608
4609
  }, children: [
4609
4610
  /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_material8.Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
4610
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react.Download, { size: 14, style: { color: "hsl(var(--primary))" } }),
4611
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react2.Download, { size: 14, style: { color: "hsl(var(--primary))" } }),
4611
4612
  /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_material8.Box, { children: [
4612
4613
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_material8.Typography, { sx: { fontSize: "1.1rem", fontWeight: 700, color: "hsl(var(--foreground))", lineHeight: 1 }, children: incidentStats.ingested }),
4613
4614
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_material8.Typography, { sx: { fontSize: "0.65rem", color: "hsl(var(--muted-foreground))", fontWeight: 500 }, children: "Incidents ingested" })
4614
4615
  ] })
4615
4616
  ] }),
4616
4617
  incidentStats.forwarded > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_material8.Box, { sx: { display: "flex", alignItems: "center", gap: 1, ml: 2, pl: 2, borderLeft: "1px solid hsl(var(--border))" }, children: [
4617
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react.Forward, { size: 14, style: { color: "hsl(var(--severity-low))" } }),
4618
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react2.Forward, { size: 14, style: { color: "hsl(var(--severity-low))" } }),
4618
4619
  /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_material8.Box, { children: [
4619
4620
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_material8.Typography, { sx: { fontSize: "1.1rem", fontWeight: 700, color: "hsl(var(--foreground))", lineHeight: 1 }, children: incidentStats.forwarded }),
4620
4621
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_material8.Typography, { sx: { fontSize: "0.65rem", color: "hsl(var(--muted-foreground))", fontWeight: 500 }, children: "Forwarded" })
@@ -4634,8 +4635,8 @@ function AppDetailDrawer({
4634
4635
  isAuthenticated,
4635
4636
  matchingEntries,
4636
4637
  onAuthChange: handleAuthChange,
4637
- onTestConnection: (appId, authId) => handleTestConnection(appName || appId, authId),
4638
- onSaveAuth: (appId, creds) => handleSaveAuth(appId, creds, appName || void 0),
4638
+ onTestConnection: (appId2, authId) => handleTestConnection(appName || appId2, authId),
4639
+ onSaveAuth: (appId2, creds) => handleSaveAuth(appId2, creds, appName || void 0),
4639
4640
  onRefreshAuth: refreshAuth
4640
4641
  }
4641
4642
  ),
@@ -4967,6 +4968,10 @@ var ShuffleMCP = import_react9.default.forwardRef(({
4967
4968
  merged = results;
4968
4969
  } else if (sourceFilter === "private") {
4969
4970
  merged = filteredPrivateApps;
4971
+ } else if (sourceFilter === "authenticated") {
4972
+ const privateNames = new Set(filteredPrivateApps.map((a) => norm2(a.name)));
4973
+ const publicOnly = results.filter((a) => !privateNames.has(norm2(a.name)));
4974
+ merged = [...filteredPrivateApps, ...publicOnly].filter(isAppConfigured);
4970
4975
  } else {
4971
4976
  const privateNames = new Set(filteredPrivateApps.map((a) => norm2(a.name)));
4972
4977
  const publicOnly = results.filter((a) => !privateNames.has(norm2(a.name)));
@@ -4975,7 +4980,7 @@ var ShuffleMCP = import_react9.default.forwardRef(({
4975
4980
  if (!pinnedApps || pinnedApps.length === 0) return merged;
4976
4981
  const pinnedNames = new Set(pinnedApps.map((a) => norm2(a.name)));
4977
4982
  return [...pinnedApps, ...merged.filter((a) => !pinnedNames.has(norm2(a.name)))];
4978
- }, [pinnedApps, results, filteredPrivateApps, sourceFilter]);
4983
+ }, [pinnedApps, results, filteredPrivateApps, sourceFilter, isAppConfigured]);
4979
4984
  const getGridColumnsStyle = (0, import_react9.useMemo)(() => {
4980
4985
  if (layout !== "grid") return {};
4981
4986
  const cols = typeof gridColumns === "number" ? gridColumns : gridColumns.md || 3;
@@ -5026,7 +5031,18 @@ var ShuffleMCP = import_react9.default.forwardRef(({
5026
5031
  /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "singul-app-details", style: customStyles.appDetails, children: [
5027
5032
  /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "singul-app-name", style: customStyles.appName, children: [
5028
5033
  app.name.replace(/_/g, " "),
5029
- app.source === "private" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "singul-private-badge", title: "From your private apps", children: "Private" })
5034
+ app.source === "private" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
5035
+ import_material9.Tooltip,
5036
+ {
5037
+ title: "Private apps are apps you have activated in your organization, or your own custom apps \u2014 not just from the public Algolia catalog.",
5038
+ arrow: true,
5039
+ enterDelay: 100,
5040
+ enterNextDelay: 100,
5041
+ placement: "top",
5042
+ slotProps: { popper: { style: { zIndex: 1e4 } } },
5043
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "singul-private-badge", children: "Private" })
5044
+ }
5045
+ )
5030
5046
  ] }),
5031
5047
  showDescription && app.description && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "singul-app-description", style: customStyles.appDescription, children: app.description }),
5032
5048
  showCategories && app.categories?.[0] && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "singul-app-category", style: customStyles.appCategory, children: app.categories[0] })
@@ -5079,21 +5095,33 @@ var ShuffleMCP = import_react9.default.forwardRef(({
5079
5095
  isLoading && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "singul-loading-spinner", style: customStyles.loadingSpinner, children: renderLoadingState ? renderLoadingState() : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "singul-spinner", style: customStyles.spinner }) })
5080
5096
  ] }),
5081
5097
  showSourceFilter && privateApps.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "singul-source-filter", role: "tablist", "aria-label": "Filter by app source", children: [
5082
- { key: "all", label: "All", count: results.length + filteredPrivateApps.length },
5083
- { key: "public", label: "Public", count: results.length },
5084
- { key: "private", label: "Private", count: filteredPrivateApps.length }
5085
- ].map((opt) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
5086
- "button",
5098
+ { key: "all", label: "All", count: results.length + filteredPrivateApps.length, title: "All available apps \u2014 both the public catalog and your private apps." },
5099
+ { key: "public", label: "Public", count: results.length, title: "Public apps from the Shuffle catalog (powered by Algolia)." },
5100
+ { key: "private", label: "Private", count: filteredPrivateApps.length, title: "Private apps are apps you have activated in your organization, or your own custom apps \u2014 not just from the public Algolia catalog." },
5101
+ { key: "authenticated", label: "Authenticated", count: [...filteredPrivateApps, ...results].filter((a, i, arr) => arr.findIndex((x) => x.name?.toLowerCase() === a.name?.toLowerCase()) === i).filter(isAppConfigured).length, title: "Apps you have authenticated and that are ready to use." }
5102
+ ].map((opt) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
5103
+ import_material9.Tooltip,
5087
5104
  {
5088
- type: "button",
5089
- role: "tab",
5090
- "aria-selected": sourceFilter === opt.key,
5091
- className: `singul-source-pill ${sourceFilter === opt.key ? "singul-source-pill-active" : ""}`,
5092
- onClick: () => setSourceFilter(opt.key),
5093
- children: [
5094
- opt.label,
5095
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "singul-source-count", children: opt.count })
5096
- ]
5105
+ title: opt.title,
5106
+ arrow: true,
5107
+ enterDelay: 100,
5108
+ enterNextDelay: 100,
5109
+ placement: "top",
5110
+ slotProps: { popper: { style: { zIndex: 1e4 } } },
5111
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { style: { display: "inline-flex" }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
5112
+ "button",
5113
+ {
5114
+ type: "button",
5115
+ role: "tab",
5116
+ "aria-selected": sourceFilter === opt.key,
5117
+ className: `singul-source-pill ${sourceFilter === opt.key ? "singul-source-pill-active" : ""}`,
5118
+ onClick: () => setSourceFilter(opt.key),
5119
+ children: [
5120
+ opt.label,
5121
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "singul-source-count", children: opt.count })
5122
+ ]
5123
+ }
5124
+ ) })
5097
5125
  },
5098
5126
  opt.key
5099
5127
  )) }),
@@ -5159,12 +5187,12 @@ var ShuffleMCP_default = ShuffleMCP;
5159
5187
 
5160
5188
  // AppSearchDrawer.tsx
5161
5189
  var import_react10 = require("react");
5162
- var import_material10 = require("@mui/material");
5190
+ var import_material11 = require("@mui/material");
5163
5191
  var import_Close3 = __toESM(require("@mui/icons-material/Close"), 1);
5164
5192
  var import_framer_motion7 = require("framer-motion");
5165
5193
 
5166
5194
  // ShufflePipelinesBanner.tsx
5167
- var import_material9 = require("@mui/material");
5195
+ var import_material10 = require("@mui/material");
5168
5196
 
5169
5197
  // ../assets/shuffle-icon.png
5170
5198
  var shuffle_icon_default = "data:image/png;base64,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";
@@ -5173,7 +5201,7 @@ var shuffle_icon_default = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJAAAA
5173
5201
  var import_jsx_runtime12 = require("react/jsx-runtime");
5174
5202
  function ShufflePipelinesBanner() {
5175
5203
  return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
5176
- import_material9.Box,
5204
+ import_material10.Box,
5177
5205
  {
5178
5206
  component: "a",
5179
5207
  href: "/detection",
@@ -5196,7 +5224,7 @@ function ShufflePipelinesBanner() {
5196
5224
  },
5197
5225
  children: [
5198
5226
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5199
- import_material9.Box,
5227
+ import_material10.Box,
5200
5228
  {
5201
5229
  component: "img",
5202
5230
  src: shuffle_icon_default,
@@ -5204,12 +5232,12 @@ function ShufflePipelinesBanner() {
5204
5232
  sx: { width: 36, height: 36, borderRadius: "10px", flexShrink: 0 }
5205
5233
  }
5206
5234
  ),
5207
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_material9.Box, { sx: { flex: 1, minWidth: 0 }, children: [
5208
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_material9.Typography, { sx: { fontWeight: 700, fontSize: "0.85rem", color: "hsl(var(--foreground))", lineHeight: 1.3 }, children: "Shuffle Pipelines" }),
5209
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_material9.Typography, { sx: { fontSize: "0.72rem", color: "hsl(var(--muted-foreground))", lineHeight: 1.4 }, children: "Do not have a SIEM? Shuffle can ingest, parse, and correlate your logs and events directly \u2014 no external SIEM required." })
5235
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_material10.Box, { sx: { flex: 1, minWidth: 0 }, children: [
5236
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_material10.Typography, { sx: { fontWeight: 700, fontSize: "0.85rem", color: "hsl(var(--foreground))", lineHeight: 1.3 }, children: "Shuffle Pipelines" }),
5237
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_material10.Typography, { sx: { fontSize: "0.72rem", color: "hsl(var(--muted-foreground))", lineHeight: 1.4 }, children: "Do not have a SIEM? Shuffle can ingest, parse, and correlate your logs and events directly \u2014 no external SIEM required." })
5210
5238
  ] }),
5211
5239
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5212
- import_material9.Chip,
5240
+ import_material10.Chip,
5213
5241
  {
5214
5242
  label: "Built-in",
5215
5243
  size: "small",
@@ -5327,16 +5355,19 @@ function AppSearchDrawer({
5327
5355
  pinnedApps
5328
5356
  }) {
5329
5357
  const [detailAppName, setDetailAppName] = (0, import_react10.useState)(null);
5358
+ const [detailAppId, setDetailAppId] = (0, import_react10.useState)(null);
5330
5359
  const handleClose = () => {
5331
5360
  setDetailAppName(null);
5361
+ setDetailAppId(null);
5332
5362
  onClose();
5333
5363
  };
5334
5364
  const handleAppSelected = (detail) => {
5365
+ const algoliaId = detail.app.objectID || null;
5335
5366
  const appInfo = {
5336
5367
  name: detail.app.name,
5337
5368
  icon: detail.app.image_url || "",
5338
5369
  categories: detail.app.categories || [],
5339
- id: detail.app.objectID || null
5370
+ id: algoliaId
5340
5371
  };
5341
5372
  if (onQuickSelect) {
5342
5373
  onQuickSelect(appInfo);
@@ -5347,10 +5378,11 @@ function AppSearchDrawer({
5347
5378
  return;
5348
5379
  }
5349
5380
  setDetailAppName(detail.app.name);
5381
+ setDetailAppId(algoliaId);
5350
5382
  };
5351
5383
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
5352
5384
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
5353
- import_material10.Drawer,
5385
+ import_material11.Drawer,
5354
5386
  {
5355
5387
  anchor,
5356
5388
  open: open && detailAppName === null,
@@ -5360,6 +5392,10 @@ function AppSearchDrawer({
5360
5392
  "& .MuiDrawer-paper": {
5361
5393
  width,
5362
5394
  maxWidth: "100vw",
5395
+ height: "100vh",
5396
+ display: "flex",
5397
+ flexDirection: "column",
5398
+ overflow: "hidden",
5363
5399
  background: "linear-gradient(180deg, hsl(var(--card)) 0%, hsl(var(--background)) 100%)",
5364
5400
  borderLeft: anchor === "right" ? "1px solid hsl(var(--border))" : "none",
5365
5401
  borderRight: anchor === "left" ? "1px solid hsl(var(--border))" : "none"
@@ -5367,7 +5403,7 @@ function AppSearchDrawer({
5367
5403
  },
5368
5404
  children: [
5369
5405
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
5370
- import_material10.Box,
5406
+ import_material11.Box,
5371
5407
  {
5372
5408
  sx: {
5373
5409
  px: 3,
@@ -5379,12 +5415,12 @@ function AppSearchDrawer({
5379
5415
  flexShrink: 0
5380
5416
  },
5381
5417
  children: [
5382
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_material10.Box, { sx: { flex: 1 }, children: [
5383
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material10.Typography, { sx: { color: "hsl(var(--foreground))", fontWeight: 700, fontSize: "1rem", lineHeight: 1.2 }, children: title }),
5384
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material10.Typography, { sx: { color: "hsl(var(--muted-foreground))", fontSize: "0.75rem" }, children: subtitle })
5418
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_material11.Box, { sx: { flex: 1 }, children: [
5419
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material11.Typography, { sx: { color: "hsl(var(--foreground))", fontWeight: 700, fontSize: "1rem", lineHeight: 1.2 }, children: title }),
5420
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material11.Typography, { sx: { color: "hsl(var(--muted-foreground))", fontSize: "0.75rem" }, children: subtitle })
5385
5421
  ] }),
5386
5422
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5387
- import_material10.IconButton,
5423
+ import_material11.IconButton,
5388
5424
  {
5389
5425
  size: "small",
5390
5426
  onClick: handleClose,
@@ -5395,13 +5431,13 @@ function AppSearchDrawer({
5395
5431
  ]
5396
5432
  }
5397
5433
  ),
5398
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_material10.Box, { sx: { flex: 1, overflowY: "auto", p: 3, minHeight: "92vh" }, children: [
5434
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_material11.Box, { sx: { flex: 1, boxSizing: "border-box", overflow: "hidden", p: 3, minHeight: 0, display: "flex", flexDirection: "column" }, children: [
5399
5435
  showPipelinesBanner && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(ShufflePipelinesBanner, {}),
5400
- API_CONFIG.apiKey && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material10.Box, { sx: { mb: 2.5 }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IntegrationStatus, { collapsed: false, showAll: true, hideAddButton: true, priorityCategory }) }),
5401
- connectionPathApps && connectionPathApps.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_material10.Box, { sx: { mb: 2.5 }, children: [
5402
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material10.Typography, { sx: { color: "hsl(var(--muted-foreground))", fontSize: "0.7rem", fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.05em", mb: 1 }, children: "In this usecase" }),
5403
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material10.Box, { sx: { display: "flex", gap: 1.5, flexWrap: "wrap" }, children: connectionPathApps.map((app) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material10.Tooltip, { title: app.name.replace(/_/g, " "), arrow: true, placement: "bottom", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
5404
- import_material10.Box,
5436
+ API_CONFIG.apiKey && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material11.Box, { sx: { mb: 2.5 }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(IntegrationStatus, { collapsed: false, showAll: true, hideAddButton: true, priorityCategory }) }),
5437
+ connectionPathApps && connectionPathApps.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_material11.Box, { sx: { mb: 2.5 }, children: [
5438
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material11.Typography, { sx: { color: "hsl(var(--muted-foreground))", fontSize: "0.7rem", fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.05em", mb: 1 }, children: "In this usecase" }),
5439
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material11.Box, { sx: { display: "flex", gap: 1.5, flexWrap: "wrap" }, children: connectionPathApps.map((app) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material11.Tooltip, { title: app.name.replace(/_/g, " "), arrow: true, placement: "bottom", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
5440
+ import_material11.Box,
5405
5441
  {
5406
5442
  onClick: () => handleAppSelected({ app: { name: app.name, image_url: app.icon, categories: [] } }),
5407
5443
  sx: {
@@ -5412,7 +5448,7 @@ function AppSearchDrawer({
5412
5448
  },
5413
5449
  children: [
5414
5450
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5415
- import_material10.Avatar,
5451
+ import_material11.Avatar,
5416
5452
  {
5417
5453
  src: app.icon,
5418
5454
  alt: app.name,
@@ -5421,7 +5457,7 @@ function AppSearchDrawer({
5421
5457
  }
5422
5458
  ),
5423
5459
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5424
- import_material10.Box,
5460
+ import_material11.Box,
5425
5461
  {
5426
5462
  sx: {
5427
5463
  position: "absolute",
@@ -5439,55 +5475,84 @@ function AppSearchDrawer({
5439
5475
  }
5440
5476
  ) }, app.name)) })
5441
5477
  ] }),
5442
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_framer_motion7.AnimatePresence, { mode: "wait", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5443
- import_framer_motion7.motion.div,
5478
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5479
+ import_material11.Box,
5444
5480
  {
5445
- initial: { opacity: 0, x: -20 },
5446
- animate: { opacity: 1, x: 0 },
5447
- exit: { opacity: 0, x: -20 },
5448
- transition: { duration: 0.2 },
5449
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5450
- ShuffleMCP,
5451
- {
5452
- apiKey: API_CONFIG.apiKey || void 0,
5453
- apiBaseUrl: API_CONFIG.baseUrl,
5454
- placeholder: initialQuery ? `Search ${initialQuery} integrations...` : "Search integrations...",
5455
- layout: "grid",
5456
- gridColumns: 2,
5457
- inline: true,
5458
- initialFilterQuery: initialQuery,
5459
- hitsPerPage: 12,
5460
- showDescription: false,
5461
- showCategories: true,
5462
- showCheckbox: false,
5463
- multiSelect: false,
5464
- preventDefault: true,
5465
- onAppSelected: handleAppSelected,
5466
- pinnedApps: pinnedApps?.map((p) => ({
5467
- name: p.name,
5468
- image_url: p.image_url,
5469
- categories: p.categories || [],
5470
- objectID: p.objectID || `pinned-${p.name}`,
5471
- description: "",
5472
- creator: "",
5473
- app_version: "1.0.0",
5474
- time_edited: 0,
5475
- generated: false,
5476
- invalid: false,
5477
- priority: 0,
5478
- actions: 0,
5479
- tags: [],
5480
- accessible_by: [],
5481
- action_labels: [],
5482
- triggers: [],
5483
- verified: true
5484
- })),
5485
- customStyles: singulStyles
5481
+ sx: {
5482
+ flex: 1,
5483
+ minHeight: 0,
5484
+ overflow: "hidden",
5485
+ "& .singul-container, & .singul-search-bar-container": {
5486
+ height: "100%",
5487
+ minHeight: 0
5488
+ },
5489
+ "& .singul-search-bar-container": {
5490
+ display: "flex",
5491
+ flexDirection: "column"
5492
+ },
5493
+ "& .singul-results-container": {
5494
+ flex: 1,
5495
+ minHeight: 0,
5496
+ maxHeight: "none",
5497
+ overflowY: "auto"
5498
+ },
5499
+ "& .singul-results-grid .singul-dropdown-item": {
5500
+ minHeight: 56,
5501
+ alignItems: "center"
5486
5502
  }
5487
- )
5488
- },
5489
- "search"
5490
- ) })
5503
+ },
5504
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_framer_motion7.AnimatePresence, { mode: "wait", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5505
+ import_framer_motion7.motion.div,
5506
+ {
5507
+ initial: { opacity: 0, x: -20 },
5508
+ animate: { opacity: 1, x: 0 },
5509
+ exit: { opacity: 0, x: -20 },
5510
+ transition: { duration: 0.2 },
5511
+ style: { height: "100%", minHeight: 0 },
5512
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5513
+ ShuffleMCP,
5514
+ {
5515
+ apiKey: API_CONFIG.apiKey || void 0,
5516
+ apiBaseUrl: API_CONFIG.baseUrl,
5517
+ placeholder: initialQuery ? `Search ${initialQuery} integrations...` : "Search integrations...",
5518
+ layout: "grid",
5519
+ gridColumns: 2,
5520
+ inline: true,
5521
+ initialFilterQuery: initialQuery,
5522
+ hitsPerPage: 12,
5523
+ showDescription: false,
5524
+ showCategories: true,
5525
+ showCheckbox: false,
5526
+ multiSelect: false,
5527
+ preventDefault: true,
5528
+ onAppSelected: handleAppSelected,
5529
+ pinnedApps: pinnedApps?.map((p) => ({
5530
+ name: p.name,
5531
+ image_url: p.image_url,
5532
+ categories: p.categories || [],
5533
+ objectID: p.objectID || `pinned-${p.name}`,
5534
+ description: "",
5535
+ creator: "",
5536
+ app_version: "1.0.0",
5537
+ time_edited: 0,
5538
+ generated: false,
5539
+ invalid: false,
5540
+ priority: 0,
5541
+ actions: 0,
5542
+ tags: [],
5543
+ accessible_by: [],
5544
+ action_labels: [],
5545
+ triggers: [],
5546
+ verified: true
5547
+ })),
5548
+ customStyles: singulStyles
5549
+ }
5550
+ )
5551
+ },
5552
+ "search"
5553
+ ) })
5554
+ }
5555
+ )
5491
5556
  ] })
5492
5557
  ]
5493
5558
  }
@@ -5499,9 +5564,11 @@ function AppSearchDrawer({
5499
5564
  onClose: () => {
5500
5565
  const name = detailAppName;
5501
5566
  setDetailAppName(null);
5567
+ setDetailAppId(null);
5502
5568
  if (name) onDetailClose?.(name);
5503
5569
  },
5504
5570
  appName: detailAppName,
5571
+ appId: detailAppId,
5505
5572
  anchor,
5506
5573
  width,
5507
5574
  onRefresh: onClose,
@@ -5511,22 +5578,1966 @@ function AppSearchDrawer({
5511
5578
  ] });
5512
5579
  }
5513
5580
 
5514
- // useAppLookup.ts
5581
+ // AgentUI.tsx
5515
5582
  var import_react11 = require("react");
5516
- var norm = (s) => s.toLowerCase().replace(/[\s_\-]+/g, "_");
5517
- function useAppLookup(appName) {
5518
- const [loading, setLoading] = (0, import_react11.useState)(false);
5519
- const [info, setInfo] = (0, import_react11.useState)(null);
5520
- const [algoliaId, setAlgoliaId] = (0, import_react11.useState)(null);
5521
- const {
5522
- authStates,
5523
- authenticatedApps,
5524
- handleAuthChange,
5525
- handleTestConnection,
5526
- handleSaveAuth,
5527
- refreshAuth
5528
- } = useAppAuth();
5529
- (0, import_react11.useEffect)(() => {
5583
+ var import_react_router_dom2 = require("react-router-dom");
5584
+ var import_material12 = require("@mui/material");
5585
+ var import_Add2 = __toESM(require("@mui/icons-material/Add"), 1);
5586
+ var import_AttachFile = __toESM(require("@mui/icons-material/AttachFile"), 1);
5587
+ var import_CheckCircle3 = __toESM(require("@mui/icons-material/CheckCircle"), 1);
5588
+ var import_Check2 = __toESM(require("@mui/icons-material/Check"), 1);
5589
+ var import_Error = __toESM(require("@mui/icons-material/Error"), 1);
5590
+ var import_HourglassDisabled = __toESM(require("@mui/icons-material/HourglassDisabled"), 1);
5591
+ var import_Pause = __toESM(require("@mui/icons-material/Pause"), 1);
5592
+ var import_PlayArrowRounded2 = __toESM(require("@mui/icons-material/PlayArrowRounded"), 1);
5593
+ var import_Refresh = __toESM(require("@mui/icons-material/Refresh"), 1);
5594
+ var import_RestartAlt2 = __toESM(require("@mui/icons-material/RestartAlt"), 1);
5595
+ var import_ThumbUp = __toESM(require("@mui/icons-material/ThumbUp"), 1);
5596
+ var import_ThumbDown = __toESM(require("@mui/icons-material/ThumbDown"), 1);
5597
+ var import_OpenInNew2 = __toESM(require("@mui/icons-material/OpenInNew"), 1);
5598
+ var import_Send = __toESM(require("@mui/icons-material/Send"), 1);
5599
+ var import_Warning = __toESM(require("@mui/icons-material/Warning"), 1);
5600
+ var import_Close4 = __toESM(require("@mui/icons-material/Close"), 1);
5601
+ var import_react_markdown4 = __toESM(require("react-markdown"), 1);
5602
+ var import_remark_gfm4 = __toESM(require("remark-gfm"), 1);
5603
+ var import_remark_breaks = __toESM(require("remark-breaks"), 1);
5604
+ var import_react18_json_view = __toESM(require("react18-json-view"), 1);
5605
+ var import_style = require("react18-json-view/src/style.css");
5606
+ var import_dark = require("react18-json-view/src/dark.css");
5607
+
5608
+ // agentRun.ts
5609
+ var resolveTarget = (path, opts = {}) => {
5610
+ const url = opts.apiBaseUrl ? `${opts.apiBaseUrl.replace(/\/+$/, "")}${path}` : getApiUrl(path);
5611
+ const headers = opts.apiKey ? { Authorization: `Bearer ${opts.apiKey}` } : { ...getAuthHeader() };
5612
+ if (opts.orgId) headers["Org-Id"] = opts.orgId;
5613
+ return { url, headers };
5614
+ };
5615
+ var parseDataUrl = (dataUrl) => {
5616
+ const match = /^data:([^;]+);base64,(.*)$/.exec(dataUrl);
5617
+ if (!match) return null;
5618
+ return { mimeType: match[1], data: match[2] };
5619
+ };
5620
+ var parseAgentResponse = (data) => {
5621
+ if (typeof data === "string") return data;
5622
+ if (data == null) return "No output returned.";
5623
+ const obj = data;
5624
+ if (obj.result !== void 0) {
5625
+ const result = obj.result;
5626
+ if (typeof result === "string") return result || "No output returned.";
5627
+ if (typeof result === "object" && result !== null) {
5628
+ const r = result;
5629
+ const parts = [];
5630
+ if (r.message && typeof r.message === "string") {
5631
+ parts.push(r.message);
5632
+ }
5633
+ const rest = { ...r };
5634
+ delete rest.message;
5635
+ if (Object.keys(rest).length > 0) {
5636
+ parts.push(JSON.stringify(rest, null, 2));
5637
+ }
5638
+ return parts.join("\n\n") || "No output returned.";
5639
+ }
5640
+ return String(result);
5641
+ }
5642
+ if (obj.message && typeof obj.message === "string") return obj.message;
5643
+ return JSON.stringify(data, null, 2);
5644
+ };
5645
+ var pollExecutionResult = async (executionId, {
5646
+ maxAttempts = 15,
5647
+ intervalMs = 2e3,
5648
+ apiKey,
5649
+ apiBaseUrl,
5650
+ orgId
5651
+ } = {}) => {
5652
+ const { url, headers } = resolveTarget("/api/v1/streams/results", { apiKey, apiBaseUrl, orgId });
5653
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
5654
+ try {
5655
+ const resp = await fetch(url, {
5656
+ method: "POST",
5657
+ credentials: "include",
5658
+ headers: {
5659
+ "Content-Type": "application/json",
5660
+ ...headers
5661
+ },
5662
+ body: JSON.stringify({
5663
+ execution_id: executionId,
5664
+ authorization: executionId
5665
+ })
5666
+ });
5667
+ if (!resp.ok) {
5668
+ if (resp.status >= 400 && resp.status < 500) {
5669
+ return {
5670
+ success: false,
5671
+ content: "",
5672
+ error: `Error ${resp.status}: Could not fetch execution result.`,
5673
+ status: resp.status
5674
+ };
5675
+ }
5676
+ await delay(intervalMs);
5677
+ continue;
5678
+ }
5679
+ const rawText = await resp.text();
5680
+ if (!rawText || rawText === "{}" || rawText === "null") {
5681
+ await delay(intervalMs);
5682
+ continue;
5683
+ }
5684
+ const contentType = resp.headers.get("content-type");
5685
+ if (!contentType?.includes("application/json")) {
5686
+ return { success: true, content: rawText, status: resp.status };
5687
+ }
5688
+ const data = JSON.parse(rawText);
5689
+ if (data?.status === "EXECUTING" || data?.status === "WAITING") {
5690
+ await delay(intervalMs);
5691
+ continue;
5692
+ }
5693
+ const content = parseAgentResponse(data);
5694
+ return {
5695
+ success: true,
5696
+ content,
5697
+ rawData: data,
5698
+ status: resp.status
5699
+ };
5700
+ } catch {
5701
+ await delay(intervalMs);
5702
+ }
5703
+ }
5704
+ return {
5705
+ success: false,
5706
+ content: "",
5707
+ error: `Timed out waiting for execution ${executionId} to complete.`,
5708
+ status: 0
5709
+ };
5710
+ };
5711
+ var delay = (ms) => new Promise((r) => setTimeout(r, ms));
5712
+ var isExecutionStub = (data) => {
5713
+ if (typeof data !== "object" || data === null) return false;
5714
+ const obj = data;
5715
+ return typeof obj.execution_id === "string" && obj.execution_id.length > 0 && // It's a stub if there's no result/message — just metadata
5716
+ obj.result === void 0 && obj.message === void 0;
5717
+ };
5718
+ var runAgent = async (request) => {
5719
+ const input = { text: request.input };
5720
+ const images = [];
5721
+ if (request.images && request.images.length > 0) {
5722
+ images.push(...request.images);
5723
+ } else if (request.image && request.image.length > 0) {
5724
+ const parsed = parseDataUrl(request.image);
5725
+ if (parsed) images.push(parsed);
5726
+ }
5727
+ if (images.length > 0) {
5728
+ input.images = images.map((img) => ({
5729
+ url: `data:${img.mimeType};base64,${img.data}`,
5730
+ detail: "auto"
5731
+ }));
5732
+ }
5733
+ const params = { input };
5734
+ if (request.toolName) params.tool_name = request.toolName;
5735
+ if (request.toolId) params.tool_id = request.toolId;
5736
+ if (request.toolNames && request.toolNames.length > 0) {
5737
+ params.tool_names = request.toolNames;
5738
+ }
5739
+ if (request.toolIds && request.toolIds.length > 0) {
5740
+ params.tool_ids = request.toolIds;
5741
+ }
5742
+ const payload = {
5743
+ jsonrpc: "2.0",
5744
+ id: crypto.randomUUID(),
5745
+ method: "tools/call",
5746
+ params
5747
+ };
5748
+ const { url: agentUrl, headers: agentHeaders } = resolveTarget("/api/v1/agent", {
5749
+ apiKey: request.apiKey,
5750
+ apiBaseUrl: request.apiBaseUrl,
5751
+ orgId: request.orgId
5752
+ });
5753
+ try {
5754
+ const response = await fetch(agentUrl, {
5755
+ method: "POST",
5756
+ credentials: "include",
5757
+ headers: {
5758
+ "Content-Type": "application/json",
5759
+ ...agentHeaders
5760
+ },
5761
+ body: JSON.stringify(payload)
5762
+ });
5763
+ const rawText = await response.text();
5764
+ const contentType = response.headers.get("content-type");
5765
+ if (!response.ok) {
5766
+ return {
5767
+ success: false,
5768
+ content: "",
5769
+ error: `Error ${response.status}: ${rawText || response.statusText}`,
5770
+ status: response.status
5771
+ };
5772
+ }
5773
+ if (!contentType?.includes("application/json")) {
5774
+ if (rawText.trim().startsWith("<!") || rawText.includes("<html")) {
5775
+ return {
5776
+ success: false,
5777
+ content: "",
5778
+ error: "Received an unexpected HTML response. This may indicate an auth redirect or server issue.",
5779
+ status: response.status
5780
+ };
5781
+ }
5782
+ return {
5783
+ success: true,
5784
+ content: rawText,
5785
+ status: response.status
5786
+ };
5787
+ }
5788
+ const data = JSON.parse(rawText);
5789
+ if (isExecutionStub(data)) {
5790
+ if (request.skipPolling) {
5791
+ return {
5792
+ success: true,
5793
+ content: "",
5794
+ rawData: data,
5795
+ status: response.status
5796
+ };
5797
+ }
5798
+ console.log(`[AgentRun] Got execution stub, polling for result: ${data.execution_id}`);
5799
+ return pollExecutionResult(data.execution_id, {
5800
+ apiKey: request.apiKey,
5801
+ apiBaseUrl: request.apiBaseUrl,
5802
+ orgId: request.orgId
5803
+ });
5804
+ }
5805
+ const content = parseAgentResponse(data);
5806
+ return {
5807
+ success: true,
5808
+ content,
5809
+ rawData: data,
5810
+ status: response.status
5811
+ };
5812
+ } catch (err) {
5813
+ return {
5814
+ success: false,
5815
+ content: "",
5816
+ error: `Network error \u2014 could not reach the agent. ${err instanceof Error ? err.message : ""}`,
5817
+ status: 0
5818
+ };
5819
+ }
5820
+ };
5821
+
5822
+ // AgentUI.tsx
5823
+ var import_jsx_runtime14 = require("react/jsx-runtime");
5824
+ var normalizeMarkdown = (raw) => {
5825
+ if (raw == null) return "";
5826
+ let s = typeof raw === "string" ? raw : (() => {
5827
+ try {
5828
+ return JSON.stringify(raw, null, 2);
5829
+ } catch {
5830
+ return String(raw);
5831
+ }
5832
+ })();
5833
+ if (s.length > 1 && s.startsWith('"') && s.endsWith('"')) {
5834
+ try {
5835
+ s = JSON.parse(s);
5836
+ } catch {
5837
+ }
5838
+ }
5839
+ s = s.replace(/\\r\\n/g, "\n").replace(/\\n/g, "\n").replace(/\\t/g, " ").replace(/\\"/g, '"');
5840
+ return s.trim();
5841
+ };
5842
+ var deepParseJsonStrings = (obj, depth = 0) => {
5843
+ if (depth > 5) return obj;
5844
+ if (typeof obj === "string") {
5845
+ const trimmed = obj.trim();
5846
+ if (trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]")) {
5847
+ try {
5848
+ const parsed = JSON.parse(trimmed);
5849
+ if (typeof parsed === "object" && parsed !== null) {
5850
+ return deepParseJsonStrings(parsed, depth + 1);
5851
+ }
5852
+ } catch {
5853
+ }
5854
+ }
5855
+ return obj;
5856
+ }
5857
+ if (Array.isArray(obj)) return obj.map((item) => deepParseJsonStrings(item, depth + 1));
5858
+ if (obj && typeof obj === "object") {
5859
+ const result = {};
5860
+ for (const [key, value] of Object.entries(obj)) {
5861
+ result[key] = deepParseJsonStrings(value, depth + 1);
5862
+ }
5863
+ return result;
5864
+ }
5865
+ return obj;
5866
+ };
5867
+ var validateJson = (raw) => {
5868
+ if (raw == null) return { valid: false, result: null };
5869
+ if (typeof raw === "object") return { valid: true, result: raw };
5870
+ if (typeof raw !== "string") return { valid: false, result: raw };
5871
+ try {
5872
+ return { valid: true, result: JSON.parse(raw) };
5873
+ } catch {
5874
+ return { valid: false, result: raw };
5875
+ }
5876
+ };
5877
+ var STATUS_COLORS = {
5878
+ finished: "hsl(142, 71%, 45%)",
5879
+ warning: "hsl(38, 92%, 50%)",
5880
+ error: "hsl(0, 72%, 55%)",
5881
+ running: "hsl(var(--primary))"
5882
+ };
5883
+ var buildToolName = (apps) => {
5884
+ if (!apps.length) return "API";
5885
+ return apps.map((a) => {
5886
+ const slug = a.name.toLowerCase().replace(/\s+/g, "_").replace(/-/g, "_");
5887
+ return a.id ? `app:${a.id}:${slug}` : slug;
5888
+ }).join(",");
5889
+ };
5890
+ var StatusIcon = ({ status }) => {
5891
+ const s = (status || "").toUpperCase();
5892
+ if (s === "RUNNING" || s === "EXECUTING" || s === "") {
5893
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.CircularProgress, { size: 18, sx: { color: STATUS_COLORS.running } });
5894
+ }
5895
+ if (s === "WAITING") {
5896
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Tooltip, { title: "Waiting for input", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_Pause.default, { sx: { color: STATUS_COLORS.running, fontSize: 20 } }) });
5897
+ }
5898
+ if (s === "FINISHED" || s === "SUCCESS") {
5899
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_CheckCircle3.default, { sx: { color: STATUS_COLORS.finished, fontSize: 20 } });
5900
+ }
5901
+ if (s === "ABORTED" || s === "FAILURE") {
5902
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_Error.default, { sx: { color: STATUS_COLORS.error, fontSize: 20 } });
5903
+ }
5904
+ if (s === "IGNORED" || s === "IGNORE") {
5905
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_Warning.default, { sx: { color: STATUS_COLORS.warning, fontSize: 20 } });
5906
+ }
5907
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_HourglassDisabled.default, { sx: { color: "hsl(var(--muted-foreground))", fontSize: 20 } });
5908
+ };
5909
+ var TimelineRow = ({
5910
+ item,
5911
+ index,
5912
+ open,
5913
+ onToggle,
5914
+ appsById,
5915
+ totalDuration,
5916
+ originalStartTime,
5917
+ maxWidth,
5918
+ questionAnswers,
5919
+ setQuestionAnswers,
5920
+ onSubmitQuestions,
5921
+ onRerunAgent,
5922
+ onRerunDecision,
5923
+ agentRequestLoading,
5924
+ getFormUrl,
5925
+ runFinished
5926
+ }) => {
5927
+ const [submitAttempted, setSubmitAttempted] = (0, import_react11.useState)(false);
5928
+ const validate = validateJson(item.details);
5929
+ const itemStart = item.start_time || 0;
5930
+ const itemEnd = item.end_time || itemStart;
5931
+ const dur = Math.max(0, itemEnd - itemStart);
5932
+ const offset = totalDuration > 0 ? (itemStart - originalStartTime) / totalDuration * maxWidth : 0;
5933
+ const width = totalDuration > 0 ? Math.max(4, dur / totalDuration * maxWidth) : 0;
5934
+ let displayType = item.type;
5935
+ let displayLabel = item.label?.replace(/_/g, " ") || "";
5936
+ const details = item.details;
5937
+ const isProcessing = item.category === "processing";
5938
+ if (isProcessing) {
5939
+ displayType = "processing";
5940
+ } else if (details?.reason) {
5941
+ displayLabel = details.reason;
5942
+ }
5943
+ if (!isProcessing) {
5944
+ if (details?.action === "finish" || item.category === "finish" || details?.action === "finalise") {
5945
+ displayType = "finalise";
5946
+ } else if (item.category === "ask" || details?.action === "ask") {
5947
+ displayType = "question";
5948
+ } else if (details?.action === "add_tool") {
5949
+ displayType = "add tool";
5950
+ }
5951
+ }
5952
+ let toolApp;
5953
+ if (details?.tool && typeof details.tool === "string" && details.tool !== "singul") {
5954
+ let tn = details.tool.toLowerCase().replace(/[\s-]+/g, "_");
5955
+ if (tn.startsWith("app:")) tn = tn.split(":")[2] || tn;
5956
+ toolApp = appsById[tn];
5957
+ }
5958
+ const questions = [];
5959
+ if (item.category === "ask" || details?.action === "ask") {
5960
+ for (const f of details?.fields || []) {
5961
+ if (f.key === "question" && f.value) {
5962
+ questions.push({ question: f.value, index: questions.length + 1 });
5963
+ }
5964
+ }
5965
+ }
5966
+ const questionsAnswered = questions.every(
5967
+ (q) => questionAnswers[q.question]?.value
5968
+ );
5969
+ const effectiveStatus = runFinished && (item.status === "RUNNING" || item.status === "WAITING") ? "IGNORED" : item.status;
5970
+ const barColor = isProcessing ? "hsl(var(--muted-foreground) / 0.45)" : effectiveStatus === "IGNORED" ? STATUS_COLORS.warning : effectiveStatus === "FINISHED" ? STATUS_COLORS.finished : effectiveStatus === "FAILURE" || effectiveStatus === "ABORTED" ? STATUS_COLORS.error : STATUS_COLORS.running;
5971
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Box, { sx: {
5972
+ borderTop: index === 0 ? "none" : "1px solid hsl(var(--border))",
5973
+ bgcolor: open ? "hsl(var(--muted) / 0.3)" : "transparent",
5974
+ transition: "background 0.15s ease"
5975
+ }, children: [
5976
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
5977
+ import_material12.Box,
5978
+ {
5979
+ onClick: onToggle,
5980
+ sx: {
5981
+ display: "flex",
5982
+ alignItems: "center",
5983
+ gap: 1.5,
5984
+ px: 2,
5985
+ py: 1.25,
5986
+ cursor: "pointer",
5987
+ "&:hover": { bgcolor: "hsl(var(--muted) / 0.4)" }
5988
+ },
5989
+ children: [
5990
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: { width: 24, display: "flex", justifyContent: "center" }, children: isProcessing ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: { width: 6, height: 6, borderRadius: "50%", bgcolor: "hsl(var(--muted-foreground) / 0.5)" } }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(StatusIcon, { status: effectiveStatus }) }),
5991
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: { width: 24, display: "flex", justifyContent: "center" }, children: isProcessing ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: { width: 22 } }) : toolApp?.icon ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Avatar, { src: toolApp.icon, sx: { width: 22, height: 22, bgcolor: "transparent" }, variant: "rounded" }) : item.category === "finalise" || details?.action === "finish" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_Check2.default, { sx: { color: STATUS_COLORS.finished, fontSize: 18 } }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: { width: 22 } }) }),
5992
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5993
+ import_material12.Chip,
5994
+ {
5995
+ label: displayType,
5996
+ size: "small",
5997
+ sx: {
5998
+ height: 22,
5999
+ bgcolor: isProcessing ? "transparent" : "hsl(var(--muted))",
6000
+ color: isProcessing ? "hsl(var(--muted-foreground))" : "hsl(var(--foreground))",
6001
+ border: isProcessing ? "1px dashed hsl(var(--border))" : "none",
6002
+ fontSize: "0.7rem",
6003
+ fontWeight: 500,
6004
+ textTransform: "capitalize",
6005
+ minWidth: 80,
6006
+ fontStyle: isProcessing ? "italic" : "normal"
6007
+ }
6008
+ }
6009
+ ),
6010
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: {
6011
+ flex: 1,
6012
+ minWidth: 0,
6013
+ fontSize: "0.85rem",
6014
+ color: "hsl(var(--foreground))",
6015
+ maxHeight: 60,
6016
+ overflow: "hidden",
6017
+ "& p": { margin: 0 },
6018
+ "& pre, & code": { fontSize: "0.78rem" }
6019
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_markdown4.default, { remarkPlugins: [import_remark_gfm4.default, import_remark_breaks.default], children: normalizeMarkdown(displayLabel) }) }),
6020
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Tooltip, { title: `Duration: ${dur.toFixed(1)}s \xB7 ${itemStart ? new Date(itemStart * 1e3).toLocaleString() : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: { width: maxWidth, position: "relative", height: 10, flexShrink: 0 }, children: dur > 0 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: {
6021
+ position: "absolute",
6022
+ left: Math.max(0, offset),
6023
+ width,
6024
+ height: 8,
6025
+ top: 1,
6026
+ bgcolor: barColor,
6027
+ borderRadius: 1,
6028
+ transition: "all 0.2s ease"
6029
+ } }) }) }),
6030
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: { width: 60, fontSize: "0.7rem", color: "hsl(var(--muted-foreground))", textAlign: "right" }, children: dur > 0 ? `${dur.toFixed(1)}s` : "" }),
6031
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
6032
+ import_material12.Box,
6033
+ {
6034
+ sx: { display: "flex", alignItems: "center", gap: 0.25, ml: 1, minWidth: 96, justifyContent: "flex-end" },
6035
+ onClick: (e) => e.stopPropagation(),
6036
+ children: [
6037
+ item.type === "decision" && details?.run_details?.status === "WAITING" && (item.category === "ask" || details?.action === "ask") && questions.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
6038
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Tooltip, { title: "Approve this step", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6039
+ import_material12.IconButton,
6040
+ {
6041
+ size: "small",
6042
+ disabled: agentRequestLoading,
6043
+ onClick: () => {
6044
+ if (details?.run_details?.id) onSubmitQuestions(details.run_details.id, { approve: "true" });
6045
+ },
6046
+ sx: { color: STATUS_COLORS.finished },
6047
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ThumbUp.default, { sx: { fontSize: 16 } })
6048
+ }
6049
+ ) }) }),
6050
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Tooltip, { title: "Deny this step", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6051
+ import_material12.IconButton,
6052
+ {
6053
+ size: "small",
6054
+ disabled: agentRequestLoading,
6055
+ onClick: () => {
6056
+ if (details?.run_details?.id) onSubmitQuestions(details.run_details.id, { approve: "false" });
6057
+ },
6058
+ sx: { color: STATUS_COLORS.error },
6059
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ThumbDown.default, { sx: { fontSize: 16 } })
6060
+ }
6061
+ ) }) })
6062
+ ] }),
6063
+ item.type === "agent" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Tooltip, { title: "Rerun the agent with the same input", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6064
+ import_material12.IconButton,
6065
+ {
6066
+ size: "small",
6067
+ disabled: agentRequestLoading,
6068
+ onClick: onRerunAgent,
6069
+ sx: { color: "hsl(var(--muted-foreground))", "&:hover": { color: "hsl(var(--primary))" } },
6070
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_RestartAlt2.default, { sx: { fontSize: 16 } })
6071
+ }
6072
+ ) }) }),
6073
+ item.type === "decision" && (() => {
6074
+ const action = details?.action;
6075
+ const cat = item.category;
6076
+ const isApiAction = action !== "ask" && cat !== "ask" && action !== "finish" && action !== "finalise" && cat !== "finish" && cat !== "finalise" && cat !== "processing" && action !== "add_tool";
6077
+ if (!isApiAction) return null;
6078
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Tooltip, { title: "Rerun from this decision (clears all decisions after it)", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6079
+ import_material12.IconButton,
6080
+ {
6081
+ size: "small",
6082
+ disabled: agentRequestLoading || !details?.run_details?.id,
6083
+ onClick: () => details && onRerunDecision(details),
6084
+ sx: { color: "hsl(var(--muted-foreground))", "&:hover": { color: "hsl(var(--primary))" } },
6085
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_RestartAlt2.default, { sx: { fontSize: 16 } })
6086
+ }
6087
+ ) }) });
6088
+ })(),
6089
+ item.type === "decision" && details?.run_details?.debug_url && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Tooltip, { title: "Open debug URL", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6090
+ import_material12.IconButton,
6091
+ {
6092
+ size: "small",
6093
+ onClick: () => window.open(details.run_details.debug_url, "_blank", "noopener,noreferrer"),
6094
+ sx: { color: "hsl(var(--muted-foreground))", "&:hover": { color: "hsl(var(--primary))" } },
6095
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_OpenInNew2.default, { sx: { fontSize: 16 } })
6096
+ }
6097
+ ) }) })
6098
+ ]
6099
+ }
6100
+ )
6101
+ ]
6102
+ }
6103
+ ),
6104
+ questions.length > 0 && !runFinished && (item.status === "RUNNING" || item.status === "WAITING") && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: { px: 4, pb: 2 }, children: (() => {
6105
+ const trySubmit = () => {
6106
+ if (agentRequestLoading) return;
6107
+ if (!questionsAnswered) {
6108
+ setSubmitAttempted(true);
6109
+ return;
6110
+ }
6111
+ if (details?.run_details?.id) {
6112
+ onSubmitQuestions(details.run_details.id, questionAnswers);
6113
+ }
6114
+ };
6115
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
6116
+ questions.map((q, qi) => {
6117
+ const value = questionAnswers[q.question]?.value || "";
6118
+ const isMissing = submitAttempted && !value;
6119
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Box, { sx: { mt: 2 }, children: [
6120
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: { fontSize: "0.85rem", color: "hsl(var(--foreground))", mb: 1 }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_markdown4.default, { remarkPlugins: [import_remark_gfm4.default, import_remark_breaks.default], children: normalizeMarkdown(q.question) }) }),
6121
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6122
+ import_material12.TextField,
6123
+ {
6124
+ fullWidth: true,
6125
+ multiline: true,
6126
+ minRows: 2,
6127
+ placeholder: "Your answer here\u2026",
6128
+ value,
6129
+ error: isMissing,
6130
+ helperText: isMissing ? "Please answer this question" : void 0,
6131
+ onChange: (e) => {
6132
+ const v = e.target.value;
6133
+ setQuestionAnswers((prev) => ({
6134
+ ...prev,
6135
+ [q.question]: { index: qi, value: v }
6136
+ }));
6137
+ },
6138
+ onKeyDown: (e) => {
6139
+ if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
6140
+ e.preventDefault();
6141
+ trySubmit();
6142
+ }
6143
+ },
6144
+ size: "small",
6145
+ sx: {
6146
+ "& .MuiOutlinedInput-root": { bgcolor: "hsl(var(--card))" }
6147
+ }
6148
+ }
6149
+ )
6150
+ ] }, qi);
6151
+ }),
6152
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Box, { sx: { display: "flex", alignItems: "center", gap: 1, mt: 2 }, children: [
6153
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6154
+ import_material12.Button,
6155
+ {
6156
+ variant: "contained",
6157
+ size: "small",
6158
+ disabled: agentRequestLoading,
6159
+ onClick: trySubmit,
6160
+ children: agentRequestLoading ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.CircularProgress, { size: 16 }) : "Submit"
6161
+ }
6162
+ ),
6163
+ details?.run_details?.id && getFormUrl && getFormUrl(details.run_details.id) && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Tooltip, { title: "Answer in the Form UI", placement: "right", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6164
+ import_material12.IconButton,
6165
+ {
6166
+ size: "small",
6167
+ onClick: () => {
6168
+ const url = getFormUrl(details.run_details.id);
6169
+ if (url) window.open(url, "_blank", "noopener,noreferrer");
6170
+ },
6171
+ sx: { color: "hsl(var(--muted-foreground))", "&:hover": { color: "hsl(var(--primary))" } },
6172
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_OpenInNew2.default, { sx: { fontSize: 18 } })
6173
+ }
6174
+ ) })
6175
+ ] })
6176
+ ] });
6177
+ })() }),
6178
+ open && runFinished && questions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Box, { sx: { px: 4, pb: 2 }, children: [
6179
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Typography, { sx: { fontSize: "0.7rem", textTransform: "uppercase", letterSpacing: 0.5, color: "hsl(var(--muted-foreground))", mb: 1 }, children: questions.length === 1 ? "Question (unanswered)" : "Questions (unanswered)" }),
6180
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: {
6181
+ p: 2,
6182
+ borderRadius: 1.5,
6183
+ border: "1px solid hsl(var(--border))",
6184
+ bgcolor: "hsl(var(--background))",
6185
+ display: "flex",
6186
+ flexDirection: "column",
6187
+ gap: 1.5
6188
+ }, children: questions.map((q, qi) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: { fontSize: "0.85rem", color: "hsl(var(--foreground))", "& p": { my: 0.5 } }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_markdown4.default, { remarkPlugins: [import_remark_gfm4.default, import_remark_breaks.default], children: normalizeMarkdown(q.question) }) }, qi)) })
6189
+ ] }),
6190
+ open && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: { px: 4, pb: 2 }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6191
+ import_material12.Box,
6192
+ {
6193
+ sx: {
6194
+ p: 2,
6195
+ borderRadius: 1.5,
6196
+ border: "1px solid hsl(var(--border))",
6197
+ bgcolor: "hsl(var(--background))",
6198
+ overflow: "auto",
6199
+ maxHeight: 400,
6200
+ fontFamily: '"JetBrains Mono", ui-monospace, monospace',
6201
+ "& .json-view": {
6202
+ fontSize: "0.72rem !important",
6203
+ fontFamily: "inherit !important",
6204
+ bgcolor: "transparent !important"
6205
+ }
6206
+ },
6207
+ children: validate.valid && validate.result && typeof validate.result === "object" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6208
+ import_react18_json_view.default,
6209
+ {
6210
+ src: deepParseJsonStrings(validate.result),
6211
+ dark: true,
6212
+ collapsed: 2,
6213
+ collapseStringMode: "word",
6214
+ collapseStringsAfterLength: 120,
6215
+ enableClipboard: true,
6216
+ displaySize: true
6217
+ }
6218
+ ) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { component: "pre", sx: { m: 0, fontSize: "0.72rem", color: "hsl(var(--foreground))" }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("code", { children: String(item.details ?? "") }) })
6219
+ }
6220
+ ) })
6221
+ ] });
6222
+ };
6223
+ var AgentUI = ({
6224
+ apps,
6225
+ defaultApps,
6226
+ autoLoadApps = true,
6227
+ title = "What do you want to do?",
6228
+ subtitle,
6229
+ placeholder = 'Describe a task, e.g. "Get my emails for today and summarise them"',
6230
+ defaultInput = "",
6231
+ autoSubmit = false,
6232
+ hideHeroIcon = false,
6233
+ heroIcon,
6234
+ heroIconSize = 84,
6235
+ maxWidth = 900,
6236
+ compact = false,
6237
+ hideAppPicker = false,
6238
+ hideAttach = false,
6239
+ appPickerLabel = "Select Apps / MCPs",
6240
+ appPickerTitle = "Select Apps / MCPs",
6241
+ appPickerSubtitle = "Pick the tools the agent is allowed to use for this run",
6242
+ submitTooltip = "\u2318+Enter to send",
6243
+ submitIcon,
6244
+ continuationPlaceholder = "Add more details to continue this task\u2026",
6245
+ readUrlParams = true,
6246
+ executionId,
6247
+ authorization,
6248
+ onRun,
6249
+ apiKey,
6250
+ apiBaseUrl,
6251
+ orgId
6252
+ }) => {
6253
+ const resolveUrl = (0, import_react11.useCallback)(
6254
+ (path) => apiBaseUrl ? `${apiBaseUrl.replace(/\/+$/, "")}${path}` : getApiUrl(path),
6255
+ [apiBaseUrl]
6256
+ );
6257
+ const resolveHeaders = (0, import_react11.useCallback)(() => {
6258
+ const h = apiKey ? { Authorization: `Bearer ${apiKey}` } : { ...getAuthHeader() };
6259
+ if (orgId) h["Org-Id"] = orgId;
6260
+ return h;
6261
+ }, [apiKey, orgId]);
6262
+ const hasApiKey = !!apiKey || !!API_CONFIG.apiKey;
6263
+ const navigate = (0, import_react_router_dom2.useNavigate)();
6264
+ const [actionInput, setActionInput] = (0, import_react11.useState)(defaultInput);
6265
+ const BUILTIN_DEFAULT_APPS = [
6266
+ { name: "http" },
6267
+ { name: "shuffle_tools" }
6268
+ ];
6269
+ const [chosenApps, setChosenApps] = (0, import_react11.useState)(apps ?? defaultApps ?? BUILTIN_DEFAULT_APPS);
6270
+ const [availableApps, setAvailableApps] = (0, import_react11.useState)([]);
6271
+ const [appSearchOpen, setAppSearchOpen] = (0, import_react11.useState)(false);
6272
+ const [agentRequestLoading, setAgentRequestLoading] = (0, import_react11.useState)(false);
6273
+ const [execution, setExecution] = (0, import_react11.useState)(null);
6274
+ const [agentData, setAgentData] = (0, import_react11.useState)({});
6275
+ const [agentActionResult, setAgentActionResult] = (0, import_react11.useState)(null);
6276
+ const [showStarter, setShowStarter] = (0, import_react11.useState)(true);
6277
+ const [openIndexes, setOpenIndexes] = (0, import_react11.useState)(/* @__PURE__ */ new Set());
6278
+ const [questionAnswers, setQuestionAnswers] = (0, import_react11.useState)({});
6279
+ const [simpleSubmitAttempted, setSimpleSubmitAttempted] = (0, import_react11.useState)(false);
6280
+ const [continuationText, setContinuationText] = (0, import_react11.useState)("");
6281
+ const [error, setError] = (0, import_react11.useState)(null);
6282
+ const [viewMode, setViewMode] = (0, import_react11.useState)("simple");
6283
+ const [attachedImages, setAttachedImages] = (0, import_react11.useState)([]);
6284
+ const [nowTick, setNowTick] = (0, import_react11.useState)(() => Math.floor(Date.now() / 1e3));
6285
+ const [localRunStart, setLocalRunStart] = (0, import_react11.useState)(null);
6286
+ const inputRef = (0, import_react11.useRef)(null);
6287
+ const fileInputRef = (0, import_react11.useRef)(null);
6288
+ const activeExecutionIdRef = (0, import_react11.useRef)(null);
6289
+ const stateRef = (0, import_react11.useRef)({
6290
+ execution: null,
6291
+ agentData: {},
6292
+ agentActionResult: null,
6293
+ openIndexes: /* @__PURE__ */ new Set(),
6294
+ questionAnswers: {},
6295
+ continuationText: "",
6296
+ localRunStart: null,
6297
+ showStarter: true
6298
+ });
6299
+ stateRef.current.execution = execution;
6300
+ stateRef.current.agentData = agentData;
6301
+ stateRef.current.agentActionResult = agentActionResult;
6302
+ stateRef.current.openIndexes = openIndexes;
6303
+ stateRef.current.questionAnswers = questionAnswers;
6304
+ stateRef.current.continuationText = continuationText;
6305
+ stateRef.current.localRunStart = localRunStart;
6306
+ stateRef.current.showStarter = showStarter;
6307
+ (0, import_react11.useEffect)(() => {
6308
+ if (execution?.execution_id) {
6309
+ setLocalRunStart((prev) => prev ?? Math.floor(Date.now() / 1e3));
6310
+ } else if (!agentRequestLoading) {
6311
+ setLocalRunStart(null);
6312
+ }
6313
+ }, [execution?.execution_id, agentRequestLoading]);
6314
+ (0, import_react11.useEffect)(() => {
6315
+ const status = (execution?.status || agentData?.status || "").toUpperCase();
6316
+ const TERMINAL = ["FINISHED", "FAILURE", "ABORTED", "CANCELLED", "CANCELED"];
6317
+ if (TERMINAL.includes(status)) return;
6318
+ if (!execution?.execution_id && !agentRequestLoading && !localRunStart) return;
6319
+ const id = setInterval(() => setNowTick(Math.floor(Date.now() / 1e3)), 1e3);
6320
+ return () => clearInterval(id);
6321
+ }, [execution?.execution_id, execution?.status, agentData?.status, agentRequestLoading, localRunStart]);
6322
+ const readImageAsDataUrl = (file) => new Promise((resolve) => {
6323
+ if (!file.type.startsWith("image/")) {
6324
+ resolve(null);
6325
+ return;
6326
+ }
6327
+ const reader = new FileReader();
6328
+ reader.onload = () => {
6329
+ const result = reader.result;
6330
+ resolve(typeof result === "string" ? { dataUrl: result, name: file.name || "Pasted image" } : null);
6331
+ };
6332
+ reader.onerror = () => resolve(null);
6333
+ reader.readAsDataURL(file);
6334
+ });
6335
+ const handleImagesSelected = async (files) => {
6336
+ if (!files) return;
6337
+ const arr = Array.from(files);
6338
+ const nonImages = arr.some((f) => !f.type.startsWith("image/"));
6339
+ if (nonImages) setError("Only image files can be attached.");
6340
+ const results = await Promise.all(arr.map(readImageAsDataUrl));
6341
+ const valid = results.filter((r) => r !== null);
6342
+ if (valid.length > 0) {
6343
+ setAttachedImages((prev) => [...prev, ...valid]);
6344
+ setError(null);
6345
+ }
6346
+ };
6347
+ const appsById = (0, import_react11.useMemo)(() => {
6348
+ const m = {};
6349
+ for (const a of chosenApps) {
6350
+ const slug = a.name.toLowerCase().replace(/\s+/g, "_").replace(/-/g, "_");
6351
+ m[slug] = a;
6352
+ }
6353
+ return m;
6354
+ }, [chosenApps]);
6355
+ (0, import_react11.useEffect)(() => {
6356
+ if (apps) setChosenApps(apps);
6357
+ }, [apps]);
6358
+ (0, import_react11.useEffect)(() => {
6359
+ const missing = chosenApps.filter((a) => !a.icon && a.name);
6360
+ if (missing.length === 0) return;
6361
+ let cancelled = false;
6362
+ const norm2 = (n) => n.toLowerCase().replace(/[\s_\-]+/g, "_");
6363
+ (async () => {
6364
+ const resolved = {};
6365
+ try {
6366
+ const { algoliasearch: algoliasearch2 } = await import("algoliasearch");
6367
+ const client = algoliasearch2("JNSS5CFDZZ", "33e4e3564f4f060e96e0531957bed552");
6368
+ await Promise.all(missing.map(async (a) => {
6369
+ const known = availableApps.find((x) => norm2(x.name) === norm2(a.name));
6370
+ if (known?.icon) {
6371
+ resolved[a.name] = known.icon;
6372
+ return;
6373
+ }
6374
+ try {
6375
+ const res = await client.searchSingleIndex({
6376
+ indexName: "appsearch",
6377
+ searchParams: { query: a.name.replace(/_/g, " "), hitsPerPage: 3 }
6378
+ });
6379
+ const match = res.hits.find((h) => norm2(h.name || "") === norm2(a.name)) || res.hits[0];
6380
+ if (match?.image_url) resolved[a.name] = match.image_url;
6381
+ } catch {
6382
+ }
6383
+ }));
6384
+ } catch {
6385
+ }
6386
+ const stillMissing = missing.filter((a) => !resolved[a.name]);
6387
+ if (stillMissing.length > 0) {
6388
+ try {
6389
+ const res = await fetch(resolveUrl("/api/v1/apps"), {
6390
+ credentials: "include",
6391
+ headers: { ...resolveHeaders() }
6392
+ });
6393
+ if (res.ok) {
6394
+ const apps2 = await res.json();
6395
+ if (Array.isArray(apps2)) {
6396
+ for (const a of stillMissing) {
6397
+ const m = apps2.find((x) => norm2(x.name || "") === norm2(a.name));
6398
+ const img = m?.large_image || m?.image_url || m?.image;
6399
+ if (img) resolved[a.name] = img;
6400
+ }
6401
+ }
6402
+ }
6403
+ } catch {
6404
+ }
6405
+ }
6406
+ if (cancelled) return;
6407
+ setChosenApps((prev) => prev.map((a) => {
6408
+ if (a.icon) return a;
6409
+ const icon = resolved[a.name];
6410
+ return icon ? { ...a, icon } : a;
6411
+ }));
6412
+ })();
6413
+ return () => {
6414
+ cancelled = true;
6415
+ };
6416
+ }, [chosenApps, availableApps, resolveUrl, resolveHeaders]);
6417
+ (0, import_react11.useEffect)(() => {
6418
+ if (!autoLoadApps) return;
6419
+ if (apps || defaultApps) return;
6420
+ if (!hasApiKey) return;
6421
+ let cancelled = false;
6422
+ (async () => {
6423
+ try {
6424
+ const resp = await fetch(resolveUrl("/api/v1/apps/authentication"), {
6425
+ credentials: "include",
6426
+ headers: { ...resolveHeaders() }
6427
+ });
6428
+ if (!resp.ok) return;
6429
+ const result = await resp.json();
6430
+ const list = Array.isArray(result) ? result : result?.data || [];
6431
+ const seen = /* @__PURE__ */ new Set();
6432
+ const loaded = [];
6433
+ for (const entry of list) {
6434
+ const app = entry?.app || entry;
6435
+ const name = app?.name;
6436
+ if (!name) continue;
6437
+ const valid = entry?.active || entry?.validation?.valid || entry?.hasValidAuth;
6438
+ if (valid === false) continue;
6439
+ const key = name.toLowerCase();
6440
+ if (seen.has(key)) continue;
6441
+ seen.add(key);
6442
+ loaded.push({
6443
+ name,
6444
+ id: app?.id || entry?.id,
6445
+ icon: app?.large_image || app?.image_url || app?.image || entry?.bestImage || ""
6446
+ });
6447
+ }
6448
+ if (!cancelled && loaded.length) setAvailableApps(loaded);
6449
+ } catch {
6450
+ }
6451
+ })();
6452
+ return () => {
6453
+ cancelled = true;
6454
+ };
6455
+ }, [autoLoadApps, apps, defaultApps, hasApiKey, resolveUrl, resolveHeaders]);
6456
+ const getExecution = (0, import_react11.useCallback)(async (executionId2, authorization2) => {
6457
+ if (!executionId2 || !authorization2) return;
6458
+ try {
6459
+ const resp = await fetch(resolveUrl("/api/v1/streams/results"), {
6460
+ method: "POST",
6461
+ credentials: "include",
6462
+ headers: { "Content-Type": "application/json", ...resolveHeaders() },
6463
+ body: JSON.stringify({ execution_id: executionId2, authorization: authorization2 })
6464
+ });
6465
+ if (activeExecutionIdRef.current && activeExecutionIdRef.current !== executionId2) return;
6466
+ if (!resp.ok) {
6467
+ setError(`Could not fetch execution (${resp.status}).`);
6468
+ return;
6469
+ }
6470
+ const json = await resp.json();
6471
+ if (activeExecutionIdRef.current && activeExecutionIdRef.current !== executionId2) return;
6472
+ if (json?.success === false) {
6473
+ setError(json.reason || "Failed to load agent data.");
6474
+ return;
6475
+ }
6476
+ setExecution({ ...json, execution_id: executionId2, authorization: authorization2 });
6477
+ let actionResult = null;
6478
+ if (Array.isArray(json?.results)) {
6479
+ actionResult = json.results.find((r) => r?.action?.app_name === "AI Agent") || json.results[0];
6480
+ } else {
6481
+ actionResult = json;
6482
+ }
6483
+ setAgentActionResult(actionResult);
6484
+ const v = validateJson(actionResult?.result);
6485
+ if (v.valid) setAgentData({ ...v.result, started_at: json.started_at, completed_at: json.completed_at, status: json.status });
6486
+ setError(null);
6487
+ } catch (err) {
6488
+ setError(err instanceof Error ? err.message : "Network error.");
6489
+ }
6490
+ }, []);
6491
+ (0, import_react11.useEffect)(() => {
6492
+ let eid = null;
6493
+ let auth = null;
6494
+ if (executionId && authorization) {
6495
+ eid = executionId;
6496
+ auth = authorization;
6497
+ } else if (readUrlParams) {
6498
+ const params = new URLSearchParams(window.location.search);
6499
+ eid = params.get("execution_id");
6500
+ auth = params.get("authorization");
6501
+ }
6502
+ if (eid && auth) {
6503
+ setShowStarter(false);
6504
+ activeExecutionIdRef.current = eid;
6505
+ setExecution({ execution_id: eid, authorization: auth, status: "EXECUTING" });
6506
+ getExecution(eid, auth);
6507
+ }
6508
+ }, [readUrlParams, executionId, authorization, getExecution]);
6509
+ (0, import_react11.useEffect)(() => {
6510
+ if (!execution?.execution_id || !execution?.authorization) return;
6511
+ const status = (execution.status || "").toUpperCase();
6512
+ const TERMINAL = ["FINISHED", "FAILURE", "ABORTED", "CANCELLED", "CANCELED"];
6513
+ if (TERMINAL.includes(status)) return;
6514
+ const id = setInterval(() => {
6515
+ getExecution(execution.execution_id, execution.authorization);
6516
+ }, 3e3);
6517
+ return () => clearInterval(id);
6518
+ }, [execution?.execution_id, execution?.authorization, execution?.status, getExecution]);
6519
+ const submitInput = (0, import_react11.useCallback)(async (text) => {
6520
+ if (!text.trim()) return;
6521
+ setError(null);
6522
+ setAgentRequestLoading(true);
6523
+ const prevExecution = stateRef.current.execution;
6524
+ const prevAgentData = stateRef.current.agentData;
6525
+ const prevAgentActionResult = stateRef.current.agentActionResult;
6526
+ const prevOpenIndexes = stateRef.current.openIndexes;
6527
+ const prevQuestionAnswers = stateRef.current.questionAnswers;
6528
+ const prevContinuationText = stateRef.current.continuationText;
6529
+ const prevLocalRunStart = stateRef.current.localRunStart;
6530
+ const prevActiveExecutionId = activeExecutionIdRef.current;
6531
+ const prevShowStarter = stateRef.current.showStarter;
6532
+ const result = await runAgent({
6533
+ input: text.trim(),
6534
+ skipPolling: true,
6535
+ ...apiKey ? { apiKey } : {},
6536
+ ...apiBaseUrl ? { apiBaseUrl } : {},
6537
+ ...orgId ? { orgId } : {},
6538
+ // Send a single comma-separated `tool_name` in the format
6539
+ // `app:<objectID>:<slug>,app:<objectID>:<slug>` so the backend resolves
6540
+ // the exact app versions instead of guessing by slug.
6541
+ ...chosenApps.length > 0 ? { toolName: buildToolName(chosenApps) } : {},
6542
+ ...attachedImages.length > 0 ? { images: attachedImages.map((img) => {
6543
+ const m = /^data:([^;]+);base64,(.*)$/.exec(img.dataUrl);
6544
+ return m ? { mimeType: m[1], data: m[2], name: img.name } : { mimeType: "image/png", data: img.dataUrl, name: img.name };
6545
+ }) } : {}
6546
+ });
6547
+ setAgentRequestLoading(false);
6548
+ if (!result.success) {
6549
+ setError(result.error || "Agent run failed.");
6550
+ activeExecutionIdRef.current = prevActiveExecutionId;
6551
+ setExecution(prevExecution);
6552
+ setAgentData(prevAgentData);
6553
+ setAgentActionResult(prevAgentActionResult);
6554
+ setOpenIndexes(prevOpenIndexes);
6555
+ setQuestionAnswers(prevQuestionAnswers);
6556
+ setContinuationText(prevContinuationText);
6557
+ setLocalRunStart(prevLocalRunStart);
6558
+ setShowStarter(prevShowStarter);
6559
+ onRun?.({ input: text, success: false, error: result.error });
6560
+ return;
6561
+ }
6562
+ const browserStart = Math.floor(Date.now() / 1e3);
6563
+ setShowStarter(false);
6564
+ activeExecutionIdRef.current = null;
6565
+ setExecution(null);
6566
+ setAgentActionResult(null);
6567
+ setOpenIndexes(/* @__PURE__ */ new Set());
6568
+ setQuestionAnswers({});
6569
+ setContinuationText("");
6570
+ setNowTick(browserStart);
6571
+ setLocalRunStart(browserStart);
6572
+ setAgentData({ original_input: text.trim() });
6573
+ if (readUrlParams && typeof window !== "undefined") {
6574
+ try {
6575
+ const url = new URL(window.location.href);
6576
+ url.searchParams.delete("execution_id");
6577
+ url.searchParams.delete("authorization");
6578
+ window.history.replaceState({}, "", url.toString());
6579
+ } catch {
6580
+ }
6581
+ }
6582
+ const raw = result.rawData;
6583
+ const eid = raw?.execution_id;
6584
+ const auth = raw?.authorization;
6585
+ if (eid && auth) {
6586
+ activeExecutionIdRef.current = eid;
6587
+ setExecution({ execution_id: eid, authorization: auth, status: "EXECUTING" });
6588
+ if (readUrlParams && typeof window !== "undefined") {
6589
+ try {
6590
+ const url = new URL(window.location.href);
6591
+ url.searchParams.set("execution_id", eid);
6592
+ url.searchParams.set("authorization", auth);
6593
+ window.history.replaceState({}, "", url.toString());
6594
+ } catch {
6595
+ }
6596
+ }
6597
+ getExecution(eid, auth);
6598
+ onRun?.({ input: text, success: true, executionId: eid });
6599
+ } else {
6600
+ setExecution({
6601
+ execution_id: eid || crypto.randomUUID(),
6602
+ authorization: auth,
6603
+ status: "FINISHED",
6604
+ results: [{ action: { app_name: "AI Agent" }, result: raw }]
6605
+ });
6606
+ const v = validateJson(raw);
6607
+ if (v.valid) {
6608
+ setAgentData({ ...v.result, status: "FINISHED", original_input: text });
6609
+ } else {
6610
+ setAgentData({ original_input: text, status: "FINISHED", message: result.content });
6611
+ }
6612
+ onRun?.({ input: text, success: true, executionId: eid });
6613
+ }
6614
+ }, [chosenApps, getExecution, onRun, attachedImages, readUrlParams]);
6615
+ const autoSubmittedRef = (0, import_react11.useRef)(false);
6616
+ (0, import_react11.useEffect)(() => {
6617
+ if (autoSubmit && defaultInput && !autoSubmittedRef.current && !executionId) {
6618
+ autoSubmittedRef.current = true;
6619
+ submitInput(defaultInput);
6620
+ }
6621
+ }, [autoSubmit, defaultInput, executionId, submitInput]);
6622
+ const submitQuestions = (0, import_react11.useCallback)(async (decisionId, answers, isContinuation) => {
6623
+ if (!execution?.execution_id || !execution?.authorization) return;
6624
+ let newArgument = {};
6625
+ if (isContinuation) {
6626
+ newArgument = { ...answers };
6627
+ } else {
6628
+ for (const k in answers) {
6629
+ if (k === "approve") {
6630
+ newArgument[k] = answers[k];
6631
+ break;
6632
+ }
6633
+ const a = answers[k];
6634
+ newArgument[`question_${a.index}`] = a.value;
6635
+ }
6636
+ }
6637
+ setAgentRequestLoading(true);
6638
+ const wfId = execution.workflow?.id || execution.execution_id;
6639
+ const params = new URLSearchParams({
6640
+ reference_execution: execution.execution_id,
6641
+ authorization: execution.authorization,
6642
+ answer: "true",
6643
+ note: JSON.stringify(newArgument),
6644
+ agentic: "true",
6645
+ decision_id: decisionId
6646
+ });
6647
+ try {
6648
+ const resp = await fetch(resolveUrl(`/api/v1/workflows/${wfId}/run?${params.toString()}`), {
6649
+ method: "GET",
6650
+ credentials: "include",
6651
+ headers: { ...resolveHeaders() }
6652
+ });
6653
+ const json = await resp.json();
6654
+ if (json.success === false) {
6655
+ toast({ title: "Failed to submit", description: json.reason || "Try again later.", variant: "destructive" });
6656
+ } else {
6657
+ toast({ title: "Submitted", description: "Agent will continue shortly." });
6658
+ setQuestionAnswers({});
6659
+ setContinuationText("");
6660
+ setTimeout(() => {
6661
+ getExecution(execution.execution_id, execution.authorization);
6662
+ }, 600);
6663
+ }
6664
+ } catch (err) {
6665
+ toast({ title: "Network error", description: String(err), variant: "destructive" });
6666
+ } finally {
6667
+ setAgentRequestLoading(false);
6668
+ }
6669
+ }, [execution, getExecution]);
6670
+ const rerunAgent = (0, import_react11.useCallback)(() => {
6671
+ const input = agentData?.original_input || actionInput || (() => {
6672
+ const msgs = agentData?.input?.messages || [];
6673
+ const m = msgs.find((m2) => m2?.role === "user" && !String(m2?.role).includes("USER CONTEXT"));
6674
+ return m?.content || "";
6675
+ })();
6676
+ if (!input) {
6677
+ toast({ title: "Nothing to rerun", description: "No original input found for this execution.", variant: "destructive" });
6678
+ return;
6679
+ }
6680
+ setActionInput(input);
6681
+ submitInput(input);
6682
+ }, [agentData, actionInput, submitInput]);
6683
+ const getFormUrl = (0, import_react11.useCallback)((decisionId) => {
6684
+ const wfId = execution?.workflow?.id;
6685
+ const auth = execution?.authorization;
6686
+ const execId = execution?.execution_id;
6687
+ const sourceNode = agentActionResult?.action?.id;
6688
+ if (!wfId || !auth || !execId || !sourceNode || !decisionId) return null;
6689
+ const backend = apiBaseUrl || (typeof window !== "undefined" ? window.location.origin : "");
6690
+ const params = new URLSearchParams({
6691
+ authorization: auth,
6692
+ reference_execution: execId,
6693
+ source_node: sourceNode,
6694
+ decision_id: decisionId,
6695
+ ...backend ? { backend_url: backend } : {}
6696
+ });
6697
+ return `/forms/${wfId}?${params.toString()}`;
6698
+ }, [execution, agentActionResult, apiBaseUrl]);
6699
+ const rerunDecision = (0, import_react11.useCallback)(async (decision) => {
6700
+ if (!execution?.execution_id) {
6701
+ toast({ title: "No execution loaded", description: "Cannot rerun this decision.", variant: "destructive" });
6702
+ return;
6703
+ }
6704
+ if (!agentActionResult?.action) {
6705
+ toast({ title: "Missing action context", description: "Could not locate the agent action node.", variant: "destructive" });
6706
+ return;
6707
+ }
6708
+ const decisionId = decision?.run_details?.id;
6709
+ if (!decisionId) {
6710
+ toast({ title: "Missing decision id", description: "This decision cannot be rerun.", variant: "destructive" });
6711
+ return;
6712
+ }
6713
+ const body = { ...agentActionResult.action };
6714
+ body.source_execution = execution.execution_id;
6715
+ body.source_workflow = execution.workflow?.id;
6716
+ setAgentRequestLoading(true);
6717
+ try {
6718
+ const resp = await fetch(resolveUrl(`/api/v1/apps/agent/run?rerun=true&decision_id=${encodeURIComponent(decisionId)}`), {
6719
+ method: "POST",
6720
+ credentials: "include",
6721
+ headers: { "Content-Type": "application/json", ...resolveHeaders() },
6722
+ body: JSON.stringify(body)
6723
+ });
6724
+ const json = await resp.json().catch(() => ({}));
6725
+ if (json?.success === false) {
6726
+ toast({ title: "Rerun failed", description: json.reason || "Try again later.", variant: "destructive" });
6727
+ } else {
6728
+ toast({ title: "Rerunning decision", description: "The agent will continue from this step." });
6729
+ setTimeout(() => getExecution(execution.execution_id, execution.authorization), 800);
6730
+ setTimeout(() => getExecution(execution.execution_id, execution.authorization), 5e3);
6731
+ }
6732
+ } catch (err) {
6733
+ toast({ title: "Network error", description: String(err), variant: "destructive" });
6734
+ } finally {
6735
+ setAgentRequestLoading(false);
6736
+ }
6737
+ }, [execution, agentActionResult, getExecution]);
6738
+ const { timeline, originalStartTime, totalDuration, finishDecisionId, finishAnswer } = (0, import_react11.useMemo)(() => {
6739
+ const toSec = (t) => {
6740
+ const n = Number(t) || 0;
6741
+ return n > 1e12 ? Math.floor(n / 1e3) : n;
6742
+ };
6743
+ const overallStatus = (execution?.status || agentData?.status || "").toUpperCase();
6744
+ const runIsFinished = ["FINISHED", "FAILURE", "ABORTED", "CANCELLED", "CANCELED"].includes(overallStatus);
6745
+ const runEndSec = toSec(agentData?.completed_at || execution?.completed_at);
6746
+ let fallbackEnd = Math.floor(Date.now() / 1e3);
6747
+ if (runIsFinished) {
6748
+ let maxKnown = runEndSec || 0;
6749
+ for (const dec of agentData?.decisions || []) {
6750
+ const rd = dec.run_details || {};
6751
+ maxKnown = Math.max(maxKnown, toSec(rd.completed_at), toSec(rd.started_at));
6752
+ }
6753
+ fallbackEnd = maxKnown || fallbackEnd;
6754
+ }
6755
+ const items = [
6756
+ {
6757
+ label: "AI Agent",
6758
+ type: "agent",
6759
+ category: "agent",
6760
+ details: agentData,
6761
+ status: execution?.status || agentData?.status,
6762
+ start_time: toSec(agentData?.started_at || execution?.started_at),
6763
+ end_time: toSec(agentData?.completed_at || execution?.completed_at)
6764
+ }
6765
+ ];
6766
+ let finishId = "";
6767
+ let finishAns = "";
6768
+ for (const dec of agentData?.decisions || []) {
6769
+ const rd = dec.run_details || {};
6770
+ items.push({
6771
+ label: dec.action,
6772
+ type: "decision",
6773
+ category: dec.category,
6774
+ status: rd.status,
6775
+ start_time: toSec(rd.started_at) || 0,
6776
+ end_time: toSec(rd.completed_at) || fallbackEnd,
6777
+ details: dec
6778
+ });
6779
+ if (dec.action === "finish" || dec.category === "finish" || dec.details?.action === "finalise" || dec.action === "finalise") {
6780
+ finishId = rd.id || "";
6781
+ finishAns = dec.reason || "";
6782
+ if (Array.isArray(dec.fields) && dec.fields.length > 0) {
6783
+ finishAns = dec.fields[0]?.value || finishAns;
6784
+ }
6785
+ }
6786
+ }
6787
+ items.sort((a, b) => (a.start_time || 0) - (b.start_time || 0));
6788
+ const decisionItems = items.filter((it) => it.type === "decision");
6789
+ const runStart = items.find((it) => it.type === "agent")?.start_time || 0;
6790
+ const processingRows = [];
6791
+ let prevEnd = runStart;
6792
+ for (const dec of decisionItems) {
6793
+ const decStart = dec.start_time || 0;
6794
+ const gap = decStart - prevEnd;
6795
+ if (prevEnd > 0 && decStart > 0 && gap >= 0.5) {
6796
+ processingRows.push({
6797
+ label: "Thinking",
6798
+ type: "decision",
6799
+ category: "processing",
6800
+ status: "FINISHED",
6801
+ start_time: prevEnd,
6802
+ end_time: decStart,
6803
+ details: void 0
6804
+ });
6805
+ }
6806
+ prevEnd = dec.end_time || decStart;
6807
+ }
6808
+ items.push(...processingRows);
6809
+ items.sort((a, b) => (a.start_time || 0) - (b.start_time || 0));
6810
+ const start = items.reduce((acc, it) => Math.min(acc, it.start_time || acc), Infinity);
6811
+ const end = items.reduce((acc, it) => Math.max(acc, it.end_time || acc), 0);
6812
+ const startSafe = start === Infinity ? 0 : start;
6813
+ const total = Math.max(1, end - startSafe);
6814
+ return { timeline: items, originalStartTime: startSafe, totalDuration: total, finishDecisionId: finishId, finishAnswer: finishAns };
6815
+ }, [agentData, execution?.status, execution?.started_at, execution?.completed_at]);
6816
+ const toggleOpen = (i) => setOpenIndexes((prev) => {
6817
+ const next = new Set(prev);
6818
+ if (next.has(i)) next.delete(i);
6819
+ else next.add(i);
6820
+ return next;
6821
+ });
6822
+ const onKeyDown = (e) => {
6823
+ if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
6824
+ e.preventDefault();
6825
+ submitInput(actionInput);
6826
+ }
6827
+ };
6828
+ const activeTab = showStarter ? "start" : viewMode;
6829
+ const hasExecution = !!execution?.execution_id;
6830
+ const showRunSwitcher = hasExecution || agentRequestLoading;
6831
+ const goToTab = (t) => {
6832
+ if (t === "start") {
6833
+ setShowStarter(true);
6834
+ } else {
6835
+ setShowStarter(false);
6836
+ setViewMode(t);
6837
+ }
6838
+ };
6839
+ const tabBar = /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Box, { sx: {
6840
+ display: "flex",
6841
+ alignItems: "center",
6842
+ gap: 1.5,
6843
+ p: 1,
6844
+ borderRadius: 999,
6845
+ border: "1px solid hsl(var(--border))",
6846
+ bgcolor: "hsl(var(--card))",
6847
+ width: "fit-content",
6848
+ alignSelf: "center"
6849
+ }, children: [
6850
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: { display: "inline-flex", gap: 0.25, p: 0.25, borderRadius: 999, bgcolor: "hsl(var(--muted) / 0.6)" }, children: ["start", "simple", "detailed"].map((t) => {
6851
+ const active = activeTab === t;
6852
+ const label = t === "start" ? "Start" : t === "simple" ? "Simple" : "Detailed";
6853
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6854
+ import_material12.Box,
6855
+ {
6856
+ component: "button",
6857
+ type: "button",
6858
+ onClick: () => goToTab(t),
6859
+ sx: {
6860
+ all: "unset",
6861
+ cursor: "pointer",
6862
+ px: 1.75,
6863
+ py: 0.5,
6864
+ borderRadius: 999,
6865
+ fontSize: "0.8rem",
6866
+ fontWeight: 600,
6867
+ color: active ? "hsl(var(--primary-foreground))" : "hsl(var(--muted-foreground))",
6868
+ bgcolor: active ? "hsl(var(--primary))" : "transparent",
6869
+ transition: "background 0.12s ease, color 0.12s ease",
6870
+ "&:hover": active ? {} : { color: "hsl(var(--foreground))", bgcolor: "hsl(var(--muted))" }
6871
+ },
6872
+ children: label
6873
+ },
6874
+ t
6875
+ );
6876
+ }) }),
6877
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Tooltip, { title: "Reload execution data", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6878
+ import_material12.IconButton,
6879
+ {
6880
+ size: "small",
6881
+ onClick: () => execution?.execution_id && execution?.authorization && getExecution(execution.execution_id, execution.authorization),
6882
+ disabled: !hasExecution,
6883
+ sx: {
6884
+ width: 30,
6885
+ height: 30,
6886
+ color: "hsl(var(--muted-foreground))",
6887
+ "&:hover": { color: "hsl(var(--foreground))", bgcolor: "hsl(var(--muted))" }
6888
+ },
6889
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_Refresh.default, { sx: { fontSize: 16 } })
6890
+ }
6891
+ ) }) })
6892
+ ] });
6893
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: { width: "100%", display: "flex", justifyContent: "center", pb: 4 }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Box, { sx: { width: "100%", maxWidth, display: "flex", flexDirection: "column", gap: 3 }, children: [
6894
+ showRunSwitcher && tabBar,
6895
+ showStarter ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
6896
+ import_material12.Box,
6897
+ {
6898
+ component: "form",
6899
+ onSubmit: (e) => {
6900
+ e.preventDefault();
6901
+ submitInput(actionInput);
6902
+ },
6903
+ sx: { display: "flex", flexDirection: "column", alignItems: "center", gap: compact ? 2 : 3, py: compact ? 2 : 4 },
6904
+ children: [
6905
+ !hideHeroIcon && !compact && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: {
6906
+ width: heroIconSize,
6907
+ height: heroIconSize,
6908
+ borderRadius: 3,
6909
+ bgcolor: "hsl(var(--card))",
6910
+ border: "1px solid hsl(var(--border))",
6911
+ display: "flex",
6912
+ alignItems: "center",
6913
+ justifyContent: "center",
6914
+ boxShadow: "0 8px 24px rgba(0,0,0,0.25)"
6915
+ }, children: heroIcon ?? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(AgentIcon_default, { size: Math.round(heroIconSize * 0.67) }) }),
6916
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Typography, { component: "h1", sx: {
6917
+ fontSize: compact ? { xs: "1.25rem", md: "1.5rem" } : { xs: "1.75rem", md: "2.25rem" },
6918
+ fontWeight: 600,
6919
+ color: "hsl(var(--foreground))",
6920
+ textAlign: "center",
6921
+ letterSpacing: "-0.01em"
6922
+ }, children: title }),
6923
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Typography, { sx: {
6924
+ fontSize: "0.95rem",
6925
+ color: "hsl(var(--muted-foreground))",
6926
+ textAlign: "center",
6927
+ mt: -1,
6928
+ maxWidth: 600
6929
+ }, children: subtitle }),
6930
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Box, { sx: {
6931
+ width: "100%",
6932
+ display: "flex",
6933
+ flexDirection: "column",
6934
+ gap: 1,
6935
+ borderRadius: attachedImages.length > 0 ? 4 : 999,
6936
+ border: "1.5px solid hsl(var(--border))",
6937
+ bgcolor: "hsl(var(--card))",
6938
+ px: 3,
6939
+ py: 1.75,
6940
+ transition: "border-color 0.15s ease, box-shadow 0.15s ease, border-radius 0.15s ease",
6941
+ "&:focus-within": {
6942
+ borderColor: "hsl(var(--primary))",
6943
+ boxShadow: "0 0 0 3px hsla(var(--primary) / 0.12)"
6944
+ }
6945
+ }, children: [
6946
+ attachedImages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: { display: "flex", flexWrap: "wrap", gap: 0.75 }, children: attachedImages.map((img, idx) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Box, { sx: {
6947
+ display: "inline-flex",
6948
+ alignItems: "center",
6949
+ gap: 1,
6950
+ p: 0.5,
6951
+ pr: 1,
6952
+ borderRadius: 1.5,
6953
+ border: "1px solid hsl(var(--border))",
6954
+ bgcolor: "hsl(var(--background))",
6955
+ maxWidth: "100%"
6956
+ }, children: [
6957
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { component: "img", src: img.dataUrl, alt: img.name, sx: { width: 32, height: 32, borderRadius: 1, objectFit: "cover", flexShrink: 0 } }),
6958
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Typography, { sx: { fontSize: "0.72rem", color: "hsl(var(--foreground))", maxWidth: 190, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: img.name }),
6959
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.IconButton, { size: "small", onClick: () => setAttachedImages((prev) => prev.filter((_, i) => i !== idx)), sx: { p: 0.25, color: "hsl(var(--muted-foreground))", "&:hover": { color: "hsl(var(--destructive))" } }, "aria-label": "Remove attached image", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_Close4.default, { sx: { fontSize: 12 } }) })
6960
+ ] }, `${img.name}-${idx}`)) }),
6961
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Box, { sx: { display: "flex", alignItems: "flex-end", gap: 1, width: "100%" }, children: [
6962
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6963
+ import_material12.InputBase,
6964
+ {
6965
+ inputRef,
6966
+ autoFocus: true,
6967
+ multiline: true,
6968
+ minRows: 1,
6969
+ maxRows: 6,
6970
+ fullWidth: true,
6971
+ value: actionInput,
6972
+ onChange: (e) => setActionInput(e.target.value),
6973
+ placeholder,
6974
+ onKeyDown,
6975
+ onPaste: (e) => {
6976
+ const items = e.clipboardData?.items;
6977
+ if (!items) return;
6978
+ const files = [];
6979
+ for (const item of Array.from(items)) {
6980
+ if (item.kind === "file" && item.type.startsWith("image/")) {
6981
+ const file = item.getAsFile();
6982
+ if (file) files.push(file);
6983
+ }
6984
+ }
6985
+ if (files.length > 0) {
6986
+ e.preventDefault();
6987
+ handleImagesSelected(files);
6988
+ }
6989
+ },
6990
+ disabled: agentRequestLoading,
6991
+ sx: {
6992
+ fontSize: "1rem",
6993
+ color: "hsl(var(--foreground))",
6994
+ "& textarea::placeholder": { color: "hsl(var(--muted-foreground))", opacity: 0.7 }
6995
+ }
6996
+ }
6997
+ ),
6998
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
6999
+ "input",
7000
+ {
7001
+ ref: fileInputRef,
7002
+ type: "file",
7003
+ accept: "image/*",
7004
+ multiple: true,
7005
+ style: { display: "none" },
7006
+ onChange: (e) => {
7007
+ handleImagesSelected(e.target.files);
7008
+ if (e.target) e.target.value = "";
7009
+ }
7010
+ }
7011
+ ),
7012
+ !hideAttach && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7013
+ import_material12.IconButton,
7014
+ {
7015
+ type: "button",
7016
+ onClick: () => fileInputRef.current?.click(),
7017
+ disabled: agentRequestLoading,
7018
+ title: attachedImages.length > 0 ? `Add image (${attachedImages.length} attached)` : "Attach image",
7019
+ sx: {
7020
+ width: 36,
7021
+ height: 36,
7022
+ color: attachedImages.length > 0 ? "hsl(var(--primary))" : "hsl(var(--muted-foreground))",
7023
+ bgcolor: attachedImages.length > 0 ? "hsla(var(--primary) / 0.1)" : "transparent",
7024
+ "&:hover": { color: "hsl(var(--foreground))", bgcolor: "hsl(var(--muted))" }
7025
+ },
7026
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_AttachFile.default, { sx: { fontSize: 18 } })
7027
+ }
7028
+ ),
7029
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Tooltip, { title: submitTooltip, placement: "top", arrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7030
+ import_material12.IconButton,
7031
+ {
7032
+ type: "submit",
7033
+ disabled: actionInput.trim().length < 3 || agentRequestLoading,
7034
+ sx: {
7035
+ width: 36,
7036
+ height: 36,
7037
+ bgcolor: actionInput.trim().length >= 3 ? "hsl(var(--primary))" : "hsl(var(--muted))",
7038
+ color: actionInput.trim().length >= 3 ? "hsl(var(--primary-foreground))" : "hsl(var(--muted-foreground))",
7039
+ "&:hover": actionInput.trim().length >= 3 ? { filter: "brightness(1.1)", bgcolor: "hsl(var(--primary))" } : {},
7040
+ "&.Mui-disabled": { bgcolor: "hsl(var(--muted))", color: "hsl(var(--muted-foreground))" }
7041
+ },
7042
+ children: agentRequestLoading ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.CircularProgress, { size: 16, sx: { color: "inherit" } }) : submitIcon ?? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_PlayArrowRounded2.default, {})
7043
+ }
7044
+ ) }) })
7045
+ ] })
7046
+ ] }),
7047
+ !hideAppPicker && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: { display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Box, { sx: {
7048
+ display: "inline-flex",
7049
+ flexWrap: "wrap",
7050
+ alignItems: "center",
7051
+ gap: 0.5,
7052
+ p: 0.5,
7053
+ borderRadius: 999,
7054
+ border: "1px solid hsl(var(--border))",
7055
+ bgcolor: "hsl(var(--card))",
7056
+ maxWidth: "100%"
7057
+ }, children: [
7058
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
7059
+ import_material12.Box,
7060
+ {
7061
+ component: "button",
7062
+ type: "button",
7063
+ onClick: () => setAppSearchOpen(true),
7064
+ sx: {
7065
+ all: "unset",
7066
+ cursor: "pointer",
7067
+ display: "inline-flex",
7068
+ alignItems: "center",
7069
+ gap: 0.5,
7070
+ px: 1.5,
7071
+ py: 0.5,
7072
+ borderRadius: 999,
7073
+ fontSize: "0.8rem",
7074
+ fontWeight: 500,
7075
+ color: "hsl(var(--muted-foreground))",
7076
+ bgcolor: "transparent",
7077
+ transition: "color 0.12s ease, background-color 0.12s ease",
7078
+ "&:hover": { color: "hsl(var(--foreground))", bgcolor: "hsl(var(--muted) / 0.5)" }
7079
+ },
7080
+ children: [
7081
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_Add2.default, { sx: { fontSize: 14 } }),
7082
+ appPickerLabel
7083
+ ]
7084
+ }
7085
+ ),
7086
+ chosenApps.map((app, i) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
7087
+ import_material12.Box,
7088
+ {
7089
+ sx: {
7090
+ display: "inline-flex",
7091
+ alignItems: "center",
7092
+ gap: 0.5,
7093
+ pl: 0.5,
7094
+ pr: 0.75,
7095
+ py: 0.25,
7096
+ borderRadius: 999,
7097
+ bgcolor: "hsl(var(--muted) / 0.6)",
7098
+ fontSize: "0.8rem",
7099
+ color: "hsl(var(--foreground))"
7100
+ },
7101
+ children: [
7102
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7103
+ import_material12.Avatar,
7104
+ {
7105
+ src: app.icon || void 0,
7106
+ alt: app.name,
7107
+ variant: "rounded",
7108
+ sx: { width: 18, height: 18, bgcolor: "transparent" }
7109
+ }
7110
+ ),
7111
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Typography, { sx: { fontSize: "0.8rem", mx: 0.25, textTransform: "capitalize" }, children: app.name.replace(/_/g, " ") }),
7112
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7113
+ import_material12.IconButton,
7114
+ {
7115
+ size: "small",
7116
+ onClick: () => setChosenApps((prev) => prev.filter((_, idx) => idx !== i)),
7117
+ sx: { p: 0.125, color: "hsl(var(--muted-foreground))", "&:hover": { color: "hsl(var(--destructive))" } },
7118
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_Close4.default, { sx: { fontSize: 12 } })
7119
+ }
7120
+ )
7121
+ ]
7122
+ },
7123
+ `${app.name}-${i}`
7124
+ ))
7125
+ ] }) }),
7126
+ error && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: {
7127
+ width: "100%",
7128
+ p: 1.5,
7129
+ borderRadius: 1.5,
7130
+ border: "1px solid hsl(var(--destructive) / 0.4)",
7131
+ bgcolor: "hsl(var(--destructive) / 0.08)",
7132
+ color: "hsl(var(--destructive))",
7133
+ fontSize: "0.85rem"
7134
+ }, children: error })
7135
+ ]
7136
+ }
7137
+ ) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Box, { children: [
7138
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Box, { sx: {
7139
+ display: "flex",
7140
+ alignItems: "center",
7141
+ gap: 2,
7142
+ p: 2,
7143
+ borderRadius: 2,
7144
+ border: "1px solid hsl(var(--border))",
7145
+ bgcolor: "hsl(var(--card))",
7146
+ mb: 2
7147
+ }, children: [
7148
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Box, { sx: { flex: 1, minWidth: 0 }, children: [
7149
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Typography, { sx: { fontSize: "0.85rem", color: "hsl(var(--foreground))", fontWeight: 600, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: agentData?.original_input || actionInput || "Agent run" }),
7150
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Typography, { sx: { fontSize: "0.7rem", color: "hsl(var(--muted-foreground))" }, children: [
7151
+ "Status: ",
7152
+ execution?.status || agentData?.status || "\u2014",
7153
+ " \xB7 ",
7154
+ execution?.execution_id?.slice(0, 8) || ""
7155
+ ] })
7156
+ ] }),
7157
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.AvatarGroup, { max: 6, sx: { "& .MuiAvatar-root": { width: 28, height: 28, borderColor: "hsl(var(--border))" } }, children: chosenApps.map((app, i) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Tooltip, { title: app.name.replace(/_/g, " "), children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7158
+ import_material12.Avatar,
7159
+ {
7160
+ src: app.icon || void 0,
7161
+ alt: app.name,
7162
+ variant: "rounded",
7163
+ onClick: () => navigate(`/apps/${encodeURIComponent(app.name.toLowerCase().replace(/\s+/g, "_"))}`),
7164
+ sx: {
7165
+ bgcolor: "hsl(var(--muted))",
7166
+ cursor: "pointer",
7167
+ transition: "transform 0.15s ease, border-color 0.15s ease",
7168
+ "&:hover": { transform: "scale(1.08)", borderColor: "hsl(var(--primary)) !important" }
7169
+ }
7170
+ }
7171
+ ) }, i)) })
7172
+ ] }),
7173
+ error && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: {
7174
+ p: 1.5,
7175
+ borderRadius: 1.5,
7176
+ mb: 2,
7177
+ border: "1px solid hsl(var(--destructive) / 0.4)",
7178
+ bgcolor: "hsl(var(--destructive) / 0.08)",
7179
+ color: "hsl(var(--destructive))",
7180
+ fontSize: "0.85rem"
7181
+ }, children: error }),
7182
+ viewMode === "simple" && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: {
7183
+ borderRadius: 2,
7184
+ border: "1px solid hsl(var(--border))",
7185
+ bgcolor: "hsl(var(--card))",
7186
+ p: 2.5,
7187
+ display: "flex",
7188
+ flexDirection: "column",
7189
+ gap: 1.5
7190
+ }, children: (() => {
7191
+ const status = (execution?.status || agentData?.status || "EXECUTING").toUpperCase();
7192
+ const decisionCount = (agentData?.decisions || []).length;
7193
+ const isRunning = !["FINISHED", "FAILURE", "ABORTED", "CANCELLED", "CANCELED"].includes(status);
7194
+ const rawStartedAt = agentData?.started_at || execution?.started_at || 0;
7195
+ const startedAtSec = rawStartedAt > 1e12 ? Math.floor(rawStartedAt / 1e3) : rawStartedAt;
7196
+ const effectiveStart = startedAtSec || localRunStart || 0;
7197
+ let durationSec = null;
7198
+ if (isRunning && effectiveStart) {
7199
+ durationSec = Math.max(0, nowTick - effectiveStart);
7200
+ } else if (totalDuration && totalDuration > 0) {
7201
+ durationSec = Math.round(totalDuration);
7202
+ }
7203
+ const pendingAsk = (agentData?.decisions || []).slice().reverse().find((d) => {
7204
+ const isAsk = d.category === "ask" || d.action === "ask";
7205
+ const st = (d.run_details?.status || "").toUpperCase();
7206
+ return isAsk && (st === "RUNNING" || st === "WAITING");
7207
+ });
7208
+ const pendingQuestions = [];
7209
+ if (pendingAsk) {
7210
+ for (const f of pendingAsk.fields || []) {
7211
+ if (f.key === "question" && f.value) {
7212
+ pendingQuestions.push({ question: f.value, index: pendingQuestions.length + 1 });
7213
+ }
7214
+ }
7215
+ }
7216
+ const pendingAnswered = pendingQuestions.every((q) => questionAnswers[q.question]?.value);
7217
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
7218
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Box, { sx: { display: "flex", alignItems: "center", gap: 1, flexWrap: "wrap" }, children: [
7219
+ isRunning ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.CircularProgress, { size: 16, sx: { color: "hsl(var(--primary))" } }) : status === "FINISHED" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_CheckCircle3.default, { sx: { fontSize: 18, color: "hsl(142 70% 45%)" } }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_Error.default, { sx: { fontSize: 18, color: "hsl(var(--destructive))" } }),
7220
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Typography, { sx: { fontSize: "0.9rem", fontWeight: 600, color: "hsl(var(--foreground))" }, children: isRunning ? "Agent is working\u2026" : status === "FINISHED" ? "Run finished" : `Run ${status.toLowerCase()}` }),
7221
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Typography, { sx: { fontSize: "0.75rem", color: "hsl(var(--muted-foreground))" }, children: [
7222
+ decisionCount,
7223
+ " step",
7224
+ decisionCount === 1 ? "" : "s",
7225
+ durationSec != null ? ` \xB7 ${durationSec}s` : ""
7226
+ ] })
7227
+ ] }),
7228
+ finishAnswer ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: {
7229
+ p: 2,
7230
+ borderRadius: 1.5,
7231
+ border: "1px solid hsl(var(--border))",
7232
+ bgcolor: "hsl(var(--background))",
7233
+ fontSize: "0.9rem",
7234
+ color: "hsl(var(--foreground))",
7235
+ "& > *:first-of-type": { mt: 0 },
7236
+ "& > *:last-child": { mb: 0 },
7237
+ "& p": { my: 1, lineHeight: 1.55 },
7238
+ "& h1, & h2, & h3, & h4": { mt: 2, mb: 1, fontWeight: 600, lineHeight: 1.3 },
7239
+ "& h1": { fontSize: "1.15rem" },
7240
+ "& h2": { fontSize: "1.05rem" },
7241
+ "& h3, & h4": { fontSize: "0.95rem" },
7242
+ "& ul": { my: 1, pl: 3, listStyleType: "disc", listStylePosition: "outside" },
7243
+ "& ol": { my: 1, pl: 3, listStyleType: "decimal", listStylePosition: "outside" },
7244
+ "& ul ul": { listStyleType: "circle" },
7245
+ "& ul ul ul": { listStyleType: "square" },
7246
+ "& li": { my: 0.25, display: "list-item" },
7247
+ "& li::marker": { color: "hsl(var(--muted-foreground))" },
7248
+ "& a": { color: "hsl(var(--primary))", textDecoration: "underline" },
7249
+ "& code": {
7250
+ px: 0.5,
7251
+ py: 0.125,
7252
+ borderRadius: 0.5,
7253
+ bgcolor: "hsl(var(--muted))",
7254
+ fontFamily: '"JetBrains Mono", ui-monospace, monospace',
7255
+ fontSize: "0.82em"
7256
+ },
7257
+ "& pre": {
7258
+ p: 1.5,
7259
+ my: 1,
7260
+ borderRadius: 1,
7261
+ bgcolor: "hsl(var(--muted))",
7262
+ overflowX: "auto",
7263
+ fontSize: "0.82rem"
7264
+ },
7265
+ "& pre code": { p: 0, bgcolor: "transparent" },
7266
+ "& blockquote": {
7267
+ borderLeft: "3px solid hsl(var(--border))",
7268
+ pl: 1.5,
7269
+ my: 1,
7270
+ color: "hsl(var(--muted-foreground))"
7271
+ },
7272
+ "& table": { borderCollapse: "collapse", my: 1, fontSize: "0.85rem" },
7273
+ "& th, & td": { border: "1px solid hsl(var(--border))", px: 1, py: 0.5 },
7274
+ "& hr": { border: 0, borderTop: "1px solid hsl(var(--border))", my: 1.5 }
7275
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_markdown4.default, { remarkPlugins: [import_remark_gfm4.default, import_remark_breaks.default], children: normalizeMarkdown(finishAnswer) }) }) : pendingAsk && pendingQuestions.length > 0 ? (() => {
7276
+ const trySimpleSubmit = () => {
7277
+ if (agentRequestLoading) return;
7278
+ if (!pendingAnswered) {
7279
+ setSimpleSubmitAttempted(true);
7280
+ return;
7281
+ }
7282
+ if (pendingAsk.run_details?.id) {
7283
+ submitQuestions(pendingAsk.run_details.id, questionAnswers);
7284
+ }
7285
+ };
7286
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Box, { sx: { display: "flex", flexDirection: "column", gap: 1.5 }, children: [
7287
+ pendingQuestions.map((q, qi) => {
7288
+ const value = questionAnswers[q.question]?.value || "";
7289
+ const isMissing = simpleSubmitAttempted && !value;
7290
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Box, { children: [
7291
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: { fontSize: "0.9rem", color: "hsl(var(--foreground))", mb: 1, "& p": { my: 0.5 } }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_markdown4.default, { remarkPlugins: [import_remark_gfm4.default, import_remark_breaks.default], children: normalizeMarkdown(q.question) }) }),
7292
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7293
+ import_material12.TextField,
7294
+ {
7295
+ fullWidth: true,
7296
+ multiline: true,
7297
+ minRows: 2,
7298
+ placeholder: "Your answer here\u2026",
7299
+ value,
7300
+ error: isMissing,
7301
+ helperText: isMissing ? "Please answer this question" : void 0,
7302
+ onChange: (e) => {
7303
+ const v = e.target.value;
7304
+ setQuestionAnswers((prev) => ({
7305
+ ...prev,
7306
+ [q.question]: { index: qi, value: v }
7307
+ }));
7308
+ },
7309
+ onKeyDown: (e) => {
7310
+ if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
7311
+ e.preventDefault();
7312
+ trySimpleSubmit();
7313
+ }
7314
+ },
7315
+ size: "small",
7316
+ sx: { "& .MuiOutlinedInput-root": { bgcolor: "hsl(var(--background))" } }
7317
+ }
7318
+ )
7319
+ ] }, qi);
7320
+ }),
7321
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
7322
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7323
+ import_material12.Button,
7324
+ {
7325
+ variant: "contained",
7326
+ size: "small",
7327
+ disabled: agentRequestLoading,
7328
+ onClick: trySimpleSubmit,
7329
+ children: agentRequestLoading ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.CircularProgress, { size: 16 }) : "Submit"
7330
+ }
7331
+ ),
7332
+ pendingAsk.run_details?.id && getFormUrl(pendingAsk.run_details.id) && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Tooltip, { title: "Answer in the Form UI", placement: "right", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7333
+ import_material12.IconButton,
7334
+ {
7335
+ size: "small",
7336
+ onClick: () => {
7337
+ const url = getFormUrl(pendingAsk.run_details.id);
7338
+ if (url) window.open(url, "_blank", "noopener,noreferrer");
7339
+ },
7340
+ sx: { color: "hsl(var(--muted-foreground))", "&:hover": { color: "hsl(var(--primary))" } },
7341
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_OpenInNew2.default, { sx: { fontSize: 18 } })
7342
+ }
7343
+ ) })
7344
+ ] })
7345
+ ] });
7346
+ })() : isRunning ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Typography, { sx: { fontSize: "0.85rem", color: "hsl(var(--muted-foreground))" }, children: "Waiting for the agent to produce the first step." }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Typography, { sx: { fontSize: "0.85rem", color: "hsl(var(--muted-foreground))" }, children: "No final answer was returned. Open Detailed to inspect each step." }),
7347
+ !isRunning && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7348
+ import_material12.Button,
7349
+ {
7350
+ size: "small",
7351
+ variant: "text",
7352
+ onClick: () => setViewMode("detailed"),
7353
+ sx: { color: "hsl(var(--primary))", textTransform: "none", px: 0 },
7354
+ children: "View detailed timeline \u2192"
7355
+ }
7356
+ ) })
7357
+ ] });
7358
+ })() }),
7359
+ viewMode === "detailed" && (() => {
7360
+ const detailedStatus = (execution?.status || agentData?.status || "EXECUTING").toUpperCase();
7361
+ const detailedIsRunning = !["FINISHED", "FAILURE", "ABORTED", "CANCELLED", "CANCELED"].includes(detailedStatus);
7362
+ const detailedRunFinished = !detailedIsRunning;
7363
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: {
7364
+ borderRadius: 2,
7365
+ border: "1px solid hsl(var(--border))",
7366
+ bgcolor: "hsl(var(--card))",
7367
+ overflow: "hidden"
7368
+ }, children: timeline.length === 0 || timeline.length === 1 && agentRequestLoading ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Box, { sx: { p: 4, textAlign: "center", color: "hsl(var(--muted-foreground))", fontSize: "0.85rem" }, children: [
7369
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.CircularProgress, { size: 20, sx: { mb: 1 } }),
7370
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Typography, { sx: { fontSize: "0.85rem" }, children: "Waiting for agent response\u2026" })
7371
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
7372
+ timeline.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7373
+ TimelineRow,
7374
+ {
7375
+ item,
7376
+ index: i,
7377
+ open: openIndexes.has(i),
7378
+ onToggle: () => toggleOpen(i),
7379
+ appsById,
7380
+ totalDuration,
7381
+ originalStartTime,
7382
+ maxWidth: 260,
7383
+ questionAnswers,
7384
+ setQuestionAnswers,
7385
+ onSubmitQuestions: submitQuestions,
7386
+ onRerunAgent: rerunAgent,
7387
+ onRerunDecision: rerunDecision,
7388
+ agentRequestLoading,
7389
+ getFormUrl,
7390
+ runFinished: detailedRunFinished
7391
+ },
7392
+ i
7393
+ )),
7394
+ detailedRunFinished && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Box, { sx: {
7395
+ borderTop: "1px solid hsl(var(--border))",
7396
+ p: 2.5,
7397
+ display: "flex",
7398
+ flexDirection: "column",
7399
+ gap: 1.5,
7400
+ bgcolor: "hsl(var(--muted) / 0.2)"
7401
+ }, children: [
7402
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Box, { sx: { display: "flex", alignItems: "center", gap: 1, flexWrap: "wrap" }, children: [
7403
+ detailedStatus === "FINISHED" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_CheckCircle3.default, { sx: { fontSize: 18, color: "hsl(142 70% 45%)" } }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_Error.default, { sx: { fontSize: 18, color: "hsl(var(--destructive))" } }),
7404
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Typography, { sx: { fontSize: "0.9rem", fontWeight: 600, color: "hsl(var(--foreground))" }, children: detailedStatus === "FINISHED" ? "Run finished" : `Run ${detailedStatus.toLowerCase()}` })
7405
+ ] }),
7406
+ finishAnswer && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: {
7407
+ p: 2,
7408
+ borderRadius: 1.5,
7409
+ border: "1px solid hsl(var(--border))",
7410
+ bgcolor: "hsl(var(--background))",
7411
+ fontSize: "0.9rem",
7412
+ color: "hsl(var(--foreground))",
7413
+ "& > *:first-of-type": { mt: 0 },
7414
+ "& > *:last-child": { mb: 0 },
7415
+ "& p": { my: 1, lineHeight: 1.55 },
7416
+ "& a": { color: "hsl(var(--primary))", textDecoration: "underline" },
7417
+ "& code": {
7418
+ px: 0.5,
7419
+ py: 0.125,
7420
+ borderRadius: 0.5,
7421
+ bgcolor: "hsl(var(--muted))",
7422
+ fontFamily: '"JetBrains Mono", ui-monospace, monospace',
7423
+ fontSize: "0.82em"
7424
+ },
7425
+ "& pre": {
7426
+ p: 1.5,
7427
+ my: 1,
7428
+ borderRadius: 1,
7429
+ bgcolor: "hsl(var(--muted))",
7430
+ overflowX: "auto",
7431
+ fontSize: "0.82rem"
7432
+ },
7433
+ "& pre code": { p: 0, bgcolor: "transparent" }
7434
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_markdown4.default, { remarkPlugins: [import_remark_gfm4.default, import_remark_breaks.default], children: normalizeMarkdown(finishAnswer) }) })
7435
+ ] })
7436
+ ] }) });
7437
+ })(),
7438
+ finishDecisionId && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Box, { sx: { mt: 3, display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material12.Box, { sx: { width: "100%", maxWidth: 640 }, children: [
7439
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.Typography, { sx: { fontSize: "0.75rem", color: "hsl(var(--muted-foreground))", mb: 0.75, textAlign: "center" }, children: "Continue this agent run with more details" }),
7440
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
7441
+ import_material12.Box,
7442
+ {
7443
+ component: "form",
7444
+ onSubmit: (e) => {
7445
+ e.preventDefault();
7446
+ if (continuationText.trim()) {
7447
+ submitQuestions(finishDecisionId, { continue: continuationText }, true);
7448
+ }
7449
+ },
7450
+ sx: {
7451
+ display: "flex",
7452
+ alignItems: "flex-end",
7453
+ gap: 1,
7454
+ p: 1.25,
7455
+ borderRadius: 999,
7456
+ border: "1.5px solid hsl(var(--border))",
7457
+ bgcolor: "hsl(var(--card))",
7458
+ "&:focus-within": {
7459
+ borderColor: "hsl(var(--primary))",
7460
+ boxShadow: "0 0 0 3px hsla(var(--primary) / 0.12)"
7461
+ }
7462
+ },
7463
+ children: [
7464
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7465
+ import_material12.InputBase,
7466
+ {
7467
+ fullWidth: true,
7468
+ multiline: true,
7469
+ minRows: 1,
7470
+ maxRows: 4,
7471
+ placeholder: continuationPlaceholder,
7472
+ value: continuationText,
7473
+ onChange: (e) => setContinuationText(e.target.value),
7474
+ onKeyDown: (e) => {
7475
+ if ((e.metaKey || e.ctrlKey) && e.key === "Enter") {
7476
+ e.preventDefault();
7477
+ if (continuationText.trim() && !agentRequestLoading) {
7478
+ submitQuestions(finishDecisionId, { continue: continuationText }, true);
7479
+ }
7480
+ }
7481
+ },
7482
+ disabled: agentRequestLoading,
7483
+ sx: { fontSize: "0.9rem", color: "hsl(var(--foreground))", px: 2 }
7484
+ }
7485
+ ),
7486
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7487
+ import_material12.IconButton,
7488
+ {
7489
+ type: "submit",
7490
+ disabled: !continuationText.trim() || agentRequestLoading,
7491
+ sx: {
7492
+ width: 36,
7493
+ height: 36,
7494
+ bgcolor: continuationText.trim() && !agentRequestLoading ? "hsl(var(--primary))" : "hsl(var(--muted))",
7495
+ color: continuationText.trim() && !agentRequestLoading ? "hsl(var(--primary-foreground))" : "hsl(var(--muted-foreground))",
7496
+ "&:hover": continuationText.trim() && !agentRequestLoading ? { filter: "brightness(1.1)", bgcolor: "hsl(var(--primary))" } : {}
7497
+ },
7498
+ children: agentRequestLoading ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material12.CircularProgress, { size: 16, sx: { color: "inherit" } }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_Send.default, { sx: { fontSize: 18 } })
7499
+ }
7500
+ )
7501
+ ]
7502
+ }
7503
+ )
7504
+ ] }) })
7505
+ ] }),
7506
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
7507
+ AppSearchDrawer,
7508
+ {
7509
+ open: appSearchOpen,
7510
+ onClose: () => setAppSearchOpen(false),
7511
+ title: appPickerTitle,
7512
+ subtitle: appPickerSubtitle,
7513
+ onQuickSelect: (app) => {
7514
+ const known = availableApps.find((a) => a.name?.toLowerCase() === app.name?.toLowerCase());
7515
+ setChosenApps(
7516
+ (prev) => prev.some((a) => a.name === app.name) ? prev : [...prev, { name: app.name, icon: app.icon || known?.icon, id: app.id || known?.id || void 0 }]
7517
+ );
7518
+ }
7519
+ }
7520
+ )
7521
+ ] }) });
7522
+ };
7523
+ var AgentUI_default = AgentUI;
7524
+
7525
+ // useAppLookup.ts
7526
+ var import_react12 = require("react");
7527
+ var norm = (s) => s.toLowerCase().replace(/[\s_\-]+/g, "_");
7528
+ function useAppLookup(appName) {
7529
+ const [loading, setLoading] = (0, import_react12.useState)(false);
7530
+ const [info, setInfo] = (0, import_react12.useState)(null);
7531
+ const [algoliaId, setAlgoliaId] = (0, import_react12.useState)(null);
7532
+ const {
7533
+ authStates,
7534
+ authenticatedApps,
7535
+ handleAuthChange,
7536
+ handleTestConnection,
7537
+ handleSaveAuth,
7538
+ refreshAuth
7539
+ } = useAppAuth();
7540
+ (0, import_react12.useEffect)(() => {
5530
7541
  if (!appName) {
5531
7542
  setInfo(null);
5532
7543
  setAlgoliaId(null);
@@ -5611,13 +7622,13 @@ function useAppLookup(appName) {
5611
7622
  setLoading(false);
5612
7623
  })();
5613
7624
  }, [appName]);
5614
- const matchingEntries = (0, import_react11.useMemo)(() => {
7625
+ const matchingEntries = (0, import_react12.useMemo)(() => {
5615
7626
  if (!appName) return [];
5616
7627
  return authenticatedApps.filter(
5617
7628
  (auth) => auth.app?.name && norm(auth.app.name) === norm(appName)
5618
7629
  );
5619
7630
  }, [appName, authenticatedApps]);
5620
- const image = (0, import_react11.useMemo)(() => {
7631
+ const image = (0, import_react12.useMemo)(() => {
5621
7632
  if (info?.image) return info.image;
5622
7633
  for (const entry of matchingEntries) {
5623
7634
  const img = entry.app?.large_image || entry.large_image;
@@ -5625,7 +7636,7 @@ function useAppLookup(appName) {
5625
7636
  }
5626
7637
  return "";
5627
7638
  }, [info, matchingEntries]);
5628
- const algoliaApp = (0, import_react11.useMemo)(() => {
7639
+ const algoliaApp = (0, import_react12.useMemo)(() => {
5629
7640
  if (!appName) return null;
5630
7641
  return {
5631
7642
  objectID: algoliaId || appName,
@@ -5658,6 +7669,7 @@ function useAppLookup(appName) {
5658
7669
  // Annotate the CommonJS export names for ESM import in node:
5659
7670
  0 && (module.exports = {
5660
7671
  API_CONFIG,
7672
+ AgentUI,
5661
7673
  AppAuthSection,
5662
7674
  AppDetailDrawer,
5663
7675
  AppDetailProvider,