@blocksdiy/react-common 1.9.0 → 1.10.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,3 +1,4 @@
1
+ import { type UIMessage } from "ai";
1
2
  import { ReactNode, SetStateAction } from "react";
2
3
  import { type VoiceCallMessage } from "../hooks/use-voice-call.js";
3
4
  export interface Attachment {
@@ -6,24 +7,45 @@ export interface Attachment {
6
7
  fileName: string;
7
8
  }
8
9
  export type MessageRole = "human" | "ai";
9
- interface MessageItemMsg {
10
+ type MessageType = "progress" | "text" | "missing_integration";
11
+ /**
12
+ * Legacy public message contract.
13
+ *
14
+ * Consumers of `@blocksdiy/react-common/agent-chat` currently read `msg.content`,
15
+ * `msg.role` (`human`/`ai`), `msg.attachments`, and the flattened compatibility
16
+ * fields returned from `AgentChatContextValue.messages`. Keep this shape stable
17
+ * while the runtime underneath moves to AI SDK `UIMessage` objects.
18
+ */
19
+ export interface LegacyMessagePayload {
10
20
  id: string;
11
21
  role: MessageRole;
12
22
  attachments?: Attachment[];
13
23
  content?: string;
14
- type: "progress" | "text" | "missing_integration";
24
+ type: MessageType;
15
25
  versionId?: number;
16
26
  payload: Record<string, any>;
17
27
  hiddenContent?: string;
18
28
  }
19
- export interface MessageItem {
20
- msg: MessageItemMsg;
29
+ export type V1AiSdkMessagePayload = AgentChatUIMessage & {
30
+ metadata: AgentChatUIMessage["metadata"] & {
31
+ version: 1;
32
+ };
33
+ };
34
+ export type PersistedMessagePayload = LegacyMessagePayload | V1AiSdkMessagePayload;
35
+ interface MessageItemBase {
21
36
  createdAt: string;
22
37
  createdBy?: string;
23
38
  chatId?: string;
24
39
  threadId?: string;
25
40
  id?: string;
26
41
  }
42
+ export type LegacyMessageItem = MessageItemBase & {
43
+ msg: LegacyMessagePayload;
44
+ };
45
+ export type V1AiSdkMessageItem = MessageItemBase & {
46
+ msg: V1AiSdkMessagePayload;
47
+ };
48
+ export type MessageItem = LegacyMessageItem | V1AiSdkMessageItem;
27
49
  export interface AgentChatContextValue {
28
50
  messages: MessageItem[];
29
51
  attachments: Attachment[];
@@ -34,7 +56,7 @@ export interface AgentChatContextValue {
34
56
  currentThreadId?: string;
35
57
  threadIds: string[];
36
58
  agentChatData?: AgentChatData;
37
- sendMessage: (message: Omit<MessageItemMsg, "id" | "role" | "type" | "payload">) => Promise<void>;
59
+ sendMessage: (message: Omit<LegacyMessagePayload, "id" | "role" | "type" | "payload">) => Promise<void>;
38
60
  sendFromInputs: () => Promise<void>;
39
61
  addMessages: (newMessages: MessageItem[]) => void;
40
62
  addAttachments: (attachments: Attachment[]) => void;
@@ -52,7 +74,52 @@ export interface AgentChatContextValue {
52
74
  chatId?: string;
53
75
  noPersistency?: boolean;
54
76
  }
77
+ export type AgentChatUIMessage = UIMessage & {
78
+ metadata?: {
79
+ version?: 1;
80
+ hiddenPrompt?: string;
81
+ };
82
+ };
83
+ export declare const isV1AiSdkMessageItem: (message: MessageItem) => message is V1AiSdkMessageItem;
84
+ export declare const isLegacyMessageItem: (message: MessageItem) => message is LegacyMessageItem;
85
+ export declare const uiMessageToV1MessageItem: (message: AgentChatUIMessage, createdAt?: string) => V1AiSdkMessageItem;
55
86
  export declare const useAgentChat: () => AgentChatContextValue;
87
+ export interface ToolCardContextValue {
88
+ open: boolean;
89
+ setOpen: (open: boolean) => void;
90
+ }
91
+ export declare const useToolCard: () => ToolCardContextValue;
92
+ export interface ToolCardProps {
93
+ asChild?: boolean;
94
+ defaultOpen?: boolean;
95
+ open?: boolean;
96
+ onOpenChange?: (open: boolean) => void;
97
+ size?: string;
98
+ variant?: string;
99
+ }
100
+ export declare function ToolCard({ asChild, defaultOpen, open: controlledOpen, onOpenChange, size, variant, ...props }: React.ComponentProps<"div"> & ToolCardProps): import("react/jsx-runtime").JSX.Element;
101
+ export interface ToolHeaderProps {
102
+ asChild?: boolean;
103
+ collapseTrigger?: ReactNode;
104
+ }
105
+ export declare function ToolHeader({ asChild, collapseTrigger, children, ...props }: React.ComponentProps<"div"> & ToolHeaderProps): import("react/jsx-runtime").JSX.Element;
106
+ export interface ToolTitleProps {
107
+ asChild?: boolean;
108
+ status?: ReactNode;
109
+ }
110
+ export declare function ToolTitle({ asChild, status, children, ...props }: React.ComponentProps<"div"> & ToolTitleProps): import("react/jsx-runtime").JSX.Element;
111
+ export interface ToolActionsProps {
112
+ asChild?: boolean;
113
+ }
114
+ export declare function ToolActions({ asChild, ...props }: React.ComponentProps<"div"> & ToolActionsProps): import("react/jsx-runtime").JSX.Element;
115
+ export interface ToolCollapseTriggerProps {
116
+ asChild?: boolean;
117
+ }
118
+ export declare function ToolCollapseTrigger({ asChild, onClick, ...props }: React.ComponentProps<"button"> & ToolCollapseTriggerProps): import("react/jsx-runtime").JSX.Element;
119
+ export interface ToolContentProps {
120
+ asChild?: boolean;
121
+ }
122
+ export declare function ToolContent({ asChild, ...props }: React.ComponentProps<"div"> & ToolContentProps): import("react/jsx-runtime").JSX.Element;
56
123
  export interface AgentChatData {
57
124
  agent: {
58
125
  title?: string;
@@ -71,12 +138,11 @@ export interface AgentChatData {
71
138
  export interface AgentChatRootProps {
72
139
  appId: string;
73
140
  token?: string;
74
- /** Agent persona block id used for direct AgentBlockService chat when `useAgentBlockDirectChat` is true. */
141
+ /** Agent/persona block id used by the Python DeepAgent chat runtime. */
75
142
  agentBlockId?: string;
76
- /**
77
- * When true with `agentBlockId`, uses `runAgentBlockChat` instead of the workflow.
78
- * Set from the host app’s `useFlag("new-agent")` (Remix). Defaults to true for hosted/compiled apps that do not pass it.
79
- */
143
+ /** Provider saved on the agent block. `deep_agent` implies the direct AI SDK transport. */
144
+ agentProvider?: string;
145
+ /** When true with `agentBlockId`, route direct Deep Agent chat through the AI SDK UI-message stream. */
80
146
  useAgentBlockDirectChat?: boolean;
81
147
  agentChatId?: string;
82
148
  defaultThreadId?: string;
@@ -91,7 +157,8 @@ export interface AgentChatRootProps {
91
157
  isEnabled: boolean;
92
158
  };
93
159
  }
94
- export declare const AgentChatRoot: ({ appId, token, agentBlockId, useAgentBlockDirectChat, agentChatId, children, chatId, noPersistency, defaultThreadId, chatContext, chatContextFiles, agentChatData, memoryEnabled, shortTermMemory, }: AgentChatRootProps) => import("react/jsx-runtime").JSX.Element;
160
+ export type ResolvedAgentChatConfig = Pick<AgentChatRootProps, "agentBlockId" | "agentProvider" | "agentChatData" | "shortTermMemory">;
161
+ export declare const AgentChatRoot: ({ appId, token, agentBlockId, agentProvider, useAgentBlockDirectChat, agentChatId, children, chatId, noPersistency, defaultThreadId, chatContext, chatContextFiles, agentChatData, memoryEnabled, shortTermMemory, }: AgentChatRootProps) => import("react/jsx-runtime").JSX.Element | null;
95
162
  export interface AgentChatVoiceContextValue {
96
163
  isConnected: boolean;
97
164
  isConnecting: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-chat.d.ts","sourceRoot":"","sources":["../../src/components/agent-chat.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent-chat.d.ts","sourceRoot":"","sources":["../../src/components/agent-chat.tsx"],"names":[],"mappings":"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"}
@@ -1,10 +1,11 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { AppVersionService, DataApiService, websocketsService } from "@blocksdiy/blocks-client-api";
3
- import { runAgentBlockChat } from "@blocksdiy/blocks-client-api";
2
+ import { useChat } from "@ai-sdk/react";
3
+ import { AppVersionService, BlocksApiService, DataApiService, websocketsService } from "@blocksdiy/blocks-client-api";
4
4
  import { getApiHost } from "@blocksdiy/blocks-client-api/envService";
5
5
  import { WorkflowRequest } from "@blocksdiy/blocks-client-api/workflowService";
6
6
  import { Slot } from "@radix-ui/react-slot";
7
- import { createContext, useCallback, useContext, useEffect, useRef, useState } from "react";
7
+ import { DefaultChatTransport } from "ai";
8
+ import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from "react";
8
9
  import { useVoiceCall } from "../hooks/use-voice-call.js";
9
10
  /* public decouple - blocks common */
10
11
  const CHAT_AGENT_HISTORY_TABLE_BLOCK_ID = "688ed13adefd8b565c779b8e";
@@ -13,6 +14,7 @@ const CHAT_AGENT_CALL_ACTION_BLOCK_ID = "688ed4d77b454b1fdaf5cf2d";
13
14
  // File upload constraints
14
15
  const MAX_FILE_SIZE_MB = 5;
15
16
  const MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * 1024 * 1024;
17
+ const DEFAULT_SHORT_TERM_MEMORY = { isEnabled: true };
16
18
  const validateAndConvertFiles = (files) => {
17
19
  if (files.length === 0) {
18
20
  return null;
@@ -34,6 +36,101 @@ const generateId = (length = 10) => {
34
36
  .toString(36)
35
37
  .substring(2, 2 + length);
36
38
  };
39
+ const isV1AiSdkMessagePayload = (msg) => "metadata" in msg && msg.metadata?.version === 1;
40
+ export const isV1AiSdkMessageItem = (message) => isV1AiSdkMessagePayload(message.msg);
41
+ export const isLegacyMessageItem = (message) => !isV1AiSdkMessageItem(message);
42
+ const attachmentsToUiFileParts = (attachments = []) => attachments.map((attachment) => ({
43
+ type: "file",
44
+ url: attachment.url,
45
+ filename: attachment.fileName,
46
+ mediaType: attachment.fileType,
47
+ }));
48
+ const uiMessageToLegacyPayload = (message) => {
49
+ const text = message.parts
50
+ .filter((part) => part.type === "text")
51
+ .map((part) => part.text)
52
+ .join("");
53
+ const attachments = message.parts
54
+ .filter((part) => part.type === "file")
55
+ .map((part) => ({
56
+ url: part.url,
57
+ fileName: part.filename ?? "File",
58
+ fileType: part.mediaType ?? "application/octet-stream",
59
+ }));
60
+ if (!text && attachments.length === 0) {
61
+ return null;
62
+ }
63
+ return {
64
+ id: message.id,
65
+ role: message.role === "user" ? "human" : "ai",
66
+ type: "text",
67
+ content: text,
68
+ attachments: attachments.length > 0 ? attachments : undefined,
69
+ hiddenContent: message.metadata?.hiddenPrompt,
70
+ payload: {},
71
+ };
72
+ };
73
+ const messageItemToLegacyPayload = (message) => {
74
+ if (isLegacyMessageItem(message)) {
75
+ return message.msg;
76
+ }
77
+ return uiMessageToLegacyPayload(message.msg);
78
+ };
79
+ const messageItemToUIMessage = (message) => {
80
+ if (isV1AiSdkMessageItem(message)) {
81
+ return message.msg;
82
+ }
83
+ return {
84
+ id: message.msg.id,
85
+ role: message.msg.role === "human" ? "user" : "assistant",
86
+ parts: [{ type: "text", text: message.msg.content ?? "" }, ...attachmentsToUiFileParts(message.msg.attachments)],
87
+ metadata: {
88
+ version: 1,
89
+ hiddenPrompt: message.msg.hiddenContent,
90
+ },
91
+ };
92
+ };
93
+ export const uiMessageToV1MessageItem = (message, createdAt = new Date().toISOString()) => {
94
+ return {
95
+ createdAt,
96
+ msg: {
97
+ ...message,
98
+ metadata: { ...message.metadata, version: 1 },
99
+ },
100
+ };
101
+ };
102
+ const appendAiSdkErrorMessage = (messages, error) => {
103
+ const text = "Error: " + (error instanceof Error ? error.message : "Unknown error");
104
+ const lastMessage = messages[messages.length - 1];
105
+ const lastText = lastMessage?.parts
106
+ ?.filter((part) => part.type === "text")
107
+ .map((part) => part.text)
108
+ .join("");
109
+ if (lastMessage?.role === "assistant" && lastText === text) {
110
+ return messages;
111
+ }
112
+ return [
113
+ ...messages,
114
+ {
115
+ id: generateId(10),
116
+ role: "assistant",
117
+ parts: [{ type: "text", text }],
118
+ metadata: { version: 1 },
119
+ },
120
+ ];
121
+ };
122
+ const storedMessageToLegacyView = (message) => {
123
+ if (isV1AiSdkMessagePayload(message.msg)) {
124
+ return {
125
+ ...uiMessageToV1MessageItem(message.msg, message.createdAt),
126
+ createdAt: message.createdAt,
127
+ id: message.id,
128
+ chatId: message.chatId,
129
+ threadId: message.threadId,
130
+ };
131
+ }
132
+ return message;
133
+ };
37
134
  export const useAgentChat = () => {
38
135
  const context = useContext(AgentChatContext);
39
136
  if (!context) {
@@ -41,6 +138,52 @@ export const useAgentChat = () => {
41
138
  }
42
139
  return context;
43
140
  };
141
+ const ToolCardContext = createContext(null);
142
+ export const useToolCard = () => {
143
+ const context = useContext(ToolCardContext);
144
+ if (!context) {
145
+ throw new Error("useToolCard must be used within a ToolCard");
146
+ }
147
+ return context;
148
+ };
149
+ export function ToolCard({ asChild = false, defaultOpen = false, open: controlledOpen, onOpenChange, size, variant, ...props }) {
150
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen);
151
+ const open = controlledOpen ?? uncontrolledOpen;
152
+ const setOpen = useCallback((nextOpen) => {
153
+ if (controlledOpen === undefined) {
154
+ setUncontrolledOpen(nextOpen);
155
+ }
156
+ onOpenChange?.(nextOpen);
157
+ }, [controlledOpen, onOpenChange]);
158
+ const Comp = asChild ? Slot : "div";
159
+ return (_jsx(ToolCardContext.Provider, { value: { open, setOpen }, children: _jsx(Comp, { "data-slot": "agent-chat-tool-card", "data-state": open ? "open" : "closed", "data-size": size, "data-variant": variant, ...props }) }));
160
+ }
161
+ export function ToolHeader({ asChild = false, collapseTrigger, children, ...props }) {
162
+ const { open } = useToolCard();
163
+ const Comp = asChild ? Slot : "div";
164
+ return (_jsxs(Comp, { "data-slot": "agent-chat-tool-header", "data-state": open ? "open" : "closed", ...props, children: [children, collapseTrigger] }));
165
+ }
166
+ export function ToolTitle({ asChild = false, status, children, ...props }) {
167
+ const Comp = asChild ? Slot : "div";
168
+ return (_jsxs(Comp, { "data-slot": "agent-chat-tool-title", ...props, children: [status, children] }));
169
+ }
170
+ export function ToolActions({ asChild = false, ...props }) {
171
+ const Comp = asChild ? Slot : "div";
172
+ return _jsx(Comp, { "data-slot": "agent-chat-tool-actions", ...props });
173
+ }
174
+ export function ToolCollapseTrigger({ asChild = false, onClick, ...props }) {
175
+ const { open, setOpen } = useToolCard();
176
+ const Comp = asChild ? Slot : "button";
177
+ return (_jsx(Comp, { type: "button", "aria-expanded": open, "data-slot": "agent-chat-tool-collapse-trigger", "data-state": open ? "open" : "closed", onClick: (e) => {
178
+ setOpen(!open);
179
+ onClick?.(e);
180
+ }, ...props }));
181
+ }
182
+ export function ToolContent({ asChild = false, ...props }) {
183
+ const { open } = useToolCard();
184
+ const Comp = asChild ? Slot : "div";
185
+ return _jsx(Comp, { "data-slot": "agent-chat-tool-content", "data-state": open ? "open" : "closed", ...props });
186
+ }
44
187
  const fileFromAttachment = async (attachment) => {
45
188
  const res = await fetch(attachment.url); // or use XMLHttpRequest if you need progress events
46
189
  if (!res.ok) {
@@ -114,39 +257,172 @@ const uploadAttachments = async ({ attachments, token, appId, }) => {
114
257
  : undefined;
115
258
  return uploadAttachments;
116
259
  };
117
- export const AgentChatRoot = ({ appId, token, agentBlockId, useAgentBlockDirectChat = true, agentChatId, children, chatId, noPersistency, defaultThreadId, chatContext, chatContextFiles, agentChatData, memoryEnabled = false, shortTermMemory = { isEnabled: true }, }) => {
260
+ const getPhotoUrlFromAgentBlockData = (agentBlockData) => {
261
+ const { photo } = agentBlockData || {};
262
+ if (photo) {
263
+ if (photo.fileBlockId) {
264
+ return `/api/blocks/fileDataBlock/${photo.fileBlockId}/redirect`;
265
+ }
266
+ if (photo.url) {
267
+ return photo.url;
268
+ }
269
+ }
270
+ return undefined;
271
+ };
272
+ const resolveAgentChatConfig = async ({ agentChatId, token, }) => {
273
+ if (!agentChatId) {
274
+ return { shortTermMemory: DEFAULT_SHORT_TERM_MEMORY };
275
+ }
276
+ const blocksApiService = new BlocksApiService({ token });
277
+ const agentChatBlock = await blocksApiService.getBlock(agentChatId);
278
+ const agentChatBlockData = agentChatBlock?.data;
279
+ if (!agentChatBlockData) {
280
+ return { shortTermMemory: DEFAULT_SHORT_TERM_MEMORY };
281
+ }
282
+ const { agentBlockId, initialMessages, initialPrompt } = agentChatBlockData;
283
+ let agentBlockData;
284
+ if (agentBlockId) {
285
+ const agentBlock = await blocksApiService.getBlock(agentBlockId);
286
+ agentBlockData = agentBlock?.data;
287
+ }
288
+ const agentProvider = typeof agentBlockData?.provider === "string" ? agentBlockData.provider : undefined;
289
+ return {
290
+ agentBlockId: agentProvider ? agentBlockId : undefined,
291
+ agentProvider,
292
+ shortTermMemory: agentChatBlockData?.shortTermMemory ?? DEFAULT_SHORT_TERM_MEMORY,
293
+ agentChatData: {
294
+ agent: {
295
+ title: agentBlockData?.title,
296
+ jobTitle: agentBlockData?.jobTitle,
297
+ photoUrl: getPhotoUrlFromAgentBlockData(agentBlockData),
298
+ voiceId: agentChatBlockData?.voiceId || agentBlockData?.voiceId,
299
+ },
300
+ initialMessages,
301
+ initialPrompt,
302
+ },
303
+ };
304
+ };
305
+ const flattenLegacyMessages = (messages) => messages.map((m) => (isV1AiSdkMessageItem(m) ? m : { ...m, ...m.msg }));
306
+ const createInitialAgentMessages = (initialMessages = []) => initialMessages.map((initialMessage) => {
307
+ const id = generateId();
308
+ return {
309
+ id,
310
+ createdAt: new Date(1).toISOString(),
311
+ msg: { id, role: "ai", type: "text", content: initialMessage.content, payload: {} },
312
+ };
313
+ });
314
+ const mergeMessageItemsById = (currentMessages, incomingMessages) => {
315
+ const nextMessages = [...currentMessages];
316
+ for (const incomingMessage of incomingMessages) {
317
+ const existingIndex = nextMessages.findIndex((message) => message.msg.id === incomingMessage.msg.id);
318
+ if (existingIndex !== -1) {
319
+ nextMessages[existingIndex] = incomingMessage;
320
+ }
321
+ else {
322
+ nextMessages.push(incomingMessage);
323
+ }
324
+ }
325
+ nextMessages.sort((a, b) => Date.parse(a.createdAt) - Date.parse(b.createdAt));
326
+ return nextMessages;
327
+ };
328
+ const formatChatContext = (chatContext) => (chatContext ? `Context: \n${JSON.stringify(chatContext)}` : undefined);
329
+ function useAgentChatInputState({ isThinking, isFetchingMessages, sendMessage, }) {
118
330
  const [prompt, setPrompt] = useState("");
119
331
  const [attachments, setAttachments] = useState([]);
120
- const [messages, setMessages] = useState([]);
121
- const [isFetchingMessages, setIsFetchingMessages] = useState(!noPersistency);
122
- const [isThinking, setIsThinking] = useState(false);
123
332
  const [isDraggingFiles, setIsDraggingFiles] = useState(false);
124
- const [currentThreadId, setCurrentThreadId] = useState(defaultThreadId);
125
333
  const [threadIds, setThreadIds] = useState([]);
334
+ const addAttachments = useCallback((newAttachments) => {
335
+ setAttachments((prevAttachments) => [...prevAttachments, ...newAttachments]);
336
+ }, [setAttachments]);
337
+ const removeAttachment = useCallback((url) => {
338
+ setAttachments((prevAttachments) => prevAttachments.filter((attachment) => attachment.url !== url));
339
+ }, [setAttachments]);
340
+ const clearAttachments = useCallback(() => {
341
+ setAttachments([]);
342
+ }, [setAttachments]);
343
+ const sendFromInputs = useCallback(async () => {
344
+ if (isThinking || isFetchingMessages || (!prompt && attachments.length === 0)) {
345
+ return;
346
+ }
347
+ const newMessage = { content: prompt, type: "text", attachments };
348
+ setPrompt("");
349
+ setAttachments([]);
350
+ return sendMessage(newMessage);
351
+ }, [setPrompt, setAttachments, sendMessage, isThinking, isFetchingMessages, prompt, attachments]);
352
+ return {
353
+ attachments,
354
+ prompt,
355
+ isDraggingFiles,
356
+ threadIds,
357
+ sendFromInputs,
358
+ addAttachments,
359
+ removeAttachment,
360
+ clearAttachments,
361
+ setPrompt,
362
+ setAttachments,
363
+ setIsDraggingFiles,
364
+ setThreadIds,
365
+ };
366
+ }
367
+ function useAgentChatDataInitialization({ agentChatData, addMessages, sendMessage, }) {
126
368
  const initializedAgentChatDataRef = useRef(false);
127
- const addMessages = useCallback((messagesToAdd) => {
128
- setMessages((prevMessages) => {
129
- const newMessages = [...prevMessages];
130
- for (const messageToAdd of messagesToAdd) {
131
- const existingIndex = newMessages.findIndex((m) => m.msg.id === messageToAdd.msg.id);
132
- if (existingIndex !== -1) {
133
- // Replace the existing message with the updated one
134
- newMessages[existingIndex] = messageToAdd;
369
+ useEffect(() => {
370
+ if (!agentChatData || initializedAgentChatDataRef.current) {
371
+ return;
372
+ }
373
+ const { initialMessages, initialPrompt } = agentChatData;
374
+ if (initialMessages && initialMessages.length > 0) {
375
+ addMessages(createInitialAgentMessages(initialMessages));
376
+ }
377
+ if (initialPrompt?.content || initialPrompt?.hiddenContent) {
378
+ sendMessage({ content: initialPrompt?.content, hiddenContent: initialPrompt?.hiddenContent });
379
+ }
380
+ initializedAgentChatDataRef.current = true;
381
+ }, [agentChatData, sendMessage, addMessages]);
382
+ }
383
+ function AgentChatContextProvider({ children, ...value }) {
384
+ return _jsx(AgentChatContext.Provider, { value: value, children: children });
385
+ }
386
+ export const AgentChatRoot = ({ appId, token, agentBlockId, agentProvider, useAgentBlockDirectChat, agentChatId, children, chatId, noPersistency, defaultThreadId, chatContext, chatContextFiles, agentChatData, memoryEnabled = false, shortTermMemory, }) => {
387
+ const [resolvedAgentChatConfig, setResolvedAgentChatConfig] = useState(null);
388
+ const isResolvingAgentChatConfig = Boolean(agentChatId && !resolvedAgentChatConfig);
389
+ const effectiveAgentBlockId = resolvedAgentChatConfig?.agentBlockId ?? agentBlockId;
390
+ const effectiveAgentProvider = resolvedAgentChatConfig?.agentProvider ?? agentProvider;
391
+ const effectiveAgentChatData = agentChatData ?? resolvedAgentChatConfig?.agentChatData;
392
+ const effectiveShortTermMemory = shortTermMemory ?? resolvedAgentChatConfig?.shortTermMemory ?? DEFAULT_SHORT_TERM_MEMORY;
393
+ const shouldUseAgentBlockDirectChat = useAgentBlockDirectChat ?? effectiveAgentProvider === "deep_agent";
394
+ const isNewAgent = Boolean(effectiveAgentBlockId && shouldUseAgentBlockDirectChat);
395
+ const [isFetchingMessages, setIsFetchingMessages] = useState(!noPersistency);
396
+ const [currentThreadId, setCurrentThreadId] = useState(defaultThreadId);
397
+ const [fetchedMessages, setFetchedMessages] = useState([]);
398
+ useEffect(() => {
399
+ let cancelled = false;
400
+ setResolvedAgentChatConfig(null);
401
+ const fetchAgentChatConfig = async () => {
402
+ try {
403
+ const config = await resolveAgentChatConfig({ agentChatId, token });
404
+ if (!cancelled) {
405
+ setResolvedAgentChatConfig(config);
135
406
  }
136
- else {
137
- // Insert new message
138
- newMessages.push(messageToAdd);
407
+ }
408
+ catch {
409
+ if (!cancelled) {
410
+ setResolvedAgentChatConfig({ shortTermMemory: DEFAULT_SHORT_TERM_MEMORY });
139
411
  }
140
412
  }
141
- // Ensure the messages are sorted chronologically by creation time
142
- newMessages.sort((a, b) => Date.parse(a.createdAt) - Date.parse(b.createdAt));
143
- return newMessages;
144
- });
145
- }, []);
413
+ };
414
+ fetchAgentChatConfig();
415
+ return () => {
416
+ cancelled = true;
417
+ };
418
+ }, [agentChatId, token]);
146
419
  useEffect(() => {
420
+ let cancelled = false;
147
421
  if (noPersistency) {
422
+ setFetchedMessages([]);
148
423
  return;
149
424
  }
425
+ setFetchedMessages([]);
150
426
  const fetchMessages = async () => {
151
427
  try {
152
428
  setIsFetchingMessages(true);
@@ -155,51 +431,94 @@ export const AgentChatRoot = ({ appId, token, agentBlockId, useAgentBlockDirectC
155
431
  chatId,
156
432
  threadId: currentThreadId,
157
433
  });
158
- const fetchedMessages = data.filter((chatMessage) => !!chatMessage);
159
- addMessages(fetchedMessages);
434
+ if (!cancelled) {
435
+ setFetchedMessages(data.filter((chatMessage) => !!chatMessage));
436
+ }
160
437
  }
161
438
  finally {
162
- setIsFetchingMessages(false);
439
+ if (!cancelled) {
440
+ setIsFetchingMessages(false);
441
+ }
163
442
  }
164
443
  };
165
444
  fetchMessages();
166
- }, [appId, token, chatId, currentThreadId, noPersistency, agentChatData, addMessages]);
445
+ return () => {
446
+ cancelled = true;
447
+ };
448
+ }, [appId, token, chatId, currentThreadId, noPersistency, effectiveAgentChatData, isNewAgent]);
449
+ if (isResolvingAgentChatConfig) {
450
+ return null;
451
+ }
452
+ const commonProps = {
453
+ appId,
454
+ token,
455
+ agentBlockId: effectiveAgentBlockId,
456
+ agentProvider: effectiveAgentProvider,
457
+ useAgentBlockDirectChat,
458
+ agentChatId,
459
+ children,
460
+ chatId,
461
+ noPersistency,
462
+ defaultThreadId,
463
+ chatContext,
464
+ chatContextFiles,
465
+ agentChatData: effectiveAgentChatData,
466
+ memoryEnabled,
467
+ shortTermMemory: effectiveShortTermMemory,
468
+ isFetchingMessages,
469
+ currentThreadId,
470
+ setCurrentThreadId,
471
+ fetchedMessages,
472
+ };
473
+ if (isNewAgent) {
474
+ return _jsx(AiSdkAgentChatProvider, { ...commonProps });
475
+ }
476
+ return _jsx(LegacyAgentChatProvider, { ...commonProps });
477
+ };
478
+ function LegacyAgentChatProvider({ appId, token, agentChatId, children, chatId, noPersistency, currentThreadId, chatContext, chatContextFiles, agentChatData, memoryEnabled = false, shortTermMemory = { isEnabled: true }, isFetchingMessages, setCurrentThreadId, fetchedMessages, }) {
479
+ const [messages, setMessages] = useState([]);
480
+ const [isThinking, setIsThinking] = useState(false);
481
+ const addMessages = useCallback((messagesToAdd) => {
482
+ setMessages((prevMessages) => {
483
+ const newMessages = [...prevMessages];
484
+ for (const rawMessageToAdd of messagesToAdd) {
485
+ const messageToAdd = storedMessageToLegacyView(rawMessageToAdd);
486
+ const existingIndex = newMessages.findIndex((m) => m.msg.id === messageToAdd.msg.id);
487
+ if (existingIndex !== -1) {
488
+ newMessages[existingIndex] = messageToAdd;
489
+ }
490
+ else {
491
+ newMessages.push(messageToAdd);
492
+ }
493
+ }
494
+ newMessages.sort((a, b) => Date.parse(a.createdAt) - Date.parse(b.createdAt));
495
+ return newMessages;
496
+ });
497
+ }, []);
498
+ useEffect(() => {
499
+ addMessages(fetchedMessages);
500
+ }, [fetchedMessages, addMessages]);
167
501
  const updateMessageWithChunk = useCallback((msgId, { content, ...updates }) => {
168
502
  setMessages((prevMessages) => {
169
503
  const newMessages = [...prevMessages];
170
504
  const index = newMessages.findIndex((m) => m.msg.id === msgId);
171
505
  if (index === -1) {
172
- const responseMessage = {
506
+ newMessages.push({
173
507
  createdAt: new Date().toISOString(),
174
- msg: {
175
- role: "ai",
176
- type: "text",
177
- id: msgId,
178
- content: content || "",
179
- payload: {},
180
- },
181
- };
182
- newMessages.push(responseMessage);
508
+ msg: { role: "ai", type: "text", id: msgId, content: content || "", payload: {} },
509
+ });
183
510
  }
184
511
  else {
185
- const newContent = content !== undefined ? newMessages[index].msg.content + content : content;
512
+ const existing = newMessages[index];
513
+ const newContent = content !== undefined ? (existing.msg.content ?? "") + content : content;
186
514
  newMessages[index] = {
187
- ...newMessages[index],
188
- msg: { ...newMessages[index].msg, content: newContent || "", ...updates },
515
+ ...existing,
516
+ msg: { ...existing.msg, content: newContent || "", ...updates },
189
517
  };
190
518
  }
191
519
  return newMessages;
192
520
  });
193
521
  }, []);
194
- const addAttachments = useCallback((newAttachments) => {
195
- setAttachments((prevAttachments) => [...prevAttachments, ...newAttachments]);
196
- }, []);
197
- const removeAttachment = useCallback((url) => {
198
- setAttachments((prevAttachments) => prevAttachments.filter((attachment) => attachment.url !== url));
199
- }, []);
200
- const clearAttachments = useCallback(() => {
201
- setAttachments([]);
202
- }, []);
203
522
  const sendMessage = useCallback(async ({ content, hiddenContent, ...message }) => {
204
523
  const newMessage = {
205
524
  createdAt: new Date().toISOString(),
@@ -216,57 +535,31 @@ export const AgentChatRoot = ({ appId, token, agentBlockId, useAgentBlockDirectC
216
535
  addMessages([newMessage]);
217
536
  try {
218
537
  setIsThinking(true);
219
- const uploadedAttachments = await uploadAttachments({
220
- attachments: message.attachments,
538
+ const uploadedAttachments = await uploadAttachments({ attachments: message.attachments, appId, token });
539
+ const result = await WorkflowRequest.run({
540
+ workflowBlockId: CHAT_AGENT_CALL_ACTION_BLOCK_ID,
221
541
  appId,
222
542
  token,
543
+ context: { appId, agentChatId },
544
+ input: {
545
+ prompt: content ?? "",
546
+ hiddenPrompt: hiddenContent ?? "",
547
+ files: uploadedAttachments,
548
+ messages: messages
549
+ .map(messageItemToLegacyPayload)
550
+ .filter((legacyMessage) => Boolean(legacyMessage)),
551
+ chatId,
552
+ noPersistency,
553
+ threadId: currentThreadId,
554
+ chatContextFiles,
555
+ chatContext: formatChatContext(chatContext),
556
+ memoryEnabled,
557
+ shortTermMemory,
558
+ },
559
+ onChunk: (chunk) => {
560
+ updateMessageWithChunk(chunk.msgId, { content: chunk.content });
561
+ },
223
562
  });
224
- let result;
225
- if (agentBlockId && useAgentBlockDirectChat) {
226
- result = (await runAgentBlockChat({
227
- token,
228
- payload: {
229
- appId,
230
- agentBlockId,
231
- agentChatId,
232
- chatId,
233
- noPersistency,
234
- prompt: content ?? "",
235
- hiddenPrompt: hiddenContent ?? "",
236
- files: uploadedAttachments,
237
- messages: messages.map((m) => m.msg),
238
- threadId: currentThreadId,
239
- chatContextFiles,
240
- chatContext: chatContext ? `Context: \n${JSON.stringify(chatContext)}` : undefined,
241
- memoryEnabled,
242
- shortTermMemory,
243
- },
244
- }));
245
- }
246
- else {
247
- result = await WorkflowRequest.run({
248
- workflowBlockId: CHAT_AGENT_CALL_ACTION_BLOCK_ID,
249
- appId,
250
- token,
251
- context: { appId, agentChatId },
252
- input: {
253
- prompt: content ?? "",
254
- hiddenPrompt: hiddenContent ?? "",
255
- files: uploadedAttachments,
256
- messages: messages.map((m) => m.msg),
257
- chatId,
258
- noPersistency,
259
- threadId: currentThreadId,
260
- chatContextFiles,
261
- chatContext: chatContext ? `Context: \n${JSON.stringify(chatContext)}` : undefined,
262
- memoryEnabled,
263
- shortTermMemory,
264
- },
265
- onChunk: (chunk) => {
266
- updateMessageWithChunk(chunk.msgId, { content: chunk.content });
267
- },
268
- });
269
- }
270
563
  addMessages(result.messages);
271
564
  }
272
565
  catch (error) {
@@ -277,7 +570,7 @@ export const AgentChatRoot = ({ appId, token, agentBlockId, useAgentBlockDirectC
277
570
  id: generateId(10),
278
571
  role: "ai",
279
572
  type: "text",
280
- content: "Error: " + error.message,
573
+ content: "Error: " + (error?.message ?? "Unknown error"),
281
574
  payload: {},
282
575
  },
283
576
  },
@@ -289,8 +582,6 @@ export const AgentChatRoot = ({ appId, token, agentBlockId, useAgentBlockDirectC
289
582
  }, [
290
583
  addMessages,
291
584
  updateMessageWithChunk,
292
- agentBlockId,
293
- useAgentBlockDirectChat,
294
585
  agentChatId,
295
586
  appId,
296
587
  messages,
@@ -303,81 +594,132 @@ export const AgentChatRoot = ({ appId, token, agentBlockId, useAgentBlockDirectC
303
594
  memoryEnabled,
304
595
  shortTermMemory,
305
596
  ]);
597
+ useAgentChatDataInitialization({ agentChatData, addMessages, sendMessage });
598
+ const inputState = useAgentChatInputState({ isThinking, isFetchingMessages, sendMessage });
599
+ return (_jsx(AgentChatContextProvider, { ...inputState, messages: flattenLegacyMessages(messages), isThinking: isThinking, isFetchingMessages: isFetchingMessages, currentThreadId: currentThreadId, agentChatData: agentChatData, sendMessage: sendMessage, addMessages: addMessages, setCurrentThreadId: setCurrentThreadId, appId: appId, token: token, agentChatId: agentChatId, chatId: chatId, noPersistency: noPersistency, children: children }));
600
+ }
601
+ function AiSdkAgentChatProvider({ appId, token, agentBlockId, agentChatId, children, chatId, noPersistency, currentThreadId, chatContext, chatContextFiles, agentChatData, shortTermMemory = { isEnabled: true }, isFetchingMessages, setCurrentThreadId, fetchedMessages, }) {
602
+ const [externalMessages, setExternalMessages] = useState([]);
603
+ const aiMessageCreatedAtByIdRef = useRef({});
604
+ const previousAiChatIdRef = useRef(undefined);
605
+ const aiChatTransport = useMemo(() => new DefaultChatTransport({
606
+ api: `${getApiHost()}/agent-chat-stream`,
607
+ credentials: "include",
608
+ prepareSendMessagesRequest: ({ body, id, messages, trigger, messageId }) => {
609
+ const submittedMessage = messages[messages.length - 1];
610
+ const requestMessages = Array.isArray(body?.messages) ? body.messages : [];
611
+ return {
612
+ body: {
613
+ ...body,
614
+ id,
615
+ trigger,
616
+ messages: submittedMessage ? [...requestMessages, submittedMessage] : requestMessages,
617
+ ...(messageId ? { messageId } : {}),
618
+ },
619
+ };
620
+ },
621
+ }), []);
622
+ const aiChatId = useMemo(() => [appId, agentChatId, chatId, currentThreadId].filter(Boolean).join(":"), [appId, agentChatId, chatId, currentThreadId]);
623
+ const { messages: aiMessages, sendMessage: sendAiSdkMessage, setMessages: setAiMessages, status: aiChatStatus, } = useChat({
624
+ id: aiChatId,
625
+ transport: aiChatTransport,
626
+ onError: (error) => {
627
+ setAiMessages((prev) => appendAiSdkErrorMessage(prev, error));
628
+ },
629
+ });
306
630
  useEffect(() => {
307
- if (!agentChatData || initializedAgentChatDataRef.current) {
631
+ if (previousAiChatIdRef.current === aiChatId) {
308
632
  return;
309
633
  }
310
- const { initialMessages, initialPrompt } = agentChatData;
311
- if (initialMessages && initialMessages.length > 0) {
312
- setMessages((prevMessages) => {
313
- return [
314
- ...initialMessages.map((initialMessage) => ({
315
- createdAt: new Date(1).toISOString(),
316
- msg: {
317
- id: generateId(),
318
- role: "ai",
319
- type: "text",
320
- content: initialMessage.content,
321
- },
322
- })),
323
- ...prevMessages,
324
- ];
325
- });
634
+ previousAiChatIdRef.current = aiChatId;
635
+ aiMessageCreatedAtByIdRef.current = {};
636
+ setExternalMessages([]);
637
+ setAiMessages([]);
638
+ }, [aiChatId, setAiMessages]);
639
+ const messages = useMemo(() => {
640
+ const fetchedMessageItems = fetchedMessages.map(storedMessageToLegacyView);
641
+ const nextMessages = mergeMessageItemsById(fetchedMessageItems, externalMessages);
642
+ for (const aiMessage of aiMessages) {
643
+ aiMessageCreatedAtByIdRef.current[aiMessage.id] ??= new Date().toISOString();
644
+ const messageItem = uiMessageToV1MessageItem(aiMessage, aiMessageCreatedAtByIdRef.current[aiMessage.id]);
645
+ const existingIndex = nextMessages.findIndex((message) => message.msg.id === messageItem.msg.id);
646
+ if (existingIndex !== -1) {
647
+ nextMessages[existingIndex] = {
648
+ ...nextMessages[existingIndex],
649
+ ...messageItem,
650
+ createdAt: nextMessages[existingIndex].createdAt,
651
+ };
652
+ }
653
+ else {
654
+ nextMessages.push(messageItem);
655
+ }
326
656
  }
327
- if (initialPrompt?.content || initialPrompt?.hiddenContent) {
328
- sendMessage({ content: initialPrompt?.content, hiddenContent: initialPrompt?.hiddenContent });
657
+ nextMessages.sort((a, b) => Date.parse(a.createdAt) - Date.parse(b.createdAt));
658
+ return nextMessages;
659
+ }, [aiMessages, externalMessages, fetchedMessages]);
660
+ const isThinking = aiChatStatus === "submitted" || aiChatStatus === "streaming";
661
+ const addExternalMessages = useCallback((messagesToAdd) => {
662
+ const normalizedMessages = messagesToAdd.map(storedMessageToLegacyView);
663
+ setExternalMessages((prevMessages) => mergeMessageItemsById(prevMessages, normalizedMessages));
664
+ }, []);
665
+ const addAiSdkErrorMessage = useCallback((error) => {
666
+ setAiMessages((prev) => appendAiSdkErrorMessage(prev, error));
667
+ }, [setAiMessages]);
668
+ const sendMessage = useCallback(async ({ content, hiddenContent, ...message }) => {
669
+ try {
670
+ const messageId = generateId();
671
+ const uploadedAttachments = await uploadAttachments({ attachments: message.attachments, appId, token });
672
+ const userUiMessage = {
673
+ id: messageId,
674
+ role: "user",
675
+ parts: [{ type: "text", text: content ?? "" }, ...attachmentsToUiFileParts(uploadedAttachments)],
676
+ metadata: { version: 1, hiddenPrompt: hiddenContent ?? undefined },
677
+ };
678
+ await sendAiSdkMessage(userUiMessage, {
679
+ headers: {
680
+ ...(token ? { Authorization: `Bearer ${token}` } : {}),
681
+ ...(AppVersionService.getCurrentVersionNumber()
682
+ ? { "x-app-version": String(AppVersionService.getCurrentVersionNumber()) }
683
+ : {}),
684
+ ...(websocketsService.getSocketId() ? { "x-socket-id": websocketsService.getSocketId() } : {}),
685
+ ...(appId ? { "x-app-id": appId } : {}),
686
+ },
687
+ body: {
688
+ appId,
689
+ agentBlockId,
690
+ agentChatId,
691
+ chatId,
692
+ threadId: currentThreadId,
693
+ noPersistency,
694
+ shortTermMemory,
695
+ chatContextFiles,
696
+ chatContext: formatChatContext(chatContext),
697
+ messages: messages.map(messageItemToUIMessage),
698
+ },
699
+ });
329
700
  }
330
- initializedAgentChatDataRef.current = true;
331
- }, [agentChatData, sendMessage]);
332
- const sendFromInputs = useCallback(async () => {
333
- if (isThinking || isFetchingMessages || (!prompt && attachments.length === 0)) {
334
- return;
701
+ catch (error) {
702
+ addAiSdkErrorMessage(error);
335
703
  }
336
- const newMessage = {
337
- content: prompt,
338
- type: "text",
339
- attachments,
340
- };
341
- setPrompt("");
342
- setAttachments([]);
343
- return sendMessage(newMessage);
344
- }, [setPrompt, setAttachments, sendMessage, isThinking, isFetchingMessages, prompt, attachments]);
345
- return (_jsx(AgentChatContext.Provider, { value: {
346
- // State
347
- messages: messages.map((m) => ({
348
- ...m,
349
- ...m.msg,
350
- })), // TODO: stop flattening msg properties — requires updating all consumers
351
- attachments,
352
- prompt,
353
- isThinking,
354
- isFetchingMessages,
355
- isDraggingFiles,
356
- currentThreadId,
357
- threadIds,
358
- agentChatData,
359
- // Actions
360
- sendMessage,
361
- sendFromInputs,
362
- addMessages,
363
- addAttachments,
364
- removeAttachment,
365
- clearAttachments,
366
- // Setters
367
- setPrompt,
368
- setAttachments,
369
- setIsDraggingFiles,
370
- setCurrentThreadId,
371
- setThreadIds,
372
- // Config
373
- appId,
374
- token,
375
- agentBlockId,
376
- agentChatId,
377
- chatId,
378
- noPersistency,
379
- }, children: children }));
380
- };
704
+ }, [
705
+ addAiSdkErrorMessage,
706
+ agentBlockId,
707
+ agentChatId,
708
+ appId,
709
+ chatId,
710
+ chatContext,
711
+ chatContextFiles,
712
+ currentThreadId,
713
+ messages,
714
+ noPersistency,
715
+ sendAiSdkMessage,
716
+ shortTermMemory,
717
+ token,
718
+ ]);
719
+ useAgentChatDataInitialization({ agentChatData, addMessages: addExternalMessages, sendMessage });
720
+ const inputState = useAgentChatInputState({ isThinking, isFetchingMessages, sendMessage });
721
+ return (_jsx(AgentChatContextProvider, { ...inputState, messages: messages, isThinking: isThinking, isFetchingMessages: isFetchingMessages, currentThreadId: currentThreadId, agentChatData: agentChatData, sendMessage: sendMessage, addMessages: addExternalMessages, setCurrentThreadId: setCurrentThreadId, appId: appId, token: token, agentBlockId: agentBlockId, agentChatId: agentChatId, chatId: chatId, noPersistency: noPersistency, children: children }));
722
+ }
381
723
  const AgentChatVoiceContext = createContext(null);
382
724
  const noopVoice = {
383
725
  isConnected: false,
@@ -562,7 +904,7 @@ export function AgentChatVoice({ children }) {
562
904
  return;
563
905
  }
564
906
  const conversationHistory = messagesRef.current
565
- .filter((m) => m.msg.content && m.msg.type === "text" && !m.msg.payload?.isVoiceMarker)
907
+ .filter((m) => isLegacyMessageItem(m) && Boolean(m.msg.content) && m.msg.type === "text" && !m.msg.payload?.isVoiceMarker)
566
908
  .slice(-20)
567
909
  .map((m) => ({
568
910
  role: (m.msg.role === "human" ? "user" : "assistant"),
@@ -602,8 +944,16 @@ export function AgentChatVoice({ children }) {
602
944
  say: voiceSay,
603
945
  }, children: children }));
604
946
  }
947
+ const hasRenderableMessageContent = (message) => {
948
+ if (isV1AiSdkMessageItem(message)) {
949
+ return Boolean(message.msg.parts.length);
950
+ }
951
+ const hasTextContent = Boolean(message.msg.content);
952
+ const hasAttachments = Boolean(message.msg.attachments?.length);
953
+ return hasTextContent || hasAttachments;
954
+ };
605
955
  export function AgentChatMessage({ message, index, ...props }) {
606
- if (!message.msg?.content && (!message.msg.attachments || message.msg.attachments.length === 0)) {
956
+ if (!hasRenderableMessageContent(message)) {
607
957
  return null;
608
958
  }
609
959
  return _jsx("div", { "data-message-index": index, "data-message-role": message.msg.role, ...props });
@@ -647,6 +997,27 @@ export function AgentChatMessages({ asChild = false, autoScroll = true, scrollAr
647
997
  scrollToBottom();
648
998
  }
649
999
  }, [messages, isThinking, autoScroll, isAtBottom, scrollToBottom]);
1000
+ // Keep the latest message pinned when streamed markdown/tool UI changes height
1001
+ // without adding a new message object.
1002
+ useEffect(() => {
1003
+ if (!autoScroll) {
1004
+ return;
1005
+ }
1006
+ const scrollElement = scrollRef.current;
1007
+ const contentElement = scrollElement?.firstElementChild;
1008
+ if (!contentElement) {
1009
+ return;
1010
+ }
1011
+ const resizeObserver = new ResizeObserver(() => {
1012
+ if (isAtBottom) {
1013
+ scrollToBottom();
1014
+ }
1015
+ });
1016
+ resizeObserver.observe(contentElement);
1017
+ return () => {
1018
+ resizeObserver.disconnect();
1019
+ };
1020
+ }, [autoScroll, isAtBottom, scrollToBottom]);
650
1021
  return (_jsxs("div", { ref: scrollRef, style: { overflow: "auto" }, className: scrollAreaClassName, ...props, children: [_jsx(Comp, { "data-slot": "agent-chat-messages", ...props }), _jsx("div", { ref: bottomRef, style: {
651
1022
  height: 0,
652
1023
  width: "100%",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocksdiy/react-common",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
4
4
  "type": "module",
5
5
  "description": "React common",
6
6
  "keywords": [],
@@ -30,11 +30,13 @@
30
30
  ]
31
31
  },
32
32
  "dependencies": {
33
+ "@ai-sdk/react": "^3.0.177",
33
34
  "@radix-ui/react-slot": "^1.2.3",
34
- "penpal": "^7.0.6",
35
35
  "@vapi-ai/web": "^2.5.2",
36
+ "ai": "^6.0.175",
37
+ "penpal": "^7.0.6",
36
38
  "react": "^19.2.4",
37
- "@blocksdiy/blocks-client-api": "1.5.0"
39
+ "@blocksdiy/blocks-client-api": "1.9.0"
38
40
  },
39
41
  "devDependencies": {
40
42
  "@types/react": "^19.2.14",