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