@shuffleio/shuffle-mcps 0.0.32 → 0.0.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +43 -30
- package/dist/index.d.ts +43 -30
- package/dist/index.js +594 -219
- package/dist/index.mjs +601 -222
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2464,6 +2464,8 @@ var AppAuthCard = ({
|
|
|
2464
2464
|
hideDocsLink,
|
|
2465
2465
|
hideUrlFields,
|
|
2466
2466
|
borderless,
|
|
2467
|
+
compactAuthForm,
|
|
2468
|
+
extraFieldsSlot,
|
|
2467
2469
|
globalUrl,
|
|
2468
2470
|
userdata,
|
|
2469
2471
|
isLoaded,
|
|
@@ -2530,10 +2532,6 @@ var AppAuthCard = ({
|
|
|
2530
2532
|
if (!alreadyValid && newestId !== autoTestFiredRef.current) {
|
|
2531
2533
|
autoTestFiredRef.current = newestId;
|
|
2532
2534
|
setTimeout(() => {
|
|
2533
|
-
toast({
|
|
2534
|
-
title: "Auto-testing new authentication",
|
|
2535
|
-
description: `Verifying connection for ${app.name.replace(/_/g, " ")}...`
|
|
2536
|
-
});
|
|
2537
2535
|
setTestingAuthId(newestId);
|
|
2538
2536
|
onTestConnection(app.objectID, newestId);
|
|
2539
2537
|
}, 500);
|
|
@@ -2595,11 +2593,17 @@ var AppAuthCard = ({
|
|
|
2595
2593
|
executionId: authState.executionId,
|
|
2596
2594
|
errorCode: authState.errorCode
|
|
2597
2595
|
});
|
|
2596
|
+
if (autoTestFiredRef.current === testingAuthId) {
|
|
2597
|
+
setSelectedAuthId(ADD_NEW_AUTH);
|
|
2598
|
+
setUserHasSelected(true);
|
|
2599
|
+
setPendingFailedAuthId(testingAuthId);
|
|
2600
|
+
autoTestFiredRef.current = null;
|
|
2601
|
+
}
|
|
2598
2602
|
setTestingAuthId(null);
|
|
2599
2603
|
}
|
|
2600
2604
|
}, [authState.status, authState.errorMessage, authState.successMessage, authState.warningMessage, testingAuthId, apiAuthEntries, wasPreValidatedPerAuth]);
|
|
2601
2605
|
const isCredentialError = localTestMessages.errorCode === 401 || localTestMessages.errorCode === 403;
|
|
2602
|
-
const showAddNewForm = selectedAuthId === ADD_NEW_AUTH;
|
|
2606
|
+
const showAddNewForm = compactAuthForm ? true : selectedAuthId === ADD_NEW_AUTH;
|
|
2603
2607
|
const isConfigured = selectedAuth?.active === true;
|
|
2604
2608
|
const isTested = selectedAuth?.validation?.valid === true;
|
|
2605
2609
|
const getLastValidTimestamp = () => {
|
|
@@ -2621,6 +2625,8 @@ var AppAuthCard = ({
|
|
|
2621
2625
|
});
|
|
2622
2626
|
};
|
|
2623
2627
|
const [localCredentials, setLocalCredentials] = (0, import_react7.useState)(authState.credentials || {});
|
|
2628
|
+
const [revealedFields, setRevealedFields] = (0, import_react7.useState)({});
|
|
2629
|
+
const [pendingFailedAuthId, setPendingFailedAuthId] = (0, import_react7.useState)(null);
|
|
2624
2630
|
const [fieldErrors, setFieldErrors] = (0, import_react7.useState)({});
|
|
2625
2631
|
const [loading, setLoading] = (0, import_react7.useState)(false);
|
|
2626
2632
|
const [saving, setSaving] = (0, import_react7.useState)(false);
|
|
@@ -2696,7 +2702,8 @@ var AppAuthCard = ({
|
|
|
2696
2702
|
for (const [k, v] of Object.entries(incoming)) {
|
|
2697
2703
|
const lk = k.toLowerCase();
|
|
2698
2704
|
const isUrlish = lk.includes("url") || lk.includes("endpoint") || lk.includes("host");
|
|
2699
|
-
|
|
2705
|
+
const isModel = lk === "model";
|
|
2706
|
+
if ((isUrlish || isModel) && typeof v === "string" && v !== prev[k]) {
|
|
2700
2707
|
next[k] = v;
|
|
2701
2708
|
changed = true;
|
|
2702
2709
|
}
|
|
@@ -2892,7 +2899,7 @@ var AppAuthCard = ({
|
|
|
2892
2899
|
sx: {
|
|
2893
2900
|
"& .MuiOutlinedInput-root": {
|
|
2894
2901
|
backgroundColor: "hsl(var(--background))",
|
|
2895
|
-
borderRadius:
|
|
2902
|
+
borderRadius: 1,
|
|
2896
2903
|
"& fieldset": { borderColor: "hsl(var(--border))" },
|
|
2897
2904
|
"&:hover fieldset": { borderColor: "hsl(var(--border) / 0.8)" },
|
|
2898
2905
|
"&.Mui-focused fieldset": { borderColor: "hsl(var(--primary))" }
|
|
@@ -2915,7 +2922,7 @@ var AppAuthCard = ({
|
|
|
2915
2922
|
sx: {
|
|
2916
2923
|
"& .MuiOutlinedInput-root": {
|
|
2917
2924
|
backgroundColor: "hsl(var(--background))",
|
|
2918
|
-
borderRadius:
|
|
2925
|
+
borderRadius: 1,
|
|
2919
2926
|
"& fieldset": { borderColor: "hsl(var(--border))" },
|
|
2920
2927
|
"&:hover fieldset": { borderColor: "hsl(var(--border) / 0.8)" },
|
|
2921
2928
|
"&.Mui-focused fieldset": { borderColor: "hsl(var(--primary))" }
|
|
@@ -2940,7 +2947,7 @@ var AppAuthCard = ({
|
|
|
2940
2947
|
displayEmpty: true,
|
|
2941
2948
|
sx: {
|
|
2942
2949
|
backgroundColor: "action.hover",
|
|
2943
|
-
borderRadius:
|
|
2950
|
+
borderRadius: 1,
|
|
2944
2951
|
color: "text.primary",
|
|
2945
2952
|
"& .MuiOutlinedInput-notchedOutline": { borderColor: "divider" },
|
|
2946
2953
|
"&:hover .MuiOutlinedInput-notchedOutline": { borderColor: "text.disabled" },
|
|
@@ -2985,6 +2992,7 @@ var AppAuthCard = ({
|
|
|
2985
2992
|
const fieldKey = param.id || param.name || `param_${index}`;
|
|
2986
2993
|
const lowerName = (param.name || "").toLowerCase();
|
|
2987
2994
|
const isSecretField = lowerName.includes("password") || lowerName.includes("secret") || lowerName.includes("key") || lowerName.includes("token");
|
|
2995
|
+
const isRevealed = !!revealedFields[fieldKey];
|
|
2988
2996
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2989
2997
|
import_material4.TextField,
|
|
2990
2998
|
{
|
|
@@ -3015,13 +3023,25 @@ var AppAuthCard = ({
|
|
|
3015
3023
|
onFocus: (e) => {
|
|
3016
3024
|
e.target.removeAttribute("readonly");
|
|
3017
3025
|
}
|
|
3018
|
-
}
|
|
3026
|
+
},
|
|
3027
|
+
input: isSecretField ? {
|
|
3028
|
+
endAdornment: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
3029
|
+
import_material4.IconButton,
|
|
3030
|
+
{
|
|
3031
|
+
size: "small",
|
|
3032
|
+
onClick: () => setRevealedFields((prev) => ({ ...prev, [fieldKey]: !prev[fieldKey] })),
|
|
3033
|
+
"aria-label": isRevealed ? `Hide ${param.name}` : `Show ${param.name}`,
|
|
3034
|
+
sx: { color: "hsl(var(--muted-foreground))", "&:hover": { color: "hsl(var(--foreground))" } },
|
|
3035
|
+
children: isRevealed ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.EyeOff, { size: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.Eye, { size: 16 })
|
|
3036
|
+
}
|
|
3037
|
+
)
|
|
3038
|
+
} : void 0
|
|
3019
3039
|
},
|
|
3020
3040
|
name: `auth-${fieldKey}-${app.objectID}-${Math.random().toString(36).slice(2, 8)}`,
|
|
3021
3041
|
sx: {
|
|
3022
3042
|
"& .MuiOutlinedInput-root": {
|
|
3023
3043
|
backgroundColor: isSecretField ? "hsl(var(--primary) / 0.06)" : "hsl(var(--muted))",
|
|
3024
|
-
borderRadius:
|
|
3044
|
+
borderRadius: 1,
|
|
3025
3045
|
"& fieldset": {
|
|
3026
3046
|
borderColor: fieldErrors[fieldKey] ? "hsl(var(--destructive))" : isSecretField ? "hsl(var(--primary) / 0.5)" : "hsl(var(--border))",
|
|
3027
3047
|
borderWidth: isSecretField ? 2 : 1
|
|
@@ -3033,7 +3053,7 @@ var AppAuthCard = ({
|
|
|
3033
3053
|
},
|
|
3034
3054
|
"& .MuiInputBase-input": {
|
|
3035
3055
|
color: "hsl(var(--foreground))",
|
|
3036
|
-
...isSecretField && {
|
|
3056
|
+
...isSecretField && !isRevealed && {
|
|
3037
3057
|
WebkitTextSecurity: "disc",
|
|
3038
3058
|
textSecurity: "disc",
|
|
3039
3059
|
fontFamily: "text-security-disc, monospace"
|
|
@@ -3084,7 +3104,6 @@ var AppAuthCard = ({
|
|
|
3084
3104
|
setSaveSuccess(success);
|
|
3085
3105
|
if (success) {
|
|
3086
3106
|
setUserHasSelected(false);
|
|
3087
|
-
setLocalCredentials({});
|
|
3088
3107
|
setFieldErrors({});
|
|
3089
3108
|
}
|
|
3090
3109
|
};
|
|
@@ -3292,7 +3311,7 @@ var AppAuthCard = ({
|
|
|
3292
3311
|
borderTop: borderless ? "none" : "1px solid hsl(var(--border))"
|
|
3293
3312
|
},
|
|
3294
3313
|
children: [
|
|
3295
|
-
apiAuthEntries.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_material4.Box, { sx: { mb: 3 }, children: [
|
|
3314
|
+
!compactAuthForm && apiAuthEntries.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_material4.Box, { sx: { mb: 3 }, children: [
|
|
3296
3315
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_material4.Typography, { variant: "body2", sx: { color: "hsl(var(--muted-foreground))", mb: 1 }, children: "Select authentication" }),
|
|
3297
3316
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_material4.FormControl, { fullWidth: true, size: "small", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
3298
3317
|
import_material4.Select,
|
|
@@ -3831,7 +3850,7 @@ var AppAuthCard = ({
|
|
|
3831
3850
|
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_material4.Typography, { sx: { fontSize: "0.875rem" }, children: localTestMessages.errorCode === 401 ? "Previous credentials were invalid or expired. Please enter new credentials." : "Access was denied with the previous credentials. Please re-authenticate with valid permissions." })
|
|
3832
3851
|
}
|
|
3833
3852
|
),
|
|
3834
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_material4.Typography, { variant: "subtitle2", sx: { color: "hsl(var(--foreground))", fontWeight: 600, mb: 2 }, children: apiAuthEntries.length === 0 ?
|
|
3853
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_material4.Typography, { variant: "subtitle2", sx: { color: "hsl(var(--foreground))", fontWeight: 600, mb: 2 }, children: apiAuthEntries.length === 0 ? `Configure ${app.name.replace(/_/g, " ")}` : "Add New Authentication" }),
|
|
3835
3854
|
loading ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_material4.Box, { sx: { display: "flex", alignItems: "center", justifyContent: "center", py: 4 }, children: [
|
|
3836
3855
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_material4.CircularProgress, { size: 32, sx: { color: "hsl(var(--primary))" } }),
|
|
3837
3856
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_material4.Typography, { sx: { ml: 2, color: "hsl(var(--muted-foreground))" }, children: "Loading configuration..." })
|
|
@@ -3867,6 +3886,7 @@ var AppAuthCard = ({
|
|
|
3867
3886
|
] })
|
|
3868
3887
|
}
|
|
3869
3888
|
) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_material4.Box, { sx: { display: "flex", flexDirection: "column", gap: 3 }, children: [
|
|
3889
|
+
extraFieldsSlot?.({ credentials: localCredentials, setField: handleCredentialChange }),
|
|
3870
3890
|
renderOAuth2Fields(),
|
|
3871
3891
|
renderParameterFields(),
|
|
3872
3892
|
authState.status === "error" && authState.errorMessage && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
@@ -3921,38 +3941,97 @@ var AppAuthCard = ({
|
|
|
3921
3941
|
children: "Failed to save authentication. Please try again."
|
|
3922
3942
|
}
|
|
3923
3943
|
),
|
|
3924
|
-
!isOAuth2 && /* @__PURE__ */ (0, import_jsx_runtime6.
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
e
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
3937
|
-
|
|
3938
|
-
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
|
|
3944
|
+
!isOAuth2 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_material4.Box, { sx: { display: "flex", justifyContent: "flex-end", pt: 1.5, gap: 1, flexWrap: "wrap" }, children: [
|
|
3945
|
+
pendingFailedAuthId && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
3946
|
+
import_material4.Button,
|
|
3947
|
+
{
|
|
3948
|
+
variant: "text",
|
|
3949
|
+
size: "medium",
|
|
3950
|
+
onClick: async (e) => {
|
|
3951
|
+
e.stopPropagation();
|
|
3952
|
+
const previousFailedId = pendingFailedAuthId;
|
|
3953
|
+
setPendingFailedAuthId(null);
|
|
3954
|
+
setUserHasSelected(true);
|
|
3955
|
+
setFieldErrors({});
|
|
3956
|
+
await onSaveAuth(app.objectID, localCredentials);
|
|
3957
|
+
let entries = apiAuthEntries;
|
|
3958
|
+
if (onRefreshAuth) {
|
|
3959
|
+
await onRefreshAuth();
|
|
3960
|
+
}
|
|
3961
|
+
entries = apiAuthEntries || [];
|
|
3962
|
+
const sorted = [...entries].sort((a, b) => (b.created || 0) - (a.created || 0));
|
|
3963
|
+
const acceptId = sorted[0]?.id || previousFailedId;
|
|
3964
|
+
setSelectedAuthId(acceptId);
|
|
3965
|
+
const stale = entries.filter((e2) => e2.id && e2.id !== acceptId);
|
|
3966
|
+
await Promise.all(stale.map(async (entry) => {
|
|
3967
|
+
try {
|
|
3968
|
+
await fetch(getApiUrl(`/api/v1/apps/authentication/${entry.id}`), {
|
|
3969
|
+
method: "DELETE",
|
|
3970
|
+
credentials: "include",
|
|
3971
|
+
headers: { ...getAuthHeader() }
|
|
3972
|
+
});
|
|
3973
|
+
} catch (err) {
|
|
3974
|
+
console.error("[AppAuthCard] Failed to delete stale auth on Save anyway:", err);
|
|
3975
|
+
}
|
|
3976
|
+
}));
|
|
3977
|
+
if (onRefreshAuth) await onRefreshAuth();
|
|
3978
|
+
if (onSelectAuth) onSelectAuth(app.objectID, acceptId);
|
|
3979
|
+
if (typeof window !== "undefined") {
|
|
3980
|
+
window.dispatchEvent(new CustomEvent("integrations-changed"));
|
|
3981
|
+
window.dispatchEvent(new CustomEvent("agent-drawer-close"));
|
|
3982
|
+
}
|
|
3947
3983
|
},
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3984
|
+
sx: {
|
|
3985
|
+
color: "hsl(var(--muted-foreground))",
|
|
3986
|
+
fontWeight: 600,
|
|
3987
|
+
textTransform: "none",
|
|
3988
|
+
fontSize: "0.85rem",
|
|
3989
|
+
px: 2,
|
|
3990
|
+
py: 1,
|
|
3991
|
+
borderRadius: 2,
|
|
3992
|
+
"&:hover": {
|
|
3993
|
+
color: "hsl(var(--foreground))",
|
|
3994
|
+
backgroundColor: "hsl(var(--muted) / 0.5)"
|
|
3995
|
+
}
|
|
3996
|
+
},
|
|
3997
|
+
title: "Our test isn't always authoritative \u2014 keep the credentials you saved and dismiss the failure.",
|
|
3998
|
+
children: "Save anyway"
|
|
3999
|
+
}
|
|
4000
|
+
),
|
|
4001
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
4002
|
+
import_material4.Button,
|
|
4003
|
+
{
|
|
4004
|
+
variant: "outlined",
|
|
4005
|
+
size: "medium",
|
|
4006
|
+
onClick: (e) => {
|
|
4007
|
+
e.stopPropagation();
|
|
4008
|
+
setPendingFailedAuthId(null);
|
|
4009
|
+
handleSave();
|
|
4010
|
+
},
|
|
4011
|
+
disabled: saving || !isFormValid(),
|
|
4012
|
+
sx: {
|
|
4013
|
+
borderColor: isFormValid() ? "hsl(var(--primary) / 0.5)" : "hsl(var(--border))",
|
|
4014
|
+
color: isFormValid() ? "hsl(var(--primary))" : "hsl(var(--muted-foreground))",
|
|
4015
|
+
fontWeight: 600,
|
|
4016
|
+
textTransform: "none",
|
|
4017
|
+
fontSize: "0.9rem",
|
|
4018
|
+
px: 3,
|
|
4019
|
+
py: 1,
|
|
4020
|
+
borderRadius: 2,
|
|
4021
|
+
transition: "all 0.2s ease",
|
|
4022
|
+
"&:hover": {
|
|
4023
|
+
borderColor: "hsl(var(--primary))",
|
|
4024
|
+
backgroundColor: "hsl(var(--primary) / 0.08)"
|
|
4025
|
+
},
|
|
4026
|
+
"&.Mui-disabled": {
|
|
4027
|
+
borderColor: "hsl(var(--border))",
|
|
4028
|
+
color: "hsl(var(--muted-foreground))"
|
|
4029
|
+
}
|
|
4030
|
+
},
|
|
4031
|
+
children: saving ? "Testing..." : pendingFailedAuthId ? "Retry Test" : "Test Authentication"
|
|
4032
|
+
}
|
|
4033
|
+
)
|
|
4034
|
+
] }),
|
|
3956
4035
|
isOAuth2 && (() => {
|
|
3957
4036
|
const hasClientId = !!localCredentials["client_id"]?.trim();
|
|
3958
4037
|
const hasClientSecret = !!localCredentials["client_secret"]?.trim();
|
|
@@ -6029,28 +6108,38 @@ function AppDetailDrawer({
|
|
|
6029
6108
|
}
|
|
6030
6109
|
}, [open, appName]);
|
|
6031
6110
|
const isLoadingAll = appLoading || isAuthenticated && appAuthLoading;
|
|
6111
|
+
const drawerWidth = `min(${width}px, 100vw)`;
|
|
6032
6112
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
6033
6113
|
import_material9.Drawer,
|
|
6034
6114
|
{
|
|
6035
6115
|
anchor,
|
|
6036
6116
|
open,
|
|
6037
6117
|
onClose: handleClose,
|
|
6038
|
-
|
|
6039
|
-
|
|
6040
|
-
|
|
6041
|
-
|
|
6042
|
-
|
|
6043
|
-
|
|
6044
|
-
|
|
6045
|
-
|
|
6046
|
-
|
|
6047
|
-
|
|
6048
|
-
|
|
6049
|
-
|
|
6118
|
+
PaperProps: {
|
|
6119
|
+
className: scopeClassName,
|
|
6120
|
+
sx: {
|
|
6121
|
+
width: drawerWidth,
|
|
6122
|
+
minWidth: drawerWidth,
|
|
6123
|
+
maxWidth: drawerWidth,
|
|
6124
|
+
flex: `0 0 ${drawerWidth}`,
|
|
6125
|
+
height: "100vh",
|
|
6126
|
+
display: "flex",
|
|
6127
|
+
flexDirection: "column",
|
|
6128
|
+
overflow: "hidden",
|
|
6129
|
+
background: "linear-gradient(180deg, hsl(var(--card)) 0%, hsl(var(--background)) 100%)",
|
|
6130
|
+
borderLeft: anchor === "right" ? "1px solid hsl(var(--border))" : "none",
|
|
6131
|
+
borderRight: anchor === "left" ? "1px solid hsl(var(--border))" : "none"
|
|
6050
6132
|
}
|
|
6051
6133
|
},
|
|
6052
6134
|
sx: {
|
|
6053
|
-
|
|
6135
|
+
zIndex: 9999,
|
|
6136
|
+
"& .MuiDrawer-paper": {
|
|
6137
|
+
boxSizing: "border-box",
|
|
6138
|
+
width: `${drawerWidth} !important`,
|
|
6139
|
+
minWidth: `${drawerWidth} !important`,
|
|
6140
|
+
maxWidth: `${drawerWidth} !important`,
|
|
6141
|
+
flex: `0 0 ${drawerWidth} !important`
|
|
6142
|
+
}
|
|
6054
6143
|
},
|
|
6055
6144
|
children: [
|
|
6056
6145
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
@@ -7083,6 +7172,7 @@ function AppSearchDrawer({
|
|
|
7083
7172
|
const t = setTimeout(() => setHighlightActive(true), highlightDelayMs);
|
|
7084
7173
|
return () => clearTimeout(t);
|
|
7085
7174
|
}, [open, highlightAppName, highlightDelayMs]);
|
|
7175
|
+
const drawerWidth = `min(${width}px, 100vw)`;
|
|
7086
7176
|
const handleClose = () => {
|
|
7087
7177
|
setDetailAppName(null);
|
|
7088
7178
|
setDetailAppId(null);
|
|
@@ -7159,29 +7249,38 @@ function AppSearchDrawer({
|
|
|
7159
7249
|
anchor,
|
|
7160
7250
|
open: open && detailAppName === null,
|
|
7161
7251
|
onClose: handleClose,
|
|
7162
|
-
|
|
7163
|
-
|
|
7164
|
-
|
|
7165
|
-
|
|
7166
|
-
|
|
7167
|
-
|
|
7168
|
-
|
|
7169
|
-
|
|
7170
|
-
|
|
7171
|
-
|
|
7172
|
-
|
|
7173
|
-
|
|
7174
|
-
|
|
7175
|
-
|
|
7176
|
-
|
|
7177
|
-
|
|
7178
|
-
|
|
7179
|
-
|
|
7252
|
+
PaperProps: {
|
|
7253
|
+
className: scopeClassName,
|
|
7254
|
+
sx: {
|
|
7255
|
+
// Strict, environment-independent sizing so the drawer
|
|
7256
|
+
// looks identical on every host (Shuffle Security, /agents,
|
|
7257
|
+
// test page, embedded library, etc.). No breakpoint variance.
|
|
7258
|
+
// NOTE: use PaperProps (not slotProps.paper) — slotProps.paper
|
|
7259
|
+
// was added in MUI v6 and is silently ignored on MUI v5 hosts,
|
|
7260
|
+
// which made the drawer collapse to content width when
|
|
7261
|
+
// consumed from the published library.
|
|
7262
|
+
width: drawerWidth,
|
|
7263
|
+
minWidth: drawerWidth,
|
|
7264
|
+
maxWidth: drawerWidth,
|
|
7265
|
+
flex: `0 0 ${drawerWidth}`,
|
|
7266
|
+
height: "100vh",
|
|
7267
|
+
display: "flex",
|
|
7268
|
+
flexDirection: "column",
|
|
7269
|
+
overflow: "hidden",
|
|
7270
|
+
background: "linear-gradient(180deg, hsl(var(--card)) 0%, hsl(var(--background)) 100%)",
|
|
7271
|
+
borderLeft: anchor === "right" ? "1px solid hsl(var(--border))" : "none",
|
|
7272
|
+
borderRight: anchor === "left" ? "1px solid hsl(var(--border))" : "none"
|
|
7180
7273
|
}
|
|
7181
7274
|
},
|
|
7182
7275
|
sx: {
|
|
7183
7276
|
zIndex: 9999,
|
|
7184
|
-
"& .MuiDrawer-paper": {
|
|
7277
|
+
"& .MuiDrawer-paper": {
|
|
7278
|
+
boxSizing: "border-box",
|
|
7279
|
+
width: `${drawerWidth} !important`,
|
|
7280
|
+
minWidth: `${drawerWidth} !important`,
|
|
7281
|
+
maxWidth: `${drawerWidth} !important`,
|
|
7282
|
+
flex: `0 0 ${drawerWidth} !important`
|
|
7283
|
+
}
|
|
7185
7284
|
},
|
|
7186
7285
|
children: [
|
|
7187
7286
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
@@ -7213,7 +7312,7 @@ function AppSearchDrawer({
|
|
|
7213
7312
|
]
|
|
7214
7313
|
}
|
|
7215
7314
|
),
|
|
7216
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_material11.Box, { sx: { flex: 1, boxSizing: "border-box", overflow: "hidden", p: 3, minHeight: 0, display: "flex", flexDirection: "column" }, children: [
|
|
7315
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_material11.Box, { sx: { flex: 1, width: "100%", minWidth: 0, boxSizing: "border-box", overflow: "hidden", p: 3, minHeight: 0, display: "flex", flexDirection: "column" }, children: [
|
|
7217
7316
|
connectionPathApps && connectionPathApps.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_material11.Box, { sx: { mb: 2.5 }, children: [
|
|
7218
7317
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material11.Typography, { sx: { color: "hsl(var(--muted-foreground))", fontSize: "0.7rem", fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.05em", mb: 1 }, children: "In this usecase" }),
|
|
7219
7318
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material11.Box, { sx: { display: "flex", gap: 1.5, flexWrap: "wrap" }, children: connectionPathApps.map((app) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material11.Tooltip, { title: app.name.replace(/_/g, " "), arrow: true, placement: "bottom", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
@@ -7260,6 +7359,8 @@ function AppSearchDrawer({
|
|
|
7260
7359
|
{
|
|
7261
7360
|
sx: {
|
|
7262
7361
|
flex: 1,
|
|
7362
|
+
width: "100%",
|
|
7363
|
+
minWidth: 0,
|
|
7263
7364
|
minHeight: 0,
|
|
7264
7365
|
overflow: "hidden",
|
|
7265
7366
|
"& .singul-container, & .singul-search-bar-container": {
|
|
@@ -7272,16 +7373,22 @@ function AppSearchDrawer({
|
|
|
7272
7373
|
},
|
|
7273
7374
|
"& .singul-results-container": {
|
|
7274
7375
|
flex: 1,
|
|
7376
|
+
width: "100%",
|
|
7377
|
+
minWidth: 0,
|
|
7275
7378
|
minHeight: 0,
|
|
7276
7379
|
maxHeight: "none",
|
|
7277
7380
|
overflowY: "auto"
|
|
7278
7381
|
},
|
|
7279
7382
|
"& .singul-results-grid": {
|
|
7383
|
+
width: "100% !important",
|
|
7384
|
+
minWidth: "0 !important",
|
|
7280
7385
|
gridTemplateColumns: "repeat(2, minmax(0, 1fr)) !important",
|
|
7281
7386
|
gridAutoRows: "78px !important",
|
|
7282
7387
|
gap: "12px !important"
|
|
7283
7388
|
},
|
|
7284
7389
|
"& .singul-results-grid .singul-dropdown-item": {
|
|
7390
|
+
width: "100%",
|
|
7391
|
+
maxWidth: "100%",
|
|
7285
7392
|
minWidth: 0,
|
|
7286
7393
|
minHeight: "78px !important",
|
|
7287
7394
|
maxHeight: "78px !important",
|
|
@@ -8045,6 +8152,73 @@ function invalidateResolvedApps() {
|
|
|
8045
8152
|
_cache.clear();
|
|
8046
8153
|
}
|
|
8047
8154
|
|
|
8155
|
+
// llmProviderDetect.ts
|
|
8156
|
+
var SHUFFLE_AI_PRESET = "Shuffle AI";
|
|
8157
|
+
var CUSTOM_PRESET = "Custom / self-hosted";
|
|
8158
|
+
var ENDPOINT_PRESETS = [
|
|
8159
|
+
{ label: SHUFFLE_AI_PRESET, url: "" },
|
|
8160
|
+
{ label: "OpenAI", url: "https://api.openai.com/v1", apiKeyUrl: "https://platform.openai.com/api-keys", apiKeyHint: "Create a key under API keys in the OpenAI platform dashboard." },
|
|
8161
|
+
{ label: "Anthropic", url: "https://api.anthropic.com/v1/", apiKeyUrl: "https://console.anthropic.com/settings/keys", apiKeyHint: "Generate a key under Settings \u2192 API Keys in the Anthropic Console." },
|
|
8162
|
+
{ label: "Google Gemini", url: "https://generativelanguage.googleapis.com/v1beta/openai/", apiKeyUrl: "https://aistudio.google.com/app/apikey", apiKeyHint: "Create a key in Google AI Studio under Get API key." },
|
|
8163
|
+
{ label: "Mistral", url: "https://api.mistral.ai/v1", apiKeyUrl: "https://console.mistral.ai/api-keys/", apiKeyHint: "Create a key under API Keys in the Mistral Console." },
|
|
8164
|
+
{ label: "Groq", url: "https://api.groq.com/openai/v1", apiKeyUrl: "https://console.groq.com/keys", apiKeyHint: "Create a key under API Keys in the Groq Console." },
|
|
8165
|
+
{ label: "DeepSeek", url: "https://api.deepseek.com/v1", apiKeyUrl: "https://platform.deepseek.com/api_keys", apiKeyHint: "Create a key under API Keys in the DeepSeek platform." },
|
|
8166
|
+
{ label: "Together AI", url: "https://api.together.xyz/v1", apiKeyUrl: "https://api.together.ai/settings/api-keys", apiKeyHint: "Create a key under Settings \u2192 API Keys in Together AI." },
|
|
8167
|
+
{ label: "OpenRouter", url: "https://openrouter.ai/api/v1", apiKeyUrl: "https://openrouter.ai/keys", apiKeyHint: "Create a key under Keys in your OpenRouter dashboard." },
|
|
8168
|
+
{ label: "Ollama (localhost)", url: "http://localhost:11434/v1", apiKeyHint: "Local Ollama does not require an API key \u2014 any non-empty value works." },
|
|
8169
|
+
{ label: "LM Studio (localhost)", url: "http://localhost:1234/v1", apiKeyHint: "Local LM Studio does not require an API key \u2014 any non-empty value works." },
|
|
8170
|
+
{ label: CUSTOM_PRESET, url: "" }
|
|
8171
|
+
];
|
|
8172
|
+
var PROVIDER_DOMAINS = {
|
|
8173
|
+
"Shuffle AI": "shuffler.io",
|
|
8174
|
+
OpenAI: "openai.com",
|
|
8175
|
+
Anthropic: "anthropic.com",
|
|
8176
|
+
"Google Gemini": "gemini.google.com",
|
|
8177
|
+
Mistral: "mistral.ai",
|
|
8178
|
+
Groq: "groq.com",
|
|
8179
|
+
DeepSeek: "deepseek.com",
|
|
8180
|
+
"Together AI": "together.ai",
|
|
8181
|
+
OpenRouter: "openrouter.ai",
|
|
8182
|
+
"Ollama (localhost)": "ollama.com",
|
|
8183
|
+
"LM Studio (localhost)": "lmstudio.ai"
|
|
8184
|
+
};
|
|
8185
|
+
var hostnameOf = (url) => {
|
|
8186
|
+
try {
|
|
8187
|
+
return new URL(url).hostname.replace(/^www\./, "");
|
|
8188
|
+
} catch {
|
|
8189
|
+
return null;
|
|
8190
|
+
}
|
|
8191
|
+
};
|
|
8192
|
+
var detectLLMProvider = (url) => {
|
|
8193
|
+
if (!url) return null;
|
|
8194
|
+
const trimmed = url.trim();
|
|
8195
|
+
if (!trimmed) return null;
|
|
8196
|
+
const exact = ENDPOINT_PRESETS.find((p) => p.url && p.url === trimmed);
|
|
8197
|
+
if (exact) return exact;
|
|
8198
|
+
const host = hostnameOf(trimmed);
|
|
8199
|
+
if (host) {
|
|
8200
|
+
const byHost = ENDPOINT_PRESETS.find((p) => {
|
|
8201
|
+
const presetHost = hostnameOf(p.url);
|
|
8202
|
+
return presetHost && presetHost === host;
|
|
8203
|
+
});
|
|
8204
|
+
if (byHost) return byHost;
|
|
8205
|
+
if (host === "localhost" || host === "127.0.0.1") {
|
|
8206
|
+
if (trimmed.includes(":11434")) return ENDPOINT_PRESETS.find((p) => p.label === "Ollama (localhost)") || null;
|
|
8207
|
+
if (trimmed.includes(":1234")) return ENDPOINT_PRESETS.find((p) => p.label === "LM Studio (localhost)") || null;
|
|
8208
|
+
}
|
|
8209
|
+
}
|
|
8210
|
+
return ENDPOINT_PRESETS.find((p) => p.label === CUSTOM_PRESET) || null;
|
|
8211
|
+
};
|
|
8212
|
+
var getProviderLogoUrl = (label, url) => {
|
|
8213
|
+
if (!label && !url) return "";
|
|
8214
|
+
let domain = label ? PROVIDER_DOMAINS[label] : void 0;
|
|
8215
|
+
if (!domain && url) {
|
|
8216
|
+
const host = hostnameOf(url);
|
|
8217
|
+
if (host) domain = host;
|
|
8218
|
+
}
|
|
8219
|
+
return domain ? `https://www.google.com/s2/favicons?domain=${domain}&sz=64` : "";
|
|
8220
|
+
};
|
|
8221
|
+
|
|
8048
8222
|
// agentRun.ts
|
|
8049
8223
|
init_api();
|
|
8050
8224
|
var resolveTarget = (path, opts = {}) => {
|
|
@@ -8959,10 +9133,10 @@ var AgentRunDiagnosisBanner = ({ run, sx, onJumpToEvidence, executionId }) => {
|
|
|
8959
9133
|
const outputWarning = !isFailed && hasOutputWarning(run);
|
|
8960
9134
|
const diagnosis = outputWarning ? diagnoseOutputWarning(run) : null;
|
|
8961
9135
|
if (!failureInfo && !diagnosis) return null;
|
|
8962
|
-
const isCritical = !!failureInfo;
|
|
9136
|
+
const isCritical = !!failureInfo || diagnosis?.kind === "token_limit";
|
|
8963
9137
|
const tone = isCritical ? "critical" : "medium";
|
|
8964
9138
|
const Icon = isCritical ? import_lucide_react10.AlertTriangle : import_lucide_react10.HelpCircle;
|
|
8965
|
-
const message =
|
|
9139
|
+
const message = failureInfo ? failureInfo.reason : `${diagnosis.title} \u2014 ${diagnosis.remediation}`;
|
|
8966
9140
|
const firstEvidence = diagnosis?.evidence?.[0] || null;
|
|
8967
9141
|
const jumpDecisionIndex = firstEvidence ? extractDecisionIndex(firstEvidence.path) : null;
|
|
8968
9142
|
const canJump = !!(onJumpToEvidence && jumpDecisionIndex !== null);
|
|
@@ -9501,7 +9675,7 @@ var TimelineRow = ({
|
|
|
9501
9675
|
),
|
|
9502
9676
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.Box, { sx: {
|
|
9503
9677
|
flex: 1,
|
|
9504
|
-
minWidth:
|
|
9678
|
+
minWidth: 180,
|
|
9505
9679
|
fontSize: "0.85rem",
|
|
9506
9680
|
color: "hsl(var(--foreground))",
|
|
9507
9681
|
maxHeight: 60,
|
|
@@ -9511,7 +9685,7 @@ var TimelineRow = ({
|
|
|
9511
9685
|
"& a": { color: "hsl(var(--primary))", textDecoration: "underline", textUnderlineOffset: "2px" },
|
|
9512
9686
|
"& a:hover": { opacity: 0.85 }
|
|
9513
9687
|
}, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_markdown4.default, { remarkPlugins: [import_remark_gfm4.default, import_remark_breaks.default], children: normalizeMarkdown(displayLabel) }) }),
|
|
9514
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.Tooltip, { title: hasTiming ? `Duration: ${dur.toFixed(2)}s \xB7 ${new Date(itemStart * 1e3).toLocaleString()}` : "No timing data", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.Box, { sx: { width: maxWidth, position: "relative", height: 10, flexShrink:
|
|
9688
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.Tooltip, { title: hasTiming ? `Duration: ${dur.toFixed(2)}s \xB7 ${new Date(itemStart * 1e3).toLocaleString()}` : "No timing data", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.Box, { sx: { width: maxWidth, maxWidth, minWidth: 40, position: "relative", height: 10, flexShrink: 1, flexBasis: maxWidth }, children: dur > 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.Box, { sx: {
|
|
9515
9689
|
position: "absolute",
|
|
9516
9690
|
left: Math.max(0, offset),
|
|
9517
9691
|
width,
|
|
@@ -9919,6 +10093,7 @@ var AgentUI = ({
|
|
|
9919
10093
|
const [chosenApps, setChosenApps] = (0, import_react15.useState)(apps ?? defaultApps ?? BUILTIN_DEFAULT_APPS);
|
|
9920
10094
|
const [availableApps, setAvailableApps] = (0, import_react15.useState)([]);
|
|
9921
10095
|
const [authAppsLoading, setAuthAppsLoading] = (0, import_react15.useState)(autoLoadApps && hasApiKey);
|
|
10096
|
+
const [detectedLLM, setDetectedLLM] = (0, import_react15.useState)(null);
|
|
9922
10097
|
const [executionApps, setExecutionApps] = (0, import_react15.useState)([]);
|
|
9923
10098
|
const [resolvedToolApps, setResolvedToolApps] = (0, import_react15.useState)({});
|
|
9924
10099
|
const [appSearchOpen, setAppSearchOpen] = (0, import_react15.useState)(false);
|
|
@@ -9953,9 +10128,25 @@ var AgentUI = ({
|
|
|
9953
10128
|
const [error, setError] = (0, import_react15.useState)(null);
|
|
9954
10129
|
const [searchParams, setSearchParams] = (0, import_react_router_dom2.useSearchParams)();
|
|
9955
10130
|
const initialViewParam = searchParams.get("agentView");
|
|
9956
|
-
const
|
|
9957
|
-
initialViewParam === "detailed"
|
|
9958
|
-
|
|
10131
|
+
const readStoredViewMode = () => {
|
|
10132
|
+
if (initialViewParam === "detailed") return "detailed";
|
|
10133
|
+
if (typeof window === "undefined") return "simple";
|
|
10134
|
+
try {
|
|
10135
|
+
const stored = window.localStorage.getItem("shuffle-agents-view-mode");
|
|
10136
|
+
if (stored === "detailed" || stored === "simple") return stored;
|
|
10137
|
+
} catch {
|
|
10138
|
+
}
|
|
10139
|
+
return "simple";
|
|
10140
|
+
};
|
|
10141
|
+
const [viewMode, setViewMode] = (0, import_react15.useState)(readStoredViewMode);
|
|
10142
|
+
(0, import_react15.useEffect)(() => {
|
|
10143
|
+
try {
|
|
10144
|
+
if (typeof window !== "undefined") {
|
|
10145
|
+
window.localStorage.setItem("shuffle-agents-view-mode", viewMode);
|
|
10146
|
+
}
|
|
10147
|
+
} catch {
|
|
10148
|
+
}
|
|
10149
|
+
}, [viewMode]);
|
|
9959
10150
|
const [attachedImages, setAttachedImages] = (0, import_react15.useState)([]);
|
|
9960
10151
|
const [nowTick, setNowTick] = (0, import_react15.useState)(() => Math.floor(Date.now() / 1e3));
|
|
9961
10152
|
const [localRunStart, setLocalRunStart] = (0, import_react15.useState)(null);
|
|
@@ -10191,12 +10382,23 @@ var AgentUI = ({
|
|
|
10191
10382
|
const list = Array.isArray(result) ? result : result?.data || [];
|
|
10192
10383
|
const seen = /* @__PURE__ */ new Set();
|
|
10193
10384
|
const loaded = [];
|
|
10385
|
+
let detectedFromEntries = null;
|
|
10194
10386
|
for (const entry of list) {
|
|
10195
10387
|
const app = entry?.app || entry;
|
|
10196
10388
|
const name = app?.name;
|
|
10197
10389
|
if (!name) continue;
|
|
10198
10390
|
const valid = entry?.active || entry?.validation?.valid || entry?.hasValidAuth || app?.is_valid || app?.tested;
|
|
10199
10391
|
if (valid === false) continue;
|
|
10392
|
+
if (!detectedFromEntries && (name.toLowerCase() === "openai" || app?.id === "5d19dd82517870c68d40cacad9b5ca91")) {
|
|
10393
|
+
const urlField = (entry?.fields || []).find((f) => (f?.key || "").toLowerCase() === "url");
|
|
10394
|
+
const urlVal = (urlField?.value || "").trim();
|
|
10395
|
+
if (urlVal) {
|
|
10396
|
+
const preset = detectLLMProvider(urlVal);
|
|
10397
|
+
if (preset) {
|
|
10398
|
+
detectedFromEntries = { label: preset.label, url: urlVal, logo: getProviderLogoUrl(preset.label, urlVal) };
|
|
10399
|
+
}
|
|
10400
|
+
}
|
|
10401
|
+
}
|
|
10200
10402
|
const key = normalizeAgentAppName(name);
|
|
10201
10403
|
if (seen.has(key)) continue;
|
|
10202
10404
|
seen.add(key);
|
|
@@ -10208,6 +10410,7 @@ var AgentUI = ({
|
|
|
10208
10410
|
}
|
|
10209
10411
|
if (signal?.cancelled) return;
|
|
10210
10412
|
setAvailableApps(loaded);
|
|
10413
|
+
setDetectedLLM(detectedFromEntries);
|
|
10211
10414
|
} catch {
|
|
10212
10415
|
} finally {
|
|
10213
10416
|
if (!signal?.cancelled) setAuthAppsLoading(false);
|
|
@@ -10469,7 +10672,12 @@ var AgentUI = ({
|
|
|
10469
10672
|
setSimpleSubmitAttempted(false);
|
|
10470
10673
|
setError(null);
|
|
10471
10674
|
setLocalRunStart(null);
|
|
10472
|
-
|
|
10675
|
+
try {
|
|
10676
|
+
const stored = typeof window !== "undefined" ? window.localStorage.getItem("shuffle-agents-view-mode") : null;
|
|
10677
|
+
setViewMode(stored === "detailed" ? "detailed" : "simple");
|
|
10678
|
+
} catch {
|
|
10679
|
+
setViewMode("simple");
|
|
10680
|
+
}
|
|
10473
10681
|
setShowStarter(false);
|
|
10474
10682
|
userPickedStartRef.current = false;
|
|
10475
10683
|
if (readUrlParams && typeof window !== "undefined") {
|
|
@@ -11909,8 +12117,19 @@ var AgentUI = ({
|
|
|
11909
12117
|
"&:hover": { color: "hsl(var(--foreground))", bgcolor: "hsl(var(--muted) / 0.5)" }
|
|
11910
12118
|
},
|
|
11911
12119
|
children: [
|
|
11912
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
11913
|
-
|
|
12120
|
+
detectedLLM?.logo ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
12121
|
+
import_material16.Box,
|
|
12122
|
+
{
|
|
12123
|
+
component: "img",
|
|
12124
|
+
src: detectedLLM.logo,
|
|
12125
|
+
alt: "",
|
|
12126
|
+
sx: { width: 14, height: 14, borderRadius: "3px", objectFit: "contain", display: "block" },
|
|
12127
|
+
onError: (e) => {
|
|
12128
|
+
e.currentTarget.style.display = "none";
|
|
12129
|
+
}
|
|
12130
|
+
}
|
|
12131
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react11.Settings, { size: 14 }),
|
|
12132
|
+
detectedLLM?.label || "Choose LLM"
|
|
11914
12133
|
]
|
|
11915
12134
|
}
|
|
11916
12135
|
) }),
|
|
@@ -12144,7 +12363,7 @@ var AgentUI = ({
|
|
|
12144
12363
|
AgentRunDiagnosisBanner_default,
|
|
12145
12364
|
{
|
|
12146
12365
|
run: execution?.results?.length ? execution : agentData,
|
|
12147
|
-
sx: { px:
|
|
12366
|
+
sx: { px: 1.5, pb: 0, mb: 2 },
|
|
12148
12367
|
executionId: execution?.execution_id,
|
|
12149
12368
|
onJumpToEvidence: (decisionIndex) => {
|
|
12150
12369
|
const dec = (agentData?.decisions || [])[decisionIndex];
|
|
@@ -12369,14 +12588,14 @@ var AgentUI = ({
|
|
|
12369
12588
|
] })
|
|
12370
12589
|
] });
|
|
12371
12590
|
})() : !finishAnswer && isRunning ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.Typography, { sx: { fontSize: "0.85rem", color: "hsl(var(--muted-foreground))" }, children: "Waiting for the agent to produce the first step." }) : !finishAnswer ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.Typography, { sx: { fontSize: "0.85rem", color: "hsl(var(--muted-foreground))" }, children: "No final answer was returned. Open Detailed to inspect each step." }) : null,
|
|
12372
|
-
|
|
12591
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material16.Box, { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
12373
12592
|
import_material16.Button,
|
|
12374
12593
|
{
|
|
12375
12594
|
size: "small",
|
|
12376
12595
|
variant: "text",
|
|
12377
12596
|
onClick: () => setViewMode("detailed"),
|
|
12378
12597
|
sx: { color: "hsl(var(--primary))", textTransform: "none", px: 0 },
|
|
12379
|
-
children: "View detailed timeline \u2192"
|
|
12598
|
+
children: isRunning ? "View live detailed timeline \u2192" : "View detailed timeline \u2192"
|
|
12380
12599
|
}
|
|
12381
12600
|
) })
|
|
12382
12601
|
] });
|
|
@@ -12657,8 +12876,6 @@ var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
|
12657
12876
|
var import_react17 = require("react");
|
|
12658
12877
|
var OPENAI_APP_NAME = "OpenAI";
|
|
12659
12878
|
var OPENAI_APP_ID = "5d19dd82517870c68d40cacad9b5ca91";
|
|
12660
|
-
var SHUFFLE_AI_PRESET = "Shuffle AI";
|
|
12661
|
-
var CUSTOM_PRESET = "Custom / self-hosted";
|
|
12662
12879
|
var OPENAI_ALGOLIA_APP = {
|
|
12663
12880
|
name: OPENAI_APP_NAME,
|
|
12664
12881
|
description: "OpenAI-compatible LLM endpoint for agent operations",
|
|
@@ -12678,32 +12895,18 @@ var OPENAI_ALGOLIA_APP = {
|
|
|
12678
12895
|
triggers: [],
|
|
12679
12896
|
verified: true
|
|
12680
12897
|
};
|
|
12681
|
-
var
|
|
12682
|
-
|
|
12683
|
-
|
|
12684
|
-
|
|
12685
|
-
|
|
12686
|
-
|
|
12687
|
-
|
|
12688
|
-
|
|
12689
|
-
|
|
12690
|
-
|
|
12691
|
-
|
|
12692
|
-
|
|
12693
|
-
{ label: CUSTOM_PRESET, url: "" }
|
|
12694
|
-
];
|
|
12695
|
-
var PROVIDER_DOMAINS = {
|
|
12696
|
-
"Shuffle AI": "shuffler.io",
|
|
12697
|
-
OpenAI: "openai.com",
|
|
12698
|
-
Anthropic: "anthropic.com",
|
|
12699
|
-
"Google Gemini": "gemini.google.com",
|
|
12700
|
-
Mistral: "mistral.ai",
|
|
12701
|
-
Groq: "groq.com",
|
|
12702
|
-
DeepSeek: "deepseek.com",
|
|
12703
|
-
"Together AI": "together.ai",
|
|
12704
|
-
OpenRouter: "openrouter.ai",
|
|
12705
|
-
"Ollama (localhost)": "ollama.com",
|
|
12706
|
-
"LM Studio (localhost)": "lmstudio.ai"
|
|
12898
|
+
var CUSTOM_MODEL = "Custom\u2026";
|
|
12899
|
+
var PROVIDER_MODELS = {
|
|
12900
|
+
OpenAI: ["gpt-5.5", "gpt-5.5-pro", "gpt-5.4", "gpt-5.4-pro", "gpt-5.4-mini", "gpt-5.4-nano", "gpt-5.2", "gpt-5", "gpt-5-mini", "gpt-5-nano", "gpt-4.1", "o4-mini"],
|
|
12901
|
+
Anthropic: ["claude-opus-4-5", "claude-sonnet-4-5", "claude-haiku-4-5", "claude-opus-4", "claude-sonnet-4", "claude-3-7-sonnet-latest"],
|
|
12902
|
+
"Google Gemini": ["gemini-3-pro-preview", "gemini-3-flash-preview", "gemini-3.1-pro-preview", "gemini-3.1-flash-lite-preview", "gemini-3.5-flash", "gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.5-flash-lite"],
|
|
12903
|
+
Mistral: ["mistral-large-2026", "mistral-medium-3", "mistral-small-3.2", "codestral-2026", "magistral-medium-2026", "ministral-8b-latest"],
|
|
12904
|
+
Groq: ["llama-4-maverick-17b-128e", "llama-4-scout-17b-16e", "llama-3.3-70b-versatile", "deepseek-r1-distill-llama-70b", "qwen-3-32b", "kimi-k2-instruct"],
|
|
12905
|
+
DeepSeek: ["deepseek-v3.5", "deepseek-v3", "deepseek-r1", "deepseek-coder-v3"],
|
|
12906
|
+
"Together AI": ["meta-llama/Llama-4-Maverick-17B-128E-Instruct", "meta-llama/Llama-4-Scout-17B-16E-Instruct", "deepseek-ai/DeepSeek-V3", "deepseek-ai/DeepSeek-R1", "Qwen/Qwen3-235B-A22B"],
|
|
12907
|
+
OpenRouter: ["openai/gpt-5.5", "openai/gpt-5.4", "anthropic/claude-opus-4.5", "anthropic/claude-sonnet-4.5", "google/gemini-3-pro-preview", "google/gemini-3-flash-preview", "meta-llama/llama-4-maverick", "deepseek/deepseek-v3.5", "x-ai/grok-4"],
|
|
12908
|
+
"Ollama (localhost)": ["llama3.3", "llama3.2", "qwen3", "qwen3:32b", "deepseek-r1", "deepseek-r1:70b", "mistral-small3", "phi4", "gemma3"],
|
|
12909
|
+
"LM Studio (localhost)": ["llama-3.3-70b-instruct", "qwen3-32b", "deepseek-r1-distill-qwen-32b", "mistral-small-3", "phi-4", "gemma-3-27b"]
|
|
12707
12910
|
};
|
|
12708
12911
|
var ProviderLogo = ({ label, url }) => {
|
|
12709
12912
|
const [errored, setErrored] = (0, import_react16.useState)(false);
|
|
@@ -12733,46 +12936,16 @@ var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serv
|
|
|
12733
12936
|
status: "pending",
|
|
12734
12937
|
credentials: {}
|
|
12735
12938
|
};
|
|
12736
|
-
const
|
|
12737
|
-
const
|
|
12738
|
-
(0, import_react16.
|
|
12739
|
-
|
|
12740
|
-
const failedEntries = openaiEntries.filter((e) => e.validation && e.validation.valid === false && e.id);
|
|
12741
|
-
if (failedEntries.length === 0) return;
|
|
12742
|
-
let cancelled = false;
|
|
12743
|
-
(async () => {
|
|
12744
|
-
let deletedAny = false;
|
|
12745
|
-
for (const entry of failedEntries) {
|
|
12746
|
-
const id = entry.id;
|
|
12747
|
-
if (attemptedDeletionRef.current.has(id)) continue;
|
|
12748
|
-
attemptedDeletionRef.current.add(id);
|
|
12749
|
-
try {
|
|
12750
|
-
const resp = await fetch(getApiUrl(`/api/v1/apps/authentication/${id}`), {
|
|
12751
|
-
method: "DELETE",
|
|
12752
|
-
credentials: "include",
|
|
12753
|
-
headers: { ...getAuthHeader() }
|
|
12754
|
-
});
|
|
12755
|
-
if (resp.ok) deletedAny = true;
|
|
12756
|
-
} catch (err) {
|
|
12757
|
-
console.error("[LocalLLMConfig] Failed to auto-delete failed OpenAI auth:", err);
|
|
12758
|
-
}
|
|
12759
|
-
}
|
|
12760
|
-
if (!cancelled && deletedAny) {
|
|
12761
|
-
await refreshAuth();
|
|
12762
|
-
refreshAllIntegrationStatus();
|
|
12763
|
-
}
|
|
12764
|
-
})();
|
|
12765
|
-
return () => {
|
|
12766
|
-
cancelled = true;
|
|
12767
|
-
};
|
|
12768
|
-
}, [openaiEntries, authState.status, refreshAuth]);
|
|
12939
|
+
const savedUrlFromEntry = (openaiEntries[0]?.fields || []).find((f) => (f?.key || "").toLowerCase() === "url")?.value || "";
|
|
12940
|
+
const currentUrl = (authState.credentials?.url || savedUrlFromEntry || "").trim();
|
|
12941
|
+
const [customModel, setCustomModel] = (0, import_react16.useState)("");
|
|
12942
|
+
const [customMode, setCustomMode] = (0, import_react16.useState)(false);
|
|
12769
12943
|
const hasOpenAIEntries = openaiEntries.length > 0;
|
|
12770
12944
|
const effectivePreset = (0, import_react16.useMemo)(() => {
|
|
12771
12945
|
if (selectedPreset) return selectedPreset;
|
|
12772
12946
|
if (!currentUrl && !hasOpenAIEntries) return SHUFFLE_AI_PRESET;
|
|
12773
12947
|
if (!currentUrl) return "";
|
|
12774
|
-
|
|
12775
|
-
return match ? match.label : CUSTOM_PRESET;
|
|
12948
|
+
return detectLLMProvider(currentUrl)?.label || CUSTOM_PRESET;
|
|
12776
12949
|
}, [selectedPreset, currentUrl, hasOpenAIEntries]);
|
|
12777
12950
|
const applyShuffleAI = async () => {
|
|
12778
12951
|
let deletedAny = false;
|
|
@@ -12809,7 +12982,16 @@ var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serv
|
|
|
12809
12982
|
setSelectedPreset(label);
|
|
12810
12983
|
const preset = ENDPOINT_PRESETS.find((p) => p.label === label);
|
|
12811
12984
|
if (!preset) return;
|
|
12812
|
-
|
|
12985
|
+
const topModel = PROVIDER_MODELS[label]?.[0] || "";
|
|
12986
|
+
const existingModel = authState.credentials?.model || "";
|
|
12987
|
+
const nextModel = topModel || existingModel;
|
|
12988
|
+
setCustomMode(false);
|
|
12989
|
+
setCustomModel("");
|
|
12990
|
+
handleAuthChange(OPENAI_APP_ID, {
|
|
12991
|
+
...authState.credentials,
|
|
12992
|
+
url: preset.label === CUSTOM_PRESET ? customUrl : preset.url,
|
|
12993
|
+
...nextModel ? { model: nextModel } : {}
|
|
12994
|
+
});
|
|
12813
12995
|
};
|
|
12814
12996
|
const handleCustomUrlChange = (value) => {
|
|
12815
12997
|
setCustomUrl(value);
|
|
@@ -12884,7 +13066,7 @@ var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serv
|
|
|
12884
13066
|
);
|
|
12885
13067
|
},
|
|
12886
13068
|
slotProps: {
|
|
12887
|
-
paper: { sx: { bgcolor: "hsl(var(--popover))", color: "hsl(var(--popover-foreground))", border: "1px solid hsl(var(--border))" } },
|
|
13069
|
+
paper: { sx: { bgcolor: "hsl(var(--popover))", color: "hsl(var(--popover-foreground))", border: "1px solid hsl(var(--border))", minWidth: 580 } },
|
|
12888
13070
|
popper: { sx: { zIndex: 9999 } }
|
|
12889
13071
|
}
|
|
12890
13072
|
}
|
|
@@ -12947,6 +13129,59 @@ var LocalLLMConfig = ({ compact, globalUrl, userdata, isLoaded, isLoggedIn, serv
|
|
|
12947
13129
|
hideDocsLink: true,
|
|
12948
13130
|
hideUrlFields: true,
|
|
12949
13131
|
borderless: true,
|
|
13132
|
+
compactAuthForm: true,
|
|
13133
|
+
extraFieldsSlot: (PROVIDER_MODELS[effectivePreset]?.length ?? 0) > 0 ? ({ credentials, setField }) => {
|
|
13134
|
+
const liveModel = credentials.model || "";
|
|
13135
|
+
const presetModels = PROVIDER_MODELS[effectivePreset] || [];
|
|
13136
|
+
const liveIsCustom = liveModel !== "" && !presetModels.includes(liveModel);
|
|
13137
|
+
const showCustom = customMode || liveIsCustom;
|
|
13138
|
+
const liveSelectValue = showCustom ? CUSTOM_MODEL : liveModel || null;
|
|
13139
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material18.Box, { sx: { display: "flex", flexDirection: "column", gap: 1 }, children: [
|
|
13140
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material18.Typography, { sx: { fontSize: "0.85rem", fontWeight: 600, color: "hsl(var(--foreground))" }, children: "Model" }),
|
|
13141
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
13142
|
+
import_material18.Autocomplete,
|
|
13143
|
+
{
|
|
13144
|
+
size: "small",
|
|
13145
|
+
fullWidth: true,
|
|
13146
|
+
disableClearable: true,
|
|
13147
|
+
options: [...presetModels, CUSTOM_MODEL],
|
|
13148
|
+
value: liveSelectValue,
|
|
13149
|
+
onChange: (_e, val) => {
|
|
13150
|
+
if (!val) return;
|
|
13151
|
+
if (val === CUSTOM_MODEL) {
|
|
13152
|
+
setCustomMode(true);
|
|
13153
|
+
setField("model", customModel);
|
|
13154
|
+
} else {
|
|
13155
|
+
setCustomMode(false);
|
|
13156
|
+
setCustomModel("");
|
|
13157
|
+
setField("model", val);
|
|
13158
|
+
}
|
|
13159
|
+
},
|
|
13160
|
+
isOptionEqualToValue: (opt, val) => opt === val,
|
|
13161
|
+
slotProps: {
|
|
13162
|
+
paper: { sx: { bgcolor: "hsl(var(--popover))", color: "hsl(var(--popover-foreground))", border: "1px solid hsl(var(--border))" } },
|
|
13163
|
+
popper: { sx: { zIndex: 9999 } }
|
|
13164
|
+
},
|
|
13165
|
+
renderInput: (params) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material18.TextField, { ...params, placeholder: "Select a model\u2026" })
|
|
13166
|
+
}
|
|
13167
|
+
),
|
|
13168
|
+
showCustom && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
13169
|
+
import_material18.TextField,
|
|
13170
|
+
{
|
|
13171
|
+
size: "small",
|
|
13172
|
+
fullWidth: true,
|
|
13173
|
+
placeholder: "Enter a custom model identifier",
|
|
13174
|
+
value: customModel || (liveIsCustom ? liveModel : ""),
|
|
13175
|
+
onChange: (e) => {
|
|
13176
|
+
setCustomModel(e.target.value);
|
|
13177
|
+
setField("model", e.target.value);
|
|
13178
|
+
},
|
|
13179
|
+
helperText: "Exact model name as expected by the provider's API",
|
|
13180
|
+
sx: { "& .MuiFormHelperText-root": { color: "hsl(var(--muted-foreground))" } }
|
|
13181
|
+
}
|
|
13182
|
+
)
|
|
13183
|
+
] });
|
|
13184
|
+
} : void 0,
|
|
12950
13185
|
globalUrl,
|
|
12951
13186
|
userdata,
|
|
12952
13187
|
isLoaded,
|
|
@@ -13024,9 +13259,16 @@ var AgentRunDrawer = ({
|
|
|
13024
13259
|
setActiveTab("localLLM");
|
|
13025
13260
|
}
|
|
13026
13261
|
};
|
|
13262
|
+
const onClose2 = () => {
|
|
13263
|
+
onClose();
|
|
13264
|
+
};
|
|
13027
13265
|
window.addEventListener("agent-drawer-open", onOpen);
|
|
13028
|
-
|
|
13029
|
-
|
|
13266
|
+
window.addEventListener("agent-drawer-close", onClose2);
|
|
13267
|
+
return () => {
|
|
13268
|
+
window.removeEventListener("agent-drawer-open", onOpen);
|
|
13269
|
+
window.removeEventListener("agent-drawer-close", onClose2);
|
|
13270
|
+
};
|
|
13271
|
+
}, [onClose]);
|
|
13030
13272
|
const effectiveLocalLLMSlot = localLLMSlot ?? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
13031
13273
|
LocalLLMConfig_default,
|
|
13032
13274
|
{
|
|
@@ -13498,7 +13740,7 @@ var STATUS_CONFIG = {
|
|
|
13498
13740
|
EXECUTING: { icon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react13.Loader2, { size: 16 }), color: "hsl(var(--severity-medium, 38 92% 50%))", label: "Running" },
|
|
13499
13741
|
RUNNING: { icon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react13.Loader2, { size: 16 }), color: "hsl(var(--severity-medium, 38 92% 50%))", label: "Running" },
|
|
13500
13742
|
WAITING: { icon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react13.Clock, { size: 16 }), color: "hsl(var(--severity-info, 217 91% 60%))", label: "Waiting" },
|
|
13501
|
-
LIMIT_REACHED: { icon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react14.AlertTriangle, { size: 16 }), color: "hsl(var(--severity-
|
|
13743
|
+
LIMIT_REACHED: { icon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react14.AlertTriangle, { size: 16 }), color: "hsl(var(--severity-critical, 0 72% 55%))", label: "Limit reached" }
|
|
13502
13744
|
};
|
|
13503
13745
|
var getEffectiveStatus = (run) => {
|
|
13504
13746
|
const raw = (run.status || "").toUpperCase();
|
|
@@ -13511,21 +13753,126 @@ var getEffectiveStatus = (run) => {
|
|
|
13511
13753
|
}
|
|
13512
13754
|
return raw;
|
|
13513
13755
|
};
|
|
13514
|
-
var
|
|
13515
|
-
|
|
13516
|
-
|
|
13517
|
-
|
|
13518
|
-
|
|
13519
|
-
if (arg
|
|
13520
|
-
|
|
13521
|
-
|
|
13522
|
-
|
|
13756
|
+
var SOURCE_ICON_SIZE = 18;
|
|
13757
|
+
var looksLikeExecutionId = (s) => /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(s.trim());
|
|
13758
|
+
var DATASTORE_KEY_RE = /\bKey:\s*(\S+)/i;
|
|
13759
|
+
var DATASTORE_CATEGORY_RE = /\bCategory:\s*(\S+)/i;
|
|
13760
|
+
var parseDatastoreTask = (arg) => {
|
|
13761
|
+
if (!arg) return null;
|
|
13762
|
+
const k = arg.match(DATASTORE_KEY_RE);
|
|
13763
|
+
const c = arg.match(DATASTORE_CATEGORY_RE);
|
|
13764
|
+
if (!k || !c) return null;
|
|
13765
|
+
const key = (k[1] || "").trim();
|
|
13766
|
+
const category = (c[1] || "").trim();
|
|
13767
|
+
if (!key || !category) return null;
|
|
13768
|
+
return { key, category };
|
|
13769
|
+
};
|
|
13770
|
+
var isAIAgentResult = (result) => String(result?.action?.app_name || "").trim().toLowerCase() === "ai agent";
|
|
13771
|
+
var getAIAgentResultPayload = (run) => {
|
|
13772
|
+
const results = Array.isArray(run.results) ? run.results : [];
|
|
13773
|
+
const agentResult = results.find(isAIAgentResult);
|
|
13774
|
+
if (!agentResult || typeof agentResult !== "object" || !("result" in agentResult)) return null;
|
|
13775
|
+
return tryParseJson(agentResult.result);
|
|
13776
|
+
};
|
|
13777
|
+
var getDirectAgentInput = (payload) => {
|
|
13778
|
+
if (!payload || typeof payload !== "object") return null;
|
|
13779
|
+
const obj = payload;
|
|
13780
|
+
if (typeof obj.original_input === "string" && obj.original_input.trim()) {
|
|
13781
|
+
return obj.original_input.trim();
|
|
13782
|
+
}
|
|
13783
|
+
if (typeof obj.input === "string" && obj.input.trim()) {
|
|
13784
|
+
return obj.input.trim();
|
|
13785
|
+
}
|
|
13786
|
+
return null;
|
|
13787
|
+
};
|
|
13788
|
+
var findDatastoreTaskInRun = (run) => {
|
|
13789
|
+
const agentInput = getDirectAgentInput(getAIAgentResultPayload(run));
|
|
13790
|
+
const agentHit = parseDatastoreTask(agentInput || void 0);
|
|
13791
|
+
if (agentHit) return agentHit;
|
|
13792
|
+
const anyRun = run;
|
|
13793
|
+
const candidates = [];
|
|
13794
|
+
if (typeof anyRun.original_input === "string") candidates.push(anyRun.original_input);
|
|
13795
|
+
if (typeof anyRun.input === "string") candidates.push(anyRun.input);
|
|
13796
|
+
if (run.execution_argument) candidates.push(run.execution_argument);
|
|
13797
|
+
if (run.result) candidates.push(run.result);
|
|
13798
|
+
if (Array.isArray(anyRun.results)) {
|
|
13799
|
+
try {
|
|
13800
|
+
candidates.push(JSON.stringify(anyRun.results));
|
|
13801
|
+
} catch {
|
|
13802
|
+
}
|
|
13803
|
+
}
|
|
13804
|
+
for (const c of candidates) {
|
|
13805
|
+
const hit = parseDatastoreTask(c);
|
|
13806
|
+
if (hit) return hit;
|
|
13807
|
+
}
|
|
13808
|
+
return null;
|
|
13809
|
+
};
|
|
13810
|
+
var classifyRunSource = (run) => {
|
|
13811
|
+
const raw = (run.execution_source || "").trim();
|
|
13812
|
+
const src = raw.toLowerCase();
|
|
13813
|
+
const ds = findDatastoreTaskInRun(run);
|
|
13814
|
+
if (ds || src.includes("datastore") || src.includes("enrichment") || src.includes("automation")) {
|
|
13815
|
+
return {
|
|
13816
|
+
kind: "datastore",
|
|
13817
|
+
label: "Datastore automation",
|
|
13818
|
+
reason: ds ? `Started by datastore automation (category "${ds.category}", key "${ds.key}"). Click to open in Datastore.` : "Started by a datastore automation (e.g. enrichment trigger).",
|
|
13819
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react13.Database, { size: SOURCE_ICON_SIZE }),
|
|
13820
|
+
datastoreKey: ds?.key,
|
|
13821
|
+
datastoreCategory: ds?.category
|
|
13822
|
+
};
|
|
13823
|
+
}
|
|
13824
|
+
if (src.includes("schedule") || src.includes("cron")) {
|
|
13825
|
+
return {
|
|
13826
|
+
kind: "schedule",
|
|
13827
|
+
label: "Schedule",
|
|
13828
|
+
reason: "Started by a scheduled trigger (cron).",
|
|
13829
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react13.Clock, { size: SOURCE_ICON_SIZE })
|
|
13830
|
+
};
|
|
13831
|
+
}
|
|
13832
|
+
if (src.includes("webhook") || src.includes("http")) {
|
|
13833
|
+
return {
|
|
13834
|
+
kind: "webhook",
|
|
13835
|
+
label: "Webhook",
|
|
13836
|
+
reason: "Started by an incoming webhook / HTTP trigger.",
|
|
13837
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react13.Globe, { size: SOURCE_ICON_SIZE })
|
|
13838
|
+
};
|
|
13839
|
+
}
|
|
13840
|
+
if (src.includes("form")) {
|
|
13841
|
+
return {
|
|
13842
|
+
kind: "form",
|
|
13843
|
+
label: "Form",
|
|
13844
|
+
reason: "Started by a form submission.",
|
|
13845
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react13.FileText, { size: SOURCE_ICON_SIZE })
|
|
13846
|
+
};
|
|
13847
|
+
}
|
|
13848
|
+
if (raw && looksLikeExecutionId(raw)) {
|
|
13849
|
+
return {
|
|
13850
|
+
kind: "workflow",
|
|
13851
|
+
label: "Workflow",
|
|
13852
|
+
reason: "Started by another workflow as a subflow.",
|
|
13853
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react13.Workflow, { size: SOURCE_ICON_SIZE })
|
|
13854
|
+
};
|
|
13855
|
+
}
|
|
13856
|
+
if (src === "" || src === "manual" || src === "default" || src === "demo") {
|
|
13857
|
+
return {
|
|
13858
|
+
kind: "manual",
|
|
13859
|
+
label: "Manual",
|
|
13860
|
+
reason: "Started manually from the Agents UI.",
|
|
13861
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react13.Hand, { size: SOURCE_ICON_SIZE })
|
|
13862
|
+
};
|
|
13863
|
+
}
|
|
13864
|
+
return {
|
|
13865
|
+
kind: "unknown",
|
|
13866
|
+
label: raw || "Unknown",
|
|
13867
|
+
reason: raw ? `Started by "${raw}".` : "Trigger source unknown.",
|
|
13868
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react13.Zap, { size: SOURCE_ICON_SIZE })
|
|
13869
|
+
};
|
|
13523
13870
|
};
|
|
13524
13871
|
var getRunIconColor = (run) => {
|
|
13525
13872
|
const status = getEffectiveStatus(run);
|
|
13526
13873
|
if (status === "FINISHED" || status === "SUCCESS") return "hsl(var(--severity-low, 142 71% 45%))";
|
|
13527
13874
|
if (status === "FAILED" || status === "ABORTED") return "hsl(var(--severity-critical, 0 72% 55%))";
|
|
13528
|
-
if (status === "LIMIT_REACHED") return "hsl(var(--severity-
|
|
13875
|
+
if (status === "LIMIT_REACHED") return "hsl(var(--severity-critical, 0 72% 55%))";
|
|
13529
13876
|
if (status === "EXECUTING" || status === "RUNNING") return "hsl(var(--severity-medium, 38 92% 50%))";
|
|
13530
13877
|
return "hsl(var(--primary, 24 100% 50%))";
|
|
13531
13878
|
};
|
|
@@ -13623,9 +13970,12 @@ var tryParseJson = (s) => {
|
|
|
13623
13970
|
}
|
|
13624
13971
|
};
|
|
13625
13972
|
var getRunPrompt = (run) => {
|
|
13626
|
-
const
|
|
13973
|
+
const anyRun = run;
|
|
13974
|
+
const agentInput = getDirectAgentInput(getAIAgentResultPayload(run));
|
|
13975
|
+
if (agentInput) return agentInput;
|
|
13976
|
+
const results = Array.isArray(anyRun.results) ? anyRun.results : null;
|
|
13627
13977
|
if (results) {
|
|
13628
|
-
const agentResult = results.find(
|
|
13978
|
+
const agentResult = results.find(isAIAgentResult);
|
|
13629
13979
|
if (agentResult?.result) {
|
|
13630
13980
|
const hit = deepFindPrompt(tryParseJson(agentResult.result));
|
|
13631
13981
|
if (hit) return hit;
|
|
@@ -13636,6 +13986,12 @@ var getRunPrompt = (run) => {
|
|
|
13636
13986
|
if (hit) return hit;
|
|
13637
13987
|
}
|
|
13638
13988
|
}
|
|
13989
|
+
if (typeof anyRun.original_input === "string" && anyRun.original_input.trim()) {
|
|
13990
|
+
return anyRun.original_input.trim();
|
|
13991
|
+
}
|
|
13992
|
+
if (typeof anyRun.input === "string" && anyRun.input.trim()) {
|
|
13993
|
+
return anyRun.input.trim();
|
|
13994
|
+
}
|
|
13639
13995
|
if (run.result) {
|
|
13640
13996
|
const hit = deepFindPrompt(tryParseJson(run.result));
|
|
13641
13997
|
if (hit) return hit;
|
|
@@ -13676,7 +14032,9 @@ var getRunSubtitle = (run) => {
|
|
|
13676
14032
|
if (run.result.length < 120) return run.result;
|
|
13677
14033
|
}
|
|
13678
14034
|
}
|
|
13679
|
-
|
|
14035
|
+
const status = getEffectiveStatus(run);
|
|
14036
|
+
const isRunning = status === "EXECUTING" || status === "RUNNING" || status === "WAITING";
|
|
14037
|
+
return run.execution_source || (isRunning ? "Agent still running\u2026" : "Agent execution");
|
|
13680
14038
|
};
|
|
13681
14039
|
var normalizeResultStatus = (s) => {
|
|
13682
14040
|
const v = (s || "").toUpperCase();
|
|
@@ -13778,41 +14136,60 @@ var AgentRunRow = ({ run, onClick, sx, appIcons, onAppClick }) => {
|
|
|
13778
14136
|
...Array.isArray(sx) ? sx : sx ? [sx] : []
|
|
13779
14137
|
],
|
|
13780
14138
|
children: [
|
|
13781
|
-
|
|
13782
|
-
|
|
13783
|
-
{
|
|
13784
|
-
|
|
13785
|
-
|
|
13786
|
-
|
|
13787
|
-
|
|
13788
|
-
|
|
13789
|
-
|
|
13790
|
-
|
|
13791
|
-
|
|
13792
|
-
|
|
13793
|
-
|
|
13794
|
-
|
|
13795
|
-
|
|
13796
|
-
|
|
13797
|
-
|
|
14139
|
+
(() => {
|
|
14140
|
+
const sourceInfo = classifyRunSource(run);
|
|
14141
|
+
const dsLink = sourceInfo.kind === "datastore" && sourceInfo.datastoreKey && sourceInfo.datastoreCategory ? `https://shuffler.io/admin?tab=datastore&category=${encodeURIComponent(sourceInfo.datastoreCategory)}&key=${encodeURIComponent(sourceInfo.datastoreKey)}` : null;
|
|
14142
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
14143
|
+
import_material20.Tooltip,
|
|
14144
|
+
{
|
|
14145
|
+
title: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_material20.Box, { sx: { lineHeight: 1.4 }, children: [
|
|
14146
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material20.Box, { sx: { fontWeight: 600 }, children: sourceInfo.label }),
|
|
14147
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material20.Box, { sx: { opacity: 0.85 }, children: sourceInfo.reason })
|
|
14148
|
+
] }),
|
|
14149
|
+
placement: "top",
|
|
14150
|
+
arrow: true,
|
|
14151
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
14152
|
+
import_material20.Box,
|
|
14153
|
+
{
|
|
14154
|
+
onClick: dsLink ? (e) => {
|
|
14155
|
+
e.stopPropagation();
|
|
14156
|
+
window.open(dsLink, "_blank", "noopener,noreferrer");
|
|
14157
|
+
} : void 0,
|
|
14158
|
+
sx: {
|
|
14159
|
+
width: 40,
|
|
14160
|
+
height: 40,
|
|
14161
|
+
borderRadius: "50%",
|
|
14162
|
+
display: "flex",
|
|
14163
|
+
alignItems: "center",
|
|
14164
|
+
justifyContent: "center",
|
|
14165
|
+
bgcolor: `${iconColor}15`,
|
|
14166
|
+
color: iconColor,
|
|
14167
|
+
flexShrink: 0,
|
|
14168
|
+
cursor: dsLink ? "pointer" : "inherit",
|
|
14169
|
+
transition: "background 0.15s ease",
|
|
14170
|
+
"&:hover": dsLink ? { bgcolor: `${iconColor}30` } : void 0
|
|
14171
|
+
},
|
|
14172
|
+
children: sourceInfo.icon
|
|
14173
|
+
}
|
|
14174
|
+
)
|
|
14175
|
+
}
|
|
14176
|
+
);
|
|
14177
|
+
})(),
|
|
13798
14178
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_material20.Box, { sx: { flex: 1, minWidth: 0 }, children: [
|
|
13799
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.
|
|
13800
|
-
|
|
13801
|
-
|
|
13802
|
-
{
|
|
13803
|
-
|
|
13804
|
-
|
|
13805
|
-
|
|
13806
|
-
|
|
13807
|
-
|
|
13808
|
-
|
|
13809
|
-
|
|
13810
|
-
|
|
13811
|
-
|
|
13812
|
-
|
|
13813
|
-
),
|
|
13814
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material20.Box, { sx: { display: "flex", alignItems: "center", color: cfg.color, flexShrink: 0 }, children: cfg.icon })
|
|
13815
|
-
] }),
|
|
14179
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material20.Box, { sx: { display: "flex", alignItems: "center", gap: 1, mb: 0.25 }, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
14180
|
+
import_material20.Typography,
|
|
14181
|
+
{
|
|
14182
|
+
sx: {
|
|
14183
|
+
fontSize: "0.9rem",
|
|
14184
|
+
fontWeight: 500,
|
|
14185
|
+
color: "hsl(var(--foreground))",
|
|
14186
|
+
overflow: "hidden",
|
|
14187
|
+
textOverflow: "ellipsis",
|
|
14188
|
+
whiteSpace: "nowrap"
|
|
14189
|
+
},
|
|
14190
|
+
children: getRunTitle(run)
|
|
14191
|
+
}
|
|
14192
|
+
) }),
|
|
13816
14193
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
13817
14194
|
import_material20.Typography,
|
|
13818
14195
|
{
|
|
@@ -13907,18 +14284,7 @@ var AgentRunRow = ({ run, onClick, sx, appIcons, onAppClick }) => {
|
|
|
13907
14284
|
) }, t.name);
|
|
13908
14285
|
})
|
|
13909
14286
|
}
|
|
13910
|
-
) :
|
|
13911
|
-
import_material20.Typography,
|
|
13912
|
-
{
|
|
13913
|
-
sx: {
|
|
13914
|
-
fontSize: "0.7rem",
|
|
13915
|
-
color: "hsl(var(--muted-foreground))",
|
|
13916
|
-
opacity: 0.5,
|
|
13917
|
-
fontStyle: "italic"
|
|
13918
|
-
},
|
|
13919
|
-
children: "No apps"
|
|
13920
|
-
}
|
|
13921
|
-
)
|
|
14287
|
+
) : null
|
|
13922
14288
|
}
|
|
13923
14289
|
)
|
|
13924
14290
|
]
|
|
@@ -14739,6 +15105,15 @@ var AgentsView = ({
|
|
|
14739
15105
|
open: false,
|
|
14740
15106
|
tab: "localLLM"
|
|
14741
15107
|
});
|
|
15108
|
+
(0, import_react20.useEffect)(() => {
|
|
15109
|
+
if (typeof window === "undefined") return;
|
|
15110
|
+
const handler = (e) => {
|
|
15111
|
+
const detail = e.detail;
|
|
15112
|
+
setBuiltInDrawer({ open: true, tab: detail?.tab ?? "localLLM" });
|
|
15113
|
+
};
|
|
15114
|
+
window.addEventListener("agent-drawer-open", handler);
|
|
15115
|
+
return () => window.removeEventListener("agent-drawer-open", handler);
|
|
15116
|
+
}, []);
|
|
14742
15117
|
const effectiveSchedule = (0, import_react20.useCallback)(
|
|
14743
15118
|
async (info) => {
|
|
14744
15119
|
if (onSchedule) return onSchedule(info);
|