@terryavg/neptune-ai-chatbot 1.0.2 → 1.0.3

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/dist/index.js CHANGED
@@ -61,23 +61,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
61
61
 
62
62
  // app/api/chat-client.ts
63
63
  function configureChatClient(config) {
64
- chatConfig.username = config.username;
65
- chatConfig.password = config.password;
66
- chatConfig.baseUrl = config.baseUrl;
67
- }
68
- function isJson(content) {
69
- if (typeof content === "object" && content !== null) {
70
- return Array.isArray(content) || Object.prototype.toString.call(content) === "[object Object]";
71
- }
72
- if (typeof content === "string") {
73
- try {
74
- const parsed = JSON.parse(content);
75
- return typeof parsed === "object" && parsed !== null;
76
- } catch (e) {
77
- return false;
78
- }
79
- }
80
- return false;
64
+ Object.assign(chatConfig, config);
81
65
  }
82
66
  async function fetchWithErrorHandling(url, options = {}) {
83
67
  const headers = new Headers(options.headers);
@@ -85,404 +69,256 @@ async function fetchWithErrorHandling(url, options = {}) {
85
69
  if (chatConfig.username && chatConfig.password) {
86
70
  headers.set(
87
71
  "Authorization",
88
- "Basic " + btoa(chatConfig.username + ":" + chatConfig.password)
72
+ "Basic " + btoa(`${chatConfig.username}:${chatConfig.password}`)
89
73
  );
90
74
  }
91
75
  const finalUrl = chatConfig.baseUrl ? `${chatConfig.baseUrl}${url}` : url;
92
- let response;
93
76
  try {
94
- response = await fetch(finalUrl, __spreadProps(__spreadValues({}, options), {
95
- headers
96
- }));
97
- } catch (networkError) {
98
- console.error("Network error:", networkError);
77
+ const res = await fetch(finalUrl, __spreadProps(__spreadValues({}, options), { headers }));
78
+ const contentType = res.headers.get("content-type");
79
+ const isJson = contentType == null ? void 0 : contentType.includes("application/json");
80
+ if (!res.ok) {
81
+ const err = isJson ? await res.json() : { message: await res.text() };
82
+ throw __spreadProps(__spreadValues({}, err), {
83
+ status: res.status,
84
+ statusText: res.statusText,
85
+ isApiError: true
86
+ });
87
+ }
88
+ if (res.status === 204 || !contentType) return { success: true };
89
+ return isJson ? res.json() : { success: true, nonJsonResponse: await res.text() };
90
+ } catch (error) {
91
+ if (error.isApiError) throw error;
99
92
  throw {
100
93
  isNetworkError: true,
101
- message: "Failed to connect to the server. Please check your network.",
102
- status: 0
94
+ message: "Network connection failed",
95
+ status: 0,
96
+ originalError: error
103
97
  };
104
98
  }
105
- if (!response.ok) {
106
- let errorBody = {
107
- message: `API request failed: ${response.status} ${response.statusText}`,
108
- statusText: response.statusText
109
- };
110
- try {
111
- const contentType2 = response.headers.get("content-type");
112
- if (contentType2 && contentType2.includes("application/json")) {
113
- const jsonError = await response.json();
114
- errorBody = __spreadProps(__spreadValues({}, jsonError), {
115
- // Include fields like status, message from API
116
- statusText: response.statusText
117
- // Keep original statusText
118
- });
119
- } else {
120
- const textError = await response.text();
121
- errorBody.message = textError || errorBody.message;
122
- }
123
- } catch (parseError) {
124
- console.error("Failed to parse error response body:", parseError);
125
- }
126
- throw __spreadProps(__spreadValues({}, errorBody), { status: response.status, isApiError: true });
127
- }
128
- const contentType = response.headers.get("content-type");
129
- if (!contentType || !contentType.includes("application/json")) {
130
- if (response.status === 204 || !contentType) {
131
- return { success: true };
132
- }
133
- const text = await response.text();
134
- if (!text.trim()) {
135
- return { success: true };
136
- }
137
- console.warn(
138
- `API returned non-JSON response for ${url}, status: ${response.status}`
139
- );
140
- return { success: true, nonJsonResponse: text };
141
- }
142
- return response.json();
143
99
  }
144
100
  async function createAgentStream(agentId, messages, conversationId, signal, stepData, streaming = true) {
145
- const lastMessage = messages[messages.length - 1];
101
+ var _a;
102
+ const lastMsg = messages[messages.length - 1];
146
103
  let input = "";
147
- if (lastMessage && lastMessage.content) {
148
- if (typeof lastMessage.content === "string") {
149
- input = lastMessage.content;
150
- } else if (Array.isArray(lastMessage.content)) {
151
- const textContent = lastMessage.content.find(
152
- (c) => c.type === "text"
153
- );
154
- if (textContent) {
155
- input = textContent.text;
156
- }
157
- }
158
- }
104
+ if (typeof (lastMsg == null ? void 0 : lastMsg.content) === "string") input = lastMsg.content;
105
+ else if (Array.isArray(lastMsg == null ? void 0 : lastMsg.content))
106
+ input = ((_a = lastMsg.content.find((c) => c.type === "text")) == null ? void 0 : _a.text) || "";
159
107
  const formData = new FormData();
160
108
  formData.append("aiAgent", agentId);
161
109
  formData.append("input", input);
162
- formData.append("stream", streaming ? "true" : "false");
163
- if (conversationId && conversationId.trim() !== "" && !conversationId.startsWith("temp-")) {
110
+ formData.append("stream", String(streaming));
111
+ if (conversationId && !conversationId.startsWith("temp-"))
164
112
  formData.append("threadID", conversationId);
165
- }
166
- if (stepData) {
167
- formData.append("variables", JSON.stringify(stepData));
168
- }
169
- if (lastMessage && Array.isArray(lastMessage.content)) {
170
- for (const content of lastMessage.content) {
171
- if (content.type === "image") {
172
- const imageContent = content;
173
- const base64Data = imageContent.image.includes(",") ? imageContent.image.split(",")[1] : imageContent.image;
174
- const byteCharacters = atob(base64Data);
175
- const byteNumbers = new Array(byteCharacters.length);
176
- for (let i = 0; i < byteCharacters.length; i++) {
177
- byteNumbers[i] = byteCharacters.charCodeAt(i);
178
- }
179
- const byteArray = new Uint8Array(byteNumbers);
180
- const blob = new Blob([byteArray], {
181
- type: imageContent.mediaType
182
- });
183
- const file = new File(
184
- [blob],
185
- `image.${imageContent.mediaType.split("/")[1]}`,
186
- {
187
- type: imageContent.mediaType
188
- }
113
+ if (stepData) formData.append("variables", JSON.stringify(stepData));
114
+ if (Array.isArray(lastMsg == null ? void 0 : lastMsg.content)) {
115
+ lastMsg.content.forEach((c) => {
116
+ if (c.type === "image")
117
+ formData.append(
118
+ "files",
119
+ base64ToFile(
120
+ c.image,
121
+ c.mediaType,
122
+ `image.${c.mediaType.split("/")[1]}`
123
+ )
189
124
  );
190
- formData.append("files", file);
191
- } else if (content.type === "file") {
192
- const fileContent = content;
193
- const base64Data = fileContent.data.includes(",") ? fileContent.data.split(",")[1] : fileContent.data;
194
- const byteCharacters = atob(base64Data);
195
- const byteNumbers = new Array(byteCharacters.length);
196
- for (let i = 0; i < byteCharacters.length; i++) {
197
- byteNumbers[i] = byteCharacters.charCodeAt(i);
198
- }
199
- const byteArray = new Uint8Array(byteNumbers);
200
- const blob = new Blob([byteArray], {
201
- type: fileContent.mediaType
202
- });
203
- const file = new File([blob], fileContent.filename, {
204
- type: fileContent.mediaType
205
- });
206
- formData.append("files", file);
207
- }
208
- }
125
+ else if (c.type === "file")
126
+ formData.append(
127
+ "files",
128
+ base64ToFile(c.data, c.mediaType, c.filename)
129
+ );
130
+ });
209
131
  }
210
132
  const url = chatConfig.baseUrl ? `${chatConfig.baseUrl}/api/AIBuildersKit/createCompletionAI` : "/api/AIBuildersKit/createCompletionAI";
211
- const headers = {};
212
- if (chatConfig.username && chatConfig.password) {
213
- headers["Authorization"] = "Basic " + btoa(chatConfig.username + ":" + chatConfig.password);
214
- }
133
+ const headers = chatConfig.username ? {
134
+ Authorization: "Basic " + btoa(`${chatConfig.username}:${chatConfig.password}`)
135
+ } : {};
215
136
  const response = await fetch(url, {
216
137
  method: "POST",
217
138
  headers,
218
139
  body: formData,
219
140
  signal
220
141
  });
221
- if (!response.ok) {
222
- let errorDetails = `API request failed: ${response.status} ${response.statusText}`;
223
- try {
224
- const errorData = await response.json();
225
- if (errorData && errorData.message) {
226
- errorDetails = errorData.message;
227
- }
228
- } catch (e) {
229
- }
230
- throw new Error(errorDetails);
231
- }
232
- if (!response.body) {
233
- throw new Error("Stream not supported by the response");
234
- }
142
+ if (!response.ok)
143
+ throw new Error(
144
+ (await response.json().catch(() => ({}))).message || response.statusText
145
+ );
146
+ if (!response.body) throw new Error("Stream not supported");
235
147
  return response.body;
236
148
  }
237
- var chatConfig, chatClient;
149
+ var chatConfig, base64ToFile, chatClient;
238
150
  var init_chat_client = __esm({
239
151
  "app/api/chat-client.ts"() {
240
152
  "use strict";
241
153
  chatConfig = {};
154
+ base64ToFile = (data, type, name) => {
155
+ const b64 = data.includes(",") ? data.split(",")[1] : data;
156
+ const bin = atob(b64);
157
+ const arr = new Uint8Array(bin.length).map((_, i) => bin.charCodeAt(i));
158
+ return new File([new Blob([arr], { type })], name, { type });
159
+ };
242
160
  chatClient = {
243
161
  conversations: {
244
162
  getAll: async (agentId) => {
245
- const response = await fetchWithErrorHandling(
163
+ const res = await fetchWithErrorHandling(
246
164
  "/api/functions/AIAgent/listUserThreads",
247
- {
248
- method: "POST",
249
- body: JSON.stringify({ agentId })
250
- }
165
+ { method: "POST", body: JSON.stringify({ agentId }) }
251
166
  );
252
- if (Array.isArray(response)) {
253
- return response;
254
- } else if (response && response.conversations && Array.isArray(response.conversations)) {
255
- return response.conversations;
256
- } else if (response && response.data && Array.isArray(response.data)) {
257
- return response.data;
258
- } else {
259
- console.error(
260
- "Unexpected response format from list-conversations:",
261
- response
262
- );
263
- return [];
264
- }
167
+ return Array.isArray(res) ? res : res.conversations || res.data || [];
265
168
  },
266
169
  get: async (id) => {
267
- const response = await fetchWithErrorHandling(
170
+ var _a, _b, _c;
171
+ const res = await fetchWithErrorHandling(
268
172
  `/api/functions/AIAgent/getConversation`,
269
- {
270
- method: "POST",
271
- body: JSON.stringify({ id })
272
- }
173
+ { method: "POST", body: JSON.stringify({ id }) }
273
174
  );
274
- if (Array.isArray(response)) {
275
- const logs = response;
276
- const messages = [];
277
- logs.forEach((log) => {
175
+ if (Array.isArray(res)) {
176
+ const messages = res.flatMap((log) => {
177
+ var _a2, _b2, _c2, _d;
278
178
  let userContent = log.input;
279
- if (log.files && log.files.length > 0) {
280
- const contentParts = [];
281
- if (log.input && log.input.trim()) {
282
- contentParts.push({
283
- type: "text",
284
- text: log.input
285
- });
286
- }
287
- log.files.forEach((file) => {
288
- if (file.mimeType.startsWith("image/")) {
289
- contentParts.push({
179
+ if ((_a2 = log.files) == null ? void 0 : _a2.length) {
180
+ userContent = [
181
+ ...((_b2 = log.input) == null ? void 0 : _b2.trim()) ? [
182
+ {
183
+ type: "text",
184
+ text: log.input
185
+ }
186
+ ] : [],
187
+ ...log.files.map(
188
+ (f) => f.mimeType.startsWith("image/") ? {
290
189
  type: "image",
291
- image: `data:${file.mimeType};base64,${file.data}`,
292
- mediaType: file.mimeType
293
- });
294
- } else {
295
- contentParts.push({
190
+ image: `data:${f.mimeType};base64,${f.data}`,
191
+ mediaType: f.mimeType
192
+ } : {
296
193
  type: "file",
297
- data: `data:${file.mimeType};base64,${file.data}`,
298
- mediaType: file.mimeType,
299
- filename: file.name
300
- });
301
- }
302
- });
303
- userContent = contentParts;
194
+ data: `data:${f.mimeType};base64,${f.data}`,
195
+ mediaType: f.mimeType,
196
+ filename: f.name
197
+ }
198
+ )
199
+ ];
304
200
  }
305
- messages.push({
306
- id: `${log.id}-user`,
307
- content: userContent,
308
- role: "user",
309
- createdAt: log.createdAt
310
- });
311
- const assistantMessage = {
201
+ const asstMsg = {
312
202
  id: `${log.id}-assistant`,
313
203
  content: log.output,
314
204
  role: "assistant",
315
205
  createdAt: log.updatedAt
316
206
  };
317
- if (log.steps && log.steps.length > 0 || log.vectors && log.vectors.length > 0 || log.feedbackPositive !== void 0) {
318
- assistantMessage.metadata = {
207
+ if (((_c2 = log.steps) == null ? void 0 : _c2.length) || ((_d = log.vectors) == null ? void 0 : _d.length) || log.feedbackPositive !== void 0) {
208
+ asstMsg.metadata = {
319
209
  logId: log.id,
320
210
  steps: log.steps,
321
211
  vectors: log.vectors,
322
212
  feedbackPositive: log.feedbackPositive
323
213
  };
324
214
  }
325
- messages.push(assistantMessage);
215
+ return [
216
+ {
217
+ id: `${log.id}-user`,
218
+ content: userContent,
219
+ role: "user",
220
+ createdAt: log.createdAt
221
+ },
222
+ asstMsg
223
+ ];
326
224
  });
327
- const conversation2 = {
225
+ return {
328
226
  id,
329
- title: logs.length > 0 ? logs[0].input.substring(0, 50) : "Conversation",
227
+ title: ((_a = res[0]) == null ? void 0 : _a.input.substring(0, 50)) || "Conversation",
330
228
  messages,
331
- createdAt: logs.length > 0 ? logs[0].createdAt : (/* @__PURE__ */ new Date()).toISOString(),
332
- updatedAt: logs.length > 0 ? logs[logs.length - 1].updatedAt : (/* @__PURE__ */ new Date()).toISOString()
229
+ createdAt: ((_b = res[0]) == null ? void 0 : _b.createdAt) || (/* @__PURE__ */ new Date()).toISOString(),
230
+ updatedAt: ((_c = res[res.length - 1]) == null ? void 0 : _c.updatedAt) || (/* @__PURE__ */ new Date()).toISOString()
333
231
  };
334
- return conversation2;
335
- }
336
- let conversation;
337
- if (response && response.id) {
338
- conversation = response;
339
- } else if (response && response.conversation) {
340
- conversation = response.conversation;
341
- } else if (response && response.data) {
342
- conversation = response.data;
343
- } else {
344
- throw new Error(
345
- "Unexpected response format from get-conversation"
346
- );
347
232
  }
348
- if (conversation.messages && Array.isArray(conversation.messages)) {
349
- conversation.messages = conversation.messages.map((message) => {
350
- if (message.role === "assistant" && typeof message.content === "string") {
351
- const content = message.content;
352
- if (isJson(content) && !content.includes("```json:")) {
353
- const jsonObj = typeof content === "string" ? JSON.parse(content) : content;
354
- return __spreadProps(__spreadValues({}, message), {
355
- content: `\`\`\`json:Response
233
+ const conv = res.conversation || res.data || res;
234
+ if (conv.messages) {
235
+ conv.messages = conv.messages.map((m) => {
236
+ if (m.role === "assistant" && typeof m.content === "string") {
237
+ try {
238
+ const parsed = JSON.parse(m.content);
239
+ if (typeof parsed === "object" && parsed !== null && !m.content.includes("```json:")) {
240
+ return __spreadProps(__spreadValues({}, m), {
241
+ content: `\`\`\`json:Response
356
242
  ${JSON.stringify(
357
- jsonObj,
358
- null,
359
- 2
360
- )}
243
+ parsed,
244
+ null,
245
+ 2
246
+ )}
361
247
  \`\`\``
362
- });
248
+ });
249
+ }
250
+ } catch (e) {
363
251
  }
364
252
  }
365
- return message;
253
+ return m;
366
254
  });
367
255
  }
368
- return conversation;
369
- },
370
- create: async (title, agentId) => {
371
- return fetchWithErrorHandling(
372
- `/api/functions/AIAgent/createThread`,
373
- {
374
- method: "POST",
375
- body: JSON.stringify(__spreadValues(__spreadValues({}, title ? { title } : {}), agentId ? { agentId } : {}))
376
- }
377
- );
256
+ return conv;
378
257
  },
379
- delete: async (id) => {
380
- return fetchWithErrorHandling(
381
- `/api/functions/AIAgent/deleteThreadByIdAndUser`,
382
- {
383
- method: "POST",
384
- body: JSON.stringify({ id })
385
- }
386
- );
387
- },
388
- update: async (id, data) => {
389
- return fetchWithErrorHandling(
390
- `/api/functions/AIAgent/renameThread`,
391
- {
392
- method: "POST",
393
- body: JSON.stringify({ id, title: data.title })
394
- }
395
- );
396
- }
258
+ create: (title, agentId) => fetchWithErrorHandling(`/api/functions/AIAgent/createThread`, {
259
+ method: "POST",
260
+ body: JSON.stringify(__spreadValues(__spreadValues({}, title && { title }), agentId && { agentId }))
261
+ }),
262
+ delete: (id) => fetchWithErrorHandling(
263
+ `/api/functions/AIAgent/deleteThreadByIdAndUser`,
264
+ { method: "POST", body: JSON.stringify({ id }) }
265
+ ),
266
+ update: (id, data) => fetchWithErrorHandling(`/api/functions/AIAgent/renameThread`, {
267
+ method: "POST",
268
+ body: JSON.stringify({ id, title: data.title })
269
+ })
397
270
  },
398
271
  messages: {
399
- getLastMessages: async (conversationId, limit = 100) => {
400
- const conversation = await chatClient.conversations.get(
401
- conversationId
402
- );
403
- return conversation.messages.slice(-limit);
404
- },
405
- sendMessage: async (agentId, conversationId, content, existingMessages, signal, debug, stepData, isTemporary, streaming = true) => {
406
- const idToUse = agentId;
407
- if (!idToUse || typeof idToUse !== "string" || idToUse.trim() === "") {
408
- const error = new Error(
409
- "Assistant or Agent ID is missing or invalid. Please provide a valid Assistant or Agent ID in the URL."
410
- );
411
- error.isConfigurationError = true;
412
- error.status = 400;
413
- throw error;
414
- }
415
- let actualConversationId = conversationId;
272
+ getLastMessages: async (conversationId, limit = 100) => (await chatClient.conversations.get(conversationId)).messages.slice(
273
+ -limit
274
+ ),
275
+ sendMessage: async (agentId, conversationId, content, existingMessages, signal, stepData, isTemporary, streaming = true) => {
276
+ var _a;
277
+ if (!agentId)
278
+ throw {
279
+ isConfigurationError: true,
280
+ status: 400,
281
+ message: "Assistant ID missing"
282
+ };
283
+ let actualId = conversationId;
284
+ let createdConv;
416
285
  if (isTemporary && agentId) {
417
- let title = "New Chat";
418
- if (typeof content === "string") {
419
- title = content.substring(0, 50);
420
- } else if (Array.isArray(content)) {
421
- const textContent = content.find(
422
- (c) => c.type === "text"
423
- );
424
- if (textContent) {
425
- title = textContent.text.substring(0, 50);
426
- }
427
- }
428
- try {
429
- const newConversation = await chatClient.conversations.create(title, agentId);
430
- actualConversationId = newConversation.id;
431
- } catch (error) {
432
- console.error("Failed to create conversation:", error);
433
- throw error;
434
- }
286
+ const titleText = typeof content === "string" ? content : ((_a = content.find(
287
+ (c) => c.type === "text"
288
+ )) == null ? void 0 : _a.text) || "";
289
+ createdConv = await chatClient.conversations.create(
290
+ titleText.substring(0, 50) || "New Chat",
291
+ agentId
292
+ );
293
+ actualId = createdConv.id;
435
294
  }
436
- const userMessage = {
437
- role: "user",
438
- content
295
+ const context = [
296
+ ...(existingMessages == null ? void 0 : existingMessages.map((m) => ({
297
+ role: m.role,
298
+ content: m.content
299
+ }))) || [],
300
+ { role: "user", content }
301
+ ].slice(-10);
302
+ return {
303
+ stream: await createAgentStream(
304
+ agentId,
305
+ context,
306
+ actualId,
307
+ signal,
308
+ stepData,
309
+ streaming
310
+ ),
311
+ threadId: actualId,
312
+ conversation: createdConv
439
313
  };
440
- let contextMessages = [];
441
- if (existingMessages && Array.isArray(existingMessages)) {
442
- const formattedMessages = existingMessages.map((msg) => ({
443
- role: msg.role,
444
- content: msg.content
445
- }));
446
- contextMessages = [...formattedMessages, userMessage];
447
- contextMessages = contextMessages.slice(-10);
448
- } else {
449
- contextMessages = [userMessage];
450
- }
451
- const stream = await createAgentStream(
452
- idToUse,
453
- contextMessages,
454
- actualConversationId,
455
- signal,
456
- stepData,
457
- streaming
458
- );
459
- return { stream, threadId: actualConversationId };
460
314
  }
461
315
  },
462
316
  feedback: {
463
- /**
464
- * Submit feedback for an AI response
465
- * @param logId - The ID of the log/message
466
- * @param feedbackPositive - true for like, false for dislike
467
- * @param aiAgent - The agent ID
468
- */
469
- submit: async (logId, feedbackPositive, aiAgent) => {
470
- const response = await fetchWithErrorHandling(
471
- "/api/AIBuildersKit/giveAgentFeedbackAI",
472
- {
473
- method: "POST",
474
- headers: {
475
- "Content-Type": "application/json"
476
- },
477
- body: JSON.stringify({
478
- id: logId,
479
- feedbackPositive,
480
- aiAgent
481
- })
482
- }
483
- );
484
- return response;
485
- }
317
+ submit: (id, feedbackPositive, aiAgent) => fetchWithErrorHandling("/api/AIBuildersKit/giveAgentFeedbackAI", {
318
+ method: "POST",
319
+ headers: { "Content-Type": "application/json" },
320
+ body: JSON.stringify({ id, feedbackPositive, aiAgent })
321
+ })
486
322
  }
487
323
  };
488
324
  }
@@ -496,7 +332,6 @@ __export(chat_input_exports, {
496
332
  function ChatInput({
497
333
  conversationId,
498
334
  agentId,
499
- debug = false,
500
335
  onAddUserMessage,
501
336
  onStreamStart,
502
337
  onStreamUpdate,
@@ -702,13 +537,12 @@ function ChatInput({
702
537
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
703
538
  });
704
539
  onStreamStart();
705
- const { stream, threadId } = await chatClient.messages.sendMessage(
540
+ const { stream, threadId, conversation } = await chatClient.messages.sendMessage(
706
541
  agentId,
707
542
  conversationId,
708
543
  finalMessageContent,
709
544
  messages,
710
545
  abortController.signal,
711
- debug,
712
546
  void 0,
713
547
  // stepData
714
548
  conversationId.startsWith("temp-"),
@@ -717,7 +551,7 @@ function ChatInput({
717
551
  // streaming mode
718
552
  );
719
553
  if (threadId && threadId !== conversationId && onThreadCreated) {
720
- onThreadCreated(conversationId, threadId);
554
+ onThreadCreated(conversationId, threadId, conversation);
721
555
  }
722
556
  if (!streaming) {
723
557
  const reader = stream.getReader();
@@ -733,9 +567,6 @@ function ChatInput({
733
567
  accumulatedResponse = outputText;
734
568
  onStreamUpdate(outputText);
735
569
  metadata = response;
736
- if (response.threadID && response.threadID !== conversationId && onThreadCreated) {
737
- onThreadCreated(conversationId, response.threadID);
738
- }
739
570
  } else {
740
571
  const reader = stream.getReader();
741
572
  const decoder = new TextDecoder();
@@ -847,9 +678,6 @@ function ChatInput({
847
678
  done = true;
848
679
  }
849
680
  }
850
- if ((metadata == null ? void 0 : metadata.threadID) && metadata.threadID !== conversationId && onThreadCreated) {
851
- onThreadCreated(conversationId, metadata.threadID);
852
- }
853
681
  }
854
682
  } catch (error) {
855
683
  console.error("Error during chat submission:", error);
@@ -1456,7 +1284,6 @@ var init_vector_results = __esm({
1456
1284
  VectorResultItem = (0, import_react4.memo)(
1457
1285
  ({ vector, theme, colors }) => {
1458
1286
  const [isExpanded, setIsExpanded] = (0, import_react4.useState)(false);
1459
- const isDark = theme === "dark";
1460
1287
  const similarityPercentage = (parseFloat(vector.similarity) * 100).toFixed(1);
1461
1288
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1462
1289
  "div",
@@ -3907,13 +3734,6 @@ function ChatMessage({
3907
3734
  toolName: message.executingToolName
3908
3735
  }
3909
3736
  ),
3910
- ((_a2 = message.metadata) == null ? void 0 : _a2.steps) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3911
- ToolExecutionWidget,
3912
- {
3913
- steps: message.metadata.steps,
3914
- theme
3915
- }
3916
- ),
3917
3737
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "markdown-content", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3918
3738
  StreamingMarkdown,
3919
3739
  {
@@ -3923,6 +3743,14 @@ function ChatMessage({
3923
3743
  cursorColor: streamingTextColor
3924
3744
  }
3925
3745
  ) }),
3746
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(StreamingIndicator, {}),
3747
+ ((_a2 = message.metadata) == null ? void 0 : _a2.steps) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3748
+ ToolExecutionWidget,
3749
+ {
3750
+ steps: message.metadata.steps,
3751
+ theme
3752
+ }
3753
+ ),
3926
3754
  ((_b2 = message.metadata) == null ? void 0 : _b2.vectors) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3927
3755
  VectorResults,
3928
3756
  {
@@ -3931,8 +3759,7 @@ function ChatMessage({
3931
3759
  vectorColor,
3932
3760
  vectorColorDark
3933
3761
  }
3934
- ),
3935
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(StreamingIndicator, {})
3762
+ )
3936
3763
  ] });
3937
3764
  } else if (Array.isArray(contentToRender)) {
3938
3765
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "space-y-3", children: [
@@ -3942,13 +3769,6 @@ function ChatMessage({
3942
3769
  toolName: message.executingToolName
3943
3770
  }
3944
3771
  ),
3945
- ((_c = message.metadata) == null ? void 0 : _c.steps) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3946
- ToolExecutionWidget,
3947
- {
3948
- steps: message.metadata.steps,
3949
- theme
3950
- }
3951
- ),
3952
3772
  contentToRender.map((part, i) => {
3953
3773
  if (part.type === "text") {
3954
3774
  const textContent = part.text;
@@ -4016,6 +3836,14 @@ function ChatMessage({
4016
3836
  }
4017
3837
  return null;
4018
3838
  }),
3839
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(StreamingIndicator, {}),
3840
+ ((_c = message.metadata) == null ? void 0 : _c.steps) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
3841
+ ToolExecutionWidget,
3842
+ {
3843
+ steps: message.metadata.steps,
3844
+ theme
3845
+ }
3846
+ ),
4019
3847
  ((_d = message.metadata) == null ? void 0 : _d.vectors) && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4020
3848
  VectorResults,
4021
3849
  {
@@ -4024,8 +3852,7 @@ function ChatMessage({
4024
3852
  vectorColor,
4025
3853
  vectorColorDark
4026
3854
  }
4027
- ),
4028
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(StreamingIndicator, {})
3855
+ )
4029
3856
  ] });
4030
3857
  }
4031
3858
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { children: "..." });
@@ -4041,6 +3868,7 @@ function ChatMessage({
4041
3868
  year: "numeric",
4042
3869
  hour: "numeric",
4043
3870
  minute: "numeric",
3871
+ second: "numeric",
4044
3872
  hour12: false
4045
3873
  }).format(new Date(date));
4046
3874
  } catch (error) {
@@ -4468,7 +4296,6 @@ init_chat_client();
4468
4296
  var import_react9 = require("react");
4469
4297
  var import_lucide_react7 = require("lucide-react");
4470
4298
  var import_framer_motion = require("framer-motion");
4471
- init_chat_client();
4472
4299
 
4473
4300
  // app/components/analytics-panel.tsx
4474
4301
  var import_react = require("react");
@@ -4476,8 +4303,7 @@ var import_lucide_react = require("lucide-react");
4476
4303
  var import_jsx_runtime = require("react/jsx-runtime");
4477
4304
  function AnalyticsPanel({
4478
4305
  name,
4479
- csvData,
4480
- theme
4306
+ csvData
4481
4307
  }) {
4482
4308
  const { headers, data } = (0, import_react.useMemo)(() => {
4483
4309
  var _a;
@@ -5685,10 +5511,7 @@ var SCROLL_BOTTOM_THRESHOLD = 50;
5685
5511
  function ChatContent({
5686
5512
  conversation,
5687
5513
  agentId,
5688
- debug = false,
5689
- onConversationUpdate,
5690
5514
  theme,
5691
- onAppStateChange,
5692
5515
  onSidebarToggle,
5693
5516
  isReadOnly = false,
5694
5517
  onThreadCreated,
@@ -5722,10 +5545,10 @@ function ChatContent({
5722
5545
  null
5723
5546
  );
5724
5547
  const streamingMessageRef = (0, import_react9.useRef)(null);
5548
+ const previousConversationIdRef = (0, import_react9.useRef)(conversation.id);
5725
5549
  const [errorDialog, setErrorDialog] = (0, import_react9.useState)(null);
5726
5550
  const [showScrollToBottomButton, setShowScrollToBottomButton] = (0, import_react9.useState)(false);
5727
5551
  const [userHasScrolledUp, setUserHasScrolledUp] = (0, import_react9.useState)(false);
5728
- const [openApp, setOpenApp] = (0, import_react9.useState)(null);
5729
5552
  const [openAnalytic, setOpenAnalytic] = (0, import_react9.useState)(null);
5730
5553
  const [chatWidth, setChatWidth] = (0, import_react9.useState)(30);
5731
5554
  const [isResizingChatApp, setIsResizingChatApp] = (0, import_react9.useState)(false);
@@ -5734,7 +5557,7 @@ function ChatContent({
5734
5557
  const minChatWidth = 20;
5735
5558
  const maxChatWidth = 80;
5736
5559
  const hasMessages = messages.length > 0 || !!streamingMessage;
5737
- const hasOpenPanel = !!openApp || !!openAnalytic;
5560
+ const hasOpenPanel = !!openAnalytic;
5738
5561
  const isWaitingForInput = (0, import_react9.useMemo)(() => {
5739
5562
  return conversation.waiting === true || messages.some((message) => message.waiting === true);
5740
5563
  }, [conversation.waiting, messages]);
@@ -5818,16 +5641,61 @@ function ChatContent({
5818
5641
  return () => clearTimeout(timeoutId);
5819
5642
  }, [conversation.id, scrollToBottom]);
5820
5643
  (0, import_react9.useEffect)(() => {
5821
- setMessages(conversation.messages || []);
5822
- }, [conversation.id, conversation.messages]);
5823
- (0, import_react9.useEffect)(() => {
5824
- if (openApp) {
5825
- setOpenApp(null);
5644
+ const conversationMessages = conversation.messages || [];
5645
+ const previousId = previousConversationIdRef.current;
5646
+ const currentId = conversation.id;
5647
+ const isTempToRealTransition = (previousId == null ? void 0 : previousId.startsWith("temp-")) && !currentId.startsWith("temp-") && isStreaming;
5648
+ if (previousId !== currentId && !isTempToRealTransition) {
5649
+ setMessages(conversationMessages);
5650
+ previousConversationIdRef.current = currentId;
5651
+ return;
5826
5652
  }
5653
+ if (isTempToRealTransition) {
5654
+ previousConversationIdRef.current = currentId;
5655
+ }
5656
+ if (isStreaming && !isTempToRealTransition) {
5657
+ return;
5658
+ }
5659
+ if (conversationMessages.length > 0 || isTempToRealTransition) {
5660
+ setMessages((prevMessages) => {
5661
+ if (prevMessages.length === 0) {
5662
+ return conversationMessages;
5663
+ }
5664
+ const filteredLocalMessages = prevMessages.filter((localMsg) => {
5665
+ if (localMsg.role === "assistant") {
5666
+ return true;
5667
+ }
5668
+ const localTime = new Date(localMsg.createdAt).getTime();
5669
+ const isLocalMessage = localMsg.id.startsWith("local-");
5670
+ if (isLocalMessage) {
5671
+ const hasBackendVersion = conversationMessages.some((backendMsg) => {
5672
+ const backendTime = new Date(backendMsg.createdAt).getTime();
5673
+ const timeDiff = Math.abs(backendTime - localTime);
5674
+ return backendMsg.role === localMsg.role && timeDiff < 5e3;
5675
+ });
5676
+ return !hasBackendVersion;
5677
+ }
5678
+ return true;
5679
+ });
5680
+ const combined = [...filteredLocalMessages, ...conversationMessages];
5681
+ const seen = /* @__PURE__ */ new Set();
5682
+ const deduplicated = combined.filter((msg) => {
5683
+ if (seen.has(msg.id)) {
5684
+ return false;
5685
+ }
5686
+ seen.add(msg.id);
5687
+ return true;
5688
+ });
5689
+ return deduplicated.sort((a, b) => {
5690
+ return new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime();
5691
+ });
5692
+ });
5693
+ }
5694
+ }, [conversation.id, conversation.messages, isStreaming]);
5695
+ (0, import_react9.useEffect)(() => {
5827
5696
  if (openAnalytic) {
5828
5697
  setOpenAnalytic(null);
5829
5698
  }
5830
- onAppStateChange == null ? void 0 : onAppStateChange(false);
5831
5699
  }, [conversation.id]);
5832
5700
  (0, import_react9.useEffect)(() => {
5833
5701
  if (messages.length > 0 && !userHasScrolledUp) {
@@ -5962,16 +5830,26 @@ function ChatContent({
5962
5830
  }), metadata && {
5963
5831
  metadata: {
5964
5832
  logId: metadata.logId,
5965
- steps: metadata.steps
5833
+ steps: metadata.steps,
5834
+ vectors: metadata.vectors
5966
5835
  }
5967
5836
  });
5968
5837
  }
5969
5838
  if (messageToAdd) {
5970
5839
  setMessages((prev) => [...prev, messageToAdd]);
5840
+ streamingMessageRef.current = {
5841
+ id: messageToAdd.id,
5842
+ role: messageToAdd.role,
5843
+ createdAt: messageToAdd.createdAt
5844
+ };
5845
+ setTimeout(() => {
5846
+ streamingMessageRef.current = null;
5847
+ }, 1e3);
5848
+ } else {
5849
+ streamingMessageRef.current = null;
5971
5850
  }
5972
5851
  setIsStreaming(false);
5973
5852
  setStreamingMessage(null);
5974
- streamingMessageRef.current = null;
5975
5853
  },
5976
5854
  []
5977
5855
  );
@@ -5987,186 +5865,16 @@ function ChatContent({
5987
5865
  setStreamingMessage(null);
5988
5866
  streamingMessageRef.current = null;
5989
5867
  }, []);
5990
- const handleAppOpen = (0, import_react9.useCallback)(
5991
- (name, url) => {
5992
- setOpenAnalytic(null);
5993
- setOpenApp({ name, url });
5994
- onAppStateChange == null ? void 0 : onAppStateChange(true);
5995
- },
5996
- [onAppStateChange]
5997
- );
5998
5868
  const handleAnalyticOpen = (0, import_react9.useCallback)(
5999
5869
  (name, data) => {
6000
- setOpenApp(null);
6001
5870
  setOpenAnalytic({ name, data });
6002
- onAppStateChange == null ? void 0 : onAppStateChange(true);
6003
5871
  onSidebarToggle == null ? void 0 : onSidebarToggle();
6004
5872
  },
6005
- [onAppStateChange, onSidebarToggle]
5873
+ [onSidebarToggle]
6006
5874
  );
6007
5875
  const handlePanelClose = (0, import_react9.useCallback)(() => {
6008
- setOpenApp(null);
6009
5876
  setOpenAnalytic(null);
6010
- onAppStateChange == null ? void 0 : onAppStateChange(false);
6011
- }, [onAppStateChange]);
6012
- const handleWidgetSubmit = (0, import_react9.useCallback)(
6013
- async (data, actionId, messageId, widgetId) => {
6014
- try {
6015
- setMessages(
6016
- (prev) => prev.map(
6017
- (message) => message.id === messageId ? __spreadProps(__spreadValues({}, message), { waiting: false }) : message
6018
- )
6019
- );
6020
- if (conversation.waiting === true) {
6021
- }
6022
- const stepData = {
6023
- action: actionId,
6024
- data,
6025
- id: widgetId,
6026
- // Use the actual widget ID passed from the form
6027
- messageId
6028
- // Backend will use this to update message.waiting = false
6029
- };
6030
- if (agentId) {
6031
- handleStreamStart();
6032
- const { stream } = await chatClient.messages.sendMessage(
6033
- agentId,
6034
- conversation.id,
6035
- "",
6036
- //`Processing form submission...`, // Simple processing message
6037
- messages,
6038
- new AbortController().signal,
6039
- debug,
6040
- stepData,
6041
- conversation.isTemporary
6042
- // Pass isTemporary flag
6043
- );
6044
- const reader = stream.getReader();
6045
- const decoder = new TextDecoder();
6046
- let done = false;
6047
- let accumulatedResponse = "";
6048
- while (!done) {
6049
- const { value, done: readerDone } = await reader.read();
6050
- done = readerDone;
6051
- if (value) {
6052
- const chunk = decoder.decode(value, {
6053
- stream: !done
6054
- });
6055
- if (chunk) {
6056
- accumulatedResponse += chunk;
6057
- handleStreamUpdate(chunk);
6058
- }
6059
- }
6060
- }
6061
- handleStreamEnd(accumulatedResponse);
6062
- if (onConversationUpdate) {
6063
- try {
6064
- await onConversationUpdate();
6065
- } catch (error) {
6066
- console.error(
6067
- "Failed to refresh conversation after form submission:",
6068
- error
6069
- );
6070
- }
6071
- }
6072
- }
6073
- } catch (error) {
6074
- console.error("Error submitting form:", error);
6075
- handleError({
6076
- title: "Form Submission Error",
6077
- message: "Failed to submit form data. Please try again."
6078
- });
6079
- }
6080
- },
6081
- [
6082
- agentId,
6083
- conversation.id,
6084
- messages,
6085
- debug,
6086
- handleStreamStart,
6087
- handleStreamUpdate,
6088
- handleStreamEnd,
6089
- handleError
6090
- ]
6091
- );
6092
- const handleWidgetCancel = (0, import_react9.useCallback)(
6093
- async (messageId, widgetId) => {
6094
- try {
6095
- setMessages(
6096
- (prev) => prev.map(
6097
- (message) => message.id === messageId ? __spreadProps(__spreadValues({}, message), { waiting: false }) : message
6098
- )
6099
- );
6100
- const stepData = {
6101
- action: "cancel",
6102
- data: null,
6103
- // No form data for cancellation
6104
- id: widgetId,
6105
- messageId
6106
- };
6107
- if (agentId) {
6108
- handleStreamStart();
6109
- const { stream } = await chatClient.messages.sendMessage(
6110
- agentId,
6111
- conversation.id,
6112
- "",
6113
- //cancelMessage.content,
6114
- messages,
6115
- new AbortController().signal,
6116
- debug,
6117
- stepData,
6118
- conversation.isTemporary
6119
- // Pass isTemporary flag
6120
- );
6121
- const reader = stream.getReader();
6122
- const decoder = new TextDecoder();
6123
- let done = false;
6124
- let accumulatedResponse = "";
6125
- while (!done) {
6126
- const { value, done: readerDone } = await reader.read();
6127
- done = readerDone;
6128
- if (value) {
6129
- const chunk = decoder.decode(value, {
6130
- stream: !done
6131
- });
6132
- if (chunk) {
6133
- accumulatedResponse += chunk;
6134
- handleStreamUpdate(chunk);
6135
- }
6136
- }
6137
- }
6138
- handleStreamEnd(accumulatedResponse);
6139
- if (onConversationUpdate) {
6140
- try {
6141
- await onConversationUpdate();
6142
- } catch (error) {
6143
- console.error(
6144
- "Failed to refresh conversation after form cancellation:",
6145
- error
6146
- );
6147
- }
6148
- }
6149
- }
6150
- } catch (error) {
6151
- console.error("Error cancelling form:", error);
6152
- handleError({
6153
- title: "Form Cancellation Error",
6154
- message: "Failed to cancel form. Please try again."
6155
- });
6156
- }
6157
- },
6158
- [
6159
- agentId,
6160
- conversation.id,
6161
- messages,
6162
- debug,
6163
- handleStreamStart,
6164
- handleStreamUpdate,
6165
- handleStreamEnd,
6166
- handleError,
6167
- onConversationUpdate
6168
- ]
6169
- );
5877
+ }, []);
6170
5878
  const startResizingChatApp = (0, import_react9.useCallback)(
6171
5879
  (e) => {
6172
5880
  e.preventDefault();
@@ -6325,7 +6033,6 @@ function ChatContent({
6325
6033
  {
6326
6034
  conversationId: conversation.id,
6327
6035
  agentId,
6328
- debug,
6329
6036
  onAddUserMessage: handleAddUserMessage,
6330
6037
  onStreamStart: handleStreamStart,
6331
6038
  onStreamUpdate: handleStreamUpdate,
@@ -6370,15 +6077,17 @@ function ChatContent({
6370
6077
  className: "space-y-2",
6371
6078
  children: [
6372
6079
  allMessages.map((message, index) => {
6080
+ var _a;
6373
6081
  const isCurrentlyStreaming = isStreaming && (streamingMessage == null ? void 0 : streamingMessage.id) === message.id;
6082
+ const wasJustStreamed = ((_a = streamingMessageRef.current) == null ? void 0 : _a.id) === message.id;
6374
6083
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
6375
6084
  import_framer_motion.motion.div,
6376
6085
  {
6377
- initial: { opacity: 0, x: -20 },
6086
+ initial: { opacity: wasJustStreamed ? 1 : 0, x: wasJustStreamed ? 0 : -20 },
6378
6087
  animate: { opacity: 1, x: 0 },
6379
6088
  transition: {
6380
- duration: isCurrentlyStreaming ? 0 : 0.3,
6381
- delay: isCurrentlyStreaming ? 0 : index * 0.05,
6089
+ duration: isCurrentlyStreaming || wasJustStreamed ? 0 : 0.3,
6090
+ delay: isCurrentlyStreaming || wasJustStreamed ? 0 : index * 0.05,
6382
6091
  ease: "easeOut"
6383
6092
  },
6384
6093
  children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
@@ -6483,7 +6192,6 @@ function ChatContent({
6483
6192
  {
6484
6193
  conversationId: conversation.id,
6485
6194
  agentId,
6486
- debug,
6487
6195
  onAddUserMessage: handleAddUserMessage,
6488
6196
  onStreamStart: handleStreamStart,
6489
6197
  onStreamUpdate: handleStreamUpdate,
@@ -6535,8 +6243,8 @@ function ChatContent({
6535
6243
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
6536
6244
  "div",
6537
6245
  {
6538
- className: `w-8 h-8 rounded-lg flex items-center justify-center ${openApp ? "bg-blue-500" : "bg-emerald-500"}`,
6539
- children: openApp ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
6246
+ className: `w-8 h-8 rounded-lg flex items-center justify-center ${false ? "bg-blue-500" : "bg-emerald-500"}`,
6247
+ children: false ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
6540
6248
  "svg",
6541
6249
  {
6542
6250
  className: "w-5 h-5 text-white",
@@ -6576,7 +6284,7 @@ function ChatContent({
6576
6284
  }
6577
6285
  ),
6578
6286
  /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
6579
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { className: "font-semibold text-gray-800 dark:text-gray-200", children: openApp ? openApp.name : "Analytics Dashboard" }),
6287
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { className: "font-semibold text-gray-800 dark:text-gray-200", children: false ? "openApp" : "Analytics Dashboard" }),
6580
6288
  openAnalytic && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: openAnalytic.name })
6581
6289
  ] })
6582
6290
  ] }),
@@ -6598,12 +6306,10 @@ function ChatContent({
6598
6306
  ] }),
6599
6307
  /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex-1 relative h-full", children: [
6600
6308
  isResizingChatApp && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "absolute inset-0 z-50 bg-transparent cursor-col-resize" }),
6601
- openApp ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
6309
+ false ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
6602
6310
  "iframe",
6603
6311
  {
6604
- src: openApp.url,
6605
6312
  className: "w-full h-full border-0",
6606
- title: openApp.name,
6607
6313
  allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",
6608
6314
  sandbox: "allow-scripts allow-same-origin allow-forms allow-popups allow-top-navigation-by-user-activation"
6609
6315
  }
@@ -6685,7 +6391,6 @@ var import_jsx_runtime10 = require("react/jsx-runtime");
6685
6391
  var useIsomorphicLayoutEffect = typeof window !== "undefined" ? import_react11.useLayoutEffect : import_react11.useEffect;
6686
6392
  function NeptuneChatBot({
6687
6393
  agentId: propAgentId,
6688
- debug: propDebug = false,
6689
6394
  theme: propTheme = "light",
6690
6395
  localDebug: propLocalDebug,
6691
6396
  title: propTitle = "Naia",
@@ -6731,14 +6436,12 @@ function NeptuneChatBot({
6731
6436
  const [conversationToRename, setConversationToRename] = (0, import_react11.useState)(null);
6732
6437
  const [theme, setTheme] = (0, import_react11.useState)(propTheme);
6733
6438
  const [agentId] = (0, import_react11.useState)(propAgentId);
6734
- const [debug] = (0, import_react11.useState)(propDebug);
6735
6439
  const [initialAssistantIdChecked] = (0, import_react11.useState)(true);
6736
6440
  const [initialLoadComplete, setInitialLoadComplete] = (0, import_react11.useState)(false);
6737
6441
  const [openMenuId, setOpenMenuId] = (0, import_react11.useState)(null);
6738
6442
  const [isCreatingConversation, setIsCreatingConversation] = (0, import_react11.useState)(false);
6739
6443
  const [sidebarWidth, setSidebarWidth] = (0, import_react11.useState)(250);
6740
6444
  const [isResizing, setIsResizing] = (0, import_react11.useState)(false);
6741
- const [hasOpenApp, setHasOpenApp] = (0, import_react11.useState)(false);
6742
6445
  const titleInputRef = (0, import_react11.useRef)(null);
6743
6446
  const resizeHandleRef = (0, import_react11.useRef)(null);
6744
6447
  const hasFetchedRef = (0, import_react11.useRef)(false);
@@ -6760,9 +6463,6 @@ function NeptuneChatBot({
6760
6463
  (0, import_react11.useEffect)(() => {
6761
6464
  applyTheme(theme);
6762
6465
  }, [theme, applyTheme]);
6763
- const handleAppStateChange = (0, import_react11.useCallback)((hasApp) => {
6764
- setHasOpenApp(hasApp);
6765
- }, []);
6766
6466
  const toggleTheme = () => {
6767
6467
  const newTheme = theme === "dark" ? "light" : "dark";
6768
6468
  setTheme(newTheme);
@@ -6867,17 +6567,15 @@ function NeptuneChatBot({
6867
6567
  return;
6868
6568
  }
6869
6569
  setConversations(data);
6870
- if (data.length > 0) {
6871
- const tempConversation = {
6872
- id: `temp-${Date.now()}`,
6873
- title: "New Chat",
6874
- messages: [],
6875
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
6876
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
6877
- isTemporary: true
6878
- };
6879
- setSelectedConversation(tempConversation);
6880
- }
6570
+ const tempConversation = {
6571
+ id: `temp-${Date.now()}`,
6572
+ title: "New Chat",
6573
+ messages: [],
6574
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
6575
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
6576
+ isTemporary: true
6577
+ };
6578
+ setSelectedConversation(tempConversation);
6881
6579
  } catch (error) {
6882
6580
  console.error("Failed to fetch conversations:", error);
6883
6581
  } finally {
@@ -6930,7 +6628,6 @@ function NeptuneChatBot({
6930
6628
  } else {
6931
6629
  loadConversationData(id);
6932
6630
  }
6933
- setHasOpenApp(false);
6934
6631
  }, []);
6935
6632
  const createNewConversation = async () => {
6936
6633
  try {
@@ -6952,39 +6649,49 @@ function NeptuneChatBot({
6952
6649
  };
6953
6650
  setSelectedConversationId(tempConversation.id);
6954
6651
  setSelectedConversation(tempConversation);
6955
- setHasOpenApp(false);
6956
6652
  } catch (error) {
6957
6653
  console.error("Failed to create new conversation:", error);
6958
6654
  }
6959
6655
  };
6960
6656
  const handleThreadCreated = (0, import_react11.useCallback)(
6961
- async (oldId, newId) => {
6962
- try {
6963
- const updatedConv = await chatClient.conversations.get(newId);
6964
- (0, import_react11.startTransition)(() => {
6657
+ async (oldId, newId, backendConversation) => {
6658
+ (0, import_react11.startTransition)(() => {
6659
+ if (backendConversation) {
6660
+ const updatedConv = __spreadProps(__spreadValues({}, backendConversation), {
6661
+ isTemporary: false
6662
+ });
6965
6663
  setConversations((prev) => {
6966
- const existingIndex = prev.findIndex(
6967
- (conv) => conv.id === oldId || conv.id === newId
6968
- );
6969
- if (existingIndex !== -1) {
6970
- const updated = [...prev];
6971
- updated[existingIndex] = __spreadProps(__spreadValues({}, updatedConv), {
6664
+ const filtered = prev.filter((conv) => conv.id !== oldId);
6665
+ return [updatedConv, ...filtered];
6666
+ });
6667
+ setSelectedConversationId(newId);
6668
+ setSelectedConversation(updatedConv);
6669
+ } else {
6670
+ setSelectedConversation((currentSelected) => {
6671
+ if (currentSelected && currentSelected.id === oldId) {
6672
+ const updatedConv = __spreadProps(__spreadValues({}, currentSelected), {
6673
+ id: newId,
6972
6674
  isTemporary: false
6973
6675
  });
6974
- return updated;
6975
- } else {
6976
- return [
6977
- __spreadProps(__spreadValues({}, updatedConv), { isTemporary: false }),
6978
- ...prev
6979
- ];
6676
+ setConversations((prev) => {
6677
+ const existingIndex = prev.findIndex(
6678
+ (conv) => conv.id === oldId || conv.id === newId
6679
+ );
6680
+ if (existingIndex !== -1) {
6681
+ const updated = [...prev];
6682
+ updated[existingIndex] = updatedConv;
6683
+ return updated;
6684
+ } else {
6685
+ return [updatedConv, ...prev];
6686
+ }
6687
+ });
6688
+ setSelectedConversationId(newId);
6689
+ return updatedConv;
6980
6690
  }
6691
+ return currentSelected;
6981
6692
  });
6982
- setSelectedConversationId(newId);
6983
- setSelectedConversation(updatedConv);
6984
- });
6985
- } catch (error) {
6986
- console.error("Failed to fetch updated conversation:", error);
6987
- }
6693
+ }
6694
+ });
6988
6695
  },
6989
6696
  []
6990
6697
  );
@@ -7405,11 +7112,11 @@ function NeptuneChatBot({
7405
7112
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
7406
7113
  "div",
7407
7114
  {
7408
- className: `flex-1 overflow-hidden bg-white dark:bg-gray-900 text-lg transition-all duration-300 ${hasOpenApp ? "flex" : "flex justify-center"}`,
7115
+ className: `flex-1 overflow-hidden bg-white dark:bg-gray-900 text-lg transition-all duration-300 ${false ? "flex" : "flex justify-center"}`,
7409
7116
  children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
7410
7117
  "div",
7411
7118
  {
7412
- className: `flex flex-col transition-all duration-300 ${hasOpenApp ? "w-full" : "w-full max-w-6xl"}`,
7119
+ className: `flex flex-col transition-all duration-300 ${false ? "w-full" : "w-full max-w-6xl"}`,
7413
7120
  children: isLoading || !initialAssistantIdChecked ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "animate-pulse text-gray-500", children: isLoading ? "Loading conversations..." : "Initializing Assistant..." }) }) : !agentId ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex h-full flex-col items-center justify-center p-4 text-center", children: [
7414
7121
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h2", { className: "text-xl font-semibold text-red-600 dark:text-red-400 mb-2", children: "Agent Not Configured" }),
7415
7122
  /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { className: "text-gray-700 dark:text-gray-300 max-w-md", children: [
@@ -7424,10 +7131,8 @@ function NeptuneChatBot({
7424
7131
  {
7425
7132
  conversation: selectedConversation,
7426
7133
  agentId,
7427
- debug,
7428
7134
  onConversationUpdate: refreshSelectedConversation,
7429
7135
  theme,
7430
- onAppStateChange: handleAppStateChange,
7431
7136
  onSidebarToggle: () => setSidebarOpen(false),
7432
7137
  onThreadCreated: handleThreadCreated,
7433
7138
  messageBubbleColor: theme === "dark" ? messageBubbleColorDark : messageBubbleColor,