@arbidocs/blocks 0.4.73 → 0.4.74
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/agents/index.cjs +253 -253
- package/dist/agents/index.js +3 -3
- package/dist/agents/workflows/WorkflowRunner.d.ts +20 -4
- package/dist/agents/workflows/WorkflowStepBar.d.ts +23 -0
- package/dist/agents/workflows/run.d.ts +1 -0
- package/dist/agents/workflows/types.d.ts +2 -0
- package/dist/chat/index.cjs +124 -124
- package/dist/chat/index.js +3 -3
- package/dist/{chunk-IUR565UW.cjs → chunk-5LP54CWR.cjs} +32 -32
- package/dist/chunk-5LP54CWR.cjs.map +1 -0
- package/dist/{chunk-3SFFTSOI.cjs → chunk-7CVF3DK2.cjs} +5 -5
- package/dist/{chunk-3SFFTSOI.cjs.map → chunk-7CVF3DK2.cjs.map} +1 -1
- package/dist/{chunk-V3L5DONY.cjs → chunk-B4SRYJLM.cjs} +31 -2
- package/dist/chunk-B4SRYJLM.cjs.map +1 -0
- package/dist/{chunk-WOYUXVVQ.cjs → chunk-HITAN7JF.cjs} +4 -4
- package/dist/{chunk-WOYUXVVQ.cjs.map → chunk-HITAN7JF.cjs.map} +1 -1
- package/dist/{chunk-3VQYJBOI.js → chunk-HOXKR26S.js} +31 -4
- package/dist/chunk-HOXKR26S.js.map +1 -0
- package/dist/{chunk-KJ3QEKOJ.cjs → chunk-IPGKTUF7.cjs} +7 -33
- package/dist/chunk-IPGKTUF7.cjs.map +1 -0
- package/dist/{chunk-QDNXEB3T.js → chunk-KOSGX3UK.js} +5 -5
- package/dist/chunk-KOSGX3UK.js.map +1 -0
- package/dist/{chunk-ORA2XE7U.js → chunk-MK6NJQGF.js} +3 -3
- package/dist/{chunk-ORA2XE7U.js.map → chunk-MK6NJQGF.js.map} +1 -1
- package/dist/{chunk-GTNUQBXI.cjs → chunk-P2RBE3FD.cjs} +254 -102
- package/dist/chunk-P2RBE3FD.cjs.map +1 -0
- package/dist/{chunk-G5DP27DU.js → chunk-UIWLDSTF.js} +3 -29
- package/dist/chunk-UIWLDSTF.js.map +1 -0
- package/dist/{chunk-VRPRAU3J.js → chunk-WJEKRSPH.js} +3 -3
- package/dist/{chunk-VRPRAU3J.js.map → chunk-WJEKRSPH.js.map} +1 -1
- package/dist/{chunk-2P3T23C7.js → chunk-YWYVIQ7T.js} +256 -104
- package/dist/chunk-YWYVIQ7T.js.map +1 -0
- package/dist/connect/index.cjs +95 -36
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.js +80 -21
- package/dist/connect/index.js.map +1 -1
- package/dist/connection/ConnectedWorkflowRunner.d.ts +5 -1
- package/dist/connection/useWorkflowThread.d.ts +4 -0
- package/dist/index.cjs +382 -382
- package/dist/index.js +6 -6
- package/dist/studio/index.cjs +4 -4
- package/dist/studio/index.js +3 -3
- package/dist/workflow-canvas/StepInspector.d.ts +11 -0
- package/dist/workflow-canvas/WorkflowCanvas.d.ts +6 -2
- package/dist/workflow-canvas/index.cjs +200 -90
- package/dist/workflow-canvas/index.cjs.map +1 -1
- package/dist/workflow-canvas/index.js +168 -58
- package/dist/workflow-canvas/index.js.map +1 -1
- package/dist/workflow-canvas/viewport.d.ts +47 -0
- package/package.json +4 -4
- package/dist/chunk-2P3T23C7.js.map +0 -1
- package/dist/chunk-3VQYJBOI.js.map +0 -1
- package/dist/chunk-G5DP27DU.js.map +0 -1
- package/dist/chunk-GTNUQBXI.cjs.map +0 -1
- package/dist/chunk-IUR565UW.cjs.map +0 -1
- package/dist/chunk-KJ3QEKOJ.cjs.map +0 -1
- package/dist/chunk-QDNXEB3T.js.map +0 -1
- package/dist/chunk-V3L5DONY.cjs.map +0 -1
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { UploadDropzone } from './chunk-EVUEIBNU.js';
|
|
3
3
|
import { FoldSection } from './chunk-XD2M6LIG.js';
|
|
4
|
+
import { useElementSize } from './chunk-HOXKR26S.js';
|
|
4
5
|
import { testIdOr, prefixedTestId } from './chunk-7F6CBP3Z.js';
|
|
5
|
-
import { useState, useRef, useEffect, useCallback, useMemo } from 'react';
|
|
6
|
+
import { useState, useRef, useEffect, useCallback, useMemo, useLayoutEffect } from 'react';
|
|
6
7
|
import { cn, Card, Button, Label, Select, SelectTrigger, SelectValue, SelectContent, SelectItem, Switch, Input, Textarea } from '@arbidocs/react/ui';
|
|
7
8
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
8
|
-
import { CheckCircle2,
|
|
9
|
+
import { CheckCircle2, ArrowLeft, Loader2, ArrowRight, RotateCw, GitBranch, FileText, Check, AlertTriangle, MinusCircle } from 'lucide-react';
|
|
9
10
|
|
|
10
11
|
// src/agents/workflows/types.ts
|
|
11
12
|
var EMPTY_WORKFLOW_SCOPE = { folders: [], labels: [] };
|
|
@@ -597,7 +598,13 @@ function stepStatesFromActivity(events) {
|
|
|
597
598
|
if (!status || typeof step !== "string") continue;
|
|
598
599
|
const responseId = typeof e.detail?.response_id === "string" ? e.detail.response_id : void 0;
|
|
599
600
|
const error = typeof e.detail?.error === "string" ? e.detail.error : null;
|
|
600
|
-
|
|
601
|
+
const startedAt = status === "running" ? e.created_at : states[step]?.startedAt;
|
|
602
|
+
states[step] = {
|
|
603
|
+
status,
|
|
604
|
+
responseId: responseId ?? states[step]?.responseId ?? null,
|
|
605
|
+
error,
|
|
606
|
+
...startedAt ? { startedAt } : {}
|
|
607
|
+
};
|
|
601
608
|
}
|
|
602
609
|
return states;
|
|
603
610
|
}
|
|
@@ -803,6 +810,15 @@ function useWorkflowView(options) {
|
|
|
803
810
|
},
|
|
804
811
|
[steps]
|
|
805
812
|
);
|
|
813
|
+
const onward = useCallback(
|
|
814
|
+
(id) => {
|
|
815
|
+
const { steps: s, states: st } = optionsRef.current;
|
|
816
|
+
const i = s.findIndex((x) => x.id === id);
|
|
817
|
+
const open = s.slice(i + 1).find((x) => !["done", "skipped"].includes(st[x.id]?.status ?? "pending"));
|
|
818
|
+
return open?.id ?? following(id);
|
|
819
|
+
},
|
|
820
|
+
[following]
|
|
821
|
+
);
|
|
806
822
|
const action = busy ? "wait" : nextAction(steps, states, current);
|
|
807
823
|
const next = useCallback(async () => {
|
|
808
824
|
const { steps: s, states: st, inputs: values } = optionsRef.current;
|
|
@@ -824,13 +840,13 @@ function useWorkflowView(options) {
|
|
|
824
840
|
await optionsRef.current.complete(at);
|
|
825
841
|
}
|
|
826
842
|
setShowErrors(false);
|
|
827
|
-
setCurrent(
|
|
843
|
+
setCurrent(onward(at.id) ?? current);
|
|
828
844
|
} catch (e) {
|
|
829
845
|
setActionError(errorMessage(e));
|
|
830
846
|
} finally {
|
|
831
847
|
setBusy(false);
|
|
832
848
|
}
|
|
833
|
-
}, [current, busy, following]);
|
|
849
|
+
}, [current, busy, following, onward]);
|
|
834
850
|
const goTo = useCallback((stepId) => {
|
|
835
851
|
setShowErrors(false);
|
|
836
852
|
setActionError(null);
|
|
@@ -856,9 +872,16 @@ function useWorkflowView(options) {
|
|
|
856
872
|
}),
|
|
857
873
|
[]
|
|
858
874
|
);
|
|
875
|
+
const currentRef = useRef(current);
|
|
876
|
+
currentRef.current = current;
|
|
859
877
|
const skip = useMemo(
|
|
860
|
-
() => act((id) =>
|
|
861
|
-
|
|
878
|
+
() => act(async (id) => {
|
|
879
|
+
await optionsRef.current.skip(id);
|
|
880
|
+
if (currentRef.current !== id) return;
|
|
881
|
+
setShowErrors(false);
|
|
882
|
+
setCurrent(onward(id) ?? id);
|
|
883
|
+
}),
|
|
884
|
+
[act, onward]
|
|
862
885
|
);
|
|
863
886
|
const retry = useMemo(
|
|
864
887
|
() => options.retry ? act((id) => optionsRef.current.retry?.(id) ?? Promise.resolve()) : void 0,
|
|
@@ -898,59 +921,38 @@ function useWorkflowView(options) {
|
|
|
898
921
|
}
|
|
899
922
|
};
|
|
900
923
|
}
|
|
901
|
-
var DEFAULT_WORKFLOW_RUNNER_LABELS = {
|
|
902
|
-
back: "Back",
|
|
903
|
-
next: "Continue",
|
|
904
|
-
skip: "Skip",
|
|
905
|
-
skipStep: "Skip this step",
|
|
906
|
-
finish: "Finish",
|
|
907
|
-
approve: "Approve",
|
|
908
|
-
working: "Working\u2026",
|
|
909
|
-
starting: "Starting\u2026",
|
|
910
|
-
retry: "Retry",
|
|
911
|
-
failed: "This step did not finish.",
|
|
912
|
-
blocked: "Starts after {steps}.",
|
|
913
|
-
awaitingReview: "Waiting for approval.",
|
|
914
|
-
approved: "Approved.",
|
|
915
|
-
skipped: "Skipped.",
|
|
916
|
-
branch: "Runs alongside; its result joins the thread",
|
|
917
|
-
complete: "Done",
|
|
918
|
-
restart: "Start again",
|
|
919
|
-
filesHeading: "Files ({count})",
|
|
920
|
-
noFiles: "No files yet."
|
|
921
|
-
};
|
|
922
924
|
function PhaseMark({ phase, icon }) {
|
|
923
|
-
if (phase === "done") return /* @__PURE__ */ jsx(Check, { className: "size-3.5" });
|
|
924
|
-
if (phase === "running") return /* @__PURE__ */ jsx(Loader2, { className: "size-3.5 animate-spin" });
|
|
925
|
-
if (phase === "failed") return /* @__PURE__ */ jsx(AlertTriangle, { className: "size-3.5" });
|
|
926
|
-
if (phase === "skipped") return /* @__PURE__ */ jsx(MinusCircle, { className: "size-3.5" });
|
|
927
|
-
return icon ? /* @__PURE__ */ jsx("span", { className: "flex size-3.5 items-center justify-center [&_svg]:size-3.5", children: icon }) : null;
|
|
925
|
+
if (phase === "done") return /* @__PURE__ */ jsx(Check, { className: "size-3.5 shrink-0" });
|
|
926
|
+
if (phase === "running") return /* @__PURE__ */ jsx(Loader2, { className: "size-3.5 shrink-0 animate-spin" });
|
|
927
|
+
if (phase === "failed") return /* @__PURE__ */ jsx(AlertTriangle, { className: "size-3.5 shrink-0" });
|
|
928
|
+
if (phase === "skipped") return /* @__PURE__ */ jsx(MinusCircle, { className: "size-3.5 shrink-0" });
|
|
929
|
+
return icon ? /* @__PURE__ */ jsx("span", { className: "flex size-3.5 shrink-0 items-center justify-center [&_svg]:size-3.5", children: icon }) : null;
|
|
928
930
|
}
|
|
929
|
-
|
|
930
|
-
|
|
931
|
+
var PILL = "flex min-w-0 max-w-full shrink-0 items-center gap-2 whitespace-nowrap rounded-full border px-2.5 py-1.5 text-xs font-medium";
|
|
932
|
+
var LABEL = "min-w-0 max-w-[12rem] truncate";
|
|
933
|
+
function WorkflowStepBar({
|
|
931
934
|
run,
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
renderUpload,
|
|
938
|
-
renderStepNote,
|
|
939
|
-
renderComplete,
|
|
940
|
-
renderScope,
|
|
941
|
-
renderDocuments,
|
|
942
|
-
renderIcon,
|
|
943
|
-
labels,
|
|
944
|
-
testIdPrefix = "workflow-run",
|
|
945
|
-
className
|
|
935
|
+
levels,
|
|
936
|
+
doneTitle,
|
|
937
|
+
doneIcon,
|
|
938
|
+
icon,
|
|
939
|
+
tid
|
|
946
940
|
}) {
|
|
947
|
-
const
|
|
948
|
-
const
|
|
949
|
-
const
|
|
950
|
-
const
|
|
951
|
-
const
|
|
952
|
-
const
|
|
953
|
-
|
|
941
|
+
const box = useRef(null);
|
|
942
|
+
const measure = useRef(null);
|
|
943
|
+
const row = useRef(null);
|
|
944
|
+
const { width } = useElementSize(box);
|
|
945
|
+
const [compact3, setCompact] = useState(false);
|
|
946
|
+
const titles = levels.map((l) => l.map((s) => s.title).join("\0")).join("") + doneTitle;
|
|
947
|
+
useLayoutEffect(() => {
|
|
948
|
+
const needed = measure.current?.scrollWidth ?? 0;
|
|
949
|
+
setCompact(width > 0 && needed > width);
|
|
950
|
+
}, [width, titles]);
|
|
951
|
+
useLayoutEffect(() => {
|
|
952
|
+
if (!compact3) return;
|
|
953
|
+
const el = row.current?.querySelector('[aria-current="step"]');
|
|
954
|
+
el?.scrollIntoView?.({ block: "nearest", inline: "nearest" });
|
|
955
|
+
}, [compact3, run.current]);
|
|
954
956
|
const pill = (s) => {
|
|
955
957
|
const phase = run.phaseOf(s.id);
|
|
956
958
|
const current = s.id === run.current;
|
|
@@ -961,7 +963,8 @@ function WorkflowRunner({
|
|
|
961
963
|
onClick: () => run.goTo(s.id),
|
|
962
964
|
disabled: run.busy,
|
|
963
965
|
className: cn(
|
|
964
|
-
|
|
966
|
+
PILL,
|
|
967
|
+
"transition-colors disabled:cursor-default",
|
|
965
968
|
current ? "border-primary bg-primary/10 text-primary" : phase === "failed" ? "border-destructive/40 text-destructive" : phase === "done" || phase === "skipped" || phase === "running" ? "border-primary/30 bg-primary/5 text-primary" : "border-border text-muted-foreground"
|
|
966
969
|
),
|
|
967
970
|
"aria-current": current ? "step" : void 0,
|
|
@@ -971,47 +974,65 @@ function WorkflowRunner({
|
|
|
971
974
|
"data-testid": tid(`step-${s.id}`),
|
|
972
975
|
children: [
|
|
973
976
|
/* @__PURE__ */ jsx(PhaseMark, { phase, icon: icon(s.icon) }),
|
|
974
|
-
/* @__PURE__ */ jsx("span", { className:
|
|
977
|
+
(current || !compact3) && /* @__PURE__ */ jsx("span", { className: LABEL, "data-testid": tid(`step-${s.id}-label`), children: s.title })
|
|
975
978
|
]
|
|
976
979
|
},
|
|
977
980
|
s.id
|
|
978
981
|
);
|
|
979
982
|
};
|
|
980
|
-
const
|
|
981
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
982
|
-
/* @__PURE__ */ jsx(
|
|
983
|
+
const done = run.isComplete;
|
|
984
|
+
return /* @__PURE__ */ jsxs("div", { ref: box, className: "relative min-w-0", children: [
|
|
985
|
+
/* @__PURE__ */ jsx(
|
|
986
|
+
"div",
|
|
987
|
+
{
|
|
988
|
+
ref: measure,
|
|
989
|
+
"aria-hidden": true,
|
|
990
|
+
className: "pointer-events-none invisible absolute left-0 top-0 flex w-max items-center gap-1.5",
|
|
991
|
+
children: [...levels, [{ id: "__done", title: doneTitle }]].map((level, i) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
992
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col items-start gap-1", children: level.map((s) => /* @__PURE__ */ jsxs("div", { className: PILL, children: [
|
|
993
|
+
/* @__PURE__ */ jsx("span", { className: "size-3.5 shrink-0" }),
|
|
994
|
+
/* @__PURE__ */ jsx(
|
|
995
|
+
"span",
|
|
996
|
+
{
|
|
997
|
+
className: cn(LABEL, "before:content-[attr(data-label)]"),
|
|
998
|
+
"data-label": s.title
|
|
999
|
+
}
|
|
1000
|
+
)
|
|
1001
|
+
] }, s.id)) }),
|
|
1002
|
+
i < levels.length && /* @__PURE__ */ jsx("div", { className: "w-2" })
|
|
1003
|
+
] }, i))
|
|
1004
|
+
}
|
|
1005
|
+
),
|
|
1006
|
+
/* @__PURE__ */ jsx(
|
|
983
1007
|
"ol",
|
|
984
1008
|
{
|
|
985
|
-
|
|
1009
|
+
ref: row,
|
|
1010
|
+
className: cn("flex w-full items-center gap-1.5", compact3 && "overflow-x-auto pb-1"),
|
|
1011
|
+
"data-compact": compact3 || void 0,
|
|
986
1012
|
"data-testid": tid("steps"),
|
|
987
1013
|
children: [...levels, null].map((level, i) => /* @__PURE__ */ jsxs(
|
|
988
1014
|
"li",
|
|
989
1015
|
{
|
|
990
1016
|
className: cn(
|
|
991
|
-
"flex items-center gap-1.5",
|
|
992
|
-
i < levels.length &&
|
|
1017
|
+
"flex min-w-0 items-center gap-1.5",
|
|
1018
|
+
i < levels.length && !compact3 && "flex-1",
|
|
1019
|
+
compact3 && "flex-none"
|
|
993
1020
|
),
|
|
994
1021
|
children: [
|
|
995
|
-
level ? /* @__PURE__ */ jsx("div", { className: "flex flex-col items-start gap-1", children: level.map(pill) }) : /* @__PURE__ */ jsxs(
|
|
1022
|
+
level ? /* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-col items-start gap-1", children: level.map(pill) }) : /* @__PURE__ */ jsxs(
|
|
996
1023
|
"div",
|
|
997
1024
|
{
|
|
998
1025
|
className: cn(
|
|
999
|
-
|
|
1000
|
-
|
|
1026
|
+
PILL,
|
|
1027
|
+
done ? "border-primary bg-primary/10 text-primary" : "border-border text-muted-foreground"
|
|
1001
1028
|
),
|
|
1002
|
-
"aria-current":
|
|
1029
|
+
"aria-current": done ? "step" : void 0,
|
|
1030
|
+
"aria-label": doneTitle,
|
|
1031
|
+
title: doneTitle,
|
|
1003
1032
|
"data-testid": tid("step-done"),
|
|
1004
1033
|
children: [
|
|
1005
|
-
/* @__PURE__ */ jsx(PhaseMark, { phase: "ready", icon:
|
|
1006
|
-
/* @__PURE__ */ jsx(
|
|
1007
|
-
"span",
|
|
1008
|
-
{
|
|
1009
|
-
className: cn(
|
|
1010
|
-
isComplete ? "inline" : crowded ? "hidden" : "hidden @4xl:inline"
|
|
1011
|
-
),
|
|
1012
|
-
children: completion?.title ?? l.complete
|
|
1013
|
-
}
|
|
1014
|
-
)
|
|
1034
|
+
/* @__PURE__ */ jsx(PhaseMark, { phase: "ready", icon: doneIcon }),
|
|
1035
|
+
(done || !compact3) && /* @__PURE__ */ jsx("span", { className: LABEL, children: doneTitle })
|
|
1015
1036
|
]
|
|
1016
1037
|
}
|
|
1017
1038
|
),
|
|
@@ -1020,7 +1041,7 @@ function WorkflowRunner({
|
|
|
1020
1041
|
{
|
|
1021
1042
|
className: cn(
|
|
1022
1043
|
"h-px",
|
|
1023
|
-
|
|
1044
|
+
compact3 ? "w-3 flex-none" : "min-w-2 flex-1",
|
|
1024
1045
|
level?.every((s) => ["done", "skipped"].includes(run.phaseOf(s.id))) ? "bg-primary/40" : "bg-border"
|
|
1025
1046
|
)
|
|
1026
1047
|
}
|
|
@@ -1030,7 +1051,76 @@ function WorkflowRunner({
|
|
|
1030
1051
|
level ? level.map((s) => s.id).join("+") : "done"
|
|
1031
1052
|
))
|
|
1032
1053
|
}
|
|
1033
|
-
)
|
|
1054
|
+
)
|
|
1055
|
+
] });
|
|
1056
|
+
}
|
|
1057
|
+
var DEFAULT_WORKFLOW_RUNNER_LABELS = {
|
|
1058
|
+
back: "Back",
|
|
1059
|
+
next: "Continue",
|
|
1060
|
+
skip: "Skip",
|
|
1061
|
+
skipStep: "Skip this step",
|
|
1062
|
+
finish: "Finish",
|
|
1063
|
+
approve: "Approve",
|
|
1064
|
+
working: "Working\u2026",
|
|
1065
|
+
stepWorking: "{step}\u2026 {elapsed}",
|
|
1066
|
+
starting: "Starting\u2026",
|
|
1067
|
+
retry: "Retry",
|
|
1068
|
+
failed: "This step did not finish.",
|
|
1069
|
+
blocked: "Starts after {steps}.",
|
|
1070
|
+
awaitingReview: "Waiting for approval.",
|
|
1071
|
+
approved: "Approved.",
|
|
1072
|
+
skipped: "Skipped.",
|
|
1073
|
+
branch: "Runs alongside; its result joins the thread",
|
|
1074
|
+
complete: "Done",
|
|
1075
|
+
restart: "Start again",
|
|
1076
|
+
filesHeading: "Already in the workspace ({count})",
|
|
1077
|
+
addedHeading: "Added for this step ({count})",
|
|
1078
|
+
noFiles: "No files yet.",
|
|
1079
|
+
fileReading: "Reading\u2026",
|
|
1080
|
+
fileReady: "Ready",
|
|
1081
|
+
fileFailed: "Could not be read",
|
|
1082
|
+
readingFiles: "Reading {current} of {count} files\u2026"
|
|
1083
|
+
};
|
|
1084
|
+
function WorkflowRunner({
|
|
1085
|
+
workflow,
|
|
1086
|
+
run,
|
|
1087
|
+
renderAgentOutput,
|
|
1088
|
+
renderReview,
|
|
1089
|
+
onUpload,
|
|
1090
|
+
uploading = false,
|
|
1091
|
+
files,
|
|
1092
|
+
renderUpload,
|
|
1093
|
+
renderStepNote,
|
|
1094
|
+
renderComplete,
|
|
1095
|
+
renderScope,
|
|
1096
|
+
renderDocuments,
|
|
1097
|
+
renderIcon,
|
|
1098
|
+
labels,
|
|
1099
|
+
testIdPrefix = "workflow-run",
|
|
1100
|
+
className
|
|
1101
|
+
}) {
|
|
1102
|
+
const l = { ...DEFAULT_WORKFLOW_RUNNER_LABELS, ...labels };
|
|
1103
|
+
const { steps, step, isComplete, action } = run;
|
|
1104
|
+
const completion = workflow.run.kind === "steps" ? workflow.run.completion : void 0;
|
|
1105
|
+
const tid = (suffix) => `${testIdPrefix}-${suffix}`;
|
|
1106
|
+
const levels = stepLevels(steps);
|
|
1107
|
+
const icon = (key) => key && renderIcon ? renderIcon(key) : void 0;
|
|
1108
|
+
const added = step?.kind === "upload" ? (files ?? []).filter((f) => f.addedFor === step.id) : [];
|
|
1109
|
+
const unread = added.filter((f) => f.status === "processing").length;
|
|
1110
|
+
const reading = action === "complete" && unread > 0;
|
|
1111
|
+
const nextLabel = reading ? l.readingFiles.replace("{current}", String(Math.min(added.length - unread + 1, added.length))).replace("{count}", String(added.length)) : action === "skip" ? l.skip : action === "finish" ? l.finish : action === "complete" && step?.kind === "review" ? l.approve : action === "wait" && (run.isRunning || run.busy) ? l.working : (step && !run.isLocked(step.id) ? step.nextLabel : void 0) ?? l.next;
|
|
1112
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-6", className), "data-testid": testIdPrefix, children: [
|
|
1113
|
+
/* @__PURE__ */ jsx(
|
|
1114
|
+
WorkflowStepBar,
|
|
1115
|
+
{
|
|
1116
|
+
run,
|
|
1117
|
+
levels,
|
|
1118
|
+
doneTitle: completion?.title ?? l.complete,
|
|
1119
|
+
doneIcon: icon(completion?.icon),
|
|
1120
|
+
icon,
|
|
1121
|
+
tid
|
|
1122
|
+
}
|
|
1123
|
+
),
|
|
1034
1124
|
isComplete ? renderComplete?.(run) ?? /* @__PURE__ */ jsxs(Card, { className: "mx-auto max-w-lg p-8 text-center", "data-testid": tid("done"), children: [
|
|
1035
1125
|
/* @__PURE__ */ jsx(CheckCircle2, { className: "mx-auto size-12 text-primary" }),
|
|
1036
1126
|
/* @__PURE__ */ jsx("h2", { className: "mt-4 text-xl font-semibold", children: completion?.title ?? l.complete }),
|
|
@@ -1049,7 +1139,7 @@ function WorkflowRunner({
|
|
|
1049
1139
|
"{steps}",
|
|
1050
1140
|
stepDependencies(steps, step.id).map((d) => steps.find((s) => s.id === d)?.title ?? d).join(", ")
|
|
1051
1141
|
) }) }) : step.kind === "form" ? /* @__PURE__ */ jsxs(Card, { className: "max-w-2xl space-y-4 p-6", "data-testid": tid(step.id), children: [
|
|
1052
|
-
|
|
1142
|
+
/* @__PURE__ */ jsx(StepHeading, { step, icon: icon(step.icon), testId: tid(`${step.id}-title`) }),
|
|
1053
1143
|
/* @__PURE__ */ jsx("fieldset", { disabled: run.isLocked(step.id), className: "contents", children: /* @__PURE__ */ jsx(
|
|
1054
1144
|
SchemaForm,
|
|
1055
1145
|
{
|
|
@@ -1071,7 +1161,7 @@ function WorkflowRunner({
|
|
|
1071
1161
|
/* @__PURE__ */ jsx(
|
|
1072
1162
|
UploadDropzone,
|
|
1073
1163
|
{
|
|
1074
|
-
onFiles: (picked) => void onUpload?.(picked),
|
|
1164
|
+
onFiles: (picked) => void onUpload?.(picked, step),
|
|
1075
1165
|
uploading,
|
|
1076
1166
|
disabled: !onUpload,
|
|
1077
1167
|
accept: step.accept,
|
|
@@ -1081,21 +1171,15 @@ function WorkflowRunner({
|
|
|
1081
1171
|
testId: tid(`${step.id}-drop`)
|
|
1082
1172
|
}
|
|
1083
1173
|
),
|
|
1084
|
-
files && /* @__PURE__ */
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
/* @__PURE__ */ jsx("span", { className: "truncate", children: f.name })
|
|
1094
|
-
]
|
|
1095
|
-
},
|
|
1096
|
-
f.id
|
|
1097
|
-
))
|
|
1098
|
-
] })
|
|
1174
|
+
files && /* @__PURE__ */ jsx(
|
|
1175
|
+
UploadFiles,
|
|
1176
|
+
{
|
|
1177
|
+
added,
|
|
1178
|
+
others: files.filter((f) => f.addedFor !== step.id),
|
|
1179
|
+
l,
|
|
1180
|
+
testId: tid(`${step.id}-files`)
|
|
1181
|
+
}
|
|
1182
|
+
)
|
|
1099
1183
|
] }),
|
|
1100
1184
|
run.actionError && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: run.actionError }),
|
|
1101
1185
|
renderStepNote?.(step, run)
|
|
@@ -1149,11 +1233,11 @@ function WorkflowRunner({
|
|
|
1149
1233
|
Button,
|
|
1150
1234
|
{
|
|
1151
1235
|
onClick: () => void run.next(),
|
|
1152
|
-
disabled: action === "wait",
|
|
1236
|
+
disabled: action === "wait" || reading,
|
|
1153
1237
|
"data-testid": tid("next"),
|
|
1154
1238
|
children: [
|
|
1155
1239
|
nextLabel,
|
|
1156
|
-
action === "wait" && (run.isRunning || run.busy) ? /* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin" }) : /* @__PURE__ */ jsx(ArrowRight, { className: "size-4" })
|
|
1240
|
+
reading || action === "wait" && (run.isRunning || run.busy) ? /* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin" }) : /* @__PURE__ */ jsx(ArrowRight, { className: "size-4" })
|
|
1157
1241
|
]
|
|
1158
1242
|
}
|
|
1159
1243
|
)
|
|
@@ -1161,15 +1245,83 @@ function WorkflowRunner({
|
|
|
1161
1245
|
] })
|
|
1162
1246
|
] });
|
|
1163
1247
|
}
|
|
1164
|
-
function
|
|
1248
|
+
function UploadFiles({
|
|
1249
|
+
added,
|
|
1250
|
+
others,
|
|
1251
|
+
l,
|
|
1252
|
+
testId
|
|
1253
|
+
}) {
|
|
1254
|
+
const heading = "text-xs font-semibold uppercase tracking-wide text-muted-foreground";
|
|
1255
|
+
const row = (f) => /* @__PURE__ */ jsxs(
|
|
1256
|
+
"div",
|
|
1257
|
+
{
|
|
1258
|
+
className: "flex items-center gap-2 text-sm text-muted-foreground",
|
|
1259
|
+
"data-status": f.status,
|
|
1260
|
+
"data-testid": `${testId}-file-${f.id}`,
|
|
1261
|
+
children: [
|
|
1262
|
+
/* @__PURE__ */ jsx(FileText, { className: "size-3.5 shrink-0 text-primary" }),
|
|
1263
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", title: f.name, children: f.name }),
|
|
1264
|
+
f.status === "processing" && /* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1 text-xs", children: [
|
|
1265
|
+
/* @__PURE__ */ jsx(Loader2, { className: "size-3 animate-spin" }),
|
|
1266
|
+
" ",
|
|
1267
|
+
l.fileReading
|
|
1268
|
+
] }),
|
|
1269
|
+
f.status === "ready" && /* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1 text-xs text-primary", children: [
|
|
1270
|
+
/* @__PURE__ */ jsx(Check, { className: "size-3" }),
|
|
1271
|
+
" ",
|
|
1272
|
+
l.fileReady
|
|
1273
|
+
] }),
|
|
1274
|
+
f.status === "failed" && /* @__PURE__ */ jsxs("span", { className: "flex shrink-0 items-center gap-1 text-xs text-destructive", children: [
|
|
1275
|
+
/* @__PURE__ */ jsx(AlertTriangle, { className: "size-3" }),
|
|
1276
|
+
" ",
|
|
1277
|
+
l.fileFailed
|
|
1278
|
+
] })
|
|
1279
|
+
]
|
|
1280
|
+
},
|
|
1281
|
+
f.id
|
|
1282
|
+
);
|
|
1283
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-3", "data-testid": testId, children: [
|
|
1284
|
+
added.length > 0 && /* @__PURE__ */ jsxs("div", { className: "space-y-1", "data-testid": `${testId}-added`, children: [
|
|
1285
|
+
/* @__PURE__ */ jsx("p", { className: heading, children: l.addedHeading.replace("{count}", String(added.length)) }),
|
|
1286
|
+
added.map(row)
|
|
1287
|
+
] }),
|
|
1288
|
+
added.length === 0 && others.length === 0 && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: l.noFiles }),
|
|
1289
|
+
others.length > 0 && /* @__PURE__ */ jsxs("details", { className: "space-y-1", "data-testid": `${testId}-others`, children: [
|
|
1290
|
+
/* @__PURE__ */ jsx("summary", { className: cn(heading, "cursor-pointer select-none"), children: l.filesHeading.replace("{count}", String(others.length)) }),
|
|
1291
|
+
/* @__PURE__ */ jsx("div", { className: "mt-1 max-h-48 space-y-1 overflow-y-auto", children: others.map(row) })
|
|
1292
|
+
] })
|
|
1293
|
+
] });
|
|
1294
|
+
}
|
|
1295
|
+
function StepHeading({
|
|
1296
|
+
step,
|
|
1297
|
+
icon,
|
|
1298
|
+
testId
|
|
1299
|
+
}) {
|
|
1165
1300
|
return /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
1166
|
-
/* @__PURE__ */ jsxs("p", { className: "flex items-center gap-2 text-sm font-medium", children: [
|
|
1301
|
+
/* @__PURE__ */ jsxs("p", { className: "flex items-center gap-2 text-sm font-medium", "data-testid": testId, children: [
|
|
1167
1302
|
icon && /* @__PURE__ */ jsx("span", { className: "flex size-4 items-center justify-center text-primary [&_svg]:size-4", children: icon }),
|
|
1168
1303
|
step.title
|
|
1169
1304
|
] }),
|
|
1170
1305
|
step.description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: step.description })
|
|
1171
1306
|
] });
|
|
1172
1307
|
}
|
|
1308
|
+
function formatElapsed(ms) {
|
|
1309
|
+
const total = Math.max(0, Math.floor(ms / 1e3));
|
|
1310
|
+
const h = Math.floor(total / 3600);
|
|
1311
|
+
const m = Math.floor(total % 3600 / 60);
|
|
1312
|
+
const sec = String(total % 60).padStart(2, "0");
|
|
1313
|
+
return h ? `${h}:${String(m).padStart(2, "0")}:${sec}` : `${m}:${sec}`;
|
|
1314
|
+
}
|
|
1315
|
+
function StepWorking({ title, since, label }) {
|
|
1316
|
+
const seen = useRef(Date.now());
|
|
1317
|
+
const start = since && Date.parse(since) || seen.current;
|
|
1318
|
+
const [now, setNow] = useState(() => Date.now());
|
|
1319
|
+
useEffect(() => {
|
|
1320
|
+
const t = setInterval(() => setNow(Date.now()), 1e3);
|
|
1321
|
+
return () => clearInterval(t);
|
|
1322
|
+
}, []);
|
|
1323
|
+
return /* @__PURE__ */ jsx("span", { children: label.replace("{step}", title).replace("{elapsed}", formatElapsed(now - start)) });
|
|
1324
|
+
}
|
|
1173
1325
|
function AgentStepBody({
|
|
1174
1326
|
step,
|
|
1175
1327
|
run,
|
|
@@ -1213,7 +1365,7 @@ function AgentStepBody({
|
|
|
1213
1365
|
children: [
|
|
1214
1366
|
/* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin" }),
|
|
1215
1367
|
" ",
|
|
1216
|
-
phase === "ready" ? l.starting : l.
|
|
1368
|
+
phase === "ready" ? l.starting : /* @__PURE__ */ jsx(StepWorking, { title: step.title, since: state?.startedAt, label: l.stepWorking })
|
|
1217
1369
|
]
|
|
1218
1370
|
}
|
|
1219
1371
|
),
|
|
@@ -1246,5 +1398,5 @@ function AgentStepBody({
|
|
|
1246
1398
|
}
|
|
1247
1399
|
|
|
1248
1400
|
export { DEFAULT_SCHEMA_FORM_LABELS, DEFAULT_WORKFLOW_RUNNER_LABELS, EMPTY_WORKFLOW_SCOPE, SKILL_PROMPT_FALLBACK_PLACEHOLDER, SKILL_PROMPT_LABEL, SchemaForm, WorkflowRunner, buildLaunch, composeStepPrompt, composeWorkflowPrompt, defaultInputs, dependsOn, fieldToFrontmatter, fillRunText, fillStepInputs, fromPlanSteps, initialRunInputs, inputsFromContext, isEmptyWorkflowScope, isPersonStep, isRunFinished, isSteppedWorkflow, isWorkflowScope, layoutFromPlanSteps, nextAction, orderSteps, promptFieldName, reviewInstructions, runFields, runThreadTitle, skillToWorkflow, stepDependencies, stepLevels, stepPhase, stepStatesFromActivity, toPlanSteps, useWorkflowView, validateInputs, validateStep, validateWorkflowGraph, workflowAccepts, workflowFromFrontmatter, workflowSteps, workflowsAccepting, workflowsForHost };
|
|
1249
|
-
//# sourceMappingURL=chunk-
|
|
1250
|
-
//# sourceMappingURL=chunk-
|
|
1401
|
+
//# sourceMappingURL=chunk-YWYVIQ7T.js.map
|
|
1402
|
+
//# sourceMappingURL=chunk-YWYVIQ7T.js.map
|