@blade-hq/agent-kit 0.5.2 → 0.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/{SkillStatusBar-DpbkD4Jx.d.ts → SkillStatusBar-BKAGU9tr.d.ts} +5 -3
- package/dist/{blade-client-CFvmjs5R.d.ts → blade-client-R3cLVOYs.d.ts} +25 -3
- package/dist/{chunk-4ZEOWH6U.js → chunk-3ZEWA2YM.js} +2 -2
- package/dist/{chunk-LVLGDM76.js → chunk-557R7QZV.js} +2 -2
- package/dist/{chunk-PTMCGZFG.js → chunk-HWOVPFWG.js} +29 -15
- package/dist/chunk-HWOVPFWG.js.map +1 -0
- package/dist/{chunk-YW2THJUX.js → chunk-NEI66DW6.js} +2 -2
- package/dist/{chunk-7JX26TWV.js → chunk-Q6CSM5DE.js} +60 -4
- package/dist/chunk-Q6CSM5DE.js.map +1 -0
- package/dist/{chunk-EV225FLR.js → chunk-S6EPGDAL.js} +227 -191
- package/dist/chunk-S6EPGDAL.js.map +1 -0
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js +1 -1
- package/dist/react/api/vibe-coding.d.ts +2 -2
- package/dist/react/api/vibe-coding.js +2 -2
- package/dist/react/components/chat/index.d.ts +3 -3
- package/dist/react/components/chat/index.js +5 -5
- package/dist/react/components/plan/index.js +3 -3
- package/dist/react/components/session/index.js +3 -3
- package/dist/react/components/workspace/index.js +32 -4
- package/dist/react/components/workspace/index.js.map +1 -1
- package/dist/react/index.d.ts +9 -7
- package/dist/react/index.js +6 -6
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/dist/chunk-7JX26TWV.js.map +0 -1
- package/dist/chunk-EV225FLR.js.map +0 -1
- package/dist/chunk-PTMCGZFG.js.map +0 -1
- /package/dist/{chunk-4ZEOWH6U.js.map → chunk-3ZEWA2YM.js.map} +0 -0
- /package/dist/{chunk-LVLGDM76.js.map → chunk-557R7QZV.js.map} +0 -0
- /package/dist/{chunk-YW2THJUX.js.map → chunk-NEI66DW6.js.map} +0 -0
|
@@ -8,13 +8,13 @@ import {
|
|
|
8
8
|
getCodeLanguageFromFilename,
|
|
9
9
|
parseAskUserQuestion,
|
|
10
10
|
useHighlightedCodeHtml
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-557R7QZV.js";
|
|
12
12
|
import {
|
|
13
13
|
Collapsible,
|
|
14
14
|
CollapsibleContent,
|
|
15
15
|
CollapsibleTrigger,
|
|
16
16
|
resolveSessionFilePreviewTarget
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-3ZEWA2YM.js";
|
|
18
18
|
import {
|
|
19
19
|
buildMessageContent,
|
|
20
20
|
buildToolPreviewKey,
|
|
@@ -57,7 +57,7 @@ import {
|
|
|
57
57
|
useUiBridgeStore,
|
|
58
58
|
useUiStore,
|
|
59
59
|
writeFile
|
|
60
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-HWOVPFWG.js";
|
|
61
61
|
import {
|
|
62
62
|
registerBridgeIframe,
|
|
63
63
|
tapBridgeEvent
|
|
@@ -66,7 +66,7 @@ import {
|
|
|
66
66
|
ModelOption,
|
|
67
67
|
ModelsConfig,
|
|
68
68
|
ModelsResource
|
|
69
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-Q6CSM5DE.js";
|
|
70
70
|
import {
|
|
71
71
|
cn,
|
|
72
72
|
copyToClipboard
|
|
@@ -80,13 +80,15 @@ import { Eye } from "lucide-react";
|
|
|
80
80
|
import { useCallback as useCallback13 } from "react";
|
|
81
81
|
|
|
82
82
|
// src/react/hooks/use-chat.ts
|
|
83
|
-
import { useCallback, useEffect } from "react";
|
|
83
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
84
84
|
var EMPTY_MESSAGES = [];
|
|
85
85
|
function useChat(sessionId) {
|
|
86
86
|
const messages = useChatStore((s) => s.messages[sessionId] ?? EMPTY_MESSAGES);
|
|
87
87
|
const isStreaming = useChatStore((s) => s.isStreaming[sessionId] ?? false);
|
|
88
88
|
const mode = useSessionStore((s) => s.modes[sessionId] ?? "executing");
|
|
89
89
|
const setAnswerCallback = useAnswerCallbackStore((s) => s.setAnswerCallback);
|
|
90
|
+
const [isStopping, setIsStopping] = useState(false);
|
|
91
|
+
const previousSessionIdRef = useRef(sessionId);
|
|
90
92
|
const send = useCallback(
|
|
91
93
|
(msg, mode2, askuserAnswer, options) => {
|
|
92
94
|
const synthesizedAnswer = askuserAnswer ?? buildPendingAskUserAnswer(sessionId, msg);
|
|
@@ -94,9 +96,27 @@ function useChat(sessionId) {
|
|
|
94
96
|
},
|
|
95
97
|
[sessionId]
|
|
96
98
|
);
|
|
97
|
-
const stop = useCallback(() => {
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
const stop = useCallback(async () => {
|
|
100
|
+
if (isStopping) return;
|
|
101
|
+
setIsStopping(true);
|
|
102
|
+
try {
|
|
103
|
+
await getSocket().stop(sessionId);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
console.error("[chat] stop request failed", error);
|
|
106
|
+
} finally {
|
|
107
|
+
setIsStopping(false);
|
|
108
|
+
}
|
|
109
|
+
}, [isStopping, sessionId]);
|
|
110
|
+
useEffect(() => {
|
|
111
|
+
if (previousSessionIdRef.current !== sessionId) {
|
|
112
|
+
previousSessionIdRef.current = sessionId;
|
|
113
|
+
setIsStopping(false);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (!isStreaming) {
|
|
117
|
+
setIsStopping(false);
|
|
118
|
+
}
|
|
119
|
+
}, [isStreaming, sessionId]);
|
|
100
120
|
const answer = useCallback(
|
|
101
121
|
(msg, toolCallId, answerData) => {
|
|
102
122
|
send(msg, mode, { tool_call_id: toolCallId, ...answerData });
|
|
@@ -107,7 +127,7 @@ function useChat(sessionId) {
|
|
|
107
127
|
setAnswerCallback(sessionId, answer);
|
|
108
128
|
return () => setAnswerCallback(sessionId, void 0);
|
|
109
129
|
}, [answer, sessionId, setAnswerCallback]);
|
|
110
|
-
return { messages, isStreaming, send, stop };
|
|
130
|
+
return { messages, isStreaming, isStopping, send, stop };
|
|
111
131
|
}
|
|
112
132
|
function buildPendingAskUserAnswer(sessionId, message) {
|
|
113
133
|
const session = useSessionStore.getState().sessions.find((item) => item.id === sessionId);
|
|
@@ -180,17 +200,17 @@ import {
|
|
|
180
200
|
useEffect as useEffect7,
|
|
181
201
|
useEffectEvent as useEffectEvent2,
|
|
182
202
|
useMemo as useMemo7,
|
|
183
|
-
useRef as
|
|
184
|
-
useState as
|
|
203
|
+
useRef as useRef5,
|
|
204
|
+
useState as useState8
|
|
185
205
|
} from "react";
|
|
186
206
|
import { createRoot } from "react-dom/client";
|
|
187
207
|
import { toast } from "sonner";
|
|
188
208
|
|
|
189
209
|
// src/react/asr/use-tiptap-voice-input.ts
|
|
190
|
-
import { useCallback as useCallback3, useEffect as useEffect3, useEffectEvent, useRef as
|
|
210
|
+
import { useCallback as useCallback3, useEffect as useEffect3, useEffectEvent, useRef as useRef3 } from "react";
|
|
191
211
|
|
|
192
212
|
// src/react/asr/use-voice-input.ts
|
|
193
|
-
import { useCallback as useCallback2, useEffect as useEffect2, useRef, useState } from "react";
|
|
213
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
|
|
194
214
|
|
|
195
215
|
// src/react/asr/voice-input-support.ts
|
|
196
216
|
function isIpHost(hostname) {
|
|
@@ -237,14 +257,14 @@ function matchesRequest(data, requestId) {
|
|
|
237
257
|
return !rid || rid === requestId;
|
|
238
258
|
}
|
|
239
259
|
function useVoiceInput(options) {
|
|
240
|
-
const [status, setStatus] =
|
|
241
|
-
const [error, setError] =
|
|
242
|
-
const [level, setLevel] =
|
|
243
|
-
const sessionRef =
|
|
244
|
-
const startingRef =
|
|
245
|
-
const stoppingRef =
|
|
246
|
-
const unmountedRef =
|
|
247
|
-
const optionsRef =
|
|
260
|
+
const [status, setStatus] = useState2("idle");
|
|
261
|
+
const [error, setError] = useState2(null);
|
|
262
|
+
const [level, setLevel] = useState2(0);
|
|
263
|
+
const sessionRef = useRef2(null);
|
|
264
|
+
const startingRef = useRef2(false);
|
|
265
|
+
const stoppingRef = useRef2(false);
|
|
266
|
+
const unmountedRef = useRef2(false);
|
|
267
|
+
const optionsRef = useRef2(options);
|
|
248
268
|
optionsRef.current = options;
|
|
249
269
|
const reportError = useCallback2((err) => {
|
|
250
270
|
const payload = typeof err === "string" ? { title: err } : err;
|
|
@@ -499,8 +519,8 @@ function useVoiceInput(options) {
|
|
|
499
519
|
// src/react/asr/use-tiptap-voice-input.ts
|
|
500
520
|
function useTiptapVoiceInput(options) {
|
|
501
521
|
const { editorRef, workletUrl, onError } = options;
|
|
502
|
-
const partialRangeRef =
|
|
503
|
-
const lastPartialLenRef =
|
|
522
|
+
const partialRangeRef = useRef3(null);
|
|
523
|
+
const lastPartialLenRef = useRef3(0);
|
|
504
524
|
const handlePartial = useEffectEvent((text) => {
|
|
505
525
|
const ed = editorRef.current;
|
|
506
526
|
if (!ed) return;
|
|
@@ -619,7 +639,7 @@ function VoiceWaveform({ level, color = "currentColor", size = 16 }) {
|
|
|
619
639
|
|
|
620
640
|
// src/react/components/model/ModelSelector.tsx
|
|
621
641
|
import { Loader2, Sparkles } from "lucide-react";
|
|
622
|
-
import { useEffect as useEffect4, useMemo, useRef as
|
|
642
|
+
import { useEffect as useEffect4, useMemo, useRef as useRef4, useState as useState3 } from "react";
|
|
623
643
|
|
|
624
644
|
// src/react/hooks/use-model-preferences.ts
|
|
625
645
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
@@ -727,9 +747,9 @@ function ModelSelector({
|
|
|
727
747
|
placement = "bottom"
|
|
728
748
|
}) {
|
|
729
749
|
const { models, defaultModel, isLoading } = useModelConfig();
|
|
730
|
-
const [isOpen, setIsOpen] =
|
|
731
|
-
const [query, setQuery] =
|
|
732
|
-
const rootRef =
|
|
750
|
+
const [isOpen, setIsOpen] = useState3(false);
|
|
751
|
+
const [query, setQuery] = useState3("");
|
|
752
|
+
const rootRef = useRef4(null);
|
|
733
753
|
useEffect4(() => {
|
|
734
754
|
if (!isOpen) return;
|
|
735
755
|
const closeOnPointerDown = (event) => {
|
|
@@ -838,7 +858,7 @@ function ModelSelector({
|
|
|
838
858
|
}
|
|
839
859
|
|
|
840
860
|
// src/react/hooks/use-input-history.ts
|
|
841
|
-
import { useCallback as useCallback4, useEffect as useEffect5, useMemo as useMemo2, useState as
|
|
861
|
+
import { useCallback as useCallback4, useEffect as useEffect5, useMemo as useMemo2, useState as useState4 } from "react";
|
|
842
862
|
var MAX_HISTORY_ENTRIES = 50;
|
|
843
863
|
function getStorageKey(sessionId) {
|
|
844
864
|
return sessionId ? `input-history:${sessionId}` : null;
|
|
@@ -863,9 +883,9 @@ function readEntries(storageKey) {
|
|
|
863
883
|
}
|
|
864
884
|
function useInputHistory(sessionId) {
|
|
865
885
|
const storageKey = useMemo2(() => getStorageKey(sessionId), [sessionId]);
|
|
866
|
-
const [entries, setEntries] =
|
|
867
|
-
const [cursor, setCursor] =
|
|
868
|
-
const [draft, setDraft] =
|
|
886
|
+
const [entries, setEntries] = useState4([]);
|
|
887
|
+
const [cursor, setCursor] = useState4(null);
|
|
888
|
+
const [draft, setDraft] = useState4("");
|
|
869
889
|
useEffect5(() => {
|
|
870
890
|
setEntries(readEntries(storageKey));
|
|
871
891
|
setCursor(null);
|
|
@@ -1004,7 +1024,7 @@ function skillDisplayName(skill) {
|
|
|
1004
1024
|
|
|
1005
1025
|
// src/react/components/chat/FileCompletionMenu.tsx
|
|
1006
1026
|
import { ChevronRight, File, Folder } from "lucide-react";
|
|
1007
|
-
import { forwardRef, useCallback as useCallback5, useImperativeHandle, useMemo as useMemo4, useState as
|
|
1027
|
+
import { forwardRef, useCallback as useCallback5, useImperativeHandle, useMemo as useMemo4, useState as useState5 } from "react";
|
|
1008
1028
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1009
1029
|
var ROOT_DIR = ".";
|
|
1010
1030
|
function isVisibleEntry(entry) {
|
|
@@ -1108,7 +1128,7 @@ var FileCompletionMenu = forwardRef(
|
|
|
1108
1128
|
}
|
|
1109
1129
|
);
|
|
1110
1130
|
var FileCompletionMenuContent = forwardRef(function FileCompletionMenuContent2({ command, editor, filterQuery, items, onExit, range, sessionId }, ref) {
|
|
1111
|
-
const [rawSelectedIndex, setRawSelectedIndex] =
|
|
1131
|
+
const [rawSelectedIndex, setRawSelectedIndex] = useState5(0);
|
|
1112
1132
|
const filteredEntries = useMemo4(() => filterEntries(items, filterQuery), [filterQuery, items]);
|
|
1113
1133
|
const selectedIndex = filteredEntries.length === 0 ? 0 : Math.min(rawSelectedIndex, filteredEntries.length - 1);
|
|
1114
1134
|
const handleSelect = useCallback5(
|
|
@@ -1189,11 +1209,11 @@ var FileCompletionMenuContent = forwardRef(function FileCompletionMenuContent2({
|
|
|
1189
1209
|
});
|
|
1190
1210
|
|
|
1191
1211
|
// src/react/components/chat/SkillCompletionMenu.tsx
|
|
1192
|
-
import { forwardRef as forwardRef2, useCallback as useCallback6, useImperativeHandle as useImperativeHandle2, useState as
|
|
1212
|
+
import { forwardRef as forwardRef2, useCallback as useCallback6, useImperativeHandle as useImperativeHandle2, useState as useState6 } from "react";
|
|
1193
1213
|
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1194
1214
|
var SkillCompletionMenu = forwardRef2(
|
|
1195
1215
|
function SkillCompletionMenu2({ command, items }, ref) {
|
|
1196
|
-
const [rawSelectedIndex, setRawSelectedIndex] =
|
|
1216
|
+
const [rawSelectedIndex, setRawSelectedIndex] = useState6(0);
|
|
1197
1217
|
const selectedIndex = items.length === 0 ? 0 : Math.min(rawSelectedIndex, items.length - 1);
|
|
1198
1218
|
const handleSelect = useCallback6(
|
|
1199
1219
|
(item) => {
|
|
@@ -1298,7 +1318,7 @@ var SkillCompletionMenu = forwardRef2(
|
|
|
1298
1318
|
|
|
1299
1319
|
// src/react/components/chat/BackgroundTasksPill.tsx
|
|
1300
1320
|
import { FileText, Square, Terminal } from "lucide-react";
|
|
1301
|
-
import { useState as
|
|
1321
|
+
import { useState as useState7 } from "react";
|
|
1302
1322
|
|
|
1303
1323
|
// src/react/hooks/use-background-tasks.ts
|
|
1304
1324
|
import { useQuery as useQuery2 } from "@tanstack/react-query";
|
|
@@ -1347,8 +1367,8 @@ function statusClass(status) {
|
|
|
1347
1367
|
}
|
|
1348
1368
|
function BackgroundTasksPill({ sessionId }) {
|
|
1349
1369
|
const { data: tasks } = useBackgroundTasks(sessionId);
|
|
1350
|
-
const [open, setOpen] =
|
|
1351
|
-
const [logTask, setLogTask] =
|
|
1370
|
+
const [open, setOpen] = useState7(false);
|
|
1371
|
+
const [logTask, setLogTask] = useState7(null);
|
|
1352
1372
|
if (tasks.length === 0) return null;
|
|
1353
1373
|
const runningCount = tasks.filter((task) => task.status === "running").length;
|
|
1354
1374
|
const openTaskLog = async (task) => {
|
|
@@ -2131,20 +2151,38 @@ function ComposerFilePill({
|
|
|
2131
2151
|
const isFile = attachment.kind === "file";
|
|
2132
2152
|
const isFailed = isFile && attachment.status === "failed";
|
|
2133
2153
|
const isUploading = isFile && attachment.status === "uploading";
|
|
2154
|
+
const uploadPercent = isUploading && typeof attachment.uploadProgress === "number" ? Math.max(0, Math.min(100, Math.round(attachment.uploadProgress * 100))) : null;
|
|
2134
2155
|
return /* @__PURE__ */ jsxs8(
|
|
2135
2156
|
"div",
|
|
2136
2157
|
{
|
|
2137
|
-
className: `flex shrink-0 items-center gap-1.5 rounded-full border px-2.5 py-1 text-[11px] ${isFailed ? "border-red-500/30 bg-red-500/5 text-red-400" : "border-[hsl(var(--border))] bg-[hsl(var(--card))] text-[hsl(var(--foreground))]"}`,
|
|
2158
|
+
className: `relative flex shrink-0 items-center gap-1.5 overflow-hidden rounded-full border px-2.5 py-1 text-[11px] ${isFailed ? "border-red-500/30 bg-red-500/5 text-red-400" : "border-[hsl(var(--border))] bg-[hsl(var(--card))] text-[hsl(var(--foreground))]"}`,
|
|
2138
2159
|
children: [
|
|
2139
|
-
|
|
2140
|
-
|
|
2160
|
+
uploadPercent !== null ? /* @__PURE__ */ jsx9(
|
|
2161
|
+
"span",
|
|
2162
|
+
{
|
|
2163
|
+
className: "absolute inset-y-0 left-0 bg-[hsl(var(--primary))]/10 transition-[width]",
|
|
2164
|
+
style: { width: `${uploadPercent}%` }
|
|
2165
|
+
}
|
|
2166
|
+
) : null,
|
|
2167
|
+
isUploading ? /* @__PURE__ */ jsx9(
|
|
2168
|
+
Loader22,
|
|
2169
|
+
{
|
|
2170
|
+
size: 12,
|
|
2171
|
+
className: "relative z-10 shrink-0 animate-spin text-[hsl(var(--muted-foreground))]"
|
|
2172
|
+
}
|
|
2173
|
+
) : /* @__PURE__ */ jsx9(Icon, { size: 12, className: "relative z-10 shrink-0 text-[hsl(var(--muted-foreground))]" }),
|
|
2174
|
+
/* @__PURE__ */ jsx9("span", { className: "relative z-10 max-w-32 truncate", children: attachment.name }),
|
|
2175
|
+
uploadPercent !== null ? /* @__PURE__ */ jsxs8("span", { className: "relative z-10 font-mono text-[10px] tabular-nums text-[hsl(var(--muted-foreground))]", children: [
|
|
2176
|
+
uploadPercent,
|
|
2177
|
+
"%"
|
|
2178
|
+
] }) : null,
|
|
2141
2179
|
/* @__PURE__ */ jsx9(
|
|
2142
2180
|
"button",
|
|
2143
2181
|
{
|
|
2144
2182
|
type: "button",
|
|
2145
2183
|
onClick: () => onRemove(attachment.id),
|
|
2146
2184
|
"aria-label": `\u79FB\u9664 ${attachment.name}`,
|
|
2147
|
-
className: "ml-0.5 inline-flex shrink-0 items-center justify-center rounded-full text-[hsl(var(--muted-foreground))] transition hover:text-rose-400",
|
|
2185
|
+
className: "relative z-10 ml-0.5 inline-flex shrink-0 items-center justify-center rounded-full text-[hsl(var(--muted-foreground))] transition hover:text-rose-400",
|
|
2148
2186
|
children: /* @__PURE__ */ jsx9(X2, { size: 10 })
|
|
2149
2187
|
}
|
|
2150
2188
|
)
|
|
@@ -2158,13 +2196,13 @@ function AddContextDialog({
|
|
|
2158
2196
|
onAdd
|
|
2159
2197
|
}) {
|
|
2160
2198
|
const CONTEXT_INLINE_THRESHOLD = 200;
|
|
2161
|
-
const [label, setLabel] =
|
|
2162
|
-
const [content, setContent] =
|
|
2163
|
-
const [showSessionPicker, setShowSessionPicker] =
|
|
2164
|
-
const [sessions, setSessions] =
|
|
2165
|
-
const [loadingSessions, setLoadingSessions] =
|
|
2166
|
-
const [importingId, setImportingId] =
|
|
2167
|
-
const [isImportProcessing, setIsImportProcessing] =
|
|
2199
|
+
const [label, setLabel] = useState8("");
|
|
2200
|
+
const [content, setContent] = useState8("");
|
|
2201
|
+
const [showSessionPicker, setShowSessionPicker] = useState8(false);
|
|
2202
|
+
const [sessions, setSessions] = useState8([]);
|
|
2203
|
+
const [loadingSessions, setLoadingSessions] = useState8(false);
|
|
2204
|
+
const [importingId, setImportingId] = useState8(null);
|
|
2205
|
+
const [isImportProcessing, setIsImportProcessing] = useState8(false);
|
|
2168
2206
|
const sanitizeContextFolderName = (raw) => {
|
|
2169
2207
|
const normalized = raw.trim().toLowerCase();
|
|
2170
2208
|
const safe = normalized.replace(/[^\w\-.\u4e00-\u9fa5]+/g, "_").replace(/^_+|_+$/g, "");
|
|
@@ -2394,7 +2432,7 @@ function ComposerContextPill({
|
|
|
2394
2432
|
content,
|
|
2395
2433
|
onRemove
|
|
2396
2434
|
}) {
|
|
2397
|
-
const [showDetail, setShowDetail] =
|
|
2435
|
+
const [showDetail, setShowDetail] = useState8(false);
|
|
2398
2436
|
const tokenK = formatTokenK(content);
|
|
2399
2437
|
return /* @__PURE__ */ jsxs8(Fragment2, { children: [
|
|
2400
2438
|
/* @__PURE__ */ jsxs8("div", { className: "flex shrink-0 items-center gap-1.5 rounded-full border border-[hsl(var(--border))] bg-[hsl(var(--accent))] px-2.5 py-1 text-[11px] text-[hsl(var(--foreground))]", children: [
|
|
@@ -2589,6 +2627,7 @@ function ChatInput({
|
|
|
2589
2627
|
onSend,
|
|
2590
2628
|
onStop,
|
|
2591
2629
|
isStreaming,
|
|
2630
|
+
isStopping = false,
|
|
2592
2631
|
mode = "executing",
|
|
2593
2632
|
onToggleMode,
|
|
2594
2633
|
renderAttachments,
|
|
@@ -2608,13 +2647,13 @@ function ChatInput({
|
|
|
2608
2647
|
onResyncSkills,
|
|
2609
2648
|
isResyncingSkills = false
|
|
2610
2649
|
}) {
|
|
2611
|
-
const [input, setInputInternal] =
|
|
2650
|
+
const [input, setInputInternal] = useState8(externalDraft?.value ?? "");
|
|
2612
2651
|
const setInput = useEffectEvent2((value) => {
|
|
2613
2652
|
setInputInternal(value);
|
|
2614
2653
|
externalDraft?.setValue(value);
|
|
2615
2654
|
});
|
|
2616
2655
|
const externalDraftValue = externalDraft?.value;
|
|
2617
|
-
const inputRef =
|
|
2656
|
+
const inputRef = useRef5(input);
|
|
2618
2657
|
inputRef.current = input;
|
|
2619
2658
|
useEffect7(() => {
|
|
2620
2659
|
if (externalDraftValue == null) return;
|
|
@@ -2624,7 +2663,7 @@ function ChatInput({
|
|
|
2624
2663
|
}
|
|
2625
2664
|
setInputInternal(externalDraftValue);
|
|
2626
2665
|
}, [externalDraftValue]);
|
|
2627
|
-
const [composerAttachments, setComposerAttachmentsInternal] =
|
|
2666
|
+
const [composerAttachments, setComposerAttachmentsInternal] = useState8(
|
|
2628
2667
|
externalAttachments?.value ?? []
|
|
2629
2668
|
);
|
|
2630
2669
|
const setComposerAttachments = useEffectEvent2(
|
|
@@ -2637,24 +2676,24 @@ function ChatInput({
|
|
|
2637
2676
|
}
|
|
2638
2677
|
);
|
|
2639
2678
|
const externalAttachmentsValue = externalAttachments?.value;
|
|
2640
|
-
const composerAttachmentsRef =
|
|
2679
|
+
const composerAttachmentsRef = useRef5(composerAttachments);
|
|
2641
2680
|
composerAttachmentsRef.current = composerAttachments;
|
|
2642
2681
|
useEffect7(() => {
|
|
2643
2682
|
if (externalAttachmentsValue == null) return;
|
|
2644
2683
|
if (composerAttachmentsRef.current === externalAttachmentsValue) return;
|
|
2645
2684
|
setComposerAttachmentsInternal(externalAttachmentsValue);
|
|
2646
2685
|
}, [externalAttachmentsValue]);
|
|
2647
|
-
const [dragging, setDragging] =
|
|
2648
|
-
const [isEditorFocused, setIsEditorFocused] =
|
|
2649
|
-
const [oversizedFiles, setOversizedFiles] =
|
|
2650
|
-
const [selectedModel, setSelectedModel] =
|
|
2686
|
+
const [dragging, setDragging] = useState8(false);
|
|
2687
|
+
const [isEditorFocused, setIsEditorFocused] = useState8(false);
|
|
2688
|
+
const [oversizedFiles, setOversizedFiles] = useState8([]);
|
|
2689
|
+
const [selectedModel, setSelectedModel] = useState8("");
|
|
2651
2690
|
const { setPreferredModel } = usePreferredModel();
|
|
2652
2691
|
const queryClient = useQueryClient2();
|
|
2653
|
-
const actionMenuRef =
|
|
2654
|
-
const fileInputRef =
|
|
2655
|
-
const folderInputRef =
|
|
2656
|
-
const editorRef =
|
|
2657
|
-
const localImageUrlsRef =
|
|
2692
|
+
const actionMenuRef = useRef5(null);
|
|
2693
|
+
const fileInputRef = useRef5(null);
|
|
2694
|
+
const folderInputRef = useRef5(null);
|
|
2695
|
+
const editorRef = useRef5(null);
|
|
2696
|
+
const localImageUrlsRef = useRef5(/* @__PURE__ */ new Map());
|
|
2658
2697
|
const activeSessionId = useSessionStore((state) => state.activeSessionId);
|
|
2659
2698
|
const sessions = useSessionStore((state) => state.sessions);
|
|
2660
2699
|
const activeSessionModel = useMemo7(
|
|
@@ -2672,7 +2711,7 @@ function ChatInput({
|
|
|
2672
2711
|
const draftAppends = useUiBridgeStore(
|
|
2673
2712
|
(state) => activeSessionId ? state.draftAppends[activeSessionId] : void 0
|
|
2674
2713
|
);
|
|
2675
|
-
const { resolvedModel } = useResolvedModel(activeSessionModel);
|
|
2714
|
+
const { resolvedModel, hasAvailableModel, isLoading: isModelLoading } = useResolvedModel(activeSessionModel);
|
|
2676
2715
|
useEffect7(() => {
|
|
2677
2716
|
setSelectedModel(resolvedModel);
|
|
2678
2717
|
}, [resolvedModel]);
|
|
@@ -2687,7 +2726,7 @@ function ChatInput({
|
|
|
2687
2726
|
const inputHistory = useInputHistory(activeSessionId);
|
|
2688
2727
|
const getSessionId = useEffectEvent2(() => activeSessionId);
|
|
2689
2728
|
const handleSlashCommand = useEffectEvent2((commandId) => onCommand?.(commandId));
|
|
2690
|
-
const [localImageUrls, setLocalImageUrls] =
|
|
2729
|
+
const [localImageUrls, setLocalImageUrls] = useState8({});
|
|
2691
2730
|
useEffect7(() => {
|
|
2692
2731
|
const closeActionMenu = (event) => {
|
|
2693
2732
|
const menu = actionMenuRef.current;
|
|
@@ -3016,7 +3055,7 @@ function ChatInput({
|
|
|
3016
3055
|
editor.commands.focus("end");
|
|
3017
3056
|
setRewindDraft(activeSessionId, null);
|
|
3018
3057
|
}, [activeSessionId, editor, rewindDraft, setRewindDraft]);
|
|
3019
|
-
const submittingRef =
|
|
3058
|
+
const submittingRef = useRef5(false);
|
|
3020
3059
|
useEffect7(() => {
|
|
3021
3060
|
let changed = false;
|
|
3022
3061
|
const nextLocalIds = /* @__PURE__ */ new Set();
|
|
@@ -3095,14 +3134,14 @@ function ChatInput({
|
|
|
3095
3134
|
});
|
|
3096
3135
|
const { isRecording, level: voiceLevel } = voice;
|
|
3097
3136
|
const handleMicDisabledClick = () => toast.info("\u8BED\u97F3\u8F93\u5165\u529F\u80FD\u672A\u5F00\u542F\uFF0C\u8BF7\u5728\u540E\u7AEF .env \u914D\u7F6E ASR_API_KEY");
|
|
3098
|
-
const voiceStopRef =
|
|
3137
|
+
const voiceStopRef = useRef5(voice.stop);
|
|
3099
3138
|
voiceStopRef.current = voice.stop;
|
|
3100
3139
|
useEffect7(() => {
|
|
3101
3140
|
if (isStreaming && isRecording) {
|
|
3102
3141
|
void voiceStopRef.current();
|
|
3103
3142
|
}
|
|
3104
3143
|
}, [isStreaming, isRecording]);
|
|
3105
|
-
const prevSessionIdRef =
|
|
3144
|
+
const prevSessionIdRef = useRef5(activeSessionId);
|
|
3106
3145
|
useEffect7(() => {
|
|
3107
3146
|
if (prevSessionIdRef.current !== activeSessionId) {
|
|
3108
3147
|
prevSessionIdRef.current = activeSessionId;
|
|
@@ -3115,6 +3154,13 @@ function ChatInput({
|
|
|
3115
3154
|
if (isStreaming || connectionStatus !== "connected") {
|
|
3116
3155
|
return;
|
|
3117
3156
|
}
|
|
3157
|
+
if (isModelLoading) {
|
|
3158
|
+
return;
|
|
3159
|
+
}
|
|
3160
|
+
if (!hasAvailableModel) {
|
|
3161
|
+
toast.error("\u6CA1\u6709\u53EF\u7528\u6A21\u578B\uFF0C\u8BF7\u68C0\u67E5\u6A21\u578B\u670D\u52A1\u914D\u7F6E");
|
|
3162
|
+
return;
|
|
3163
|
+
}
|
|
3118
3164
|
if (submittingRef.current) {
|
|
3119
3165
|
return;
|
|
3120
3166
|
}
|
|
@@ -3153,14 +3199,24 @@ function ChatInput({
|
|
|
3153
3199
|
if (pendingFiles.length > 0) {
|
|
3154
3200
|
setComposerAttachments(
|
|
3155
3201
|
(prev) => prev.map(
|
|
3156
|
-
(a) => a.kind === "file" && a.status === "pending" ? { ...a, status: "uploading" } : a
|
|
3202
|
+
(a) => a.kind === "file" && a.status === "pending" ? { ...a, status: "uploading", uploadProgress: 0 } : a
|
|
3157
3203
|
)
|
|
3158
3204
|
);
|
|
3159
3205
|
try {
|
|
3160
3206
|
const result = await uploadFiles(
|
|
3161
3207
|
uploadSessionId,
|
|
3162
3208
|
".",
|
|
3163
|
-
pendingFiles.map((a) => ({ file: a.file, name: a.name }))
|
|
3209
|
+
pendingFiles.map((a) => ({ file: a.file, name: a.name })),
|
|
3210
|
+
{
|
|
3211
|
+
onProgress: (progress) => {
|
|
3212
|
+
if (typeof progress.percent !== "number") return;
|
|
3213
|
+
setComposerAttachments(
|
|
3214
|
+
(prev) => prev.map(
|
|
3215
|
+
(a) => pendingFiles.some((pending) => pending.id === a.id) && a.kind === "file" && a.status === "uploading" ? { ...a, uploadProgress: progress.percent } : a
|
|
3216
|
+
)
|
|
3217
|
+
);
|
|
3218
|
+
}
|
|
3219
|
+
}
|
|
3164
3220
|
);
|
|
3165
3221
|
const uploadResultById = /* @__PURE__ */ new Map();
|
|
3166
3222
|
const failedSet = new Set(result.failed);
|
|
@@ -3176,9 +3232,15 @@ function ChatInput({
|
|
|
3176
3232
|
updatedAttachments = composerAttachments.map((a) => {
|
|
3177
3233
|
if (!uploadResultById.has(a.id)) return a;
|
|
3178
3234
|
const uploadedPath = uploadResultById.get(a.id);
|
|
3179
|
-
if (!uploadedPath) return { ...a, status: "failed" };
|
|
3235
|
+
if (!uploadedPath) return { ...a, status: "failed", uploadProgress: null };
|
|
3180
3236
|
const actualName = uploadedPath.split("/").pop() || a.name;
|
|
3181
|
-
return {
|
|
3237
|
+
return {
|
|
3238
|
+
...a,
|
|
3239
|
+
name: actualName,
|
|
3240
|
+
status: "uploaded",
|
|
3241
|
+
uploadedPath,
|
|
3242
|
+
uploadProgress: null
|
|
3243
|
+
};
|
|
3182
3244
|
});
|
|
3183
3245
|
setComposerAttachments(updatedAttachments);
|
|
3184
3246
|
if (result.uploaded.length > 0) {
|
|
@@ -3220,7 +3282,7 @@ function ChatInput({
|
|
|
3220
3282
|
const removeAttachment = (id) => {
|
|
3221
3283
|
setComposerAttachments((prev) => prev.filter((attachment) => attachment.id !== id));
|
|
3222
3284
|
};
|
|
3223
|
-
const [showAddContext, setShowAddContext] =
|
|
3285
|
+
const [showAddContext, setShowAddContext] = useState8(false);
|
|
3224
3286
|
const isPlanning = mode === "planning";
|
|
3225
3287
|
const placeholder = isPlanning ? "\u89C4\u5212\u8FDB\u884C\u4E2D\u2026 \u53EF\u8F93\u5165\u8865\u5145\u9700\u6C42\u6216\u7B49\u5F85\u5B8C\u6210" : "\u8F93\u5165\u6D88\u606F\u2026";
|
|
3226
3288
|
const attachments = renderAttachments?.() ?? null;
|
|
@@ -3238,10 +3300,11 @@ function ChatInput({
|
|
|
3238
3300
|
(attachment) => attachment.status === "uploading"
|
|
3239
3301
|
);
|
|
3240
3302
|
const hasValidAttachments = composerAttachments.some((attachment) => attachment.status !== "failed");
|
|
3241
|
-
const isSendDisabled = connectionStatus !== "connected" || hasUploadingFiles || !input.trim() && !hasValidAttachments && !hasRenderedAttachments && !hasPendingContexts;
|
|
3303
|
+
const isSendDisabled = connectionStatus !== "connected" || isModelLoading || !hasAvailableModel || hasUploadingFiles || !input.trim() && !hasValidAttachments && !hasRenderedAttachments && !hasPendingContexts;
|
|
3242
3304
|
return /* @__PURE__ */ jsxs8(Fragment2, { children: [
|
|
3243
3305
|
/* @__PURE__ */ jsx9("div", { className: `bg-[hsl(var(--background))] px-5 py-3 ${className ?? ""}`, children: /* @__PURE__ */ jsxs8("div", { className: `mx-auto ${maxWidthClassName} ${innerClassName ?? ""}`, children: [
|
|
3244
3306
|
activeSessionId ? /* @__PURE__ */ jsx9(BackgroundTasksPill, { sessionId: activeSessionId }) : null,
|
|
3307
|
+
!isModelLoading && !hasAvailableModel ? /* @__PURE__ */ jsx9("div", { className: "mb-2 rounded-lg border border-[hsl(var(--destructive))]/30 bg-[hsl(var(--destructive))]/8 px-3 py-2 text-xs text-[hsl(var(--destructive))]", children: "\u6CA1\u6709\u53EF\u7528\u6A21\u578B\uFF0C\u8BF7\u68C0\u67E5\u6A21\u578B\u670D\u52A1\u914D\u7F6E" }) : null,
|
|
3245
3308
|
/* @__PURE__ */ jsx9(
|
|
3246
3309
|
"div",
|
|
3247
3310
|
{
|
|
@@ -3596,10 +3659,11 @@ function ChatInput({
|
|
|
3596
3659
|
"button",
|
|
3597
3660
|
{
|
|
3598
3661
|
type: "button",
|
|
3599
|
-
onClick: onStop,
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3662
|
+
onClick: () => void onStop(),
|
|
3663
|
+
disabled: isStopping,
|
|
3664
|
+
"aria-label": isStopping ? "\u6B63\u5728\u505C\u6B62" : "\u505C\u6B62\u751F\u6210",
|
|
3665
|
+
className: "flex h-7 w-7 items-center justify-center rounded-lg bg-[hsl(var(--destructive))] text-[hsl(var(--destructive-foreground))] transition-opacity hover:opacity-80 disabled:cursor-wait disabled:opacity-70",
|
|
3666
|
+
children: isStopping ? /* @__PURE__ */ jsx9(Loader22, { size: 13, className: "animate-spin" }) : /* @__PURE__ */ jsx9(Square2, { size: 13 })
|
|
3603
3667
|
}
|
|
3604
3668
|
) : /* @__PURE__ */ jsx9(
|
|
3605
3669
|
"button",
|
|
@@ -3608,6 +3672,7 @@ function ChatInput({
|
|
|
3608
3672
|
onClick: handleSubmit,
|
|
3609
3673
|
disabled: isSendDisabled || isRecording,
|
|
3610
3674
|
"aria-label": "\u53D1\u9001\u6D88\u606F",
|
|
3675
|
+
title: isModelLoading ? "\u6B63\u5728\u52A0\u8F7D\u6A21\u578B\u914D\u7F6E" : !hasAvailableModel ? "\u6CA1\u6709\u53EF\u7528\u6A21\u578B\uFF0C\u8BF7\u68C0\u67E5\u6A21\u578B\u670D\u52A1\u914D\u7F6E" : "\u53D1\u9001\u6D88\u606F",
|
|
3611
3676
|
className: "flex h-7 w-7 items-center justify-center rounded-lg bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))] transition-opacity hover:opacity-80 disabled:opacity-25",
|
|
3612
3677
|
children: /* @__PURE__ */ jsx9(Send, { size: 13 })
|
|
3613
3678
|
}
|
|
@@ -3689,12 +3754,12 @@ import {
|
|
|
3689
3754
|
useEffect as useEffect16,
|
|
3690
3755
|
useEffectEvent as useEffectEvent4,
|
|
3691
3756
|
useMemo as useMemo17,
|
|
3692
|
-
useRef as
|
|
3693
|
-
useState as
|
|
3757
|
+
useRef as useRef12,
|
|
3758
|
+
useState as useState21
|
|
3694
3759
|
} from "react";
|
|
3695
3760
|
|
|
3696
3761
|
// ../../node_modules/.pnpm/use-stick-to-bottom@1.1.3_react@19.2.4/node_modules/use-stick-to-bottom/dist/useStickToBottom.js
|
|
3697
|
-
import { useCallback as useCallback7, useMemo as useMemo8, useRef as
|
|
3762
|
+
import { useCallback as useCallback7, useMemo as useMemo8, useRef as useRef6, useState as useState9 } from "react";
|
|
3698
3763
|
var DEFAULT_SPRING_ANIMATION = {
|
|
3699
3764
|
/**
|
|
3700
3765
|
* A value from 0 to 1, on how much to damp the animation.
|
|
@@ -3731,10 +3796,10 @@ globalThis.document?.addEventListener("click", () => {
|
|
|
3731
3796
|
mouseDown = false;
|
|
3732
3797
|
});
|
|
3733
3798
|
var useStickToBottom = (options = {}) => {
|
|
3734
|
-
const [escapedFromLock, updateEscapedFromLock] =
|
|
3735
|
-
const [isAtBottom, updateIsAtBottom] =
|
|
3736
|
-
const [isNearBottom, setIsNearBottom] =
|
|
3737
|
-
const optionsRef =
|
|
3799
|
+
const [escapedFromLock, updateEscapedFromLock] = useState9(false);
|
|
3800
|
+
const [isAtBottom, updateIsAtBottom] = useState9(options.initial !== false);
|
|
3801
|
+
const [isNearBottom, setIsNearBottom] = useState9(false);
|
|
3802
|
+
const optionsRef = useRef6(null);
|
|
3738
3803
|
optionsRef.current = options;
|
|
3739
3804
|
const isSelecting = useCallback7(() => {
|
|
3740
3805
|
if (!mouseDown) {
|
|
@@ -4038,11 +4103,11 @@ function mergeAnimations(...animations) {
|
|
|
4038
4103
|
|
|
4039
4104
|
// ../../node_modules/.pnpm/use-stick-to-bottom@1.1.3_react@19.2.4/node_modules/use-stick-to-bottom/dist/StickToBottom.js
|
|
4040
4105
|
import * as React from "react";
|
|
4041
|
-
import { createContext, useContext, useEffect as useEffect8, useImperativeHandle as useImperativeHandle3, useLayoutEffect, useMemo as useMemo9, useRef as
|
|
4106
|
+
import { createContext, useContext, useEffect as useEffect8, useImperativeHandle as useImperativeHandle3, useLayoutEffect, useMemo as useMemo9, useRef as useRef7 } from "react";
|
|
4042
4107
|
var StickToBottomContext = createContext(null);
|
|
4043
4108
|
var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect8;
|
|
4044
4109
|
function StickToBottom({ instance, children, resize, initial, mass, damping, stiffness, targetScrollTop: currentTargetScrollTop, contextRef, ...props }) {
|
|
4045
|
-
const customTargetScrollTop =
|
|
4110
|
+
const customTargetScrollTop = useRef7(null);
|
|
4046
4111
|
const targetScrollTop = React.useCallback((target, elements) => {
|
|
4047
4112
|
const get = context?.targetScrollTop ?? currentTargetScrollTop;
|
|
4048
4113
|
return get?.(target, elements) ?? target;
|
|
@@ -4119,7 +4184,7 @@ function useStickToBottomContext() {
|
|
|
4119
4184
|
|
|
4120
4185
|
// src/react/components/chat/AssistantTurnBlock.tsx
|
|
4121
4186
|
import { AlertCircle, BookOpen, Check as Check4, ChevronRight as ChevronRight5 } from "lucide-react";
|
|
4122
|
-
import { useCallback as useCallback11, useEffect as useEffect14, useMemo as useMemo15, useRef as
|
|
4187
|
+
import { useCallback as useCallback11, useEffect as useEffect14, useMemo as useMemo15, useRef as useRef11, useState as useState18 } from "react";
|
|
4123
4188
|
|
|
4124
4189
|
// src/react/routes.ts
|
|
4125
4190
|
var MEMORIES_ROUTE = "/memories";
|
|
@@ -4137,8 +4202,8 @@ import {
|
|
|
4137
4202
|
useContext as useContext2,
|
|
4138
4203
|
useEffect as useEffect9,
|
|
4139
4204
|
useMemo as useMemo11,
|
|
4140
|
-
useRef as
|
|
4141
|
-
useState as
|
|
4205
|
+
useRef as useRef8,
|
|
4206
|
+
useState as useState10
|
|
4142
4207
|
} from "react";
|
|
4143
4208
|
import { createPortal as createPortal2 } from "react-dom";
|
|
4144
4209
|
import { Streamdown } from "streamdown";
|
|
@@ -4205,7 +4270,6 @@ var useReasoning = () => {
|
|
|
4205
4270
|
}
|
|
4206
4271
|
return context;
|
|
4207
4272
|
};
|
|
4208
|
-
var AUTO_CLOSE_DELAY = 3e3;
|
|
4209
4273
|
var MS_IN_S = 1e3;
|
|
4210
4274
|
var Reasoning = memo2(
|
|
4211
4275
|
({
|
|
@@ -4218,10 +4282,8 @@ var Reasoning = memo2(
|
|
|
4218
4282
|
children,
|
|
4219
4283
|
...props
|
|
4220
4284
|
}) => {
|
|
4221
|
-
const resolvedDefaultOpen = defaultOpen ?? isStreaming;
|
|
4222
|
-
const isExplicitlyClosed = defaultOpen === false;
|
|
4223
4285
|
const [isOpen, setIsOpen] = useControllableState({
|
|
4224
|
-
defaultProp:
|
|
4286
|
+
defaultProp: defaultOpen ?? false,
|
|
4225
4287
|
onChange: onOpenChange,
|
|
4226
4288
|
prop: open
|
|
4227
4289
|
});
|
|
@@ -4229,12 +4291,9 @@ var Reasoning = memo2(
|
|
|
4229
4291
|
defaultProp: void 0,
|
|
4230
4292
|
prop: durationProp
|
|
4231
4293
|
});
|
|
4232
|
-
const
|
|
4233
|
-
const [hasAutoClosed, setHasAutoClosed] = useState9(false);
|
|
4234
|
-
const startTimeRef = useRef7(null);
|
|
4294
|
+
const startTimeRef = useRef8(null);
|
|
4235
4295
|
useEffect9(() => {
|
|
4236
4296
|
if (isStreaming) {
|
|
4237
|
-
hasEverStreamedRef.current = true;
|
|
4238
4297
|
if (startTimeRef.current === null) {
|
|
4239
4298
|
startTimeRef.current = Date.now();
|
|
4240
4299
|
}
|
|
@@ -4243,20 +4302,6 @@ var Reasoning = memo2(
|
|
|
4243
4302
|
startTimeRef.current = null;
|
|
4244
4303
|
}
|
|
4245
4304
|
}, [isStreaming, setDuration]);
|
|
4246
|
-
useEffect9(() => {
|
|
4247
|
-
if (isStreaming && !isOpen && !isExplicitlyClosed) {
|
|
4248
|
-
setIsOpen(true);
|
|
4249
|
-
}
|
|
4250
|
-
}, [isStreaming, isOpen, setIsOpen, isExplicitlyClosed]);
|
|
4251
|
-
useEffect9(() => {
|
|
4252
|
-
if (hasEverStreamedRef.current && !isStreaming && isOpen && !hasAutoClosed) {
|
|
4253
|
-
const timer = setTimeout(() => {
|
|
4254
|
-
setIsOpen(false);
|
|
4255
|
-
setHasAutoClosed(true);
|
|
4256
|
-
}, AUTO_CLOSE_DELAY);
|
|
4257
|
-
return () => clearTimeout(timer);
|
|
4258
|
-
}
|
|
4259
|
-
}, [isStreaming, isOpen, setIsOpen, hasAutoClosed]);
|
|
4260
4305
|
const handleOpenChange = useCallback9(
|
|
4261
4306
|
(newOpen) => {
|
|
4262
4307
|
setIsOpen(newOpen);
|
|
@@ -4270,7 +4315,7 @@ var Reasoning = memo2(
|
|
|
4270
4315
|
return /* @__PURE__ */ jsx12(ReasoningContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx12(
|
|
4271
4316
|
Collapsible,
|
|
4272
4317
|
{
|
|
4273
|
-
className: cn("not-prose
|
|
4318
|
+
className: cn("not-prose", className),
|
|
4274
4319
|
onOpenChange: handleOpenChange,
|
|
4275
4320
|
open: isOpen,
|
|
4276
4321
|
...props,
|
|
@@ -4279,38 +4324,36 @@ var Reasoning = memo2(
|
|
|
4279
4324
|
) });
|
|
4280
4325
|
}
|
|
4281
4326
|
);
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
}
|
|
4286
|
-
if (duration === void 0) {
|
|
4287
|
-
return /* @__PURE__ */ jsx12("p", { children: "\u5DF2\u6DF1\u5EA6\u601D\u8003" });
|
|
4288
|
-
}
|
|
4289
|
-
return /* @__PURE__ */ jsxs10("p", { children: [
|
|
4290
|
-
"\u5DF2\u6DF1\u5EA6\u601D\u8003 ",
|
|
4291
|
-
duration,
|
|
4292
|
-
" \u79D2"
|
|
4293
|
-
] });
|
|
4294
|
-
};
|
|
4327
|
+
function formatWordCount(value) {
|
|
4328
|
+
return new Intl.NumberFormat("zh-CN").format(value);
|
|
4329
|
+
}
|
|
4295
4330
|
var ReasoningTrigger = memo2(
|
|
4296
4331
|
({
|
|
4297
4332
|
className,
|
|
4298
4333
|
children,
|
|
4299
|
-
|
|
4334
|
+
wordCount,
|
|
4300
4335
|
...props
|
|
4301
4336
|
}) => {
|
|
4302
4337
|
const { isStreaming, isOpen, duration } = useReasoning();
|
|
4338
|
+
const status = isStreaming || duration === 0 ? "\u6B63\u5728\u601D\u8003" : "\u5DF2\u601D\u8003";
|
|
4339
|
+
const detail = `${formatWordCount(wordCount)} \u5B57`;
|
|
4303
4340
|
return /* @__PURE__ */ jsx12(
|
|
4304
4341
|
CollapsibleTrigger,
|
|
4305
4342
|
{
|
|
4306
4343
|
className: cn(
|
|
4307
|
-
"flex w-
|
|
4344
|
+
"flex w-fit items-center gap-2 rounded-full px-1 py-0.5 text-muted-foreground text-sm transition-colors hover:text-foreground",
|
|
4308
4345
|
className
|
|
4309
4346
|
),
|
|
4310
4347
|
...props,
|
|
4311
4348
|
children: children ?? /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
4312
4349
|
/* @__PURE__ */ jsx12(BrainIcon, { className: "size-4" }),
|
|
4313
|
-
|
|
4350
|
+
/* @__PURE__ */ jsxs10("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
4351
|
+
isStreaming || duration === 0 ? /* @__PURE__ */ jsx12(Shimmer, { duration: 1, children: status }) : /* @__PURE__ */ jsx12("span", { children: status }),
|
|
4352
|
+
/* @__PURE__ */ jsxs10("span", { className: "text-[hsl(var(--muted-foreground))]/70", children: [
|
|
4353
|
+
"\xB7 ",
|
|
4354
|
+
detail
|
|
4355
|
+
] })
|
|
4356
|
+
] }),
|
|
4314
4357
|
/* @__PURE__ */ jsx12(
|
|
4315
4358
|
ChevronDownIcon,
|
|
4316
4359
|
{
|
|
@@ -4332,7 +4375,7 @@ var ReasoningContent = memo2(
|
|
|
4332
4375
|
CollapsibleContent,
|
|
4333
4376
|
{
|
|
4334
4377
|
className: cn(
|
|
4335
|
-
"mt-
|
|
4378
|
+
"mt-2 max-h-60 overflow-auto rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))]/20 px-3 py-2 text-sm",
|
|
4336
4379
|
"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-muted-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in",
|
|
4337
4380
|
className
|
|
4338
4381
|
),
|
|
@@ -4346,7 +4389,7 @@ function compactReasoningText(text) {
|
|
|
4346
4389
|
}
|
|
4347
4390
|
function ThinkingBadge({ reasoning, variant = "inline", onClick }) {
|
|
4348
4391
|
const compactReasoning = compactReasoningText(reasoning);
|
|
4349
|
-
const [open, setOpen] =
|
|
4392
|
+
const [open, setOpen] = useState10(false);
|
|
4350
4393
|
return /* @__PURE__ */ jsxs10(
|
|
4351
4394
|
"span",
|
|
4352
4395
|
{
|
|
@@ -4423,10 +4466,10 @@ ReasoningContent.displayName = "ReasoningContent";
|
|
|
4423
4466
|
|
|
4424
4467
|
// src/react/components/chat/AgentLoopBlock.tsx
|
|
4425
4468
|
import { Bot, Check as Check3, ChevronRight as ChevronRight4, FileText as FileText6, Loader2 as Loader24, MessageSquareMore as MessageSquareMore2 } from "lucide-react";
|
|
4426
|
-
import { useEffect as useEffect13, useMemo as useMemo14, useState as
|
|
4469
|
+
import { useEffect as useEffect13, useMemo as useMemo14, useState as useState17 } from "react";
|
|
4427
4470
|
|
|
4428
4471
|
// src/react/components/chat/ResourceIframe.tsx
|
|
4429
|
-
import { useEffect as useEffect10, useEffectEvent as useEffectEvent3, useRef as
|
|
4472
|
+
import { useEffect as useEffect10, useEffectEvent as useEffectEvent3, useRef as useRef9, useState as useState11 } from "react";
|
|
4430
4473
|
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
4431
4474
|
function isResourceBridgeMessage(value) {
|
|
4432
4475
|
return typeof value === "object" && value !== null && value.__resourceBridge === true && typeof value.action === "string";
|
|
@@ -4435,8 +4478,8 @@ var INLINE_HEIGHT_MIN = 80;
|
|
|
4435
4478
|
var INLINE_HEIGHT_MAX = 6e3;
|
|
4436
4479
|
var INLINE_HEIGHT_PADDING = 8;
|
|
4437
4480
|
function ResourceIframe({ ui, sessionId }) {
|
|
4438
|
-
const iframeRef =
|
|
4439
|
-
const iframeKeyRef =
|
|
4481
|
+
const iframeRef = useRef9(null);
|
|
4482
|
+
const iframeKeyRef = useRef9(
|
|
4440
4483
|
`iframe-${Math.random().toString(36).slice(2, 10)}`
|
|
4441
4484
|
);
|
|
4442
4485
|
const activeSessionId = useSessionStore((state) => state.activeSessionId);
|
|
@@ -4444,7 +4487,7 @@ function ResourceIframe({ ui, sessionId }) {
|
|
|
4444
4487
|
const theme = useUiStore((state) => state.theme);
|
|
4445
4488
|
const resourceUri = ui.resourceUri ?? ui.resourceURI;
|
|
4446
4489
|
const iframeLabel = ui.title ?? resourceUri ?? "\u5DE5\u5177\u754C\u9762";
|
|
4447
|
-
const [autoHeight, setAutoHeight] =
|
|
4490
|
+
const [autoHeight, setAutoHeight] = useState11(null);
|
|
4448
4491
|
useEffect10(() => {
|
|
4449
4492
|
setAutoHeight(null);
|
|
4450
4493
|
}, [ui.resourceHTML, resourceUri]);
|
|
@@ -4555,7 +4598,7 @@ function ResourceIframe({ ui, sessionId }) {
|
|
|
4555
4598
|
|
|
4556
4599
|
// src/react/components/chat/ToolCallBlock.tsx
|
|
4557
4600
|
import { Check, ChevronRight as ChevronRight3, Loader2 as Loader23, MessageSquareMore, PanelRightOpen, X as X4 } from "lucide-react";
|
|
4558
|
-
import { useMemo as useMemo12, useState as
|
|
4601
|
+
import { useMemo as useMemo12, useState as useState14 } from "react";
|
|
4559
4602
|
|
|
4560
4603
|
// src/react/components/chat/tool-renderers/shared.tsx
|
|
4561
4604
|
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
@@ -4882,21 +4925,21 @@ function FileEditRenderer({ toolCall }) {
|
|
|
4882
4925
|
}
|
|
4883
4926
|
|
|
4884
4927
|
// src/react/components/chat/tool-renderers/FileReadRenderer.tsx
|
|
4885
|
-
import { useState as
|
|
4928
|
+
import { useState as useState13 } from "react";
|
|
4886
4929
|
|
|
4887
4930
|
// src/react/components/chat/ImageLightbox.tsx
|
|
4888
4931
|
import { ChevronLeft, ChevronRight as ChevronRight2, Download as Download2, ExternalLink, Minus, Plus as Plus2, RotateCcw, X as X3 } from "lucide-react";
|
|
4889
|
-
import { useCallback as useCallback10, useEffect as useEffect11, useRef as
|
|
4932
|
+
import { useCallback as useCallback10, useEffect as useEffect11, useRef as useRef10, useState as useState12 } from "react";
|
|
4890
4933
|
import { createPortal as createPortal3 } from "react-dom";
|
|
4891
4934
|
import { Fragment as Fragment4, jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
4892
4935
|
function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
|
|
4893
|
-
const [currentIndex, setCurrentIndex] =
|
|
4894
|
-
const [scale, setScale] =
|
|
4895
|
-
const [translate, setTranslate] =
|
|
4896
|
-
const dragging =
|
|
4897
|
-
const dragStart =
|
|
4898
|
-
const translateStart =
|
|
4899
|
-
const imgRef =
|
|
4936
|
+
const [currentIndex, setCurrentIndex] = useState12(initialIndex);
|
|
4937
|
+
const [scale, setScale] = useState12(1);
|
|
4938
|
+
const [translate, setTranslate] = useState12({ x: 0, y: 0 });
|
|
4939
|
+
const dragging = useRef10(false);
|
|
4940
|
+
const dragStart = useRef10({ x: 0, y: 0 });
|
|
4941
|
+
const translateStart = useRef10({ x: 0, y: 0 });
|
|
4942
|
+
const imgRef = useRef10(null);
|
|
4900
4943
|
const reset = useCallback10(() => {
|
|
4901
4944
|
setScale(1);
|
|
4902
4945
|
setTranslate({ x: 0, y: 0 });
|
|
@@ -4915,7 +4958,7 @@ function ImageLightbox({ open, onOpenChange, images, initialIndex = 0 }) {
|
|
|
4915
4958
|
setCurrentIndex((i) => Math.min(images.length - 1, i + 1));
|
|
4916
4959
|
reset();
|
|
4917
4960
|
}, [images.length, reset]);
|
|
4918
|
-
const prevOpenRef =
|
|
4961
|
+
const prevOpenRef = useRef10(false);
|
|
4919
4962
|
useEffect11(() => {
|
|
4920
4963
|
if (open && !prevOpenRef.current) {
|
|
4921
4964
|
setCurrentIndex(initialIndex);
|
|
@@ -5205,7 +5248,7 @@ function formatLineRange(startLine, endLine) {
|
|
|
5205
5248
|
return startLine === endLine ? `\u7B2C ${startLine} \u884C` : `\u7B2C ${startLine}-${endLine} \u884C`;
|
|
5206
5249
|
}
|
|
5207
5250
|
function FileReadRenderer({ toolCall }) {
|
|
5208
|
-
const [lightboxIndex, setLightboxIndex] =
|
|
5251
|
+
const [lightboxIndex, setLightboxIndex] = useState13(null);
|
|
5209
5252
|
const argsValue = parseJsonValue(toolCall.arguments);
|
|
5210
5253
|
const args = isPlainObject(argsValue) ? argsValue : null;
|
|
5211
5254
|
const filePath = extractToolFilePath(toolCall);
|
|
@@ -5503,7 +5546,7 @@ function ToolCallBlock({
|
|
|
5503
5546
|
reasoning,
|
|
5504
5547
|
customization
|
|
5505
5548
|
}) {
|
|
5506
|
-
const [expanded, setExpanded] =
|
|
5549
|
+
const [expanded, setExpanded] = useState14(false);
|
|
5507
5550
|
const activeSessionId = useSessionStore((s) => s.activeSessionId);
|
|
5508
5551
|
const sessions = useSessionStore((s) => s.sessions);
|
|
5509
5552
|
const pushArtifact = useUiStore((s) => s.pushArtifact);
|
|
@@ -5707,7 +5750,7 @@ function buildAskUserPayload(argumentsJson) {
|
|
|
5707
5750
|
}
|
|
5708
5751
|
|
|
5709
5752
|
// src/react/components/chat/UserMessageBubble.tsx
|
|
5710
|
-
import { useState as
|
|
5753
|
+
import { useState as useState16 } from "react";
|
|
5711
5754
|
|
|
5712
5755
|
// src/react/lib/preview-dispatch.ts
|
|
5713
5756
|
var IMAGE_EXTS = [
|
|
@@ -6040,10 +6083,10 @@ function MessageFileAttachmentList({
|
|
|
6040
6083
|
|
|
6041
6084
|
// src/react/components/chat/MessageActions.tsx
|
|
6042
6085
|
import { Check as Check2, Copy } from "lucide-react";
|
|
6043
|
-
import { useState as
|
|
6086
|
+
import { useState as useState15 } from "react";
|
|
6044
6087
|
import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
6045
6088
|
function MessageActions({ content, className }) {
|
|
6046
|
-
const [copied, setCopied] =
|
|
6089
|
+
const [copied, setCopied] = useState15(false);
|
|
6047
6090
|
const handleCopy = async () => {
|
|
6048
6091
|
const ok = await copyToClipboard(content);
|
|
6049
6092
|
if (ok) {
|
|
@@ -6233,8 +6276,8 @@ function UserMessageBubble({ message, className }) {
|
|
|
6233
6276
|
alt: attachment.name || "\u7528\u6237\u4E0A\u4F20\u7684\u56FE\u7247"
|
|
6234
6277
|
}))
|
|
6235
6278
|
];
|
|
6236
|
-
const [lightboxIndex, setLightboxIndex] =
|
|
6237
|
-
const [preview, setPreview] =
|
|
6279
|
+
const [lightboxIndex, setLightboxIndex] = useState16(null);
|
|
6280
|
+
const [preview, setPreview] = useState16(null);
|
|
6238
6281
|
const handleTextAttachmentPreview = (attachment) => {
|
|
6239
6282
|
if (!activeSessionId) return;
|
|
6240
6283
|
const pathForUrl = attachment.uploadedPath ?? attachment.name;
|
|
@@ -6401,7 +6444,7 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
|
|
|
6401
6444
|
() => visibleLoopToolCalls.some((childToolCall) => childToolCall.status === "awaiting_answer"),
|
|
6402
6445
|
[visibleLoopToolCalls]
|
|
6403
6446
|
);
|
|
6404
|
-
const [expanded, setExpanded] =
|
|
6447
|
+
const [expanded, setExpanded] = useState17(hasAwaitingAnswer);
|
|
6405
6448
|
const completedToolLabels = useMemo14(
|
|
6406
6449
|
() => visibleLoopToolCalls.flatMap((childToolCall) => {
|
|
6407
6450
|
const isCompleted = childToolCall.status === "done" || childToolCall.status !== "pending" && childToolCall.status !== "awaiting_answer" && childToolCall.status !== "error" && childToolCall.status !== "cancelled";
|
|
@@ -6653,12 +6696,9 @@ function ExpandedChildAssistantMessage({
|
|
|
6653
6696
|
const text = typeof message.content === "string" ? message.content.trim() : message.content.filter((part) => part.type === "text").map((part) => part.text).join("").trim();
|
|
6654
6697
|
const toolCalls = message.tool_calls ?? [];
|
|
6655
6698
|
const hasToolCalls = toolCalls.length > 0;
|
|
6656
|
-
const firstToolCallId = toolCalls[0]?.id;
|
|
6657
|
-
const toolReasoning = !isStreaming && !text && hasToolCalls ? message.reasoning : void 0;
|
|
6658
|
-
const standaloneReasoning = !isStreaming && !text && !hasToolCalls ? message.reasoning : void 0;
|
|
6659
6699
|
return /* @__PURE__ */ jsxs24("div", { className: "flex flex-col gap-2", children: [
|
|
6660
|
-
message.reasoning &&
|
|
6661
|
-
/* @__PURE__ */ jsx29(ReasoningTrigger, {}),
|
|
6700
|
+
message.reasoning && /* @__PURE__ */ jsxs24(Reasoning, { isStreaming, children: [
|
|
6701
|
+
/* @__PURE__ */ jsx29(ReasoningTrigger, { wordCount: message.reasoning.length }),
|
|
6662
6702
|
/* @__PURE__ */ jsx29(ReasoningContent, { children: message.reasoning })
|
|
6663
6703
|
] }),
|
|
6664
6704
|
text ? /* @__PURE__ */ jsx29(
|
|
@@ -6667,18 +6707,17 @@ function ExpandedChildAssistantMessage({
|
|
|
6667
6707
|
text,
|
|
6668
6708
|
isStreaming,
|
|
6669
6709
|
sessionId,
|
|
6670
|
-
reasoning:
|
|
6710
|
+
reasoning: void 0
|
|
6671
6711
|
}
|
|
6672
6712
|
) : null,
|
|
6673
6713
|
!text && isStreaming && /* @__PURE__ */ jsx29("span", { className: "pl-8 text-[12px] text-[hsl(var(--muted-foreground))]", children: "\u6B63\u5728\u751F\u6210..." }),
|
|
6674
|
-
standaloneReasoning ? /* @__PURE__ */ jsx29("div", { className: "pl-8", children: /* @__PURE__ */ jsx29(ThinkingBadge, { reasoning: standaloneReasoning, variant: "block" }) }) : null,
|
|
6675
6714
|
hasToolCalls && /* @__PURE__ */ jsx29("div", { className: "flex flex-col gap-2", children: toolCalls.map(
|
|
6676
|
-
(toolCall
|
|
6715
|
+
(toolCall) => formatToolName(toolCall.name) === "Agent" ? /* @__PURE__ */ jsx29(
|
|
6677
6716
|
AgentLoopBlock,
|
|
6678
6717
|
{
|
|
6679
6718
|
toolCall,
|
|
6680
6719
|
sessionId,
|
|
6681
|
-
reasoning:
|
|
6720
|
+
reasoning: void 0
|
|
6682
6721
|
},
|
|
6683
6722
|
toolCall.id
|
|
6684
6723
|
) : /* @__PURE__ */ jsx29(
|
|
@@ -6688,7 +6727,7 @@ function ExpandedChildAssistantMessage({
|
|
|
6688
6727
|
sessionId,
|
|
6689
6728
|
level: 2,
|
|
6690
6729
|
turnBlocks: message.blocks,
|
|
6691
|
-
reasoning:
|
|
6730
|
+
reasoning: void 0
|
|
6692
6731
|
},
|
|
6693
6732
|
toolCall.id
|
|
6694
6733
|
)
|
|
@@ -6910,10 +6949,10 @@ function AssistantTurnBlock({
|
|
|
6910
6949
|
),
|
|
6911
6950
|
[allToolCalls]
|
|
6912
6951
|
);
|
|
6913
|
-
const [displayMode, setDisplayMode] =
|
|
6952
|
+
const [displayMode, setDisplayMode] = useState18(
|
|
6914
6953
|
defaultTurnDisplayMode({ forceExpanded, hasActionableToolCall })
|
|
6915
6954
|
);
|
|
6916
|
-
const wasStreamingRef =
|
|
6955
|
+
const wasStreamingRef = useRef11(isStreaming);
|
|
6917
6956
|
useEffect14(() => {
|
|
6918
6957
|
if (wasStreamingRef.current && !isStreaming && !forceExpanded) {
|
|
6919
6958
|
setDisplayMode(defaultTurnDisplayMode({ forceExpanded, hasActionableToolCall }));
|
|
@@ -7012,23 +7051,18 @@ function AssistantMessages({
|
|
|
7012
7051
|
return messages.map(
|
|
7013
7052
|
(message, index) => isRenderableAssistantMessage(message, isStreaming && index === messages.length - 1) ? (() => {
|
|
7014
7053
|
const isStreamingLastMessage = isStreaming && index === messages.length - 1;
|
|
7015
|
-
const hasText = !!getMessageText(message);
|
|
7016
7054
|
const reasoning = message.reasoning;
|
|
7017
7055
|
const hasReasoning = !!reasoning;
|
|
7018
|
-
const hasAttachments = getImageParts(message.content).length > 0 || getFileParts(message.content).length > 0;
|
|
7019
7056
|
const toolCalls = message.tool_calls ?? [];
|
|
7020
7057
|
const hasToolCalls = toolCalls.length > 0;
|
|
7021
|
-
const firstToolCallId = toolCalls[0]?.id;
|
|
7022
7058
|
const toolRenderItems = groupDetailedToolCalls(toolCalls);
|
|
7023
|
-
const toolReasoning = hasReasoning && !hasText && !hasAttachments && hasToolCalls && !isStreamingLastMessage ? reasoning : void 0;
|
|
7024
|
-
const contentReasoning = hasReasoning && !isStreamingLastMessage && (hasText || hasAttachments || !hasToolCalls) ? reasoning : void 0;
|
|
7025
7059
|
return /* @__PURE__ */ jsxs25(
|
|
7026
7060
|
"div",
|
|
7027
7061
|
{
|
|
7028
7062
|
className: "flex flex-col gap-3",
|
|
7029
7063
|
children: [
|
|
7030
|
-
hasReasoning &&
|
|
7031
|
-
/* @__PURE__ */ jsx30(ReasoningTrigger, {}),
|
|
7064
|
+
hasReasoning && /* @__PURE__ */ jsxs25(Reasoning, { isStreaming: isStreamingLastMessage, children: [
|
|
7065
|
+
/* @__PURE__ */ jsx30(ReasoningTrigger, { wordCount: reasoning.length }),
|
|
7032
7066
|
/* @__PURE__ */ jsx30(ReasoningContent, { children: reasoning })
|
|
7033
7067
|
] }),
|
|
7034
7068
|
/* @__PURE__ */ jsx30(
|
|
@@ -7037,7 +7071,7 @@ function AssistantMessages({
|
|
|
7037
7071
|
message,
|
|
7038
7072
|
isStreaming: isStreamingLastMessage,
|
|
7039
7073
|
sessionId,
|
|
7040
|
-
reasoning:
|
|
7074
|
+
reasoning: void 0,
|
|
7041
7075
|
className: customization?.classNames?.assistantText
|
|
7042
7076
|
}
|
|
7043
7077
|
),
|
|
@@ -7048,7 +7082,7 @@ function AssistantMessages({
|
|
|
7048
7082
|
{
|
|
7049
7083
|
toolCalls: item.toolCalls,
|
|
7050
7084
|
kind: item.kind,
|
|
7051
|
-
reasoning:
|
|
7085
|
+
reasoning: void 0,
|
|
7052
7086
|
sessionId,
|
|
7053
7087
|
sessionStatus,
|
|
7054
7088
|
askAnswers,
|
|
@@ -7066,7 +7100,7 @@ function AssistantMessages({
|
|
|
7066
7100
|
{
|
|
7067
7101
|
toolCall,
|
|
7068
7102
|
sessionId,
|
|
7069
|
-
reasoning:
|
|
7103
|
+
reasoning: void 0
|
|
7070
7104
|
},
|
|
7071
7105
|
toolCall.id
|
|
7072
7106
|
) : customization?.components?.ToolCall ? /* @__PURE__ */ jsx30(
|
|
@@ -7080,7 +7114,7 @@ function AssistantMessages({
|
|
|
7080
7114
|
sessionStatus,
|
|
7081
7115
|
level,
|
|
7082
7116
|
turnBlocks: message.blocks,
|
|
7083
|
-
reasoning:
|
|
7117
|
+
reasoning: void 0,
|
|
7084
7118
|
customization
|
|
7085
7119
|
},
|
|
7086
7120
|
toolCall.id
|
|
@@ -7095,7 +7129,7 @@ function AssistantMessages({
|
|
|
7095
7129
|
sessionStatus,
|
|
7096
7130
|
level,
|
|
7097
7131
|
turnBlocks: message.blocks,
|
|
7098
|
-
reasoning:
|
|
7132
|
+
reasoning: void 0,
|
|
7099
7133
|
customization
|
|
7100
7134
|
},
|
|
7101
7135
|
toolCall.id
|
|
@@ -7137,7 +7171,7 @@ function CompactToolGroupBlock({
|
|
|
7137
7171
|
level,
|
|
7138
7172
|
customization
|
|
7139
7173
|
}) {
|
|
7140
|
-
const [expanded, setExpanded] =
|
|
7174
|
+
const [expanded, setExpanded] = useState18(false);
|
|
7141
7175
|
const indentClass = level === 2 ? "ml-3" : "ml-4";
|
|
7142
7176
|
const hasError = toolCalls.some(
|
|
7143
7177
|
(tc) => tc.status === "error" || tc.status === "cancelled"
|
|
@@ -7303,7 +7337,7 @@ function AssistantText({
|
|
|
7303
7337
|
}
|
|
7304
7338
|
function MemoryRefsHint({ refs: rawRefs }) {
|
|
7305
7339
|
const refs = Array.isArray(rawRefs) ? rawRefs : [];
|
|
7306
|
-
const [expanded, setExpanded] =
|
|
7340
|
+
const [expanded, setExpanded] = useState18(false);
|
|
7307
7341
|
const hasSkill = refs.some((r3) => r3.skill_name);
|
|
7308
7342
|
const label = hasSkill ? "\u53C2\u8003\u4E86\u8BE5\u6280\u80FD\u7684\u5386\u53F2\u7ECF\u9A8C" : "\u53C2\u8003\u4E86\u5386\u53F2\u7ECF\u9A8C";
|
|
7309
7343
|
return /* @__PURE__ */ jsxs25("div", { className: "ml-4", children: [
|
|
@@ -7351,7 +7385,7 @@ function MemoryRefsHint({ refs: rawRefs }) {
|
|
|
7351
7385
|
|
|
7352
7386
|
// src/react/components/chat/CompactionCard.tsx
|
|
7353
7387
|
import { ChevronDown as ChevronDown2, ChevronRight as ChevronRight6, Loader2 as Loader25, Square as Square3, XCircle } from "lucide-react";
|
|
7354
|
-
import { useState as
|
|
7388
|
+
import { useState as useState19 } from "react";
|
|
7355
7389
|
import { jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
7356
7390
|
var PERCENT_FORMATTER = new Intl.NumberFormat("zh-CN", {
|
|
7357
7391
|
style: "percent",
|
|
@@ -7411,7 +7445,7 @@ function CompactionCard({
|
|
|
7411
7445
|
...compaction,
|
|
7412
7446
|
status: status ?? "completed"
|
|
7413
7447
|
} : activeCompaction;
|
|
7414
|
-
const [expanded, setExpanded] =
|
|
7448
|
+
const [expanded, setExpanded] = useState19(false);
|
|
7415
7449
|
if (!source || !source.compaction_id) {
|
|
7416
7450
|
return null;
|
|
7417
7451
|
}
|
|
@@ -7453,7 +7487,7 @@ function CompactionCard({
|
|
|
7453
7487
|
"button",
|
|
7454
7488
|
{
|
|
7455
7489
|
type: "button",
|
|
7456
|
-
onClick: () => getSocket().stop(sessionId),
|
|
7490
|
+
onClick: () => void getSocket().stop(sessionId),
|
|
7457
7491
|
className: "shrink-0 rounded-md border border-current/15 px-2 py-0.5 text-[11px] transition-opacity hover:opacity-80",
|
|
7458
7492
|
children: "\u53D6\u6D88\u6574\u7406"
|
|
7459
7493
|
}
|
|
@@ -7572,7 +7606,7 @@ import {
|
|
|
7572
7606
|
TerminalSquare,
|
|
7573
7607
|
WandSparkles
|
|
7574
7608
|
} from "lucide-react";
|
|
7575
|
-
import { useEffect as useEffect15, useMemo as useMemo16, useState as
|
|
7609
|
+
import { useEffect as useEffect15, useMemo as useMemo16, useState as useState20 } from "react";
|
|
7576
7610
|
import { jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
7577
7611
|
var EMPTY_EVENTS = [];
|
|
7578
7612
|
function formatElapsedDuration(durationMs) {
|
|
@@ -7651,7 +7685,7 @@ function getTurnStartedAt(events) {
|
|
|
7651
7685
|
return null;
|
|
7652
7686
|
}
|
|
7653
7687
|
function useElapsedDuration(startedAt, active) {
|
|
7654
|
-
const [now, setNow] =
|
|
7688
|
+
const [now, setNow] = useState20(() => Date.now());
|
|
7655
7689
|
useEffect15(() => {
|
|
7656
7690
|
if (!active || startedAt == null) {
|
|
7657
7691
|
return;
|
|
@@ -7943,10 +7977,10 @@ function MessageList({
|
|
|
7943
7977
|
) ?? null,
|
|
7944
7978
|
[lastTurnId, renderBlocks]
|
|
7945
7979
|
);
|
|
7946
|
-
const containerRef =
|
|
7947
|
-
const scrollContainerRef =
|
|
7948
|
-
const frameRef =
|
|
7949
|
-
const [activeTurnId, setActiveTurnId] =
|
|
7980
|
+
const containerRef = useRef12(null);
|
|
7981
|
+
const scrollContainerRef = useRef12(null);
|
|
7982
|
+
const frameRef = useRef12(null);
|
|
7983
|
+
const [activeTurnId, setActiveTurnId] = useState21(lastTurnId);
|
|
7950
7984
|
const layoutSignature = useMemo17(
|
|
7951
7985
|
() => getMessagesMeasureSignature(messages),
|
|
7952
7986
|
[messages]
|
|
@@ -8244,6 +8278,7 @@ function ChatView({
|
|
|
8244
8278
|
const {
|
|
8245
8279
|
messages,
|
|
8246
8280
|
isStreaming,
|
|
8281
|
+
isStopping,
|
|
8247
8282
|
send,
|
|
8248
8283
|
stop
|
|
8249
8284
|
} = useChat(sessionId);
|
|
@@ -8291,6 +8326,7 @@ function ChatView({
|
|
|
8291
8326
|
onSend: (msg, _targetSessionId, model) => send(msg, mode, void 0, { model: model || void 0 }),
|
|
8292
8327
|
onStop: stop,
|
|
8293
8328
|
isStreaming,
|
|
8329
|
+
isStopping,
|
|
8294
8330
|
mode,
|
|
8295
8331
|
onToggleMode: toggleMode,
|
|
8296
8332
|
renderAttachments,
|
|
@@ -8360,4 +8396,4 @@ use-stick-to-bottom/dist/StickToBottom.js:
|
|
|
8360
8396
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
8361
8397
|
*--------------------------------------------------------------------------------------------*)
|
|
8362
8398
|
*/
|
|
8363
|
-
//# sourceMappingURL=chunk-
|
|
8399
|
+
//# sourceMappingURL=chunk-S6EPGDAL.js.map
|