@invergent/agent-chat-react 1.5.3 → 1.5.4
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/artifact-chart-X53FKRDZ.js +153 -0
- package/dist/artifact-chart-X53FKRDZ.js.map +1 -0
- package/dist/chunk-QSC4UIVT.js +11 -0
- package/dist/chunk-QSC4UIVT.js.map +1 -0
- package/dist/index.cjs +463 -172
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -2
- package/dist/index.d.ts +12 -2
- package/dist/index.js +210 -115
- package/dist/index.js.map +1 -1
- package/package.json +3 -6
- package/dist/artifact-chart-7J6GOR4M.js +0 -88
- package/dist/artifact-chart-7J6GOR4M.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var clsx = require('clsx');
|
|
4
|
+
var tailwindMerge = require('tailwind-merge');
|
|
3
5
|
var react = require('react');
|
|
4
|
-
var
|
|
6
|
+
var auto = require('chart.js/auto');
|
|
5
7
|
var nextThemes = require('next-themes');
|
|
6
8
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
9
|
var classVarianceAuthority = require('class-variance-authority');
|
|
8
10
|
var radixUi = require('radix-ui');
|
|
9
|
-
var clsx = require('clsx');
|
|
10
|
-
var tailwindMerge = require('tailwind-merge');
|
|
11
11
|
var lucideReact = require('lucide-react');
|
|
12
12
|
var useStickToBottom = require('use-stick-to-bottom');
|
|
13
13
|
var cjk = require('@streamdown/cjk');
|
|
@@ -39,56 +39,63 @@ var __export = (target, all) => {
|
|
|
39
39
|
for (var name in all)
|
|
40
40
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
41
41
|
};
|
|
42
|
+
function cn(...inputs) {
|
|
43
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
44
|
+
}
|
|
45
|
+
var init_utils = __esm({
|
|
46
|
+
"src/lib/utils.ts"() {
|
|
47
|
+
}
|
|
48
|
+
});
|
|
42
49
|
|
|
43
50
|
// src/components/chat/artifacts/artifact-chart.tsx
|
|
44
51
|
var artifact_chart_exports = {};
|
|
45
52
|
__export(artifact_chart_exports, {
|
|
46
53
|
ArtifactChart: () => ArtifactChart
|
|
47
54
|
});
|
|
48
|
-
function ArtifactChart({
|
|
55
|
+
function ArtifactChart({
|
|
56
|
+
spec,
|
|
57
|
+
fill = false
|
|
58
|
+
}) {
|
|
49
59
|
const { resolvedTheme } = nextThemes.useTheme();
|
|
50
60
|
const isDark = resolvedTheme === "dark";
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
react.useEffect(() => {
|
|
54
|
-
const el = containerRef.current;
|
|
55
|
-
if (!el) return;
|
|
56
|
-
const observer = new ResizeObserver((entries) => {
|
|
57
|
-
const w = entries[0]?.contentRect.width ?? el.offsetWidth;
|
|
58
|
-
if (w >= MIN_CHART_WIDTH) setWidth(Math.floor(w));
|
|
59
|
-
});
|
|
60
|
-
observer.observe(el);
|
|
61
|
-
if (el.offsetWidth >= MIN_CHART_WIDTH) setWidth(el.offsetWidth);
|
|
62
|
-
return () => observer.disconnect();
|
|
63
|
-
}, []);
|
|
61
|
+
const canvasRef = react.useRef(null);
|
|
62
|
+
const chartRef = react.useRef(null);
|
|
64
63
|
const [error, setError] = react.useState(null);
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
const base = spec.vega_lite ?? {};
|
|
68
|
-
const themeConfig = isDark ? DARK_CONFIG : LIGHT_CONFIG;
|
|
64
|
+
const config = react.useMemo(() => {
|
|
65
|
+
const base = cloneChartConfig(spec.chart_js ?? {});
|
|
69
66
|
return {
|
|
70
|
-
$schema: VEGA_LITE_SCHEMA,
|
|
71
|
-
width,
|
|
72
|
-
height: DEFAULT_CHART_HEIGHT,
|
|
73
67
|
...base,
|
|
74
|
-
|
|
75
|
-
...themeConfig,
|
|
76
|
-
...base.config ?? {}
|
|
77
|
-
}
|
|
68
|
+
options: mergeThemeOptions(base.options, base.type, isDark)
|
|
78
69
|
};
|
|
79
|
-
}, [spec.
|
|
70
|
+
}, [spec.chart_js, isDark]);
|
|
80
71
|
react.useEffect(() => {
|
|
72
|
+
const canvas = canvasRef.current;
|
|
73
|
+
if (!canvas) return;
|
|
74
|
+
chartRef.current?.destroy();
|
|
75
|
+
chartRef.current = null;
|
|
81
76
|
setError(null);
|
|
82
|
-
|
|
77
|
+
try {
|
|
78
|
+
chartRef.current = new auto.Chart(canvas, config);
|
|
79
|
+
} catch (e) {
|
|
80
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
81
|
+
}
|
|
82
|
+
return () => {
|
|
83
|
+
chartRef.current?.destroy();
|
|
84
|
+
chartRef.current = null;
|
|
85
|
+
};
|
|
86
|
+
}, [config]);
|
|
83
87
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
84
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
85
|
-
|
|
88
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
89
|
+
"div",
|
|
86
90
|
{
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
91
|
+
className: cn("relative w-full", fill && "h-full min-h-80"),
|
|
92
|
+
style: fill ? void 0 : {
|
|
93
|
+
height: DEFAULT_CHART_HEIGHT,
|
|
94
|
+
maxHeight: MAX_INLINE_CHART_HEIGHT
|
|
95
|
+
},
|
|
96
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("canvas", { ref: canvasRef })
|
|
90
97
|
}
|
|
91
|
-
)
|
|
98
|
+
),
|
|
92
99
|
error && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-destructive", children: [
|
|
93
100
|
"Chart error: ",
|
|
94
101
|
error
|
|
@@ -96,35 +103,101 @@ function ArtifactChart({ spec }) {
|
|
|
96
103
|
spec.caption && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: spec.caption })
|
|
97
104
|
] });
|
|
98
105
|
}
|
|
99
|
-
|
|
106
|
+
function cloneChartConfig(value) {
|
|
107
|
+
return JSON.parse(JSON.stringify(value));
|
|
108
|
+
}
|
|
109
|
+
function mergeThemeOptions(options, chartType, isDark) {
|
|
110
|
+
const theme = isDark ? DARK_THEME : LIGHT_THEME;
|
|
111
|
+
const base = isRecord(options) ? options : {};
|
|
112
|
+
const plugins = isRecord(base.plugins) ? base.plugins : {};
|
|
113
|
+
const legend = isRecord(plugins.legend) ? plugins.legend : {};
|
|
114
|
+
const legendLabels = isRecord(legend.labels) ? legend.labels : {};
|
|
115
|
+
const title = isRecord(plugins.title) ? plugins.title : {};
|
|
116
|
+
const scales = isRecord(base.scales) ? base.scales : {};
|
|
117
|
+
return {
|
|
118
|
+
responsive: true,
|
|
119
|
+
maintainAspectRatio: false,
|
|
120
|
+
color: theme.text,
|
|
121
|
+
...base,
|
|
122
|
+
plugins: {
|
|
123
|
+
...plugins,
|
|
124
|
+
legend: {
|
|
125
|
+
...legend,
|
|
126
|
+
labels: {
|
|
127
|
+
color: theme.text,
|
|
128
|
+
...legendLabels
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
title: {
|
|
132
|
+
color: theme.title,
|
|
133
|
+
...title
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
scales: mergeScales(scales, chartType, theme)
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function mergeScales(scales, chartType, theme) {
|
|
140
|
+
const names = /* @__PURE__ */ new Set([...defaultScaleNames(chartType), ...Object.keys(scales)]);
|
|
141
|
+
const merged = {};
|
|
142
|
+
for (const name of names) {
|
|
143
|
+
const scale = isRecord(scales[name]) ? scales[name] : {};
|
|
144
|
+
const ticks = isRecord(scale.ticks) ? scale.ticks : {};
|
|
145
|
+
const grid = isRecord(scale.grid) ? scale.grid : {};
|
|
146
|
+
const title = isRecord(scale.title) ? scale.title : {};
|
|
147
|
+
merged[name] = {
|
|
148
|
+
...scale,
|
|
149
|
+
ticks: {
|
|
150
|
+
color: theme.text,
|
|
151
|
+
...ticks
|
|
152
|
+
},
|
|
153
|
+
grid: {
|
|
154
|
+
color: theme.grid,
|
|
155
|
+
...grid
|
|
156
|
+
},
|
|
157
|
+
border: {
|
|
158
|
+
color: theme.border,
|
|
159
|
+
...isRecord(scale.border) ? scale.border : {}
|
|
160
|
+
},
|
|
161
|
+
title: {
|
|
162
|
+
color: theme.title,
|
|
163
|
+
...title
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
return merged;
|
|
168
|
+
}
|
|
169
|
+
function defaultScaleNames(chartType) {
|
|
170
|
+
if (chartType === "bar" || chartType === "line" || chartType === "scatter") {
|
|
171
|
+
return ["x", "y"];
|
|
172
|
+
}
|
|
173
|
+
if (chartType === "bubble") {
|
|
174
|
+
return ["x", "y"];
|
|
175
|
+
}
|
|
176
|
+
if (chartType === "radar" || chartType === "polarArea") {
|
|
177
|
+
return ["r"];
|
|
178
|
+
}
|
|
179
|
+
return [];
|
|
180
|
+
}
|
|
181
|
+
function isRecord(value) {
|
|
182
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
183
|
+
}
|
|
184
|
+
var DEFAULT_CHART_HEIGHT, MAX_INLINE_CHART_HEIGHT, LIGHT_THEME, DARK_THEME;
|
|
100
185
|
var init_artifact_chart = __esm({
|
|
101
186
|
"src/components/chat/artifacts/artifact-chart.tsx"() {
|
|
102
|
-
|
|
187
|
+
init_utils();
|
|
103
188
|
DEFAULT_CHART_HEIGHT = 320;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
gridColor: "#e5e7eb",
|
|
111
|
-
domainColor: "#d1d5db",
|
|
112
|
-
tickColor: "#d1d5db"
|
|
113
|
-
},
|
|
114
|
-
view: { stroke: "transparent" },
|
|
115
|
-
legend: { labelColor: "#444", titleColor: "#111" }
|
|
189
|
+
MAX_INLINE_CHART_HEIGHT = 800;
|
|
190
|
+
LIGHT_THEME = {
|
|
191
|
+
text: "#444",
|
|
192
|
+
title: "#111",
|
|
193
|
+
grid: "#e5e7eb",
|
|
194
|
+
border: "#d1d5db"
|
|
116
195
|
};
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
gridColor: "#374151",
|
|
123
|
-
domainColor: "#4b5563",
|
|
124
|
-
tickColor: "#4b5563"
|
|
125
|
-
},
|
|
126
|
-
view: { stroke: "transparent" },
|
|
127
|
-
legend: { labelColor: "#cbd5e1", titleColor: "#f1f5f9" }
|
|
196
|
+
DARK_THEME = {
|
|
197
|
+
text: "#cbd5e1",
|
|
198
|
+
title: "#f1f5f9",
|
|
199
|
+
grid: "#374151",
|
|
200
|
+
border: "#4b5563"
|
|
128
201
|
};
|
|
129
202
|
}
|
|
130
203
|
});
|
|
@@ -139,9 +212,9 @@ function useAgentChatAdapterContext() {
|
|
|
139
212
|
}
|
|
140
213
|
return value;
|
|
141
214
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
215
|
+
|
|
216
|
+
// src/components/ui/button.tsx
|
|
217
|
+
init_utils();
|
|
145
218
|
var buttonVariants = classVarianceAuthority.cva(
|
|
146
219
|
"group/button inline-flex shrink-0 items-center justify-center rounded-none border border-transparent bg-clip-padding text-xs font-semibold tracking-widest whitespace-nowrap uppercase transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/30 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-2 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
|
147
220
|
{
|
|
@@ -190,10 +263,13 @@ function Button({
|
|
|
190
263
|
}
|
|
191
264
|
);
|
|
192
265
|
}
|
|
266
|
+
|
|
267
|
+
// src/components/ai-elements/conversation.tsx
|
|
268
|
+
init_utils();
|
|
193
269
|
var Conversation = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
194
270
|
useStickToBottom.StickToBottom,
|
|
195
271
|
{
|
|
196
|
-
className: cn("relative flex-1
|
|
272
|
+
className: cn("relative flex-1", className),
|
|
197
273
|
initial: "smooth",
|
|
198
274
|
resize: "smooth",
|
|
199
275
|
role: "log",
|
|
@@ -258,6 +334,9 @@ var ConversationScrollButton = ({
|
|
|
258
334
|
}
|
|
259
335
|
);
|
|
260
336
|
};
|
|
337
|
+
|
|
338
|
+
// src/components/ui/tooltip.tsx
|
|
339
|
+
init_utils();
|
|
261
340
|
function TooltipProvider({
|
|
262
341
|
delayDuration = 0,
|
|
263
342
|
...props
|
|
@@ -304,6 +383,9 @@ function TooltipContent({
|
|
|
304
383
|
}
|
|
305
384
|
) });
|
|
306
385
|
}
|
|
386
|
+
|
|
387
|
+
// src/components/ai-elements/message.tsx
|
|
388
|
+
init_utils();
|
|
307
389
|
var Message = ({ className, from, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
308
390
|
"div",
|
|
309
391
|
{
|
|
@@ -378,6 +460,12 @@ function CollapsibleContent({
|
|
|
378
460
|
}
|
|
379
461
|
);
|
|
380
462
|
}
|
|
463
|
+
|
|
464
|
+
// src/components/ai-elements/reasoning.tsx
|
|
465
|
+
init_utils();
|
|
466
|
+
|
|
467
|
+
// src/components/ai-elements/shimmer.tsx
|
|
468
|
+
init_utils();
|
|
381
469
|
var ShimmerComponent = ({
|
|
382
470
|
children,
|
|
383
471
|
as: Component = "p",
|
|
@@ -554,6 +642,9 @@ var ReasoningContent = react.memo(
|
|
|
554
642
|
Reasoning.displayName = "Reasoning";
|
|
555
643
|
ReasoningTrigger.displayName = "ReasoningTrigger";
|
|
556
644
|
ReasoningContent.displayName = "ReasoningContent";
|
|
645
|
+
|
|
646
|
+
// src/components/reui/timeline.tsx
|
|
647
|
+
init_utils();
|
|
557
648
|
var TimelineContext = react.createContext(
|
|
558
649
|
void 0
|
|
559
650
|
);
|
|
@@ -676,6 +767,62 @@ function TimelineSeparator({
|
|
|
676
767
|
}
|
|
677
768
|
);
|
|
678
769
|
}
|
|
770
|
+
init_utils();
|
|
771
|
+
|
|
772
|
+
// src/components/chat/tools/shared.ts
|
|
773
|
+
function statusColorClass(status) {
|
|
774
|
+
if (status === "running") return "bg-primary animate-pulse";
|
|
775
|
+
if (status === "error") return "bg-red-500";
|
|
776
|
+
if (status === "cancelled") return "bg-muted-foreground/40";
|
|
777
|
+
return "bg-emerald-500";
|
|
778
|
+
}
|
|
779
|
+
function effectiveStatus(tc) {
|
|
780
|
+
if (tc.cancelled) return "cancelled";
|
|
781
|
+
if (tc.status !== "complete" || !tc.result) return tc.status;
|
|
782
|
+
try {
|
|
783
|
+
const parsed = JSON.parse(tc.result);
|
|
784
|
+
if (parsed?.exit_code !== void 0 && parsed.exit_code !== 0) return "error";
|
|
785
|
+
if (parsed?.error) return "error";
|
|
786
|
+
if (parsed?.status === "blocked" || parsed?.status === "error") return "error";
|
|
787
|
+
if (parsed?.success === false) return "error";
|
|
788
|
+
} catch {
|
|
789
|
+
}
|
|
790
|
+
return "complete";
|
|
791
|
+
}
|
|
792
|
+
function formatArgs(args) {
|
|
793
|
+
try {
|
|
794
|
+
return JSON.stringify(JSON.parse(args), null, 2);
|
|
795
|
+
} catch {
|
|
796
|
+
return args;
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
function parseArgs(args) {
|
|
800
|
+
try {
|
|
801
|
+
return JSON.parse(args);
|
|
802
|
+
} catch {
|
|
803
|
+
return null;
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
function truncate(s, max) {
|
|
807
|
+
return s.length > max ? s.slice(0, max) + "\n... (truncated)" : s;
|
|
808
|
+
}
|
|
809
|
+
function toolErrorSummary(result, max = 180) {
|
|
810
|
+
if (!result) return "";
|
|
811
|
+
try {
|
|
812
|
+
const parsed = JSON.parse(result);
|
|
813
|
+
const error = typeof parsed?.error === "string" ? parsed.error : "";
|
|
814
|
+
if (error === "sandbox_unavailable") {
|
|
815
|
+
return "Sandbox is unavailable. Workspace commands cannot run right now.";
|
|
816
|
+
}
|
|
817
|
+
const reason = typeof parsed?.reason === "string" ? parsed.reason : "";
|
|
818
|
+
const message = typeof parsed?.message === "string" ? parsed.message : "";
|
|
819
|
+
const detail = reason || message;
|
|
820
|
+
const summary = error && detail && detail !== error ? `${error}: ${detail}` : error || detail;
|
|
821
|
+
return summary ? summary.replace(/\s+/g, " ").slice(0, max) : "";
|
|
822
|
+
} catch {
|
|
823
|
+
return "";
|
|
824
|
+
}
|
|
825
|
+
}
|
|
679
826
|
function CopyButton({ text }) {
|
|
680
827
|
const [copied, setCopied] = react.useState(false);
|
|
681
828
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -711,7 +858,8 @@ function parseTerminalResult(result, args) {
|
|
|
711
858
|
const hasOutput = typeof parsed?.output === "string";
|
|
712
859
|
const hasStdout = typeof parsed?.stdout === "string";
|
|
713
860
|
const hasExitCode = typeof parsed?.exit_code === "number";
|
|
714
|
-
|
|
861
|
+
const errorSummary = toolErrorSummary(result, 400);
|
|
862
|
+
if (!hasOutput && !hasStdout && !hasExitCode && !errorSummary) {
|
|
715
863
|
return null;
|
|
716
864
|
}
|
|
717
865
|
let command = "";
|
|
@@ -721,20 +869,20 @@ function parseTerminalResult(result, args) {
|
|
|
721
869
|
} catch {
|
|
722
870
|
}
|
|
723
871
|
const output = parsed.output ?? parsed.stdout ?? "";
|
|
724
|
-
const stderr = parsed.stderr ??
|
|
872
|
+
const stderr = parsed.stderr ?? errorSummary;
|
|
725
873
|
const combined = stderr ? `${output}
|
|
726
874
|
${stderr}`.trim() : output;
|
|
727
875
|
return {
|
|
728
876
|
output: combined,
|
|
729
|
-
exit_code: parsed.exit_code ?? 0,
|
|
730
|
-
error:
|
|
877
|
+
exit_code: parsed.exit_code ?? (errorSummary ? 1 : 0),
|
|
878
|
+
error: errorSummary || null,
|
|
731
879
|
command
|
|
732
880
|
};
|
|
733
881
|
} catch {
|
|
734
882
|
return null;
|
|
735
883
|
}
|
|
736
884
|
}
|
|
737
|
-
function TerminalCollapsible({ command, output, isRunning }) {
|
|
885
|
+
function TerminalCollapsible({ command, output, isRunning, hasError }) {
|
|
738
886
|
const [isOpen, setIsOpen] = react.useState(false);
|
|
739
887
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
740
888
|
Collapsible,
|
|
@@ -744,7 +892,7 @@ function TerminalCollapsible({ command, output, isRunning }) {
|
|
|
744
892
|
className: "not-prose w-full",
|
|
745
893
|
children: [
|
|
746
894
|
/* @__PURE__ */ jsxRuntime.jsxs(CollapsibleTrigger, { className: "group/trigger flex w-fit items-center gap-2 text-sm transition-colors", children: [
|
|
747
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-left", children: isRunning ? /* @__PURE__ */ jsxRuntime.jsx(Shimmer, { as: "span", duration: 1, children: "Running command..." }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-foreground", children: "Command result" }) }),
|
|
895
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-left", children: isRunning ? /* @__PURE__ */ jsxRuntime.jsx(Shimmer, { as: "span", duration: 1, children: "Running command..." }) : hasError ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-destructive", children: "Command failed" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-semibold text-foreground", children: "Command result" }) }),
|
|
748
896
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
749
897
|
lucideReact.ChevronDownIcon,
|
|
750
898
|
{
|
|
@@ -801,7 +949,8 @@ function TerminalToolBlock({ tc }) {
|
|
|
801
949
|
{
|
|
802
950
|
command: result.command,
|
|
803
951
|
output,
|
|
804
|
-
isRunning
|
|
952
|
+
isRunning,
|
|
953
|
+
hasError: result.exit_code !== 0 || Boolean(result.error)
|
|
805
954
|
}
|
|
806
955
|
);
|
|
807
956
|
}
|
|
@@ -816,6 +965,9 @@ function TerminalToolBlock({ tc }) {
|
|
|
816
965
|
}
|
|
817
966
|
return null;
|
|
818
967
|
}
|
|
968
|
+
|
|
969
|
+
// src/components/ui/scroll-area.tsx
|
|
970
|
+
init_utils();
|
|
819
971
|
function ScrollArea({
|
|
820
972
|
className,
|
|
821
973
|
children,
|
|
@@ -868,6 +1020,9 @@ function ScrollBar({
|
|
|
868
1020
|
}
|
|
869
1021
|
);
|
|
870
1022
|
}
|
|
1023
|
+
|
|
1024
|
+
// src/components/ai-elements/queue.tsx
|
|
1025
|
+
init_utils();
|
|
871
1026
|
var QueueItem = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
872
1027
|
"li",
|
|
873
1028
|
{
|
|
@@ -1020,6 +1175,9 @@ function TodoToolBlock({ tc }) {
|
|
|
1020
1175
|
}) }) })
|
|
1021
1176
|
] }) });
|
|
1022
1177
|
}
|
|
1178
|
+
|
|
1179
|
+
// src/components/ai-elements/code-block.tsx
|
|
1180
|
+
init_utils();
|
|
1023
1181
|
var isItalic = (fontStyle) => fontStyle && fontStyle & 1;
|
|
1024
1182
|
var isBold = (fontStyle) => fontStyle && fontStyle & 2;
|
|
1025
1183
|
var isUnderline = (fontStyle) => (
|
|
@@ -1309,6 +1467,9 @@ var CodeBlockCopyButton = ({
|
|
|
1309
1467
|
}
|
|
1310
1468
|
);
|
|
1311
1469
|
};
|
|
1470
|
+
|
|
1471
|
+
// src/components/ui/tabs.tsx
|
|
1472
|
+
init_utils();
|
|
1312
1473
|
function Tabs({
|
|
1313
1474
|
className,
|
|
1314
1475
|
orientation = "horizontal",
|
|
@@ -1388,6 +1549,12 @@ function TabsContent({
|
|
|
1388
1549
|
}
|
|
1389
1550
|
);
|
|
1390
1551
|
}
|
|
1552
|
+
|
|
1553
|
+
// src/components/ai-elements/sandbox.tsx
|
|
1554
|
+
init_utils();
|
|
1555
|
+
|
|
1556
|
+
// src/components/ui/badge.tsx
|
|
1557
|
+
init_utils();
|
|
1391
1558
|
var badgeVariants = classVarianceAuthority.cva(
|
|
1392
1559
|
"group/badge inline-flex w-fit shrink-0 items-center justify-center gap-1.5 overflow-hidden rounded-none border-0 bg-transparent px-0 py-0 text-[0.625rem] font-semibold tracking-widest whitespace-nowrap uppercase transition-colors focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-0 has-data-[icon=inline-start]:pl-0 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!",
|
|
1393
1560
|
{
|
|
@@ -1645,6 +1812,9 @@ function WebToolBlock({ tc }) {
|
|
|
1645
1812
|
displayText && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/70 truncate text-xs", children: displayText })
|
|
1646
1813
|
] });
|
|
1647
1814
|
}
|
|
1815
|
+
|
|
1816
|
+
// src/components/ui/dialog.tsx
|
|
1817
|
+
init_utils();
|
|
1648
1818
|
function Dialog({
|
|
1649
1819
|
...props
|
|
1650
1820
|
}) {
|
|
@@ -1774,6 +1944,12 @@ function DialogDescription({
|
|
|
1774
1944
|
}
|
|
1775
1945
|
);
|
|
1776
1946
|
}
|
|
1947
|
+
|
|
1948
|
+
// src/components/chat/tools/file-tools.tsx
|
|
1949
|
+
init_utils();
|
|
1950
|
+
|
|
1951
|
+
// src/components/chat/diff-viewer.tsx
|
|
1952
|
+
init_utils();
|
|
1777
1953
|
function splitChangeLines(change) {
|
|
1778
1954
|
const v = change.value;
|
|
1779
1955
|
if (v === "") return [];
|
|
@@ -2252,6 +2428,9 @@ function ListFilesBlock({ tc }) {
|
|
|
2252
2428
|
] })
|
|
2253
2429
|
] });
|
|
2254
2430
|
}
|
|
2431
|
+
|
|
2432
|
+
// src/components/ai-elements/terminal.tsx
|
|
2433
|
+
init_utils();
|
|
2255
2434
|
var TerminalContext = react.createContext({
|
|
2256
2435
|
autoScroll: true,
|
|
2257
2436
|
isStreaming: false,
|
|
@@ -2446,7 +2625,10 @@ var Terminal = ({
|
|
|
2446
2625
|
}
|
|
2447
2626
|
) });
|
|
2448
2627
|
};
|
|
2449
|
-
|
|
2628
|
+
|
|
2629
|
+
// src/components/chat/tools/process-tool.tsx
|
|
2630
|
+
init_utils();
|
|
2631
|
+
function parseArgs2(args) {
|
|
2450
2632
|
try {
|
|
2451
2633
|
return JSON.parse(args);
|
|
2452
2634
|
} catch {
|
|
@@ -2670,7 +2852,7 @@ function OutputPreview({ output }) {
|
|
|
2670
2852
|
}
|
|
2671
2853
|
function ProcessToolBlock({ tc }) {
|
|
2672
2854
|
const isRunning = tc.status === "running";
|
|
2673
|
-
const args =
|
|
2855
|
+
const args = parseArgs2(tc.args);
|
|
2674
2856
|
const result = parseResult(tc.result);
|
|
2675
2857
|
const action = args.action || "unknown";
|
|
2676
2858
|
const actionLabel = {
|
|
@@ -2740,6 +2922,12 @@ function ProcessToolBlock({ tc }) {
|
|
|
2740
2922
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-background pb-1", children: content })
|
|
2741
2923
|
] });
|
|
2742
2924
|
}
|
|
2925
|
+
|
|
2926
|
+
// src/components/chat/tools/expert-tool.tsx
|
|
2927
|
+
init_utils();
|
|
2928
|
+
|
|
2929
|
+
// src/components/ui/textarea.tsx
|
|
2930
|
+
init_utils();
|
|
2743
2931
|
function Textarea({ className, ...props }) {
|
|
2744
2932
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2745
2933
|
"textarea",
|
|
@@ -2753,44 +2941,6 @@ function Textarea({ className, ...props }) {
|
|
|
2753
2941
|
}
|
|
2754
2942
|
);
|
|
2755
2943
|
}
|
|
2756
|
-
|
|
2757
|
-
// src/components/chat/tools/shared.ts
|
|
2758
|
-
function statusColorClass(status) {
|
|
2759
|
-
if (status === "running") return "bg-primary animate-pulse";
|
|
2760
|
-
if (status === "error") return "bg-red-500";
|
|
2761
|
-
if (status === "cancelled") return "bg-muted-foreground/40";
|
|
2762
|
-
return "bg-emerald-500";
|
|
2763
|
-
}
|
|
2764
|
-
function effectiveStatus(tc) {
|
|
2765
|
-
if (tc.cancelled) return "cancelled";
|
|
2766
|
-
if (tc.status !== "complete" || !tc.result) return tc.status;
|
|
2767
|
-
try {
|
|
2768
|
-
const parsed = JSON.parse(tc.result);
|
|
2769
|
-
if (parsed?.exit_code !== void 0 && parsed.exit_code !== 0) return "error";
|
|
2770
|
-
if (parsed?.error) return "error";
|
|
2771
|
-
if (parsed?.status === "blocked" || parsed?.status === "error") return "error";
|
|
2772
|
-
if (parsed?.success === false) return "error";
|
|
2773
|
-
} catch {
|
|
2774
|
-
}
|
|
2775
|
-
return "complete";
|
|
2776
|
-
}
|
|
2777
|
-
function formatArgs(args) {
|
|
2778
|
-
try {
|
|
2779
|
-
return JSON.stringify(JSON.parse(args), null, 2);
|
|
2780
|
-
} catch {
|
|
2781
|
-
return args;
|
|
2782
|
-
}
|
|
2783
|
-
}
|
|
2784
|
-
function parseArgs2(args) {
|
|
2785
|
-
try {
|
|
2786
|
-
return JSON.parse(args);
|
|
2787
|
-
} catch {
|
|
2788
|
-
return null;
|
|
2789
|
-
}
|
|
2790
|
-
}
|
|
2791
|
-
function truncate(s, max) {
|
|
2792
|
-
return s.length > max ? s.slice(0, max) + "\n... (truncated)" : s;
|
|
2793
|
-
}
|
|
2794
2944
|
var MAX_REASON_LENGTH = 500;
|
|
2795
2945
|
function ExpertToolBlock({ tc }) {
|
|
2796
2946
|
const [expanded, setExpanded] = react.useState(false);
|
|
@@ -2826,7 +2976,7 @@ function ExpertToolBlock({ tc }) {
|
|
|
2826
2976
|
}
|
|
2827
2977
|
void submit("up");
|
|
2828
2978
|
};
|
|
2829
|
-
const args =
|
|
2979
|
+
const args = parseArgs(tc.args) ?? {};
|
|
2830
2980
|
const expertName = args.expert ?? null;
|
|
2831
2981
|
const question = args.question ?? args.prompt ?? "";
|
|
2832
2982
|
const result = parseExpertResult(tc.result);
|
|
@@ -2938,7 +3088,7 @@ function ExpertToolBlock({ tc }) {
|
|
|
2938
3088
|
}
|
|
2939
3089
|
function parseExpertResult(result) {
|
|
2940
3090
|
if (!result) return null;
|
|
2941
|
-
const parsed =
|
|
3091
|
+
const parsed = parseArgs(result);
|
|
2942
3092
|
if (parsed) {
|
|
2943
3093
|
return {
|
|
2944
3094
|
...parsed,
|
|
@@ -3045,11 +3195,11 @@ function ReasonForm({
|
|
|
3045
3195
|
] });
|
|
3046
3196
|
}
|
|
3047
3197
|
function SkillsListBlock({ tc }) {
|
|
3048
|
-
const args =
|
|
3198
|
+
const args = parseArgs(tc.args) ?? {};
|
|
3049
3199
|
const filter = args.category ? `category: ${args.category}` : "all";
|
|
3050
3200
|
let summary = "";
|
|
3051
3201
|
if (tc.result) {
|
|
3052
|
-
const parsed =
|
|
3202
|
+
const parsed = parseArgs(tc.result);
|
|
3053
3203
|
if (parsed?.count !== void 0) {
|
|
3054
3204
|
summary = `${parsed.count} skill${parsed.count === 1 ? "" : "s"}`;
|
|
3055
3205
|
}
|
|
@@ -3064,11 +3214,11 @@ function SkillsListBlock({ tc }) {
|
|
|
3064
3214
|
] });
|
|
3065
3215
|
}
|
|
3066
3216
|
function SkillViewBlock({ tc }) {
|
|
3067
|
-
const args =
|
|
3217
|
+
const args = parseArgs(tc.args) ?? {};
|
|
3068
3218
|
const target = args.file_path ? `${args.name ?? "?"}/${args.file_path}` : args.name ?? "?";
|
|
3069
3219
|
let summary = "";
|
|
3070
3220
|
if (tc.result) {
|
|
3071
|
-
const parsed =
|
|
3221
|
+
const parsed = parseArgs(tc.result);
|
|
3072
3222
|
if (parsed?.staged_at) {
|
|
3073
3223
|
summary = `staged at ${parsed.staged_at}`;
|
|
3074
3224
|
} else if (parsed?.token_estimate) {
|
|
@@ -3084,6 +3234,12 @@ function SkillViewBlock({ tc }) {
|
|
|
3084
3234
|
] })
|
|
3085
3235
|
] });
|
|
3086
3236
|
}
|
|
3237
|
+
|
|
3238
|
+
// src/components/chat/tools/clarify-tool.tsx
|
|
3239
|
+
init_utils();
|
|
3240
|
+
|
|
3241
|
+
// src/components/ui/input.tsx
|
|
3242
|
+
init_utils();
|
|
3087
3243
|
function Input({ className, type, ...props }) {
|
|
3088
3244
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3089
3245
|
"input",
|
|
@@ -3115,7 +3271,7 @@ function buildAnswer(q, sel) {
|
|
|
3115
3271
|
}
|
|
3116
3272
|
function ClarifyToolBlock({ tc }) {
|
|
3117
3273
|
const { adapter, sessionId } = useAgentChatAdapterContext();
|
|
3118
|
-
const args = react.useMemo(() =>
|
|
3274
|
+
const args = react.useMemo(() => parseArgs(tc.args), [tc.args]);
|
|
3119
3275
|
const questions = args?.questions ?? [];
|
|
3120
3276
|
const [active, setActive] = react.useState(0);
|
|
3121
3277
|
const [selections, setSelections] = react.useState(
|
|
@@ -3397,7 +3553,7 @@ function ClarifyLocked({
|
|
|
3397
3553
|
] });
|
|
3398
3554
|
}
|
|
3399
3555
|
function ArtifactToolBlock({ tc }) {
|
|
3400
|
-
const args =
|
|
3556
|
+
const args = parseArgs(tc.args) ?? {};
|
|
3401
3557
|
const status = effectiveStatus(tc);
|
|
3402
3558
|
const label = status === "running" ? "Creating artifact\u2026" : status === "error" ? "Tried to create" : "Created";
|
|
3403
3559
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-sm ", children: [
|
|
@@ -3405,13 +3561,16 @@ function ArtifactToolBlock({ tc }) {
|
|
|
3405
3561
|
args.name && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground truncate", children: args.name })
|
|
3406
3562
|
] });
|
|
3407
3563
|
}
|
|
3564
|
+
|
|
3565
|
+
// src/components/chat/tools/delegate-tool.tsx
|
|
3566
|
+
init_utils();
|
|
3408
3567
|
function firstLine(s) {
|
|
3409
3568
|
const idx = s.indexOf("\n");
|
|
3410
3569
|
return idx === -1 ? s : s.slice(0, idx);
|
|
3411
3570
|
}
|
|
3412
3571
|
function DelegateToolBlock({ tc }) {
|
|
3413
3572
|
const [expanded, setExpanded] = react.useState(false);
|
|
3414
|
-
const args =
|
|
3573
|
+
const args = parseArgs(tc.args);
|
|
3415
3574
|
const goal = args?.goal ?? "";
|
|
3416
3575
|
const context = args?.context ?? "";
|
|
3417
3576
|
const agentType = args?.agent_type;
|
|
@@ -3505,6 +3664,7 @@ function DelegateToolBlock({ tc }) {
|
|
|
3505
3664
|
] })
|
|
3506
3665
|
] });
|
|
3507
3666
|
}
|
|
3667
|
+
init_utils();
|
|
3508
3668
|
var ACTION_VERB = {
|
|
3509
3669
|
add: "Saved",
|
|
3510
3670
|
replace: "Updated",
|
|
@@ -3521,8 +3681,8 @@ var TARGET_LABEL = {
|
|
|
3521
3681
|
};
|
|
3522
3682
|
function MemoryToolBlock({ tc }) {
|
|
3523
3683
|
const [isOpen, setIsOpen] = react.useState(false);
|
|
3524
|
-
const args =
|
|
3525
|
-
const result = tc.result ?
|
|
3684
|
+
const args = parseArgs(tc.args) ?? {};
|
|
3685
|
+
const result = tc.result ? parseArgs(tc.result) : null;
|
|
3526
3686
|
const action = args.action ?? "add";
|
|
3527
3687
|
const target = args.target ?? "memory";
|
|
3528
3688
|
const verb = ACTION_VERB[action] ?? action;
|
|
@@ -3600,8 +3760,8 @@ var ACTION_LABEL = {
|
|
|
3600
3760
|
remove_file: "Remove skill file"
|
|
3601
3761
|
};
|
|
3602
3762
|
function SkillManageToolBlock({ tc }) {
|
|
3603
|
-
const args =
|
|
3604
|
-
const result = tc.result ?
|
|
3763
|
+
const args = parseArgs(tc.args) ?? {};
|
|
3764
|
+
const result = tc.result ? parseArgs(tc.result) : null;
|
|
3605
3765
|
const action = args.action ?? "manage";
|
|
3606
3766
|
const label = ACTION_LABEL[action] ?? "Manage skill";
|
|
3607
3767
|
const target = args.file_path ? `${args.name ?? "?"}/${args.file_path}` : args.name ?? "?";
|
|
@@ -3622,8 +3782,8 @@ function firstLine2(value) {
|
|
|
3622
3782
|
return (index === -1 ? value : value.slice(0, index)).trim();
|
|
3623
3783
|
}
|
|
3624
3784
|
function CoordinatorToolBlock({ tc }) {
|
|
3625
|
-
const args =
|
|
3626
|
-
const result = tc.result ?
|
|
3785
|
+
const args = parseArgs(tc.args) ?? {};
|
|
3786
|
+
const result = tc.result ? parseArgs(tc.result) : null;
|
|
3627
3787
|
const failed = Boolean(result?.error);
|
|
3628
3788
|
let label = "Worker";
|
|
3629
3789
|
let target = "";
|
|
@@ -3656,6 +3816,9 @@ function CoordinatorToolBlock({ tc }) {
|
|
|
3656
3816
|
] })
|
|
3657
3817
|
] });
|
|
3658
3818
|
}
|
|
3819
|
+
|
|
3820
|
+
// src/components/chat/tools/default-tool.tsx
|
|
3821
|
+
init_utils();
|
|
3659
3822
|
var TOOL_LABELS = {
|
|
3660
3823
|
kb_list_pages: "Knowledge Base",
|
|
3661
3824
|
kb_read_page: "Read KB Page",
|
|
@@ -3810,6 +3973,9 @@ function AssistantMessage({
|
|
|
3810
3973
|
] })
|
|
3811
3974
|
] }) });
|
|
3812
3975
|
}
|
|
3976
|
+
|
|
3977
|
+
// src/components/ui/hover-card.tsx
|
|
3978
|
+
init_utils();
|
|
3813
3979
|
function HoverCard({
|
|
3814
3980
|
...props
|
|
3815
3981
|
}) {
|
|
@@ -3840,6 +4006,9 @@ function HoverCardContent({
|
|
|
3840
4006
|
}
|
|
3841
4007
|
) });
|
|
3842
4008
|
}
|
|
4009
|
+
|
|
4010
|
+
// src/components/ui/progress.tsx
|
|
4011
|
+
init_utils();
|
|
3843
4012
|
function Progress({
|
|
3844
4013
|
className,
|
|
3845
4014
|
value,
|
|
@@ -3865,6 +4034,9 @@ function Progress({
|
|
|
3865
4034
|
}
|
|
3866
4035
|
);
|
|
3867
4036
|
}
|
|
4037
|
+
|
|
4038
|
+
// src/components/ai-elements/context.tsx
|
|
4039
|
+
init_utils();
|
|
3868
4040
|
var PERCENT_MAX = 100;
|
|
3869
4041
|
var ICON_RADIUS = 10;
|
|
3870
4042
|
var ICON_VIEWBOX = 24;
|
|
@@ -4129,6 +4301,12 @@ var ContextCacheUsage = ({
|
|
|
4129
4301
|
}
|
|
4130
4302
|
);
|
|
4131
4303
|
};
|
|
4304
|
+
|
|
4305
|
+
// src/components/ui/command.tsx
|
|
4306
|
+
init_utils();
|
|
4307
|
+
|
|
4308
|
+
// src/components/ui/input-group.tsx
|
|
4309
|
+
init_utils();
|
|
4132
4310
|
function InputGroup({ className, ...props }) {
|
|
4133
4311
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4134
4312
|
"div",
|
|
@@ -4313,6 +4491,9 @@ function CommandItem({
|
|
|
4313
4491
|
}
|
|
4314
4492
|
);
|
|
4315
4493
|
}
|
|
4494
|
+
|
|
4495
|
+
// src/components/ui/dropdown-menu.tsx
|
|
4496
|
+
init_utils();
|
|
4316
4497
|
function DropdownMenu({
|
|
4317
4498
|
...props
|
|
4318
4499
|
}) {
|
|
@@ -4366,9 +4547,15 @@ function DropdownMenuItem({
|
|
|
4366
4547
|
}
|
|
4367
4548
|
);
|
|
4368
4549
|
}
|
|
4550
|
+
|
|
4551
|
+
// src/components/ui/spinner.tsx
|
|
4552
|
+
init_utils();
|
|
4369
4553
|
function Spinner({ className, ...props }) {
|
|
4370
4554
|
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2Icon, { role: "status", "aria-label": "Loading", className: cn("size-4 animate-spin", className), ...props });
|
|
4371
4555
|
}
|
|
4556
|
+
|
|
4557
|
+
// src/components/ai-elements/prompt-input.tsx
|
|
4558
|
+
init_utils();
|
|
4372
4559
|
var convertBlobUrlToDataUrl = async (url) => {
|
|
4373
4560
|
try {
|
|
4374
4561
|
const response = await fetch(url);
|
|
@@ -5066,6 +5253,9 @@ var PromptInputSubmit = ({
|
|
|
5066
5253
|
}
|
|
5067
5254
|
);
|
|
5068
5255
|
};
|
|
5256
|
+
|
|
5257
|
+
// src/components/ui/popover.tsx
|
|
5258
|
+
init_utils();
|
|
5069
5259
|
function Popover({
|
|
5070
5260
|
...props
|
|
5071
5261
|
}) {
|
|
@@ -5313,6 +5503,9 @@ function ChatComposerInner({
|
|
|
5313
5503
|
)
|
|
5314
5504
|
] });
|
|
5315
5505
|
}
|
|
5506
|
+
|
|
5507
|
+
// src/components/ai-elements/artifact.tsx
|
|
5508
|
+
init_utils();
|
|
5316
5509
|
var Artifact = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5317
5510
|
"div",
|
|
5318
5511
|
{
|
|
@@ -5433,6 +5626,9 @@ function ArtifactTable({ spec }) {
|
|
|
5433
5626
|
)) })
|
|
5434
5627
|
] }) });
|
|
5435
5628
|
}
|
|
5629
|
+
|
|
5630
|
+
// src/components/chat/artifacts/artifact-html.tsx
|
|
5631
|
+
init_utils();
|
|
5436
5632
|
var DEFAULT_HEIGHT_PX = 480;
|
|
5437
5633
|
var EXPANDED_HEIGHT_PX = 800;
|
|
5438
5634
|
var MIN_ZOOM = 0.5;
|
|
@@ -5574,7 +5770,7 @@ function exportArtifact(payload) {
|
|
|
5574
5770
|
};
|
|
5575
5771
|
case "chart":
|
|
5576
5772
|
return {
|
|
5577
|
-
text: JSON.stringify(payload.spec.
|
|
5773
|
+
text: JSON.stringify(payload.spec.chart_js, null, 2),
|
|
5578
5774
|
mime: "application/json",
|
|
5579
5775
|
extension: "json"
|
|
5580
5776
|
};
|
|
@@ -5760,7 +5956,7 @@ function ArtifactBody({
|
|
|
5760
5956
|
react.Suspense,
|
|
5761
5957
|
{
|
|
5762
5958
|
fallback: /* @__PURE__ */ jsxRuntime.jsx(Shimmer, { duration: 5, className: "text-sm text-muted-foreground", children: "Loading chart\u2026" }),
|
|
5763
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(ArtifactChart2, { spec: payload.spec })
|
|
5959
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ArtifactChart2, { spec: payload.spec, fill })
|
|
5764
5960
|
}
|
|
5765
5961
|
);
|
|
5766
5962
|
case "html":
|
|
@@ -5769,6 +5965,7 @@ function ArtifactBody({
|
|
|
5769
5965
|
return /* @__PURE__ */ jsxRuntime.jsx(ArtifactSvg, { spec: payload.spec });
|
|
5770
5966
|
}
|
|
5771
5967
|
}
|
|
5968
|
+
init_utils();
|
|
5772
5969
|
var ErrorMessage = react.memo(function ErrorMessage2({
|
|
5773
5970
|
errorInfo,
|
|
5774
5971
|
onRetry,
|
|
@@ -5849,6 +6046,9 @@ var ErrorMessage = react.memo(function ErrorMessage2({
|
|
|
5849
6046
|
}
|
|
5850
6047
|
);
|
|
5851
6048
|
});
|
|
6049
|
+
|
|
6050
|
+
// src/components/chat/chat-thread.tsx
|
|
6051
|
+
init_utils();
|
|
5852
6052
|
function messageToEntries(msg, isLast) {
|
|
5853
6053
|
if (msg.role === "system") {
|
|
5854
6054
|
if (msg.systemKind === "skill_invoked") {
|
|
@@ -5980,7 +6180,7 @@ function OrphanSystemMarker({
|
|
|
5980
6180
|
);
|
|
5981
6181
|
}
|
|
5982
6182
|
if (message.systemKind === "error" && message.errorInfo) {
|
|
5983
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto my-2 w-full max-w-4xl
|
|
6183
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto my-2 w-full max-w-4xl", children: /* @__PURE__ */ jsxRuntime.jsx(ErrorMessage, { errorInfo: message.errorInfo, onRetry }) });
|
|
5984
6184
|
}
|
|
5985
6185
|
return null;
|
|
5986
6186
|
}
|
|
@@ -6034,6 +6234,7 @@ function TimelineEntryItem({
|
|
|
6034
6234
|
] });
|
|
6035
6235
|
}
|
|
6036
6236
|
if (entry.kind === "tool") {
|
|
6237
|
+
const failureSummary = effectiveStatus(entry.tc) === "error" ? toolErrorSummary(entry.tc.result) : "";
|
|
6037
6238
|
return /* @__PURE__ */ jsxRuntime.jsxs(TimelineItem, { step, children: [
|
|
6038
6239
|
/* @__PURE__ */ jsxRuntime.jsxs(TimelineHeader, { children: [
|
|
6039
6240
|
/* @__PURE__ */ jsxRuntime.jsx(TimelineSeparator, { style: { backgroundColor: "var(--color-border)" } }),
|
|
@@ -6044,7 +6245,10 @@ function TimelineEntryItem({
|
|
|
6044
6245
|
}
|
|
6045
6246
|
)
|
|
6046
6247
|
] }),
|
|
6047
|
-
/* @__PURE__ */ jsxRuntime.jsx(TimelineContent, { children: entry.tc.cancelled ? /* @__PURE__ */ jsxRuntime.jsx(CancelledToolRow, { tc: entry.tc }) : /* @__PURE__ */ jsxRuntime.
|
|
6248
|
+
/* @__PURE__ */ jsxRuntime.jsx(TimelineContent, { children: entry.tc.cancelled ? /* @__PURE__ */ jsxRuntime.jsx(CancelledToolRow, { tc: entry.tc }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
6249
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToolCallBlock, { tc: entry.tc, onFileSelect }),
|
|
6250
|
+
failureSummary ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-full truncate text-xs text-destructive", title: failureSummary, children: failureSummary }) : null
|
|
6251
|
+
] }) })
|
|
6048
6252
|
] });
|
|
6049
6253
|
}
|
|
6050
6254
|
if (entry.kind === "text") {
|
|
@@ -6162,6 +6366,7 @@ function ChatThread({
|
|
|
6162
6366
|
sessionId,
|
|
6163
6367
|
messages,
|
|
6164
6368
|
isRunning,
|
|
6369
|
+
isLoadingHistory = false,
|
|
6165
6370
|
onSend,
|
|
6166
6371
|
onStop,
|
|
6167
6372
|
onFileSelect,
|
|
@@ -6184,7 +6389,14 @@ function ChatThread({
|
|
|
6184
6389
|
}, [messages]);
|
|
6185
6390
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden bg-background text-sm", children: [
|
|
6186
6391
|
/* @__PURE__ */ jsxRuntime.jsxs(Conversation, { className: "relative flex-1 min-h-0", children: [
|
|
6187
|
-
/* @__PURE__ */ jsxRuntime.jsx(ConversationContent, { className: "mx-auto w-full max-w-
|
|
6392
|
+
/* @__PURE__ */ jsxRuntime.jsx(ConversationContent, { className: "mx-auto w-full max-w-4xl", children: messages.length === 0 && isLoadingHistory ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6393
|
+
ConversationEmptyState,
|
|
6394
|
+
{
|
|
6395
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquareIcon, { className: "size-8 opacity-40" }),
|
|
6396
|
+
title: "Loading conversation",
|
|
6397
|
+
description: "Fetching the session history."
|
|
6398
|
+
}
|
|
6399
|
+
) : messages.length === 0 && !disabled ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6188
6400
|
ConversationEmptyState,
|
|
6189
6401
|
{
|
|
6190
6402
|
icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquareIcon, { className: "size-8 opacity-40" }),
|
|
@@ -6237,7 +6449,7 @@ function ChatThread({
|
|
|
6237
6449
|
] }) }),
|
|
6238
6450
|
/* @__PURE__ */ jsxRuntime.jsx(ConversationScrollButton, {})
|
|
6239
6451
|
] }),
|
|
6240
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto w-full max-w-
|
|
6452
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto w-full max-w-4xl px-6 pb-5 pt-3", children: [
|
|
6241
6453
|
retryIndicator && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxRuntime.jsx(RetryBanner, { indicator: retryIndicator }) }),
|
|
6242
6454
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6243
6455
|
ChatComposer,
|
|
@@ -6252,6 +6464,9 @@ function ChatThread({
|
|
|
6252
6464
|
] })
|
|
6253
6465
|
] });
|
|
6254
6466
|
}
|
|
6467
|
+
|
|
6468
|
+
// src/components/ai-elements/file-tree.tsx
|
|
6469
|
+
init_utils();
|
|
6255
6470
|
var noop = () => {
|
|
6256
6471
|
};
|
|
6257
6472
|
var FileTreeContext = react.createContext({
|
|
@@ -6418,6 +6633,9 @@ function FileTreeFile({
|
|
|
6418
6633
|
}
|
|
6419
6634
|
);
|
|
6420
6635
|
}
|
|
6636
|
+
|
|
6637
|
+
// src/components/ui/skeleton.tsx
|
|
6638
|
+
init_utils();
|
|
6421
6639
|
function Skeleton({ className, ...props }) {
|
|
6422
6640
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6423
6641
|
"div",
|
|
@@ -6428,6 +6646,9 @@ function Skeleton({ className, ...props }) {
|
|
|
6428
6646
|
);
|
|
6429
6647
|
}
|
|
6430
6648
|
|
|
6649
|
+
// src/components/workspace/workspace-panel.tsx
|
|
6650
|
+
init_utils();
|
|
6651
|
+
|
|
6431
6652
|
// src/lib/format.ts
|
|
6432
6653
|
function formatFileSize(bytes) {
|
|
6433
6654
|
if (bytes < 1024) return `${bytes} B`;
|
|
@@ -6838,7 +7059,7 @@ function formatPdfPreviewError(error) {
|
|
|
6838
7059
|
return error instanceof Error ? error.message : "Failed to render PDF preview.";
|
|
6839
7060
|
}
|
|
6840
7061
|
var SKELETON_WIDTHS2 = [75, 60, 90, 65, 80, 70, 85, 55];
|
|
6841
|
-
var DEFAULT_WIDTH =
|
|
7062
|
+
var DEFAULT_WIDTH = 400;
|
|
6842
7063
|
var MIN_WIDTH = 300;
|
|
6843
7064
|
var MAX_WIDTH = 900;
|
|
6844
7065
|
function collectExpandedPaths(entries, depth = 0) {
|
|
@@ -6920,6 +7141,8 @@ function WorkspacePanel({
|
|
|
6920
7141
|
sessionId,
|
|
6921
7142
|
selectedPath,
|
|
6922
7143
|
onSelectedPathChange,
|
|
7144
|
+
collapsed = false,
|
|
7145
|
+
onCollapsedChange,
|
|
6923
7146
|
disabled = false
|
|
6924
7147
|
}) {
|
|
6925
7148
|
const fileInputRef = react.useRef(null);
|
|
@@ -7114,6 +7337,25 @@ function WorkspacePanel({
|
|
|
7114
7337
|
window.removeEventListener("mouseup", onMouseUp);
|
|
7115
7338
|
};
|
|
7116
7339
|
}, []);
|
|
7340
|
+
if (collapsed) {
|
|
7341
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7342
|
+
"aside",
|
|
7343
|
+
{
|
|
7344
|
+
role: "button",
|
|
7345
|
+
tabIndex: 0,
|
|
7346
|
+
className: "relative z-10 flex min-h-0 w-10 shrink-0 cursor-pointer items-center justify-center border-l border-muted-foreground/20 bg-card text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/30",
|
|
7347
|
+
"aria-label": "Expand workspace",
|
|
7348
|
+
onClick: () => onCollapsedChange?.(false),
|
|
7349
|
+
onKeyDown: (event) => {
|
|
7350
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
7351
|
+
event.preventDefault();
|
|
7352
|
+
onCollapsedChange?.(false);
|
|
7353
|
+
}
|
|
7354
|
+
},
|
|
7355
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FolderOpenIcon, { className: "size-4 text-amber-500" })
|
|
7356
|
+
}
|
|
7357
|
+
);
|
|
7358
|
+
}
|
|
7117
7359
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7118
7360
|
"aside",
|
|
7119
7361
|
{
|
|
@@ -7146,6 +7388,19 @@ function WorkspacePanel({
|
|
|
7146
7388
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-sm font-medium text-foreground", children: rootName }),
|
|
7147
7389
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-xs text-faint", children: "Workspace" })
|
|
7148
7390
|
] }),
|
|
7391
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
7392
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7393
|
+
Button,
|
|
7394
|
+
{
|
|
7395
|
+
variant: "ghost",
|
|
7396
|
+
size: "icon-sm",
|
|
7397
|
+
onClick: () => onCollapsedChange?.(true),
|
|
7398
|
+
"aria-label": "Collapse workspace",
|
|
7399
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, { className: "size-4" })
|
|
7400
|
+
}
|
|
7401
|
+
) }),
|
|
7402
|
+
/* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { side: "bottom", children: "Collapse" })
|
|
7403
|
+
] }),
|
|
7149
7404
|
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
7150
7405
|
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7151
7406
|
Button,
|
|
@@ -7345,10 +7600,11 @@ var EMPTY_TOKEN_USAGE = {
|
|
|
7345
7600
|
contextWindow: 0,
|
|
7346
7601
|
model: ""
|
|
7347
7602
|
};
|
|
7348
|
-
function createInitialAgentChatState() {
|
|
7603
|
+
function createInitialAgentChatState(options = {}) {
|
|
7349
7604
|
return {
|
|
7350
7605
|
messages: [],
|
|
7351
7606
|
isRunning: false,
|
|
7607
|
+
isLoadingHistory: options.isLoadingHistory ?? false,
|
|
7352
7608
|
tokenUsage: EMPTY_TOKEN_USAGE,
|
|
7353
7609
|
retryIndicator: null,
|
|
7354
7610
|
lastEventId: 0,
|
|
@@ -7360,6 +7616,7 @@ function createInitialAgentChatState() {
|
|
|
7360
7616
|
function applyAgentChatEvent(state, event) {
|
|
7361
7617
|
let nextState = {
|
|
7362
7618
|
...state,
|
|
7619
|
+
isLoadingHistory: false,
|
|
7363
7620
|
lastEventId: Math.max(state.lastEventId, event.eventId),
|
|
7364
7621
|
sessionDone: state.sessionDone || event.type === "session.done"
|
|
7365
7622
|
};
|
|
@@ -7893,11 +8150,12 @@ function useAgentChatRuntime({
|
|
|
7893
8150
|
onSessionChange
|
|
7894
8151
|
}) {
|
|
7895
8152
|
const [state, setState] = react.useState(
|
|
7896
|
-
() => createInitialAgentChatState()
|
|
8153
|
+
() => createInitialAgentChatState({ isLoadingHistory: Boolean(sessionId) })
|
|
7897
8154
|
);
|
|
7898
8155
|
const stateRef = react.useRef(state);
|
|
7899
8156
|
const streamRef = react.useRef(null);
|
|
7900
8157
|
const reconnectTimerRef = react.useRef(null);
|
|
8158
|
+
const previousSessionIdRef = react.useRef(sessionId);
|
|
7901
8159
|
react.useEffect(() => {
|
|
7902
8160
|
stateRef.current = state;
|
|
7903
8161
|
}, [state]);
|
|
@@ -7913,6 +8171,8 @@ function useAgentChatRuntime({
|
|
|
7913
8171
|
stream?.close();
|
|
7914
8172
|
}, []);
|
|
7915
8173
|
react.useEffect(() => {
|
|
8174
|
+
const previousSessionId = previousSessionIdRef.current;
|
|
8175
|
+
previousSessionIdRef.current = sessionId;
|
|
7916
8176
|
clearReconnectTimer();
|
|
7917
8177
|
closeStream();
|
|
7918
8178
|
if (!sessionId) {
|
|
@@ -7920,11 +8180,11 @@ function useAgentChatRuntime({
|
|
|
7920
8180
|
return;
|
|
7921
8181
|
}
|
|
7922
8182
|
let cancelled = false;
|
|
7923
|
-
const connect = () => {
|
|
8183
|
+
const connect = (after) => {
|
|
7924
8184
|
if (cancelled) return;
|
|
7925
8185
|
const stream = adapter.openEventStream({
|
|
7926
8186
|
sessionId,
|
|
7927
|
-
after: stateRef.current.lastEventId
|
|
8187
|
+
after: after ?? stateRef.current.lastEventId
|
|
7928
8188
|
});
|
|
7929
8189
|
streamRef.current = stream;
|
|
7930
8190
|
for (const eventType of AGENT_CHAT_LISTENED_EVENTS) {
|
|
@@ -7947,14 +8207,32 @@ function useAgentChatRuntime({
|
|
|
7947
8207
|
streamRef.current = null;
|
|
7948
8208
|
}
|
|
7949
8209
|
if (!stateRef.current.sessionDone && !cancelled) {
|
|
7950
|
-
reconnectTimerRef.current = setTimeout(connect, 3e3);
|
|
8210
|
+
reconnectTimerRef.current = setTimeout(() => connect(), 3e3);
|
|
7951
8211
|
}
|
|
7952
8212
|
};
|
|
7953
8213
|
};
|
|
7954
|
-
|
|
7955
|
-
|
|
8214
|
+
const currentState = stateRef.current;
|
|
8215
|
+
const preservePendingFirstMessage = previousSessionId === null && currentState.isRunning && currentState.messages.some(
|
|
8216
|
+
(message) => message.role === "user" && message.id.startsWith("local-")
|
|
8217
|
+
);
|
|
8218
|
+
const initialState = preservePendingFirstMessage ? {
|
|
8219
|
+
...createInitialAgentChatState({ isLoadingHistory: false }),
|
|
8220
|
+
messages: currentState.messages,
|
|
8221
|
+
isRunning: true
|
|
8222
|
+
} : createInitialAgentChatState({
|
|
8223
|
+
isLoadingHistory: true
|
|
8224
|
+
});
|
|
8225
|
+
stateRef.current = initialState;
|
|
8226
|
+
setState(initialState);
|
|
8227
|
+
connect(0);
|
|
7956
8228
|
adapter.getSession({ sessionId }).then((session) => {
|
|
7957
8229
|
if (cancelled) return;
|
|
8230
|
+
if (session.messageCount === 0) {
|
|
8231
|
+
setState((prev) => ({
|
|
8232
|
+
...prev,
|
|
8233
|
+
isLoadingHistory: false
|
|
8234
|
+
}));
|
|
8235
|
+
}
|
|
7958
8236
|
if (isTerminalStatus(session.status)) {
|
|
7959
8237
|
setState((prev) => ({
|
|
7960
8238
|
...prev,
|
|
@@ -8037,13 +8315,18 @@ function useAgentChatRuntime({
|
|
|
8037
8315
|
}, []);
|
|
8038
8316
|
const send = react.useCallback(
|
|
8039
8317
|
async (content) => {
|
|
8318
|
+
markSending(content);
|
|
8040
8319
|
if (!sessionId) {
|
|
8041
|
-
|
|
8042
|
-
|
|
8043
|
-
|
|
8320
|
+
try {
|
|
8321
|
+
const session = await adapter.createSession({ agentId });
|
|
8322
|
+
onSessionChange?.(session.id);
|
|
8323
|
+
await adapter.sendMessage({ sessionId: session.id, content });
|
|
8324
|
+
} catch (error) {
|
|
8325
|
+
markSendError(error instanceof Error ? error.message : "send failed");
|
|
8326
|
+
throw error;
|
|
8327
|
+
}
|
|
8044
8328
|
return;
|
|
8045
8329
|
}
|
|
8046
|
-
markSending(content);
|
|
8047
8330
|
try {
|
|
8048
8331
|
await adapter.sendMessage({ sessionId, content });
|
|
8049
8332
|
} catch (error) {
|
|
@@ -8080,6 +8363,7 @@ function useAgentChatRuntime({
|
|
|
8080
8363
|
return {
|
|
8081
8364
|
messages: state.messages,
|
|
8082
8365
|
isRunning: state.isRunning,
|
|
8366
|
+
isLoadingHistory: state.isLoadingHistory,
|
|
8083
8367
|
tokenUsage: state.tokenUsage,
|
|
8084
8368
|
retryIndicator: state.retryIndicator,
|
|
8085
8369
|
send,
|
|
@@ -8116,6 +8400,7 @@ function AgentChat({
|
|
|
8116
8400
|
disabled
|
|
8117
8401
|
}) {
|
|
8118
8402
|
const [workspacePath, setWorkspacePath] = react.useState(null);
|
|
8403
|
+
const [workspaceCollapsed, setWorkspaceCollapsed] = react.useState(false);
|
|
8119
8404
|
const runtime = useAgentChatRuntime({
|
|
8120
8405
|
adapter,
|
|
8121
8406
|
agentId,
|
|
@@ -8147,6 +8432,7 @@ function AgentChat({
|
|
|
8147
8432
|
sessionId,
|
|
8148
8433
|
messages: runtime.messages,
|
|
8149
8434
|
isRunning: runtime.isRunning,
|
|
8435
|
+
isLoadingHistory: runtime.isLoadingHistory,
|
|
8150
8436
|
onSend: (content) => void runtime.send(content),
|
|
8151
8437
|
onStop: () => void runtime.stop(),
|
|
8152
8438
|
onRetry: runtime.retry,
|
|
@@ -8163,6 +8449,8 @@ function AgentChat({
|
|
|
8163
8449
|
sessionId,
|
|
8164
8450
|
selectedPath: workspacePath,
|
|
8165
8451
|
onSelectedPathChange: setWorkspacePath,
|
|
8452
|
+
collapsed: workspaceCollapsed,
|
|
8453
|
+
onCollapsedChange: setWorkspaceCollapsed,
|
|
8166
8454
|
disabled
|
|
8167
8455
|
}
|
|
8168
8456
|
)
|
|
@@ -8170,6 +8458,7 @@ function AgentChat({
|
|
|
8170
8458
|
}
|
|
8171
8459
|
);
|
|
8172
8460
|
}
|
|
8461
|
+
init_utils();
|
|
8173
8462
|
var POLL_INTERVAL_ACTIVE_MS = 4e3;
|
|
8174
8463
|
var POLL_INTERVAL_IDLE_MS = 3e4;
|
|
8175
8464
|
var DEFAULT_SESSION_LIST_LIMIT = 50;
|
|
@@ -8233,6 +8522,20 @@ function mergeTreeNodes(groups) {
|
|
|
8233
8522
|
}
|
|
8234
8523
|
return Array.from(byId.values());
|
|
8235
8524
|
}
|
|
8525
|
+
function pruneDeletedSessionNodes(nodes, deletedSessionId) {
|
|
8526
|
+
const deletedIds = /* @__PURE__ */ new Set([deletedSessionId]);
|
|
8527
|
+
let changed = true;
|
|
8528
|
+
while (changed) {
|
|
8529
|
+
changed = false;
|
|
8530
|
+
for (const node of nodes) {
|
|
8531
|
+
if (node.parentId && deletedIds.has(node.parentId) && !deletedIds.has(node.id)) {
|
|
8532
|
+
deletedIds.add(node.id);
|
|
8533
|
+
changed = true;
|
|
8534
|
+
}
|
|
8535
|
+
}
|
|
8536
|
+
}
|
|
8537
|
+
return nodes.filter((node) => !deletedIds.has(node.id));
|
|
8538
|
+
}
|
|
8236
8539
|
function formatSessionTime(value) {
|
|
8237
8540
|
const date = new Date(value);
|
|
8238
8541
|
if (Number.isNaN(date.getTime())) return "";
|
|
@@ -8349,11 +8652,12 @@ function SessionTreePanel({
|
|
|
8349
8652
|
title = "Running",
|
|
8350
8653
|
sessionListLimit = DEFAULT_SESSION_LIST_LIMIT,
|
|
8351
8654
|
hideRoot = false,
|
|
8655
|
+
hideHeader = false,
|
|
8656
|
+
loadList = false,
|
|
8352
8657
|
onSessionSelect,
|
|
8353
8658
|
onSessionDelete
|
|
8354
8659
|
}) {
|
|
8355
8660
|
const [nodes, setNodes] = react.useState([]);
|
|
8356
|
-
const [loading, setLoading] = react.useState(false);
|
|
8357
8661
|
const [error, setError] = react.useState(null);
|
|
8358
8662
|
const [hasEverLoaded, setHasEverLoaded] = react.useState(false);
|
|
8359
8663
|
const [deletingSessionId, setDeletingSessionId] = react.useState(
|
|
@@ -8365,18 +8669,16 @@ function SessionTreePanel({
|
|
|
8365
8669
|
const resetContext = react.useRef(null);
|
|
8366
8670
|
const refetch = react.useCallback(
|
|
8367
8671
|
async (opts) => {
|
|
8368
|
-
const canLoadSessionList = Boolean(
|
|
8672
|
+
const canLoadSessionList = Boolean(loadList && adapter.listSessions);
|
|
8369
8673
|
const canLoadSessionTree = Boolean(sessionId && adapter.getSessionTree);
|
|
8370
8674
|
if (!canLoadSessionList && !canLoadSessionTree) {
|
|
8371
8675
|
setNodes([]);
|
|
8372
8676
|
setHasEverLoaded(true);
|
|
8373
|
-
setLoading(false);
|
|
8374
8677
|
return;
|
|
8375
8678
|
}
|
|
8376
8679
|
const currentRequestId = ++requestId.current;
|
|
8377
|
-
if (!opts?.silent) setLoading(true);
|
|
8378
8680
|
try {
|
|
8379
|
-
const sessionListPromise =
|
|
8681
|
+
const sessionListPromise = loadList && adapter.listSessions ? adapter.listSessions({
|
|
8380
8682
|
agentId,
|
|
8381
8683
|
limit: sessionListLimit
|
|
8382
8684
|
}) : Promise.resolve(null);
|
|
@@ -8402,13 +8704,9 @@ function SessionTreePanel({
|
|
|
8402
8704
|
if (!opts?.silent) {
|
|
8403
8705
|
setError(e instanceof Error ? e.message : "Failed to load tree");
|
|
8404
8706
|
}
|
|
8405
|
-
} finally {
|
|
8406
|
-
if (mounted.current && currentRequestId === requestId.current && !opts?.silent) {
|
|
8407
|
-
setLoading(false);
|
|
8408
|
-
}
|
|
8409
8707
|
}
|
|
8410
8708
|
},
|
|
8411
|
-
[adapter, agentId, sessionId, sessionListLimit]
|
|
8709
|
+
[adapter, agentId, loadList, sessionId, sessionListLimit]
|
|
8412
8710
|
);
|
|
8413
8711
|
react.useEffect(() => {
|
|
8414
8712
|
mounted.current = true;
|
|
@@ -8418,8 +8716,8 @@ function SessionTreePanel({
|
|
|
8418
8716
|
}, []);
|
|
8419
8717
|
react.useEffect(() => {
|
|
8420
8718
|
const previous = resetContext.current;
|
|
8421
|
-
const shouldReset = !previous || previous.
|
|
8422
|
-
resetContext.current = {
|
|
8719
|
+
const shouldReset = !previous || previous.loadList !== loadList || previous.agentId !== agentId || previous.sessionListLimit !== sessionListLimit;
|
|
8720
|
+
resetContext.current = { loadList, agentId, sessionListLimit };
|
|
8423
8721
|
if (shouldReset) {
|
|
8424
8722
|
setNodes([]);
|
|
8425
8723
|
setHasEverLoaded(false);
|
|
@@ -8427,7 +8725,7 @@ function SessionTreePanel({
|
|
|
8427
8725
|
}
|
|
8428
8726
|
setError(null);
|
|
8429
8727
|
void refetch();
|
|
8430
|
-
}, [adapter, agentId, refetch, sessionListLimit]);
|
|
8728
|
+
}, [adapter, agentId, loadList, refetch, sessionListLimit]);
|
|
8431
8729
|
const runningCount = react.useMemo(
|
|
8432
8730
|
() => nodes.filter((n) => n.status === "active").length,
|
|
8433
8731
|
[nodes]
|
|
@@ -8464,6 +8762,11 @@ function SessionTreePanel({
|
|
|
8464
8762
|
setDeletingSessionId(id);
|
|
8465
8763
|
try {
|
|
8466
8764
|
await adapter.deleteSession({ sessionId: id });
|
|
8765
|
+
setNodes((current) => {
|
|
8766
|
+
const next = pruneDeletedSessionNodes(current, id);
|
|
8767
|
+
lastFingerprint.current = treeFingerprint(next);
|
|
8768
|
+
return next;
|
|
8769
|
+
});
|
|
8467
8770
|
onSessionDelete?.(id);
|
|
8468
8771
|
await refetch({ silent: true });
|
|
8469
8772
|
} catch (e) {
|
|
@@ -8478,24 +8781,12 @@ function SessionTreePanel({
|
|
|
8478
8781
|
if (nodes.length === 0) return null;
|
|
8479
8782
|
const topLevel = hideRoot ? roots.flatMap((r) => r.children) : roots;
|
|
8480
8783
|
if (topLevel.length === 0) return null;
|
|
8481
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8482
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 px-3 py-2 text-xs font-semibold uppercase tracking-wide", children: [
|
|
8784
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8785
|
+
!hideHeader && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-line flex items-center gap-1.5 px-3 py-2 text-xs font-semibold uppercase tracking-wide", children: [
|
|
8483
8786
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.UsersIcon, { className: "w-3.5 h-3.5" }),
|
|
8484
8787
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: title }),
|
|
8485
8788
|
runningCount > 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "default", className: "h-4 px-1.5 text-[10px] ml-auto", children: runningCount })
|
|
8486
8789
|
] }),
|
|
8487
|
-
loading && /* @__PURE__ */ jsxRuntime.jsx(
|
|
8488
|
-
"div",
|
|
8489
|
-
{
|
|
8490
|
-
className: "px-3 py-2",
|
|
8491
|
-
role: "status",
|
|
8492
|
-
"aria-label": "Loading sessions",
|
|
8493
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
8494
|
-
/* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-3.5 w-28" }),
|
|
8495
|
-
/* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-3 w-20" })
|
|
8496
|
-
] })
|
|
8497
|
-
}
|
|
8498
|
-
),
|
|
8499
8790
|
error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-2 text-xs text-destructive", children: error }),
|
|
8500
8791
|
!error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-1 pb-2", children: topLevel.map((entry) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
8501
8792
|
TreeNodeRow,
|