@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/README.md +48 -2
- package/dist/index.cjs +2319 -307
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +134 -9
- package/dist/index.d.ts +134 -9
- package/dist/index.js +2315 -292
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
62
|
-
|
|
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(--
|
|
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(--
|
|
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:
|
|
882
|
-
|
|
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
|
-
|
|
3885
|
+
setCopied(true);
|
|
3886
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
3871
3887
|
} catch {
|
|
3872
|
-
|
|
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
|
-
|
|
3949
|
+
toast.error(parsed.reason || "Run failed");
|
|
3933
3950
|
} else {
|
|
3934
|
-
|
|
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
|
-
|
|
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.
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
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
|
-
"
|
|
4050
|
-
backgroundColor: "hsl(var(--
|
|
4051
|
-
color: "hsl(var(--
|
|
4052
|
-
|
|
4053
|
-
|
|
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
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
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
|
-
|
|
4083
|
-
px:
|
|
4084
|
-
py:
|
|
4067
|
+
gap: 1,
|
|
4068
|
+
px: 2,
|
|
4069
|
+
py: 1,
|
|
4085
4070
|
borderBottom: "1px solid hsl(var(--border))",
|
|
4086
|
-
backgroundColor: "hsl(var(--
|
|
4071
|
+
backgroundColor: "hsl(var(--card))"
|
|
4087
4072
|
},
|
|
4088
4073
|
children: [
|
|
4089
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
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
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
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
|
-
|
|
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
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
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
|
-
|
|
4495
|
+
toast.success(`${displayName} deactivated`);
|
|
4495
4496
|
} else {
|
|
4496
|
-
const
|
|
4497
|
-
if (!
|
|
4498
|
-
const activateRes = await fetch(getApiUrl(`/api/v1/apps/${
|
|
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(
|
|
4505
|
-
|
|
4505
|
+
setActivatedAppId(appId2);
|
|
4506
|
+
toast.success(`${displayName} activated`);
|
|
4506
4507
|
}
|
|
4507
4508
|
} catch (err) {
|
|
4508
4509
|
console.error("[Activate] Error:", err);
|
|
4509
|
-
|
|
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)(
|
|
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)(
|
|
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: (
|
|
4638
|
-
onSaveAuth: (
|
|
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)(
|
|
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
|
-
|
|
5086
|
-
|
|
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
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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)(
|
|
5208
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
5209
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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)(
|
|
5383
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5384
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
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
|
-
|
|
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)(
|
|
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)(
|
|
5401
|
-
connectionPathApps && connectionPathApps.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
5402
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5403
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5404
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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)(
|
|
5443
|
-
|
|
5478
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
5479
|
+
import_material11.Box,
|
|
5444
5480
|
{
|
|
5445
|
-
|
|
5446
|
-
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
5457
|
-
|
|
5458
|
-
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
|
|
5465
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
5581
|
+
// AgentUI.tsx
|
|
5515
5582
|
var import_react11 = require("react");
|
|
5516
|
-
var
|
|
5517
|
-
|
|
5518
|
-
|
|
5519
|
-
|
|
5520
|
-
|
|
5521
|
-
|
|
5522
|
-
|
|
5523
|
-
|
|
5524
|
-
|
|
5525
|
-
|
|
5526
|
-
|
|
5527
|
-
|
|
5528
|
-
|
|
5529
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|