@messenger-box/tailwind-ui-inbox 10.0.3-alpha.72 → 10.0.3-alpha.74
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.
- package/CHANGELOG.md +8 -0
- package/lib/components/AIAgent/AIAgent.d.ts +7 -0
- package/lib/components/AIAgent/AIAgent.d.ts.map +1 -1
- package/lib/components/AIAgent/AIAgent.js +362 -615
- package/lib/components/AIAgent/AIAgent.js.map +1 -1
- package/lib/components/InboxMessage/InputComponent.d.ts.map +1 -1
- package/lib/components/InboxMessage/InputComponent.js +143 -140
- package/lib/components/InboxMessage/InputComponent.js.map +1 -1
- package/lib/components/InboxMessage/RightSidebarAi.d.ts +23 -0
- package/lib/components/InboxMessage/RightSidebarAi.d.ts.map +1 -0
- package/lib/components/InboxMessage/RightSidebarAi.js +9 -0
- package/lib/components/InboxMessage/RightSidebarAi.js.map +1 -0
- package/lib/components/InboxMessage/index.d.ts +1 -0
- package/lib/components/InboxMessage/index.d.ts.map +1 -1
- package/lib/components/InboxMessage/message-widgets/ErrorFixCard.d.ts +11 -0
- package/lib/components/InboxMessage/message-widgets/ErrorFixCard.d.ts.map +1 -0
- package/lib/components/InboxMessage/message-widgets/ErrorFixCard.js +194 -0
- package/lib/components/InboxMessage/message-widgets/ErrorFixCard.js.map +1 -0
- package/lib/components/InboxMessage/message-widgets/ModernMessageGroup.d.ts +5 -1
- package/lib/components/InboxMessage/message-widgets/ModernMessageGroup.d.ts.map +1 -1
- package/lib/components/InboxMessage/message-widgets/ModernMessageGroup.js +308 -857
- package/lib/components/InboxMessage/message-widgets/ModernMessageGroup.js.map +1 -1
- package/lib/components/ModelConfigPanel.d.ts +12 -0
- package/lib/components/ModelConfigPanel.d.ts.map +1 -0
- package/lib/components/ModelConfigPanel.js +304 -0
- package/lib/components/ModelConfigPanel.js.map +1 -0
- package/lib/components/filler-components/RightSiderBar.d.ts +24 -0
- package/lib/components/filler-components/RightSiderBar.d.ts.map +1 -0
- package/lib/components/filler-components/RightSiderBar.js +335 -0
- package/lib/components/filler-components/RightSiderBar.js.map +1 -0
- package/lib/components/index.d.ts +4 -2
- package/lib/components/index.d.ts.map +1 -1
- package/lib/components/live-code-editor/hybrid-live-editor.d.ts +20 -0
- package/lib/components/live-code-editor/hybrid-live-editor.d.ts.map +1 -0
- package/lib/components/live-code-editor/hybrid-live-editor.js +68 -0
- package/lib/components/live-code-editor/hybrid-live-editor.js.map +1 -0
- package/lib/components/live-code-editor/index.d.ts +4 -0
- package/lib/components/live-code-editor/index.d.ts.map +1 -0
- package/lib/components/live-code-editor/live-code-editor.d.ts +14 -0
- package/lib/components/live-code-editor/live-code-editor.d.ts.map +1 -0
- package/lib/components/live-code-editor/live-code-editor.js +207 -0
- package/lib/components/live-code-editor/live-code-editor.js.map +1 -0
- package/lib/components/slot-fill/chat-message-filler.js +1 -1
- package/lib/components/slot-fill/chat-message-filler.js.map +1 -1
- package/lib/components/slot-fill/index.d.ts +1 -0
- package/lib/components/slot-fill/index.d.ts.map +1 -1
- package/lib/components/slot-fill/right-sidebar-filler.d.ts +4 -0
- package/lib/components/slot-fill/right-sidebar-filler.d.ts.map +1 -0
- package/lib/components/slot-fill/right-sidebar-filler.js +13 -0
- package/lib/components/slot-fill/right-sidebar-filler.js.map +1 -0
- package/lib/components/ui/button.d.ts +9 -0
- package/lib/components/ui/button.d.ts.map +1 -0
- package/lib/compute.js +1 -2
- package/lib/container/AiInbox.d.ts.map +1 -1
- package/lib/container/AiLandingInput.d.ts.map +1 -1
- package/lib/container/AiLandingInput.js +46 -119
- package/lib/container/AiLandingInput.js.map +1 -1
- package/lib/container/Inbox.js +1 -1
- package/lib/container/Inbox.js.map +1 -1
- package/lib/container/InboxAiMessagesLoader.d.ts +0 -21
- package/lib/container/InboxAiMessagesLoader.d.ts.map +1 -1
- package/lib/container/InboxAiMessagesLoader.js +18 -35
- package/lib/container/InboxAiMessagesLoader.js.map +1 -1
- package/lib/container/ServiceInbox.js +1 -1
- package/lib/container/ServiceInbox.js.map +1 -1
- package/lib/container/ThreadMessages.js +1 -1
- package/lib/container/ThreadMessages.js.map +1 -1
- package/lib/container/ThreadMessagesInbox.js +1 -1
- package/lib/container/ThreadMessagesInbox.js.map +1 -1
- package/lib/container/Threads.js +1 -1
- package/lib/container/Threads.js.map +1 -1
- package/lib/container/index.d.ts +5 -4
- package/lib/container/index.d.ts.map +1 -1
- package/lib/enums/messenger-slot-fill-name-enum.d.ts +2 -1
- package/lib/enums/messenger-slot-fill-name-enum.d.ts.map +1 -1
- package/lib/enums/messenger-slot-fill-name-enum.js +1 -0
- package/lib/enums/messenger-slot-fill-name-enum.js.map +1 -1
- package/lib/hooks/index.d.ts +3 -0
- package/lib/hooks/index.d.ts.map +1 -0
- package/lib/hooks/use-file-sync.d.ts +16 -0
- package/lib/hooks/use-file-sync.d.ts.map +1 -0
- package/lib/hooks/use-file-sync.js +63 -0
- package/lib/hooks/use-file-sync.js.map +1 -0
- package/lib/hooks/usePersistentModelConfig.d.ts +15 -0
- package/lib/hooks/usePersistentModelConfig.d.ts.map +1 -0
- package/lib/hooks/usePersistentModelConfig.js +46 -0
- package/lib/hooks/usePersistentModelConfig.js.map +1 -0
- package/lib/index.d.ts +5 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/machines/aiAgentMachine.d.ts.map +1 -1
- package/lib/machines/aiAgentMachine.js +64 -21
- package/lib/machines/aiAgentMachine.js.map +1 -1
- package/lib/machines/aiAgentMachine.simple.d.ts +3 -0
- package/lib/machines/aiAgentMachine.simple.d.ts.map +1 -0
- package/lib/machines/aiAgentMachine.simple.js +108 -0
- package/lib/machines/aiAgentMachine.simple.js.map +1 -0
- package/lib/machines/index.d.ts +3 -0
- package/lib/machines/index.d.ts.map +1 -0
- package/lib/module.d.ts +2 -1
- package/lib/module.d.ts.map +1 -1
- package/lib/module.js +11 -3
- package/lib/module.js.map +1 -1
- package/lib/routes.json +1 -2
- package/lib/templates/InboxWithAi.d.ts.map +1 -1
- package/lib/templates/InboxWithAi.js +129 -70
- package/lib/templates/InboxWithAi.js.map +1 -1
- package/lib/templates/InboxWithAi.tsx +151 -90
- package/lib/templates/index.d.ts +2 -0
- package/lib/templates/index.d.ts.map +1 -0
- package/lib/templates/index.ts +1 -0
- package/lib/utils/utils.d.ts +2 -0
- package/lib/utils/utils.d.ts.map +1 -0
- package/lib/utils/utils.js +3 -0
- package/lib/utils/utils.js.map +1 -0
- package/package.json +8 -5
- package/src/components/AIAgent/AIAgent.tsx +469 -731
- package/src/components/AIAgent/AIAgent.tsx.bk +1365 -0
- package/src/components/InboxMessage/InputComponent.tsx +2 -1
- package/src/components/InboxMessage/RightSidebarAi.tsx +37 -0
- package/src/components/InboxMessage/index.ts +1 -0
- package/src/components/InboxMessage/message-widgets/ErrorFixCard.tsx +240 -0
- package/src/components/InboxMessage/message-widgets/ModernMessageGroup.tsx +337 -1116
- package/src/components/ModelConfigPanel.tsx +334 -0
- package/src/components/filler-components/RightSiderBar.tsx +408 -0
- package/src/components/index.ts +4 -1
- package/src/components/live-code-editor/hybrid-live-editor.tsx +105 -0
- package/src/components/live-code-editor/index.ts +3 -0
- package/src/components/live-code-editor/live-code-editor.tsx +257 -0
- package/src/components/slot-fill/index.ts +1 -0
- package/src/components/slot-fill/right-sidebar-filler.tsx +39 -0
- package/src/components/ui/button.tsx +32 -0
- package/src/container/AiInbox.tsx +26 -3
- package/src/container/AiLandingInput.tsx +48 -22
- package/src/container/InboxAiMessagesLoader.tsx +17 -41
- package/src/container/index.ts +14 -6
- package/src/enums/messenger-slot-fill-name-enum.ts +1 -0
- package/src/hooks/index.ts +2 -0
- package/src/hooks/use-file-sync.ts +91 -0
- package/src/hooks/usePersistentModelConfig.ts +63 -0
- package/src/index.ts +19 -1
- package/src/machines/aiAgentMachine.simple.ts +89 -0
- package/src/machines/aiAgentMachine.ts +67 -19
- package/src/machines/aiAgentMachine.ts.bk +1296 -0
- package/src/machines/index.ts +2 -0
- package/src/module.tsx +10 -1
- package/src/templates/InboxWithAi.tsx +151 -90
- package/src/templates/index.ts +1 -0
- package/src/utils/utils.ts +3 -0
- package/lib/components/InboxMessage/MessageInputComponent.js +0 -173
- package/lib/components/InboxMessage/MessageInputComponent.js.map +0 -1
- package/lib/components/InboxMessage/MessagesBuilderUi.js +0 -162
- package/lib/components/InboxMessage/MessagesBuilderUi.js.map +0 -1
- package/lib/container/AiInbox.js +0 -1520
- package/lib/container/AiInbox.js.map +0 -1
- package/lib/container/AiInboxWithLoader.js +0 -300
- package/lib/container/AiInboxWithLoader.js.map +0 -1
- package/lib/container/InboxTemplate1.js +0 -1375
- package/lib/container/InboxTemplate1.js.map +0 -1
- package/lib/container/InboxTemplate2.js +0 -1426
- package/lib/container/InboxTemplate2.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React__default,{useState,useRef,
|
|
1
|
+
import React__default,{useState,useRef,useEffect,useCallback,useMemo}from'react';import {useMachine}from'@xstate/react';import {aiAgentMachine}from'../../machines/aiAgentMachine.simple.js';import {InputComponent}from'../InboxMessage/InputComponent.js';import {isToday,isYesterday,format}from'date-fns';import {useTranslation}from'react-i18next';import {ModernMessageGroupComponent}from'../InboxMessage/message-widgets/ModernMessageGroup.js';import {useUploadFiles}from'@messenger-box/platform-client';import {useSelector,shallowEqual}from'react-redux';import {userSelector}from'@adminide-stack/user-auth0-client';import {objectId}from'@messenger-box/core';import {useApolloClient}from'@apollo/client/index.js';import {useSendMessagesMutation,useGenerateAiCodeMutation,useRecreateSandboxMutation,useOnChatMessageAddedSubscription,useSandboxErrorSubscription,useMessagesQuery,MessagesDocument,OnChatMessageAddedDocument}from'common/graphql';import {config}from'../../config/env-config.js';import {orderBy,uniqBy}from'lodash-es';import {useParams,useNavigate}from'@remix-run/react';import {SubscriptionHandler}from'../InboxMessage/SubscriptionHandler.js';import {usePersistentModelConfig}from'../../hooks/usePersistentModelConfig.js';const {
|
|
2
2
|
MESSAGES_PER_PAGE
|
|
3
3
|
} = config;
|
|
4
4
|
const AIAgent = ({
|
|
@@ -8,7 +8,13 @@ const AIAgent = ({
|
|
|
8
8
|
className = '',
|
|
9
9
|
currentUser,
|
|
10
10
|
isDesktopView = false,
|
|
11
|
-
isSmallScreen = false
|
|
11
|
+
isSmallScreen = false,
|
|
12
|
+
setMessages,
|
|
13
|
+
setSelectedPost,
|
|
14
|
+
messages,
|
|
15
|
+
selectedPost,
|
|
16
|
+
setIsLoading,
|
|
17
|
+
isLoading
|
|
12
18
|
}) => {
|
|
13
19
|
const [state, send] = useMachine(aiAgentMachine);
|
|
14
20
|
useApolloClient();
|
|
@@ -16,16 +22,45 @@ const AIAgent = ({
|
|
|
16
22
|
startUpload
|
|
17
23
|
} = useUploadFiles();
|
|
18
24
|
const [sendMsg] = useSendMessagesMutation();
|
|
19
|
-
useSelector(userSelector, shallowEqual);
|
|
25
|
+
const auth = useSelector(userSelector, shallowEqual);
|
|
20
26
|
const {
|
|
21
27
|
id: pathChannelId
|
|
22
28
|
} = useParams();
|
|
29
|
+
useNavigate();
|
|
30
|
+
const {
|
|
31
|
+
modelConfig,
|
|
32
|
+
getValidatedConfig,
|
|
33
|
+
hasApiKey
|
|
34
|
+
} = usePersistentModelConfig();
|
|
35
|
+
// const [isLoading, setIsLoading] = useState(false);
|
|
36
|
+
const [errorData, setError] = useState(null);
|
|
23
37
|
// Get channelId from props or path params
|
|
24
38
|
const actualChannelId = channelId || pathChannelId;
|
|
39
|
+
const [generateAiCode] = useGenerateAiCodeMutation();
|
|
40
|
+
const [recreateSandbox] = useRecreateSandboxMutation();
|
|
41
|
+
const {
|
|
42
|
+
data: chatMessageAddedData
|
|
43
|
+
} = useOnChatMessageAddedSubscription({
|
|
44
|
+
variables: {
|
|
45
|
+
channelId: actualChannelId?.toString() || ''
|
|
46
|
+
},
|
|
47
|
+
skip: !actualChannelId
|
|
48
|
+
});
|
|
49
|
+
// Subscribe to sandbox errors if projectId is provided
|
|
50
|
+
const {
|
|
51
|
+
data: sandboxErrorData
|
|
52
|
+
} = useSandboxErrorSubscription({
|
|
53
|
+
variables: {
|
|
54
|
+
projectId: actualChannelId?.toString() || ''
|
|
55
|
+
},
|
|
56
|
+
skip: !actualChannelId
|
|
57
|
+
});
|
|
25
58
|
// Direct message query from InboxWithAiLoader.tsx
|
|
26
59
|
const messagesQuery = useMessagesQuery({
|
|
27
60
|
variables: {
|
|
28
|
-
|
|
61
|
+
props: {
|
|
62
|
+
projectId: actualChannelId?.toString()
|
|
63
|
+
},
|
|
29
64
|
parentId: null,
|
|
30
65
|
limit: MESSAGES_PER_PAGE
|
|
31
66
|
},
|
|
@@ -49,24 +84,131 @@ const AIAgent = ({
|
|
|
49
84
|
} = useTranslation('translations');
|
|
50
85
|
const [isOpen, setIsOpen] = useState(false);
|
|
51
86
|
const [selectedElement, setSelectedElement] = useState(null);
|
|
52
|
-
const [currentProcessingMessage, setCurrentProcessingMessage] = useState(null);
|
|
53
|
-
const [processedMessageIds, setProcessedMessageIds] = useState(new Set());
|
|
54
87
|
const [activeTab, setActiveTab] = useState('chat');
|
|
55
88
|
const bottomRef = useRef(null);
|
|
89
|
+
const [sandboxErrors, setSandboxErrors] = useState([]);
|
|
90
|
+
const [currentFiles, setCurrentFiles] = useState({});
|
|
91
|
+
const [canvasLayers, setCanvasLayers] = useState([]);
|
|
56
92
|
// New state variables for message display control
|
|
57
|
-
const [
|
|
58
|
-
const
|
|
93
|
+
const [isSuccessThinking, setIsSuccessThinking] = useState(false);
|
|
94
|
+
const successThinkingTimeoutRef = useRef(null);
|
|
59
95
|
// Get regular messages from direct query
|
|
60
96
|
const {
|
|
61
97
|
data: messagesData,
|
|
62
98
|
loading: messageLoading,
|
|
99
|
+
refetch: refetchMessages,
|
|
63
100
|
fetchMore: fetchMoreMessages,
|
|
64
101
|
subscribeToMore
|
|
65
102
|
} = messagesQuery;
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
if (actualChannelId) {
|
|
105
|
+
refetchMessages({
|
|
106
|
+
limit: MESSAGES_PER_PAGE,
|
|
107
|
+
props: {
|
|
108
|
+
projectId: actualChannelId?.toString()
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}, [actualChannelId, refetchMessages]);
|
|
113
|
+
useEffect(() => {
|
|
114
|
+
if (chatMessageAddedData?.chatMessageAdded) {
|
|
115
|
+
console.log('chatMessageAddedData?.chatMessageAdded', JSON.stringify(chatMessageAddedData?.chatMessageAdded, null, 2));
|
|
116
|
+
// handleGenerateAiCode(chatMessageAddedData.chatMessageAdded.id);
|
|
117
|
+
// Stop the success thinking loader once a new message arrives
|
|
118
|
+
if (isSuccessThinking) {
|
|
119
|
+
setIsSuccessThinking(false);
|
|
120
|
+
if (successThinkingTimeoutRef.current) {
|
|
121
|
+
clearTimeout(successThinkingTimeoutRef.current);
|
|
122
|
+
successThinkingTimeoutRef.current = null;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}, [chatMessageAddedData?.chatMessageAdded]);
|
|
127
|
+
useEffect(() => {
|
|
128
|
+
if (messagesData?.messages?.data?.length == 1) {
|
|
129
|
+
handleGenerateAiCode(messagesData.messages.data[0].id);
|
|
130
|
+
}
|
|
131
|
+
// console.log('messagesData?.messages?.data',JSON.stringify(messagesData?.messages?.data,null,2))
|
|
132
|
+
}, [messagesData?.messages?.data]);
|
|
133
|
+
// Handle sandbox error subscription updates
|
|
134
|
+
useEffect(() => {
|
|
135
|
+
if (sandboxErrorData?.sandboxError) {
|
|
136
|
+
const errorData = sandboxErrorData.sandboxError;
|
|
137
|
+
console.log('Sandbox error received:', errorData);
|
|
138
|
+
setSandboxErrors(prev => [...prev, errorData.error]);
|
|
139
|
+
}
|
|
140
|
+
}, [sandboxErrorData]);
|
|
66
141
|
const regularMessages = useMemo(() => {
|
|
67
142
|
if (!messagesData?.messages?.data) return [];
|
|
68
143
|
return orderBy(uniqBy(messagesData.messages.data || [], 'id'), ['createdAt'], ['asc']);
|
|
69
144
|
}, [messagesData?.messages?.data]);
|
|
145
|
+
// Send regular messages to AI agent machine for context
|
|
146
|
+
useEffect(() => {
|
|
147
|
+
if (regularMessages && regularMessages.length > 0) {
|
|
148
|
+
send({
|
|
149
|
+
type: 'UPDATE_REGULAR_MESSAGES',
|
|
150
|
+
messages: regularMessages
|
|
151
|
+
});
|
|
152
|
+
setMessages(regularMessages);
|
|
153
|
+
const currentMessage = regularMessages?.[regularMessages.length - 1];
|
|
154
|
+
setSelectedPost(regularMessages[regularMessages.length - 1]);
|
|
155
|
+
setCurrentFiles(currentMessage?.propsConfiguration?.contents?.fragment?.files ?? {});
|
|
156
|
+
let canvasLayers = currentMessage?.propsConfiguration?.contents?.fragment?.canvasLayers ?? [];
|
|
157
|
+
const summary = currentMessage?.propsConfiguration?.contents?.fragment?.summary ?? null;
|
|
158
|
+
// If not in direct field, try to extract from summary
|
|
159
|
+
if (!canvasLayers && summary) {
|
|
160
|
+
const canvasLayersMatch = summary?.match(/<canvas_layers>([\s\S]*?)<\/canvas_layers>/);
|
|
161
|
+
if (canvasLayersMatch) {
|
|
162
|
+
try {
|
|
163
|
+
canvasLayers = JSON.parse(canvasLayersMatch[1]);
|
|
164
|
+
} catch (error) {
|
|
165
|
+
console.error('Failed to parse canvas layers from summary:', error);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// Update canvas layers if available
|
|
170
|
+
if (canvasLayers && Array.isArray(canvasLayers)) {
|
|
171
|
+
setCanvasLayers(canvasLayers);
|
|
172
|
+
}
|
|
173
|
+
console.log('currenmessage', currentMessage);
|
|
174
|
+
if (currentMessage?.propsConfiguration?.contents?.role === 'ASSISTANT') ;
|
|
175
|
+
scrollToBottom('smooth', 0);
|
|
176
|
+
}
|
|
177
|
+
}, [regularMessages, send]);
|
|
178
|
+
const handleGenerateAiCode = useCallback(messageId => {
|
|
179
|
+
generateAiCode({
|
|
180
|
+
variables: {
|
|
181
|
+
messageId: messageId,
|
|
182
|
+
modelConfig: modelConfig
|
|
183
|
+
},
|
|
184
|
+
onCompleted: res => {
|
|
185
|
+
if (res.generateAiCode.success) {
|
|
186
|
+
console.log('generated_result', res);
|
|
187
|
+
// Show AI is thinking loader on success
|
|
188
|
+
if (successThinkingTimeoutRef.current) {
|
|
189
|
+
clearTimeout(successThinkingTimeoutRef.current);
|
|
190
|
+
successThinkingTimeoutRef.current = null;
|
|
191
|
+
}
|
|
192
|
+
setIsSuccessThinking(true);
|
|
193
|
+
// Fallback auto-hide after 15s in case no subsequent event arrives
|
|
194
|
+
successThinkingTimeoutRef.current = setTimeout(() => {
|
|
195
|
+
setIsSuccessThinking(false);
|
|
196
|
+
// setIsLoading(false);
|
|
197
|
+
successThinkingTimeoutRef.current = null;
|
|
198
|
+
}, 15000);
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
onError: err => {
|
|
202
|
+
console.log('err', JSON.stringify(err, null, 2));
|
|
203
|
+
// Also ensure loader is hidden on error
|
|
204
|
+
if (successThinkingTimeoutRef.current) {
|
|
205
|
+
clearTimeout(successThinkingTimeoutRef.current);
|
|
206
|
+
successThinkingTimeoutRef.current = null;
|
|
207
|
+
}
|
|
208
|
+
setIsSuccessThinking(false);
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
}, [generateAiCode, modelConfig]);
|
|
70
212
|
const onOpen = element => {
|
|
71
213
|
setSelectedElement(element);
|
|
72
214
|
setIsOpen(true);
|
|
@@ -87,87 +229,148 @@ const AIAgent = ({
|
|
|
87
229
|
}
|
|
88
230
|
}, delay);
|
|
89
231
|
}, []);
|
|
232
|
+
const recreateSandboxForFragment = useCallback(async messageId => {
|
|
233
|
+
if (!actualChannelId) {
|
|
234
|
+
console.error('No project ID available for sandbox recreation');
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
try {
|
|
238
|
+
setIsLoading(true);
|
|
239
|
+
setError(null);
|
|
240
|
+
const response = await recreateSandbox({
|
|
241
|
+
variables: {
|
|
242
|
+
projectId: actualChannelId,
|
|
243
|
+
messageId
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
if (response.data?.recreateSandbox?.success) {
|
|
247
|
+
console.log('Sandbox recreation initiated successfully');
|
|
248
|
+
// The subscription will handle updating the UI with the new sandbox URL
|
|
249
|
+
} else {
|
|
250
|
+
const errorMsg = response.data?.recreateSandbox?.message || 'Failed to recreate sandbox';
|
|
251
|
+
throw new Error(errorMsg);
|
|
252
|
+
}
|
|
253
|
+
} catch (err) {
|
|
254
|
+
console.error('Error recreating sandbox:', err);
|
|
255
|
+
setError(err instanceof Error ? err.message : 'Failed to recreate sandbox');
|
|
256
|
+
setIsLoading(false);
|
|
257
|
+
}
|
|
258
|
+
}, [recreateSandbox, actualChannelId]);
|
|
90
259
|
// Updated handleSend function from InboxWithAi.tsx
|
|
91
260
|
const handleSend = useCallback(async (message, files = []) => {
|
|
92
261
|
// Allow sending if there's either a message or files
|
|
93
262
|
if ((!message || !message.trim()) && (!files || files.length === 0)) return;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
},
|
|
135
|
-
props: {},
|
|
136
|
-
files: {
|
|
137
|
-
__typename: 'FilesInfo',
|
|
138
|
-
data: files || [],
|
|
139
|
-
totalCount: files?.length || 0
|
|
140
|
-
},
|
|
141
|
-
replies: {
|
|
142
|
-
__typename: 'Messages',
|
|
143
|
-
data: [],
|
|
144
|
-
totalCount: 0
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
const optimisticMessage = createOptimisticMessage(files);
|
|
148
|
-
if (files?.length > 0) {
|
|
149
|
-
const uploadResponse = await startUpload({
|
|
150
|
-
file: files,
|
|
151
|
-
saveUploadedFile: {
|
|
152
|
-
variables: {
|
|
153
|
-
postId
|
|
154
|
-
}
|
|
263
|
+
const validated = getValidatedConfig();
|
|
264
|
+
if (!validated && !hasApiKey) {
|
|
265
|
+
// No API key/config; do nothing (AiLandingInput would prompt config UI)
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
// Start the AI thinking loader immediately on send
|
|
269
|
+
if (successThinkingTimeoutRef.current) {
|
|
270
|
+
clearTimeout(successThinkingTimeoutRef.current);
|
|
271
|
+
successThinkingTimeoutRef.current = null;
|
|
272
|
+
}
|
|
273
|
+
setIsSuccessThinking(true);
|
|
274
|
+
setIsLoading(true);
|
|
275
|
+
// Safety auto-stop in case no event arrives
|
|
276
|
+
successThinkingTimeoutRef.current = setTimeout(() => {
|
|
277
|
+
setIsSuccessThinking(false);
|
|
278
|
+
successThinkingTimeoutRef.current = null;
|
|
279
|
+
}, 15000);
|
|
280
|
+
// If we already have a channel, send message (with optional file upload) similar to Inbox
|
|
281
|
+
if (actualChannelId) {
|
|
282
|
+
try {
|
|
283
|
+
const postId = objectId();
|
|
284
|
+
const channelId = objectId();
|
|
285
|
+
const currentDate = new Date();
|
|
286
|
+
const createOptimisticMessage = uploadedFiles => ({
|
|
287
|
+
__typename: 'Post',
|
|
288
|
+
id: postId,
|
|
289
|
+
message,
|
|
290
|
+
createdAt: currentDate.toISOString(),
|
|
291
|
+
updatedAt: currentDate.toISOString(),
|
|
292
|
+
author: {
|
|
293
|
+
__typename: 'UserAccount',
|
|
294
|
+
id: auth?.id,
|
|
295
|
+
givenName: auth?.profile?.given_name || '',
|
|
296
|
+
familyName: auth?.profile?.family_name || '',
|
|
297
|
+
email: auth?.profile?.email || '',
|
|
298
|
+
username: auth?.profile?.nickname || '',
|
|
299
|
+
fullName: auth?.profile?.name || '',
|
|
300
|
+
picture: auth?.profile?.picture || '',
|
|
301
|
+
alias: [auth?.authUserId ?? ''],
|
|
302
|
+
tokens: []
|
|
155
303
|
},
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
304
|
+
isDelivered: false,
|
|
305
|
+
isRead: false,
|
|
306
|
+
type: 'TEXT',
|
|
307
|
+
parentId: null,
|
|
308
|
+
fromServer: false,
|
|
309
|
+
channel: {
|
|
310
|
+
__typename: 'Channel',
|
|
311
|
+
id: actualChannelId
|
|
312
|
+
},
|
|
313
|
+
propsConfiguration: {
|
|
314
|
+
__typename: 'MachineConfiguration',
|
|
315
|
+
id: null,
|
|
316
|
+
resource: '',
|
|
317
|
+
contents: null,
|
|
318
|
+
keys: null,
|
|
319
|
+
target: null,
|
|
320
|
+
overrides: null
|
|
321
|
+
},
|
|
322
|
+
props: {},
|
|
323
|
+
files: {
|
|
324
|
+
__typename: 'FilesInfo',
|
|
325
|
+
data: uploadedFiles || [],
|
|
326
|
+
totalCount: uploadedFiles?.length || 0
|
|
327
|
+
},
|
|
328
|
+
replies: {
|
|
329
|
+
__typename: 'Messages',
|
|
330
|
+
data: [],
|
|
331
|
+
totalCount: 0
|
|
160
332
|
}
|
|
161
333
|
});
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
334
|
+
const cacheMessagesQuery = {
|
|
335
|
+
query: MessagesDocument,
|
|
336
|
+
variables: {
|
|
337
|
+
// Match variables used in useMessagesQuery above
|
|
338
|
+
props: {
|
|
339
|
+
projectId: actualChannelId.toString()
|
|
340
|
+
},
|
|
341
|
+
parentId: null,
|
|
342
|
+
limit: MESSAGES_PER_PAGE
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
const extraProps = {
|
|
346
|
+
projectId: actualChannelId,
|
|
347
|
+
template: modelConfig?.template || 'vite-react',
|
|
348
|
+
role: 'USER',
|
|
349
|
+
sendNotificationWithProjectId: true
|
|
350
|
+
};
|
|
351
|
+
if (files?.length > 0) {
|
|
352
|
+
const uploadResponse = await startUpload({
|
|
353
|
+
file: files,
|
|
354
|
+
saveUploadedFile: {
|
|
355
|
+
variables: {
|
|
356
|
+
postId
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
createUploadLink: {
|
|
360
|
+
variables: {
|
|
361
|
+
postId
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
const uploadedFiles = uploadResponse.data;
|
|
366
|
+
const fileIds = (uploadedFiles || []).map(f => f.id);
|
|
165
367
|
await sendMsg({
|
|
166
368
|
variables: {
|
|
167
369
|
postId,
|
|
168
370
|
channelId: actualChannelId,
|
|
169
371
|
content: message,
|
|
170
|
-
files: fileIds
|
|
372
|
+
files: fileIds,
|
|
373
|
+
extraProps
|
|
171
374
|
},
|
|
172
375
|
optimisticResponse: {
|
|
173
376
|
__typename: 'Mutation',
|
|
@@ -177,282 +380,47 @@ const AIAgent = ({
|
|
|
177
380
|
data: mutationData
|
|
178
381
|
}) => {
|
|
179
382
|
if (!mutationData?.sendMessage) return;
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
query: MessagesDocument,
|
|
183
|
-
variables: {
|
|
184
|
-
channelId: actualChannelId.toString(),
|
|
185
|
-
parentId: null,
|
|
186
|
-
limit: MESSAGES_PER_PAGE
|
|
187
|
-
}
|
|
188
|
-
};
|
|
189
|
-
try {
|
|
190
|
-
const existingData = cache.readQuery(messagesQuery);
|
|
191
|
-
if (existingData?.messages) {
|
|
192
|
-
cache.writeQuery({
|
|
193
|
-
...messagesQuery,
|
|
194
|
-
data: {
|
|
195
|
-
messages: {
|
|
196
|
-
...existingData.messages,
|
|
197
|
-
data: [...(existingData.messages.data || []), mutationData.sendMessage],
|
|
198
|
-
totalCount: (existingData.messages.totalCount || 0) + 1
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
} catch (error) {
|
|
204
|
-
console.debug('Cache update failed (expected on first message):', error);
|
|
383
|
+
if (mutationData?.sendMessage?.id) {
|
|
384
|
+
handleGenerateAiCode(mutationData.sendMessage.id);
|
|
205
385
|
}
|
|
206
386
|
}
|
|
207
387
|
});
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
variables: {
|
|
227
|
-
channelId: actualChannelId.toString(),
|
|
228
|
-
parentId: null,
|
|
229
|
-
limit: MESSAGES_PER_PAGE
|
|
230
|
-
}
|
|
231
|
-
};
|
|
232
|
-
try {
|
|
233
|
-
const existingData = cache.readQuery(messagesQuery);
|
|
234
|
-
if (existingData?.messages) {
|
|
235
|
-
cache.writeQuery({
|
|
236
|
-
...messagesQuery,
|
|
237
|
-
data: {
|
|
238
|
-
messages: {
|
|
239
|
-
...existingData.messages,
|
|
240
|
-
data: [...(existingData.messages.data || []), mutationData.sendMessage],
|
|
241
|
-
totalCount: (existingData.messages.totalCount || 0) + 1
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
});
|
|
388
|
+
} else {
|
|
389
|
+
await sendMsg({
|
|
390
|
+
variables: {
|
|
391
|
+
channelId: actualChannelId,
|
|
392
|
+
content: message,
|
|
393
|
+
extraProps
|
|
394
|
+
},
|
|
395
|
+
optimisticResponse: {
|
|
396
|
+
__typename: 'Mutation',
|
|
397
|
+
sendMessage: createOptimisticMessage()
|
|
398
|
+
},
|
|
399
|
+
update: (cache, {
|
|
400
|
+
data: mutationData
|
|
401
|
+
}) => {
|
|
402
|
+
if (!mutationData?.sendMessage) return;
|
|
403
|
+
console.log('mutationData', JSON.stringify(mutationData, null, 2));
|
|
404
|
+
if (mutationData?.sendMessage?.id) {
|
|
405
|
+
handleGenerateAiCode(mutationData.sendMessage.id);
|
|
245
406
|
}
|
|
246
|
-
} catch (error) {
|
|
247
|
-
console.debug('Cache update failed (expected on first message):', error);
|
|
248
407
|
}
|
|
249
|
-
}
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
// Send message to AI agent machine
|
|
253
|
-
send({
|
|
254
|
-
type: 'SEND_MESSAGE',
|
|
255
|
-
message: message.trim()
|
|
256
|
-
});
|
|
257
|
-
// Ensure we scroll to the newest message immediately
|
|
258
|
-
scrollToBottom('smooth', 0);
|
|
259
|
-
// When sending new messages, increment the displayed count to show the new message
|
|
260
|
-
// This ensures we show both the existing last message and the new message
|
|
261
|
-
setDisplayedMessageCount(prev => {
|
|
262
|
-
const newCount = Math.max(prev + 1, 2);
|
|
263
|
-
console.log('🔄 Message sent: Updating displayedMessageCount', {
|
|
264
|
-
previous: prev,
|
|
265
|
-
new: newCount,
|
|
266
|
-
reason: 'New message sent'
|
|
267
|
-
});
|
|
268
|
-
return newCount;
|
|
269
|
-
});
|
|
270
|
-
// Call the optional onSendMessage prop if provided
|
|
271
|
-
if (onSendMessage) {
|
|
272
|
-
await onSendMessage(message, files);
|
|
273
|
-
}
|
|
274
|
-
} catch (error) {
|
|
275
|
-
console.error('Error sending message:', error);
|
|
276
|
-
}
|
|
277
|
-
}, [actualChannelId, currentUser, startUpload, sendMsg, send, onSendMessage]);
|
|
278
|
-
// Debug effect to track AI messages changes
|
|
279
|
-
useEffect(() => {
|
|
280
|
-
console.log('🤖 AI messages state changed:', aiMessages.length);
|
|
281
|
-
if (aiMessages.length > 0) {
|
|
282
|
-
console.log('🤖 Latest AI message:', aiMessages[aiMessages.length - 1]);
|
|
283
|
-
// Clear processing message if we have new AI responses
|
|
284
|
-
if (currentProcessingMessage !== null) {
|
|
285
|
-
console.log('🤖 AI response received, clearing processing message');
|
|
286
|
-
setCurrentProcessingMessage(null);
|
|
287
|
-
}
|
|
288
|
-
// Auto-scroll to bottom when new AI response appears
|
|
289
|
-
scrollToBottom('smooth', 200);
|
|
290
|
-
} else {
|
|
291
|
-
console.log('🤖 No AI messages in state - this might indicate an issue');
|
|
292
|
-
}
|
|
293
|
-
}, [aiMessages, currentProcessingMessage]);
|
|
294
|
-
// Debug effect to track machine state changes
|
|
295
|
-
useEffect(() => {
|
|
296
|
-
console.log('🤖 Machine state changed:', state.value);
|
|
297
|
-
console.log('🤖 Machine context:', {
|
|
298
|
-
messagesCount: state.context.messages.length,
|
|
299
|
-
hasMessageToRespondTo: !!state.context.messageToRespondTo,
|
|
300
|
-
messageToRespondTo: state.context.messageToRespondTo
|
|
301
|
-
});
|
|
302
|
-
// Check if we're in processing state but no AI response is being generated
|
|
303
|
-
if (state.value === 'processing' && !state.context.messageToRespondTo) {
|
|
304
|
-
console.log('🤖 ⚠️ WARNING: In processing state but no messageToRespondTo!');
|
|
305
|
-
}
|
|
306
|
-
// Auto-scroll when AI starts processing
|
|
307
|
-
if (state.value === 'processing') {
|
|
308
|
-
scrollToBottom('smooth', 100);
|
|
309
|
-
}
|
|
310
|
-
}, [state.value, state.context, scrollToBottom]);
|
|
311
|
-
// Send regular messages to AI agent machine for context
|
|
312
|
-
useEffect(() => {
|
|
313
|
-
if (regularMessages && regularMessages.length > 0) {
|
|
314
|
-
send({
|
|
315
|
-
type: 'UPDATE_REGULAR_MESSAGES',
|
|
316
|
-
messages: regularMessages
|
|
317
|
-
});
|
|
318
|
-
}
|
|
319
|
-
}, [regularMessages, send]);
|
|
320
|
-
// Reset processed messages when regular messages change completely
|
|
321
|
-
useEffect(() => {
|
|
322
|
-
if (regularMessages && regularMessages.length > 0) {
|
|
323
|
-
// Check if we have completely new messages (different IDs)
|
|
324
|
-
new Set(regularMessages.map(msg => msg.id));
|
|
325
|
-
const hasNewMessages = !regularMessages.every(msg => processedMessageIds.has(msg.id));
|
|
326
|
-
if (hasNewMessages) {
|
|
327
|
-
console.log('🤖 New messages detected, resetting processed state');
|
|
328
|
-
setProcessedMessageIds(new Set());
|
|
329
|
-
setCurrentProcessingMessage(null);
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
}, [regularMessages]);
|
|
333
|
-
// Sequential auto-response logic - respond to each message one at a time
|
|
334
|
-
useEffect(() => {
|
|
335
|
-
if (regularMessages && regularMessages.length > 0) {
|
|
336
|
-
console.log('🤖 Regular messages detected:', regularMessages.length);
|
|
337
|
-
console.log('🤖 Current AI messages:', aiMessages.length);
|
|
338
|
-
console.log('🤖 Already processed message IDs:', Array.from(processedMessageIds));
|
|
339
|
-
// Find messages that don't have AI responses yet and haven't been processed
|
|
340
|
-
const messagesWithoutAIResponses = regularMessages.filter((msg, index) => {
|
|
341
|
-
// Check if this message already has an AI response
|
|
342
|
-
const hasAIResponse = aiMessages.length > index;
|
|
343
|
-
// Check if this message has already been processed
|
|
344
|
-
const alreadyProcessed = processedMessageIds.has(msg.id);
|
|
345
|
-
return !hasAIResponse && !alreadyProcessed;
|
|
346
|
-
});
|
|
347
|
-
if (messagesWithoutAIResponses.length > 0) {
|
|
348
|
-
console.log(`🤖 Found ${messagesWithoutAIResponses.length} messages to process`);
|
|
349
|
-
// Simplified: Just process the first message and let the machine handle the rest
|
|
350
|
-
const firstMsg = messagesWithoutAIResponses[0];
|
|
351
|
-
console.log(`🤖 Starting with first message: ${firstMsg.message?.substring(0, 50)}...`);
|
|
352
|
-
// Mark this message as being processed
|
|
353
|
-
setProcessedMessageIds(prev => new Set([...prev, firstMsg.id]));
|
|
354
|
-
setCurrentProcessingMessage(0);
|
|
355
|
-
// Send the first message to AI
|
|
356
|
-
send({
|
|
357
|
-
type: 'AUTO_RESPOND_TO_MESSAGE',
|
|
358
|
-
message: firstMsg.message,
|
|
359
|
-
isAutoResponse: true
|
|
360
|
-
});
|
|
361
|
-
} else {
|
|
362
|
-
console.log('🤖 All messages already have AI responses or are being processed');
|
|
363
|
-
setCurrentProcessingMessage(null);
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
}, [regularMessages.length, aiMessages.length, processedMessageIds.size]); // Only depend on lengths and processed count
|
|
367
|
-
// Process next message when machine becomes idle (after completing AI response)
|
|
368
|
-
useEffect(() => {
|
|
369
|
-
// Only run when machine is idle and we have messages to process
|
|
370
|
-
if (state.matches('idle') && regularMessages && regularMessages.length > 0) {
|
|
371
|
-
console.log('🤖 Machine idle, checking for next message to process...');
|
|
372
|
-
console.log('🤖 Current state - AI messages:', aiMessages.length, 'Processed IDs:', processedMessageIds.size);
|
|
373
|
-
// Find the next message that needs an AI response
|
|
374
|
-
const nextMessageIndex = regularMessages.findIndex((msg, index) => {
|
|
375
|
-
const hasAIResponse = aiMessages.length > index;
|
|
376
|
-
const alreadyProcessed = processedMessageIds.has(msg.id);
|
|
377
|
-
const needsResponse = !hasAIResponse && !alreadyProcessed;
|
|
378
|
-
console.log(`🤖 Message ${index + 1} "${msg.message?.substring(0, 30)}..." - hasAIResponse: ${hasAIResponse}, alreadyProcessed: ${alreadyProcessed}, needsResponse: ${needsResponse}`);
|
|
379
|
-
return needsResponse;
|
|
380
|
-
});
|
|
381
|
-
if (nextMessageIndex !== -1) {
|
|
382
|
-
console.log(`🤖 Found next message to process: ${nextMessageIndex + 1}: ${regularMessages[nextMessageIndex].message?.substring(0, 50)}...`);
|
|
383
|
-
// Check if this message is a duplicate of a previous one
|
|
384
|
-
const currentMessage = regularMessages[nextMessageIndex];
|
|
385
|
-
const previousMessageIndex = regularMessages.findIndex((prevMsg, prevIndex) => prevIndex < nextMessageIndex && prevMsg.message === currentMessage.message);
|
|
386
|
-
if (previousMessageIndex !== -1 && aiMessages.length > previousMessageIndex) {
|
|
387
|
-
// This is a duplicate message, mark it as processed without sending to AI
|
|
388
|
-
console.log(`🤖 Duplicate message detected: "${currentMessage.message}" - reusing AI response from message ${previousMessageIndex + 1}`);
|
|
389
|
-
setProcessedMessageIds(prev => new Set([...prev, currentMessage.id]));
|
|
390
|
-
setCurrentProcessingMessage(null);
|
|
391
|
-
// Continue with next message immediately
|
|
392
|
-
setTimeout(() => {
|
|
393
|
-
send({
|
|
394
|
-
type: 'CONTINUE_PROCESSING'
|
|
395
|
-
});
|
|
396
|
-
}, 100);
|
|
397
|
-
} else {
|
|
398
|
-
// Mark this message as being processed
|
|
399
|
-
setProcessedMessageIds(prev => new Set([...prev, currentMessage.id]));
|
|
400
|
-
setCurrentProcessingMessage(nextMessageIndex);
|
|
401
|
-
// Send to AI
|
|
402
|
-
console.log(`🤖 Sending message to AI: "${currentMessage.message}"`);
|
|
403
|
-
send({
|
|
404
|
-
type: 'AUTO_RESPOND_TO_MESSAGE',
|
|
405
|
-
message: currentMessage.message,
|
|
406
|
-
isAutoResponse: true
|
|
407
408
|
});
|
|
408
409
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
console.log(`🤖 No more messages to process. Summary:`, {
|
|
415
|
-
totalMessages: totalMessagesNeedingResponses,
|
|
416
|
-
messagesWithResponses,
|
|
417
|
-
messagesProcessed,
|
|
418
|
-
allHaveResponses: messagesWithResponses >= totalMessagesNeedingResponses
|
|
419
|
-
});
|
|
420
|
-
if (messagesWithResponses >= totalMessagesNeedingResponses) {
|
|
421
|
-
console.log('🤖 All messages have been processed successfully');
|
|
422
|
-
setCurrentProcessingMessage(null);
|
|
423
|
-
} else {
|
|
424
|
-
console.log('🤖 ⚠️ Discrepancy detected: Some messages may not have proper AI responses');
|
|
425
|
-
// Force a reset to try again
|
|
426
|
-
setProcessedMessageIds(new Set());
|
|
427
|
-
setCurrentProcessingMessage(null);
|
|
428
|
-
}
|
|
410
|
+
// Scroll to bottom after send
|
|
411
|
+
scrollToBottom('smooth', 0);
|
|
412
|
+
} catch (error) {
|
|
413
|
+
console.error('Error sending message from AIAgent:', error);
|
|
414
|
+
setIsLoading(false);
|
|
429
415
|
}
|
|
416
|
+
return;
|
|
430
417
|
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
setCurrentProcessingMessage(null);
|
|
438
|
-
console.log('🤖 Reset processing state for new messages');
|
|
439
|
-
}
|
|
440
|
-
}, [regularMessages.length]); // Only depend on length to avoid unnecessary resets
|
|
441
|
-
// Only reset displayed message count on initial load, not when new messages arrive
|
|
442
|
-
useEffect(() => {
|
|
443
|
-
if (regularMessages && regularMessages.length > 0) {
|
|
444
|
-
// Only reset to show last message if this is the first time we're getting messages
|
|
445
|
-
// or if we're currently showing more messages than we have
|
|
446
|
-
if (displayedMessageCount === 1 || displayedMessageCount > regularMessages.length) {
|
|
447
|
-
console.log('🔄 Resetting displayedMessageCount to 1:', {
|
|
448
|
-
reason: 'Initial load or count mismatch',
|
|
449
|
-
currentDisplayed: displayedMessageCount,
|
|
450
|
-
regularMessagesLength: regularMessages.length
|
|
451
|
-
});
|
|
452
|
-
setDisplayedMessageCount(1);
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
}, [regularMessages.length, displayedMessageCount]);
|
|
418
|
+
// If no channelId, we skip sending here.
|
|
419
|
+
}, [actualChannelId, auth, startUpload, sendMsg, scrollToBottom, getValidatedConfig, hasApiKey, modelConfig]);
|
|
420
|
+
const fixError = useCallback(errorMessage => {
|
|
421
|
+
// Use sendMessage to fix the error, which will use createProject flow
|
|
422
|
+
return handleSend(errorMessage);
|
|
423
|
+
}, [handleSend]);
|
|
456
424
|
const handleRetry = useCallback(() => {
|
|
457
425
|
send({
|
|
458
426
|
type: 'RETRY'
|
|
@@ -463,173 +431,22 @@ const AIAgent = ({
|
|
|
463
431
|
type: 'CLEAR_ERROR'
|
|
464
432
|
});
|
|
465
433
|
}, [send]);
|
|
466
|
-
//
|
|
434
|
+
// Use only default/regular messages and ignore AI messages
|
|
467
435
|
const allMessages = useMemo(() => {
|
|
468
436
|
if (!regularMessages) return [];
|
|
469
|
-
console.log('🔄 Merging messages - AI messages:', aiMessages.length, 'Regular messages:', regularMessages.length);
|
|
470
|
-
console.log('🔄 AI messages content:', aiMessages.map(m => ({
|
|
471
|
-
id: m.id,
|
|
472
|
-
content: m.content.substring(0, 50) + '...',
|
|
473
|
-
sender: m.sender
|
|
474
|
-
})));
|
|
475
437
|
const regularMessagesFormatted = (regularMessages || []).map((m, idx) => ({
|
|
476
438
|
id: m.id || `regular-${idx}`,
|
|
477
439
|
message: m.message || m.content || '',
|
|
478
440
|
createdAt: new Date(m.createdAt || Date.now()),
|
|
441
|
+
propsConfiguration: m.propsConfiguration,
|
|
442
|
+
props: m.props,
|
|
443
|
+
files: m.files,
|
|
479
444
|
sender: 'user',
|
|
480
445
|
author: m.author,
|
|
481
|
-
isUserMessage: true
|
|
446
|
+
isUserMessage: true
|
|
482
447
|
}));
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
message: m.content,
|
|
486
|
-
createdAt: new Date(m.timestamp || Date.now()),
|
|
487
|
-
sender: 'ai',
|
|
488
|
-
isUserMessage: false // Explicitly mark as AI message
|
|
489
|
-
}));
|
|
490
|
-
// Show ALL user messages immediately, interleave AI responses as they arrive
|
|
491
|
-
const interleavedMessages = [];
|
|
492
|
-
console.log('🔄 Starting message interleaving...');
|
|
493
|
-
console.log('🔄 Regular messages count:', regularMessagesFormatted.length);
|
|
494
|
-
console.log('🔄 AI messages count:', aiMessagesFormatted.length);
|
|
495
|
-
for (let i = 0; i < regularMessagesFormatted.length; i++) {
|
|
496
|
-
const userMsg = regularMessagesFormatted[i];
|
|
497
|
-
console.log(`🔄 Processing user message ${i + 1}:`, {
|
|
498
|
-
id: userMsg.id,
|
|
499
|
-
message: userMsg.message.substring(0, 50),
|
|
500
|
-
sender: userMsg.sender,
|
|
501
|
-
isUserMessage: userMsg.isUserMessage,
|
|
502
|
-
author: userMsg.author
|
|
503
|
-
});
|
|
504
|
-
interleavedMessages.push(userMsg);
|
|
505
|
-
console.log(`🔄 Added user message ${i + 1}: ${userMsg.message.substring(0, 50)}...`);
|
|
506
|
-
// Check if this message is a duplicate of a previous one
|
|
507
|
-
const isDuplicate = i > 0 && regularMessagesFormatted.slice(0, i).some(prevMsg => prevMsg.message === userMsg.message);
|
|
508
|
-
if (isDuplicate) {
|
|
509
|
-
// Find the first occurrence of this message to get its AI response
|
|
510
|
-
const firstOccurrenceIndex = regularMessagesFormatted.findIndex(msg => msg.message === userMsg.message);
|
|
511
|
-
const hasAIResponseForFirst = firstOccurrenceIndex < aiMessagesFormatted.length;
|
|
512
|
-
if (hasAIResponseForFirst) {
|
|
513
|
-
// Reuse the AI response from the first occurrence
|
|
514
|
-
const aiResponse = aiMessagesFormatted[firstOccurrenceIndex];
|
|
515
|
-
const adjustedCreatedAt = new Date(userMsg.createdAt.getTime() + 1);
|
|
516
|
-
const finalAiResponse = {
|
|
517
|
-
...aiResponse,
|
|
518
|
-
createdAt: adjustedCreatedAt,
|
|
519
|
-
id: `duplicate-${aiResponse.id}-${i}`,
|
|
520
|
-
isDuplicate: true
|
|
521
|
-
};
|
|
522
|
-
interleavedMessages.push(finalAiResponse);
|
|
523
|
-
console.log(`🔄 Added duplicate AI response for message ${i + 1} (reusing from message ${firstOccurrenceIndex + 1}):`, {
|
|
524
|
-
id: finalAiResponse.id,
|
|
525
|
-
message: finalAiResponse.message.substring(0, 50),
|
|
526
|
-
sender: finalAiResponse.sender,
|
|
527
|
-
isUserMessage: finalAiResponse.isUserMessage,
|
|
528
|
-
isDuplicate: finalAiResponse.isDuplicate
|
|
529
|
-
});
|
|
530
|
-
} else {
|
|
531
|
-
// First occurrence doesn't have AI response yet, show loading
|
|
532
|
-
const loadingMessage = {
|
|
533
|
-
id: `loading-duplicate-${i}`,
|
|
534
|
-
message: 'Loading...',
|
|
535
|
-
// Shorter text since we show visual loader
|
|
536
|
-
createdAt: new Date(userMsg.createdAt.getTime() + 1),
|
|
537
|
-
sender: 'ai',
|
|
538
|
-
isLoading: true,
|
|
539
|
-
isProcessing: false,
|
|
540
|
-
isUserMessage: false,
|
|
541
|
-
isDuplicate: true
|
|
542
|
-
};
|
|
543
|
-
interleavedMessages.push(loadingMessage);
|
|
544
|
-
console.log(`🔄 Added loading indicator for duplicate message ${i + 1}:`, {
|
|
545
|
-
id: loadingMessage.id,
|
|
546
|
-
message: loadingMessage.message,
|
|
547
|
-
isDuplicate: loadingMessage.isDuplicate
|
|
548
|
-
});
|
|
549
|
-
}
|
|
550
|
-
} else {
|
|
551
|
-
// This is not a duplicate, handle normally
|
|
552
|
-
if (i < aiMessagesFormatted.length) {
|
|
553
|
-
const aiResponse = aiMessagesFormatted[i];
|
|
554
|
-
// Ensure AI response sorts after corresponding user message
|
|
555
|
-
const adjustedCreatedAt = new Date(userMsg.createdAt.getTime() + 1);
|
|
556
|
-
const finalAiResponse = {
|
|
557
|
-
...aiResponse,
|
|
558
|
-
createdAt: adjustedCreatedAt
|
|
559
|
-
};
|
|
560
|
-
interleavedMessages.push(finalAiResponse);
|
|
561
|
-
console.log(`🔄 Added AI response for message ${i + 1}:`, {
|
|
562
|
-
id: finalAiResponse.id,
|
|
563
|
-
message: finalAiResponse.message.substring(0, 50),
|
|
564
|
-
sender: finalAiResponse.sender,
|
|
565
|
-
isUserMessage: finalAiResponse.isUserMessage
|
|
566
|
-
});
|
|
567
|
-
} else {
|
|
568
|
-
// Add a loading indicator for messages waiting for AI responses
|
|
569
|
-
const loadingMessage = {
|
|
570
|
-
id: `loading-${i}`,
|
|
571
|
-
message: 'Loading...',
|
|
572
|
-
// Shorter text since we show visual loader
|
|
573
|
-
createdAt: new Date(userMsg.createdAt.getTime() + 1),
|
|
574
|
-
sender: 'ai',
|
|
575
|
-
isLoading: true,
|
|
576
|
-
isProcessing: currentProcessingMessage === i,
|
|
577
|
-
isUserMessage: false // Explicitly mark as not a user message
|
|
578
|
-
};
|
|
579
|
-
interleavedMessages.push(loadingMessage);
|
|
580
|
-
console.log(`🔄 Added loading indicator for message ${i + 1}:`, {
|
|
581
|
-
id: loadingMessage.id,
|
|
582
|
-
message: loadingMessage.message,
|
|
583
|
-
sender: loadingMessage.sender,
|
|
584
|
-
isUserMessage: loadingMessage.isUserMessage,
|
|
585
|
-
isProcessing: loadingMessage.isProcessing
|
|
586
|
-
});
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
console.log('🔄 Final interleaved messages:', interleavedMessages.length);
|
|
591
|
-
console.log('🔄 Message structure:', interleavedMessages.map(m => ({
|
|
592
|
-
sender: m.sender,
|
|
593
|
-
isUserMessage: m.isUserMessage,
|
|
594
|
-
message: m.message.substring(0, 30) + '...'
|
|
595
|
-
})));
|
|
596
|
-
return interleavedMessages;
|
|
597
|
-
}, [aiMessages, regularMessages, currentUser, currentProcessingMessage]);
|
|
598
|
-
// Update hasMoreMessages when allMessages changes
|
|
599
|
-
useEffect(() => {
|
|
600
|
-
if (allMessages && allMessages.length > 0) {
|
|
601
|
-
// Count complete conversation pairs instead of individual messages
|
|
602
|
-
const conversationPairs = Math.ceil(allMessages.length / 2);
|
|
603
|
-
console.log('🔄 Conversation pairs calculation:', {
|
|
604
|
-
totalMessages: allMessages.length,
|
|
605
|
-
conversationPairs,
|
|
606
|
-
displayedMessageCount,
|
|
607
|
-
hasMore: conversationPairs > displayedMessageCount
|
|
608
|
-
});
|
|
609
|
-
// Show "Load Past Messages" whenever there are more conversation pairs
|
|
610
|
-
// than currently displayed (including initial view)
|
|
611
|
-
const hasMore = conversationPairs > displayedMessageCount;
|
|
612
|
-
setHasMoreMessages(hasMore);
|
|
613
|
-
// Ensure we always show at least the last conversation
|
|
614
|
-
if (displayedMessageCount === 0) {
|
|
615
|
-
setDisplayedMessageCount(1);
|
|
616
|
-
}
|
|
617
|
-
} else {
|
|
618
|
-
setHasMoreMessages(false);
|
|
619
|
-
}
|
|
620
|
-
}, [allMessages, displayedMessageCount]);
|
|
621
|
-
// Function to load more past messages
|
|
622
|
-
const loadMoreMessages = useCallback(() => {
|
|
623
|
-
if (allMessages && allMessages.length > 0) {
|
|
624
|
-
// Load more conversation pairs (5 pairs = 10 messages)
|
|
625
|
-
const conversationPairs = Math.ceil(allMessages.length / 2);
|
|
626
|
-
setDisplayedMessageCount(prev => Math.min(prev + 5, conversationPairs));
|
|
627
|
-
}
|
|
628
|
-
}, [allMessages]);
|
|
629
|
-
// Function to reset to showing only last message
|
|
630
|
-
useCallback(() => {
|
|
631
|
-
setDisplayedMessageCount(1);
|
|
632
|
-
}, []);
|
|
448
|
+
return regularMessagesFormatted;
|
|
449
|
+
}, [regularMessages, currentUser]);
|
|
633
450
|
// Build list with date separators similar to MessagesBuilderUi
|
|
634
451
|
const messageListWithDates = useMemo(() => {
|
|
635
452
|
let currentDate = '';
|
|
@@ -683,57 +500,11 @@ const AIAgent = ({
|
|
|
683
500
|
}
|
|
684
501
|
return sections;
|
|
685
502
|
}, [messageListWithDates]);
|
|
686
|
-
//
|
|
503
|
+
// Show all messages without limiting
|
|
687
504
|
const limitedMessagesByDate = useMemo(() => {
|
|
688
505
|
if (!messagesByDate || messagesByDate.length === 0) return [];
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
const limitedSections = [];
|
|
692
|
-
// Start from the end (most recent messages) and work backwards
|
|
693
|
-
for (let i = messagesByDate.length - 1; i >= 0; i--) {
|
|
694
|
-
const section = messagesByDate[i];
|
|
695
|
-
const sectionMessages = [...section.messages];
|
|
696
|
-
// Count conversation pairs in this section
|
|
697
|
-
let sectionPairs = 0;
|
|
698
|
-
for (let j = 0; j < sectionMessages.length; j++) {
|
|
699
|
-
const currentMsg = sectionMessages[j];
|
|
700
|
-
if (currentMsg.sender === 'user' || currentMsg.isUserMessage) {
|
|
701
|
-
// Check if there's an AI response following this user message
|
|
702
|
-
if (j + 1 < sectionMessages.length) {
|
|
703
|
-
const nextMsg = sectionMessages[j + 1];
|
|
704
|
-
if (nextMsg.sender === 'ai' || !nextMsg.isUserMessage) {
|
|
705
|
-
sectionPairs++;
|
|
706
|
-
j++; // Skip the AI response since we counted it as a pair
|
|
707
|
-
}
|
|
708
|
-
} else {
|
|
709
|
-
sectionPairs++; // User message without AI response still counts
|
|
710
|
-
}
|
|
711
|
-
} else if (currentMsg.sender === 'ai' || !currentMsg.isUserMessage) {
|
|
712
|
-
// AI message without preceding user message counts as half a pair
|
|
713
|
-
sectionPairs += 0.5;
|
|
714
|
-
}
|
|
715
|
-
}
|
|
716
|
-
// If this section would exceed our limit, only take what we can fit
|
|
717
|
-
if (conversationPairs + sectionPairs > displayedMessageCount) {
|
|
718
|
-
const remainingPairs = displayedMessageCount - conversationPairs;
|
|
719
|
-
if (remainingPairs > 0) {
|
|
720
|
-
// Take only the last N conversation pairs from this section
|
|
721
|
-
const limitedMessages = sectionMessages.slice(-Math.floor(remainingPairs * 2));
|
|
722
|
-
limitedSections.unshift({
|
|
723
|
-
...section,
|
|
724
|
-
messages: limitedMessages
|
|
725
|
-
});
|
|
726
|
-
conversationPairs += remainingPairs;
|
|
727
|
-
}
|
|
728
|
-
break;
|
|
729
|
-
} else {
|
|
730
|
-
// We can fit this entire section
|
|
731
|
-
limitedSections.unshift(section);
|
|
732
|
-
conversationPairs += sectionPairs;
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
return limitedSections;
|
|
736
|
-
}, [messagesByDate, displayedMessageCount]);
|
|
506
|
+
return messagesByDate;
|
|
507
|
+
}, [messagesByDate]);
|
|
737
508
|
// Ensure we show complete conversation pairs (user message + AI response)
|
|
738
509
|
const completeConversationMessages = useMemo(() => {
|
|
739
510
|
if (!limitedMessagesByDate || limitedMessagesByDate.length === 0) return [];
|
|
@@ -788,14 +559,27 @@ const AIAgent = ({
|
|
|
788
559
|
}, [limitedMessagesByDate]);
|
|
789
560
|
// Auto scroll to bottom when messages, typing status, or AI responses change
|
|
790
561
|
useEffect(() => {
|
|
791
|
-
scrollToBottom('smooth', 100);
|
|
562
|
+
// scrollToBottom('smooth', 100);
|
|
792
563
|
}, [completeConversationMessages?.length, isTyping, aiMessages.length, scrollToBottom]);
|
|
793
|
-
//
|
|
564
|
+
// Cleanup any pending timeout on unmount
|
|
794
565
|
useEffect(() => {
|
|
795
|
-
|
|
796
|
-
|
|
566
|
+
return () => {
|
|
567
|
+
if (successThinkingTimeoutRef.current) {
|
|
568
|
+
clearTimeout(successThinkingTimeoutRef.current);
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
}, []);
|
|
572
|
+
const extractCleanContent = useCallback(summary => {
|
|
573
|
+
if (!summary) return 'Project generated successfully!';
|
|
574
|
+
// Extract content from <task_summary> tags
|
|
575
|
+
const taskSummaryMatch = summary.match(/<task_summary>([\s\S]*?)<\/task_summary>/);
|
|
576
|
+
if (taskSummaryMatch) {
|
|
577
|
+
return taskSummaryMatch[1].trim();
|
|
797
578
|
}
|
|
798
|
-
|
|
579
|
+
// If no task_summary tags, remove canvas_layers and return the rest
|
|
580
|
+
const withoutCanvasLayers = summary.replace(/<canvas_layers>[\s\S]*?<\/canvas_layers>/g, '').trim();
|
|
581
|
+
return withoutCanvasLayers || 'Project generated successfully!';
|
|
582
|
+
}, []);
|
|
799
583
|
return React__default.createElement("div", {
|
|
800
584
|
className: `flex flex-col h-full ${className}`
|
|
801
585
|
}, React__default.createElement("div", {
|
|
@@ -814,27 +598,7 @@ const AIAgent = ({
|
|
|
814
598
|
className: `relative ${activeTab === 'history' ? 'text-blue-600 font-medium' : 'text-gray-500 hover:text-gray-700'} text-sm transition-colors`
|
|
815
599
|
}, React__default.createElement("span", null, "History"), activeTab === 'history' && React__default.createElement("div", {
|
|
816
600
|
className: "absolute bottom-0 left-0 w-full h-0.5 bg-blue-600"
|
|
817
|
-
}))),
|
|
818
|
-
onClick: () => {
|
|
819
|
-
// Reset to show only the last message for new chat
|
|
820
|
-
setDisplayedMessageCount(1);
|
|
821
|
-
setHasMoreMessages(false);
|
|
822
|
-
// Clear processing state
|
|
823
|
-
setProcessedMessageIds(new Set());
|
|
824
|
-
setCurrentProcessingMessage(null);
|
|
825
|
-
// Clear AI messages by sending update event to the machine
|
|
826
|
-
send({
|
|
827
|
-
type: 'UPDATE',
|
|
828
|
-
value: {
|
|
829
|
-
messages: []
|
|
830
|
-
}
|
|
831
|
-
});
|
|
832
|
-
},
|
|
833
|
-
className: "px-4 py-2 text-sm text-gray-700 border border-gray-300 rounded-lg hover:bg-gray-200 transition-colors",
|
|
834
|
-
style: {
|
|
835
|
-
borderRadius: '10px'
|
|
836
|
-
}
|
|
837
|
-
}, "New Chat"))), activeTab === 'history' ? (/* History Tab Content */
|
|
601
|
+
}))))), activeTab === 'history' ? (/* History Tab Content */
|
|
838
602
|
React__default.createElement("div", {
|
|
839
603
|
className: "flex-1 overflow-y-auto bg-white"
|
|
840
604
|
}, React__default.createElement("div", {
|
|
@@ -873,7 +637,7 @@ const AIAgent = ({
|
|
|
873
637
|
d: "M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z"
|
|
874
638
|
})))))), React__default.createElement("div", {
|
|
875
639
|
className: "px-4 py-2"
|
|
876
|
-
}, regularMessages && regularMessages.length > 0 ? regularMessages.map((msg, index) => {
|
|
640
|
+
}, regularMessages && regularMessages.length > 0 ? regularMessages.filter(msg => msg?.propsConfiguration?.contents?.role === 'USER').map((msg, index) => {
|
|
877
641
|
new Date(msg.createdAt);
|
|
878
642
|
return React__default.createElement("div", {
|
|
879
643
|
key: msg.id || index,
|
|
@@ -895,7 +659,8 @@ const AIAgent = ({
|
|
|
895
659
|
})), "Restore to this point")), React__default.createElement(ModernMessageGroupComponent, {
|
|
896
660
|
messages: [{
|
|
897
661
|
id: msg.id,
|
|
898
|
-
message: msg.message || msg.content || 'No message content',
|
|
662
|
+
//message: msg.message || msg.content || 'No message content',
|
|
663
|
+
message: msg?.propsConfiguration?.contents?.role === 'ASSISTANT' ? msg.propsConfiguration?.contents?.fragment?.summary ? extractCleanContent(msg.propsConfiguration?.contents?.fragment?.summary) : msg.message : msg.message,
|
|
899
664
|
author: msg.author || {
|
|
900
665
|
id: 'user',
|
|
901
666
|
givenName: 'User',
|
|
@@ -914,16 +679,16 @@ const AIAgent = ({
|
|
|
914
679
|
parentId: null,
|
|
915
680
|
fromServer: null,
|
|
916
681
|
updatedAt: msg.createdAt,
|
|
917
|
-
propsConfiguration:
|
|
918
|
-
props:
|
|
919
|
-
files:
|
|
682
|
+
propsConfiguration: msg.propsConfiguration,
|
|
683
|
+
props: msg.props,
|
|
684
|
+
files: msg.files,
|
|
920
685
|
replies: null,
|
|
921
686
|
channel: null,
|
|
922
687
|
isPinned: false
|
|
923
688
|
}],
|
|
924
689
|
currentUser: currentUser,
|
|
925
690
|
onOpen: onOpen,
|
|
926
|
-
onMessageClick:
|
|
691
|
+
onMessageClick: msg => setSelectedPost(msg),
|
|
927
692
|
isDesktopView: isDesktopView,
|
|
928
693
|
isSmallScreen: isSmallScreen
|
|
929
694
|
}));
|
|
@@ -954,12 +719,7 @@ const AIAgent = ({
|
|
|
954
719
|
className: "flex-1 overflow-y-auto bg-white"
|
|
955
720
|
}, React__default.createElement("div", {
|
|
956
721
|
className: `w-full pb-4 pt-2 ${isDesktopView ? 'space-y-3 max-w-full mx-auto' : isSmallScreen ? 'space-y-2' : 'space-y-2'}`
|
|
957
|
-
},
|
|
958
|
-
className: "px-4 py-3 text-center"
|
|
959
|
-
}, React__default.createElement("button", {
|
|
960
|
-
onClick: loadMoreMessages,
|
|
961
|
-
className: "px-4 py-2 text-sm text-gray-600 bg-gray-100 border border-gray-300 rounded-lg hover:bg-gray-200 transition-colors"
|
|
962
|
-
}, "Load Past Messages")), (!completeConversationMessages || completeConversationMessages.length === 0) && React__default.createElement("div", {
|
|
722
|
+
}, (!completeConversationMessages || completeConversationMessages.length === 0) && React__default.createElement("div", {
|
|
963
723
|
className: "px-4 py-8 text-center"
|
|
964
724
|
}, React__default.createElement("div", {
|
|
965
725
|
className: "text-gray-500 text-lg font-medium mb-2"
|
|
@@ -1000,7 +760,8 @@ const AIAgent = ({
|
|
|
1000
760
|
React__default.createElement(ModernMessageGroupComponent, {
|
|
1001
761
|
messages: [{
|
|
1002
762
|
id: msg.id,
|
|
1003
|
-
message: msg.message,
|
|
763
|
+
// message: msg.message,
|
|
764
|
+
message: msg?.propsConfiguration?.contents?.role === 'ASSISTANT' ? msg.propsConfiguration?.contents?.fragment?.summary ? extractCleanContent(msg.propsConfiguration?.contents?.fragment?.summary) : msg.message : msg.message,
|
|
1004
765
|
author: msg.sender === 'user' ? msg.author : {
|
|
1005
766
|
id: 'ai-assistant',
|
|
1006
767
|
givenName: 'AI',
|
|
@@ -1019,19 +780,23 @@ const AIAgent = ({
|
|
|
1019
780
|
parentId: null,
|
|
1020
781
|
fromServer: null,
|
|
1021
782
|
updatedAt: msg.createdAt,
|
|
1022
|
-
propsConfiguration:
|
|
1023
|
-
props:
|
|
1024
|
-
files:
|
|
783
|
+
propsConfiguration: msg.propsConfiguration,
|
|
784
|
+
props: msg.props,
|
|
785
|
+
files: msg.files,
|
|
1025
786
|
replies: null,
|
|
1026
787
|
channel: null,
|
|
1027
788
|
isPinned: false
|
|
1028
789
|
}],
|
|
1029
790
|
currentUser: currentUser,
|
|
1030
791
|
onOpen: onOpen,
|
|
1031
|
-
onMessageClick:
|
|
792
|
+
onMessageClick: msg => setSelectedPost(msg),
|
|
1032
793
|
isDesktopView: isDesktopView,
|
|
1033
|
-
isSmallScreen: isSmallScreen
|
|
1034
|
-
|
|
794
|
+
isSmallScreen: isSmallScreen,
|
|
795
|
+
sandboxErrors: sandboxErrors,
|
|
796
|
+
currentFiles: currentFiles,
|
|
797
|
+
onFixError: fixError,
|
|
798
|
+
onRecreateSandbox: recreateSandboxForFragment
|
|
799
|
+
})))))), (isTyping || isSuccessThinking || isLoading) && React__default.createElement("div", {
|
|
1035
800
|
className: "px-4"
|
|
1036
801
|
}, React__default.createElement("div", {
|
|
1037
802
|
className: "flex justify-start"
|
|
@@ -1093,25 +858,7 @@ const AIAgent = ({
|
|
|
1093
858
|
className: "px-2 py-1 text-xs bg-gray-100 text-gray-700 rounded hover:bg-gray-200 transition-colors"
|
|
1094
859
|
}, "Dismiss")))), activeTab === 'chat' && React__default.createElement("div", {
|
|
1095
860
|
className: "border-t border-gray-200 bg-white"
|
|
1096
|
-
},
|
|
1097
|
-
className: "px-4 py-2 border-b border-blue-100 bg-blue-50"
|
|
1098
|
-
}, React__default.createElement("div", {
|
|
1099
|
-
className: "flex items-center space-x-2 text-sm text-blue-700"
|
|
1100
|
-
}, React__default.createElement("div", {
|
|
1101
|
-
className: "flex space-x-1"
|
|
1102
|
-
}, React__default.createElement("div", {
|
|
1103
|
-
className: "w-2 h-2 bg-blue-500 rounded-full animate-bounce"
|
|
1104
|
-
}), React__default.createElement("div", {
|
|
1105
|
-
className: "w-2 h-2 bg-blue-500 rounded-full animate-bounce",
|
|
1106
|
-
style: {
|
|
1107
|
-
animationDelay: '0.1s'
|
|
1108
|
-
}
|
|
1109
|
-
}), React__default.createElement("div", {
|
|
1110
|
-
className: "w-2 h-2 bg-blue-500 rounded-full animate-bounce",
|
|
1111
|
-
style: {
|
|
1112
|
-
animationDelay: '0.2s'
|
|
1113
|
-
}
|
|
1114
|
-
})), React__default.createElement("span", null, "AI is processing message ", currentProcessingMessage + 1, " of ", regularMessages.length))), React__default.createElement(InputComponent, {
|
|
861
|
+
}, React__default.createElement(InputComponent, {
|
|
1115
862
|
channelId: actualChannelId,
|
|
1116
863
|
handleSend: handleSend,
|
|
1117
864
|
placeholder: placeholder
|