@blocksdiy/react-common 1.22.1 → 1.24.0
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.
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
import { type Message, type UserMessage } from "@ag-ui/client";
|
|
2
2
|
import { ReactNode, SetStateAction } from "react";
|
|
3
3
|
export { type Message } from "@ag-ui/client";
|
|
4
|
-
export { useCopilotReadable } from "@copilotkit/react-core";
|
|
5
4
|
export { useRenderTool, useRenderToolCall, useDefaultRenderTool, useHumanInTheLoop } from "@copilotkit/react-core/v2";
|
|
6
5
|
export interface Attachment {
|
|
7
6
|
url: string;
|
|
8
7
|
fileType: string;
|
|
9
8
|
fileName: string;
|
|
10
9
|
}
|
|
10
|
+
export interface AgentChatComponent {
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
toolName?: string;
|
|
14
|
+
code?: string;
|
|
15
|
+
input?: Record<string, unknown>;
|
|
16
|
+
description?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare const getAgentChatComponentToolName: (name: string) => string;
|
|
11
19
|
export interface AgentChat {
|
|
12
|
-
initialMessages?: {
|
|
13
|
-
content: string;
|
|
14
|
-
}[];
|
|
15
20
|
initialPrompt?: {
|
|
16
21
|
content?: string;
|
|
17
22
|
hiddenContent?: string;
|
|
18
23
|
};
|
|
24
|
+
disableGeneratingDynamicChatComponent?: boolean;
|
|
25
|
+
hideToolsUi?: boolean;
|
|
19
26
|
}
|
|
20
27
|
export interface Agent {
|
|
21
28
|
id: string;
|
|
@@ -36,8 +43,10 @@ export interface AgentChatContextValue {
|
|
|
36
43
|
currentThreadId?: string;
|
|
37
44
|
agent: Agent | null;
|
|
38
45
|
agentChat: AgentChat | null;
|
|
46
|
+
components: AgentChatComponent[];
|
|
39
47
|
sendMessage: (message: Omit<UserMessage, "id" | "role">) => Promise<void>;
|
|
40
48
|
sendFromInputs: () => Promise<void>;
|
|
49
|
+
stopGeneration: () => void;
|
|
41
50
|
addAttachments: (attachments: Attachment[]) => void;
|
|
42
51
|
removeAttachment: (url: string) => void;
|
|
43
52
|
clearAttachments: () => void;
|
|
@@ -58,6 +67,7 @@ export interface AgentChatRootProps {
|
|
|
58
67
|
/** When true with `agentId`, route direct Deep Agent chat through the AI SDK UI-message stream. */
|
|
59
68
|
useAgentBlockDirectChat?: boolean;
|
|
60
69
|
agentChatId?: string;
|
|
70
|
+
componentIds?: string[];
|
|
61
71
|
defaultThreadId?: string;
|
|
62
72
|
noPersistency?: boolean;
|
|
63
73
|
children?: ReactNode;
|
|
@@ -65,7 +75,7 @@ export interface AgentChatRootProps {
|
|
|
65
75
|
chatContext?: any;
|
|
66
76
|
chatContextFiles?: Attachment[];
|
|
67
77
|
}
|
|
68
|
-
export declare const AgentChatRoot: ({ ...props }: AgentChatRootProps) => import("react/jsx-runtime").JSX.Element;
|
|
78
|
+
export declare const AgentChatRoot: ({ ...props }: AgentChatRootProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
69
79
|
export interface AgentChatMessageProps {
|
|
70
80
|
message: Message;
|
|
71
81
|
index: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"new-agent-chat.d.ts","sourceRoot":"","sources":["../../src/components/new-agent-chat.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAK/D,OAAO,EAEL,SAAS,EACT,cAAc,EAQf,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"new-agent-chat.d.ts","sourceRoot":"","sources":["../../src/components/new-agent-chat.tsx"],"names":[],"mappings":"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"}
|
|
@@ -4,12 +4,14 @@ import { getApiHost } from "@blocksdiy/blocks-client-api/envService";
|
|
|
4
4
|
import { CopilotKit, useCopilotChatInternal } from "@copilotkit/react-core";
|
|
5
5
|
import { Slot } from "@radix-ui/react-slot";
|
|
6
6
|
import { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState, } from "react";
|
|
7
|
+
export { useRenderTool, useRenderToolCall, useDefaultRenderTool, useHumanInTheLoop } from "@copilotkit/react-core/v2";
|
|
7
8
|
// Client-only `useLayoutEffect`, falls back to `useEffect` during SSR.
|
|
8
9
|
// Needed so the `agent.threadId` mirror commits before CopilotKit's
|
|
9
10
|
// connect-on-mount effect reads it.
|
|
10
11
|
const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
11
|
-
export
|
|
12
|
-
|
|
12
|
+
export const getAgentChatComponentToolName = (name) => {
|
|
13
|
+
return name.replace(/[^a-zA-Z0-9_-]/g, "_").toLowerCase();
|
|
14
|
+
};
|
|
13
15
|
const MAX_FILE_SIZE_MB = 5;
|
|
14
16
|
const MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * 1024 * 1024;
|
|
15
17
|
// CopilotKit v2 requires a UUID `thread_id`; non-UUIDs get replaced per
|
|
@@ -85,16 +87,17 @@ const SessionReadables = () => {
|
|
|
85
87
|
// });
|
|
86
88
|
return null;
|
|
87
89
|
};
|
|
88
|
-
const ChatInitializer = ({ agentId, agentChatId, chatId, token, appId, currentThreadId, setCurrentThreadId, children, }) => {
|
|
90
|
+
const ChatInitializer = ({ agentId, agentChatId, chatId, token, appId, componentIds, currentThreadId, setCurrentThreadId, children, }) => {
|
|
89
91
|
const [agentChat, setAgentChat] = useState(null);
|
|
90
92
|
const [agent, setAgent] = useState(null);
|
|
93
|
+
const [components, setComponents] = useState([]);
|
|
91
94
|
// `isConfigLoaded` covers the (small, parallel) async fetch of the
|
|
92
95
|
// agent + agentChat block configs. The actual chat transcript loads
|
|
93
96
|
// through CopilotKit's `connectAgent` pipeline, which surfaces via
|
|
94
97
|
// `isAvailable` below — see `isFetchingMessages` for the combined
|
|
95
98
|
// "are we still warming up" signal exposed to consumers.
|
|
96
99
|
const [isConfigLoaded, setIsConfigLoaded] = useState(false);
|
|
97
|
-
const { messages: copilotMessages, sendMessage: copilotSendMessage, isAvailable: isAgentReady, isLoading: isAgentRunning, agent: copilotAgent, } = useCopilotChatInternal();
|
|
100
|
+
const { messages: copilotMessages, sendMessage: copilotSendMessage, stopGeneration: copilotStopGeneration, isAvailable: isAgentReady, isLoading: isAgentRunning, agent: copilotAgent, } = useCopilotChatInternal();
|
|
98
101
|
// Mirror `currentThreadId` onto the agent instance — the `<CopilotKit>`
|
|
99
102
|
// prop only feeds React context, but `agent.threadId` is what hits the
|
|
100
103
|
// wire and the LangGraph checkpoint. `<CopilotChat>` does this for you;
|
|
@@ -111,9 +114,17 @@ const ChatInitializer = ({ agentId, agentChatId, chatId, token, appId, currentTh
|
|
|
111
114
|
const [attachments, setAttachments] = useState([]);
|
|
112
115
|
const [isDraggingFiles, setIsDraggingFiles] = useState(false);
|
|
113
116
|
const blocksApiService = useMemo(() => new BlocksApiService({ token }), [token]);
|
|
117
|
+
const canSendMessage = Boolean(agentChatId && agentChat && agent && isConfigLoaded && isAgentReady && !isAgentRunning);
|
|
114
118
|
const sendMessage = useCallback((message) => {
|
|
119
|
+
if (!canSendMessage) {
|
|
120
|
+
return Promise.resolve();
|
|
121
|
+
}
|
|
115
122
|
return copilotSendMessage({ id: generateId(), role: "user", ...message });
|
|
116
|
-
}, [copilotSendMessage]);
|
|
123
|
+
}, [canSendMessage, copilotSendMessage]);
|
|
124
|
+
const stopGeneration = useCallback(() => {
|
|
125
|
+
copilotStopGeneration();
|
|
126
|
+
copilotAgent?.abortRun?.();
|
|
127
|
+
}, [copilotAgent, copilotStopGeneration]);
|
|
117
128
|
const getAgentChatBlock = useCallback(async () => {
|
|
118
129
|
if (!agentChatId) {
|
|
119
130
|
return null;
|
|
@@ -124,6 +135,33 @@ const ChatInitializer = ({ agentId, agentChatId, chatId, token, appId, currentTh
|
|
|
124
135
|
}
|
|
125
136
|
return agentChatBlock;
|
|
126
137
|
}, [agentChatId, blocksApiService]);
|
|
138
|
+
const getChatComponentBlocks = useCallback(async () => {
|
|
139
|
+
if (!componentIds?.length) {
|
|
140
|
+
return [];
|
|
141
|
+
}
|
|
142
|
+
const maybeComponentBlocks = await Promise.all(componentIds.map(async (componentId) => {
|
|
143
|
+
try {
|
|
144
|
+
const block = await blocksApiService.getBlock(componentId);
|
|
145
|
+
const id = block?.id ?? componentId;
|
|
146
|
+
const name = block?.name;
|
|
147
|
+
if (!id || !name) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
id,
|
|
152
|
+
name,
|
|
153
|
+
code: block?.data?.code,
|
|
154
|
+
input: block?.data?.input,
|
|
155
|
+
description: block?.data?.description,
|
|
156
|
+
toolName: getAgentChatComponentToolName(name),
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
}));
|
|
163
|
+
return maybeComponentBlocks.filter((component) => Boolean(component));
|
|
164
|
+
}, [blocksApiService, componentIds]);
|
|
127
165
|
const sendAgentInitialPrompt = useCallback((agentInitialPrompt) => {
|
|
128
166
|
if (!agentInitialPrompt) {
|
|
129
167
|
return;
|
|
@@ -147,6 +185,7 @@ const ChatInitializer = ({ agentId, agentChatId, chatId, token, appId, currentTh
|
|
|
147
185
|
currentThreadId ?? "",
|
|
148
186
|
agentId ?? "",
|
|
149
187
|
agentChatId ?? "",
|
|
188
|
+
componentIds?.join(",") ?? "",
|
|
150
189
|
token ?? "",
|
|
151
190
|
appId ?? "",
|
|
152
191
|
].join("|");
|
|
@@ -161,7 +200,10 @@ const ChatInitializer = ({ agentId, agentChatId, chatId, token, appId, currentTh
|
|
|
161
200
|
try {
|
|
162
201
|
const agentChatBlock = await getAgentChatBlock();
|
|
163
202
|
const effectiveAgentId = agentId ?? agentChatBlock?.data?.agentBlockId;
|
|
164
|
-
const agentBlock =
|
|
203
|
+
const [agentBlock, chatComponentBlocks] = await Promise.all([
|
|
204
|
+
effectiveAgentId ? blocksApiService.getBlock(effectiveAgentId) : null,
|
|
205
|
+
getChatComponentBlocks(),
|
|
206
|
+
]);
|
|
165
207
|
if (ac.signal.aborted) {
|
|
166
208
|
return;
|
|
167
209
|
}
|
|
@@ -169,9 +211,11 @@ const ChatInitializer = ({ agentId, agentChatId, chatId, token, appId, currentTh
|
|
|
169
211
|
throw new Error("Agent chat configuration not found");
|
|
170
212
|
}
|
|
171
213
|
setAgentChat({
|
|
172
|
-
initialMessages: agentChatBlock.data.initialMessages,
|
|
173
214
|
initialPrompt: agentChatBlock.data.initialPrompt,
|
|
215
|
+
disableGeneratingDynamicChatComponent: agentChatBlock.data.disableGeneratingDynamicChatComponent,
|
|
216
|
+
hideToolsUi: agentChatBlock.data.hideToolsUi,
|
|
174
217
|
});
|
|
218
|
+
setComponents(chatComponentBlocks);
|
|
175
219
|
setAgent({
|
|
176
220
|
id: agentBlock.id,
|
|
177
221
|
title: agentBlock?.data?.title,
|
|
@@ -211,8 +255,18 @@ const ChatInitializer = ({ agentId, agentChatId, chatId, token, appId, currentTh
|
|
|
211
255
|
// a render-order race where `isAgentReady` flips true before the
|
|
212
256
|
// mirrored React state catches up, which would otherwise double-send
|
|
213
257
|
// the prompt on top of replayed history.
|
|
258
|
+
//
|
|
259
|
+
// `canSendMessage` is also part of the gate: `sendMessage` silently
|
|
260
|
+
// no-ops when its closed-over `canSendMessage` is false (e.g. while
|
|
261
|
+
// the `agent` mirror is committing or CopilotKit briefly reports
|
|
262
|
+
// `isLoading`). Without this guard the optimistic `initialPromptSentRef`
|
|
263
|
+
// flip below would lock the prompt out forever after a single
|
|
264
|
+
// dropped call. Re-runs as soon as the gate opens.
|
|
214
265
|
useEffect(() => {
|
|
215
|
-
if (
|
|
266
|
+
if (initialPromptSentRef.current) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
if (!isAgentReady || !isConfigLoaded) {
|
|
216
270
|
return;
|
|
217
271
|
}
|
|
218
272
|
if (!agentChat?.initialPrompt) {
|
|
@@ -222,10 +276,16 @@ const ChatInitializer = ({ agentId, agentChatId, chatId, token, appId, currentTh
|
|
|
222
276
|
initialPromptSentRef.current = true;
|
|
223
277
|
return;
|
|
224
278
|
}
|
|
279
|
+
if (!canSendMessage) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
225
282
|
initialPromptSentRef.current = true;
|
|
226
283
|
sendAgentInitialPrompt(agentChat.initialPrompt);
|
|
227
|
-
}, [isAgentReady, isConfigLoaded, agentChat, copilotAgent, sendAgentInitialPrompt]);
|
|
284
|
+
}, [isAgentReady, isConfigLoaded, agentChat, copilotAgent, canSendMessage, sendAgentInitialPrompt]);
|
|
228
285
|
const sendFromInputs = async () => {
|
|
286
|
+
if (!canSendMessage) {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
229
289
|
const currentPrompt = prompt;
|
|
230
290
|
// const currentAttachments = attachments;
|
|
231
291
|
setPrompt("");
|
|
@@ -285,6 +345,7 @@ const ChatInitializer = ({ agentId, agentChatId, chatId, token, appId, currentTh
|
|
|
285
345
|
attachments,
|
|
286
346
|
sendMessage,
|
|
287
347
|
sendFromInputs,
|
|
348
|
+
stopGeneration,
|
|
288
349
|
addAttachments,
|
|
289
350
|
removeAttachment,
|
|
290
351
|
clearAttachments,
|
|
@@ -298,19 +359,16 @@ const ChatInitializer = ({ agentId, agentChatId, chatId, token, appId, currentTh
|
|
|
298
359
|
isAgentReady,
|
|
299
360
|
agentChat,
|
|
300
361
|
agent,
|
|
362
|
+
components,
|
|
301
363
|
currentThreadId,
|
|
302
364
|
}, children: children }));
|
|
303
365
|
};
|
|
304
366
|
export const AgentChatRoot = ({ ...props
|
|
305
|
-
// agentHarness,
|
|
306
|
-
// useAgentBlockDirectChat,
|
|
307
|
-
// chatContextFiles,
|
|
308
367
|
// agentChatData,
|
|
309
368
|
// memoryEnabled = false,
|
|
310
369
|
// shortTermMemory,
|
|
311
|
-
// useDynamicUI,
|
|
312
370
|
}) => {
|
|
313
|
-
const { appId, token, children, agentId, agentChatId, chatId, defaultThreadId, noPersistency, chatContext } = props;
|
|
371
|
+
const { appId, token, children, agentId, agentHarness, useAgentBlockDirectChat, agentChatId, componentIds, chatId, defaultThreadId, noPersistency, chatContext, chatContextFiles, } = props;
|
|
314
372
|
const currentAppVersion = AppVersionService.getCurrentVersionNumber();
|
|
315
373
|
const socketId = websocketsService.getSocketId();
|
|
316
374
|
const headers = useMemo(() => ({
|
|
@@ -321,15 +379,22 @@ export const AgentChatRoot = ({ ...props
|
|
|
321
379
|
}), [token, currentAppVersion, socketId, appId]);
|
|
322
380
|
const [currentThreadId, setCurrentThreadId] = useState(() => defaultThreadId ?? (noPersistency ? crypto.randomUUID() : DEFAULT_CHAT_THREAD_ID));
|
|
323
381
|
const chatContextStr = chatContext == null ? undefined : typeof chatContext === "string" ? chatContext : JSON.stringify(chatContext);
|
|
382
|
+
if (!appId || !agentChatId) {
|
|
383
|
+
return null;
|
|
384
|
+
}
|
|
324
385
|
return (_jsxs(CopilotKit, { runtimeUrl: `${getApiHost()}/agent-chat-stream`, agent: "default", headers: headers, threadId: currentThreadId,
|
|
325
386
|
// debug={true}
|
|
326
387
|
properties: {
|
|
327
388
|
appId,
|
|
328
389
|
agentId,
|
|
390
|
+
agentHarness,
|
|
391
|
+
useAgentBlockDirectChat,
|
|
329
392
|
agentChatId,
|
|
330
393
|
chatId,
|
|
394
|
+
noPersistency,
|
|
331
395
|
chatContext: chatContextStr,
|
|
332
|
-
|
|
396
|
+
chatContextFiles,
|
|
397
|
+
}, children: [_jsx(SessionReadables, {}), _jsx(ChatInitializer, { agentId: agentId, agentChatId: agentChatId, chatId: chatId, noPersistency: noPersistency, token: token, appId: appId, componentIds: componentIds, currentThreadId: currentThreadId, setCurrentThreadId: setCurrentThreadId, children: children })] }));
|
|
333
398
|
};
|
|
334
399
|
export function AgentChatMessage({ message, index, ...props }) {
|
|
335
400
|
return _jsx("div", { "data-message-index": index, "data-message-role": message.role, ...props });
|
|
@@ -368,7 +433,8 @@ export function AgentChatFetching({ asChild = false, ...props }) {
|
|
|
368
433
|
return _jsx(Comp, { "data-slot": "agent-chat-fetching", ...props });
|
|
369
434
|
}
|
|
370
435
|
export function AgentChatInput({ asChild = false, onChange, onKeyDown, onPaste, onDragOver, onDragLeave, onDrop, onSubmit, acceptFiles = true, ...props }) {
|
|
371
|
-
const { setIsDraggingFiles, addAttachments, prompt, setPrompt, sendFromInputs } = useAgentChat();
|
|
436
|
+
const { setIsDraggingFiles, addAttachments, prompt, setPrompt, sendFromInputs, isThinking, isAgentReady, isFetchingMessages, } = useAgentChat();
|
|
437
|
+
const isDisabled = props.disabled || isThinking || !isAgentReady || isFetchingMessages;
|
|
372
438
|
const handleDragOver = useCallback((e) => {
|
|
373
439
|
if (!acceptFiles) {
|
|
374
440
|
return;
|
|
@@ -403,10 +469,13 @@ export function AgentChatInput({ asChild = false, onChange, onKeyDown, onPaste,
|
|
|
403
469
|
const handleKeyDown = useCallback((e) => {
|
|
404
470
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
405
471
|
e.preventDefault();
|
|
472
|
+
if (isDisabled) {
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
406
475
|
onSubmit?.(e);
|
|
407
476
|
sendFromInputs();
|
|
408
477
|
}
|
|
409
|
-
}, [
|
|
478
|
+
}, [isDisabled, onSubmit, sendFromInputs]);
|
|
410
479
|
const handleChange = useCallback((e) => {
|
|
411
480
|
setPrompt(e.target.value);
|
|
412
481
|
}, [setPrompt]);
|
|
@@ -456,11 +525,20 @@ export function AgentChatInput({ asChild = false, onChange, onKeyDown, onPaste,
|
|
|
456
525
|
: onDrop, "data-slot": "agent-chat-input", ...props }));
|
|
457
526
|
}
|
|
458
527
|
export function AgentChatSendTrigger({ asChild = false, onClick, disabled, ...props }) {
|
|
459
|
-
const { isThinking, isAgentReady, isFetchingMessages, sendFromInputs } = useAgentChat();
|
|
528
|
+
const { isThinking, isAgentReady, isFetchingMessages, sendFromInputs, stopGeneration } = useAgentChat();
|
|
460
529
|
const Comp = asChild ? Slot : "button";
|
|
461
|
-
const isDisabled = disabled ?? (isThinking
|
|
530
|
+
const isDisabled = disabled ?? (!isThinking && (!isAgentReady || isFetchingMessages));
|
|
462
531
|
return (_jsx(Comp, { onClick: (e) => {
|
|
463
|
-
|
|
532
|
+
if (isDisabled) {
|
|
533
|
+
e.preventDefault();
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
if (isThinking) {
|
|
537
|
+
stopGeneration();
|
|
538
|
+
}
|
|
539
|
+
else {
|
|
540
|
+
sendFromInputs();
|
|
541
|
+
}
|
|
464
542
|
onClick?.(e);
|
|
465
543
|
}, disabled: isDisabled, "data-slot": "agent-chat-send-trigger", ...props }));
|
|
466
544
|
}
|