@blade-hq/agent-kit 0.5.6 → 0.5.10
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-CvNCQRtt.d.ts → SkillStatusBar-Dlf-_G5d.d.ts} +2 -2
- package/dist/{blade-client-B6xMtRwr.d.ts → blade-client-7VANnJfr.d.ts} +5 -1
- package/dist/{chunk-CBO2A567.js → chunk-ETHPRRT2.js} +9 -1
- package/dist/chunk-ETHPRRT2.js.map +1 -0
- package/dist/{chunk-VPWN6VS4.js → chunk-G2LJZTPX.js} +178 -93
- package/dist/chunk-G2LJZTPX.js.map +1 -0
- package/dist/{chunk-PX53WJ2C.js → chunk-GIE2Q2MB.js} +28 -16
- package/dist/chunk-GIE2Q2MB.js.map +1 -0
- package/dist/{chunk-T3G4VHAM.js → chunk-STCTXRMJ.js} +2 -2
- package/dist/{chunk-D7IT5PRL.js → chunk-UM7G65GH.js} +116 -20
- package/dist/chunk-UM7G65GH.js.map +1 -0
- package/dist/{chunk-NOUG4L43.js → chunk-X3S36RR2.js} +2 -2
- package/dist/client/index.d.ts +1051 -17
- package/dist/client/index.js +1 -1
- package/dist/react/api/vibe-coding.d.ts +3 -3
- package/dist/react/api/vibe-coding.js +2 -2
- package/dist/react/components/chat/index.d.ts +6 -5
- package/dist/react/components/chat/index.js +5 -5
- package/dist/react/components/plan/index.js +3 -3
- package/dist/react/components/session/index.d.ts +1 -1
- package/dist/react/components/session/index.js +3 -3
- package/dist/react/components/workspace/index.js +3 -3
- package/dist/react/index.d.ts +177 -8
- package/dist/react/index.js +469 -6
- package/dist/react/index.js.map +1 -1
- package/dist/{session-ADRevzHD.d.ts → session-BuaeCsMC.d.ts} +62 -2
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/dist/chunk-CBO2A567.js.map +0 -1
- package/dist/chunk-D7IT5PRL.js.map +0 -1
- package/dist/chunk-PX53WJ2C.js.map +0 -1
- package/dist/chunk-VPWN6VS4.js.map +0 -1
- /package/dist/{chunk-T3G4VHAM.js.map → chunk-STCTXRMJ.js.map} +0 -0
- /package/dist/{chunk-NOUG4L43.js.map → chunk-X3S36RR2.js.map} +0 -0
|
@@ -8,14 +8,15 @@ import {
|
|
|
8
8
|
getCodeLanguageFromFilename,
|
|
9
9
|
parseAskUserQuestion,
|
|
10
10
|
useHighlightedCodeHtml
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-GIE2Q2MB.js";
|
|
12
12
|
import {
|
|
13
13
|
Collapsible,
|
|
14
14
|
CollapsibleContent,
|
|
15
15
|
CollapsibleTrigger,
|
|
16
16
|
resolveSessionFilePreviewTarget
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-X3S36RR2.js";
|
|
18
18
|
import {
|
|
19
|
+
apiFetchResponse,
|
|
19
20
|
buildMessageContent,
|
|
20
21
|
buildToolPreviewKey,
|
|
21
22
|
contentPreview,
|
|
@@ -57,7 +58,7 @@ import {
|
|
|
57
58
|
useUiBridgeStore,
|
|
58
59
|
useUiStore,
|
|
59
60
|
writeFile
|
|
60
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-UM7G65GH.js";
|
|
61
62
|
import {
|
|
62
63
|
registerBridgeIframe,
|
|
63
64
|
tapBridgeEvent
|
|
@@ -66,7 +67,7 @@ import {
|
|
|
66
67
|
ModelOption,
|
|
67
68
|
ModelsConfig,
|
|
68
69
|
ModelsResource
|
|
69
|
-
} from "./chunk-
|
|
70
|
+
} from "./chunk-ETHPRRT2.js";
|
|
70
71
|
import {
|
|
71
72
|
cn,
|
|
72
73
|
copyToClipboard
|
|
@@ -77,7 +78,7 @@ import {
|
|
|
77
78
|
|
|
78
79
|
// src/react/components/chat/ChatView.tsx
|
|
79
80
|
import { Eye } from "lucide-react";
|
|
80
|
-
import { useCallback as useCallback13 } from "react";
|
|
81
|
+
import { useCallback as useCallback13, useMemo as useMemo18 } from "react";
|
|
81
82
|
|
|
82
83
|
// src/react/hooks/use-chat.ts
|
|
83
84
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
@@ -2121,11 +2122,22 @@ function isImageAttachment(attachment) {
|
|
|
2121
2122
|
function buildSubmitPayload(text, attachments, pendingContexts, onBeforeSend) {
|
|
2122
2123
|
const validAttachments = attachments.filter((attachment) => attachment.status !== "failed");
|
|
2123
2124
|
const payload = buildMessageContent(text, validAttachments);
|
|
2124
|
-
const contextParts = pendingContexts.
|
|
2125
|
-
|
|
2126
|
-
|
|
2125
|
+
const contextParts = pendingContexts.flatMap((context) => {
|
|
2126
|
+
const parts = [
|
|
2127
|
+
{
|
|
2128
|
+
type: "text",
|
|
2129
|
+
text: `[\u4E0A\u4E0B\u6587: ${context.label}]
|
|
2127
2130
|
${context.content}`
|
|
2128
|
-
|
|
2131
|
+
}
|
|
2132
|
+
];
|
|
2133
|
+
if (context.imageUrl) {
|
|
2134
|
+
parts.push({
|
|
2135
|
+
type: "image_url",
|
|
2136
|
+
image_url: { url: context.imageUrl }
|
|
2137
|
+
});
|
|
2138
|
+
}
|
|
2139
|
+
return parts;
|
|
2140
|
+
});
|
|
2129
2141
|
const mergedPayload = contextParts.length === 0 ? payload : typeof payload === "string" ? payload.trim() ? [...contextParts, { type: "text", text: payload }] : contextParts : [...contextParts, ...payload];
|
|
2130
2142
|
return onBeforeSend ? onBeforeSend(mergedPayload) : mergedPayload;
|
|
2131
2143
|
}
|
|
@@ -2430,12 +2442,23 @@ function ComposerContextPill({
|
|
|
2430
2442
|
id,
|
|
2431
2443
|
label,
|
|
2432
2444
|
content,
|
|
2445
|
+
imageUrl,
|
|
2433
2446
|
onRemove
|
|
2434
2447
|
}) {
|
|
2435
2448
|
const [showDetail, setShowDetail] = useState8(false);
|
|
2436
2449
|
const tokenK = formatTokenK(content);
|
|
2437
2450
|
return /* @__PURE__ */ jsxs8(Fragment2, { children: [
|
|
2438
2451
|
/* @__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: [
|
|
2452
|
+
imageUrl ? /* @__PURE__ */ jsx9(
|
|
2453
|
+
"button",
|
|
2454
|
+
{
|
|
2455
|
+
type: "button",
|
|
2456
|
+
onClick: () => setShowDetail(true),
|
|
2457
|
+
className: "h-6 w-6 overflow-hidden rounded-md border border-[hsl(var(--border))] bg-white",
|
|
2458
|
+
title: "\u67E5\u770B\u9009\u4E2D\u533A\u57DF\u622A\u56FE",
|
|
2459
|
+
children: /* @__PURE__ */ jsx9("img", { src: imageUrl, alt: "\u9009\u4E2D\u533A\u57DF\u622A\u56FE", className: "h-full w-full object-cover" })
|
|
2460
|
+
}
|
|
2461
|
+
) : null,
|
|
2439
2462
|
/* @__PURE__ */ jsx9(
|
|
2440
2463
|
"button",
|
|
2441
2464
|
{
|
|
@@ -2481,7 +2504,10 @@ function ComposerContextPill({
|
|
|
2481
2504
|
onKeyDown: (e) => e.stopPropagation(),
|
|
2482
2505
|
children: [
|
|
2483
2506
|
/* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between border-b border-[hsl(var(--border))] px-6 py-3", children: [
|
|
2484
|
-
/* @__PURE__ */
|
|
2507
|
+
/* @__PURE__ */ jsxs8("div", { className: "min-w-0", children: [
|
|
2508
|
+
/* @__PURE__ */ jsx9("h4", { className: "truncate text-xs font-semibold text-[hsl(var(--foreground))]", children: label }),
|
|
2509
|
+
imageUrl ? /* @__PURE__ */ jsx9("p", { className: "mt-0.5 text-[11px] text-[hsl(var(--muted-foreground))]", children: "\u5DF2\u9644\u52A0\u9009\u4E2D\u533A\u57DF\u622A\u56FE\uFF0C\u975E\u591A\u6A21\u6001\u6A21\u578B\u4F1A\u81EA\u52A8\u5FFD\u7565\u56FE\u7247\u3002" }) : null
|
|
2510
|
+
] }),
|
|
2485
2511
|
/* @__PURE__ */ jsx9(
|
|
2486
2512
|
"button",
|
|
2487
2513
|
{
|
|
@@ -2492,7 +2518,10 @@ function ComposerContextPill({
|
|
|
2492
2518
|
}
|
|
2493
2519
|
)
|
|
2494
2520
|
] }),
|
|
2495
|
-
/* @__PURE__ */
|
|
2521
|
+
/* @__PURE__ */ jsxs8("div", { className: "min-h-0 flex-1 overflow-y-auto px-6 py-4", children: [
|
|
2522
|
+
imageUrl ? /* @__PURE__ */ jsx9("div", { className: "mb-4 rounded-xl border border-[hsl(var(--border))] bg-white p-2", children: /* @__PURE__ */ jsx9("img", { src: imageUrl, alt: "\u9009\u4E2D\u533A\u57DF\u622A\u56FE", className: "max-h-72 max-w-full rounded-lg object-contain" }) }) : null,
|
|
2523
|
+
/* @__PURE__ */ jsx9("pre", { className: "whitespace-pre-wrap break-words font-mono text-[11px] leading-[1.6] text-[hsl(var(--foreground)/0.85)]", children: content })
|
|
2524
|
+
] })
|
|
2496
2525
|
]
|
|
2497
2526
|
}
|
|
2498
2527
|
)
|
|
@@ -3387,6 +3416,7 @@ function ChatInput({
|
|
|
3387
3416
|
id: context.id,
|
|
3388
3417
|
label: context.label,
|
|
3389
3418
|
content: context.content,
|
|
3419
|
+
imageUrl: context.imageUrl,
|
|
3390
3420
|
onRemove: (contextId) => {
|
|
3391
3421
|
if (!activeSessionId) {
|
|
3392
3422
|
return;
|
|
@@ -3751,10 +3781,10 @@ function ConnectionBanner() {
|
|
|
3751
3781
|
import { ChevronDown as ChevronDown3, Lightbulb as Lightbulb2, MessageSquare } from "lucide-react";
|
|
3752
3782
|
import {
|
|
3753
3783
|
useCallback as useCallback12,
|
|
3754
|
-
useEffect as
|
|
3784
|
+
useEffect as useEffect17,
|
|
3755
3785
|
useEffectEvent as useEffectEvent4,
|
|
3756
3786
|
useMemo as useMemo17,
|
|
3757
|
-
useRef as
|
|
3787
|
+
useRef as useRef13,
|
|
3758
3788
|
useState as useState21
|
|
3759
3789
|
} from "react";
|
|
3760
3790
|
|
|
@@ -4184,7 +4214,7 @@ function useStickToBottomContext() {
|
|
|
4184
4214
|
|
|
4185
4215
|
// src/react/components/chat/AssistantTurnBlock.tsx
|
|
4186
4216
|
import { AlertCircle, BookOpen, Check as Check4, ChevronRight as ChevronRight5 } from "lucide-react";
|
|
4187
|
-
import { useCallback as useCallback11, useEffect as
|
|
4217
|
+
import { memo as memo3, useCallback as useCallback11, useEffect as useEffect15, useMemo as useMemo15, useRef as useRef12, useState as useState18 } from "react";
|
|
4188
4218
|
|
|
4189
4219
|
// src/react/routes.ts
|
|
4190
4220
|
var MEMORIES_ROUTE = "/memories";
|
|
@@ -4466,7 +4496,7 @@ ReasoningContent.displayName = "ReasoningContent";
|
|
|
4466
4496
|
|
|
4467
4497
|
// src/react/components/chat/AgentLoopBlock.tsx
|
|
4468
4498
|
import { Bot, Check as Check3, ChevronRight as ChevronRight4, FileText as FileText6, Loader2 as Loader24, MessageSquareMore as MessageSquareMore2 } from "lucide-react";
|
|
4469
|
-
import { useEffect as
|
|
4499
|
+
import { useEffect as useEffect14, useMemo as useMemo14, useState as useState17 } from "react";
|
|
4470
4500
|
|
|
4471
4501
|
// src/react/components/chat/ResourceIframe.tsx
|
|
4472
4502
|
import { useEffect as useEffect10, useEffectEvent as useEffectEvent3, useRef as useRef9, useState as useState11 } from "react";
|
|
@@ -5752,7 +5782,8 @@ function buildAskUserPayload(argumentsJson) {
|
|
|
5752
5782
|
}
|
|
5753
5783
|
|
|
5754
5784
|
// src/react/components/chat/UserMessageBubble.tsx
|
|
5755
|
-
import {
|
|
5785
|
+
import { useQueries } from "@tanstack/react-query";
|
|
5786
|
+
import { useEffect as useEffect13, useRef as useRef11, useState as useState16 } from "react";
|
|
5756
5787
|
|
|
5757
5788
|
// src/react/lib/preview-dispatch.ts
|
|
5758
5789
|
var IMAGE_EXTS = [
|
|
@@ -6253,29 +6284,47 @@ function UserMessageBubble({ message, className }) {
|
|
|
6253
6284
|
)
|
|
6254
6285
|
] }) });
|
|
6255
6286
|
}
|
|
6256
|
-
const
|
|
6257
|
-
if (!isImageTextAttachment(attachment.name, attachment.uploadedPath))
|
|
6258
|
-
|
|
6259
|
-
}
|
|
6260
|
-
const pathForUrl = attachment.uploadedPath ?? attachment.name;
|
|
6261
|
-
return [
|
|
6262
|
-
{
|
|
6263
|
-
...attachment,
|
|
6264
|
-
url: buildSessionFileUrl(activeSessionId, pathForUrl)
|
|
6265
|
-
}
|
|
6266
|
-
];
|
|
6287
|
+
const imageTextAttachmentMeta = activeSessionId ? textAttachments.flatMap((attachment) => {
|
|
6288
|
+
if (!isImageTextAttachment(attachment.name, attachment.uploadedPath)) return [];
|
|
6289
|
+
return [{ ...attachment, filePath: attachment.uploadedPath ?? attachment.name }];
|
|
6267
6290
|
}) : [];
|
|
6268
6291
|
const nonImageTextAttachments = textAttachments.filter(
|
|
6269
6292
|
(attachment) => !isImageTextAttachment(attachment.name, attachment.uploadedPath)
|
|
6270
6293
|
);
|
|
6294
|
+
const imageAttachmentQueries = useQueries({
|
|
6295
|
+
queries: imageTextAttachmentMeta.map((att) => ({
|
|
6296
|
+
queryKey: ["session-image", activeSessionId, att.filePath],
|
|
6297
|
+
queryFn: async ({ signal }) => {
|
|
6298
|
+
const apiPath = `/api/sessions/${encodeURIComponent(activeSessionId)}/files/${encodeURIComponent(att.filePath)}`;
|
|
6299
|
+
const res = await apiFetchResponse(apiPath, { signal });
|
|
6300
|
+
const blob = await res.blob();
|
|
6301
|
+
return URL.createObjectURL(blob);
|
|
6302
|
+
},
|
|
6303
|
+
enabled: !!activeSessionId
|
|
6304
|
+
}))
|
|
6305
|
+
});
|
|
6306
|
+
const blobUrlMapRef = useRef11(/* @__PURE__ */ new Map());
|
|
6307
|
+
for (let i = 0; i < imageAttachmentQueries.length; i++) {
|
|
6308
|
+
const url = imageAttachmentQueries[i].data;
|
|
6309
|
+
const key = imageTextAttachmentMeta[i]?.filePath ?? String(i);
|
|
6310
|
+
const prev = blobUrlMapRef.current.get(key);
|
|
6311
|
+
if (prev && url && prev !== url) URL.revokeObjectURL(prev);
|
|
6312
|
+
if (url) blobUrlMapRef.current.set(key, url);
|
|
6313
|
+
}
|
|
6314
|
+
useEffect13(() => {
|
|
6315
|
+
const urls = blobUrlMapRef.current;
|
|
6316
|
+
return () => {
|
|
6317
|
+
for (const u of urls.values()) URL.revokeObjectURL(u);
|
|
6318
|
+
};
|
|
6319
|
+
}, []);
|
|
6271
6320
|
const lightboxImages = [
|
|
6272
6321
|
...imageParts.map((part) => ({
|
|
6273
6322
|
src: part.image_url.url,
|
|
6274
6323
|
alt: "\u7528\u6237\u4E0A\u4F20\u7684\u56FE\u7247"
|
|
6275
6324
|
})),
|
|
6276
|
-
...
|
|
6277
|
-
src:
|
|
6278
|
-
alt:
|
|
6325
|
+
...imageAttachmentQueries.map((q, i) => ({
|
|
6326
|
+
src: q.data ?? "",
|
|
6327
|
+
alt: imageTextAttachmentMeta[i]?.name || "\u7528\u6237\u4E0A\u4F20\u7684\u56FE\u7247"
|
|
6279
6328
|
}))
|
|
6280
6329
|
];
|
|
6281
6330
|
const [lightboxIndex, setLightboxIndex] = useState16(null);
|
|
@@ -6299,7 +6348,7 @@ function UserMessageBubble({ message, className }) {
|
|
|
6299
6348
|
setPreview({ filename: attachment.name, url, mode });
|
|
6300
6349
|
};
|
|
6301
6350
|
return /* @__PURE__ */ jsx28("div", { className: cn("flex justify-end", className), children: /* @__PURE__ */ jsxs23("div", { className: "group flex max-w-[72%] flex-col items-end gap-3", children: [
|
|
6302
|
-
(imageParts.length > 0 ||
|
|
6351
|
+
(imageParts.length > 0 || imageTextAttachmentMeta.length > 0) && /* @__PURE__ */ jsxs23("div", { className: "grid gap-2", children: [
|
|
6303
6352
|
imageParts.map((part, idx) => /* @__PURE__ */ jsx28(
|
|
6304
6353
|
"button",
|
|
6305
6354
|
{
|
|
@@ -6318,24 +6367,34 @@ function UserMessageBubble({ message, className }) {
|
|
|
6318
6367
|
},
|
|
6319
6368
|
part.image_url.url
|
|
6320
6369
|
)),
|
|
6321
|
-
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
|
|
6327
|
-
|
|
6328
|
-
|
|
6329
|
-
"
|
|
6330
|
-
|
|
6331
|
-
|
|
6332
|
-
|
|
6333
|
-
|
|
6334
|
-
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
|
|
6338
|
-
|
|
6370
|
+
imageTextAttachmentMeta.map((att, idx) => {
|
|
6371
|
+
const blobUrl = imageAttachmentQueries[idx]?.data;
|
|
6372
|
+
return blobUrl ? /* @__PURE__ */ jsx28(
|
|
6373
|
+
"button",
|
|
6374
|
+
{
|
|
6375
|
+
type: "button",
|
|
6376
|
+
onClick: () => setLightboxIndex(imageParts.length + idx),
|
|
6377
|
+
className: "cursor-zoom-in",
|
|
6378
|
+
title: "\u67E5\u770B\u5927\u56FE",
|
|
6379
|
+
children: /* @__PURE__ */ jsx28(
|
|
6380
|
+
"img",
|
|
6381
|
+
{
|
|
6382
|
+
src: blobUrl,
|
|
6383
|
+
alt: att.name || "\u7528\u6237\u4E0A\u4F20\u7684\u56FE\u7247",
|
|
6384
|
+
className: "max-h-64 rounded-xl border border-[hsl(var(--user-msg-border))] object-cover"
|
|
6385
|
+
}
|
|
6386
|
+
)
|
|
6387
|
+
},
|
|
6388
|
+
`${att.uploadedPath}:${att.name}`
|
|
6389
|
+
) : imageAttachmentQueries[idx]?.isError ? null : /* @__PURE__ */ jsx28(
|
|
6390
|
+
"div",
|
|
6391
|
+
{
|
|
6392
|
+
className: "flex h-20 items-center justify-center rounded-xl border border-[hsl(var(--user-msg-border))] bg-[hsl(var(--muted)/0.3)] text-xs text-[hsl(var(--muted-foreground))]",
|
|
6393
|
+
children: "\u52A0\u8F7D\u4E2D..."
|
|
6394
|
+
},
|
|
6395
|
+
`${att.uploadedPath}:${att.name}`
|
|
6396
|
+
);
|
|
6397
|
+
})
|
|
6339
6398
|
] }),
|
|
6340
6399
|
lightboxImages.length > 0 && /* @__PURE__ */ jsx28(
|
|
6341
6400
|
ImageLightbox,
|
|
@@ -6496,7 +6555,7 @@ function AgentLoopBlock({ toolCall, sessionId, reasoning }) {
|
|
|
6496
6555
|
),
|
|
6497
6556
|
[childMessages]
|
|
6498
6557
|
);
|
|
6499
|
-
|
|
6558
|
+
useEffect14(() => {
|
|
6500
6559
|
if (hasAwaitingAnswer) {
|
|
6501
6560
|
setExpanded(true);
|
|
6502
6561
|
}
|
|
@@ -6820,6 +6879,8 @@ function getLoopCardStyles(status) {
|
|
|
6820
6879
|
|
|
6821
6880
|
// src/react/components/chat/AssistantTurnBlock.tsx
|
|
6822
6881
|
import { jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
6882
|
+
var EMPTY_MESSAGES3 = [];
|
|
6883
|
+
var EMPTY_AGENT_LOOPS2 = {};
|
|
6823
6884
|
function defaultTurnDisplayMode({
|
|
6824
6885
|
forceExpanded,
|
|
6825
6886
|
hasActionableToolCall
|
|
@@ -6954,7 +7015,7 @@ function collectTurnMessages({
|
|
|
6954
7015
|
});
|
|
6955
7016
|
return merged;
|
|
6956
7017
|
}
|
|
6957
|
-
function
|
|
7018
|
+
function AssistantTurnBlockBase({
|
|
6958
7019
|
sessionId,
|
|
6959
7020
|
messages: rawMessages,
|
|
6960
7021
|
isStreaming = false,
|
|
@@ -6967,6 +7028,10 @@ function AssistantTurnBlock({
|
|
|
6967
7028
|
}) {
|
|
6968
7029
|
const messages = Array.isArray(rawMessages) ? rawMessages : [];
|
|
6969
7030
|
const allToolCalls = useMemo15(() => messages.flatMap((m) => m.tool_calls ?? []), [messages]);
|
|
7031
|
+
const hasAgentToolCall = useMemo15(
|
|
7032
|
+
() => allToolCalls.some((toolCall) => formatToolName(toolCall.name) === "Agent"),
|
|
7033
|
+
[allToolCalls]
|
|
7034
|
+
);
|
|
6970
7035
|
const hasActionableToolCall = useMemo15(
|
|
6971
7036
|
() => allToolCalls.some(
|
|
6972
7037
|
(tc) => tc.status === "error" || tc.status === "cancelled" || formatToolName(tc.name) === "AskUserQuestion" && tc.status === "awaiting_answer"
|
|
@@ -6976,18 +7041,22 @@ function AssistantTurnBlock({
|
|
|
6976
7041
|
const [displayMode, setDisplayMode] = useState18(
|
|
6977
7042
|
defaultTurnDisplayMode({ forceExpanded, hasActionableToolCall })
|
|
6978
7043
|
);
|
|
6979
|
-
const wasStreamingRef =
|
|
6980
|
-
|
|
7044
|
+
const wasStreamingRef = useRef12(isStreaming);
|
|
7045
|
+
useEffect15(() => {
|
|
6981
7046
|
if (wasStreamingRef.current && !isStreaming && !forceExpanded) {
|
|
6982
7047
|
setDisplayMode(defaultTurnDisplayMode({ forceExpanded, hasActionableToolCall }));
|
|
6983
7048
|
}
|
|
6984
7049
|
wasStreamingRef.current = isStreaming;
|
|
6985
7050
|
}, [forceExpanded, hasActionableToolCall, isStreaming]);
|
|
6986
|
-
const sessionMessages = useChatStore(
|
|
6987
|
-
|
|
7051
|
+
const sessionMessages = useChatStore(
|
|
7052
|
+
(state) => hasAgentToolCall ? state.messages[sessionId] ?? EMPTY_MESSAGES3 : EMPTY_MESSAGES3
|
|
7053
|
+
);
|
|
7054
|
+
const agentLoops = useChatStore(
|
|
7055
|
+
(state) => hasAgentToolCall ? state.agentLoops[sessionId] ?? EMPTY_AGENT_LOOPS2 : EMPTY_AGENT_LOOPS2
|
|
7056
|
+
);
|
|
6988
7057
|
const turnMessages = useMemo15(
|
|
6989
|
-
() => collectTurnMessages({ rootMessages: messages, sessionMessages, agentLoops }),
|
|
6990
|
-
[agentLoops, messages, sessionMessages]
|
|
7058
|
+
() => hasAgentToolCall ? collectTurnMessages({ rootMessages: messages, sessionMessages, agentLoops }) : messages,
|
|
7059
|
+
[agentLoops, hasAgentToolCall, messages, sessionMessages]
|
|
6991
7060
|
);
|
|
6992
7061
|
const resourceBlocks = useMemo15(() => getInlineResourceBlocks(turnMessages), [turnMessages]);
|
|
6993
7062
|
const finalMessage = useMemo15(() => getLastTextMessage(turnMessages), [turnMessages]);
|
|
@@ -7061,6 +7130,10 @@ function AssistantTurnBlock({
|
|
|
7061
7130
|
}
|
|
7062
7131
|
);
|
|
7063
7132
|
}
|
|
7133
|
+
function areAssistantTurnBlockPropsEqual(prev, next) {
|
|
7134
|
+
return prev.turnKey === next.turnKey && prev.sessionId === next.sessionId && prev.messages === next.messages && prev.isStreaming === next.isStreaming && prev.isLastTurn === next.isLastTurn && prev.askAnswers === next.askAnswers && prev.onAnswer === next.onAnswer && prev.sessionStatus === next.sessionStatus && prev.level === next.level && prev.forceExpanded === next.forceExpanded && prev.customization === next.customization;
|
|
7135
|
+
}
|
|
7136
|
+
var AssistantTurnBlock = memo3(AssistantTurnBlockBase, areAssistantTurnBlockPropsEqual);
|
|
7064
7137
|
function AssistantMessages({
|
|
7065
7138
|
messages,
|
|
7066
7139
|
isStreaming,
|
|
@@ -7630,7 +7703,7 @@ import {
|
|
|
7630
7703
|
TerminalSquare,
|
|
7631
7704
|
WandSparkles
|
|
7632
7705
|
} from "lucide-react";
|
|
7633
|
-
import { useEffect as
|
|
7706
|
+
import { useEffect as useEffect16, useMemo as useMemo16, useState as useState20 } from "react";
|
|
7634
7707
|
import { jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
7635
7708
|
var EMPTY_EVENTS = [];
|
|
7636
7709
|
function formatElapsedDuration(durationMs) {
|
|
@@ -7710,7 +7783,7 @@ function getTurnStartedAt(events) {
|
|
|
7710
7783
|
}
|
|
7711
7784
|
function useElapsedDuration(startedAt, active) {
|
|
7712
7785
|
const [now, setNow] = useState20(() => Date.now());
|
|
7713
|
-
|
|
7786
|
+
useEffect16(() => {
|
|
7714
7787
|
if (!active || startedAt == null) {
|
|
7715
7788
|
return;
|
|
7716
7789
|
}
|
|
@@ -7846,45 +7919,34 @@ function getAssistantTurnPreview(messages) {
|
|
|
7846
7919
|
return "\u672C\u8F6E\u56DE\u590D";
|
|
7847
7920
|
}
|
|
7848
7921
|
function getMessageMeasureSignature(message) {
|
|
7849
|
-
const contentSize = typeof message.content === "string" ? message.content.length : message.content.
|
|
7922
|
+
const contentSize = typeof message.content === "string" ? message.content.length : message.content.length;
|
|
7850
7923
|
return [
|
|
7851
7924
|
message.entry_id ?? message.timestamp ?? message.role,
|
|
7852
7925
|
message.status ?? "",
|
|
7853
7926
|
message.reasoning?.length ?? 0,
|
|
7854
7927
|
message.tool_calls?.length ?? 0,
|
|
7928
|
+
message.blocks?.length ?? 0,
|
|
7855
7929
|
contentSize
|
|
7856
7930
|
].join(":");
|
|
7857
7931
|
}
|
|
7858
7932
|
function getMessagesMeasureSignature(messages) {
|
|
7859
7933
|
return messages.map((message) => getMessageMeasureSignature(message)).join("|");
|
|
7860
7934
|
}
|
|
7861
|
-
function
|
|
7862
|
-
|
|
7863
|
-
|
|
7864
|
-
} catch {
|
|
7865
|
-
return String(value);
|
|
7866
|
-
}
|
|
7867
|
-
}
|
|
7868
|
-
function hashString(value) {
|
|
7869
|
-
let hash = 0;
|
|
7870
|
-
for (let index = 0; index < value.length; index += 1) {
|
|
7871
|
-
hash = hash * 31 + value.charCodeAt(index) | 0;
|
|
7872
|
-
}
|
|
7873
|
-
return hash.toString(36);
|
|
7874
|
-
}
|
|
7875
|
-
function getMessageRenderSignature(message) {
|
|
7935
|
+
function getMessageResetSignature(message) {
|
|
7936
|
+
const contentSize = typeof message.content === "string" ? message.content.length : message.content.length;
|
|
7937
|
+
const toolSignature = message.tool_calls?.map((toolCall) => `${toolCall.id}:${toolCall.status}:${toolCall.result == null ? 0 : 1}`).join(",") ?? "";
|
|
7876
7938
|
return [
|
|
7877
7939
|
message.entry_id ?? message.timestamp ?? message.role,
|
|
7878
7940
|
message.status ?? "",
|
|
7879
|
-
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7883
|
-
|
|
7941
|
+
contentSize,
|
|
7942
|
+
message.reasoning?.length ?? 0,
|
|
7943
|
+
message.blocks?.length ?? 0,
|
|
7944
|
+
message.memory_refs?.length ?? 0,
|
|
7945
|
+
toolSignature
|
|
7884
7946
|
].join(":");
|
|
7885
7947
|
}
|
|
7886
|
-
function
|
|
7887
|
-
return messages.map((message) =>
|
|
7948
|
+
function getMessagesResetSignature(messages) {
|
|
7949
|
+
return messages.map((message) => getMessageResetSignature(message)).join("|");
|
|
7888
7950
|
}
|
|
7889
7951
|
function findScrollContainer(start) {
|
|
7890
7952
|
let current = start;
|
|
@@ -7909,7 +7971,17 @@ function MessageList({
|
|
|
7909
7971
|
const agentLoops = useChatStore((state) => state.agentLoops[sessionId]);
|
|
7910
7972
|
const askAnswers = useChatStore((state) => state.askAnswers[sessionId]);
|
|
7911
7973
|
const agentLoopNameSet = useMemo17(() => new Set(Object.keys(agentLoops ?? {})), [agentLoops]);
|
|
7974
|
+
const assistantMessagesCacheRef = useRef13(/* @__PURE__ */ new Map());
|
|
7912
7975
|
const renderBlocks = useMemo17(() => {
|
|
7976
|
+
const stableAssistantMessages = (key, buffer) => {
|
|
7977
|
+
const previous = assistantMessagesCacheRef.current.get(key);
|
|
7978
|
+
if (previous && previous.length === buffer.length && previous.every((message, index) => message === buffer[index])) {
|
|
7979
|
+
return previous;
|
|
7980
|
+
}
|
|
7981
|
+
const next = [...buffer];
|
|
7982
|
+
assistantMessagesCacheRef.current.set(key, next);
|
|
7983
|
+
return next;
|
|
7984
|
+
};
|
|
7913
7985
|
const visible = messages.filter((message) => {
|
|
7914
7986
|
const loopName = message.loop_name ?? "root";
|
|
7915
7987
|
if (loopName !== "root") return false;
|
|
@@ -7927,13 +7999,15 @@ function MessageList({
|
|
|
7927
7999
|
assistantTurnCount += 1;
|
|
7928
8000
|
const last = assistantBuffer[assistantBuffer.length - 1];
|
|
7929
8001
|
const isStreaming = assistantBuffer.some((message) => message.status === "streaming");
|
|
8002
|
+
const key = last.entry_id ?? `assistant-${blocks.length}`;
|
|
8003
|
+
const stableMessages = stableAssistantMessages(key, assistantBuffer);
|
|
7930
8004
|
blocks.push({
|
|
7931
8005
|
type: "assistant_turn",
|
|
7932
|
-
messages:
|
|
7933
|
-
key
|
|
8006
|
+
messages: stableMessages,
|
|
8007
|
+
key,
|
|
7934
8008
|
anchorId: `chat-turn-${assistantTurnCount}`,
|
|
7935
8009
|
isStreaming,
|
|
7936
|
-
railTitle: lastUserPreview || getAssistantTurnPreview(
|
|
8010
|
+
railTitle: lastUserPreview || getAssistantTurnPreview(stableMessages)
|
|
7937
8011
|
});
|
|
7938
8012
|
assistantBuffer = [];
|
|
7939
8013
|
};
|
|
@@ -7972,6 +8046,14 @@ function MessageList({
|
|
|
7972
8046
|
});
|
|
7973
8047
|
}
|
|
7974
8048
|
flushAssistant();
|
|
8049
|
+
const activeAssistantKeys = new Set(
|
|
8050
|
+
blocks.filter((block) => block.type === "assistant_turn").map((block) => block.key)
|
|
8051
|
+
);
|
|
8052
|
+
for (const key of assistantMessagesCacheRef.current.keys()) {
|
|
8053
|
+
if (!activeAssistantKeys.has(key)) {
|
|
8054
|
+
assistantMessagesCacheRef.current.delete(key);
|
|
8055
|
+
}
|
|
8056
|
+
}
|
|
7975
8057
|
return blocks;
|
|
7976
8058
|
}, [agentLoopNameSet, messages]);
|
|
7977
8059
|
const hasInterruptedTurn = useMemo17(
|
|
@@ -8001,9 +8083,9 @@ function MessageList({
|
|
|
8001
8083
|
) ?? null,
|
|
8002
8084
|
[lastTurnId, renderBlocks]
|
|
8003
8085
|
);
|
|
8004
|
-
const containerRef =
|
|
8005
|
-
const scrollContainerRef =
|
|
8006
|
-
const frameRef =
|
|
8086
|
+
const containerRef = useRef13(null);
|
|
8087
|
+
const scrollContainerRef = useRef13(null);
|
|
8088
|
+
const frameRef = useRef13(null);
|
|
8007
8089
|
const [activeTurnId, setActiveTurnId] = useState21(lastTurnId);
|
|
8008
8090
|
const layoutSignature = useMemo17(
|
|
8009
8091
|
() => getMessagesMeasureSignature(messages),
|
|
@@ -8045,7 +8127,7 @@ function MessageList({
|
|
|
8045
8127
|
measureActiveTurn();
|
|
8046
8128
|
});
|
|
8047
8129
|
});
|
|
8048
|
-
|
|
8130
|
+
useEffect17(() => {
|
|
8049
8131
|
scrollContainerRef.current = findScrollContainer(containerRef.current);
|
|
8050
8132
|
const sc = scrollContainerRef.current;
|
|
8051
8133
|
if (!sc) return;
|
|
@@ -8061,7 +8143,7 @@ function MessageList({
|
|
|
8061
8143
|
}
|
|
8062
8144
|
};
|
|
8063
8145
|
}, [scheduleMeasure]);
|
|
8064
|
-
|
|
8146
|
+
useEffect17(() => {
|
|
8065
8147
|
scheduleMeasure();
|
|
8066
8148
|
}, [lastTurnId, layoutSignature, scheduleMeasure]);
|
|
8067
8149
|
const handleSelectTurn = useCallback12((turnId) => {
|
|
@@ -8191,7 +8273,7 @@ function MessageListContent({
|
|
|
8191
8273
|
{
|
|
8192
8274
|
label: "\u52A9\u624B\u6D88\u606F",
|
|
8193
8275
|
details: block.key,
|
|
8194
|
-
resetKey:
|
|
8276
|
+
resetKey: getMessagesResetSignature(block.messages),
|
|
8195
8277
|
children: customization?.components?.AssistantTurn ? /* @__PURE__ */ jsx35(
|
|
8196
8278
|
customization.components.AssistantTurn,
|
|
8197
8279
|
{
|
|
@@ -8324,7 +8406,10 @@ function ChatView({
|
|
|
8324
8406
|
},
|
|
8325
8407
|
[send]
|
|
8326
8408
|
);
|
|
8327
|
-
const customization =
|
|
8409
|
+
const customization = useMemo18(
|
|
8410
|
+
() => ({ classNames, components, renderers }),
|
|
8411
|
+
[classNames, components, renderers]
|
|
8412
|
+
);
|
|
8328
8413
|
const SkillStatus = components?.SkillStatusBar;
|
|
8329
8414
|
return /* @__PURE__ */ jsxs31("div", { className: `flex min-h-0 flex-1 flex-col overflow-hidden ${classNames?.root ?? ""}`, children: [
|
|
8330
8415
|
isViewer && /* @__PURE__ */ jsxs31("div", { className: `flex items-center justify-center gap-2 border-b border-[hsl(var(--border))] bg-[hsl(var(--card))] py-2 text-xs text-[hsl(var(--muted-foreground))] ${classNames?.viewerBanner ?? ""}`, children: [
|
|
@@ -8420,4 +8505,4 @@ use-stick-to-bottom/dist/StickToBottom.js:
|
|
|
8420
8505
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
8421
8506
|
*--------------------------------------------------------------------------------------------*)
|
|
8422
8507
|
*/
|
|
8423
|
-
//# sourceMappingURL=chunk-
|
|
8508
|
+
//# sourceMappingURL=chunk-G2LJZTPX.js.map
|