@invergent/agent-chat-react 1.5.2 → 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 +795 -241
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -2
- package/dist/index.d.ts +23 -2
- package/dist/index.js +542 -185
- package/dist/index.js.map +1 -1
- package/package.json +5 -7
- 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');
|
|
@@ -22,8 +22,10 @@ var Ansi = require('ansi-to-react');
|
|
|
22
22
|
var tokenlens = require('tokenlens');
|
|
23
23
|
var cmdk = require('cmdk');
|
|
24
24
|
var nanoid = require('nanoid');
|
|
25
|
+
require('pdfjs-dist/web/pdf_viewer.css');
|
|
25
26
|
var dateFns = require('date-fns');
|
|
26
27
|
|
|
28
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
27
29
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
28
30
|
|
|
29
31
|
var Ansi__default = /*#__PURE__*/_interopDefault(Ansi);
|
|
@@ -37,56 +39,63 @@ var __export = (target, all) => {
|
|
|
37
39
|
for (var name in all)
|
|
38
40
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
39
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
|
+
});
|
|
40
49
|
|
|
41
50
|
// src/components/chat/artifacts/artifact-chart.tsx
|
|
42
51
|
var artifact_chart_exports = {};
|
|
43
52
|
__export(artifact_chart_exports, {
|
|
44
53
|
ArtifactChart: () => ArtifactChart
|
|
45
54
|
});
|
|
46
|
-
function ArtifactChart({
|
|
55
|
+
function ArtifactChart({
|
|
56
|
+
spec,
|
|
57
|
+
fill = false
|
|
58
|
+
}) {
|
|
47
59
|
const { resolvedTheme } = nextThemes.useTheme();
|
|
48
60
|
const isDark = resolvedTheme === "dark";
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
react.useEffect(() => {
|
|
52
|
-
const el = containerRef.current;
|
|
53
|
-
if (!el) return;
|
|
54
|
-
const observer = new ResizeObserver((entries) => {
|
|
55
|
-
const w = entries[0]?.contentRect.width ?? el.offsetWidth;
|
|
56
|
-
if (w >= MIN_CHART_WIDTH) setWidth(Math.floor(w));
|
|
57
|
-
});
|
|
58
|
-
observer.observe(el);
|
|
59
|
-
if (el.offsetWidth >= MIN_CHART_WIDTH) setWidth(el.offsetWidth);
|
|
60
|
-
return () => observer.disconnect();
|
|
61
|
-
}, []);
|
|
61
|
+
const canvasRef = react.useRef(null);
|
|
62
|
+
const chartRef = react.useRef(null);
|
|
62
63
|
const [error, setError] = react.useState(null);
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
const base = spec.vega_lite ?? {};
|
|
66
|
-
const themeConfig = isDark ? DARK_CONFIG : LIGHT_CONFIG;
|
|
64
|
+
const config = react.useMemo(() => {
|
|
65
|
+
const base = cloneChartConfig(spec.chart_js ?? {});
|
|
67
66
|
return {
|
|
68
|
-
$schema: VEGA_LITE_SCHEMA,
|
|
69
|
-
width,
|
|
70
|
-
height: DEFAULT_CHART_HEIGHT,
|
|
71
67
|
...base,
|
|
72
|
-
|
|
73
|
-
...themeConfig,
|
|
74
|
-
...base.config ?? {}
|
|
75
|
-
}
|
|
68
|
+
options: mergeThemeOptions(base.options, base.type, isDark)
|
|
76
69
|
};
|
|
77
|
-
}, [spec.
|
|
70
|
+
}, [spec.chart_js, isDark]);
|
|
78
71
|
react.useEffect(() => {
|
|
72
|
+
const canvas = canvasRef.current;
|
|
73
|
+
if (!canvas) return;
|
|
74
|
+
chartRef.current?.destroy();
|
|
75
|
+
chartRef.current = null;
|
|
79
76
|
setError(null);
|
|
80
|
-
|
|
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]);
|
|
81
87
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
82
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
83
|
-
|
|
88
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
89
|
+
"div",
|
|
84
90
|
{
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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 })
|
|
88
97
|
}
|
|
89
|
-
)
|
|
98
|
+
),
|
|
90
99
|
error && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-destructive", children: [
|
|
91
100
|
"Chart error: ",
|
|
92
101
|
error
|
|
@@ -94,35 +103,101 @@ function ArtifactChart({ spec }) {
|
|
|
94
103
|
spec.caption && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: spec.caption })
|
|
95
104
|
] });
|
|
96
105
|
}
|
|
97
|
-
|
|
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;
|
|
98
185
|
var init_artifact_chart = __esm({
|
|
99
186
|
"src/components/chat/artifacts/artifact-chart.tsx"() {
|
|
100
|
-
|
|
187
|
+
init_utils();
|
|
101
188
|
DEFAULT_CHART_HEIGHT = 320;
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
gridColor: "#e5e7eb",
|
|
109
|
-
domainColor: "#d1d5db",
|
|
110
|
-
tickColor: "#d1d5db"
|
|
111
|
-
},
|
|
112
|
-
view: { stroke: "transparent" },
|
|
113
|
-
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"
|
|
114
195
|
};
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
gridColor: "#374151",
|
|
121
|
-
domainColor: "#4b5563",
|
|
122
|
-
tickColor: "#4b5563"
|
|
123
|
-
},
|
|
124
|
-
view: { stroke: "transparent" },
|
|
125
|
-
legend: { labelColor: "#cbd5e1", titleColor: "#f1f5f9" }
|
|
196
|
+
DARK_THEME = {
|
|
197
|
+
text: "#cbd5e1",
|
|
198
|
+
title: "#f1f5f9",
|
|
199
|
+
grid: "#374151",
|
|
200
|
+
border: "#4b5563"
|
|
126
201
|
};
|
|
127
202
|
}
|
|
128
203
|
});
|
|
@@ -137,9 +212,9 @@ function useAgentChatAdapterContext() {
|
|
|
137
212
|
}
|
|
138
213
|
return value;
|
|
139
214
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
215
|
+
|
|
216
|
+
// src/components/ui/button.tsx
|
|
217
|
+
init_utils();
|
|
143
218
|
var buttonVariants = classVarianceAuthority.cva(
|
|
144
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",
|
|
145
220
|
{
|
|
@@ -188,10 +263,13 @@ function Button({
|
|
|
188
263
|
}
|
|
189
264
|
);
|
|
190
265
|
}
|
|
266
|
+
|
|
267
|
+
// src/components/ai-elements/conversation.tsx
|
|
268
|
+
init_utils();
|
|
191
269
|
var Conversation = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
192
270
|
useStickToBottom.StickToBottom,
|
|
193
271
|
{
|
|
194
|
-
className: cn("relative flex-1
|
|
272
|
+
className: cn("relative flex-1", className),
|
|
195
273
|
initial: "smooth",
|
|
196
274
|
resize: "smooth",
|
|
197
275
|
role: "log",
|
|
@@ -256,6 +334,9 @@ var ConversationScrollButton = ({
|
|
|
256
334
|
}
|
|
257
335
|
);
|
|
258
336
|
};
|
|
337
|
+
|
|
338
|
+
// src/components/ui/tooltip.tsx
|
|
339
|
+
init_utils();
|
|
259
340
|
function TooltipProvider({
|
|
260
341
|
delayDuration = 0,
|
|
261
342
|
...props
|
|
@@ -302,6 +383,9 @@ function TooltipContent({
|
|
|
302
383
|
}
|
|
303
384
|
) });
|
|
304
385
|
}
|
|
386
|
+
|
|
387
|
+
// src/components/ai-elements/message.tsx
|
|
388
|
+
init_utils();
|
|
305
389
|
var Message = ({ className, from, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
306
390
|
"div",
|
|
307
391
|
{
|
|
@@ -376,6 +460,12 @@ function CollapsibleContent({
|
|
|
376
460
|
}
|
|
377
461
|
);
|
|
378
462
|
}
|
|
463
|
+
|
|
464
|
+
// src/components/ai-elements/reasoning.tsx
|
|
465
|
+
init_utils();
|
|
466
|
+
|
|
467
|
+
// src/components/ai-elements/shimmer.tsx
|
|
468
|
+
init_utils();
|
|
379
469
|
var ShimmerComponent = ({
|
|
380
470
|
children,
|
|
381
471
|
as: Component = "p",
|
|
@@ -552,6 +642,9 @@ var ReasoningContent = react.memo(
|
|
|
552
642
|
Reasoning.displayName = "Reasoning";
|
|
553
643
|
ReasoningTrigger.displayName = "ReasoningTrigger";
|
|
554
644
|
ReasoningContent.displayName = "ReasoningContent";
|
|
645
|
+
|
|
646
|
+
// src/components/reui/timeline.tsx
|
|
647
|
+
init_utils();
|
|
555
648
|
var TimelineContext = react.createContext(
|
|
556
649
|
void 0
|
|
557
650
|
);
|
|
@@ -674,6 +767,62 @@ function TimelineSeparator({
|
|
|
674
767
|
}
|
|
675
768
|
);
|
|
676
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
|
+
}
|
|
677
826
|
function CopyButton({ text }) {
|
|
678
827
|
const [copied, setCopied] = react.useState(false);
|
|
679
828
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -709,7 +858,8 @@ function parseTerminalResult(result, args) {
|
|
|
709
858
|
const hasOutput = typeof parsed?.output === "string";
|
|
710
859
|
const hasStdout = typeof parsed?.stdout === "string";
|
|
711
860
|
const hasExitCode = typeof parsed?.exit_code === "number";
|
|
712
|
-
|
|
861
|
+
const errorSummary = toolErrorSummary(result, 400);
|
|
862
|
+
if (!hasOutput && !hasStdout && !hasExitCode && !errorSummary) {
|
|
713
863
|
return null;
|
|
714
864
|
}
|
|
715
865
|
let command = "";
|
|
@@ -719,20 +869,20 @@ function parseTerminalResult(result, args) {
|
|
|
719
869
|
} catch {
|
|
720
870
|
}
|
|
721
871
|
const output = parsed.output ?? parsed.stdout ?? "";
|
|
722
|
-
const stderr = parsed.stderr ??
|
|
872
|
+
const stderr = parsed.stderr ?? errorSummary;
|
|
723
873
|
const combined = stderr ? `${output}
|
|
724
874
|
${stderr}`.trim() : output;
|
|
725
875
|
return {
|
|
726
876
|
output: combined,
|
|
727
|
-
exit_code: parsed.exit_code ?? 0,
|
|
728
|
-
error:
|
|
877
|
+
exit_code: parsed.exit_code ?? (errorSummary ? 1 : 0),
|
|
878
|
+
error: errorSummary || null,
|
|
729
879
|
command
|
|
730
880
|
};
|
|
731
881
|
} catch {
|
|
732
882
|
return null;
|
|
733
883
|
}
|
|
734
884
|
}
|
|
735
|
-
function TerminalCollapsible({ command, output, isRunning }) {
|
|
885
|
+
function TerminalCollapsible({ command, output, isRunning, hasError }) {
|
|
736
886
|
const [isOpen, setIsOpen] = react.useState(false);
|
|
737
887
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
738
888
|
Collapsible,
|
|
@@ -742,7 +892,7 @@ function TerminalCollapsible({ command, output, isRunning }) {
|
|
|
742
892
|
className: "not-prose w-full",
|
|
743
893
|
children: [
|
|
744
894
|
/* @__PURE__ */ jsxRuntime.jsxs(CollapsibleTrigger, { className: "group/trigger flex w-fit items-center gap-2 text-sm transition-colors", children: [
|
|
745
|
-
/* @__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" }) }),
|
|
746
896
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
747
897
|
lucideReact.ChevronDownIcon,
|
|
748
898
|
{
|
|
@@ -799,7 +949,8 @@ function TerminalToolBlock({ tc }) {
|
|
|
799
949
|
{
|
|
800
950
|
command: result.command,
|
|
801
951
|
output,
|
|
802
|
-
isRunning
|
|
952
|
+
isRunning,
|
|
953
|
+
hasError: result.exit_code !== 0 || Boolean(result.error)
|
|
803
954
|
}
|
|
804
955
|
);
|
|
805
956
|
}
|
|
@@ -814,6 +965,9 @@ function TerminalToolBlock({ tc }) {
|
|
|
814
965
|
}
|
|
815
966
|
return null;
|
|
816
967
|
}
|
|
968
|
+
|
|
969
|
+
// src/components/ui/scroll-area.tsx
|
|
970
|
+
init_utils();
|
|
817
971
|
function ScrollArea({
|
|
818
972
|
className,
|
|
819
973
|
children,
|
|
@@ -866,6 +1020,9 @@ function ScrollBar({
|
|
|
866
1020
|
}
|
|
867
1021
|
);
|
|
868
1022
|
}
|
|
1023
|
+
|
|
1024
|
+
// src/components/ai-elements/queue.tsx
|
|
1025
|
+
init_utils();
|
|
869
1026
|
var QueueItem = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
870
1027
|
"li",
|
|
871
1028
|
{
|
|
@@ -1018,6 +1175,9 @@ function TodoToolBlock({ tc }) {
|
|
|
1018
1175
|
}) }) })
|
|
1019
1176
|
] }) });
|
|
1020
1177
|
}
|
|
1178
|
+
|
|
1179
|
+
// src/components/ai-elements/code-block.tsx
|
|
1180
|
+
init_utils();
|
|
1021
1181
|
var isItalic = (fontStyle) => fontStyle && fontStyle & 1;
|
|
1022
1182
|
var isBold = (fontStyle) => fontStyle && fontStyle & 2;
|
|
1023
1183
|
var isUnderline = (fontStyle) => (
|
|
@@ -1307,6 +1467,9 @@ var CodeBlockCopyButton = ({
|
|
|
1307
1467
|
}
|
|
1308
1468
|
);
|
|
1309
1469
|
};
|
|
1470
|
+
|
|
1471
|
+
// src/components/ui/tabs.tsx
|
|
1472
|
+
init_utils();
|
|
1310
1473
|
function Tabs({
|
|
1311
1474
|
className,
|
|
1312
1475
|
orientation = "horizontal",
|
|
@@ -1386,6 +1549,12 @@ function TabsContent({
|
|
|
1386
1549
|
}
|
|
1387
1550
|
);
|
|
1388
1551
|
}
|
|
1552
|
+
|
|
1553
|
+
// src/components/ai-elements/sandbox.tsx
|
|
1554
|
+
init_utils();
|
|
1555
|
+
|
|
1556
|
+
// src/components/ui/badge.tsx
|
|
1557
|
+
init_utils();
|
|
1389
1558
|
var badgeVariants = classVarianceAuthority.cva(
|
|
1390
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!",
|
|
1391
1560
|
{
|
|
@@ -1643,6 +1812,9 @@ function WebToolBlock({ tc }) {
|
|
|
1643
1812
|
displayText && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/70 truncate text-xs", children: displayText })
|
|
1644
1813
|
] });
|
|
1645
1814
|
}
|
|
1815
|
+
|
|
1816
|
+
// src/components/ui/dialog.tsx
|
|
1817
|
+
init_utils();
|
|
1646
1818
|
function Dialog({
|
|
1647
1819
|
...props
|
|
1648
1820
|
}) {
|
|
@@ -1772,6 +1944,12 @@ function DialogDescription({
|
|
|
1772
1944
|
}
|
|
1773
1945
|
);
|
|
1774
1946
|
}
|
|
1947
|
+
|
|
1948
|
+
// src/components/chat/tools/file-tools.tsx
|
|
1949
|
+
init_utils();
|
|
1950
|
+
|
|
1951
|
+
// src/components/chat/diff-viewer.tsx
|
|
1952
|
+
init_utils();
|
|
1775
1953
|
function splitChangeLines(change) {
|
|
1776
1954
|
const v = change.value;
|
|
1777
1955
|
if (v === "") return [];
|
|
@@ -2250,6 +2428,9 @@ function ListFilesBlock({ tc }) {
|
|
|
2250
2428
|
] })
|
|
2251
2429
|
] });
|
|
2252
2430
|
}
|
|
2431
|
+
|
|
2432
|
+
// src/components/ai-elements/terminal.tsx
|
|
2433
|
+
init_utils();
|
|
2253
2434
|
var TerminalContext = react.createContext({
|
|
2254
2435
|
autoScroll: true,
|
|
2255
2436
|
isStreaming: false,
|
|
@@ -2444,7 +2625,10 @@ var Terminal = ({
|
|
|
2444
2625
|
}
|
|
2445
2626
|
) });
|
|
2446
2627
|
};
|
|
2447
|
-
|
|
2628
|
+
|
|
2629
|
+
// src/components/chat/tools/process-tool.tsx
|
|
2630
|
+
init_utils();
|
|
2631
|
+
function parseArgs2(args) {
|
|
2448
2632
|
try {
|
|
2449
2633
|
return JSON.parse(args);
|
|
2450
2634
|
} catch {
|
|
@@ -2668,7 +2852,7 @@ function OutputPreview({ output }) {
|
|
|
2668
2852
|
}
|
|
2669
2853
|
function ProcessToolBlock({ tc }) {
|
|
2670
2854
|
const isRunning = tc.status === "running";
|
|
2671
|
-
const args =
|
|
2855
|
+
const args = parseArgs2(tc.args);
|
|
2672
2856
|
const result = parseResult(tc.result);
|
|
2673
2857
|
const action = args.action || "unknown";
|
|
2674
2858
|
const actionLabel = {
|
|
@@ -2738,6 +2922,12 @@ function ProcessToolBlock({ tc }) {
|
|
|
2738
2922
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-background pb-1", children: content })
|
|
2739
2923
|
] });
|
|
2740
2924
|
}
|
|
2925
|
+
|
|
2926
|
+
// src/components/chat/tools/expert-tool.tsx
|
|
2927
|
+
init_utils();
|
|
2928
|
+
|
|
2929
|
+
// src/components/ui/textarea.tsx
|
|
2930
|
+
init_utils();
|
|
2741
2931
|
function Textarea({ className, ...props }) {
|
|
2742
2932
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2743
2933
|
"textarea",
|
|
@@ -2751,44 +2941,6 @@ function Textarea({ className, ...props }) {
|
|
|
2751
2941
|
}
|
|
2752
2942
|
);
|
|
2753
2943
|
}
|
|
2754
|
-
|
|
2755
|
-
// src/components/chat/tools/shared.ts
|
|
2756
|
-
function statusColorClass(status) {
|
|
2757
|
-
if (status === "running") return "bg-primary animate-pulse";
|
|
2758
|
-
if (status === "error") return "bg-red-500";
|
|
2759
|
-
if (status === "cancelled") return "bg-muted-foreground/40";
|
|
2760
|
-
return "bg-emerald-500";
|
|
2761
|
-
}
|
|
2762
|
-
function effectiveStatus(tc) {
|
|
2763
|
-
if (tc.cancelled) return "cancelled";
|
|
2764
|
-
if (tc.status !== "complete" || !tc.result) return tc.status;
|
|
2765
|
-
try {
|
|
2766
|
-
const parsed = JSON.parse(tc.result);
|
|
2767
|
-
if (parsed?.exit_code !== void 0 && parsed.exit_code !== 0) return "error";
|
|
2768
|
-
if (parsed?.error) return "error";
|
|
2769
|
-
if (parsed?.status === "blocked" || parsed?.status === "error") return "error";
|
|
2770
|
-
if (parsed?.success === false) return "error";
|
|
2771
|
-
} catch {
|
|
2772
|
-
}
|
|
2773
|
-
return "complete";
|
|
2774
|
-
}
|
|
2775
|
-
function formatArgs(args) {
|
|
2776
|
-
try {
|
|
2777
|
-
return JSON.stringify(JSON.parse(args), null, 2);
|
|
2778
|
-
} catch {
|
|
2779
|
-
return args;
|
|
2780
|
-
}
|
|
2781
|
-
}
|
|
2782
|
-
function parseArgs2(args) {
|
|
2783
|
-
try {
|
|
2784
|
-
return JSON.parse(args);
|
|
2785
|
-
} catch {
|
|
2786
|
-
return null;
|
|
2787
|
-
}
|
|
2788
|
-
}
|
|
2789
|
-
function truncate(s, max) {
|
|
2790
|
-
return s.length > max ? s.slice(0, max) + "\n... (truncated)" : s;
|
|
2791
|
-
}
|
|
2792
2944
|
var MAX_REASON_LENGTH = 500;
|
|
2793
2945
|
function ExpertToolBlock({ tc }) {
|
|
2794
2946
|
const [expanded, setExpanded] = react.useState(false);
|
|
@@ -2824,7 +2976,7 @@ function ExpertToolBlock({ tc }) {
|
|
|
2824
2976
|
}
|
|
2825
2977
|
void submit("up");
|
|
2826
2978
|
};
|
|
2827
|
-
const args =
|
|
2979
|
+
const args = parseArgs(tc.args) ?? {};
|
|
2828
2980
|
const expertName = args.expert ?? null;
|
|
2829
2981
|
const question = args.question ?? args.prompt ?? "";
|
|
2830
2982
|
const result = parseExpertResult(tc.result);
|
|
@@ -2936,7 +3088,7 @@ function ExpertToolBlock({ tc }) {
|
|
|
2936
3088
|
}
|
|
2937
3089
|
function parseExpertResult(result) {
|
|
2938
3090
|
if (!result) return null;
|
|
2939
|
-
const parsed =
|
|
3091
|
+
const parsed = parseArgs(result);
|
|
2940
3092
|
if (parsed) {
|
|
2941
3093
|
return {
|
|
2942
3094
|
...parsed,
|
|
@@ -3043,11 +3195,11 @@ function ReasonForm({
|
|
|
3043
3195
|
] });
|
|
3044
3196
|
}
|
|
3045
3197
|
function SkillsListBlock({ tc }) {
|
|
3046
|
-
const args =
|
|
3198
|
+
const args = parseArgs(tc.args) ?? {};
|
|
3047
3199
|
const filter = args.category ? `category: ${args.category}` : "all";
|
|
3048
3200
|
let summary = "";
|
|
3049
3201
|
if (tc.result) {
|
|
3050
|
-
const parsed =
|
|
3202
|
+
const parsed = parseArgs(tc.result);
|
|
3051
3203
|
if (parsed?.count !== void 0) {
|
|
3052
3204
|
summary = `${parsed.count} skill${parsed.count === 1 ? "" : "s"}`;
|
|
3053
3205
|
}
|
|
@@ -3062,11 +3214,11 @@ function SkillsListBlock({ tc }) {
|
|
|
3062
3214
|
] });
|
|
3063
3215
|
}
|
|
3064
3216
|
function SkillViewBlock({ tc }) {
|
|
3065
|
-
const args =
|
|
3217
|
+
const args = parseArgs(tc.args) ?? {};
|
|
3066
3218
|
const target = args.file_path ? `${args.name ?? "?"}/${args.file_path}` : args.name ?? "?";
|
|
3067
3219
|
let summary = "";
|
|
3068
3220
|
if (tc.result) {
|
|
3069
|
-
const parsed =
|
|
3221
|
+
const parsed = parseArgs(tc.result);
|
|
3070
3222
|
if (parsed?.staged_at) {
|
|
3071
3223
|
summary = `staged at ${parsed.staged_at}`;
|
|
3072
3224
|
} else if (parsed?.token_estimate) {
|
|
@@ -3082,6 +3234,12 @@ function SkillViewBlock({ tc }) {
|
|
|
3082
3234
|
] })
|
|
3083
3235
|
] });
|
|
3084
3236
|
}
|
|
3237
|
+
|
|
3238
|
+
// src/components/chat/tools/clarify-tool.tsx
|
|
3239
|
+
init_utils();
|
|
3240
|
+
|
|
3241
|
+
// src/components/ui/input.tsx
|
|
3242
|
+
init_utils();
|
|
3085
3243
|
function Input({ className, type, ...props }) {
|
|
3086
3244
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3087
3245
|
"input",
|
|
@@ -3113,7 +3271,7 @@ function buildAnswer(q, sel) {
|
|
|
3113
3271
|
}
|
|
3114
3272
|
function ClarifyToolBlock({ tc }) {
|
|
3115
3273
|
const { adapter, sessionId } = useAgentChatAdapterContext();
|
|
3116
|
-
const args = react.useMemo(() =>
|
|
3274
|
+
const args = react.useMemo(() => parseArgs(tc.args), [tc.args]);
|
|
3117
3275
|
const questions = args?.questions ?? [];
|
|
3118
3276
|
const [active, setActive] = react.useState(0);
|
|
3119
3277
|
const [selections, setSelections] = react.useState(
|
|
@@ -3395,7 +3553,7 @@ function ClarifyLocked({
|
|
|
3395
3553
|
] });
|
|
3396
3554
|
}
|
|
3397
3555
|
function ArtifactToolBlock({ tc }) {
|
|
3398
|
-
const args =
|
|
3556
|
+
const args = parseArgs(tc.args) ?? {};
|
|
3399
3557
|
const status = effectiveStatus(tc);
|
|
3400
3558
|
const label = status === "running" ? "Creating artifact\u2026" : status === "error" ? "Tried to create" : "Created";
|
|
3401
3559
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-sm ", children: [
|
|
@@ -3403,13 +3561,16 @@ function ArtifactToolBlock({ tc }) {
|
|
|
3403
3561
|
args.name && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground truncate", children: args.name })
|
|
3404
3562
|
] });
|
|
3405
3563
|
}
|
|
3564
|
+
|
|
3565
|
+
// src/components/chat/tools/delegate-tool.tsx
|
|
3566
|
+
init_utils();
|
|
3406
3567
|
function firstLine(s) {
|
|
3407
3568
|
const idx = s.indexOf("\n");
|
|
3408
3569
|
return idx === -1 ? s : s.slice(0, idx);
|
|
3409
3570
|
}
|
|
3410
3571
|
function DelegateToolBlock({ tc }) {
|
|
3411
3572
|
const [expanded, setExpanded] = react.useState(false);
|
|
3412
|
-
const args =
|
|
3573
|
+
const args = parseArgs(tc.args);
|
|
3413
3574
|
const goal = args?.goal ?? "";
|
|
3414
3575
|
const context = args?.context ?? "";
|
|
3415
3576
|
const agentType = args?.agent_type;
|
|
@@ -3503,6 +3664,7 @@ function DelegateToolBlock({ tc }) {
|
|
|
3503
3664
|
] })
|
|
3504
3665
|
] });
|
|
3505
3666
|
}
|
|
3667
|
+
init_utils();
|
|
3506
3668
|
var ACTION_VERB = {
|
|
3507
3669
|
add: "Saved",
|
|
3508
3670
|
replace: "Updated",
|
|
@@ -3519,8 +3681,8 @@ var TARGET_LABEL = {
|
|
|
3519
3681
|
};
|
|
3520
3682
|
function MemoryToolBlock({ tc }) {
|
|
3521
3683
|
const [isOpen, setIsOpen] = react.useState(false);
|
|
3522
|
-
const args =
|
|
3523
|
-
const result = tc.result ?
|
|
3684
|
+
const args = parseArgs(tc.args) ?? {};
|
|
3685
|
+
const result = tc.result ? parseArgs(tc.result) : null;
|
|
3524
3686
|
const action = args.action ?? "add";
|
|
3525
3687
|
const target = args.target ?? "memory";
|
|
3526
3688
|
const verb = ACTION_VERB[action] ?? action;
|
|
@@ -3598,8 +3760,8 @@ var ACTION_LABEL = {
|
|
|
3598
3760
|
remove_file: "Remove skill file"
|
|
3599
3761
|
};
|
|
3600
3762
|
function SkillManageToolBlock({ tc }) {
|
|
3601
|
-
const args =
|
|
3602
|
-
const result = tc.result ?
|
|
3763
|
+
const args = parseArgs(tc.args) ?? {};
|
|
3764
|
+
const result = tc.result ? parseArgs(tc.result) : null;
|
|
3603
3765
|
const action = args.action ?? "manage";
|
|
3604
3766
|
const label = ACTION_LABEL[action] ?? "Manage skill";
|
|
3605
3767
|
const target = args.file_path ? `${args.name ?? "?"}/${args.file_path}` : args.name ?? "?";
|
|
@@ -3620,8 +3782,8 @@ function firstLine2(value) {
|
|
|
3620
3782
|
return (index === -1 ? value : value.slice(0, index)).trim();
|
|
3621
3783
|
}
|
|
3622
3784
|
function CoordinatorToolBlock({ tc }) {
|
|
3623
|
-
const args =
|
|
3624
|
-
const result = tc.result ?
|
|
3785
|
+
const args = parseArgs(tc.args) ?? {};
|
|
3786
|
+
const result = tc.result ? parseArgs(tc.result) : null;
|
|
3625
3787
|
const failed = Boolean(result?.error);
|
|
3626
3788
|
let label = "Worker";
|
|
3627
3789
|
let target = "";
|
|
@@ -3654,6 +3816,9 @@ function CoordinatorToolBlock({ tc }) {
|
|
|
3654
3816
|
] })
|
|
3655
3817
|
] });
|
|
3656
3818
|
}
|
|
3819
|
+
|
|
3820
|
+
// src/components/chat/tools/default-tool.tsx
|
|
3821
|
+
init_utils();
|
|
3657
3822
|
var TOOL_LABELS = {
|
|
3658
3823
|
kb_list_pages: "Knowledge Base",
|
|
3659
3824
|
kb_read_page: "Read KB Page",
|
|
@@ -3808,6 +3973,9 @@ function AssistantMessage({
|
|
|
3808
3973
|
] })
|
|
3809
3974
|
] }) });
|
|
3810
3975
|
}
|
|
3976
|
+
|
|
3977
|
+
// src/components/ui/hover-card.tsx
|
|
3978
|
+
init_utils();
|
|
3811
3979
|
function HoverCard({
|
|
3812
3980
|
...props
|
|
3813
3981
|
}) {
|
|
@@ -3838,6 +4006,9 @@ function HoverCardContent({
|
|
|
3838
4006
|
}
|
|
3839
4007
|
) });
|
|
3840
4008
|
}
|
|
4009
|
+
|
|
4010
|
+
// src/components/ui/progress.tsx
|
|
4011
|
+
init_utils();
|
|
3841
4012
|
function Progress({
|
|
3842
4013
|
className,
|
|
3843
4014
|
value,
|
|
@@ -3863,6 +4034,9 @@ function Progress({
|
|
|
3863
4034
|
}
|
|
3864
4035
|
);
|
|
3865
4036
|
}
|
|
4037
|
+
|
|
4038
|
+
// src/components/ai-elements/context.tsx
|
|
4039
|
+
init_utils();
|
|
3866
4040
|
var PERCENT_MAX = 100;
|
|
3867
4041
|
var ICON_RADIUS = 10;
|
|
3868
4042
|
var ICON_VIEWBOX = 24;
|
|
@@ -4127,6 +4301,12 @@ var ContextCacheUsage = ({
|
|
|
4127
4301
|
}
|
|
4128
4302
|
);
|
|
4129
4303
|
};
|
|
4304
|
+
|
|
4305
|
+
// src/components/ui/command.tsx
|
|
4306
|
+
init_utils();
|
|
4307
|
+
|
|
4308
|
+
// src/components/ui/input-group.tsx
|
|
4309
|
+
init_utils();
|
|
4130
4310
|
function InputGroup({ className, ...props }) {
|
|
4131
4311
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4132
4312
|
"div",
|
|
@@ -4311,6 +4491,9 @@ function CommandItem({
|
|
|
4311
4491
|
}
|
|
4312
4492
|
);
|
|
4313
4493
|
}
|
|
4494
|
+
|
|
4495
|
+
// src/components/ui/dropdown-menu.tsx
|
|
4496
|
+
init_utils();
|
|
4314
4497
|
function DropdownMenu({
|
|
4315
4498
|
...props
|
|
4316
4499
|
}) {
|
|
@@ -4364,9 +4547,15 @@ function DropdownMenuItem({
|
|
|
4364
4547
|
}
|
|
4365
4548
|
);
|
|
4366
4549
|
}
|
|
4550
|
+
|
|
4551
|
+
// src/components/ui/spinner.tsx
|
|
4552
|
+
init_utils();
|
|
4367
4553
|
function Spinner({ className, ...props }) {
|
|
4368
4554
|
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2Icon, { role: "status", "aria-label": "Loading", className: cn("size-4 animate-spin", className), ...props });
|
|
4369
4555
|
}
|
|
4556
|
+
|
|
4557
|
+
// src/components/ai-elements/prompt-input.tsx
|
|
4558
|
+
init_utils();
|
|
4370
4559
|
var convertBlobUrlToDataUrl = async (url) => {
|
|
4371
4560
|
try {
|
|
4372
4561
|
const response = await fetch(url);
|
|
@@ -5064,6 +5253,9 @@ var PromptInputSubmit = ({
|
|
|
5064
5253
|
}
|
|
5065
5254
|
);
|
|
5066
5255
|
};
|
|
5256
|
+
|
|
5257
|
+
// src/components/ui/popover.tsx
|
|
5258
|
+
init_utils();
|
|
5067
5259
|
function Popover({
|
|
5068
5260
|
...props
|
|
5069
5261
|
}) {
|
|
@@ -5311,6 +5503,9 @@ function ChatComposerInner({
|
|
|
5311
5503
|
)
|
|
5312
5504
|
] });
|
|
5313
5505
|
}
|
|
5506
|
+
|
|
5507
|
+
// src/components/ai-elements/artifact.tsx
|
|
5508
|
+
init_utils();
|
|
5314
5509
|
var Artifact = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
5315
5510
|
"div",
|
|
5316
5511
|
{
|
|
@@ -5431,6 +5626,9 @@ function ArtifactTable({ spec }) {
|
|
|
5431
5626
|
)) })
|
|
5432
5627
|
] }) });
|
|
5433
5628
|
}
|
|
5629
|
+
|
|
5630
|
+
// src/components/chat/artifacts/artifact-html.tsx
|
|
5631
|
+
init_utils();
|
|
5434
5632
|
var DEFAULT_HEIGHT_PX = 480;
|
|
5435
5633
|
var EXPANDED_HEIGHT_PX = 800;
|
|
5436
5634
|
var MIN_ZOOM = 0.5;
|
|
@@ -5572,7 +5770,7 @@ function exportArtifact(payload) {
|
|
|
5572
5770
|
};
|
|
5573
5771
|
case "chart":
|
|
5574
5772
|
return {
|
|
5575
|
-
text: JSON.stringify(payload.spec.
|
|
5773
|
+
text: JSON.stringify(payload.spec.chart_js, null, 2),
|
|
5576
5774
|
mime: "application/json",
|
|
5577
5775
|
extension: "json"
|
|
5578
5776
|
};
|
|
@@ -5758,7 +5956,7 @@ function ArtifactBody({
|
|
|
5758
5956
|
react.Suspense,
|
|
5759
5957
|
{
|
|
5760
5958
|
fallback: /* @__PURE__ */ jsxRuntime.jsx(Shimmer, { duration: 5, className: "text-sm text-muted-foreground", children: "Loading chart\u2026" }),
|
|
5761
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(ArtifactChart2, { spec: payload.spec })
|
|
5959
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ArtifactChart2, { spec: payload.spec, fill })
|
|
5762
5960
|
}
|
|
5763
5961
|
);
|
|
5764
5962
|
case "html":
|
|
@@ -5767,6 +5965,7 @@ function ArtifactBody({
|
|
|
5767
5965
|
return /* @__PURE__ */ jsxRuntime.jsx(ArtifactSvg, { spec: payload.spec });
|
|
5768
5966
|
}
|
|
5769
5967
|
}
|
|
5968
|
+
init_utils();
|
|
5770
5969
|
var ErrorMessage = react.memo(function ErrorMessage2({
|
|
5771
5970
|
errorInfo,
|
|
5772
5971
|
onRetry,
|
|
@@ -5847,6 +6046,9 @@ var ErrorMessage = react.memo(function ErrorMessage2({
|
|
|
5847
6046
|
}
|
|
5848
6047
|
);
|
|
5849
6048
|
});
|
|
6049
|
+
|
|
6050
|
+
// src/components/chat/chat-thread.tsx
|
|
6051
|
+
init_utils();
|
|
5850
6052
|
function messageToEntries(msg, isLast) {
|
|
5851
6053
|
if (msg.role === "system") {
|
|
5852
6054
|
if (msg.systemKind === "skill_invoked") {
|
|
@@ -5978,7 +6180,7 @@ function OrphanSystemMarker({
|
|
|
5978
6180
|
);
|
|
5979
6181
|
}
|
|
5980
6182
|
if (message.systemKind === "error" && message.errorInfo) {
|
|
5981
|
-
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 }) });
|
|
5982
6184
|
}
|
|
5983
6185
|
return null;
|
|
5984
6186
|
}
|
|
@@ -6032,6 +6234,7 @@ function TimelineEntryItem({
|
|
|
6032
6234
|
] });
|
|
6033
6235
|
}
|
|
6034
6236
|
if (entry.kind === "tool") {
|
|
6237
|
+
const failureSummary = effectiveStatus(entry.tc) === "error" ? toolErrorSummary(entry.tc.result) : "";
|
|
6035
6238
|
return /* @__PURE__ */ jsxRuntime.jsxs(TimelineItem, { step, children: [
|
|
6036
6239
|
/* @__PURE__ */ jsxRuntime.jsxs(TimelineHeader, { children: [
|
|
6037
6240
|
/* @__PURE__ */ jsxRuntime.jsx(TimelineSeparator, { style: { backgroundColor: "var(--color-border)" } }),
|
|
@@ -6042,7 +6245,10 @@ function TimelineEntryItem({
|
|
|
6042
6245
|
}
|
|
6043
6246
|
)
|
|
6044
6247
|
] }),
|
|
6045
|
-
/* @__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
|
+
] }) })
|
|
6046
6252
|
] });
|
|
6047
6253
|
}
|
|
6048
6254
|
if (entry.kind === "text") {
|
|
@@ -6160,6 +6366,7 @@ function ChatThread({
|
|
|
6160
6366
|
sessionId,
|
|
6161
6367
|
messages,
|
|
6162
6368
|
isRunning,
|
|
6369
|
+
isLoadingHistory = false,
|
|
6163
6370
|
onSend,
|
|
6164
6371
|
onStop,
|
|
6165
6372
|
onFileSelect,
|
|
@@ -6182,7 +6389,14 @@ function ChatThread({
|
|
|
6182
6389
|
}, [messages]);
|
|
6183
6390
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 flex-col overflow-hidden bg-background text-sm", children: [
|
|
6184
6391
|
/* @__PURE__ */ jsxRuntime.jsxs(Conversation, { className: "relative flex-1 min-h-0", children: [
|
|
6185
|
-
/* @__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(
|
|
6186
6400
|
ConversationEmptyState,
|
|
6187
6401
|
{
|
|
6188
6402
|
icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquareIcon, { className: "size-8 opacity-40" }),
|
|
@@ -6235,7 +6449,7 @@ function ChatThread({
|
|
|
6235
6449
|
] }) }),
|
|
6236
6450
|
/* @__PURE__ */ jsxRuntime.jsx(ConversationScrollButton, {})
|
|
6237
6451
|
] }),
|
|
6238
|
-
/* @__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: [
|
|
6239
6453
|
retryIndicator && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxRuntime.jsx(RetryBanner, { indicator: retryIndicator }) }),
|
|
6240
6454
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6241
6455
|
ChatComposer,
|
|
@@ -6250,6 +6464,9 @@ function ChatThread({
|
|
|
6250
6464
|
] })
|
|
6251
6465
|
] });
|
|
6252
6466
|
}
|
|
6467
|
+
|
|
6468
|
+
// src/components/ai-elements/file-tree.tsx
|
|
6469
|
+
init_utils();
|
|
6253
6470
|
var noop = () => {
|
|
6254
6471
|
};
|
|
6255
6472
|
var FileTreeContext = react.createContext({
|
|
@@ -6416,6 +6633,9 @@ function FileTreeFile({
|
|
|
6416
6633
|
}
|
|
6417
6634
|
);
|
|
6418
6635
|
}
|
|
6636
|
+
|
|
6637
|
+
// src/components/ui/skeleton.tsx
|
|
6638
|
+
init_utils();
|
|
6419
6639
|
function Skeleton({ className, ...props }) {
|
|
6420
6640
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6421
6641
|
"div",
|
|
@@ -6426,6 +6646,9 @@ function Skeleton({ className, ...props }) {
|
|
|
6426
6646
|
);
|
|
6427
6647
|
}
|
|
6428
6648
|
|
|
6649
|
+
// src/components/workspace/workspace-panel.tsx
|
|
6650
|
+
init_utils();
|
|
6651
|
+
|
|
6429
6652
|
// src/lib/format.ts
|
|
6430
6653
|
function formatFileSize(bytes) {
|
|
6431
6654
|
if (bytes < 1024) return `${bytes} B`;
|
|
@@ -6465,17 +6688,24 @@ function getLanguageHint(path) {
|
|
|
6465
6688
|
return map[ext] ?? "plaintext";
|
|
6466
6689
|
}
|
|
6467
6690
|
var SKELETON_WIDTHS = [70, 85, 55, 90, 60, 78, 45, 82, 65, 72];
|
|
6691
|
+
var PDF_WORKER_SRC = new URL(
|
|
6692
|
+
"pdfjs-dist/legacy/build/pdf.worker.mjs",
|
|
6693
|
+
(typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))
|
|
6694
|
+
).toString();
|
|
6468
6695
|
function FileViewer({
|
|
6469
6696
|
file,
|
|
6470
6697
|
loading,
|
|
6471
6698
|
error,
|
|
6699
|
+
downloadUrl,
|
|
6700
|
+
onDelete,
|
|
6472
6701
|
onClose
|
|
6473
6702
|
}) {
|
|
6474
6703
|
const visible = loading || file !== null || error !== null;
|
|
6475
6704
|
if (!visible) return null;
|
|
6476
6705
|
const fileName2 = file?.path.split("/").pop() ?? "File";
|
|
6477
6706
|
const lang = file ? getLanguageHint(file.path) : "";
|
|
6478
|
-
const
|
|
6707
|
+
const isPdf = file?.mime_type === "application/pdf" || file?.path.toLowerCase().endsWith(".pdf") || false;
|
|
6708
|
+
const isImage = file?.encoding === "base64" && !isPdf;
|
|
6479
6709
|
const HeaderIcon = isImage ? lucideReact.ImageIcon : lucideReact.FileTextIcon;
|
|
6480
6710
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1 flex-col border-t border-line", children: [
|
|
6481
6711
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 items-center gap-2 border-b border-line px-3 py-2", children: [
|
|
@@ -6490,6 +6720,28 @@ function FileViewer({
|
|
|
6490
6720
|
] })
|
|
6491
6721
|
] })
|
|
6492
6722
|
] }),
|
|
6723
|
+
downloadUrl && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6724
|
+
"a",
|
|
6725
|
+
{
|
|
6726
|
+
href: downloadUrl,
|
|
6727
|
+
download: fileName2,
|
|
6728
|
+
className: "shrink-0 rounded p-0.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
6729
|
+
"aria-label": `Download ${fileName2}`,
|
|
6730
|
+
title: "Download",
|
|
6731
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.DownloadIcon, { className: "size-3.5" })
|
|
6732
|
+
}
|
|
6733
|
+
),
|
|
6734
|
+
onDelete && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6735
|
+
"button",
|
|
6736
|
+
{
|
|
6737
|
+
type: "button",
|
|
6738
|
+
onClick: onDelete,
|
|
6739
|
+
className: "shrink-0 rounded p-0.5 text-muted-foreground transition-colors hover:bg-destructive/10 hover:text-destructive",
|
|
6740
|
+
"aria-label": `Delete ${fileName2}`,
|
|
6741
|
+
title: "Delete",
|
|
6742
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.TrashIcon, { className: "size-3.5" })
|
|
6743
|
+
}
|
|
6744
|
+
),
|
|
6493
6745
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6494
6746
|
"button",
|
|
6495
6747
|
{
|
|
@@ -6516,6 +6768,8 @@ function FileViewer({
|
|
|
6516
6768
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircleIcon, { className: "mt-0.5 size-3.5 shrink-0" }),
|
|
6517
6769
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: error })
|
|
6518
6770
|
] }),
|
|
6771
|
+
file && isPdf && file.encoding !== "base64" && /* @__PURE__ */ jsxRuntime.jsx(FileViewerError, { message: "PDF preview requires base64 file content." }),
|
|
6772
|
+
file && isPdf && file.encoding === "base64" && /* @__PURE__ */ jsxRuntime.jsx(PdfPreview, { file, fileName: fileName2 }),
|
|
6519
6773
|
file && isImage && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center p-4", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6520
6774
|
"img",
|
|
6521
6775
|
{
|
|
@@ -6524,66 +6778,290 @@ function FileViewer({
|
|
|
6524
6778
|
className: "max-h-[60vh] max-w-full rounded object-contain"
|
|
6525
6779
|
}
|
|
6526
6780
|
) }),
|
|
6527
|
-
file && !isImage && /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "wrap-break-word whitespace-pre-wrap p-3 text-[11px] leading-relaxed text-foreground", children: /* @__PURE__ */ jsxRuntime.jsx("code", { "data-language": lang, children: file.content }) })
|
|
6781
|
+
file && !isImage && !isPdf && /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "wrap-break-word whitespace-pre-wrap p-3 text-[11px] leading-relaxed text-foreground", children: /* @__PURE__ */ jsxRuntime.jsx("code", { "data-language": lang, children: file.content }) })
|
|
6528
6782
|
] })
|
|
6529
6783
|
] });
|
|
6530
6784
|
}
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
|
|
6560
|
-
|
|
6561
|
-
|
|
6562
|
-
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
|
|
6566
|
-
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
|
|
6570
|
-
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
|
|
6574
|
-
|
|
6575
|
-
|
|
6576
|
-
|
|
6577
|
-
|
|
6785
|
+
function FileViewerError({ message }) {
|
|
6786
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2 p-3 text-xs text-destructive", children: [
|
|
6787
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircleIcon, { className: "mt-0.5 size-3.5 shrink-0" }),
|
|
6788
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: message })
|
|
6789
|
+
] });
|
|
6790
|
+
}
|
|
6791
|
+
function PdfPreview({
|
|
6792
|
+
file,
|
|
6793
|
+
fileName: fileName2
|
|
6794
|
+
}) {
|
|
6795
|
+
const containerRef = react.useRef(null);
|
|
6796
|
+
const viewerRef = react.useRef(null);
|
|
6797
|
+
const pdfViewerRef = react.useRef(null);
|
|
6798
|
+
const eventBusRef = react.useRef(null);
|
|
6799
|
+
const findControllerRef = react.useRef(null);
|
|
6800
|
+
const [error, setError] = react.useState(null);
|
|
6801
|
+
const [pageNumber, setPageNumber] = react.useState(1);
|
|
6802
|
+
const [pagesCount, setPagesCount] = react.useState(0);
|
|
6803
|
+
const [scale, setScale] = react.useState(1);
|
|
6804
|
+
const [query, setQuery] = react.useState("");
|
|
6805
|
+
react.useEffect(() => {
|
|
6806
|
+
let cancelled = false;
|
|
6807
|
+
let loadingTask = null;
|
|
6808
|
+
let pdfDocument = null;
|
|
6809
|
+
const renderPdf = async () => {
|
|
6810
|
+
setError(null);
|
|
6811
|
+
const container = containerRef.current;
|
|
6812
|
+
const viewerElement = viewerRef.current;
|
|
6813
|
+
if (!container || !viewerElement) return;
|
|
6814
|
+
const pdfBytes = decodeBase64(file.content);
|
|
6815
|
+
const pdfjs = await import('pdfjs-dist/legacy/build/pdf.mjs');
|
|
6816
|
+
pdfjs.GlobalWorkerOptions.workerSrc = PDF_WORKER_SRC;
|
|
6817
|
+
globalThis.pdfjsLib = pdfjs;
|
|
6818
|
+
const pdfViewerModule = await import('pdfjs-dist/web/pdf_viewer.mjs');
|
|
6819
|
+
loadingTask = pdfjs.getDocument({ data: pdfBytes });
|
|
6820
|
+
const pdf = await loadingTask.promise;
|
|
6821
|
+
pdfDocument = pdf;
|
|
6822
|
+
if (cancelled) return;
|
|
6823
|
+
const eventBus = new pdfViewerModule.EventBus();
|
|
6824
|
+
const linkService = new pdfViewerModule.PDFLinkService({ eventBus });
|
|
6825
|
+
const findController = new pdfViewerModule.PDFFindController({
|
|
6826
|
+
eventBus,
|
|
6827
|
+
linkService
|
|
6828
|
+
});
|
|
6829
|
+
const pdfViewer = new pdfViewerModule.PDFViewer({
|
|
6830
|
+
container,
|
|
6831
|
+
viewer: viewerElement,
|
|
6832
|
+
eventBus,
|
|
6833
|
+
linkService,
|
|
6834
|
+
findController,
|
|
6835
|
+
removePageBorders: true
|
|
6836
|
+
});
|
|
6837
|
+
linkService.setViewer(pdfViewer);
|
|
6838
|
+
linkService.setDocument(pdf);
|
|
6839
|
+
findController.setDocument(pdf);
|
|
6840
|
+
const onPagesInit = () => {
|
|
6841
|
+
pdfViewer.currentScaleValue = "page-width";
|
|
6842
|
+
setScale(pdfViewer.currentScale || 1);
|
|
6843
|
+
setPagesCount(pdfViewer.pagesCount);
|
|
6844
|
+
setPageNumber(pdfViewer.currentPageNumber);
|
|
6845
|
+
};
|
|
6846
|
+
const onPageChanging = (event) => {
|
|
6847
|
+
if (typeof event.pageNumber === "number") {
|
|
6848
|
+
setPageNumber(event.pageNumber);
|
|
6849
|
+
}
|
|
6850
|
+
};
|
|
6851
|
+
const onScaleChanging = (event) => {
|
|
6852
|
+
if (typeof event.scale === "number") {
|
|
6853
|
+
setScale(event.scale);
|
|
6854
|
+
}
|
|
6855
|
+
};
|
|
6856
|
+
eventBus.on("pagesinit", onPagesInit);
|
|
6857
|
+
eventBus.on("pagechanging", onPageChanging);
|
|
6858
|
+
eventBus.on("scalechanging", onScaleChanging);
|
|
6859
|
+
pdfViewerRef.current = pdfViewer;
|
|
6860
|
+
eventBusRef.current = eventBus;
|
|
6861
|
+
findControllerRef.current = findController;
|
|
6862
|
+
setPagesCount(pdf.numPages);
|
|
6863
|
+
pdfViewer.setDocument(pdf);
|
|
6864
|
+
};
|
|
6865
|
+
void renderPdf().catch((nextError) => {
|
|
6866
|
+
if (cancelled) return;
|
|
6867
|
+
if (nextError instanceof Error && nextError.name === "RenderingCancelledException") {
|
|
6868
|
+
return;
|
|
6869
|
+
}
|
|
6870
|
+
setError(formatPdfPreviewError(nextError));
|
|
6871
|
+
});
|
|
6872
|
+
return () => {
|
|
6873
|
+
cancelled = true;
|
|
6874
|
+
loadingTask?.destroy();
|
|
6875
|
+
pdfDocument?.destroy();
|
|
6876
|
+
pdfViewerRef.current?.cleanup();
|
|
6877
|
+
pdfViewerRef.current = null;
|
|
6878
|
+
eventBusRef.current = null;
|
|
6879
|
+
findControllerRef.current = null;
|
|
6880
|
+
};
|
|
6881
|
+
}, [file.content]);
|
|
6882
|
+
const setViewerPage = (nextPage) => {
|
|
6883
|
+
const viewer = pdfViewerRef.current;
|
|
6884
|
+
if (!viewer) return;
|
|
6885
|
+
const clampedPage = Math.min(
|
|
6886
|
+
Math.max(1, nextPage),
|
|
6887
|
+
Math.max(1, viewer.pagesCount)
|
|
6888
|
+
);
|
|
6889
|
+
viewer.currentPageNumber = clampedPage;
|
|
6890
|
+
setPageNumber(clampedPage);
|
|
6891
|
+
};
|
|
6892
|
+
const setViewerScale = (nextScale) => {
|
|
6893
|
+
const viewer = pdfViewerRef.current;
|
|
6894
|
+
if (!viewer) return;
|
|
6895
|
+
const clampedScale = Math.min(3, Math.max(0.5, nextScale));
|
|
6896
|
+
viewer.currentScale = clampedScale;
|
|
6897
|
+
setScale(clampedScale);
|
|
6898
|
+
};
|
|
6899
|
+
const runFind = (findPrevious = false) => {
|
|
6900
|
+
const eventBus = eventBusRef.current;
|
|
6901
|
+
if (!eventBus || !query.trim()) return;
|
|
6902
|
+
eventBus.dispatch("find", {
|
|
6903
|
+
source: eventBus,
|
|
6904
|
+
type: "again",
|
|
6905
|
+
query,
|
|
6906
|
+
phraseSearch: true,
|
|
6907
|
+
caseSensitive: false,
|
|
6908
|
+
entireWord: false,
|
|
6909
|
+
highlightAll: true,
|
|
6910
|
+
findPrevious,
|
|
6911
|
+
matchDiacritics: true
|
|
6912
|
+
});
|
|
6913
|
+
};
|
|
6914
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-full flex-col", children: [
|
|
6915
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex shrink-0 flex-wrap items-center gap-1.5 border-b border-line px-2 py-1.5", children: [
|
|
6916
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6917
|
+
Button,
|
|
6918
|
+
{
|
|
6919
|
+
type: "button",
|
|
6920
|
+
variant: "ghost",
|
|
6921
|
+
size: "icon-xs",
|
|
6922
|
+
onClick: () => setViewerPage(pageNumber - 1),
|
|
6923
|
+
disabled: pageNumber <= 1,
|
|
6924
|
+
"aria-label": "Previous PDF page",
|
|
6925
|
+
title: "Previous page",
|
|
6926
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeftIcon, { className: "size-3.5" })
|
|
6927
|
+
}
|
|
6928
|
+
),
|
|
6929
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6930
|
+
Input,
|
|
6931
|
+
{
|
|
6932
|
+
type: "number",
|
|
6933
|
+
min: 1,
|
|
6934
|
+
max: pagesCount || 1,
|
|
6935
|
+
value: pageNumber,
|
|
6936
|
+
onChange: (event) => setViewerPage(Number(event.target.value)),
|
|
6937
|
+
"aria-label": "PDF page number",
|
|
6938
|
+
className: "h-7 w-12 border-input px-1 text-center text-xs"
|
|
6939
|
+
}
|
|
6940
|
+
),
|
|
6941
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
|
|
6942
|
+
"/ ",
|
|
6943
|
+
pagesCount || "-"
|
|
6944
|
+
] }),
|
|
6945
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6946
|
+
Button,
|
|
6947
|
+
{
|
|
6948
|
+
type: "button",
|
|
6949
|
+
variant: "ghost",
|
|
6950
|
+
size: "icon-xs",
|
|
6951
|
+
onClick: () => setViewerPage(pageNumber + 1),
|
|
6952
|
+
disabled: pagesCount > 0 && pageNumber >= pagesCount,
|
|
6953
|
+
"aria-label": "Next PDF page",
|
|
6954
|
+
title: "Next page",
|
|
6955
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, { className: "size-3.5" })
|
|
6956
|
+
}
|
|
6957
|
+
),
|
|
6958
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-1 h-5 w-px bg-line" }),
|
|
6959
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6960
|
+
Button,
|
|
6961
|
+
{
|
|
6962
|
+
type: "button",
|
|
6963
|
+
variant: "ghost",
|
|
6964
|
+
size: "icon-xs",
|
|
6965
|
+
onClick: () => setViewerScale(scale - 0.1),
|
|
6966
|
+
disabled: scale <= 0.5,
|
|
6967
|
+
"aria-label": "Zoom out PDF",
|
|
6968
|
+
title: "Zoom out",
|
|
6969
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MinusIcon, { className: "size-3.5" })
|
|
6970
|
+
}
|
|
6971
|
+
),
|
|
6972
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
6973
|
+
"button",
|
|
6974
|
+
{
|
|
6975
|
+
type: "button",
|
|
6976
|
+
className: "h-7 min-w-12 px-1 text-xs text-muted-foreground hover:text-foreground",
|
|
6977
|
+
onClick: () => {
|
|
6978
|
+
const viewer = pdfViewerRef.current;
|
|
6979
|
+
if (!viewer) return;
|
|
6980
|
+
viewer.currentScaleValue = "page-width";
|
|
6981
|
+
setScale(viewer.currentScale || 1);
|
|
6982
|
+
},
|
|
6983
|
+
"aria-label": "Fit PDF to width",
|
|
6984
|
+
title: "Fit width",
|
|
6985
|
+
children: [
|
|
6986
|
+
Math.round(scale * 100),
|
|
6987
|
+
"%"
|
|
6988
|
+
]
|
|
6989
|
+
}
|
|
6990
|
+
),
|
|
6991
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6992
|
+
Button,
|
|
6993
|
+
{
|
|
6994
|
+
type: "button",
|
|
6995
|
+
variant: "ghost",
|
|
6996
|
+
size: "icon-xs",
|
|
6997
|
+
onClick: () => setViewerScale(scale + 0.1),
|
|
6998
|
+
disabled: scale >= 3,
|
|
6999
|
+
"aria-label": "Zoom in PDF",
|
|
7000
|
+
title: "Zoom in",
|
|
7001
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PlusIcon, { className: "size-3.5" })
|
|
7002
|
+
}
|
|
7003
|
+
),
|
|
7004
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-1 h-5 w-px bg-line" }),
|
|
7005
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.SearchIcon, { className: "size-3.5 text-muted-foreground" }),
|
|
7006
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7007
|
+
Input,
|
|
7008
|
+
{
|
|
7009
|
+
type: "search",
|
|
7010
|
+
value: query,
|
|
7011
|
+
onChange: (event) => setQuery(event.target.value),
|
|
7012
|
+
onKeyDown: (event) => {
|
|
7013
|
+
if (event.key === "Enter") runFind(event.shiftKey);
|
|
7014
|
+
},
|
|
7015
|
+
placeholder: "Find",
|
|
7016
|
+
"aria-label": "Find in PDF",
|
|
7017
|
+
className: "h-7 w-28 border-input px-1 text-xs"
|
|
7018
|
+
}
|
|
7019
|
+
),
|
|
7020
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7021
|
+
Button,
|
|
7022
|
+
{
|
|
7023
|
+
type: "button",
|
|
7024
|
+
variant: "ghost",
|
|
7025
|
+
size: "xs",
|
|
7026
|
+
onClick: () => runFind(false),
|
|
7027
|
+
disabled: !query.trim(),
|
|
7028
|
+
children: "Find"
|
|
7029
|
+
}
|
|
7030
|
+
)
|
|
7031
|
+
] }),
|
|
7032
|
+
error && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full items-start gap-2 p-3 text-xs text-destructive", children: [
|
|
7033
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircleIcon, { className: "mt-0.5 size-3.5 shrink-0" }),
|
|
7034
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: error })
|
|
7035
|
+
] }),
|
|
7036
|
+
!error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative h-[70vh] min-h-[420px] flex-1 bg-muted/20", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7037
|
+
"div",
|
|
7038
|
+
{
|
|
7039
|
+
ref: containerRef,
|
|
7040
|
+
"aria-label": `PDF viewer for ${fileName2}`,
|
|
7041
|
+
className: "absolute inset-0 overflow-auto",
|
|
7042
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: viewerRef, className: "pdfViewer" })
|
|
7043
|
+
}
|
|
7044
|
+
) })
|
|
7045
|
+
] });
|
|
7046
|
+
}
|
|
7047
|
+
function decodeBase64(content) {
|
|
7048
|
+
const binary = globalThis.atob(content);
|
|
7049
|
+
const bytes = new Uint8Array(binary.length);
|
|
7050
|
+
for (let index = 0; index < binary.length; index += 1) {
|
|
7051
|
+
bytes[index] = binary.charCodeAt(index);
|
|
7052
|
+
}
|
|
7053
|
+
return bytes;
|
|
7054
|
+
}
|
|
7055
|
+
function formatPdfPreviewError(error) {
|
|
7056
|
+
if (error instanceof Error && (error.name === "InvalidCharacterError" || error.message === "Invalid character")) {
|
|
7057
|
+
return "PDF preview data is not valid base64.";
|
|
7058
|
+
}
|
|
7059
|
+
return error instanceof Error ? error.message : "Failed to render PDF preview.";
|
|
7060
|
+
}
|
|
6578
7061
|
var SKELETON_WIDTHS2 = [75, 60, 90, 65, 80, 70, 85, 55];
|
|
6579
|
-
var DEFAULT_WIDTH =
|
|
7062
|
+
var DEFAULT_WIDTH = 400;
|
|
6580
7063
|
var MIN_WIDTH = 300;
|
|
6581
7064
|
var MAX_WIDTH = 900;
|
|
6582
|
-
function isViewable(name) {
|
|
6583
|
-
const dot = name.lastIndexOf(".");
|
|
6584
|
-
const ext = dot >= 0 ? name.slice(dot).toLowerCase() : "";
|
|
6585
|
-
return TEXT_EXTENSIONS.has(ext) || IMAGE_EXTENSIONS.has(ext);
|
|
6586
|
-
}
|
|
6587
7065
|
function collectExpandedPaths(entries, depth = 0) {
|
|
6588
7066
|
const paths = [];
|
|
6589
7067
|
for (const entry of entries) {
|
|
@@ -6608,8 +7086,8 @@ function findEntry(entries, path) {
|
|
|
6608
7086
|
}
|
|
6609
7087
|
function RenderEntries({
|
|
6610
7088
|
entries,
|
|
6611
|
-
|
|
6612
|
-
|
|
7089
|
+
onDelete,
|
|
7090
|
+
downloadUrlFor
|
|
6613
7091
|
}) {
|
|
6614
7092
|
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: entries.map((entry) => {
|
|
6615
7093
|
if (entry.kind === "dir") {
|
|
@@ -6617,27 +7095,26 @@ function RenderEntries({
|
|
|
6617
7095
|
RenderEntries,
|
|
6618
7096
|
{
|
|
6619
7097
|
entries: entry.children,
|
|
6620
|
-
|
|
6621
|
-
|
|
7098
|
+
onDelete,
|
|
7099
|
+
downloadUrlFor
|
|
6622
7100
|
}
|
|
6623
7101
|
) }, entry.path);
|
|
6624
7102
|
}
|
|
6625
|
-
const
|
|
7103
|
+
const fileName2 = entry.name;
|
|
6626
7104
|
return /* @__PURE__ */ jsxRuntime.jsxs(FileTreeFile, { name: entry.name, path: entry.path, children: [
|
|
6627
7105
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "size-4 shrink-0" }),
|
|
6628
7106
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate", children: entry.name }),
|
|
6629
7107
|
entry.size != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 shrink-0 text-xs text-muted-foreground/60", children: formatFileSize(entry.size) }),
|
|
6630
7108
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-1 flex shrink-0 items-center gap-0 opacity-0 transition-opacity group-hover:opacity-100", children: [
|
|
6631
|
-
|
|
6632
|
-
"
|
|
7109
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7110
|
+
"a",
|
|
6633
7111
|
{
|
|
6634
|
-
|
|
7112
|
+
href: downloadUrlFor(entry.path),
|
|
7113
|
+
download: fileName2,
|
|
6635
7114
|
className: "rounded p-0.5 text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
6636
|
-
onClick: (event) =>
|
|
6637
|
-
|
|
6638
|
-
|
|
6639
|
-
},
|
|
6640
|
-
title: "View",
|
|
7115
|
+
onClick: (event) => event.stopPropagation(),
|
|
7116
|
+
title: "Download",
|
|
7117
|
+
"aria-label": `Download ${fileName2}`,
|
|
6641
7118
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.DownloadIcon, { className: "size-3" })
|
|
6642
7119
|
}
|
|
6643
7120
|
),
|
|
@@ -6651,6 +7128,7 @@ function RenderEntries({
|
|
|
6651
7128
|
onDelete(entry.path);
|
|
6652
7129
|
},
|
|
6653
7130
|
title: "Delete",
|
|
7131
|
+
"aria-label": `Delete ${fileName2}`,
|
|
6654
7132
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.TrashIcon, { className: "size-3" })
|
|
6655
7133
|
}
|
|
6656
7134
|
)
|
|
@@ -6663,6 +7141,8 @@ function WorkspacePanel({
|
|
|
6663
7141
|
sessionId,
|
|
6664
7142
|
selectedPath,
|
|
6665
7143
|
onSelectedPathChange,
|
|
7144
|
+
collapsed = false,
|
|
7145
|
+
onCollapsedChange,
|
|
6666
7146
|
disabled = false
|
|
6667
7147
|
}) {
|
|
6668
7148
|
const fileInputRef = react.useRef(null);
|
|
@@ -6857,6 +7337,25 @@ function WorkspacePanel({
|
|
|
6857
7337
|
window.removeEventListener("mouseup", onMouseUp);
|
|
6858
7338
|
};
|
|
6859
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
|
+
}
|
|
6860
7359
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6861
7360
|
"aside",
|
|
6862
7361
|
{
|
|
@@ -6889,6 +7388,19 @@ function WorkspacePanel({
|
|
|
6889
7388
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-sm font-medium text-foreground", children: rootName }),
|
|
6890
7389
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-xs text-faint", children: "Workspace" })
|
|
6891
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
|
+
] }),
|
|
6892
7404
|
/* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
|
|
6893
7405
|
/* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6894
7406
|
Button,
|
|
@@ -6968,8 +7480,8 @@ function WorkspacePanel({
|
|
|
6968
7480
|
RenderEntries,
|
|
6969
7481
|
{
|
|
6970
7482
|
entries,
|
|
6971
|
-
|
|
6972
|
-
|
|
7483
|
+
onDelete: setDeleteTarget,
|
|
7484
|
+
downloadUrlFor: (path) => sessionId ? adapter.getWorkspaceDownloadUrl({ sessionId, path }) : "#"
|
|
6973
7485
|
}
|
|
6974
7486
|
)
|
|
6975
7487
|
}
|
|
@@ -6981,7 +7493,13 @@ function WorkspacePanel({
|
|
|
6981
7493
|
file,
|
|
6982
7494
|
loading: fileLoading,
|
|
6983
7495
|
error: fileError,
|
|
7496
|
+
downloadUrl: file && sessionId ? adapter.getWorkspaceDownloadUrl({
|
|
7497
|
+
sessionId,
|
|
7498
|
+
path: file.path
|
|
7499
|
+
}) : null,
|
|
7500
|
+
onDelete: file ? () => setDeleteTarget(file.path) : null,
|
|
6984
7501
|
onClose: () => {
|
|
7502
|
+
onSelectedPathChange(null);
|
|
6985
7503
|
setFile(null);
|
|
6986
7504
|
setFileError(null);
|
|
6987
7505
|
}
|
|
@@ -7082,10 +7600,11 @@ var EMPTY_TOKEN_USAGE = {
|
|
|
7082
7600
|
contextWindow: 0,
|
|
7083
7601
|
model: ""
|
|
7084
7602
|
};
|
|
7085
|
-
function createInitialAgentChatState() {
|
|
7603
|
+
function createInitialAgentChatState(options = {}) {
|
|
7086
7604
|
return {
|
|
7087
7605
|
messages: [],
|
|
7088
7606
|
isRunning: false,
|
|
7607
|
+
isLoadingHistory: options.isLoadingHistory ?? false,
|
|
7089
7608
|
tokenUsage: EMPTY_TOKEN_USAGE,
|
|
7090
7609
|
retryIndicator: null,
|
|
7091
7610
|
lastEventId: 0,
|
|
@@ -7097,6 +7616,7 @@ function createInitialAgentChatState() {
|
|
|
7097
7616
|
function applyAgentChatEvent(state, event) {
|
|
7098
7617
|
let nextState = {
|
|
7099
7618
|
...state,
|
|
7619
|
+
isLoadingHistory: false,
|
|
7100
7620
|
lastEventId: Math.max(state.lastEventId, event.eventId),
|
|
7101
7621
|
sessionDone: state.sessionDone || event.type === "session.done"
|
|
7102
7622
|
};
|
|
@@ -7630,11 +8150,12 @@ function useAgentChatRuntime({
|
|
|
7630
8150
|
onSessionChange
|
|
7631
8151
|
}) {
|
|
7632
8152
|
const [state, setState] = react.useState(
|
|
7633
|
-
() => createInitialAgentChatState()
|
|
8153
|
+
() => createInitialAgentChatState({ isLoadingHistory: Boolean(sessionId) })
|
|
7634
8154
|
);
|
|
7635
8155
|
const stateRef = react.useRef(state);
|
|
7636
8156
|
const streamRef = react.useRef(null);
|
|
7637
8157
|
const reconnectTimerRef = react.useRef(null);
|
|
8158
|
+
const previousSessionIdRef = react.useRef(sessionId);
|
|
7638
8159
|
react.useEffect(() => {
|
|
7639
8160
|
stateRef.current = state;
|
|
7640
8161
|
}, [state]);
|
|
@@ -7650,6 +8171,8 @@ function useAgentChatRuntime({
|
|
|
7650
8171
|
stream?.close();
|
|
7651
8172
|
}, []);
|
|
7652
8173
|
react.useEffect(() => {
|
|
8174
|
+
const previousSessionId = previousSessionIdRef.current;
|
|
8175
|
+
previousSessionIdRef.current = sessionId;
|
|
7653
8176
|
clearReconnectTimer();
|
|
7654
8177
|
closeStream();
|
|
7655
8178
|
if (!sessionId) {
|
|
@@ -7657,11 +8180,11 @@ function useAgentChatRuntime({
|
|
|
7657
8180
|
return;
|
|
7658
8181
|
}
|
|
7659
8182
|
let cancelled = false;
|
|
7660
|
-
const connect = () => {
|
|
8183
|
+
const connect = (after) => {
|
|
7661
8184
|
if (cancelled) return;
|
|
7662
8185
|
const stream = adapter.openEventStream({
|
|
7663
8186
|
sessionId,
|
|
7664
|
-
after: stateRef.current.lastEventId
|
|
8187
|
+
after: after ?? stateRef.current.lastEventId
|
|
7665
8188
|
});
|
|
7666
8189
|
streamRef.current = stream;
|
|
7667
8190
|
for (const eventType of AGENT_CHAT_LISTENED_EVENTS) {
|
|
@@ -7684,14 +8207,32 @@ function useAgentChatRuntime({
|
|
|
7684
8207
|
streamRef.current = null;
|
|
7685
8208
|
}
|
|
7686
8209
|
if (!stateRef.current.sessionDone && !cancelled) {
|
|
7687
|
-
reconnectTimerRef.current = setTimeout(connect, 3e3);
|
|
8210
|
+
reconnectTimerRef.current = setTimeout(() => connect(), 3e3);
|
|
7688
8211
|
}
|
|
7689
8212
|
};
|
|
7690
8213
|
};
|
|
7691
|
-
|
|
7692
|
-
|
|
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);
|
|
7693
8228
|
adapter.getSession({ sessionId }).then((session) => {
|
|
7694
8229
|
if (cancelled) return;
|
|
8230
|
+
if (session.messageCount === 0) {
|
|
8231
|
+
setState((prev) => ({
|
|
8232
|
+
...prev,
|
|
8233
|
+
isLoadingHistory: false
|
|
8234
|
+
}));
|
|
8235
|
+
}
|
|
7695
8236
|
if (isTerminalStatus(session.status)) {
|
|
7696
8237
|
setState((prev) => ({
|
|
7697
8238
|
...prev,
|
|
@@ -7774,13 +8315,18 @@ function useAgentChatRuntime({
|
|
|
7774
8315
|
}, []);
|
|
7775
8316
|
const send = react.useCallback(
|
|
7776
8317
|
async (content) => {
|
|
8318
|
+
markSending(content);
|
|
7777
8319
|
if (!sessionId) {
|
|
7778
|
-
|
|
7779
|
-
|
|
7780
|
-
|
|
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
|
+
}
|
|
7781
8328
|
return;
|
|
7782
8329
|
}
|
|
7783
|
-
markSending(content);
|
|
7784
8330
|
try {
|
|
7785
8331
|
await adapter.sendMessage({ sessionId, content });
|
|
7786
8332
|
} catch (error) {
|
|
@@ -7817,6 +8363,7 @@ function useAgentChatRuntime({
|
|
|
7817
8363
|
return {
|
|
7818
8364
|
messages: state.messages,
|
|
7819
8365
|
isRunning: state.isRunning,
|
|
8366
|
+
isLoadingHistory: state.isLoadingHistory,
|
|
7820
8367
|
tokenUsage: state.tokenUsage,
|
|
7821
8368
|
retryIndicator: state.retryIndicator,
|
|
7822
8369
|
send,
|
|
@@ -7853,6 +8400,7 @@ function AgentChat({
|
|
|
7853
8400
|
disabled
|
|
7854
8401
|
}) {
|
|
7855
8402
|
const [workspacePath, setWorkspacePath] = react.useState(null);
|
|
8403
|
+
const [workspaceCollapsed, setWorkspaceCollapsed] = react.useState(false);
|
|
7856
8404
|
const runtime = useAgentChatRuntime({
|
|
7857
8405
|
adapter,
|
|
7858
8406
|
agentId,
|
|
@@ -7884,6 +8432,7 @@ function AgentChat({
|
|
|
7884
8432
|
sessionId,
|
|
7885
8433
|
messages: runtime.messages,
|
|
7886
8434
|
isRunning: runtime.isRunning,
|
|
8435
|
+
isLoadingHistory: runtime.isLoadingHistory,
|
|
7887
8436
|
onSend: (content) => void runtime.send(content),
|
|
7888
8437
|
onStop: () => void runtime.stop(),
|
|
7889
8438
|
onRetry: runtime.retry,
|
|
@@ -7900,6 +8449,8 @@ function AgentChat({
|
|
|
7900
8449
|
sessionId,
|
|
7901
8450
|
selectedPath: workspacePath,
|
|
7902
8451
|
onSelectedPathChange: setWorkspacePath,
|
|
8452
|
+
collapsed: workspaceCollapsed,
|
|
8453
|
+
onCollapsedChange: setWorkspaceCollapsed,
|
|
7903
8454
|
disabled
|
|
7904
8455
|
}
|
|
7905
8456
|
)
|
|
@@ -7907,6 +8458,7 @@ function AgentChat({
|
|
|
7907
8458
|
}
|
|
7908
8459
|
);
|
|
7909
8460
|
}
|
|
8461
|
+
init_utils();
|
|
7910
8462
|
var POLL_INTERVAL_ACTIVE_MS = 4e3;
|
|
7911
8463
|
var POLL_INTERVAL_IDLE_MS = 3e4;
|
|
7912
8464
|
var DEFAULT_SESSION_LIST_LIMIT = 50;
|
|
@@ -7970,6 +8522,20 @@ function mergeTreeNodes(groups) {
|
|
|
7970
8522
|
}
|
|
7971
8523
|
return Array.from(byId.values());
|
|
7972
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
|
+
}
|
|
7973
8539
|
function formatSessionTime(value) {
|
|
7974
8540
|
const date = new Date(value);
|
|
7975
8541
|
if (Number.isNaN(date.getTime())) return "";
|
|
@@ -8086,11 +8652,12 @@ function SessionTreePanel({
|
|
|
8086
8652
|
title = "Running",
|
|
8087
8653
|
sessionListLimit = DEFAULT_SESSION_LIST_LIMIT,
|
|
8088
8654
|
hideRoot = false,
|
|
8655
|
+
hideHeader = false,
|
|
8656
|
+
loadList = false,
|
|
8089
8657
|
onSessionSelect,
|
|
8090
8658
|
onSessionDelete
|
|
8091
8659
|
}) {
|
|
8092
8660
|
const [nodes, setNodes] = react.useState([]);
|
|
8093
|
-
const [loading, setLoading] = react.useState(false);
|
|
8094
8661
|
const [error, setError] = react.useState(null);
|
|
8095
8662
|
const [hasEverLoaded, setHasEverLoaded] = react.useState(false);
|
|
8096
8663
|
const [deletingSessionId, setDeletingSessionId] = react.useState(
|
|
@@ -8102,18 +8669,16 @@ function SessionTreePanel({
|
|
|
8102
8669
|
const resetContext = react.useRef(null);
|
|
8103
8670
|
const refetch = react.useCallback(
|
|
8104
8671
|
async (opts) => {
|
|
8105
|
-
const canLoadSessionList = Boolean(
|
|
8672
|
+
const canLoadSessionList = Boolean(loadList && adapter.listSessions);
|
|
8106
8673
|
const canLoadSessionTree = Boolean(sessionId && adapter.getSessionTree);
|
|
8107
8674
|
if (!canLoadSessionList && !canLoadSessionTree) {
|
|
8108
8675
|
setNodes([]);
|
|
8109
8676
|
setHasEverLoaded(true);
|
|
8110
|
-
setLoading(false);
|
|
8111
8677
|
return;
|
|
8112
8678
|
}
|
|
8113
8679
|
const currentRequestId = ++requestId.current;
|
|
8114
|
-
if (!opts?.silent) setLoading(true);
|
|
8115
8680
|
try {
|
|
8116
|
-
const sessionListPromise =
|
|
8681
|
+
const sessionListPromise = loadList && adapter.listSessions ? adapter.listSessions({
|
|
8117
8682
|
agentId,
|
|
8118
8683
|
limit: sessionListLimit
|
|
8119
8684
|
}) : Promise.resolve(null);
|
|
@@ -8139,13 +8704,9 @@ function SessionTreePanel({
|
|
|
8139
8704
|
if (!opts?.silent) {
|
|
8140
8705
|
setError(e instanceof Error ? e.message : "Failed to load tree");
|
|
8141
8706
|
}
|
|
8142
|
-
} finally {
|
|
8143
|
-
if (mounted.current && currentRequestId === requestId.current && !opts?.silent) {
|
|
8144
|
-
setLoading(false);
|
|
8145
|
-
}
|
|
8146
8707
|
}
|
|
8147
8708
|
},
|
|
8148
|
-
[adapter, agentId, sessionId, sessionListLimit]
|
|
8709
|
+
[adapter, agentId, loadList, sessionId, sessionListLimit]
|
|
8149
8710
|
);
|
|
8150
8711
|
react.useEffect(() => {
|
|
8151
8712
|
mounted.current = true;
|
|
@@ -8155,8 +8716,8 @@ function SessionTreePanel({
|
|
|
8155
8716
|
}, []);
|
|
8156
8717
|
react.useEffect(() => {
|
|
8157
8718
|
const previous = resetContext.current;
|
|
8158
|
-
const shouldReset = !previous || previous.
|
|
8159
|
-
resetContext.current = {
|
|
8719
|
+
const shouldReset = !previous || previous.loadList !== loadList || previous.agentId !== agentId || previous.sessionListLimit !== sessionListLimit;
|
|
8720
|
+
resetContext.current = { loadList, agentId, sessionListLimit };
|
|
8160
8721
|
if (shouldReset) {
|
|
8161
8722
|
setNodes([]);
|
|
8162
8723
|
setHasEverLoaded(false);
|
|
@@ -8164,7 +8725,7 @@ function SessionTreePanel({
|
|
|
8164
8725
|
}
|
|
8165
8726
|
setError(null);
|
|
8166
8727
|
void refetch();
|
|
8167
|
-
}, [adapter, agentId, refetch, sessionListLimit]);
|
|
8728
|
+
}, [adapter, agentId, loadList, refetch, sessionListLimit]);
|
|
8168
8729
|
const runningCount = react.useMemo(
|
|
8169
8730
|
() => nodes.filter((n) => n.status === "active").length,
|
|
8170
8731
|
[nodes]
|
|
@@ -8201,6 +8762,11 @@ function SessionTreePanel({
|
|
|
8201
8762
|
setDeletingSessionId(id);
|
|
8202
8763
|
try {
|
|
8203
8764
|
await adapter.deleteSession({ sessionId: id });
|
|
8765
|
+
setNodes((current) => {
|
|
8766
|
+
const next = pruneDeletedSessionNodes(current, id);
|
|
8767
|
+
lastFingerprint.current = treeFingerprint(next);
|
|
8768
|
+
return next;
|
|
8769
|
+
});
|
|
8204
8770
|
onSessionDelete?.(id);
|
|
8205
8771
|
await refetch({ silent: true });
|
|
8206
8772
|
} catch (e) {
|
|
@@ -8215,24 +8781,12 @@ function SessionTreePanel({
|
|
|
8215
8781
|
if (nodes.length === 0) return null;
|
|
8216
8782
|
const topLevel = hideRoot ? roots.flatMap((r) => r.children) : roots;
|
|
8217
8783
|
if (topLevel.length === 0) return null;
|
|
8218
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8219
|
-
/* @__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: [
|
|
8220
8786
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.UsersIcon, { className: "w-3.5 h-3.5" }),
|
|
8221
8787
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: title }),
|
|
8222
8788
|
runningCount > 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "default", className: "h-4 px-1.5 text-[10px] ml-auto", children: runningCount })
|
|
8223
8789
|
] }),
|
|
8224
|
-
loading && /* @__PURE__ */ jsxRuntime.jsx(
|
|
8225
|
-
"div",
|
|
8226
|
-
{
|
|
8227
|
-
className: "px-3 py-2",
|
|
8228
|
-
role: "status",
|
|
8229
|
-
"aria-label": "Loading sessions",
|
|
8230
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
8231
|
-
/* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-3.5 w-28" }),
|
|
8232
|
-
/* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "h-3 w-20" })
|
|
8233
|
-
] })
|
|
8234
|
-
}
|
|
8235
|
-
),
|
|
8236
8790
|
error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-2 text-xs text-destructive", children: error }),
|
|
8237
8791
|
!error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-1 pb-2", children: topLevel.map((entry) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
8238
8792
|
TreeNodeRow,
|