@blocksdiy/react-common 1.30.2 → 1.31.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,7 +1,8 @@
|
|
|
1
|
-
import { type Message, type UserMessage } from "@ag-ui/client";
|
|
1
|
+
import { type Message, ToolMessage, type UserMessage } from "@ag-ui/client";
|
|
2
|
+
import { useRenderToolCall } from "@copilotkit/react-core/v2";
|
|
2
3
|
import { ReactNode, SetStateAction } from "react";
|
|
3
|
-
export { type Message, type AssistantMessage } from "@ag-ui/client";
|
|
4
|
-
export { useRenderTool,
|
|
4
|
+
export { type Message, type AssistantMessage, type UserMessage } from "@ag-ui/client";
|
|
5
|
+
export { useRenderTool, useDefaultRenderTool, useHumanInTheLoop, useFrontendTool, ToolCallStatus, } from "@copilotkit/react-core/v2";
|
|
5
6
|
export interface Attachment {
|
|
6
7
|
url: string;
|
|
7
8
|
fileType: string;
|
|
@@ -10,8 +11,7 @@ export interface Attachment {
|
|
|
10
11
|
export interface AgentChatComponent {
|
|
11
12
|
id: string;
|
|
12
13
|
name: string;
|
|
13
|
-
|
|
14
|
-
code?: string;
|
|
14
|
+
code: string;
|
|
15
15
|
input?: Record<string, unknown>;
|
|
16
16
|
description?: string;
|
|
17
17
|
/**
|
|
@@ -50,7 +50,14 @@ export interface AgentChatContextValue {
|
|
|
50
50
|
currentThreadId?: string;
|
|
51
51
|
agent: Agent | null;
|
|
52
52
|
agentChat: AgentChat | null;
|
|
53
|
-
components:
|
|
53
|
+
components: AgentChatComponent[];
|
|
54
|
+
messageGroups: {
|
|
55
|
+
messageIds: string[];
|
|
56
|
+
role: "assistant" | "user";
|
|
57
|
+
}[];
|
|
58
|
+
messageById: Map<string, Message>;
|
|
59
|
+
toolMessages: ToolMessage[];
|
|
60
|
+
renderToolCall: ReturnType<typeof useRenderToolCall>;
|
|
54
61
|
sendMessage: (message: Omit<UserMessage, "id" | "role">) => Promise<void>;
|
|
55
62
|
sendFromInputs: () => Promise<void>;
|
|
56
63
|
stopGeneration: () => void;
|
|
@@ -88,6 +95,13 @@ export interface AgentChatMessageProps {
|
|
|
88
95
|
index: number;
|
|
89
96
|
}
|
|
90
97
|
export declare function AgentChatMessage({ message, index, ...props }: React.ComponentProps<"div"> & AgentChatMessageProps): import("react/jsx-runtime").JSX.Element | null;
|
|
98
|
+
export interface AgentChatMessageGroupProps {
|
|
99
|
+
messageGroup: {
|
|
100
|
+
messageIds: string[];
|
|
101
|
+
role: "assistant" | "user";
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
export declare function AgentChatMessageGroup({ messageGroup, ...props }: React.ComponentProps<"div"> & AgentChatMessageGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
91
105
|
export interface AgentChatMessagesProps {
|
|
92
106
|
scrollAreaClassName?: string;
|
|
93
107
|
}
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"new-agent-chat.d.ts","sourceRoot":"","sources":["../../src/components/new-agent-chat.tsx"],"names":[],"mappings":"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"}
|
|
@@ -2,11 +2,11 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
2
2
|
import { BlocksApiService, getBuilderContextHeaders, websocketsService } from "@blocksdiy/blocks-client-api";
|
|
3
3
|
import { getApiHost } from "@blocksdiy/blocks-client-api/envService";
|
|
4
4
|
import { CopilotKit, useCopilotChatInternal } from "@copilotkit/react-core";
|
|
5
|
-
import { useCopilotKit } from "@copilotkit/react-core/v2";
|
|
5
|
+
import { useCopilotKit, useRenderToolCall } from "@copilotkit/react-core/v2";
|
|
6
6
|
import { Slot } from "@radix-ui/react-slot";
|
|
7
7
|
import { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState, } from "react";
|
|
8
|
-
export { useRenderTool, useRenderToolCall, useDefaultRenderTool, useHumanInTheLoop, useFrontendTool, ToolCallStatus, } from "@copilotkit/react-core/v2";
|
|
9
8
|
import { useStickToBottom } from "use-stick-to-bottom";
|
|
9
|
+
export { useRenderTool, useDefaultRenderTool, useHumanInTheLoop, useFrontendTool, ToolCallStatus, } from "@copilotkit/react-core/v2";
|
|
10
10
|
// Client-only `useLayoutEffect`, falls back to `useEffect` during SSR.
|
|
11
11
|
// Needed so the `agent.threadId` mirror commits before CopilotKit's
|
|
12
12
|
// connect-on-mount effect reads it.
|
|
@@ -65,11 +65,81 @@ const validateAndConvertFiles = (files) => {
|
|
|
65
65
|
return null;
|
|
66
66
|
}
|
|
67
67
|
return files.map((file) => ({
|
|
68
|
-
fileType: file.type,
|
|
68
|
+
fileType: file.type || "application/octet-stream",
|
|
69
69
|
fileName: file.name,
|
|
70
70
|
url: URL.createObjectURL(file),
|
|
71
71
|
}));
|
|
72
72
|
};
|
|
73
|
+
const fileFromAttachment = async (attachment) => {
|
|
74
|
+
const response = await fetch(attachment.url);
|
|
75
|
+
if (!response.ok) {
|
|
76
|
+
throw new Error("The blob URL is no longer valid");
|
|
77
|
+
}
|
|
78
|
+
const blob = await response.blob();
|
|
79
|
+
return new File([blob], attachment.fileName, {
|
|
80
|
+
type: attachment.fileType,
|
|
81
|
+
lastModified: Date.now(),
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
const getBrowserUploadUrl = (uploadUrl) => {
|
|
85
|
+
try {
|
|
86
|
+
const url = new URL(uploadUrl);
|
|
87
|
+
if (url.hostname === "localhost" && url.port === "4566") {
|
|
88
|
+
url.hostname = "blocks.localhost";
|
|
89
|
+
return url.toString();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return uploadUrl;
|
|
94
|
+
}
|
|
95
|
+
return uploadUrl;
|
|
96
|
+
};
|
|
97
|
+
const uploadFile = async ({ appId, blocksApiService, file, }) => {
|
|
98
|
+
const formData = new FormData();
|
|
99
|
+
const { uploadUrl, fields, protectedUrl } = await blocksApiService.getDataAssetUploadUrl({
|
|
100
|
+
productId: appId,
|
|
101
|
+
fileName: file.name,
|
|
102
|
+
fileType: file.type,
|
|
103
|
+
});
|
|
104
|
+
const request = new XMLHttpRequest();
|
|
105
|
+
if (!uploadUrl || !fields || !protectedUrl) {
|
|
106
|
+
throw new Error("Unable to prepare file upload");
|
|
107
|
+
}
|
|
108
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
109
|
+
formData.append(key, value);
|
|
110
|
+
}
|
|
111
|
+
formData.append("file", file);
|
|
112
|
+
request.open("POST", getBrowserUploadUrl(uploadUrl));
|
|
113
|
+
return new Promise((resolve, reject) => {
|
|
114
|
+
request.onload = () => {
|
|
115
|
+
if (request.status >= 200 && request.status < 300) {
|
|
116
|
+
resolve(protectedUrl);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
reject(new Error(`Error uploading file (${request.status})`));
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
request.onerror = () => {
|
|
123
|
+
reject(new Error("Error uploading file"));
|
|
124
|
+
};
|
|
125
|
+
request.send(formData);
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
const uploadAttachments = async ({ attachments, appId, token, }) => {
|
|
129
|
+
if (attachments.length === 0) {
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
const blocksApiService = new BlocksApiService({ token });
|
|
133
|
+
return Promise.all(attachments.map(async (attachment) => {
|
|
134
|
+
const file = await fileFromAttachment(attachment);
|
|
135
|
+
const protectedUrl = await uploadFile({ appId, blocksApiService, file });
|
|
136
|
+
return {
|
|
137
|
+
url: protectedUrl,
|
|
138
|
+
fileName: attachment.fileName,
|
|
139
|
+
fileType: attachment.fileType,
|
|
140
|
+
};
|
|
141
|
+
}));
|
|
142
|
+
};
|
|
73
143
|
const hasSendableInput = (prompt, attachments) => {
|
|
74
144
|
return prompt.trim().length > 0 || attachments.length > 0;
|
|
75
145
|
};
|
|
@@ -131,6 +201,33 @@ const ChatInitializer = ({ agentBlock, agentChatBlock, chatId, token, appId, com
|
|
|
131
201
|
const [isConfigLoaded, setIsConfigLoaded] = useState(false);
|
|
132
202
|
const { messages: copilotMessages, stopGeneration: copilotStopGeneration, isAvailable: isAgentReady, isLoading: isAgentRunning, agent: copilotAgent, } = useCopilotChatInternal();
|
|
133
203
|
const { copilotkit } = useCopilotKit();
|
|
204
|
+
const renderToolCall = useRenderToolCall();
|
|
205
|
+
const messageById = useMemo(() => {
|
|
206
|
+
const messagesSet = new Map();
|
|
207
|
+
copilotMessages.forEach((message) => {
|
|
208
|
+
messagesSet.set(message.id, message);
|
|
209
|
+
});
|
|
210
|
+
return messagesSet;
|
|
211
|
+
}, [copilotMessages]);
|
|
212
|
+
const toolMessages = useMemo(() => {
|
|
213
|
+
return copilotMessages.filter((message) => message.role === "tool");
|
|
214
|
+
}, [copilotMessages]);
|
|
215
|
+
const messageGroups = useMemo(() => {
|
|
216
|
+
const groups = [];
|
|
217
|
+
copilotMessages.forEach((message) => {
|
|
218
|
+
if (message.role !== "assistant" && message.role !== "user") {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
const lastGroup = groups[groups.length - 1];
|
|
222
|
+
if (!lastGroup || lastGroup.role !== message.role) {
|
|
223
|
+
groups.push({ role: message.role, messageIds: [message.id] });
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
lastGroup.messageIds.push(message.id);
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
return groups;
|
|
230
|
+
}, [copilotMessages]);
|
|
134
231
|
// Mirror `currentThreadId` onto the agent instance — the `<CopilotKit>`
|
|
135
232
|
// prop only feeds React context, but `agent.threadId` is what hits the
|
|
136
233
|
// wire and the LangGraph checkpoint. `<CopilotChat>` does this for you;
|
|
@@ -180,7 +277,6 @@ const ChatInitializer = ({ agentBlock, agentChatBlock, chatId, token, appId, com
|
|
|
180
277
|
copilotStopGeneration();
|
|
181
278
|
copilotAgent?.abortRun?.();
|
|
182
279
|
}, [copilotAgent, copilotStopGeneration]);
|
|
183
|
-
const componentsKey = components?.map((component) => component.id).join(",") ?? "";
|
|
184
280
|
const initKeyRef = useRef(null);
|
|
185
281
|
// Guard against re-firing the initial prompt across re-renders of the
|
|
186
282
|
// post-connect effect. Reset whenever the init key changes (thread
|
|
@@ -192,7 +288,6 @@ const ChatInitializer = ({ agentBlock, agentChatBlock, chatId, token, appId, com
|
|
|
192
288
|
currentThreadId ?? "",
|
|
193
289
|
agentBlock?.id ?? "",
|
|
194
290
|
agentChatBlock?.id ?? "",
|
|
195
|
-
componentsKey,
|
|
196
291
|
token ?? "",
|
|
197
292
|
appId ?? "",
|
|
198
293
|
].join("|");
|
|
@@ -243,7 +338,7 @@ const ChatInitializer = ({ agentBlock, agentChatBlock, chatId, token, appId, com
|
|
|
243
338
|
initialPromptSentRef.current = false;
|
|
244
339
|
};
|
|
245
340
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
246
|
-
}, [chatId, currentThreadId, agentBlock?.id, agentChatBlock?.id,
|
|
341
|
+
}, [chatId, currentThreadId, agentBlock?.id, agentChatBlock?.id, token, appId]);
|
|
247
342
|
// After CopilotKit's `connectAgent` resolves, the agent's message list
|
|
248
343
|
// already reflects whatever the backend replayed (history + any
|
|
249
344
|
// seeded initial messages). If the thread is still empty AND the
|
|
@@ -298,12 +393,45 @@ const ChatInitializer = ({ agentBlock, agentChatBlock, chatId, token, appId, com
|
|
|
298
393
|
});
|
|
299
394
|
void runAgentWithRetry(copilotAgent, copilotAgent.messages.length).catch(() => undefined);
|
|
300
395
|
}, [isAgentReady, isConfigLoaded, agentChat, copilotAgent, canSendMessage, runAgentWithRetry]);
|
|
396
|
+
const buildMessageContentFromInput = (currentPrompt = prompt, currentAttachments = attachments) => {
|
|
397
|
+
if (currentAttachments.length === 0) {
|
|
398
|
+
return currentPrompt;
|
|
399
|
+
}
|
|
400
|
+
const contentArray = [];
|
|
401
|
+
currentAttachments.forEach((attachment) => {
|
|
402
|
+
const source = { type: "url", value: attachment.url, mimeType: attachment.fileType };
|
|
403
|
+
const metadata = { filename: attachment.fileName };
|
|
404
|
+
switch (true) {
|
|
405
|
+
case attachment.fileType.startsWith("image/"):
|
|
406
|
+
contentArray.push({ type: "image", source, metadata });
|
|
407
|
+
break;
|
|
408
|
+
case attachment.fileType.startsWith("audio/"):
|
|
409
|
+
contentArray.push({ type: "audio", source, metadata });
|
|
410
|
+
break;
|
|
411
|
+
case attachment.fileType.startsWith("video/"):
|
|
412
|
+
contentArray.push({ type: "video", source, metadata });
|
|
413
|
+
break;
|
|
414
|
+
default:
|
|
415
|
+
contentArray.push({ type: "document", source, metadata });
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
if (currentPrompt) {
|
|
419
|
+
contentArray.push({ type: "text", text: currentPrompt });
|
|
420
|
+
}
|
|
421
|
+
return contentArray;
|
|
422
|
+
};
|
|
301
423
|
const sendFromInputs = async () => {
|
|
302
424
|
if (!canSendMessage || !hasSendableInput(prompt, attachments)) {
|
|
303
425
|
return;
|
|
304
426
|
}
|
|
305
427
|
const currentPrompt = prompt;
|
|
306
|
-
|
|
428
|
+
const currentAttachments = attachments;
|
|
429
|
+
const uploadedAttachments = await uploadAttachments({
|
|
430
|
+
attachments: currentAttachments,
|
|
431
|
+
appId,
|
|
432
|
+
token,
|
|
433
|
+
});
|
|
434
|
+
const messageContent = buildMessageContentFromInput(currentPrompt, uploadedAttachments ?? []);
|
|
307
435
|
setPrompt("");
|
|
308
436
|
setAttachments([]);
|
|
309
437
|
// Auto-skip any frontend user-choice tool call that's still waiting.
|
|
@@ -344,7 +472,7 @@ const ChatInitializer = ({ agentBlock, agentChatBlock, chatId, token, appId, com
|
|
|
344
472
|
});
|
|
345
473
|
}
|
|
346
474
|
}
|
|
347
|
-
await sendMessage({ content:
|
|
475
|
+
await sendMessage({ content: messageContent }).catch(() => undefined);
|
|
348
476
|
};
|
|
349
477
|
const addAttachments = (attachments) => {
|
|
350
478
|
if (!attachmentsEnabled) {
|
|
@@ -373,6 +501,10 @@ const ChatInitializer = ({ agentBlock, agentChatBlock, chatId, token, appId, com
|
|
|
373
501
|
};
|
|
374
502
|
return (_jsx(AgentChatContext.Provider, { value: {
|
|
375
503
|
messages: copilotMessages,
|
|
504
|
+
messageGroups,
|
|
505
|
+
renderToolCall,
|
|
506
|
+
messageById,
|
|
507
|
+
toolMessages,
|
|
376
508
|
prompt,
|
|
377
509
|
attachments,
|
|
378
510
|
sendMessage,
|
|
@@ -454,7 +586,6 @@ export const AgentChatRoot = ({ ...props
|
|
|
454
586
|
code,
|
|
455
587
|
input: block?.data?.input,
|
|
456
588
|
description,
|
|
457
|
-
toolName: getAgentChatComponentToolName(name),
|
|
458
589
|
userInterrupt: Boolean(block?.data?.userInterrupt),
|
|
459
590
|
};
|
|
460
591
|
}
|
|
@@ -499,6 +630,9 @@ export function AgentChatMessage({ message, index, ...props }) {
|
|
|
499
630
|
}
|
|
500
631
|
return _jsx("div", { "data-message-index": index, "data-message-role": message.role, ...props });
|
|
501
632
|
}
|
|
633
|
+
export function AgentChatMessageGroup({ messageGroup, ...props }) {
|
|
634
|
+
return (_jsx("div", { "data-slot": "agent-chat-message-group", "data-message-group": messageGroup.role, "data-message-group-role": messageGroup.role, ...props }));
|
|
635
|
+
}
|
|
502
636
|
export function AgentChatMessages({ scrollAreaClassName, ...props }) {
|
|
503
637
|
const { messages } = useAgentChat();
|
|
504
638
|
const userMessageCount = messages.filter((message) => message.role === "user" && message.name !== HIDDEN_INITIAL_PROMPT_MESSAGE_NAME).length;
|
|
@@ -516,7 +650,12 @@ export function AgentChatMessages({ scrollAreaClassName, ...props }) {
|
|
|
516
650
|
}
|
|
517
651
|
previousUserMessageCountRef.current = userMessageCount;
|
|
518
652
|
}, [scrollToBottom, userMessageCount]);
|
|
519
|
-
return (_jsx("div", { ref: scrollRef,
|
|
653
|
+
return (_jsx("div", { ref: scrollRef, className: scrollAreaClassName, style: {
|
|
654
|
+
height: "100%",
|
|
655
|
+
width: "100%",
|
|
656
|
+
overflow: "auto",
|
|
657
|
+
scrollbarGutter: "stable both-edges",
|
|
658
|
+
}, children: _jsx("div", { ref: contentRef, "data-slot": "agent-chat-messages", ...props }) }));
|
|
520
659
|
}
|
|
521
660
|
export function AgentChatThinking({ asChild = false, ...props }) {
|
|
522
661
|
const { isThinking } = useAgentChat();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocksdiy/react-common",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.31.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "React common",
|
|
6
6
|
"keywords": [],
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"penpal": "^7.0.6",
|
|
39
39
|
"react": "^19.2.4",
|
|
40
40
|
"use-stick-to-bottom": "1.1.4",
|
|
41
|
-
"@blocksdiy/blocks-client-api": "1.
|
|
41
|
+
"@blocksdiy/blocks-client-api": "1.13.0"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@types/react": "^19.2.14",
|