@blade-hq/agent-react 2612.0.0-beta.67 → 2612.0.0-beta.69
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/README.md +2 -0
- package/dist/{chunk-MAFNMG2O.js → chunk-2DPLLZOU.js} +18 -13
- package/dist/{chunk-MAFNMG2O.js.map → chunk-2DPLLZOU.js.map} +1 -1
- package/dist/{chunk-N576N2XO.js → chunk-7MCGQH34.js} +12 -9
- package/dist/chunk-7MCGQH34.js.map +1 -0
- package/dist/{chunk-UC7SY3G5.js → chunk-HCW7SI5Q.js} +333 -269
- package/dist/chunk-HCW7SI5Q.js.map +1 -0
- package/dist/{chunk-X66C66OQ.js → chunk-J72ZLILV.js} +287 -67
- package/dist/chunk-J72ZLILV.js.map +1 -0
- package/dist/{chunk-HS5G33FO.js → chunk-QIR73CES.js} +1031 -8
- package/dist/chunk-QIR73CES.js.map +1 -0
- package/dist/{chunk-VSIUEXGV.js → chunk-WRIMPZPN.js} +12 -962
- package/dist/chunk-WRIMPZPN.js.map +1 -0
- package/dist/{chunk-XV6AO37F.js → chunk-XJ6ZA6LN.js} +9 -9
- package/dist/{chunk-U3RHQHI6.js → chunk-XP6T6SHZ.js} +48 -48
- package/dist/components/AccountConnectors.d.ts +1 -1
- package/dist/components/ManagedConnection.d.ts +0 -1
- package/dist/components/McpAppFrame.d.ts +17 -0
- package/dist/components/SessionPluginIcon.d.ts +1 -0
- package/dist/connectors.js +2 -2
- package/dist/index.js +7 -7
- package/dist/internal.d.ts +2 -0
- package/dist/internal.js +10 -8
- package/dist/internal.js.map +1 -1
- package/dist/questions.js +4 -5
- package/dist/questions.js.map +1 -1
- package/dist/rich-input.js +20 -20
- package/dist/style.full.css +1 -1
- package/dist/tool-details.js +4 -4
- package/node_modules/@modelcontextprotocol/ext-apps/LICENSE +216 -0
- package/node_modules/@modelcontextprotocol/ext-apps/README.md +284 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/docs/patterns.d.ts +9 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/app-bridge.d.ts +1348 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/app-bridge.examples.d.ts +9 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/app-bridge.js +39 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/app-bridge.test.d.ts +1 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/app-with-deps.js +82 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/app.d.ts +1214 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/app.examples.d.ts +9 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/app.js +39 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/app.test.d.ts +1 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/constants.d.ts +65 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/events.d.ts +47 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/events.test.d.ts +1 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/generated/schema.d.ts +1047 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/generated/schema.json +6170 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/generated/schema.test.d.ts +41 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/interop-v1.test.d.ts +1 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/legacy-handlers.d.ts +66 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/legacy-handlers.test.d.ts +1 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/message-transport.d.ts +126 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/message-transport.examples.d.ts +9 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/message-transport.test.d.ts +1 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/index.d.ts +37 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/index.examples.d.ts +6 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/index.js +39 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/react-with-deps.js +82 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/useApp.d.ts +115 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/useApp.examples.d.ts +6 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/useAutoResize.d.ts +54 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/useAutoResize.examples.d.ts +6 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/useDocumentTheme.d.ts +44 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/useDocumentTheme.examples.d.ts +6 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/useHostStyles.d.ts +113 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/react/useHostStyles.examples.d.ts +6 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/server/index.d.ts +381 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/server/index.examples.d.ts +9 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/server/index.js +1 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/server/index.test.d.ts +1 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/spec.types.d.ts +698 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/standard-schema.d.ts +23 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/styles.d.ts +184 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/styles.examples.d.ts +9 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/types.d.ts +33 -0
- package/node_modules/@modelcontextprotocol/ext-apps/dist/src/wire-compat.test.d.ts +1 -0
- package/node_modules/@modelcontextprotocol/ext-apps/package.json +144 -0
- package/node_modules/@standard-schema/spec/LICENSE +21 -0
- package/node_modules/@standard-schema/spec/README.md +198 -0
- package/node_modules/@standard-schema/spec/dist/index.cjs +18 -0
- package/node_modules/@standard-schema/spec/dist/index.d.cts +119 -0
- package/node_modules/@standard-schema/spec/dist/index.d.ts +119 -0
- package/node_modules/@standard-schema/spec/dist/index.js +0 -0
- package/node_modules/@standard-schema/spec/package.json +52 -0
- package/package.json +6 -2
- package/dist/chunk-HS5G33FO.js.map +0 -1
- package/dist/chunk-N576N2XO.js.map +0 -1
- package/dist/chunk-UC7SY3G5.js.map +0 -1
- package/dist/chunk-VSIUEXGV.js.map +0 -1
- package/dist/chunk-X66C66OQ.js.map +0 -1
- /package/dist/{chunk-XV6AO37F.js.map → chunk-XJ6ZA6LN.js.map} +0 -0
- /package/dist/{chunk-U3RHQHI6.js.map → chunk-XP6T6SHZ.js.map} +0 -0
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BrowserConnectionDialog,
|
|
3
|
-
Check,
|
|
4
|
-
Copy,
|
|
5
3
|
Dialog,
|
|
6
4
|
DialogClose,
|
|
7
5
|
DialogContent,
|
|
8
6
|
DialogTitle,
|
|
9
|
-
Download,
|
|
10
|
-
Plug,
|
|
11
|
-
X,
|
|
12
7
|
cn,
|
|
13
8
|
copyToClipboard,
|
|
14
9
|
useChatEnvironment,
|
|
15
10
|
useHighlightedCode,
|
|
16
11
|
useOptionalBladeClient
|
|
17
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-WRIMPZPN.js";
|
|
18
13
|
import {
|
|
19
|
-
|
|
14
|
+
Check,
|
|
15
|
+
Copy,
|
|
16
|
+
Download,
|
|
17
|
+
Plug,
|
|
18
|
+
X,
|
|
19
|
+
dist_exports8 as dist_exports,
|
|
20
20
|
useOverlayRoot
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-QIR73CES.js";
|
|
22
22
|
import {
|
|
23
23
|
__export
|
|
24
24
|
} from "./chunk-PR4QN5HX.js";
|
|
@@ -9477,4 +9477,4 @@ export {
|
|
|
9477
9477
|
CodeBlockPre,
|
|
9478
9478
|
MarkdownContent
|
|
9479
9479
|
};
|
|
9480
|
-
//# sourceMappingURL=chunk-
|
|
9480
|
+
//# sourceMappingURL=chunk-XJ6ZA6LN.js.map
|
|
@@ -9,17 +9,59 @@ import {
|
|
|
9
9
|
useEffectEvent,
|
|
10
10
|
useSessionPluginActivation,
|
|
11
11
|
useSessionSkills
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-2DPLLZOU.js";
|
|
13
13
|
import {
|
|
14
14
|
ImageLightbox,
|
|
15
15
|
McpAppMessageContext,
|
|
16
16
|
MessageImage,
|
|
17
17
|
ToolUiCardView,
|
|
18
18
|
getRenderer
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-HCW7SI5Q.js";
|
|
20
20
|
import {
|
|
21
21
|
MarkdownContent
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-XJ6ZA6LN.js";
|
|
23
|
+
import {
|
|
24
|
+
BladeProvider,
|
|
25
|
+
ChatEnvironmentProvider,
|
|
26
|
+
CurrentChatSessionProvider,
|
|
27
|
+
Dialog,
|
|
28
|
+
DialogClose,
|
|
29
|
+
DialogContent,
|
|
30
|
+
DialogDescription,
|
|
31
|
+
DialogTitle,
|
|
32
|
+
PlanUpdateBlock,
|
|
33
|
+
SessionSourceProvider,
|
|
34
|
+
cn,
|
|
35
|
+
copyToClipboard,
|
|
36
|
+
extractToolFilePath,
|
|
37
|
+
formatToolFileName,
|
|
38
|
+
formatToolName,
|
|
39
|
+
getPlanUpdateDisplayState,
|
|
40
|
+
getToolDescription,
|
|
41
|
+
getToolDisplayLabel,
|
|
42
|
+
getToolOutputTag,
|
|
43
|
+
getToolStatusLabel,
|
|
44
|
+
getToolTone,
|
|
45
|
+
isPlanUpdateTool,
|
|
46
|
+
notifyChat,
|
|
47
|
+
parsePlanUpdate,
|
|
48
|
+
useBladeClient,
|
|
49
|
+
useBladeHost,
|
|
50
|
+
useChatEnvironment,
|
|
51
|
+
useChatRenderMode,
|
|
52
|
+
useChatSessionDetail,
|
|
53
|
+
useChatVirtualizer,
|
|
54
|
+
useComposerBridge,
|
|
55
|
+
useCurrentChatSessionId,
|
|
56
|
+
useHideTodo,
|
|
57
|
+
useIsSessionHistoryLoading,
|
|
58
|
+
useOptionalBladeClient,
|
|
59
|
+
usePlanRevealRevision,
|
|
60
|
+
useSessionHandle,
|
|
61
|
+
useSessionSource,
|
|
62
|
+
useSessionState,
|
|
63
|
+
useSingleSessionSource
|
|
64
|
+
} from "./chunk-WRIMPZPN.js";
|
|
23
65
|
import {
|
|
24
66
|
Archive,
|
|
25
67
|
ArrowRight,
|
|
@@ -27,12 +69,10 @@ import {
|
|
|
27
69
|
ArrowUpRight,
|
|
28
70
|
Ban,
|
|
29
71
|
BellRing,
|
|
30
|
-
BladeProvider,
|
|
31
72
|
BookOpen,
|
|
32
73
|
Bookmark,
|
|
33
74
|
Bot,
|
|
34
75
|
Brain,
|
|
35
|
-
ChatEnvironmentProvider,
|
|
36
76
|
Check,
|
|
37
77
|
ChevronDown,
|
|
38
78
|
ChevronRight,
|
|
@@ -41,12 +81,6 @@ import {
|
|
|
41
81
|
CirclePause,
|
|
42
82
|
CircleSlash,
|
|
43
83
|
Copy,
|
|
44
|
-
CurrentChatSessionProvider,
|
|
45
|
-
Dialog,
|
|
46
|
-
DialogClose,
|
|
47
|
-
DialogContent,
|
|
48
|
-
DialogDescription,
|
|
49
|
-
DialogTitle,
|
|
50
84
|
Download,
|
|
51
85
|
ExternalLink,
|
|
52
86
|
Eye,
|
|
@@ -69,12 +103,10 @@ import {
|
|
|
69
103
|
PanelRightOpen,
|
|
70
104
|
Pencil,
|
|
71
105
|
PencilLine,
|
|
72
|
-
PlanUpdateBlock,
|
|
73
106
|
Play,
|
|
74
107
|
RefreshCcw,
|
|
75
108
|
Search,
|
|
76
109
|
Send,
|
|
77
|
-
SessionSourceProvider,
|
|
78
110
|
Settings2,
|
|
79
111
|
Sparkles,
|
|
80
112
|
Square,
|
|
@@ -84,41 +116,9 @@ import {
|
|
|
84
116
|
Wrench,
|
|
85
117
|
X,
|
|
86
118
|
Zap,
|
|
87
|
-
|
|
88
|
-
copyToClipboard,
|
|
89
|
-
extractToolFilePath,
|
|
90
|
-
formatToolFileName,
|
|
91
|
-
formatToolName,
|
|
92
|
-
getPlanUpdateDisplayState,
|
|
93
|
-
getToolDescription,
|
|
94
|
-
getToolDisplayLabel,
|
|
95
|
-
getToolOutputTag,
|
|
96
|
-
getToolStatusLabel,
|
|
97
|
-
getToolTone,
|
|
98
|
-
isPlanUpdateTool,
|
|
99
|
-
notifyChat,
|
|
100
|
-
parsePlanUpdate,
|
|
101
|
-
useBladeClient,
|
|
102
|
-
useBladeHost,
|
|
103
|
-
useChatEnvironment,
|
|
104
|
-
useChatRenderMode,
|
|
105
|
-
useChatSessionDetail,
|
|
106
|
-
useChatVirtualizer,
|
|
107
|
-
useComposerBridge,
|
|
108
|
-
useCurrentChatSessionId,
|
|
109
|
-
useHideTodo,
|
|
110
|
-
useIsSessionHistoryLoading,
|
|
111
|
-
useOptionalBladeClient,
|
|
112
|
-
usePlanRevealRevision,
|
|
113
|
-
useSessionHandle,
|
|
114
|
-
useSessionSource,
|
|
115
|
-
useSessionState,
|
|
116
|
-
useSingleSessionSource
|
|
117
|
-
} from "./chunk-VSIUEXGV.js";
|
|
118
|
-
import {
|
|
119
|
-
dist_exports,
|
|
119
|
+
dist_exports2 as dist_exports,
|
|
120
120
|
useControllableState
|
|
121
|
-
} from "./chunk-
|
|
121
|
+
} from "./chunk-QIR73CES.js";
|
|
122
122
|
|
|
123
123
|
// src/hooks/use-agent-session.ts
|
|
124
124
|
import { useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
@@ -13619,4 +13619,4 @@ use-stick-to-bottom/dist/StickToBottom.js:
|
|
|
13619
13619
|
js-yaml/dist/js-yaml.mjs:
|
|
13620
13620
|
(*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT *)
|
|
13621
13621
|
*/
|
|
13622
|
-
//# sourceMappingURL=chunk-
|
|
13622
|
+
//# sourceMappingURL=chunk-XP6T6SHZ.js.map
|
|
@@ -4,7 +4,7 @@ export declare function AccountConnectors({ client, query, sessionId, pending, o
|
|
|
4
4
|
query?: string;
|
|
5
5
|
sessionId?: string | null;
|
|
6
6
|
pending?: Set<string>;
|
|
7
|
-
onUse?: (name: string, label: string, enabled: boolean) => Promise<void>;
|
|
7
|
+
onUse?: (name: string, label: string, enabled: boolean, icon?: string | null) => Promise<void>;
|
|
8
8
|
onSelectedChange?: (items: AccountConnector[]) => void;
|
|
9
9
|
disabledReason?: string | null;
|
|
10
10
|
manage?: boolean;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { ConnectorAuthorization, ConnectorAuthorizationAction, ConnectorAuthorizationOptions } from "@blade-hq/agent-client";
|
|
2
|
-
export declare function managedAuthorizationURL(view: ConnectorAuthorization | null): string | null;
|
|
3
2
|
export interface ManagedConnectionProps {
|
|
4
3
|
read: () => Promise<ConnectorAuthorization>;
|
|
5
4
|
act: (action: ConnectorAuthorizationAction, options?: ConnectorAuthorizationOptions) => Promise<ConnectorAuthorization>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { AppBridge } from "@modelcontextprotocol/ext-apps/app-bridge";
|
|
2
|
+
export interface McpAppFrameProps {
|
|
3
|
+
html?: string;
|
|
4
|
+
resourceMeta: Record<string, unknown>;
|
|
5
|
+
title?: string;
|
|
6
|
+
error?: string | null;
|
|
7
|
+
toolInput?: Parameters<AppBridge["sendToolInput"]>[0];
|
|
8
|
+
callTool?: AppBridge["oncalltool"];
|
|
9
|
+
sendMessage?: AppBridge["onmessage"];
|
|
10
|
+
updateModelContext?: AppBridge["onupdatemodelcontext"];
|
|
11
|
+
requestDisplayMode?: AppBridge["onrequestdisplaymode"];
|
|
12
|
+
sizeChange?: AppBridge["onsizechange"];
|
|
13
|
+
openLink?: AppBridge["onopenlink"];
|
|
14
|
+
onReady?: (bridge: AppBridge) => void;
|
|
15
|
+
}
|
|
16
|
+
/** Sandboxed MCP App surface shared by chat cards and file previews. */
|
|
17
|
+
export declare function McpAppFrame(props: McpAppFrameProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -6,6 +6,7 @@ export interface SessionPluginIconProps {
|
|
|
6
6
|
* 这样首页这种还没有会话的地方也能显示包内图标。
|
|
7
7
|
*/
|
|
8
8
|
sessionId: string | null;
|
|
9
|
+
/** Also accepts the package data image returned by the connector catalog. */
|
|
9
10
|
plugin: Pick<SessionPlugin, "name" | "icon">;
|
|
10
11
|
/** 边长,默认 20。 */
|
|
11
12
|
size?: number;
|
package/dist/connectors.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -6,21 +6,21 @@ import {
|
|
|
6
6
|
useAgentSession,
|
|
7
7
|
useReplay,
|
|
8
8
|
useTopicAssetSubmissionAccess
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-XP6T6SHZ.js";
|
|
10
|
+
import "./chunk-2DPLLZOU.js";
|
|
11
11
|
import {
|
|
12
12
|
ConnectorConnection,
|
|
13
13
|
DeviceConnection
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import "./chunk-
|
|
14
|
+
} from "./chunk-J72ZLILV.js";
|
|
15
|
+
import "./chunk-HCW7SI5Q.js";
|
|
16
16
|
import {
|
|
17
17
|
MarkdownContent
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-XJ6ZA6LN.js";
|
|
19
19
|
import {
|
|
20
20
|
BladeProvider,
|
|
21
21
|
useBladeClient
|
|
22
|
-
} from "./chunk-
|
|
23
|
-
import "./chunk-
|
|
22
|
+
} from "./chunk-WRIMPZPN.js";
|
|
23
|
+
import "./chunk-QIR73CES.js";
|
|
24
24
|
import "./chunk-PR4QN5HX.js";
|
|
25
25
|
export {
|
|
26
26
|
BladeProvider,
|
package/dist/internal.d.ts
CHANGED
|
@@ -62,3 +62,5 @@ export { CodeBlockPre } from "./chat/markdown/MarkdownContent";
|
|
|
62
62
|
export { ChatLoadingIndicator, isPreparingReply } from "./chat/ChatLoadingIndicator";
|
|
63
63
|
export { BrowserConnectionDialog } from "./components/BrowserConnectionDialog";
|
|
64
64
|
export { AccountConnectors } from "./components/AccountConnectors";
|
|
65
|
+
export { McpAppFrame } from "./components/McpAppFrame";
|
|
66
|
+
export type { McpAppFrameProps } from "./components/McpAppFrame";
|
package/dist/internal.js
CHANGED
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
useTopicAssetSubmissionAccess,
|
|
26
26
|
useTurnNavigation,
|
|
27
27
|
useTypewriterReveal
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-XP6T6SHZ.js";
|
|
29
29
|
import {
|
|
30
30
|
AccountConnectors,
|
|
31
31
|
ConnectorPanel,
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
TRIGGER_ICON_LIMIT,
|
|
34
34
|
selectionFromItem,
|
|
35
35
|
triggerSummary
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-7MCGQH34.js";
|
|
37
37
|
import {
|
|
38
38
|
PluginConnectorList,
|
|
39
39
|
SessionPluginConfigDialog,
|
|
@@ -44,22 +44,23 @@ import {
|
|
|
44
44
|
mergeConnectorItems,
|
|
45
45
|
sessionPluginLabel,
|
|
46
46
|
useSessionPluginActivation
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-2DPLLZOU.js";
|
|
48
48
|
import {
|
|
49
49
|
ConnectorConnection,
|
|
50
50
|
DeviceConnection
|
|
51
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-J72ZLILV.js";
|
|
52
52
|
import {
|
|
53
53
|
McpAppCard,
|
|
54
|
+
McpAppFrame,
|
|
54
55
|
MessageImage,
|
|
55
56
|
ToolUiCardView
|
|
56
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-HCW7SI5Q.js";
|
|
57
58
|
import {
|
|
58
59
|
CodeBlockPre,
|
|
59
60
|
DEFAULT_ALLOWED_TAGS,
|
|
60
61
|
MarkdownContent,
|
|
61
62
|
MarkdownRenderer
|
|
62
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-XJ6ZA6LN.js";
|
|
63
64
|
import {
|
|
64
65
|
BladeProvider,
|
|
65
66
|
BrowserConnectionDialog,
|
|
@@ -73,14 +74,14 @@ import {
|
|
|
73
74
|
useBladeClient,
|
|
74
75
|
useBladeHost,
|
|
75
76
|
useOptionalBladeClient
|
|
76
|
-
} from "./chunk-
|
|
77
|
+
} from "./chunk-WRIMPZPN.js";
|
|
77
78
|
import {
|
|
78
79
|
Content2,
|
|
79
80
|
Portal,
|
|
80
81
|
Provider,
|
|
81
82
|
Root3,
|
|
82
83
|
Trigger
|
|
83
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-QIR73CES.js";
|
|
84
85
|
import "./chunk-PR4QN5HX.js";
|
|
85
86
|
|
|
86
87
|
// src/internal.ts
|
|
@@ -585,6 +586,7 @@ export {
|
|
|
585
586
|
MarkdownContent,
|
|
586
587
|
MarkdownRenderer,
|
|
587
588
|
McpAppCard,
|
|
589
|
+
McpAppFrame,
|
|
588
590
|
MessageImage,
|
|
589
591
|
MountHostContext,
|
|
590
592
|
MountSlot,
|
package/dist/internal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal.ts","../src/lib/mount-renderers.tsx","../src/components/SessionMemoryToggle.tsx","../src/components/SessionBranchPicker.tsx"],"sourcesContent":["export * from \"./index\"\nexport * from \"./chat\"\nexport { useBladeHost, useOptionalBladeClient } from \"./context\"\nexport { MountHostContext, MountSlot, mountRenderersToReact } from \"./lib/mount-renderers\"\n\nexport { useLlmChat } from \"./hooks/use-llm-chat\"\nexport { useMessagePin } from \"./hooks/use-message-pin\"\nexport type { UseMessagePinOptions } from \"./hooks/use-message-pin\"\nexport { useTypewriterReveal } from \"./hooks/use-typewriter-reveal\"\nexport type { UseTypewriterRevealResult } from \"./hooks/use-typewriter-reveal\"\nexport {\n latestUserSpeechEntryId,\n TURN_NAV_HIGHLIGHT_CLASS,\n turnNavItemsFromMessages,\n useTurnNavigation,\n} from \"./hooks/use-turn-navigation\"\nexport type {\n TurnNavigationOptions,\n TurnNavigationResult,\n TurnNavigationSource,\n} from \"./hooks/use-turn-navigation\"\nexport type { UseLlmChatResult } from \"./hooks/use-llm-chat\"\n\nexport { ConnectorPanel } from \"./components/ConnectorPanel\"\nexport type { ConnectorPanelProps } from \"./components/ConnectorPanel\"\nexport { PluginConnectorList } from \"./components/PluginConnectorList\"\nexport type { ConfiguringPlugin, PluginConnectorListProps } from \"./components/PluginConnectorList\"\nexport { useSessionPluginActivation } from \"./components/use-session-plugin-activation\"\nexport type { UseSessionPluginActivationResult } from \"./components/use-session-plugin-activation\"\nexport {\n catalogToConnectorItems,\n filterConnectorItems,\n mergeConnectorItems,\n} from \"./components/plugin-connector\"\nexport type { PluginConnectorItem } from \"./components/plugin-connector\"\nexport { selectionFromItem, triggerSummary, TRIGGER_ICON_LIMIT } from \"./components/connector-panel-types\"\nexport type {\n PluginConnectorSelection,\n TriggerSummary,\n} from \"./components/connector-panel-types\"\nexport { SessionPluginSelector } from \"./components/SessionPluginSelector\"\nexport type { SessionPluginSelectorProps } from \"./components/SessionPluginSelector\"\nexport { SessionPluginIcon, sessionPluginLabel } from \"./components/SessionPluginIcon\"\nexport type { SessionPluginIconProps, SessionPluginLabelProps } from \"./components/SessionPluginIcon\"\nexport { PluginTriggerStack } from \"./components/PluginTriggerStack\"\nexport type { PluginTriggerStackProps } from \"./components/PluginTriggerStack\"\nexport { SessionPluginConfigDialog } from \"./components/SessionPluginConfigDialog\"\nexport type { SessionPluginConfigDialogProps } from \"./components/SessionPluginConfigDialog\"\nexport { SessionPluginConfigForm } from \"./components/SessionPluginConfigForm\"\nexport type {\n SessionPluginConfigDraft,\n SessionPluginConfigFormProps,\n} from \"./components/SessionPluginConfigForm\"\nexport { AgentChat } from \"./components/AgentChat\"\nexport type { AgentChatProps } from \"./components/AgentChat\"\nexport { LlmChat } from \"./components/LlmChat\"\nexport type { LlmChatProps } from \"./components/LlmChat\"\nexport type { LlmAdvancedSettings, LlmOverride } from \"./components/LlmAdvancedSettings\"\nexport { DEFAULT_ALLOWED_TAGS, MarkdownRenderer } from \"./components/markdown\"\nexport type {\n AllowedTags,\n CodeBlockOverrides,\n LinkSafetyConfig,\n MarkdownComponents,\n MarkdownRendererProps,\n RawHtmlPlugin,\n} from \"./components/markdown\"\nexport { WhatIfUserBubble } from \"./components/WhatIfUserBubble\"\nexport type { WhatIfUserBubbleProps } from \"./components/WhatIfUserBubble\"\nexport { parseWhatIfPrompt } from \"./lib/whatif-prompt\"\nexport type { ParsedWhatIfPrompt, WhatIfQuote } from \"./lib/whatif-prompt\"\nexport {\n getPlanUpdateDisplayState,\n isPlanUpdateTool,\n PLAN_AUTO_COLLAPSE_MS,\n parsePlanUpdate,\n pickCurrentPlanStep,\n PlanUpdateBlock,\n} from \"./components/PlanUpdateBlock\"\nexport type { PlanUpdateDisplayState } from \"./components/PlanUpdateBlock\"\nexport { ContextCard, ContextGroupCard } from \"./components/ContextCard\"\nexport type { ContextCardProps, ContextGroupCardProps } from \"./components/ContextCard\"\nexport { ToolUiCardView } from \"./components/ToolUiCardView\"\nexport { McpAppCard } from \"./components/McpAppCard\"\nexport type { McpAppMessage } from \"./components/McpAppCard\"\nexport { SessionMemoryToggle } from \"./components/SessionMemoryToggle\"\nexport type { SessionMemoryToggleProps } from \"./components/SessionMemoryToggle\"\nexport { SessionQueuePanel, isQueuePanelVisible } from \"./components/SessionQueuePanel\"\nexport type { SessionQueuePanelProps } from \"./components/SessionQueuePanel\"\n\nexport { SessionBranchPicker } from \"./components/SessionBranchPicker\"\nexport type { SessionBranchPickerProps } from \"./components/SessionBranchPicker\"\n\nexport { MessageImage, type MessageImageProps } from \"./components/MessageImage\"\n\nexport { BackgroundWakeNotice } from \"./components/BackgroundWakeNotice\"\n\nexport { TopicAssetSubmitDialog, useTopicAssetSubmissionAccess } from \"./components/TopicAssetSubmitDialog\"\nexport type { TopicAssetSubmitDialogProps } from \"./components/TopicAssetSubmitDialog\"\n\nexport { CodeBlockPre } from \"./chat/markdown/MarkdownContent\"\n\nexport { ChatLoadingIndicator, isPreparingReply } from \"./chat/ChatLoadingIndicator\"\n\nexport { BrowserConnectionDialog } from \"./components/BrowserConnectionDialog\"\n\nexport { AccountConnectors } from \"./components/AccountConnectors\"\n","import type {\n BladeChatMountRenderers,\n MountHandle,\n MountRenderer,\n MountRendererObject,\n MountResult,\n} from \"@blade-hq/agent-client\"\nimport { createContext, useContext, useId, useLayoutEffect, useRef, type ReactNode } from \"react\"\nimport type { ChatViewRenderers } from \"../chat/customization\"\n\n/**\n * 挂载节点放在哪里。\n *\n * `<blade-chat>` 把它设成元素本身:挂载节点作为元素的 light DOM 子节点,经 Shadow DOM\n * 里的 `<slot>` 显示在区块位置,宿主页面的样式(包括 Vue 的 scoped 样式)直接生效。\n * 没有设置时(npm 包里),挂载节点就是组件内的一个 div。\n */\nexport const MountHostContext = createContext<HTMLElement | null>(null)\n\nfunction normalizeResult<T>(result: MountResult<T>): MountHandle<T> {\n if (typeof result === \"function\") return { destroy: result }\n if (result && typeof result === \"object\") return result\n return { destroy: () => {} }\n}\n\nfunction toObject<T>(renderer: MountRenderer<T>): MountRendererObject<T> {\n return typeof renderer === \"function\" ? { mount: renderer } : renderer\n}\n\nfunction sameData(a: object, b: object): boolean {\n const aKeys = Object.keys(a)\n if (aKeys.length !== Object.keys(b).length) return false\n return aKeys.every((key) => Object.is((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key]))\n}\n\ninterface MountSlotProps<T extends object> {\n renderer: MountRendererObject<T>\n data: T\n}\n\n/** 给宿主一个 DOM 节点挂自己的内容;数据变化时原地更新或清理后重挂,卸载时清理。 */\nexport function MountSlot<T extends object>({ renderer, data }: MountSlotProps<T>) {\n const host = useContext(MountHostContext)\n const slotName = `blade-mount-${useId().replace(/[^a-zA-Z0-9_-]/g, \"\")}`\n const localRef = useRef<HTMLDivElement>(null)\n const dataRef = useRef(data)\n const mountedRef = useRef<{ target: HTMLElement; handle: MountHandle<T>; data: T } | null>(null)\n\n useLayoutEffect(() => {\n dataRef.current = data\n })\n\n useLayoutEffect(() => {\n let target: HTMLElement\n if (host) {\n target = document.createElement(\"div\")\n target.slot = slotName\n host.appendChild(target)\n } else {\n if (!localRef.current) return\n target = localRef.current\n }\n const initial = dataRef.current\n mountedRef.current = { target, handle: normalizeResult(renderer.mount(target, initial)), data: initial }\n return () => {\n const mounted = mountedRef.current\n mountedRef.current = null\n mounted?.handle.destroy()\n if (host) target.remove()\n else target.replaceChildren()\n }\n }, [host, renderer, slotName])\n\n useLayoutEffect(() => {\n const mounted = mountedRef.current\n if (!mounted || sameData(mounted.data, data)) return\n mounted.data = data\n if (mounted.handle.update) {\n mounted.handle.update(data)\n return\n }\n mounted.handle.destroy()\n mounted.target.replaceChildren()\n mounted.handle = normalizeResult(renderer.mount(mounted.target, data))\n }, [data, renderer])\n\n return host ? <slot name={slotName} /> : <div ref={localRef} data-blade-mount=\"\" />\n}\n\nfunction slotFor<T extends object>(renderer: MountRendererObject<T>, data: T): ReactNode | null {\n if (renderer.match && !renderer.match(data)) return null\n return <MountSlot renderer={renderer} data={data} />\n}\n\n/**\n * 把挂载式渲染器转成普通 React 渲染器:两种写法走同一条渲染路径,`match` 返回\n * false 等于 React 渲染器返回 null(走默认渲染)。调用方要按 `renderers` 对象缓存结果,\n * 否则每次渲染都会得到新的渲染器、挂载内容被反复重建。\n */\nexport function mountRenderersToReact(\n renderers: BladeChatMountRenderers | null | undefined,\n context: { sessionId?: string } = {},\n): ChatViewRenderers | undefined {\n if (!renderers) return undefined\n const result: ChatViewRenderers = {}\n if (renderers.toolCall) {\n const renderer = toObject(renderers.toolCall)\n result.toolCall = (toolCall) => slotFor(renderer, { toolCall, sessionId: context.sessionId })\n }\n if (renderers.userMessage) {\n const renderer = toObject(renderers.userMessage)\n result.userMessage = ({ message }) => slotFor(renderer, { message })\n }\n if (renderers.assistantText) {\n const renderer = toObject(renderers.assistantText)\n result.assistantText = ({ message, streaming, compact, sessionId }) =>\n slotFor(renderer, { message, streaming, compact, sessionId })\n }\n return result\n}\n","import type { BladeClient } from \"@blade-hq/agent-client\"\nimport { useCallback, useEffect, useRef, useState, useSyncExternalStore } from \"react\"\nimport { useOptionalBladeClient } from \"../context\"\nimport { cn } from \"../lib/utils\"\n\ninterface SaveState {\n saving: boolean\n listeners: Set<() => void>\n}\n\nconst saveStates = new WeakMap<BladeClient, Map<string, SaveState>>()\n\nfunction getSaveState(client: BladeClient, sessionId: string): SaveState {\n let clientStates = saveStates.get(client)\n if (!clientStates) {\n clientStates = new Map()\n saveStates.set(client, clientStates)\n }\n let state = clientStates.get(sessionId)\n if (!state) {\n state = { saving: false, listeners: new Set() }\n clientStates.set(sessionId, state)\n }\n return state\n}\n\nfunction notify(state: SaveState) {\n for (const listener of state.listeners) listener()\n}\n\nfunction cleanupSaveState(client: BladeClient, sessionId: string, state: SaveState) {\n if (state.saving || state.listeners.size > 0) return\n const clientStates = saveStates.get(client)\n if (clientStates?.get(sessionId) === state) clientStates.delete(sessionId)\n}\n\nexport interface SessionMemoryToggleProps {\n sessionId: string\n enabled: boolean\n /** 不在 BladeProvider 内使用时显式传入,与宿主现有 BladeClient 复用连接和鉴权。 */\n client?: BladeClient\n disabled?: boolean\n label?: string\n className?: string\n labelClassName?: string\n inputClassName?: string\n onSaved?: (sessionId: string, enabled: boolean) => void\n onError?: (error: unknown) => void\n}\n\n/**\n * 当前会话记忆开关。同一 client + sessionId 的所有实例共享保存锁,避免多个聊天入口\n * 或会话切换时发出乱序更新;服务端成功后才通过 onSaved 交还权威值。\n */\nexport function SessionMemoryToggle({\n sessionId,\n enabled,\n client: clientProp,\n disabled = false,\n label = \"当前会话使用记忆\",\n className,\n labelClassName,\n inputClassName,\n onSaved,\n onError,\n}: SessionMemoryToggleProps) {\n const contextClient = useOptionalBladeClient()\n const client = clientProp ?? contextClient\n if (!client) {\n throw new Error(\"SessionMemoryToggle 必须在 <BladeProvider> 内使用或显式传入 client\")\n }\n\n const saveState = getSaveState(client, sessionId)\n const subscribe = useCallback(\n (listener: () => void) => {\n saveState.listeners.add(listener)\n return () => {\n saveState.listeners.delete(listener)\n cleanupSaveState(client, sessionId, saveState)\n }\n },\n [client, saveState, sessionId],\n )\n const getSaving = useCallback(() => saveState.saving, [saveState])\n const saving = useSyncExternalStore(\n subscribe,\n getSaving,\n getSaving,\n )\n const [draftEnabled, setDraftEnabled] = useState(enabled)\n const activeSessionIdRef = useRef(sessionId)\n activeSessionIdRef.current = sessionId\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: a new session must discard this component instance's optimistic value even when both sessions share the same enabled prop\n useEffect(() => {\n setDraftEnabled(enabled)\n }, [enabled, sessionId])\n\n const update = useCallback(\n (nextEnabled: boolean) => {\n const currentSaveState = getSaveState(client, sessionId)\n if (currentSaveState.saving) return\n currentSaveState.saving = true\n notify(currentSaveState)\n setDraftEnabled(nextEnabled)\n\n void client.sessions.updateSessionMemory(sessionId, nextEnabled).then(\n (updated) => {\n if (activeSessionIdRef.current === sessionId) {\n setDraftEnabled(updated.memory_enabled)\n }\n onSaved?.(sessionId, updated.memory_enabled)\n },\n (error) => {\n if (activeSessionIdRef.current === sessionId) setDraftEnabled(enabled)\n onError?.(error)\n },\n ).finally(() => {\n currentSaveState.saving = false\n notify(currentSaveState)\n cleanupSaveState(client, sessionId, currentSaveState)\n })\n },\n [client, enabled, onError, onSaved, sessionId],\n )\n\n return (\n <label className={cn(\"flex items-center justify-between\", className)}>\n <span className={labelClassName}>{label}</span>\n <input\n type=\"checkbox\"\n checked={draftEnabled}\n onChange={(event) => update(event.target.checked)}\n disabled={disabled || saving}\n className={inputClassName}\n />\n </label>\n )\n}\n","import type { BladeClient } from \"@blade-hq/agent-client\"\nimport * as Tooltip from \"@radix-ui/react-tooltip\"\nimport { useMemo, useState } from \"react\"\nimport { cn } from \"../lib/utils\"\n\ntype CheckpointTree = Awaited<ReturnType<BladeClient[\"sessions\"][\"getSessionCheckpoints\"]>>\ntype CheckpointNode = CheckpointTree[\"nodes\"][number]\n\nexport interface SessionBranchPickerProps {\n tree: CheckpointTree\n /** Disable changes while this session is running or read-only. */\n disabled?: boolean\n /** Restore only the conversation; the host owns history refresh and composer drafts. */\n onCheckout: (checkpointId: string, position: \"before\" | \"turn_end\") => Promise<void>\n}\n\nconst ROW_HEIGHT = 32\nconst SVG_WIDTH = 44\n\ninterface LayoutNode {\n id: string\n column: number\n row: number\n parentRow: number | null\n parentColumn: number | null\n isActive: boolean\n isCurrent: boolean\n isVirtual: boolean\n preview: string\n content: string\n}\n\ninterface LayoutGraph {\n nodes: LayoutNode[]\n hasCycle: boolean\n maxColumn: number\n maxRow: number\n}\n\nexport function SessionBranchPicker({\n tree,\n disabled = false,\n onCheckout,\n}: SessionBranchPickerProps) {\n const [checkoutError, setCheckoutError] = useState<string | null>(null)\n const [pendingNodeId, setPendingNodeId] = useState<string | null>(null)\n const hasHistory = tree.nodes.length > 0\n const layout = useMemo(() => buildLayoutNodes(tree), [tree])\n const nodeMap = useMemo(() => new Map(tree.nodes.map((node) => [node.id, node])), [tree])\n const isBusy = disabled || pendingNodeId !== null\n const graphHeight = Math.max((layout.maxRow + 1) * ROW_HEIGHT, ROW_HEIGHT)\n const graphWidth = Math.max(SVG_WIDTH, getColumnX(layout.maxColumn) + 12)\n\n async function checkoutNode(node: CheckpointNode, position: \"before\" | \"turn_end\") {\n if (isBusy) return\n setCheckoutError(null)\n setPendingNodeId(node.id)\n try {\n await onCheckout(node.id, position)\n } catch (error) {\n setCheckoutError(error instanceof Error ? error.message : \"切换失败,请稍后重试\")\n } finally {\n setPendingNodeId(null)\n }\n }\n\n async function handleVirtualClick(node: LayoutNode) {\n if (isBusy || !node.isVirtual || node.isActive) return\n const sourceNode = nodeMap.get(node.content)\n if (sourceNode) await checkoutNode(sourceNode, \"turn_end\")\n }\n\n async function handleNodeSelect(node: LayoutNode) {\n if (isBusy) return\n const sourceNode = nodeMap.get(node.id)\n if (sourceNode) await checkoutNode(sourceNode, \"before\")\n }\n\n if (!hasHistory) return null\n\n return (\n <Tooltip.Provider delayDuration={200}>\n {checkoutError ? (\n <p role=\"alert\" className=\"mb-2 text-xs text-destructive\">\n {checkoutError}\n </p>\n ) : null}\n <div className=\"flex max-h-52 justify-center overflow-x-auto overflow-y-auto\">\n <div className=\"relative\" style={{ height: graphHeight, width: graphWidth }}>\n <svg\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-0 top-0 z-10 overflow-visible\"\n width={graphWidth}\n height={graphHeight}\n viewBox={`0 0 ${graphWidth} ${graphHeight}`}\n fill=\"none\"\n >\n {layout.nodes.map((node) => {\n if (node.parentRow == null || node.parentColumn == null) {\n return null\n }\n\n const childStroke = node.isActive\n ? \"hsl(var(--primary))\"\n : \"hsl(var(--muted-foreground))\"\n\n return (\n <path\n key={`path-${node.id}`}\n d={buildEdgePath(\n getColumnX(node.parentColumn),\n getRowY(node.parentRow),\n getColumnX(node.column),\n getRowY(node.row),\n )}\n stroke={childStroke}\n strokeOpacity={node.isActive ? 0.95 : 0.45}\n strokeWidth={node.isActive ? 1.8 : 1.4}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeDasharray={node.isVirtual ? \"3 3\" : undefined}\n />\n )\n })}\n </svg>\n\n <div className=\"relative z-0 h-full\">\n {layout.nodes.map((node) => {\n const isPendingNode = pendingNodeId === node.id\n const color = node.isActive ? \"hsl(var(--primary))\" : \"hsl(var(--muted-foreground))\"\n const previewText = node.isVirtual\n ? isPendingNode\n ? \"切换中...\"\n : \"\"\n : isPendingNode\n ? \"切换中...\"\n : node.preview\n const shouldShowTooltip = !node.isVirtual || Boolean(previewText)\n const button = (\n <button\n type=\"button\"\n onClick={() =>\n void (node.isVirtual ? handleVirtualClick(node) : handleNodeSelect(node))\n }\n disabled={isBusy}\n aria-current={!node.isVirtual && node.isCurrent ? \"step\" : undefined}\n aria-label={node.isVirtual ? \"切换到该分支\" : node.preview}\n className={cn(\n \"absolute z-20 m-0 h-8 w-6 overflow-visible border-0 bg-transparent p-0\",\n isBusy ? \"cursor-not-allowed opacity-60\" : \"cursor-pointer\",\n )}\n style={{\n top: node.row * ROW_HEIGHT,\n left: getColumnX(node.column) - 12,\n }}\n >\n <span aria-hidden=\"true\" className=\"absolute left-0 top-0 h-8 w-6\">\n <svg\n aria-hidden=\"true\"\n role=\"img\"\n className=\"pointer-events-none absolute left-0 top-0 h-full w-full overflow-visible\"\n width={24}\n height={ROW_HEIGHT}\n viewBox={`0 0 24 ${ROW_HEIGHT}`}\n fill=\"none\"\n >\n {node.isVirtual ? (\n <circle\n cx={12}\n cy={ROW_HEIGHT / 2}\n r={3.5}\n fill=\"none\"\n stroke={color}\n strokeWidth={1.2}\n strokeDasharray=\"2 2\"\n opacity={0.7}\n />\n ) : (\n <g>\n {node.isCurrent ? (\n <circle cx={12} cy={ROW_HEIGHT / 2} r={9} fill={color} opacity={0.18} />\n ) : null}\n <circle\n cx={12}\n cy={ROW_HEIGHT / 2}\n r={node.isCurrent ? 5.5 : 4}\n fill={color}\n />\n </g>\n )}\n </svg>\n </span>\n </button>\n )\n\n if (!shouldShowTooltip) {\n return <div key={node.id}>{button}</div>\n }\n\n return (\n <Tooltip.Root key={node.id}>\n <Tooltip.Trigger asChild>{button}</Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Content\n side=\"right\"\n sideOffset={8}\n className={cn(\n \"z-[60] rounded-md border border-border bg-popover px-2 py-1 text-xs text-foreground shadow-md\",\n !node.isVirtual && node.isCurrent && \"font-semibold\",\n )}\n >\n {previewText}\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n )\n })}\n </div>\n </div>\n </div>\n </Tooltip.Provider>\n )\n}\nfunction buildLayoutNodes(tree: CheckpointTree | undefined): LayoutGraph {\n if (!tree || tree.nodes.length === 0) {\n return { nodes: [], hasCycle: false, maxColumn: 0, maxRow: 0 }\n }\n\n const nodeMap = new Map(tree.nodes.map((node) => [node.id, node]))\n const order = new Map(tree.nodes.map((node, index) => [node.id, index]))\n const childrenMap = new Map<string | null, CheckpointNode[]>()\n\n for (const node of tree.nodes) {\n const parentId = node.parent_id && nodeMap.has(node.parent_id) ? node.parent_id : null\n const siblings = childrenMap.get(parentId) ?? []\n siblings.push(node)\n childrenMap.set(parentId, siblings)\n }\n\n const activeIds = new Set<string>()\n const activeVisited = new Set<string>()\n const leafId = tree.leaf_id\n let current = tree.leaf_id\n\n while (current && nodeMap.has(current) && !activeVisited.has(current)) {\n activeIds.add(current)\n activeVisited.add(current)\n current = nodeMap.get(current)?.parent_id ?? null\n }\n\n const layoutNodes: LayoutNode[] = []\n const placed = new Set<string>()\n const visiting = new Set<string>()\n let nextColumn = 1\n let maxColumn = 0\n let maxRow = 0\n let hasCycle = false\n\n const rootSort = (a: CheckpointNode, b: CheckpointNode) =>\n (order.get(a.id) ?? 0) - (order.get(b.id) ?? 0)\n\n const childSort = (a: CheckpointNode, b: CheckpointNode) =>\n (order.get(a.id) ?? 0) - (order.get(b.id) ?? 0)\n\n const allocateColumn = () => {\n const fresh = nextColumn\n nextColumn += 1\n return fresh\n }\n\n function walk(node: CheckpointNode, parent: LayoutNode | null, column: number, row: number) {\n if (visiting.has(node.id)) {\n hasCycle = true\n return\n }\n\n if (placed.has(node.id)) {\n return\n }\n\n visiting.add(node.id)\n maxColumn = Math.max(maxColumn, column)\n maxRow = Math.max(maxRow, row)\n\n const layoutNode: LayoutNode = {\n id: node.id,\n column,\n row,\n parentRow: parent?.row ?? null,\n parentColumn: parent?.column ?? null,\n isActive: activeIds.has(node.id),\n isCurrent: node.id === leafId,\n isVirtual: false,\n preview: formatPreview(node.content_preview),\n content: node.content,\n }\n\n layoutNodes.push(layoutNode)\n placed.add(node.id)\n\n const children = [...(childrenMap.get(node.id) ?? [])].sort(childSort)\n\n if (children.length === 0) {\n const virtualRow = row + 1\n maxRow = Math.max(maxRow, virtualRow)\n layoutNodes.push({\n id: `__virtual__${node.id}`,\n column,\n row: virtualRow,\n parentRow: layoutNode.row,\n parentColumn: layoutNode.column,\n isActive: activeIds.has(node.id),\n isCurrent: false,\n isVirtual: true,\n preview: \"\",\n content: node.id,\n })\n } else {\n for (const [index, child] of children.entries()) {\n if (visiting.has(child.id)) {\n hasCycle = true\n continue\n }\n\n const childColumn = index === 0 ? column : allocateColumn()\n walk(child, layoutNode, childColumn, row + 1)\n }\n }\n\n visiting.delete(node.id)\n }\n\n const roots = [...(childrenMap.get(null) ?? [])].sort(rootSort)\n for (const [index, root] of roots.entries()) {\n const rootColumn = index === 0 ? 0 : allocateColumn()\n walk(root, null, rootColumn, 0)\n }\n\n for (const node of [...tree.nodes].sort(rootSort)) {\n if (!placed.has(node.id)) {\n hasCycle = true\n const rootColumn = layoutNodes.length === 0 ? 0 : allocateColumn()\n walk(node, null, rootColumn, 0)\n }\n }\n\n return {\n nodes: layoutNodes,\n hasCycle,\n maxColumn,\n maxRow,\n }\n}\n\nfunction formatPreview(preview: string): string {\n const normalized = preview.replace(/\\s+/g, \" \").trim()\n return normalized.length > 0 ? normalized : \"(空消息)\"\n}\n\nfunction getColumnX(column: number): number {\n return 12 + column * 24\n}\n\nfunction getRowY(row: number): number {\n return row * ROW_HEIGHT + ROW_HEIGHT / 2\n}\n\nfunction buildEdgePath(fromX: number, fromY: number, toX: number, toY: number): string {\n if (fromX === toX || fromY === toY) {\n return `M ${fromX} ${fromY} L ${toX} ${toY}`\n }\n\n const r = Math.min(5, Math.abs(toX - fromX), Math.abs(toY - fromY))\n const dx = toX > fromX ? 1 : -1\n\n return [\n `M ${fromX} ${fromY}`,\n `H ${toX - dx * r}`,\n `A ${r} ${r} 0 0 ${dx > 0 ? 1 : 0} ${toX} ${fromY + r}`,\n `V ${toY}`,\n ].join(\" \")\n}\n"],"mappings":"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","names":["useRef","jsx","useRef","useState","jsx","jsxs","useState"]}
|
|
1
|
+
{"version":3,"sources":["../src/internal.ts","../src/lib/mount-renderers.tsx","../src/components/SessionMemoryToggle.tsx","../src/components/SessionBranchPicker.tsx"],"sourcesContent":["export * from \"./index\"\nexport * from \"./chat\"\nexport { useBladeHost, useOptionalBladeClient } from \"./context\"\nexport { MountHostContext, MountSlot, mountRenderersToReact } from \"./lib/mount-renderers\"\n\nexport { useLlmChat } from \"./hooks/use-llm-chat\"\nexport { useMessagePin } from \"./hooks/use-message-pin\"\nexport type { UseMessagePinOptions } from \"./hooks/use-message-pin\"\nexport { useTypewriterReveal } from \"./hooks/use-typewriter-reveal\"\nexport type { UseTypewriterRevealResult } from \"./hooks/use-typewriter-reveal\"\nexport {\n latestUserSpeechEntryId,\n TURN_NAV_HIGHLIGHT_CLASS,\n turnNavItemsFromMessages,\n useTurnNavigation,\n} from \"./hooks/use-turn-navigation\"\nexport type {\n TurnNavigationOptions,\n TurnNavigationResult,\n TurnNavigationSource,\n} from \"./hooks/use-turn-navigation\"\nexport type { UseLlmChatResult } from \"./hooks/use-llm-chat\"\n\nexport { ConnectorPanel } from \"./components/ConnectorPanel\"\nexport type { ConnectorPanelProps } from \"./components/ConnectorPanel\"\nexport { PluginConnectorList } from \"./components/PluginConnectorList\"\nexport type { ConfiguringPlugin, PluginConnectorListProps } from \"./components/PluginConnectorList\"\nexport { useSessionPluginActivation } from \"./components/use-session-plugin-activation\"\nexport type { UseSessionPluginActivationResult } from \"./components/use-session-plugin-activation\"\nexport {\n catalogToConnectorItems,\n filterConnectorItems,\n mergeConnectorItems,\n} from \"./components/plugin-connector\"\nexport type { PluginConnectorItem } from \"./components/plugin-connector\"\nexport { selectionFromItem, triggerSummary, TRIGGER_ICON_LIMIT } from \"./components/connector-panel-types\"\nexport type {\n PluginConnectorSelection,\n TriggerSummary,\n} from \"./components/connector-panel-types\"\nexport { SessionPluginSelector } from \"./components/SessionPluginSelector\"\nexport type { SessionPluginSelectorProps } from \"./components/SessionPluginSelector\"\nexport { SessionPluginIcon, sessionPluginLabel } from \"./components/SessionPluginIcon\"\nexport type { SessionPluginIconProps, SessionPluginLabelProps } from \"./components/SessionPluginIcon\"\nexport { PluginTriggerStack } from \"./components/PluginTriggerStack\"\nexport type { PluginTriggerStackProps } from \"./components/PluginTriggerStack\"\nexport { SessionPluginConfigDialog } from \"./components/SessionPluginConfigDialog\"\nexport type { SessionPluginConfigDialogProps } from \"./components/SessionPluginConfigDialog\"\nexport { SessionPluginConfigForm } from \"./components/SessionPluginConfigForm\"\nexport type {\n SessionPluginConfigDraft,\n SessionPluginConfigFormProps,\n} from \"./components/SessionPluginConfigForm\"\nexport { AgentChat } from \"./components/AgentChat\"\nexport type { AgentChatProps } from \"./components/AgentChat\"\nexport { LlmChat } from \"./components/LlmChat\"\nexport type { LlmChatProps } from \"./components/LlmChat\"\nexport type { LlmAdvancedSettings, LlmOverride } from \"./components/LlmAdvancedSettings\"\nexport { DEFAULT_ALLOWED_TAGS, MarkdownRenderer } from \"./components/markdown\"\nexport type {\n AllowedTags,\n CodeBlockOverrides,\n LinkSafetyConfig,\n MarkdownComponents,\n MarkdownRendererProps,\n RawHtmlPlugin,\n} from \"./components/markdown\"\nexport { WhatIfUserBubble } from \"./components/WhatIfUserBubble\"\nexport type { WhatIfUserBubbleProps } from \"./components/WhatIfUserBubble\"\nexport { parseWhatIfPrompt } from \"./lib/whatif-prompt\"\nexport type { ParsedWhatIfPrompt, WhatIfQuote } from \"./lib/whatif-prompt\"\nexport {\n getPlanUpdateDisplayState,\n isPlanUpdateTool,\n PLAN_AUTO_COLLAPSE_MS,\n parsePlanUpdate,\n pickCurrentPlanStep,\n PlanUpdateBlock,\n} from \"./components/PlanUpdateBlock\"\nexport type { PlanUpdateDisplayState } from \"./components/PlanUpdateBlock\"\nexport { ContextCard, ContextGroupCard } from \"./components/ContextCard\"\nexport type { ContextCardProps, ContextGroupCardProps } from \"./components/ContextCard\"\nexport { ToolUiCardView } from \"./components/ToolUiCardView\"\nexport { McpAppCard } from \"./components/McpAppCard\"\nexport type { McpAppMessage } from \"./components/McpAppCard\"\nexport { SessionMemoryToggle } from \"./components/SessionMemoryToggle\"\nexport type { SessionMemoryToggleProps } from \"./components/SessionMemoryToggle\"\nexport { SessionQueuePanel, isQueuePanelVisible } from \"./components/SessionQueuePanel\"\nexport type { SessionQueuePanelProps } from \"./components/SessionQueuePanel\"\n\nexport { SessionBranchPicker } from \"./components/SessionBranchPicker\"\nexport type { SessionBranchPickerProps } from \"./components/SessionBranchPicker\"\n\nexport { MessageImage, type MessageImageProps } from \"./components/MessageImage\"\n\nexport { BackgroundWakeNotice } from \"./components/BackgroundWakeNotice\"\n\nexport { TopicAssetSubmitDialog, useTopicAssetSubmissionAccess } from \"./components/TopicAssetSubmitDialog\"\nexport type { TopicAssetSubmitDialogProps } from \"./components/TopicAssetSubmitDialog\"\n\nexport { CodeBlockPre } from \"./chat/markdown/MarkdownContent\"\n\nexport { ChatLoadingIndicator, isPreparingReply } from \"./chat/ChatLoadingIndicator\"\n\nexport { BrowserConnectionDialog } from \"./components/BrowserConnectionDialog\"\n\nexport { AccountConnectors } from \"./components/AccountConnectors\"\n\nexport { McpAppFrame } from \"./components/McpAppFrame\"\nexport type { McpAppFrameProps } from \"./components/McpAppFrame\"\n","import type {\n BladeChatMountRenderers,\n MountHandle,\n MountRenderer,\n MountRendererObject,\n MountResult,\n} from \"@blade-hq/agent-client\"\nimport { createContext, useContext, useId, useLayoutEffect, useRef, type ReactNode } from \"react\"\nimport type { ChatViewRenderers } from \"../chat/customization\"\n\n/**\n * 挂载节点放在哪里。\n *\n * `<blade-chat>` 把它设成元素本身:挂载节点作为元素的 light DOM 子节点,经 Shadow DOM\n * 里的 `<slot>` 显示在区块位置,宿主页面的样式(包括 Vue 的 scoped 样式)直接生效。\n * 没有设置时(npm 包里),挂载节点就是组件内的一个 div。\n */\nexport const MountHostContext = createContext<HTMLElement | null>(null)\n\nfunction normalizeResult<T>(result: MountResult<T>): MountHandle<T> {\n if (typeof result === \"function\") return { destroy: result }\n if (result && typeof result === \"object\") return result\n return { destroy: () => {} }\n}\n\nfunction toObject<T>(renderer: MountRenderer<T>): MountRendererObject<T> {\n return typeof renderer === \"function\" ? { mount: renderer } : renderer\n}\n\nfunction sameData(a: object, b: object): boolean {\n const aKeys = Object.keys(a)\n if (aKeys.length !== Object.keys(b).length) return false\n return aKeys.every((key) => Object.is((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key]))\n}\n\ninterface MountSlotProps<T extends object> {\n renderer: MountRendererObject<T>\n data: T\n}\n\n/** 给宿主一个 DOM 节点挂自己的内容;数据变化时原地更新或清理后重挂,卸载时清理。 */\nexport function MountSlot<T extends object>({ renderer, data }: MountSlotProps<T>) {\n const host = useContext(MountHostContext)\n const slotName = `blade-mount-${useId().replace(/[^a-zA-Z0-9_-]/g, \"\")}`\n const localRef = useRef<HTMLDivElement>(null)\n const dataRef = useRef(data)\n const mountedRef = useRef<{ target: HTMLElement; handle: MountHandle<T>; data: T } | null>(null)\n\n useLayoutEffect(() => {\n dataRef.current = data\n })\n\n useLayoutEffect(() => {\n let target: HTMLElement\n if (host) {\n target = document.createElement(\"div\")\n target.slot = slotName\n host.appendChild(target)\n } else {\n if (!localRef.current) return\n target = localRef.current\n }\n const initial = dataRef.current\n mountedRef.current = { target, handle: normalizeResult(renderer.mount(target, initial)), data: initial }\n return () => {\n const mounted = mountedRef.current\n mountedRef.current = null\n mounted?.handle.destroy()\n if (host) target.remove()\n else target.replaceChildren()\n }\n }, [host, renderer, slotName])\n\n useLayoutEffect(() => {\n const mounted = mountedRef.current\n if (!mounted || sameData(mounted.data, data)) return\n mounted.data = data\n if (mounted.handle.update) {\n mounted.handle.update(data)\n return\n }\n mounted.handle.destroy()\n mounted.target.replaceChildren()\n mounted.handle = normalizeResult(renderer.mount(mounted.target, data))\n }, [data, renderer])\n\n return host ? <slot name={slotName} /> : <div ref={localRef} data-blade-mount=\"\" />\n}\n\nfunction slotFor<T extends object>(renderer: MountRendererObject<T>, data: T): ReactNode | null {\n if (renderer.match && !renderer.match(data)) return null\n return <MountSlot renderer={renderer} data={data} />\n}\n\n/**\n * 把挂载式渲染器转成普通 React 渲染器:两种写法走同一条渲染路径,`match` 返回\n * false 等于 React 渲染器返回 null(走默认渲染)。调用方要按 `renderers` 对象缓存结果,\n * 否则每次渲染都会得到新的渲染器、挂载内容被反复重建。\n */\nexport function mountRenderersToReact(\n renderers: BladeChatMountRenderers | null | undefined,\n context: { sessionId?: string } = {},\n): ChatViewRenderers | undefined {\n if (!renderers) return undefined\n const result: ChatViewRenderers = {}\n if (renderers.toolCall) {\n const renderer = toObject(renderers.toolCall)\n result.toolCall = (toolCall) => slotFor(renderer, { toolCall, sessionId: context.sessionId })\n }\n if (renderers.userMessage) {\n const renderer = toObject(renderers.userMessage)\n result.userMessage = ({ message }) => slotFor(renderer, { message })\n }\n if (renderers.assistantText) {\n const renderer = toObject(renderers.assistantText)\n result.assistantText = ({ message, streaming, compact, sessionId }) =>\n slotFor(renderer, { message, streaming, compact, sessionId })\n }\n return result\n}\n","import type { BladeClient } from \"@blade-hq/agent-client\"\nimport { useCallback, useEffect, useRef, useState, useSyncExternalStore } from \"react\"\nimport { useOptionalBladeClient } from \"../context\"\nimport { cn } from \"../lib/utils\"\n\ninterface SaveState {\n saving: boolean\n listeners: Set<() => void>\n}\n\nconst saveStates = new WeakMap<BladeClient, Map<string, SaveState>>()\n\nfunction getSaveState(client: BladeClient, sessionId: string): SaveState {\n let clientStates = saveStates.get(client)\n if (!clientStates) {\n clientStates = new Map()\n saveStates.set(client, clientStates)\n }\n let state = clientStates.get(sessionId)\n if (!state) {\n state = { saving: false, listeners: new Set() }\n clientStates.set(sessionId, state)\n }\n return state\n}\n\nfunction notify(state: SaveState) {\n for (const listener of state.listeners) listener()\n}\n\nfunction cleanupSaveState(client: BladeClient, sessionId: string, state: SaveState) {\n if (state.saving || state.listeners.size > 0) return\n const clientStates = saveStates.get(client)\n if (clientStates?.get(sessionId) === state) clientStates.delete(sessionId)\n}\n\nexport interface SessionMemoryToggleProps {\n sessionId: string\n enabled: boolean\n /** 不在 BladeProvider 内使用时显式传入,与宿主现有 BladeClient 复用连接和鉴权。 */\n client?: BladeClient\n disabled?: boolean\n label?: string\n className?: string\n labelClassName?: string\n inputClassName?: string\n onSaved?: (sessionId: string, enabled: boolean) => void\n onError?: (error: unknown) => void\n}\n\n/**\n * 当前会话记忆开关。同一 client + sessionId 的所有实例共享保存锁,避免多个聊天入口\n * 或会话切换时发出乱序更新;服务端成功后才通过 onSaved 交还权威值。\n */\nexport function SessionMemoryToggle({\n sessionId,\n enabled,\n client: clientProp,\n disabled = false,\n label = \"当前会话使用记忆\",\n className,\n labelClassName,\n inputClassName,\n onSaved,\n onError,\n}: SessionMemoryToggleProps) {\n const contextClient = useOptionalBladeClient()\n const client = clientProp ?? contextClient\n if (!client) {\n throw new Error(\"SessionMemoryToggle 必须在 <BladeProvider> 内使用或显式传入 client\")\n }\n\n const saveState = getSaveState(client, sessionId)\n const subscribe = useCallback(\n (listener: () => void) => {\n saveState.listeners.add(listener)\n return () => {\n saveState.listeners.delete(listener)\n cleanupSaveState(client, sessionId, saveState)\n }\n },\n [client, saveState, sessionId],\n )\n const getSaving = useCallback(() => saveState.saving, [saveState])\n const saving = useSyncExternalStore(\n subscribe,\n getSaving,\n getSaving,\n )\n const [draftEnabled, setDraftEnabled] = useState(enabled)\n const activeSessionIdRef = useRef(sessionId)\n activeSessionIdRef.current = sessionId\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: a new session must discard this component instance's optimistic value even when both sessions share the same enabled prop\n useEffect(() => {\n setDraftEnabled(enabled)\n }, [enabled, sessionId])\n\n const update = useCallback(\n (nextEnabled: boolean) => {\n const currentSaveState = getSaveState(client, sessionId)\n if (currentSaveState.saving) return\n currentSaveState.saving = true\n notify(currentSaveState)\n setDraftEnabled(nextEnabled)\n\n void client.sessions.updateSessionMemory(sessionId, nextEnabled).then(\n (updated) => {\n if (activeSessionIdRef.current === sessionId) {\n setDraftEnabled(updated.memory_enabled)\n }\n onSaved?.(sessionId, updated.memory_enabled)\n },\n (error) => {\n if (activeSessionIdRef.current === sessionId) setDraftEnabled(enabled)\n onError?.(error)\n },\n ).finally(() => {\n currentSaveState.saving = false\n notify(currentSaveState)\n cleanupSaveState(client, sessionId, currentSaveState)\n })\n },\n [client, enabled, onError, onSaved, sessionId],\n )\n\n return (\n <label className={cn(\"flex items-center justify-between\", className)}>\n <span className={labelClassName}>{label}</span>\n <input\n type=\"checkbox\"\n checked={draftEnabled}\n onChange={(event) => update(event.target.checked)}\n disabled={disabled || saving}\n className={inputClassName}\n />\n </label>\n )\n}\n","import type { BladeClient } from \"@blade-hq/agent-client\"\nimport * as Tooltip from \"@radix-ui/react-tooltip\"\nimport { useMemo, useState } from \"react\"\nimport { cn } from \"../lib/utils\"\n\ntype CheckpointTree = Awaited<ReturnType<BladeClient[\"sessions\"][\"getSessionCheckpoints\"]>>\ntype CheckpointNode = CheckpointTree[\"nodes\"][number]\n\nexport interface SessionBranchPickerProps {\n tree: CheckpointTree\n /** Disable changes while this session is running or read-only. */\n disabled?: boolean\n /** Restore only the conversation; the host owns history refresh and composer drafts. */\n onCheckout: (checkpointId: string, position: \"before\" | \"turn_end\") => Promise<void>\n}\n\nconst ROW_HEIGHT = 32\nconst SVG_WIDTH = 44\n\ninterface LayoutNode {\n id: string\n column: number\n row: number\n parentRow: number | null\n parentColumn: number | null\n isActive: boolean\n isCurrent: boolean\n isVirtual: boolean\n preview: string\n content: string\n}\n\ninterface LayoutGraph {\n nodes: LayoutNode[]\n hasCycle: boolean\n maxColumn: number\n maxRow: number\n}\n\nexport function SessionBranchPicker({\n tree,\n disabled = false,\n onCheckout,\n}: SessionBranchPickerProps) {\n const [checkoutError, setCheckoutError] = useState<string | null>(null)\n const [pendingNodeId, setPendingNodeId] = useState<string | null>(null)\n const hasHistory = tree.nodes.length > 0\n const layout = useMemo(() => buildLayoutNodes(tree), [tree])\n const nodeMap = useMemo(() => new Map(tree.nodes.map((node) => [node.id, node])), [tree])\n const isBusy = disabled || pendingNodeId !== null\n const graphHeight = Math.max((layout.maxRow + 1) * ROW_HEIGHT, ROW_HEIGHT)\n const graphWidth = Math.max(SVG_WIDTH, getColumnX(layout.maxColumn) + 12)\n\n async function checkoutNode(node: CheckpointNode, position: \"before\" | \"turn_end\") {\n if (isBusy) return\n setCheckoutError(null)\n setPendingNodeId(node.id)\n try {\n await onCheckout(node.id, position)\n } catch (error) {\n setCheckoutError(error instanceof Error ? error.message : \"切换失败,请稍后重试\")\n } finally {\n setPendingNodeId(null)\n }\n }\n\n async function handleVirtualClick(node: LayoutNode) {\n if (isBusy || !node.isVirtual || node.isActive) return\n const sourceNode = nodeMap.get(node.content)\n if (sourceNode) await checkoutNode(sourceNode, \"turn_end\")\n }\n\n async function handleNodeSelect(node: LayoutNode) {\n if (isBusy) return\n const sourceNode = nodeMap.get(node.id)\n if (sourceNode) await checkoutNode(sourceNode, \"before\")\n }\n\n if (!hasHistory) return null\n\n return (\n <Tooltip.Provider delayDuration={200}>\n {checkoutError ? (\n <p role=\"alert\" className=\"mb-2 text-xs text-destructive\">\n {checkoutError}\n </p>\n ) : null}\n <div className=\"flex max-h-52 justify-center overflow-x-auto overflow-y-auto\">\n <div className=\"relative\" style={{ height: graphHeight, width: graphWidth }}>\n <svg\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-0 top-0 z-10 overflow-visible\"\n width={graphWidth}\n height={graphHeight}\n viewBox={`0 0 ${graphWidth} ${graphHeight}`}\n fill=\"none\"\n >\n {layout.nodes.map((node) => {\n if (node.parentRow == null || node.parentColumn == null) {\n return null\n }\n\n const childStroke = node.isActive\n ? \"hsl(var(--primary))\"\n : \"hsl(var(--muted-foreground))\"\n\n return (\n <path\n key={`path-${node.id}`}\n d={buildEdgePath(\n getColumnX(node.parentColumn),\n getRowY(node.parentRow),\n getColumnX(node.column),\n getRowY(node.row),\n )}\n stroke={childStroke}\n strokeOpacity={node.isActive ? 0.95 : 0.45}\n strokeWidth={node.isActive ? 1.8 : 1.4}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeDasharray={node.isVirtual ? \"3 3\" : undefined}\n />\n )\n })}\n </svg>\n\n <div className=\"relative z-0 h-full\">\n {layout.nodes.map((node) => {\n const isPendingNode = pendingNodeId === node.id\n const color = node.isActive ? \"hsl(var(--primary))\" : \"hsl(var(--muted-foreground))\"\n const previewText = node.isVirtual\n ? isPendingNode\n ? \"切换中...\"\n : \"\"\n : isPendingNode\n ? \"切换中...\"\n : node.preview\n const shouldShowTooltip = !node.isVirtual || Boolean(previewText)\n const button = (\n <button\n type=\"button\"\n onClick={() =>\n void (node.isVirtual ? handleVirtualClick(node) : handleNodeSelect(node))\n }\n disabled={isBusy}\n aria-current={!node.isVirtual && node.isCurrent ? \"step\" : undefined}\n aria-label={node.isVirtual ? \"切换到该分支\" : node.preview}\n className={cn(\n \"absolute z-20 m-0 h-8 w-6 overflow-visible border-0 bg-transparent p-0\",\n isBusy ? \"cursor-not-allowed opacity-60\" : \"cursor-pointer\",\n )}\n style={{\n top: node.row * ROW_HEIGHT,\n left: getColumnX(node.column) - 12,\n }}\n >\n <span aria-hidden=\"true\" className=\"absolute left-0 top-0 h-8 w-6\">\n <svg\n aria-hidden=\"true\"\n role=\"img\"\n className=\"pointer-events-none absolute left-0 top-0 h-full w-full overflow-visible\"\n width={24}\n height={ROW_HEIGHT}\n viewBox={`0 0 24 ${ROW_HEIGHT}`}\n fill=\"none\"\n >\n {node.isVirtual ? (\n <circle\n cx={12}\n cy={ROW_HEIGHT / 2}\n r={3.5}\n fill=\"none\"\n stroke={color}\n strokeWidth={1.2}\n strokeDasharray=\"2 2\"\n opacity={0.7}\n />\n ) : (\n <g>\n {node.isCurrent ? (\n <circle cx={12} cy={ROW_HEIGHT / 2} r={9} fill={color} opacity={0.18} />\n ) : null}\n <circle\n cx={12}\n cy={ROW_HEIGHT / 2}\n r={node.isCurrent ? 5.5 : 4}\n fill={color}\n />\n </g>\n )}\n </svg>\n </span>\n </button>\n )\n\n if (!shouldShowTooltip) {\n return <div key={node.id}>{button}</div>\n }\n\n return (\n <Tooltip.Root key={node.id}>\n <Tooltip.Trigger asChild>{button}</Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Content\n side=\"right\"\n sideOffset={8}\n className={cn(\n \"z-[60] rounded-md border border-border bg-popover px-2 py-1 text-xs text-foreground shadow-md\",\n !node.isVirtual && node.isCurrent && \"font-semibold\",\n )}\n >\n {previewText}\n </Tooltip.Content>\n </Tooltip.Portal>\n </Tooltip.Root>\n )\n })}\n </div>\n </div>\n </div>\n </Tooltip.Provider>\n )\n}\nfunction buildLayoutNodes(tree: CheckpointTree | undefined): LayoutGraph {\n if (!tree || tree.nodes.length === 0) {\n return { nodes: [], hasCycle: false, maxColumn: 0, maxRow: 0 }\n }\n\n const nodeMap = new Map(tree.nodes.map((node) => [node.id, node]))\n const order = new Map(tree.nodes.map((node, index) => [node.id, index]))\n const childrenMap = new Map<string | null, CheckpointNode[]>()\n\n for (const node of tree.nodes) {\n const parentId = node.parent_id && nodeMap.has(node.parent_id) ? node.parent_id : null\n const siblings = childrenMap.get(parentId) ?? []\n siblings.push(node)\n childrenMap.set(parentId, siblings)\n }\n\n const activeIds = new Set<string>()\n const activeVisited = new Set<string>()\n const leafId = tree.leaf_id\n let current = tree.leaf_id\n\n while (current && nodeMap.has(current) && !activeVisited.has(current)) {\n activeIds.add(current)\n activeVisited.add(current)\n current = nodeMap.get(current)?.parent_id ?? null\n }\n\n const layoutNodes: LayoutNode[] = []\n const placed = new Set<string>()\n const visiting = new Set<string>()\n let nextColumn = 1\n let maxColumn = 0\n let maxRow = 0\n let hasCycle = false\n\n const rootSort = (a: CheckpointNode, b: CheckpointNode) =>\n (order.get(a.id) ?? 0) - (order.get(b.id) ?? 0)\n\n const childSort = (a: CheckpointNode, b: CheckpointNode) =>\n (order.get(a.id) ?? 0) - (order.get(b.id) ?? 0)\n\n const allocateColumn = () => {\n const fresh = nextColumn\n nextColumn += 1\n return fresh\n }\n\n function walk(node: CheckpointNode, parent: LayoutNode | null, column: number, row: number) {\n if (visiting.has(node.id)) {\n hasCycle = true\n return\n }\n\n if (placed.has(node.id)) {\n return\n }\n\n visiting.add(node.id)\n maxColumn = Math.max(maxColumn, column)\n maxRow = Math.max(maxRow, row)\n\n const layoutNode: LayoutNode = {\n id: node.id,\n column,\n row,\n parentRow: parent?.row ?? null,\n parentColumn: parent?.column ?? null,\n isActive: activeIds.has(node.id),\n isCurrent: node.id === leafId,\n isVirtual: false,\n preview: formatPreview(node.content_preview),\n content: node.content,\n }\n\n layoutNodes.push(layoutNode)\n placed.add(node.id)\n\n const children = [...(childrenMap.get(node.id) ?? [])].sort(childSort)\n\n if (children.length === 0) {\n const virtualRow = row + 1\n maxRow = Math.max(maxRow, virtualRow)\n layoutNodes.push({\n id: `__virtual__${node.id}`,\n column,\n row: virtualRow,\n parentRow: layoutNode.row,\n parentColumn: layoutNode.column,\n isActive: activeIds.has(node.id),\n isCurrent: false,\n isVirtual: true,\n preview: \"\",\n content: node.id,\n })\n } else {\n for (const [index, child] of children.entries()) {\n if (visiting.has(child.id)) {\n hasCycle = true\n continue\n }\n\n const childColumn = index === 0 ? column : allocateColumn()\n walk(child, layoutNode, childColumn, row + 1)\n }\n }\n\n visiting.delete(node.id)\n }\n\n const roots = [...(childrenMap.get(null) ?? [])].sort(rootSort)\n for (const [index, root] of roots.entries()) {\n const rootColumn = index === 0 ? 0 : allocateColumn()\n walk(root, null, rootColumn, 0)\n }\n\n for (const node of [...tree.nodes].sort(rootSort)) {\n if (!placed.has(node.id)) {\n hasCycle = true\n const rootColumn = layoutNodes.length === 0 ? 0 : allocateColumn()\n walk(node, null, rootColumn, 0)\n }\n }\n\n return {\n nodes: layoutNodes,\n hasCycle,\n maxColumn,\n maxRow,\n }\n}\n\nfunction formatPreview(preview: string): string {\n const normalized = preview.replace(/\\s+/g, \" \").trim()\n return normalized.length > 0 ? normalized : \"(空消息)\"\n}\n\nfunction getColumnX(column: number): number {\n return 12 + column * 24\n}\n\nfunction getRowY(row: number): number {\n return row * ROW_HEIGHT + ROW_HEIGHT / 2\n}\n\nfunction buildEdgePath(fromX: number, fromY: number, toX: number, toY: number): string {\n if (fromX === toX || fromY === toY) {\n return `M ${fromX} ${fromY} L ${toX} ${toY}`\n }\n\n const r = Math.min(5, Math.abs(toX - fromX), Math.abs(toY - fromY))\n const dx = toX > fromX ? 1 : -1\n\n return [\n `M ${fromX} ${fromY}`,\n `H ${toX - dx * r}`,\n `A ${r} ${r} 0 0 ${dx > 0 ? 1 : 0} ${toX} ${fromY + r}`,\n `V ${toY}`,\n ].join(\" \")\n}\n"],"mappings":"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","names":["useRef","jsx","useRef","useState","jsx","jsxs","useState"]}
|
package/dist/questions.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MarkdownContent
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-XJ6ZA6LN.js";
|
|
4
|
+
import "./chunk-WRIMPZPN.js";
|
|
4
5
|
import {
|
|
5
6
|
Check,
|
|
6
7
|
LoaderCircle,
|
|
7
|
-
MessageSquareMore
|
|
8
|
-
} from "./chunk-VSIUEXGV.js";
|
|
9
|
-
import {
|
|
8
|
+
MessageSquareMore,
|
|
10
9
|
buttonVariants,
|
|
11
10
|
cn
|
|
12
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-QIR73CES.js";
|
|
13
12
|
import "./chunk-PR4QN5HX.js";
|
|
14
13
|
|
|
15
14
|
// src/chat/QuestionnaireQuestionBlock.tsx
|