@blocksdiy/react-common 1.8.1 → 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
|
-
|
|
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:
|
|
24
|
+
type: MessageType;
|
|
15
25
|
versionId?: number;
|
|
16
26
|
payload: Record<string, any>;
|
|
17
27
|
hiddenContent?: string;
|
|
18
28
|
}
|
|
19
|
-
export
|
|
20
|
-
|
|
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<
|
|
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
|
|
141
|
+
/** Agent/persona block id used by the Python DeepAgent chat runtime. */
|
|
75
142
|
agentBlockId?: string;
|
|
76
|
-
/**
|
|
77
|
-
|
|
78
|
-
|
|
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;
|
|
@@ -87,8 +153,12 @@ export interface AgentChatRootProps {
|
|
|
87
153
|
chatContextFiles?: Attachment[];
|
|
88
154
|
agentChatData?: AgentChatData;
|
|
89
155
|
memoryEnabled?: boolean;
|
|
156
|
+
shortTermMemory?: {
|
|
157
|
+
isEnabled: boolean;
|
|
158
|
+
};
|
|
90
159
|
}
|
|
91
|
-
export
|
|
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;
|
|
92
162
|
export interface AgentChatVoiceContextValue {
|
|
93
163
|
isConnected: boolean;
|
|
94
164
|
isConnecting: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-chat.d.ts","sourceRoot":"","sources":["../../src/components/agent-chat.tsx"],"names":[],"mappings":"AAKA,OAAO,
|
|
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 {
|
|
3
|
-
import {
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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
|
-
|
|
137
|
-
|
|
138
|
-
|
|
407
|
+
}
|
|
408
|
+
catch {
|
|
409
|
+
if (!cancelled) {
|
|
410
|
+
setResolvedAgentChatConfig({ shortTermMemory: DEFAULT_SHORT_TERM_MEMORY });
|
|
139
411
|
}
|
|
140
412
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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
|
-
|
|
159
|
-
|
|
434
|
+
if (!cancelled) {
|
|
435
|
+
setFetchedMessages(data.filter((chatMessage) => !!chatMessage));
|
|
436
|
+
}
|
|
160
437
|
}
|
|
161
438
|
finally {
|
|
162
|
-
|
|
439
|
+
if (!cancelled) {
|
|
440
|
+
setIsFetchingMessages(false);
|
|
441
|
+
}
|
|
163
442
|
}
|
|
164
443
|
};
|
|
165
444
|
fetchMessages();
|
|
166
|
-
|
|
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
|
-
|
|
506
|
+
newMessages.push({
|
|
173
507
|
createdAt: new Date().toISOString(),
|
|
174
|
-
msg: {
|
|
175
|
-
|
|
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
|
|
512
|
+
const existing = newMessages[index];
|
|
513
|
+
const newContent = content !== undefined ? (existing.msg.content ?? "") + content : content;
|
|
186
514
|
newMessages[index] = {
|
|
187
|
-
...
|
|
188
|
-
msg: { ...
|
|
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,55 +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
|
-
|
|
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
|
-
},
|
|
243
|
-
}));
|
|
244
|
-
}
|
|
245
|
-
else {
|
|
246
|
-
result = await WorkflowRequest.run({
|
|
247
|
-
workflowBlockId: CHAT_AGENT_CALL_ACTION_BLOCK_ID,
|
|
248
|
-
appId,
|
|
249
|
-
token,
|
|
250
|
-
context: { appId, agentChatId },
|
|
251
|
-
input: {
|
|
252
|
-
prompt: content ?? "",
|
|
253
|
-
hiddenPrompt: hiddenContent ?? "",
|
|
254
|
-
files: uploadedAttachments,
|
|
255
|
-
messages: messages.map((m) => m.msg),
|
|
256
|
-
chatId,
|
|
257
|
-
noPersistency,
|
|
258
|
-
threadId: currentThreadId,
|
|
259
|
-
chatContextFiles,
|
|
260
|
-
chatContext: chatContext ? `Context: \n${JSON.stringify(chatContext)}` : undefined,
|
|
261
|
-
memoryEnabled,
|
|
262
|
-
},
|
|
263
|
-
onChunk: (chunk) => {
|
|
264
|
-
updateMessageWithChunk(chunk.msgId, { content: chunk.content });
|
|
265
|
-
},
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
563
|
addMessages(result.messages);
|
|
269
564
|
}
|
|
270
565
|
catch (error) {
|
|
@@ -275,7 +570,7 @@ export const AgentChatRoot = ({ appId, token, agentBlockId, useAgentBlockDirectC
|
|
|
275
570
|
id: generateId(10),
|
|
276
571
|
role: "ai",
|
|
277
572
|
type: "text",
|
|
278
|
-
content: "Error: " + error
|
|
573
|
+
content: "Error: " + (error?.message ?? "Unknown error"),
|
|
279
574
|
payload: {},
|
|
280
575
|
},
|
|
281
576
|
},
|
|
@@ -287,8 +582,6 @@ export const AgentChatRoot = ({ appId, token, agentBlockId, useAgentBlockDirectC
|
|
|
287
582
|
}, [
|
|
288
583
|
addMessages,
|
|
289
584
|
updateMessageWithChunk,
|
|
290
|
-
agentBlockId,
|
|
291
|
-
useAgentBlockDirectChat,
|
|
292
585
|
agentChatId,
|
|
293
586
|
appId,
|
|
294
587
|
messages,
|
|
@@ -299,82 +592,134 @@ export const AgentChatRoot = ({ appId, token, agentBlockId, useAgentBlockDirectC
|
|
|
299
592
|
chatContext,
|
|
300
593
|
chatContextFiles,
|
|
301
594
|
memoryEnabled,
|
|
595
|
+
shortTermMemory,
|
|
302
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
|
+
});
|
|
303
630
|
useEffect(() => {
|
|
304
|
-
if (
|
|
631
|
+
if (previousAiChatIdRef.current === aiChatId) {
|
|
305
632
|
return;
|
|
306
633
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
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
|
+
}
|
|
323
656
|
}
|
|
324
|
-
|
|
325
|
-
|
|
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
|
+
});
|
|
326
700
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
const sendFromInputs = useCallback(async () => {
|
|
330
|
-
if (isThinking || isFetchingMessages || (!prompt && attachments.length === 0)) {
|
|
331
|
-
return;
|
|
701
|
+
catch (error) {
|
|
702
|
+
addAiSdkErrorMessage(error);
|
|
332
703
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
isDraggingFiles,
|
|
353
|
-
currentThreadId,
|
|
354
|
-
threadIds,
|
|
355
|
-
agentChatData,
|
|
356
|
-
// Actions
|
|
357
|
-
sendMessage,
|
|
358
|
-
sendFromInputs,
|
|
359
|
-
addMessages,
|
|
360
|
-
addAttachments,
|
|
361
|
-
removeAttachment,
|
|
362
|
-
clearAttachments,
|
|
363
|
-
// Setters
|
|
364
|
-
setPrompt,
|
|
365
|
-
setAttachments,
|
|
366
|
-
setIsDraggingFiles,
|
|
367
|
-
setCurrentThreadId,
|
|
368
|
-
setThreadIds,
|
|
369
|
-
// Config
|
|
370
|
-
appId,
|
|
371
|
-
token,
|
|
372
|
-
agentBlockId,
|
|
373
|
-
agentChatId,
|
|
374
|
-
chatId,
|
|
375
|
-
noPersistency,
|
|
376
|
-
}, children: children }));
|
|
377
|
-
};
|
|
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
|
+
}
|
|
378
723
|
const AgentChatVoiceContext = createContext(null);
|
|
379
724
|
const noopVoice = {
|
|
380
725
|
isConnected: false,
|
|
@@ -559,7 +904,7 @@ export function AgentChatVoice({ children }) {
|
|
|
559
904
|
return;
|
|
560
905
|
}
|
|
561
906
|
const conversationHistory = messagesRef.current
|
|
562
|
-
.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)
|
|
563
908
|
.slice(-20)
|
|
564
909
|
.map((m) => ({
|
|
565
910
|
role: (m.msg.role === "human" ? "user" : "assistant"),
|
|
@@ -599,8 +944,16 @@ export function AgentChatVoice({ children }) {
|
|
|
599
944
|
say: voiceSay,
|
|
600
945
|
}, children: children }));
|
|
601
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
|
+
};
|
|
602
955
|
export function AgentChatMessage({ message, index, ...props }) {
|
|
603
|
-
if (!
|
|
956
|
+
if (!hasRenderableMessageContent(message)) {
|
|
604
957
|
return null;
|
|
605
958
|
}
|
|
606
959
|
return _jsx("div", { "data-message-index": index, "data-message-role": message.msg.role, ...props });
|
|
@@ -644,6 +997,27 @@ export function AgentChatMessages({ asChild = false, autoScroll = true, scrollAr
|
|
|
644
997
|
scrollToBottom();
|
|
645
998
|
}
|
|
646
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]);
|
|
647
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: {
|
|
648
1022
|
height: 0,
|
|
649
1023
|
width: "100%",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocksdiy/react-common",
|
|
3
|
-
"version": "1.
|
|
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.
|
|
39
|
+
"@blocksdiy/blocks-client-api": "1.9.0"
|
|
38
40
|
},
|
|
39
41
|
"devDependencies": {
|
|
40
42
|
"@types/react": "^19.2.14",
|