@blocksdiy/react-common 1.28.1 → 1.29.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,8 +1,7 @@
|
|
|
1
|
-
import { type Message,
|
|
2
|
-
import { useRenderToolCall } from "@copilotkit/react-core/v2";
|
|
1
|
+
import { type Message, type UserMessage } from "@ag-ui/client";
|
|
3
2
|
import { ReactNode, SetStateAction } from "react";
|
|
4
|
-
export { type Message, type AssistantMessage
|
|
5
|
-
export { useRenderTool, useDefaultRenderTool, useHumanInTheLoop, useFrontendTool, ToolCallStatus, } from "@copilotkit/react-core/v2";
|
|
3
|
+
export { type Message, type AssistantMessage } from "@ag-ui/client";
|
|
4
|
+
export { useRenderTool, useRenderToolCall, useDefaultRenderTool, useHumanInTheLoop, useFrontendTool, ToolCallStatus, } from "@copilotkit/react-core/v2";
|
|
6
5
|
export interface Attachment {
|
|
7
6
|
url: string;
|
|
8
7
|
fileType: string;
|
|
@@ -11,7 +10,8 @@ export interface Attachment {
|
|
|
11
10
|
export interface AgentChatComponent {
|
|
12
11
|
id: string;
|
|
13
12
|
name: string;
|
|
14
|
-
|
|
13
|
+
toolName?: string;
|
|
14
|
+
code?: string;
|
|
15
15
|
input?: Record<string, unknown>;
|
|
16
16
|
description?: string;
|
|
17
17
|
/**
|
|
@@ -51,14 +51,6 @@ export interface AgentChatContextValue {
|
|
|
51
51
|
agent: Agent | null;
|
|
52
52
|
agentChat: AgentChat | null;
|
|
53
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>;
|
|
61
|
-
hasSentMessageInSession: boolean;
|
|
62
54
|
sendMessage: (message: Omit<UserMessage, "id" | "role">) => Promise<void>;
|
|
63
55
|
sendFromInputs: () => Promise<void>;
|
|
64
56
|
stopGeneration: () => void;
|
|
@@ -72,11 +64,6 @@ export interface AgentChatContextValue {
|
|
|
72
64
|
}
|
|
73
65
|
export declare const AgentChatContext: import("react").Context<AgentChatContextValue | null>;
|
|
74
66
|
export declare const useAgentChat: () => AgentChatContextValue;
|
|
75
|
-
interface AgentChatScrollContextValue {
|
|
76
|
-
isAtBottom: boolean;
|
|
77
|
-
scrollToBottom: () => void;
|
|
78
|
-
}
|
|
79
|
-
export declare const useAgentChatScroll: () => AgentChatScrollContextValue;
|
|
80
67
|
export interface AgentChatRootProps {
|
|
81
68
|
appId: string;
|
|
82
69
|
token?: string;
|
|
@@ -101,22 +88,10 @@ export interface AgentChatMessageProps {
|
|
|
101
88
|
index: number;
|
|
102
89
|
}
|
|
103
90
|
export declare function AgentChatMessage({ message, index, ...props }: React.ComponentProps<"div"> & AgentChatMessageProps): import("react/jsx-runtime").JSX.Element | null;
|
|
104
|
-
export interface AgentChatMessageGroupProps {
|
|
105
|
-
messageGroup: {
|
|
106
|
-
messageIds: string[];
|
|
107
|
-
role: "assistant" | "user";
|
|
108
|
-
};
|
|
109
|
-
isLast?: boolean;
|
|
110
|
-
}
|
|
111
|
-
export declare function AgentChatMessageGroup({ messageGroup, isLast, style, ...props }: React.ComponentProps<"div"> & AgentChatMessageGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
112
91
|
export interface AgentChatMessagesProps {
|
|
113
92
|
scrollAreaClassName?: string;
|
|
114
93
|
}
|
|
115
|
-
export declare function AgentChatMessages({ scrollAreaClassName,
|
|
116
|
-
export interface AgentChatScrollToBottomProps {
|
|
117
|
-
asChild?: boolean;
|
|
118
|
-
}
|
|
119
|
-
export declare function AgentChatScrollToBottom({ asChild, onClick, ...props }: React.ComponentProps<"button"> & AgentChatScrollToBottomProps): import("react/jsx-runtime").JSX.Element | null;
|
|
94
|
+
export declare function AgentChatMessages({ scrollAreaClassName, ...props }: React.ComponentProps<"div"> & AgentChatMessagesProps): import("react/jsx-runtime").JSX.Element;
|
|
120
95
|
export interface AgentChatThinkingProps {
|
|
121
96
|
asChild?: boolean;
|
|
122
97
|
}
|
|
@@ -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,
|
|
1
|
+
{"version":3,"file":"new-agent-chat.d.ts","sourceRoot":"","sources":["../../src/components/new-agent-chat.tsx"],"names":[],"mappings":"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"}
|
|
@@ -2,10 +2,11 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
2
2
|
import { AppVersionService, BlocksApiService, 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
|
|
5
|
+
import { useCopilotKit } 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, useDefaultRenderTool, useHumanInTheLoop, useFrontendTool, ToolCallStatus, } from "@copilotkit/react-core/v2";
|
|
8
|
+
export { useRenderTool, useRenderToolCall, useDefaultRenderTool, useHumanInTheLoop, useFrontendTool, ToolCallStatus, } from "@copilotkit/react-core/v2";
|
|
9
|
+
import { useStickToBottom } from "use-stick-to-bottom";
|
|
9
10
|
// Client-only `useLayoutEffect`, falls back to `useEffect` during SSR.
|
|
10
11
|
// Needed so the `agent.threadId` mirror commits before CopilotKit's
|
|
11
12
|
// connect-on-mount effect reads it.
|
|
@@ -60,84 +61,44 @@ const validateAndConvertFiles = (files) => {
|
|
|
60
61
|
}
|
|
61
62
|
const hasOversizedFiles = files.some((file) => file.size > MAX_FILE_SIZE_BYTES);
|
|
62
63
|
if (hasOversizedFiles) {
|
|
64
|
+
console.error(`Upload failed because some files are bigger than ${MAX_FILE_SIZE_MB} MB.`);
|
|
63
65
|
return null;
|
|
64
66
|
}
|
|
65
67
|
return files.map((file) => ({
|
|
66
|
-
fileType: file.type
|
|
68
|
+
fileType: file.type,
|
|
67
69
|
fileName: file.name,
|
|
68
70
|
url: URL.createObjectURL(file),
|
|
69
71
|
}));
|
|
70
72
|
};
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
if (!response.ok) {
|
|
74
|
-
throw new Error("The blob URL is no longer valid");
|
|
75
|
-
}
|
|
76
|
-
const blob = await response.blob();
|
|
77
|
-
return new File([blob], attachment.fileName, {
|
|
78
|
-
type: attachment.fileType,
|
|
79
|
-
lastModified: Date.now(),
|
|
80
|
-
});
|
|
73
|
+
const hasSendableInput = (prompt, attachments) => {
|
|
74
|
+
return prompt.trim().length > 0 || attachments.length > 0;
|
|
81
75
|
};
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
76
|
+
const isRecord = (value) => {
|
|
77
|
+
return typeof value === "object" && value !== null;
|
|
78
|
+
};
|
|
79
|
+
const getNumericStatus = (value) => {
|
|
80
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
81
|
+
return value;
|
|
89
82
|
}
|
|
90
|
-
|
|
91
|
-
|
|
83
|
+
if (typeof value === "string") {
|
|
84
|
+
const parsed = Number.parseInt(value, 10);
|
|
85
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
92
86
|
}
|
|
93
|
-
return
|
|
87
|
+
return undefined;
|
|
94
88
|
};
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
productId: appId,
|
|
99
|
-
fileName: file.name,
|
|
100
|
-
fileType: file.type,
|
|
101
|
-
});
|
|
102
|
-
const request = new XMLHttpRequest();
|
|
103
|
-
if (uploadUrl && fields) {
|
|
104
|
-
for (const [key, value] of Object.entries(fields)) {
|
|
105
|
-
formData.append(key, value);
|
|
106
|
-
}
|
|
107
|
-
formData.append("file", file);
|
|
108
|
-
request.open("POST", getBrowserUploadUrl(uploadUrl));
|
|
89
|
+
const getAgentRunErrorStatus = (error) => {
|
|
90
|
+
if (!isRecord(error)) {
|
|
91
|
+
return undefined;
|
|
109
92
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
reject(new Error("Error uploading file"));
|
|
117
|
-
}
|
|
118
|
-
};
|
|
119
|
-
request.onerror = () => {
|
|
120
|
-
reject(new Error("Error uploading file"));
|
|
121
|
-
};
|
|
122
|
-
request.send(formData);
|
|
123
|
-
});
|
|
124
|
-
};
|
|
125
|
-
const uploadAttachments = async ({ attachments, blocksApiService, appId, }) => {
|
|
126
|
-
if (!attachments?.length) {
|
|
93
|
+
const directStatus = getNumericStatus(error.status);
|
|
94
|
+
if (directStatus !== undefined) {
|
|
95
|
+
return directStatus;
|
|
96
|
+
}
|
|
97
|
+
const response = error.response;
|
|
98
|
+
if (!isRecord(response)) {
|
|
127
99
|
return undefined;
|
|
128
100
|
}
|
|
129
|
-
return
|
|
130
|
-
const file = await fileFromAttachment(attachment);
|
|
131
|
-
const protectedUrl = await uploadFile({ appId, blocksApiService, file });
|
|
132
|
-
return {
|
|
133
|
-
url: protectedUrl,
|
|
134
|
-
fileName: attachment.fileName,
|
|
135
|
-
fileType: attachment.fileType,
|
|
136
|
-
};
|
|
137
|
-
}));
|
|
138
|
-
};
|
|
139
|
-
const hasSendableInput = (prompt, attachments) => {
|
|
140
|
-
return prompt.trim().length > 0 || attachments.length > 0;
|
|
101
|
+
return getNumericStatus(response.status);
|
|
141
102
|
};
|
|
142
103
|
export const AgentChatContext = createContext(null);
|
|
143
104
|
export const useAgentChat = () => {
|
|
@@ -147,55 +108,6 @@ export const useAgentChat = () => {
|
|
|
147
108
|
}
|
|
148
109
|
return context;
|
|
149
110
|
};
|
|
150
|
-
const NEW_MESSAGE_SCROLL_HIDE_MS = 500;
|
|
151
|
-
const AgentChatScrollContext = createContext(null);
|
|
152
|
-
export const useAgentChatScroll = () => {
|
|
153
|
-
const context = useContext(AgentChatScrollContext);
|
|
154
|
-
if (!context) {
|
|
155
|
-
throw new Error("useAgentChatScroll must be used within an AgentChatMessages provider");
|
|
156
|
-
}
|
|
157
|
-
return context;
|
|
158
|
-
};
|
|
159
|
-
const getMessageGroups = (scrollElement) => {
|
|
160
|
-
return Array.from(scrollElement.querySelectorAll('[data-slot="agent-chat-message-group"]'));
|
|
161
|
-
};
|
|
162
|
-
const SCROLL_BOTTOM_OFFSET_PX = 70;
|
|
163
|
-
const getTargetScrollTop = (scrollElement) => {
|
|
164
|
-
return Math.max(scrollElement.scrollHeight - 1 - scrollElement.clientHeight, 0);
|
|
165
|
-
};
|
|
166
|
-
const isScrollAtBottom = (scrollElement) => {
|
|
167
|
-
return getTargetScrollTop(scrollElement) - scrollElement.scrollTop <= SCROLL_BOTTOM_OFFSET_PX;
|
|
168
|
-
};
|
|
169
|
-
const setScrollTopInstantly = (scrollElement, scrollTop) => {
|
|
170
|
-
const { scrollBehavior } = getComputedStyle(scrollElement);
|
|
171
|
-
if (scrollBehavior !== "auto") {
|
|
172
|
-
scrollElement.style.scrollBehavior = "auto";
|
|
173
|
-
}
|
|
174
|
-
scrollElement.scrollTop = scrollTop;
|
|
175
|
-
if (scrollBehavior !== "auto") {
|
|
176
|
-
scrollElement.style.scrollBehavior = scrollBehavior;
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
const AGENT_CHAT_CONTAINER_HEIGHT_VAR = "--agent-chat-container-height";
|
|
180
|
-
const AGENT_CHAT_LATEST_USER_HEIGHT_VAR = "--agent-chat-latest-user-message-height";
|
|
181
|
-
const LAST_ASSISTANT_MESSAGE_GROUP_STYLE = {
|
|
182
|
-
minHeight: `max(calc(var(${AGENT_CHAT_CONTAINER_HEIGHT_VAR}, 0px) - var(${AGENT_CHAT_LATEST_USER_HEIGHT_VAR}, var(${AGENT_CHAT_CONTAINER_HEIGHT_VAR}, 0px))), 0px)`,
|
|
183
|
-
};
|
|
184
|
-
const updateScrollHeightVariables = (scrollElement) => {
|
|
185
|
-
const messageGroups = getMessageGroups(scrollElement);
|
|
186
|
-
const latestUserGroup = messageGroups.reverse().find((messageGroup) => messageGroup.dataset.messageGroup === "user");
|
|
187
|
-
scrollElement.style.setProperty(AGENT_CHAT_CONTAINER_HEIGHT_VAR, `${scrollElement.clientHeight}px`);
|
|
188
|
-
if (latestUserGroup) {
|
|
189
|
-
scrollElement.style.setProperty(AGENT_CHAT_LATEST_USER_HEIGHT_VAR, `${latestUserGroup.offsetHeight}px`);
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
scrollElement.style.removeProperty(AGENT_CHAT_LATEST_USER_HEIGHT_VAR);
|
|
193
|
-
}
|
|
194
|
-
};
|
|
195
|
-
const clearScrollHeightVariables = (scrollElement) => {
|
|
196
|
-
scrollElement.style.removeProperty(AGENT_CHAT_CONTAINER_HEIGHT_VAR);
|
|
197
|
-
scrollElement.style.removeProperty(AGENT_CHAT_LATEST_USER_HEIGHT_VAR);
|
|
198
|
-
};
|
|
199
111
|
const SessionReadables = () => {
|
|
200
112
|
// const now = new Date();
|
|
201
113
|
// useCopilotReadable({
|
|
@@ -218,35 +130,14 @@ const ChatInitializer = ({ agentId, agentChatId, chatId, token, appId, component
|
|
|
218
130
|
// `isAvailable` below — see `isFetchingMessages` for the combined
|
|
219
131
|
// "are we still warming up" signal exposed to consumers.
|
|
220
132
|
const [isConfigLoaded, setIsConfigLoaded] = useState(false);
|
|
221
|
-
const { messages: copilotMessages,
|
|
133
|
+
const { messages: copilotMessages, stopGeneration: copilotStopGeneration, isAvailable: isAgentReady, isLoading: isAgentRunning, agent: copilotAgent, } = useCopilotChatInternal();
|
|
222
134
|
const { copilotkit } = useCopilotKit();
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
return messagesSet;
|
|
230
|
-
}, [copilotMessages]);
|
|
231
|
-
const toolMessages = useMemo(() => {
|
|
232
|
-
return copilotMessages.filter((message) => message.role === "tool");
|
|
233
|
-
}, [copilotMessages]);
|
|
234
|
-
const messageGroups = useMemo(() => {
|
|
235
|
-
const groups = [];
|
|
236
|
-
copilotMessages.forEach((message) => {
|
|
237
|
-
if (message.role !== "assistant" && message.role !== "user") {
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
const lastGroup = groups[groups.length - 1];
|
|
241
|
-
if (!lastGroup || lastGroup.role !== message.role) {
|
|
242
|
-
groups.push({ role: message.role, messageIds: [message.id] });
|
|
243
|
-
}
|
|
244
|
-
else {
|
|
245
|
-
lastGroup.messageIds.push(message.id);
|
|
246
|
-
}
|
|
247
|
-
});
|
|
248
|
-
return groups;
|
|
249
|
-
}, [copilotMessages]);
|
|
135
|
+
const isRunStartingRef = useRef(false);
|
|
136
|
+
useEffect(() => {
|
|
137
|
+
return () => {
|
|
138
|
+
isRunStartingRef.current = false;
|
|
139
|
+
};
|
|
140
|
+
}, []);
|
|
250
141
|
// Mirror `currentThreadId` onto the agent instance — the `<CopilotKit>`
|
|
251
142
|
// prop only feeds React context, but `agent.threadId` is what hits the
|
|
252
143
|
// wire and the LangGraph checkpoint. `<CopilotChat>` does this for you;
|
|
@@ -262,7 +153,6 @@ const ChatInitializer = ({ agentId, agentChatId, chatId, token, appId, component
|
|
|
262
153
|
const [prompt, setPrompt] = useState("");
|
|
263
154
|
const [attachments, setAttachments] = useState([]);
|
|
264
155
|
const [isDraggingFiles, setIsDraggingFiles] = useState(false);
|
|
265
|
-
const [hasSentMessageInSession, setHasSentMessageInSession] = useState(false);
|
|
266
156
|
const blocksApiService = useMemo(() => new BlocksApiService({ token }), [token]);
|
|
267
157
|
const attachmentsEnabled = agentChat ? agentChat.disableAttachments !== true : false;
|
|
268
158
|
const canSendMessage = Boolean(agentChatId && agentChat && agent && isConfigLoaded && isAgentReady && !isAgentRunning);
|
|
@@ -270,14 +160,38 @@ const ChatInitializer = ({ agentId, agentChatId, chatId, token, appId, component
|
|
|
270
160
|
// CopilotKit reports `isLoading` during connect/replay as well as real runs.
|
|
271
161
|
// Only expose thinking once the bootstrap connect phase has completed.
|
|
272
162
|
const isThinking = isAgentRunning && !isFetchingMessages;
|
|
163
|
+
const runAgentWithRetry = useCallback(async (agentToRun, messageCountAtRunStart) => {
|
|
164
|
+
if (isRunStartingRef.current) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
isRunStartingRef.current = true;
|
|
168
|
+
try {
|
|
169
|
+
try {
|
|
170
|
+
await copilotkit.runAgent({ agent: agentToRun });
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
const hasAgentStartedResponding = agentToRun.messages.length > messageCountAtRunStart;
|
|
174
|
+
const status = getAgentRunErrorStatus(error);
|
|
175
|
+
if (status !== undefined && status >= 500 && status < 600 && !hasAgentStartedResponding) {
|
|
176
|
+
await copilotkit.runAgent({ agent: agentToRun });
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
throw error;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
finally {
|
|
183
|
+
isRunStartingRef.current = false;
|
|
184
|
+
}
|
|
185
|
+
}, [copilotkit]);
|
|
273
186
|
const sendMessage = useCallback((message) => {
|
|
274
|
-
if (!canSendMessage) {
|
|
187
|
+
if (!canSendMessage || !copilotAgent || isRunStartingRef.current) {
|
|
275
188
|
return Promise.resolve();
|
|
276
189
|
}
|
|
277
|
-
|
|
278
|
-
return
|
|
279
|
-
}, [canSendMessage,
|
|
190
|
+
copilotAgent.addMessage({ ...message, id: generateId(), role: "user" });
|
|
191
|
+
return runAgentWithRetry(copilotAgent, copilotAgent.messages.length);
|
|
192
|
+
}, [canSendMessage, copilotAgent, runAgentWithRetry]);
|
|
280
193
|
const stopGeneration = useCallback(() => {
|
|
194
|
+
isRunStartingRef.current = false;
|
|
281
195
|
copilotStopGeneration();
|
|
282
196
|
copilotAgent?.abortRun?.();
|
|
283
197
|
}, [copilotAgent, copilotStopGeneration]);
|
|
@@ -295,7 +209,7 @@ const ChatInitializer = ({ agentId, agentChatId, chatId, token, appId, component
|
|
|
295
209
|
if (!componentIds?.length) {
|
|
296
210
|
return [];
|
|
297
211
|
}
|
|
298
|
-
const
|
|
212
|
+
const maybeComponentBlocks = await Promise.all(componentIds.map(async (componentId) => {
|
|
299
213
|
try {
|
|
300
214
|
const block = await blocksApiService.getBlock(componentId);
|
|
301
215
|
const id = block?.id ?? componentId;
|
|
@@ -311,6 +225,7 @@ const ChatInitializer = ({ agentId, agentChatId, chatId, token, appId, component
|
|
|
311
225
|
code,
|
|
312
226
|
input: block?.data?.input,
|
|
313
227
|
description,
|
|
228
|
+
toolName: getAgentChatComponentToolName(name),
|
|
314
229
|
userInterrupt: Boolean(block?.data?.userInterrupt),
|
|
315
230
|
};
|
|
316
231
|
}
|
|
@@ -318,7 +233,7 @@ const ChatInitializer = ({ agentId, agentChatId, chatId, token, appId, component
|
|
|
318
233
|
return null;
|
|
319
234
|
}
|
|
320
235
|
}));
|
|
321
|
-
return
|
|
236
|
+
return maybeComponentBlocks.filter((component) => Boolean(component));
|
|
322
237
|
}, [blocksApiService, componentIds]);
|
|
323
238
|
const componentIdsKey = componentIds?.join(",") ?? "";
|
|
324
239
|
const initKeyRef = useRef(null);
|
|
@@ -341,7 +256,6 @@ const ChatInitializer = ({ agentId, agentChatId, chatId, token, appId, component
|
|
|
341
256
|
}
|
|
342
257
|
initKeyRef.current = initKey;
|
|
343
258
|
initialPromptSentRef.current = false;
|
|
344
|
-
setHasSentMessageInSession(false);
|
|
345
259
|
const ac = new AbortController();
|
|
346
260
|
const initialize = async () => {
|
|
347
261
|
setIsConfigLoaded(false);
|
|
@@ -444,47 +358,14 @@ const ChatInitializer = ({ agentId, agentChatId, chatId, token, appId, component
|
|
|
444
358
|
...(hiddenPrompt ? { name: HIDDEN_INITIAL_PROMPT_MESSAGE_NAME } : {}),
|
|
445
359
|
content: prompt,
|
|
446
360
|
});
|
|
447
|
-
void
|
|
448
|
-
}, [isAgentReady, isConfigLoaded, agentChat, copilotAgent, canSendMessage,
|
|
449
|
-
const buildMessageContentFromInput = (currentPrompt = prompt, currentAttachments = attachments) => {
|
|
450
|
-
if (currentAttachments.length === 0) {
|
|
451
|
-
return currentPrompt;
|
|
452
|
-
}
|
|
453
|
-
const contentArray = [];
|
|
454
|
-
currentAttachments.forEach((attachment) => {
|
|
455
|
-
const source = { type: "url", value: attachment.url, mimeType: attachment.fileType };
|
|
456
|
-
const metadata = { filename: attachment.fileName };
|
|
457
|
-
switch (true) {
|
|
458
|
-
case attachment.fileType.startsWith("image/"):
|
|
459
|
-
contentArray.push({ type: "image", source, metadata });
|
|
460
|
-
break;
|
|
461
|
-
case attachment.fileType.startsWith("audio/"):
|
|
462
|
-
contentArray.push({ type: "audio", source, metadata });
|
|
463
|
-
break;
|
|
464
|
-
case attachment.fileType.startsWith("video/"):
|
|
465
|
-
contentArray.push({ type: "video", source, metadata });
|
|
466
|
-
break;
|
|
467
|
-
default:
|
|
468
|
-
contentArray.push({ type: "document", source, metadata });
|
|
469
|
-
}
|
|
470
|
-
});
|
|
471
|
-
if (currentPrompt) {
|
|
472
|
-
contentArray.push({ type: "text", text: currentPrompt });
|
|
473
|
-
}
|
|
474
|
-
return contentArray;
|
|
475
|
-
};
|
|
361
|
+
void runAgentWithRetry(copilotAgent, copilotAgent.messages.length).catch(() => undefined);
|
|
362
|
+
}, [isAgentReady, isConfigLoaded, agentChat, copilotAgent, canSendMessage, runAgentWithRetry]);
|
|
476
363
|
const sendFromInputs = async () => {
|
|
477
364
|
if (!canSendMessage || !hasSendableInput(prompt, attachments)) {
|
|
478
365
|
return;
|
|
479
366
|
}
|
|
480
367
|
const currentPrompt = prompt;
|
|
481
|
-
const currentAttachments = attachments;
|
|
482
|
-
const uploadedAttachments = await uploadAttachments({
|
|
483
|
-
attachments: currentAttachments,
|
|
484
|
-
appId,
|
|
485
|
-
blocksApiService,
|
|
486
|
-
});
|
|
487
|
-
const messageContent = buildMessageContentFromInput(currentPrompt, uploadedAttachments ?? []);
|
|
368
|
+
// const currentAttachments = attachments;
|
|
488
369
|
setPrompt("");
|
|
489
370
|
setAttachments([]);
|
|
490
371
|
// Auto-skip any frontend user-choice tool call that's still waiting.
|
|
@@ -525,9 +406,7 @@ const ChatInitializer = ({ agentId, agentChatId, chatId, token, appId, component
|
|
|
525
406
|
});
|
|
526
407
|
}
|
|
527
408
|
}
|
|
528
|
-
await sendMessage({
|
|
529
|
-
content: messageContent,
|
|
530
|
-
});
|
|
409
|
+
await sendMessage({ content: currentPrompt }).catch(() => undefined);
|
|
531
410
|
};
|
|
532
411
|
const addAttachments = (attachments) => {
|
|
533
412
|
if (!attachmentsEnabled) {
|
|
@@ -556,11 +435,6 @@ const ChatInitializer = ({ agentId, agentChatId, chatId, token, appId, component
|
|
|
556
435
|
};
|
|
557
436
|
return (_jsx(AgentChatContext.Provider, { value: {
|
|
558
437
|
messages: copilotMessages,
|
|
559
|
-
messageGroups,
|
|
560
|
-
renderToolCall,
|
|
561
|
-
messageById,
|
|
562
|
-
toolMessages,
|
|
563
|
-
hasSentMessageInSession,
|
|
564
438
|
prompt,
|
|
565
439
|
attachments,
|
|
566
440
|
sendMessage,
|
|
@@ -622,139 +496,24 @@ export function AgentChatMessage({ message, index, ...props }) {
|
|
|
622
496
|
}
|
|
623
497
|
return _jsx("div", { "data-message-index": index, "data-message-role": message.role, ...props });
|
|
624
498
|
}
|
|
625
|
-
export function
|
|
626
|
-
const {
|
|
627
|
-
const
|
|
628
|
-
const
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
? {
|
|
634
|
-
...style,
|
|
635
|
-
...LAST_ASSISTANT_MESSAGE_GROUP_STYLE,
|
|
636
|
-
}
|
|
637
|
-
: style;
|
|
638
|
-
return (_jsx("div", { "data-slot": "agent-chat-message-group", "data-message-group": messageGroup.role, "data-message-group-role": messageGroup.role, style: mergedStyle, ...props }));
|
|
639
|
-
}
|
|
640
|
-
export function AgentChatMessages({ scrollAreaClassName, children, ...props }) {
|
|
641
|
-
const { isFetchingMessages, isThinking, messageGroups } = useAgentChat();
|
|
642
|
-
const messageGroupCount = messageGroups.length;
|
|
643
|
-
const scrollRef = useRef(null);
|
|
644
|
-
const previousMessageGroupCountRef = useRef(messageGroupCount);
|
|
645
|
-
const hasCompletedInitialScrollRef = useRef(false);
|
|
646
|
-
const previousIsThinkingRef = useRef(isThinking);
|
|
647
|
-
const newMessageScrollTimeoutRef = useRef(null);
|
|
648
|
-
const [isNewMessageScrollInProgress, setIsNewMessageScrollInProgress] = useState(false);
|
|
649
|
-
const [isAtBottom, setIsAtBottom] = useState(true);
|
|
650
|
-
const scrollToBottom = useCallback((behavior = "smooth") => {
|
|
651
|
-
const scrollElement = scrollRef.current;
|
|
652
|
-
if (!scrollElement) {
|
|
653
|
-
return;
|
|
654
|
-
}
|
|
655
|
-
const targetScrollTop = getTargetScrollTop(scrollElement);
|
|
656
|
-
if (behavior === "instant") {
|
|
657
|
-
setScrollTopInstantly(scrollElement, targetScrollTop);
|
|
658
|
-
}
|
|
659
|
-
else {
|
|
660
|
-
scrollElement.scrollTo({ top: targetScrollTop, behavior });
|
|
661
|
-
}
|
|
662
|
-
setIsAtBottom(true);
|
|
663
|
-
}, []);
|
|
664
|
-
const scrollContextValue = useMemo(() => ({
|
|
665
|
-
isAtBottom: isAtBottom || isNewMessageScrollInProgress,
|
|
666
|
-
scrollToBottom: () => {
|
|
667
|
-
void scrollToBottom();
|
|
668
|
-
},
|
|
669
|
-
}), [isAtBottom, isNewMessageScrollInProgress, scrollToBottom]);
|
|
670
|
-
useIsomorphicLayoutEffect(() => {
|
|
671
|
-
const scrollElement = scrollRef.current;
|
|
672
|
-
if (!scrollElement) {
|
|
673
|
-
return;
|
|
674
|
-
}
|
|
675
|
-
if (getComputedStyle(scrollElement).overflow === "visible") {
|
|
676
|
-
scrollElement.style.overflow = "auto";
|
|
677
|
-
}
|
|
678
|
-
const updateIsAtBottom = () => {
|
|
679
|
-
setIsAtBottom(isScrollAtBottom(scrollElement));
|
|
680
|
-
};
|
|
681
|
-
updateIsAtBottom();
|
|
682
|
-
scrollElement.addEventListener("scroll", updateIsAtBottom, { passive: true });
|
|
683
|
-
return () => {
|
|
684
|
-
scrollElement.removeEventListener("scroll", updateIsAtBottom);
|
|
685
|
-
};
|
|
686
|
-
}, []);
|
|
687
|
-
useEffect(() => {
|
|
688
|
-
return () => {
|
|
689
|
-
if (newMessageScrollTimeoutRef.current !== null) {
|
|
690
|
-
window.clearTimeout(newMessageScrollTimeoutRef.current);
|
|
691
|
-
}
|
|
692
|
-
};
|
|
693
|
-
}, []);
|
|
499
|
+
export function AgentChatMessages({ scrollAreaClassName, ...props }) {
|
|
500
|
+
const { messages } = useAgentChat();
|
|
501
|
+
const userMessageCount = messages.filter((message) => message.role === "user" && message.name !== HIDDEN_INITIAL_PROMPT_MESSAGE_NAME).length;
|
|
502
|
+
const previousUserMessageCountRef = useRef(userMessageCount);
|
|
503
|
+
const { scrollRef, contentRef, scrollToBottom } = useStickToBottom({
|
|
504
|
+
resize: "smooth",
|
|
505
|
+
initial: { damping: 1, stiffness: 1 },
|
|
506
|
+
});
|
|
694
507
|
useEffect(() => {
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
}, [
|
|
703
|
-
|
|
704
|
-
const scrollElement = scrollRef.current;
|
|
705
|
-
if (isFetchingMessages) {
|
|
706
|
-
previousMessageGroupCountRef.current = messageGroupCount;
|
|
707
|
-
return;
|
|
708
|
-
}
|
|
709
|
-
if (!scrollElement) {
|
|
710
|
-
previousMessageGroupCountRef.current = messageGroupCount;
|
|
711
|
-
return;
|
|
712
|
-
}
|
|
713
|
-
if (!hasCompletedInitialScrollRef.current) {
|
|
714
|
-
clearScrollHeightVariables(scrollElement);
|
|
715
|
-
scrollToBottom("instant");
|
|
716
|
-
previousMessageGroupCountRef.current = messageGroupCount;
|
|
717
|
-
hasCompletedInitialScrollRef.current = true;
|
|
718
|
-
return;
|
|
719
|
-
}
|
|
720
|
-
if (messageGroupCount < previousMessageGroupCountRef.current) {
|
|
721
|
-
previousMessageGroupCountRef.current = messageGroupCount;
|
|
722
|
-
clearScrollHeightVariables(scrollElement);
|
|
723
|
-
scrollToBottom("instant");
|
|
724
|
-
return;
|
|
725
|
-
}
|
|
726
|
-
if (messageGroupCount > previousMessageGroupCountRef.current) {
|
|
727
|
-
updateScrollHeightVariables(scrollElement);
|
|
728
|
-
setIsNewMessageScrollInProgress(true);
|
|
729
|
-
if (newMessageScrollTimeoutRef.current !== null) {
|
|
730
|
-
window.clearTimeout(newMessageScrollTimeoutRef.current);
|
|
731
|
-
}
|
|
732
|
-
newMessageScrollTimeoutRef.current = window.setTimeout(() => {
|
|
733
|
-
setIsNewMessageScrollInProgress(false);
|
|
734
|
-
newMessageScrollTimeoutRef.current = null;
|
|
735
|
-
}, NEW_MESSAGE_SCROLL_HIDE_MS);
|
|
736
|
-
scrollToBottom("smooth");
|
|
737
|
-
}
|
|
738
|
-
previousMessageGroupCountRef.current = messageGroupCount;
|
|
739
|
-
}, [isFetchingMessages, messageGroupCount, scrollToBottom]);
|
|
740
|
-
return (_jsx(AgentChatScrollContext.Provider, { value: scrollContextValue, children: _jsx("div", { ...props, children: _jsx("div", { ref: scrollRef, style: {
|
|
741
|
-
height: "100%",
|
|
742
|
-
width: "100%",
|
|
743
|
-
scrollbarGutter: "stable both-edges",
|
|
744
|
-
}, children: _jsx("div", { className: scrollAreaClassName, children: children }) }) }) }));
|
|
745
|
-
}
|
|
746
|
-
export function AgentChatScrollToBottom({ asChild = false, onClick, ...props }) {
|
|
747
|
-
const { isAtBottom, scrollToBottom } = useAgentChatScroll();
|
|
748
|
-
const Comp = asChild ? Slot : "button";
|
|
749
|
-
if (isAtBottom) {
|
|
750
|
-
return null;
|
|
751
|
-
}
|
|
752
|
-
return (_jsx(Comp, { "data-slot": "agent-chat-scroll-to-bottom", onClick: (event) => {
|
|
753
|
-
onClick?.(event);
|
|
754
|
-
if (!event.defaultPrevented) {
|
|
755
|
-
scrollToBottom();
|
|
756
|
-
}
|
|
757
|
-
}, ...props }));
|
|
508
|
+
if (userMessageCount > previousUserMessageCountRef.current) {
|
|
509
|
+
void scrollToBottom({
|
|
510
|
+
animation: "smooth",
|
|
511
|
+
ignoreEscapes: true,
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
previousUserMessageCountRef.current = userMessageCount;
|
|
515
|
+
}, [scrollToBottom, userMessageCount]);
|
|
516
|
+
return (_jsx("div", { ref: scrollRef, style: { overflow: "auto" }, className: scrollAreaClassName, children: _jsx("div", { ref: contentRef, "data-slot": "agent-chat-messages", ...props }) }));
|
|
758
517
|
}
|
|
759
518
|
export function AgentChatThinking({ asChild = false, ...props }) {
|
|
760
519
|
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.29.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.5.0"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@types/react": "^19.2.14",
|