@optifye/dashboard-core 4.0.2 → 4.1.1
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.d.mts +124 -1
- package/dist/index.d.ts +124 -1
- package/dist/index.js +1309 -400
- package/dist/index.mjs +1300 -401
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@ var dateFns = require('date-fns');
|
|
|
7
7
|
var dateFnsTz = require('date-fns-tz');
|
|
8
8
|
var supabaseJs = require('@supabase/supabase-js');
|
|
9
9
|
var mixpanel = require('mixpanel-browser');
|
|
10
|
+
var useSWR = require('swr');
|
|
10
11
|
var Hls2 = require('hls.js');
|
|
11
12
|
var motionUtils = require('motion-utils');
|
|
12
13
|
var motionDom = require('motion-dom');
|
|
@@ -19,7 +20,6 @@ var jsPDF = require('jspdf');
|
|
|
19
20
|
var clientS3 = require('@aws-sdk/client-s3');
|
|
20
21
|
var outline = require('@heroicons/react/24/outline');
|
|
21
22
|
var SelectPrimitive = require('@radix-ui/react-select');
|
|
22
|
-
var useSWR = require('swr');
|
|
23
23
|
var sonner = require('sonner');
|
|
24
24
|
var s3RequestPresigner = require('@aws-sdk/s3-request-presigner');
|
|
25
25
|
var stream = require('stream');
|
|
@@ -46,11 +46,11 @@ function _interopNamespace(e) {
|
|
|
46
46
|
|
|
47
47
|
var React46__namespace = /*#__PURE__*/_interopNamespace(React46);
|
|
48
48
|
var mixpanel__default = /*#__PURE__*/_interopDefault(mixpanel);
|
|
49
|
+
var useSWR__default = /*#__PURE__*/_interopDefault(useSWR);
|
|
49
50
|
var Hls2__default = /*#__PURE__*/_interopDefault(Hls2);
|
|
50
51
|
var html2canvas__default = /*#__PURE__*/_interopDefault(html2canvas);
|
|
51
52
|
var jsPDF__default = /*#__PURE__*/_interopDefault(jsPDF);
|
|
52
53
|
var SelectPrimitive__namespace = /*#__PURE__*/_interopNamespace(SelectPrimitive);
|
|
53
|
-
var useSWR__default = /*#__PURE__*/_interopDefault(useSWR);
|
|
54
54
|
|
|
55
55
|
var __create = Object.create;
|
|
56
56
|
var __defProp = Object.defineProperty;
|
|
@@ -5641,7 +5641,9 @@ var DEFAULT_DATE_TIME_CONFIG = {
|
|
|
5641
5641
|
}
|
|
5642
5642
|
};
|
|
5643
5643
|
var DEFAULT_ENDPOINTS_CONFIG = {
|
|
5644
|
-
whatsapp: "/api/send-whatsapp-direct"
|
|
5644
|
+
whatsapp: "/api/send-whatsapp-direct",
|
|
5645
|
+
agnoApiUrl: process.env.NEXT_PUBLIC_AGNO_URL || "https://optifye-agent-production.up.railway.app"
|
|
5646
|
+
// Default AGNO API URL
|
|
5645
5647
|
};
|
|
5646
5648
|
var DEFAULT_THEME_CONFIG = {
|
|
5647
5649
|
// Sensible defaults for theme can be added here
|
|
@@ -8235,6 +8237,210 @@ var resetCoreMixpanel = () => {
|
|
|
8235
8237
|
mixpanel__default.default.reset();
|
|
8236
8238
|
};
|
|
8237
8239
|
|
|
8240
|
+
// src/lib/services/sseClient.ts
|
|
8241
|
+
var SSEChatClient = class {
|
|
8242
|
+
constructor(baseUrl) {
|
|
8243
|
+
this.controllers = /* @__PURE__ */ new Map();
|
|
8244
|
+
this.baseUrl = baseUrl || "";
|
|
8245
|
+
}
|
|
8246
|
+
async sendMessage(message, userId, threadId, context, callbacks) {
|
|
8247
|
+
const connectionId = `${threadId || "new"}-${Date.now()}`;
|
|
8248
|
+
if (threadId) {
|
|
8249
|
+
for (const [id3, controller2] of this.controllers.entries()) {
|
|
8250
|
+
if (id3.startsWith(threadId)) {
|
|
8251
|
+
controller2.abort();
|
|
8252
|
+
this.controllers.delete(id3);
|
|
8253
|
+
}
|
|
8254
|
+
}
|
|
8255
|
+
}
|
|
8256
|
+
const controller = new AbortController();
|
|
8257
|
+
this.controllers.set(connectionId, controller);
|
|
8258
|
+
console.log("[SSEClient] Sending message:", {
|
|
8259
|
+
message,
|
|
8260
|
+
thread_id: threadId,
|
|
8261
|
+
user_id: userId,
|
|
8262
|
+
context
|
|
8263
|
+
});
|
|
8264
|
+
const agnoApiUrl = this.baseUrl || "https://optifye-agent-production.up.railway.app";
|
|
8265
|
+
const endpoint = `${agnoApiUrl}/api/chat`;
|
|
8266
|
+
console.log("[SSEClient] Posting directly to AGNO:", endpoint);
|
|
8267
|
+
const response = await fetch(endpoint, {
|
|
8268
|
+
method: "POST",
|
|
8269
|
+
headers: {
|
|
8270
|
+
"Content-Type": "application/json",
|
|
8271
|
+
"Accept": "text/event-stream"
|
|
8272
|
+
},
|
|
8273
|
+
body: JSON.stringify({
|
|
8274
|
+
message,
|
|
8275
|
+
thread_id: threadId,
|
|
8276
|
+
user_id: userId,
|
|
8277
|
+
company_id: context.companyId,
|
|
8278
|
+
line_id: context.lineId,
|
|
8279
|
+
shift_id: context.shiftId
|
|
8280
|
+
}),
|
|
8281
|
+
signal: controller.signal,
|
|
8282
|
+
// Don't include credentials since the API returns Access-Control-Allow-Origin: *
|
|
8283
|
+
// credentials: 'include', // Include cookies for CORS
|
|
8284
|
+
mode: "cors"
|
|
8285
|
+
// Explicitly set CORS mode
|
|
8286
|
+
});
|
|
8287
|
+
console.log("[SSEClient] Response status:", response.status);
|
|
8288
|
+
console.log("[SSEClient] Response headers:", Object.fromEntries(response.headers.entries()));
|
|
8289
|
+
if (!response.ok) {
|
|
8290
|
+
let errorMessage = `Chat request failed with status ${response.status}`;
|
|
8291
|
+
try {
|
|
8292
|
+
const error = await response.json();
|
|
8293
|
+
errorMessage = error.detail || error.message || errorMessage;
|
|
8294
|
+
} catch (e) {
|
|
8295
|
+
try {
|
|
8296
|
+
const text = await response.text();
|
|
8297
|
+
if (text) errorMessage = text;
|
|
8298
|
+
} catch (textError) {
|
|
8299
|
+
}
|
|
8300
|
+
}
|
|
8301
|
+
console.error("[SSEClient] Error response:", errorMessage);
|
|
8302
|
+
throw new Error(errorMessage);
|
|
8303
|
+
}
|
|
8304
|
+
const contentType = response.headers.get("content-type");
|
|
8305
|
+
if (!contentType?.includes("text/event-stream")) {
|
|
8306
|
+
console.warn("[SSEClient] Unexpected content-type:", contentType);
|
|
8307
|
+
}
|
|
8308
|
+
try {
|
|
8309
|
+
await this.handleSSEStream(response, callbacks);
|
|
8310
|
+
} finally {
|
|
8311
|
+
this.controllers.delete(connectionId);
|
|
8312
|
+
}
|
|
8313
|
+
}
|
|
8314
|
+
async handleSSEStream(response, callbacks) {
|
|
8315
|
+
if (!response.body) {
|
|
8316
|
+
console.error("[SSEClient] Response body is null");
|
|
8317
|
+
throw new Error("No response body available for streaming");
|
|
8318
|
+
}
|
|
8319
|
+
const reader = response.body.getReader();
|
|
8320
|
+
const decoder = new TextDecoder();
|
|
8321
|
+
let buffer = "";
|
|
8322
|
+
try {
|
|
8323
|
+
console.log("[SSEClient] Starting to read stream...");
|
|
8324
|
+
while (true) {
|
|
8325
|
+
const { done, value } = await reader.read();
|
|
8326
|
+
if (done) {
|
|
8327
|
+
console.log("[SSEClient] Stream ended");
|
|
8328
|
+
break;
|
|
8329
|
+
}
|
|
8330
|
+
buffer += decoder.decode(value, { stream: true });
|
|
8331
|
+
const lines = buffer.split("\n");
|
|
8332
|
+
buffer = lines.pop() || "";
|
|
8333
|
+
for (let i = 0; i < lines.length; i++) {
|
|
8334
|
+
const line = lines[i].trim();
|
|
8335
|
+
if (!line) continue;
|
|
8336
|
+
console.log("[SSEClient] Processing line:", line);
|
|
8337
|
+
if (line.startsWith("event:")) {
|
|
8338
|
+
const event = line.slice(6).trim();
|
|
8339
|
+
console.log("[SSEClient] Event type:", event);
|
|
8340
|
+
const nextLine = lines[i + 1];
|
|
8341
|
+
if (nextLine?.startsWith("data:")) {
|
|
8342
|
+
const dataStr = nextLine.slice(5).trim();
|
|
8343
|
+
console.log("[SSEClient] Event data:", dataStr);
|
|
8344
|
+
try {
|
|
8345
|
+
const data = JSON.parse(dataStr);
|
|
8346
|
+
switch (event) {
|
|
8347
|
+
case "thread":
|
|
8348
|
+
callbacks.onThreadCreated?.(data.thread_id);
|
|
8349
|
+
break;
|
|
8350
|
+
case "message":
|
|
8351
|
+
callbacks.onMessage?.(data.text);
|
|
8352
|
+
break;
|
|
8353
|
+
case "reasoning":
|
|
8354
|
+
callbacks.onReasoning?.(data.text);
|
|
8355
|
+
break;
|
|
8356
|
+
case "complete":
|
|
8357
|
+
callbacks.onComplete?.(data.message_id);
|
|
8358
|
+
break;
|
|
8359
|
+
case "error":
|
|
8360
|
+
callbacks.onError?.(data.error);
|
|
8361
|
+
break;
|
|
8362
|
+
}
|
|
8363
|
+
} catch (e) {
|
|
8364
|
+
console.error("[SSEClient] Failed to parse data:", dataStr, e);
|
|
8365
|
+
}
|
|
8366
|
+
i++;
|
|
8367
|
+
}
|
|
8368
|
+
}
|
|
8369
|
+
}
|
|
8370
|
+
}
|
|
8371
|
+
} finally {
|
|
8372
|
+
reader.releaseLock();
|
|
8373
|
+
}
|
|
8374
|
+
}
|
|
8375
|
+
abort(threadId) {
|
|
8376
|
+
if (threadId) {
|
|
8377
|
+
for (const [id3, controller] of this.controllers.entries()) {
|
|
8378
|
+
if (id3.startsWith(threadId)) {
|
|
8379
|
+
controller.abort();
|
|
8380
|
+
this.controllers.delete(id3);
|
|
8381
|
+
}
|
|
8382
|
+
}
|
|
8383
|
+
} else {
|
|
8384
|
+
for (const [id3, controller] of this.controllers.entries()) {
|
|
8385
|
+
controller.abort();
|
|
8386
|
+
}
|
|
8387
|
+
this.controllers.clear();
|
|
8388
|
+
}
|
|
8389
|
+
}
|
|
8390
|
+
};
|
|
8391
|
+
|
|
8392
|
+
// src/lib/services/chatService.ts
|
|
8393
|
+
async function getUserThreads(userId, limit = 20) {
|
|
8394
|
+
const supabase = _getSupabaseInstance();
|
|
8395
|
+
const { data, error } = await supabase.schema("ai").from("chat_threads").select("*").eq("user_id", userId).order("updated_at", { ascending: false }).limit(limit);
|
|
8396
|
+
if (error) throw error;
|
|
8397
|
+
return data;
|
|
8398
|
+
}
|
|
8399
|
+
async function getUserThreadsPaginated(userId, page = 1, pageSize = 20) {
|
|
8400
|
+
const supabase = _getSupabaseInstance();
|
|
8401
|
+
const from = (page - 1) * pageSize;
|
|
8402
|
+
const to = from + pageSize - 1;
|
|
8403
|
+
const { data, error, count } = await supabase.schema("ai").from("chat_threads").select("*", { count: "exact" }).eq("user_id", userId).order("updated_at", { ascending: false }).range(from, to);
|
|
8404
|
+
if (error) throw error;
|
|
8405
|
+
return {
|
|
8406
|
+
threads: data,
|
|
8407
|
+
totalCount: count || 0,
|
|
8408
|
+
totalPages: Math.ceil((count || 0) / pageSize),
|
|
8409
|
+
currentPage: page
|
|
8410
|
+
};
|
|
8411
|
+
}
|
|
8412
|
+
async function getThreadMessages(threadId, limit = 50, beforePosition) {
|
|
8413
|
+
const supabase = _getSupabaseInstance();
|
|
8414
|
+
let query = supabase.schema("ai").from("chat_messages").select("*").eq("thread_id", threadId).order("position", { ascending: true });
|
|
8415
|
+
if (beforePosition !== void 0) {
|
|
8416
|
+
query = query.lt("position", beforePosition);
|
|
8417
|
+
}
|
|
8418
|
+
const { data, error } = await query.limit(limit);
|
|
8419
|
+
if (error) throw error;
|
|
8420
|
+
return data;
|
|
8421
|
+
}
|
|
8422
|
+
async function getAllThreadMessages(threadId) {
|
|
8423
|
+
const supabase = _getSupabaseInstance();
|
|
8424
|
+
const { data, error } = await supabase.schema("ai").from("chat_messages").select("*").eq("thread_id", threadId).order("position", { ascending: true });
|
|
8425
|
+
if (error) throw error;
|
|
8426
|
+
return data;
|
|
8427
|
+
}
|
|
8428
|
+
async function updateThreadTitle(threadId, newTitle) {
|
|
8429
|
+
const supabase = _getSupabaseInstance();
|
|
8430
|
+
const { data, error } = await supabase.schema("ai").from("chat_threads").update({
|
|
8431
|
+
title: newTitle,
|
|
8432
|
+
auto_title: false,
|
|
8433
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
8434
|
+
}).eq("id", threadId).select().single();
|
|
8435
|
+
if (error) throw error;
|
|
8436
|
+
return data;
|
|
8437
|
+
}
|
|
8438
|
+
async function deleteThread(threadId) {
|
|
8439
|
+
const supabase = _getSupabaseInstance();
|
|
8440
|
+
const { error } = await supabase.schema("ai").from("chat_threads").delete().eq("id", threadId);
|
|
8441
|
+
if (error) throw error;
|
|
8442
|
+
}
|
|
8443
|
+
|
|
8238
8444
|
// src/lib/hooks/useLineDetailedMetrics.ts
|
|
8239
8445
|
var useLineDetailedMetrics = (lineIdFromProp) => {
|
|
8240
8446
|
const entityConfig = useEntityConfig();
|
|
@@ -9355,6 +9561,122 @@ var useWorkspaceOperators = (workspaceId, options) => {
|
|
|
9355
9561
|
refetch: fetchData
|
|
9356
9562
|
};
|
|
9357
9563
|
};
|
|
9564
|
+
function useThreads() {
|
|
9565
|
+
const supabase = _getSupabaseInstance();
|
|
9566
|
+
const fetcher = async (key) => {
|
|
9567
|
+
const { data: { session } } = await supabase.auth.getSession();
|
|
9568
|
+
if (!session) {
|
|
9569
|
+
console.log("[useThreads] No session found");
|
|
9570
|
+
return [];
|
|
9571
|
+
}
|
|
9572
|
+
const user = session.user;
|
|
9573
|
+
if (!user) {
|
|
9574
|
+
console.log("[useThreads] No user in session");
|
|
9575
|
+
return [];
|
|
9576
|
+
}
|
|
9577
|
+
console.log("[useThreads] Fetching threads for user:", user.id);
|
|
9578
|
+
try {
|
|
9579
|
+
const { data, error: error2 } = await supabase.schema("ai").from("chat_threads").select("*").eq("user_id", user.id).order("updated_at", { ascending: false });
|
|
9580
|
+
if (error2) {
|
|
9581
|
+
console.error("[useThreads] Error fetching threads:", error2);
|
|
9582
|
+
throw error2;
|
|
9583
|
+
}
|
|
9584
|
+
console.log("[useThreads] Fetched threads:", data?.length || 0);
|
|
9585
|
+
return data || [];
|
|
9586
|
+
} catch (err) {
|
|
9587
|
+
console.error("[useThreads] Unexpected error:", err);
|
|
9588
|
+
throw err;
|
|
9589
|
+
}
|
|
9590
|
+
};
|
|
9591
|
+
const { data: threads = [], error, isLoading, mutate } = useSWR__default.default("chat_threads", fetcher, {
|
|
9592
|
+
revalidateOnFocus: false,
|
|
9593
|
+
revalidateOnReconnect: true
|
|
9594
|
+
});
|
|
9595
|
+
const createThread = React46.useCallback(async (title) => {
|
|
9596
|
+
const { data: { session } } = await supabase.auth.getSession();
|
|
9597
|
+
if (!session?.user) throw new Error("Not authenticated");
|
|
9598
|
+
const user = session.user;
|
|
9599
|
+
console.log("[useThreads] Creating thread for user:", user.id);
|
|
9600
|
+
const { data, error: error2 } = await supabase.schema("ai").from("chat_threads").insert([{
|
|
9601
|
+
user_id: user.id,
|
|
9602
|
+
title: title || `Chat ${(/* @__PURE__ */ new Date()).toLocaleDateString()}`,
|
|
9603
|
+
auto_title: !title,
|
|
9604
|
+
model_id: "gpt-4o-mini",
|
|
9605
|
+
has_reasoning: false,
|
|
9606
|
+
last_message: null,
|
|
9607
|
+
message_count: 0
|
|
9608
|
+
}]).select().single();
|
|
9609
|
+
if (error2) {
|
|
9610
|
+
console.error("[useThreads] Error creating thread:", error2);
|
|
9611
|
+
throw error2;
|
|
9612
|
+
}
|
|
9613
|
+
console.log("[useThreads] Created thread:", data?.id);
|
|
9614
|
+
mutate([data, ...threads], false);
|
|
9615
|
+
return data;
|
|
9616
|
+
}, [supabase, threads, mutate]);
|
|
9617
|
+
const deleteThread2 = React46.useCallback(async (threadId) => {
|
|
9618
|
+
const { error: error2 } = await supabase.schema("ai").from("chat_threads").delete().eq("id", threadId);
|
|
9619
|
+
if (error2) throw error2;
|
|
9620
|
+
mutate(threads.filter((t) => t.id !== threadId), false);
|
|
9621
|
+
}, [supabase, threads, mutate]);
|
|
9622
|
+
return {
|
|
9623
|
+
threads,
|
|
9624
|
+
isLoading,
|
|
9625
|
+
error,
|
|
9626
|
+
mutate,
|
|
9627
|
+
createThread,
|
|
9628
|
+
deleteThread: deleteThread2
|
|
9629
|
+
};
|
|
9630
|
+
}
|
|
9631
|
+
function useMessages(threadId) {
|
|
9632
|
+
const supabase = _getSupabaseInstance();
|
|
9633
|
+
const [messages, setMessages] = React46.useState([]);
|
|
9634
|
+
const [isLoading, setIsLoading] = React46.useState(true);
|
|
9635
|
+
const [error, setError] = React46.useState(null);
|
|
9636
|
+
React46.useEffect(() => {
|
|
9637
|
+
if (!threadId) {
|
|
9638
|
+
setMessages([]);
|
|
9639
|
+
setIsLoading(false);
|
|
9640
|
+
return;
|
|
9641
|
+
}
|
|
9642
|
+
const loadMessages = async () => {
|
|
9643
|
+
setIsLoading(true);
|
|
9644
|
+
setError(null);
|
|
9645
|
+
try {
|
|
9646
|
+
const { data, error: fetchError } = await supabase.schema("ai").from("chat_messages").select("*").eq("thread_id", threadId).order("position", { ascending: true });
|
|
9647
|
+
if (fetchError) throw fetchError;
|
|
9648
|
+
setMessages(data);
|
|
9649
|
+
} catch (err) {
|
|
9650
|
+
setError(err);
|
|
9651
|
+
console.error("Error loading messages:", err);
|
|
9652
|
+
} finally {
|
|
9653
|
+
setIsLoading(false);
|
|
9654
|
+
}
|
|
9655
|
+
};
|
|
9656
|
+
loadMessages();
|
|
9657
|
+
}, [threadId, supabase]);
|
|
9658
|
+
const addMessage = React46.useCallback(async (message) => {
|
|
9659
|
+
const maxPosition = messages.reduce((max, msg) => Math.max(max, msg.position), -1);
|
|
9660
|
+
const { data, error: insertError } = await supabase.schema("ai").from("chat_messages").insert([{
|
|
9661
|
+
...message,
|
|
9662
|
+
position: maxPosition + 1
|
|
9663
|
+
}]).select().single();
|
|
9664
|
+
if (insertError) throw insertError;
|
|
9665
|
+
return data;
|
|
9666
|
+
}, [supabase, messages]);
|
|
9667
|
+
const updateMessage = React46.useCallback(async (id3, content) => {
|
|
9668
|
+
const { error: updateError } = await supabase.schema("ai").from("chat_messages").update({ content }).eq("id", id3);
|
|
9669
|
+
if (updateError) throw updateError;
|
|
9670
|
+
}, [supabase]);
|
|
9671
|
+
return {
|
|
9672
|
+
messages,
|
|
9673
|
+
setMessages,
|
|
9674
|
+
isLoading,
|
|
9675
|
+
error,
|
|
9676
|
+
addMessage,
|
|
9677
|
+
updateMessage
|
|
9678
|
+
};
|
|
9679
|
+
}
|
|
9358
9680
|
var DEFAULT_FACTORY_OVERVIEW_TABLE_NAME = "factory_daily_summary";
|
|
9359
9681
|
var useFactoryOverviewMetrics = (options) => {
|
|
9360
9682
|
const { companyId, factoryId: entityFactoryId } = useEntityConfig();
|
|
@@ -13066,6 +13388,15 @@ var createSupabaseClient = (url, key) => supabaseJs.createClient(url, key, {
|
|
|
13066
13388
|
persistSession: true,
|
|
13067
13389
|
detectSessionInUrl: true,
|
|
13068
13390
|
flowType: "pkce"
|
|
13391
|
+
},
|
|
13392
|
+
db: {
|
|
13393
|
+
schema: "public"
|
|
13394
|
+
// Default schema, we'll use .schema('ai') in queries
|
|
13395
|
+
},
|
|
13396
|
+
global: {
|
|
13397
|
+
headers: {
|
|
13398
|
+
"x-application-name": "optifye-dashboard"
|
|
13399
|
+
}
|
|
13069
13400
|
}
|
|
13070
13401
|
});
|
|
13071
13402
|
var getAnonClient = () => {
|
|
@@ -21682,6 +22013,22 @@ var HourlyOutputChart = ({
|
|
|
21682
22013
|
// Keep original data for labels
|
|
21683
22014
|
color: (animatedData[i] || 0) >= Math.round(pphThreshold) ? "#00AB45" : "#E34329"
|
|
21684
22015
|
}));
|
|
22016
|
+
const maxYValue = Math.ceil(pphThreshold * 1.5);
|
|
22017
|
+
const generateYAxisTicks = () => {
|
|
22018
|
+
const targetValue = Math.round(pphThreshold);
|
|
22019
|
+
const ticks = [0];
|
|
22020
|
+
if (targetValue > 0) {
|
|
22021
|
+
ticks.push(targetValue);
|
|
22022
|
+
}
|
|
22023
|
+
const step = Math.ceil((maxYValue - targetValue) / 2);
|
|
22024
|
+
if (step > 5) {
|
|
22025
|
+
for (let i = targetValue + step; i < maxYValue; i += step) {
|
|
22026
|
+
ticks.push(i);
|
|
22027
|
+
}
|
|
22028
|
+
}
|
|
22029
|
+
ticks.push(maxYValue);
|
|
22030
|
+
return [...new Set(ticks)].sort((a, b) => a - b);
|
|
22031
|
+
};
|
|
21685
22032
|
const renderLegend = () => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center text-sm text-gray-600 absolute -bottom-1 left-0 right-0 bg-white py-1", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 border border-gray-100 rounded-full px-3 py-1", children: [
|
|
21686
22033
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-8 flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full border-t-2 border-[#E34329] border-dashed" }) }),
|
|
21687
22034
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
@@ -21721,7 +22068,8 @@ var HourlyOutputChart = ({
|
|
|
21721
22068
|
{
|
|
21722
22069
|
tickMargin: 8,
|
|
21723
22070
|
width: 35,
|
|
21724
|
-
|
|
22071
|
+
domain: [0, maxYValue],
|
|
22072
|
+
ticks: generateYAxisTicks(),
|
|
21725
22073
|
tickFormatter: (value) => value,
|
|
21726
22074
|
tick: (props) => {
|
|
21727
22075
|
const { x, y, payload } = props;
|
|
@@ -27774,9 +28122,9 @@ var SideNavBar = React46.memo(({
|
|
|
27774
28122
|
}
|
|
27775
28123
|
)
|
|
27776
28124
|
] }),
|
|
27777
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-auto", children: [
|
|
27778
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-10 h-px bg-gray-200 my-
|
|
27779
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "
|
|
28125
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-auto mb-2", children: [
|
|
28126
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-10 h-px bg-gray-200 my-3" }),
|
|
28127
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
27780
28128
|
"button",
|
|
27781
28129
|
{
|
|
27782
28130
|
onClick: handleProfileClick,
|
|
@@ -28315,146 +28663,127 @@ var SingleVideoStream = ({
|
|
|
28315
28663
|
);
|
|
28316
28664
|
};
|
|
28317
28665
|
var SingleVideoStream_default = SingleVideoStream;
|
|
28318
|
-
|
|
28319
|
-
|
|
28320
|
-
|
|
28321
|
-
|
|
28322
|
-
|
|
28323
|
-
|
|
28324
|
-
}
|
|
28325
|
-
|
|
28326
|
-
|
|
28327
|
-
|
|
28328
|
-
|
|
28329
|
-
|
|
28330
|
-
const requestData = {
|
|
28331
|
-
prompt: userQuestion,
|
|
28332
|
-
line_id: lineId,
|
|
28333
|
-
shift_id: shiftId,
|
|
28334
|
-
company_id: companyId
|
|
28335
|
-
};
|
|
28336
|
-
if (context) {
|
|
28337
|
-
requestData.context = context;
|
|
28338
|
-
}
|
|
28339
|
-
console.log("[OptifyeAgent] Sending request:", requestData);
|
|
28340
|
-
const response = await fetch(`${this.apiUrl}/api/custom-analysis`, {
|
|
28341
|
-
method: "POST",
|
|
28342
|
-
headers: {
|
|
28343
|
-
"Content-Type": "application/json"
|
|
28344
|
-
},
|
|
28345
|
-
body: JSON.stringify(requestData),
|
|
28346
|
-
signal: AbortSignal.timeout(6e4)
|
|
28347
|
-
// 60 second timeout
|
|
28348
|
-
});
|
|
28349
|
-
const responseText = await response.text();
|
|
28350
|
-
console.log("[OptifyeAgent] Response status:", response.status);
|
|
28351
|
-
console.log("[OptifyeAgent] Response text:", responseText);
|
|
28352
|
-
let result;
|
|
28666
|
+
var ThreadSidebar = ({
|
|
28667
|
+
activeThreadId,
|
|
28668
|
+
onSelectThread,
|
|
28669
|
+
onNewThread,
|
|
28670
|
+
className = ""
|
|
28671
|
+
}) => {
|
|
28672
|
+
const { threads, isLoading, error, deleteThread: deleteThread2 } = useThreads();
|
|
28673
|
+
const [deletingId, setDeletingId] = React46.useState(null);
|
|
28674
|
+
const handleDelete = async (e, threadId) => {
|
|
28675
|
+
e.stopPropagation();
|
|
28676
|
+
if (confirm("Are you sure you want to delete this conversation?")) {
|
|
28677
|
+
setDeletingId(threadId);
|
|
28353
28678
|
try {
|
|
28354
|
-
|
|
28355
|
-
|
|
28356
|
-
|
|
28357
|
-
if (responseText.includes("'Agent' object has no attribute")) {
|
|
28358
|
-
return {
|
|
28359
|
-
success: false,
|
|
28360
|
-
error: "Server error: The AI agent service is experiencing issues. Please try again later or contact support."
|
|
28361
|
-
};
|
|
28362
|
-
}
|
|
28363
|
-
return {
|
|
28364
|
-
success: false,
|
|
28365
|
-
error: `Invalid response format from server: ${responseText.substring(0, 200)}`
|
|
28366
|
-
};
|
|
28367
|
-
}
|
|
28368
|
-
if (response.ok) {
|
|
28369
|
-
return {
|
|
28370
|
-
success: result.success ?? true,
|
|
28371
|
-
analysis: result.analysis || result.response || result.message || result.data,
|
|
28372
|
-
timestamp: result.timestamp,
|
|
28373
|
-
error: result.error
|
|
28374
|
-
};
|
|
28375
|
-
} else {
|
|
28376
|
-
const errorMsg = result.error || result.message || `API request failed: ${response.status}`;
|
|
28377
|
-
console.error("[OptifyeAgent] API error:", errorMsg);
|
|
28378
|
-
if (errorMsg.includes("'Agent' object has no attribute")) {
|
|
28379
|
-
return {
|
|
28380
|
-
success: false,
|
|
28381
|
-
error: "The AI service is currently being updated. Please try again in a few moments."
|
|
28382
|
-
};
|
|
28679
|
+
await deleteThread2(threadId);
|
|
28680
|
+
if (activeThreadId === threadId) {
|
|
28681
|
+
onNewThread();
|
|
28383
28682
|
}
|
|
28384
|
-
|
|
28385
|
-
|
|
28386
|
-
|
|
28387
|
-
|
|
28388
|
-
|
|
28389
|
-
} catch (error) {
|
|
28390
|
-
const errorMsg = error instanceof Error ? `Failed to connect to Optifye Agent: ${error.message}` : "Failed to connect to Optifye Agent";
|
|
28391
|
-
console.error("[OptifyeAgent] Request failed:", error);
|
|
28392
|
-
if (error instanceof Error && error.name === "AbortError") {
|
|
28393
|
-
return {
|
|
28394
|
-
success: false,
|
|
28395
|
-
error: "Request timed out. The AI agent is taking too long to respond. Please try again."
|
|
28396
|
-
};
|
|
28683
|
+
} catch (error2) {
|
|
28684
|
+
console.error("Error deleting thread:", error2);
|
|
28685
|
+
alert("Failed to delete conversation. Please try again.");
|
|
28686
|
+
} finally {
|
|
28687
|
+
setDeletingId(null);
|
|
28397
28688
|
}
|
|
28398
|
-
return {
|
|
28399
|
-
success: false,
|
|
28400
|
-
error: errorMsg
|
|
28401
|
-
};
|
|
28402
28689
|
}
|
|
28403
|
-
}
|
|
28404
|
-
|
|
28405
|
-
|
|
28406
|
-
|
|
28407
|
-
|
|
28408
|
-
|
|
28409
|
-
|
|
28410
|
-
|
|
28411
|
-
|
|
28412
|
-
|
|
28413
|
-
|
|
28414
|
-
|
|
28415
|
-
|
|
28416
|
-
}
|
|
28417
|
-
return false;
|
|
28418
|
-
} catch (error) {
|
|
28419
|
-
console.error("[OptifyeAgent] Health check failed:", error);
|
|
28420
|
-
return false;
|
|
28690
|
+
};
|
|
28691
|
+
const formatDate = (dateString) => {
|
|
28692
|
+
const date = new Date(dateString);
|
|
28693
|
+
const now2 = /* @__PURE__ */ new Date();
|
|
28694
|
+
const diffMs = now2.getTime() - date.getTime();
|
|
28695
|
+
const diffDays = Math.floor(diffMs / (1e3 * 60 * 60 * 24));
|
|
28696
|
+
if (diffDays === 0) {
|
|
28697
|
+
return "Today";
|
|
28698
|
+
} else if (diffDays === 1) {
|
|
28699
|
+
return "Yesterday";
|
|
28700
|
+
} else if (diffDays < 7) {
|
|
28701
|
+
return date.toLocaleDateString("en-US", { weekday: "short" });
|
|
28702
|
+
} else {
|
|
28703
|
+
return date.toLocaleDateString("en-US", { month: "short", day: "numeric" });
|
|
28421
28704
|
}
|
|
28705
|
+
};
|
|
28706
|
+
if (error) {
|
|
28707
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `p-4 text-red-600 text-sm ${className}`, children: "Failed to load conversations" });
|
|
28422
28708
|
}
|
|
28709
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-col h-screen bg-gray-50 border-r border-gray-200 ${className}`, children: [
|
|
28710
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 p-4 border-b border-gray-200", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
28711
|
+
"button",
|
|
28712
|
+
{
|
|
28713
|
+
onClick: onNewThread,
|
|
28714
|
+
className: "w-full flex items-center justify-center gap-2 px-4 py-2.5 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-sm font-medium",
|
|
28715
|
+
children: [
|
|
28716
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "w-4 h-4" }),
|
|
28717
|
+
"New Chat"
|
|
28718
|
+
]
|
|
28719
|
+
}
|
|
28720
|
+
) }),
|
|
28721
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto min-h-0", children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center p-8", children: /* @__PURE__ */ jsxRuntime.jsx(LoadingSpinner_default, { size: "sm" }) }) : threads.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 text-center text-gray-500 text-sm", children: "No conversations yet" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-2", children: threads.map((thread) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
28722
|
+
"div",
|
|
28723
|
+
{
|
|
28724
|
+
onClick: () => onSelectThread(thread.id),
|
|
28725
|
+
className: `group relative flex items-start gap-3 px-4 py-3 hover:bg-gray-100 cursor-pointer transition-colors ${activeThreadId === thread.id ? "bg-gray-100" : ""}`,
|
|
28726
|
+
children: [
|
|
28727
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "w-4 h-4 text-gray-400 mt-0.5 flex-shrink-0" }),
|
|
28728
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
28729
|
+
/* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-medium text-gray-900 truncate", children: thread.title || "Untitled Chat" }),
|
|
28730
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-500 mt-0.5", children: formatDate(thread.created_at) })
|
|
28731
|
+
] }),
|
|
28732
|
+
deletingId === thread.id ? /* @__PURE__ */ jsxRuntime.jsx(LoadingSpinner_default, { size: "sm", className: "flex-shrink-0" }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
28733
|
+
"button",
|
|
28734
|
+
{
|
|
28735
|
+
onClick: (e) => handleDelete(e, thread.id),
|
|
28736
|
+
className: "flex-shrink-0 opacity-0 group-hover:opacity-100 p-1 hover:bg-gray-200 rounded transition-all",
|
|
28737
|
+
title: "Delete conversation",
|
|
28738
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "w-3.5 h-3.5 text-gray-500" })
|
|
28739
|
+
}
|
|
28740
|
+
)
|
|
28741
|
+
]
|
|
28742
|
+
},
|
|
28743
|
+
thread.id
|
|
28744
|
+
)) }) }),
|
|
28745
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0 p-4 border-t border-gray-200", children: /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-gray-500 text-center", children: [
|
|
28746
|
+
threads.length,
|
|
28747
|
+
" conversation",
|
|
28748
|
+
threads.length !== 1 ? "s" : ""
|
|
28749
|
+
] }) })
|
|
28750
|
+
] });
|
|
28423
28751
|
};
|
|
28424
|
-
var optifyeAgentClient = new OptifyeAgentClient();
|
|
28425
|
-
async function getManufacturingInsights(userQuestion, lineId, shiftId, companyId, context) {
|
|
28426
|
-
if (!userQuestion || !userQuestion.trim()) {
|
|
28427
|
-
return {
|
|
28428
|
-
success: false,
|
|
28429
|
-
error: "Please provide a question"
|
|
28430
|
-
};
|
|
28431
|
-
}
|
|
28432
|
-
if (!lineId || !companyId) {
|
|
28433
|
-
console.warn("[OptifyeAgent] Missing required IDs:", { lineId, companyId });
|
|
28434
|
-
}
|
|
28435
|
-
return optifyeAgentClient.getManufacturingInsights(
|
|
28436
|
-
userQuestion,
|
|
28437
|
-
lineId,
|
|
28438
|
-
shiftId,
|
|
28439
|
-
companyId,
|
|
28440
|
-
context
|
|
28441
|
-
);
|
|
28442
|
-
}
|
|
28443
28752
|
var axelProfilePng = "/axel-profile.png";
|
|
28444
28753
|
var AIAgentView = () => {
|
|
28445
28754
|
const { navigate, pathname } = useNavigation();
|
|
28755
|
+
const config = useDashboardConfig();
|
|
28446
28756
|
const entityConfig = useEntityConfig();
|
|
28447
28757
|
const dateTimeConfig = useDateTimeConfig();
|
|
28448
28758
|
const shiftConfig = useShiftConfig();
|
|
28449
28759
|
const [inputValue, setInputValue] = React46.useState("");
|
|
28450
|
-
const [
|
|
28451
|
-
const [isLoading, setIsLoading] = React46.useState(false);
|
|
28760
|
+
const [loadingThreads, setLoadingThreads] = React46.useState(/* @__PURE__ */ new Set());
|
|
28452
28761
|
const [lastError, setLastError] = React46.useState(null);
|
|
28453
28762
|
const [copiedMessageId, setCopiedMessageId] = React46.useState(null);
|
|
28454
|
-
const [
|
|
28763
|
+
const [activeThreadId, setActiveThreadId] = React46.useState(void 0);
|
|
28764
|
+
const [isSidebarOpen, setIsSidebarOpen] = React46.useState(false);
|
|
28765
|
+
const [streamingStates, setStreamingStates] = React46.useState(/* @__PURE__ */ new Map());
|
|
28766
|
+
const [userId, setUserId] = React46.useState(null);
|
|
28767
|
+
const [pendingThreadId, setPendingThreadId] = React46.useState(null);
|
|
28768
|
+
const [isTransitioning, setIsTransitioning] = React46.useState(false);
|
|
28769
|
+
const [typedText, setTypedText] = React46.useState("");
|
|
28770
|
+
const [newChatCount, setNewChatCount] = React46.useState(0);
|
|
28771
|
+
const isThreadLoading = (threadId) => {
|
|
28772
|
+
return threadId ? loadingThreads.has(threadId) : false;
|
|
28773
|
+
};
|
|
28774
|
+
const getStreamingState = (threadId) => {
|
|
28775
|
+
return threadId ? streamingStates.get(threadId) || { message: "", reasoning: "" } : { message: "", reasoning: "" };
|
|
28776
|
+
};
|
|
28455
28777
|
const textareaRef = React46.useRef(null);
|
|
28456
28778
|
const messagesEndRef = React46.useRef(null);
|
|
28457
28779
|
const containerRef = React46.useRef(null);
|
|
28780
|
+
const { createThread, mutate: mutateThreads } = useThreads();
|
|
28781
|
+
const { messages, addMessage, setMessages } = useMessages(activeThreadId);
|
|
28782
|
+
const agnoApiUrl = config.endpoints?.agnoApiUrl || "https://optifye-agent-production.up.railway.app";
|
|
28783
|
+
const sseClient = React46.useMemo(() => {
|
|
28784
|
+
console.log("[AIAgentView] Using AGNO API URL:", agnoApiUrl);
|
|
28785
|
+
return new SSEChatClient(agnoApiUrl);
|
|
28786
|
+
}, [agnoApiUrl]);
|
|
28458
28787
|
const getLineIdFromPath = () => {
|
|
28459
28788
|
const pathParts = pathname.split("/");
|
|
28460
28789
|
const lineIdIndex = pathParts.findIndex((part) => part === "ai-agent") + 1;
|
|
@@ -28466,17 +28795,55 @@ var AIAgentView = () => {
|
|
|
28466
28795
|
const lineId = getLineIdFromPath();
|
|
28467
28796
|
const { shiftId } = getCurrentShift(dateTimeConfig.defaultTimezone || "Asia/Kolkata", shiftConfig);
|
|
28468
28797
|
const companyId = entityConfig.companyId || "default-company-id";
|
|
28798
|
+
const ACTIVE_THREAD_STORAGE_KEY = `ai-agent-active-thread-${lineId}`;
|
|
28799
|
+
React46.useEffect(() => {
|
|
28800
|
+
const savedThreadId = localStorage.getItem(ACTIVE_THREAD_STORAGE_KEY);
|
|
28801
|
+
if (savedThreadId && savedThreadId !== "undefined") {
|
|
28802
|
+
setActiveThreadId(savedThreadId);
|
|
28803
|
+
}
|
|
28804
|
+
}, [ACTIVE_THREAD_STORAGE_KEY]);
|
|
28805
|
+
React46.useEffect(() => {
|
|
28806
|
+
if (activeThreadId) {
|
|
28807
|
+
localStorage.setItem(ACTIVE_THREAD_STORAGE_KEY, activeThreadId);
|
|
28808
|
+
} else {
|
|
28809
|
+
localStorage.removeItem(ACTIVE_THREAD_STORAGE_KEY);
|
|
28810
|
+
}
|
|
28811
|
+
}, [activeThreadId, ACTIVE_THREAD_STORAGE_KEY]);
|
|
28469
28812
|
React46.useEffect(() => {
|
|
28470
28813
|
if (textareaRef.current) {
|
|
28471
28814
|
textareaRef.current.style.height = "auto";
|
|
28472
28815
|
textareaRef.current.style.height = `${Math.min(textareaRef.current.scrollHeight, 120)}px`;
|
|
28473
28816
|
}
|
|
28474
28817
|
}, [inputValue]);
|
|
28818
|
+
const scrollToBottom = () => {
|
|
28819
|
+
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
28820
|
+
};
|
|
28475
28821
|
React46.useEffect(() => {
|
|
28476
|
-
if (
|
|
28477
|
-
|
|
28822
|
+
if (activeThreadId && messages.length > 0) {
|
|
28823
|
+
setTimeout(scrollToBottom, 100);
|
|
28478
28824
|
}
|
|
28479
|
-
}, []);
|
|
28825
|
+
}, [activeThreadId]);
|
|
28826
|
+
React46.useEffect(() => {
|
|
28827
|
+
if (messages.length === 0 && !isTransitioning) {
|
|
28828
|
+
const fullText = "Hi, I'm Axel - Your AI Supervisor";
|
|
28829
|
+
let index = 0;
|
|
28830
|
+
setTypedText("");
|
|
28831
|
+
const typeInterval = setInterval(() => {
|
|
28832
|
+
if (index < fullText.length) {
|
|
28833
|
+
setTypedText(fullText.substring(0, index + 1));
|
|
28834
|
+
index++;
|
|
28835
|
+
} else {
|
|
28836
|
+
clearInterval(typeInterval);
|
|
28837
|
+
}
|
|
28838
|
+
}, 50);
|
|
28839
|
+
return () => clearInterval(typeInterval);
|
|
28840
|
+
}
|
|
28841
|
+
}, [messages.length, isTransitioning]);
|
|
28842
|
+
React46.useEffect(() => {
|
|
28843
|
+
if (isSidebarOpen) {
|
|
28844
|
+
setNewChatCount(0);
|
|
28845
|
+
}
|
|
28846
|
+
}, [isSidebarOpen]);
|
|
28480
28847
|
const copyToClipboard = async (text, messageId) => {
|
|
28481
28848
|
try {
|
|
28482
28849
|
await navigator.clipboard.writeText(text);
|
|
@@ -28486,311 +28853,721 @@ var AIAgentView = () => {
|
|
|
28486
28853
|
console.error("Failed to copy text: ", err);
|
|
28487
28854
|
}
|
|
28488
28855
|
};
|
|
28856
|
+
const handleNewThread = () => {
|
|
28857
|
+
setActiveThreadId(void 0);
|
|
28858
|
+
setMessages([]);
|
|
28859
|
+
setInputValue("");
|
|
28860
|
+
setPendingThreadId(null);
|
|
28861
|
+
setTypedText("");
|
|
28862
|
+
localStorage.removeItem(ACTIVE_THREAD_STORAGE_KEY);
|
|
28863
|
+
textareaRef.current?.focus();
|
|
28864
|
+
};
|
|
28865
|
+
React46.useEffect(() => {
|
|
28866
|
+
const checkAuth = async () => {
|
|
28867
|
+
const supabase2 = _getSupabaseInstance();
|
|
28868
|
+
const { data: { session } } = await supabase2.auth.getSession();
|
|
28869
|
+
if (session?.user) {
|
|
28870
|
+
setUserId(session.user.id);
|
|
28871
|
+
console.log("[AIAgentView] User authenticated:", session.user.id);
|
|
28872
|
+
} else {
|
|
28873
|
+
console.log("[AIAgentView] No authenticated session found");
|
|
28874
|
+
}
|
|
28875
|
+
};
|
|
28876
|
+
checkAuth();
|
|
28877
|
+
const supabase = _getSupabaseInstance();
|
|
28878
|
+
const { data: { subscription } } = supabase.auth.onAuthStateChange((event, session) => {
|
|
28879
|
+
if (session?.user) {
|
|
28880
|
+
setUserId(session.user.id);
|
|
28881
|
+
} else {
|
|
28882
|
+
setUserId(null);
|
|
28883
|
+
}
|
|
28884
|
+
});
|
|
28885
|
+
return () => {
|
|
28886
|
+
subscription.unsubscribe();
|
|
28887
|
+
};
|
|
28888
|
+
}, []);
|
|
28489
28889
|
const handleSubmit = async (e) => {
|
|
28490
28890
|
e.preventDefault();
|
|
28491
|
-
if (!inputValue.trim() ||
|
|
28891
|
+
if (!inputValue.trim() || !userId) return;
|
|
28892
|
+
let currentThreadId = activeThreadId || `temp-${Date.now()}`;
|
|
28893
|
+
if (isThreadLoading(currentThreadId)) return;
|
|
28492
28894
|
const userMessage = inputValue.trim();
|
|
28493
|
-
|
|
28494
|
-
|
|
28495
|
-
|
|
28895
|
+
if (displayMessages.length === 0) {
|
|
28896
|
+
setIsTransitioning(true);
|
|
28897
|
+
setTimeout(() => {
|
|
28898
|
+
setIsTransitioning(false);
|
|
28899
|
+
}, 800);
|
|
28900
|
+
}
|
|
28901
|
+
setInputValue("");
|
|
28902
|
+
setLoadingThreads((prev) => new Set(prev).add(currentThreadId));
|
|
28903
|
+
setLastError(null);
|
|
28904
|
+
if (!activeThreadId) {
|
|
28905
|
+
setPendingThreadId(currentThreadId);
|
|
28906
|
+
}
|
|
28907
|
+
setStreamingStates((prev) => {
|
|
28908
|
+
const newMap = new Map(prev);
|
|
28909
|
+
newMap.set(currentThreadId, { message: "", reasoning: "" });
|
|
28910
|
+
return newMap;
|
|
28911
|
+
});
|
|
28912
|
+
const tempUserMessage = {
|
|
28913
|
+
id: Date.now(),
|
|
28914
|
+
// Temporary ID
|
|
28915
|
+
thread_id: activeThreadId || "",
|
|
28496
28916
|
role: "user",
|
|
28497
28917
|
content: userMessage,
|
|
28498
|
-
|
|
28918
|
+
reasoning: null,
|
|
28919
|
+
model_id: null,
|
|
28920
|
+
token_usage: null,
|
|
28921
|
+
metadata: null,
|
|
28922
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
28923
|
+
position: messages.length
|
|
28499
28924
|
};
|
|
28500
|
-
setMessages((prev) => [...prev,
|
|
28501
|
-
|
|
28502
|
-
setIsLoading(true);
|
|
28503
|
-
setIsTyping(true);
|
|
28504
|
-
setLastError(null);
|
|
28925
|
+
setMessages((prev) => [...prev, tempUserMessage]);
|
|
28926
|
+
setTimeout(scrollToBottom, 100);
|
|
28505
28927
|
try {
|
|
28506
|
-
|
|
28507
|
-
role: msg.role,
|
|
28508
|
-
content: msg.content
|
|
28509
|
-
}));
|
|
28510
|
-
const context = {
|
|
28511
|
-
timeframe: "flexible",
|
|
28512
|
-
focus: "conversational",
|
|
28513
|
-
conversation_style: "friendly_expert",
|
|
28514
|
-
system_prompt: `You are Axel, a friendly and knowledgeable manufacturing expert.
|
|
28515
|
-
|
|
28516
|
-
Your personality:
|
|
28517
|
-
- Warm, approachable, and professional
|
|
28518
|
-
- You respond naturally to greetings and casual conversation
|
|
28519
|
-
- You're passionate about manufacturing and love sharing your expertise
|
|
28520
|
-
- You can discuss any manufacturing topic across any timeframe
|
|
28521
|
-
|
|
28522
|
-
Guidelines:
|
|
28523
|
-
- Respond to greetings warmly (e.g., "Hi" \u2192 "Hi there! How can I help you with your manufacturing needs today?")
|
|
28524
|
-
- For manufacturing questions, provide detailed, actionable insights
|
|
28525
|
-
- You can analyze past data, current performance, or future projections
|
|
28526
|
-
- Always maintain a conversational tone while being informative
|
|
28527
|
-
- If asked about non-manufacturing topics, politely redirect to your expertise
|
|
28528
|
-
|
|
28529
|
-
Remember: You're not just an AI, you're Axel - a trusted manufacturing advisor who builds relationships with clients.`,
|
|
28530
|
-
conversation_history: conversationHistory,
|
|
28531
|
-
allow_any_timeframe: true,
|
|
28532
|
-
personality_traits: ["friendly", "expert", "conversational", "helpful"]
|
|
28533
|
-
};
|
|
28534
|
-
console.log("[AIAgentView] Submitting message:", {
|
|
28535
|
-
message: userMessage,
|
|
28536
|
-
lineId,
|
|
28537
|
-
shiftId,
|
|
28538
|
-
companyId,
|
|
28539
|
-
context
|
|
28540
|
-
});
|
|
28541
|
-
const result = await getManufacturingInsights(
|
|
28928
|
+
await sseClient.sendMessage(
|
|
28542
28929
|
userMessage,
|
|
28543
|
-
|
|
28544
|
-
|
|
28545
|
-
|
|
28546
|
-
|
|
28930
|
+
userId,
|
|
28931
|
+
activeThreadId || null,
|
|
28932
|
+
{
|
|
28933
|
+
companyId,
|
|
28934
|
+
lineId,
|
|
28935
|
+
shiftId
|
|
28936
|
+
},
|
|
28937
|
+
{
|
|
28938
|
+
onThreadCreated: (threadId) => {
|
|
28939
|
+
if (!activeThreadId) {
|
|
28940
|
+
const oldThreadId = currentThreadId;
|
|
28941
|
+
currentThreadId = threadId;
|
|
28942
|
+
setActiveThreadId(threadId);
|
|
28943
|
+
setPendingThreadId(null);
|
|
28944
|
+
if (!isSidebarOpen) {
|
|
28945
|
+
setNewChatCount((prev) => prev + 1);
|
|
28946
|
+
}
|
|
28947
|
+
setLoadingThreads((prev) => {
|
|
28948
|
+
const newSet = new Set(prev);
|
|
28949
|
+
if (newSet.has(oldThreadId)) {
|
|
28950
|
+
newSet.delete(oldThreadId);
|
|
28951
|
+
newSet.add(threadId);
|
|
28952
|
+
}
|
|
28953
|
+
return newSet;
|
|
28954
|
+
});
|
|
28955
|
+
setStreamingStates((prev) => {
|
|
28956
|
+
const newMap = new Map(prev);
|
|
28957
|
+
const streamingState = newMap.get(oldThreadId);
|
|
28958
|
+
if (streamingState) {
|
|
28959
|
+
newMap.delete(oldThreadId);
|
|
28960
|
+
newMap.set(threadId, streamingState);
|
|
28961
|
+
}
|
|
28962
|
+
return newMap;
|
|
28963
|
+
});
|
|
28964
|
+
mutateThreads();
|
|
28965
|
+
}
|
|
28966
|
+
},
|
|
28967
|
+
onMessage: (text) => {
|
|
28968
|
+
setStreamingStates((prev) => {
|
|
28969
|
+
const newMap = new Map(prev);
|
|
28970
|
+
const current = newMap.get(currentThreadId) || { message: "", reasoning: "" };
|
|
28971
|
+
newMap.set(currentThreadId, { ...current, message: current.message + text });
|
|
28972
|
+
return newMap;
|
|
28973
|
+
});
|
|
28974
|
+
},
|
|
28975
|
+
onReasoning: (text) => {
|
|
28976
|
+
setStreamingStates((prev) => {
|
|
28977
|
+
const newMap = new Map(prev);
|
|
28978
|
+
const current = newMap.get(currentThreadId) || { message: "", reasoning: "" };
|
|
28979
|
+
newMap.set(currentThreadId, { ...current, reasoning: current.reasoning + text });
|
|
28980
|
+
return newMap;
|
|
28981
|
+
});
|
|
28982
|
+
},
|
|
28983
|
+
onComplete: async (messageId) => {
|
|
28984
|
+
if (currentThreadId && !currentThreadId.startsWith("temp-")) {
|
|
28985
|
+
const updatedMessages = await getAllThreadMessages(currentThreadId);
|
|
28986
|
+
setMessages(updatedMessages);
|
|
28987
|
+
}
|
|
28988
|
+
setStreamingStates((prev) => {
|
|
28989
|
+
const newMap = new Map(prev);
|
|
28990
|
+
newMap.delete(currentThreadId);
|
|
28991
|
+
return newMap;
|
|
28992
|
+
});
|
|
28993
|
+
setLoadingThreads((prev) => {
|
|
28994
|
+
const newSet = new Set(prev);
|
|
28995
|
+
newSet.delete(currentThreadId);
|
|
28996
|
+
return newSet;
|
|
28997
|
+
});
|
|
28998
|
+
if (!activeThreadId) {
|
|
28999
|
+
setPendingThreadId(null);
|
|
29000
|
+
}
|
|
29001
|
+
},
|
|
29002
|
+
onError: (error) => {
|
|
29003
|
+
console.error("Chat error:", error);
|
|
29004
|
+
setLastError(error);
|
|
29005
|
+
setLoadingThreads((prev) => {
|
|
29006
|
+
const newSet = new Set(prev);
|
|
29007
|
+
newSet.delete(currentThreadId);
|
|
29008
|
+
return newSet;
|
|
29009
|
+
});
|
|
29010
|
+
setStreamingStates((prev) => {
|
|
29011
|
+
const newMap = new Map(prev);
|
|
29012
|
+
newMap.delete(currentThreadId);
|
|
29013
|
+
return newMap;
|
|
29014
|
+
});
|
|
29015
|
+
if (!activeThreadId) {
|
|
29016
|
+
setPendingThreadId(null);
|
|
29017
|
+
}
|
|
29018
|
+
setMessages((prev) => prev.slice(0, -1));
|
|
29019
|
+
}
|
|
29020
|
+
}
|
|
28547
29021
|
);
|
|
28548
|
-
if (result.success && result.analysis) {
|
|
28549
|
-
const assistantMessage = {
|
|
28550
|
-
id: Date.now().toString(),
|
|
28551
|
-
role: "assistant",
|
|
28552
|
-
content: result.analysis,
|
|
28553
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
28554
|
-
};
|
|
28555
|
-
setMessages((prev) => [...prev, assistantMessage]);
|
|
28556
|
-
} else {
|
|
28557
|
-
const errorMessage = result.error || "Sorry, I encountered an error processing your request. Please try again.";
|
|
28558
|
-
const errorAssistantMessage = {
|
|
28559
|
-
id: Date.now().toString(),
|
|
28560
|
-
role: "assistant",
|
|
28561
|
-
content: errorMessage,
|
|
28562
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
28563
|
-
error: true
|
|
28564
|
-
};
|
|
28565
|
-
setMessages((prev) => [...prev, errorAssistantMessage]);
|
|
28566
|
-
setLastError(errorMessage);
|
|
28567
|
-
console.error("[AIAgentView] API returned error:", errorMessage);
|
|
28568
|
-
}
|
|
28569
29022
|
} catch (error) {
|
|
28570
|
-
console.error("[AIAgentView] Error
|
|
28571
|
-
const errorMessage =
|
|
28572
|
-
const errorAssistantMessage = {
|
|
28573
|
-
id: Date.now().toString(),
|
|
28574
|
-
role: "assistant",
|
|
28575
|
-
content: errorMessage,
|
|
28576
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
28577
|
-
error: true
|
|
28578
|
-
};
|
|
28579
|
-
setMessages((prev) => [...prev, errorAssistantMessage]);
|
|
29023
|
+
console.error("[AIAgentView] Error in chat:", error);
|
|
29024
|
+
const errorMessage = error instanceof Error ? error.message : "An unexpected error occurred";
|
|
28580
29025
|
setLastError(errorMessage);
|
|
28581
|
-
|
|
28582
|
-
|
|
28583
|
-
|
|
29026
|
+
setLoadingThreads((prev) => {
|
|
29027
|
+
const newSet = new Set(prev);
|
|
29028
|
+
newSet.delete(currentThreadId);
|
|
29029
|
+
return newSet;
|
|
29030
|
+
});
|
|
29031
|
+
setStreamingStates((prev) => {
|
|
29032
|
+
const newMap = new Map(prev);
|
|
29033
|
+
newMap.delete(currentThreadId);
|
|
29034
|
+
return newMap;
|
|
29035
|
+
});
|
|
29036
|
+
if (!activeThreadId) {
|
|
29037
|
+
setPendingThreadId(null);
|
|
29038
|
+
}
|
|
29039
|
+
setMessages((prev) => prev.slice(0, -1));
|
|
28584
29040
|
}
|
|
28585
29041
|
};
|
|
28586
29042
|
const handleKeyDown = (e) => {
|
|
28587
29043
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
28588
29044
|
e.preventDefault();
|
|
28589
|
-
|
|
29045
|
+
if (!isCurrentThreadLoading) {
|
|
29046
|
+
handleSubmit(e);
|
|
29047
|
+
}
|
|
28590
29048
|
}
|
|
28591
29049
|
};
|
|
28592
29050
|
const formatMessage = (content) => {
|
|
28593
|
-
|
|
28594
|
-
|
|
28595
|
-
|
|
28596
|
-
|
|
29051
|
+
const processInlineFormatting = (text) => {
|
|
29052
|
+
text = text.replace(/\*\*(.*?)\*\*/g, '<strong class="font-semibold text-gray-900">$1</strong>');
|
|
29053
|
+
text = text.replace(/`([^`]+)`/g, '<code class="bg-gray-100 px-1.5 py-0.5 rounded text-sm font-mono text-gray-800">$1</code>');
|
|
29054
|
+
return text;
|
|
29055
|
+
};
|
|
29056
|
+
const parseTableFromText = (lines2, startIndex) => {
|
|
29057
|
+
const tableLines = [];
|
|
29058
|
+
let i = startIndex;
|
|
29059
|
+
while (i < lines2.length) {
|
|
29060
|
+
const line = lines2[i].trim();
|
|
29061
|
+
if (!line) {
|
|
29062
|
+
i++;
|
|
29063
|
+
break;
|
|
29064
|
+
}
|
|
29065
|
+
if (line.includes("|") || line.match(/^[-|=\s]+$/)) {
|
|
29066
|
+
tableLines.push(line);
|
|
29067
|
+
i++;
|
|
29068
|
+
} else {
|
|
29069
|
+
break;
|
|
29070
|
+
}
|
|
28597
29071
|
}
|
|
28598
|
-
if (
|
|
28599
|
-
|
|
29072
|
+
if (tableLines.length === 0) return { html: "", endIndex: startIndex };
|
|
29073
|
+
const dataLines = tableLines.filter((line) => !line.match(/^[-|=\s]+$/));
|
|
29074
|
+
if (dataLines.length === 0) return { html: "", endIndex: i };
|
|
29075
|
+
let headerRow = [];
|
|
29076
|
+
let dataRows = [];
|
|
29077
|
+
const firstLine = dataLines[0];
|
|
29078
|
+
if (firstLine.includes("|")) {
|
|
29079
|
+
const cells = firstLine.split("|").map((cell) => cell.trim()).filter((cell) => cell.length > 0);
|
|
29080
|
+
if (cells.length >= 2) {
|
|
29081
|
+
headerRow = cells;
|
|
29082
|
+
for (let j = 1; j < dataLines.length; j++) {
|
|
29083
|
+
const row = dataLines[j];
|
|
29084
|
+
if (row.includes("|")) {
|
|
29085
|
+
const rowCells = row.split("|").map((cell) => cell.trim()).filter((cell) => cell.length > 0);
|
|
29086
|
+
while (rowCells.length < headerRow.length) rowCells.push("");
|
|
29087
|
+
if (rowCells.length > headerRow.length) rowCells.splice(headerRow.length);
|
|
29088
|
+
dataRows.push(rowCells);
|
|
29089
|
+
}
|
|
29090
|
+
}
|
|
29091
|
+
}
|
|
28600
29092
|
}
|
|
28601
|
-
|
|
28602
|
-
|
|
28603
|
-
|
|
28604
|
-
|
|
28605
|
-
|
|
28606
|
-
|
|
28607
|
-
|
|
28608
|
-
|
|
29093
|
+
if (headerRow.length === 0) {
|
|
29094
|
+
for (const line of dataLines) {
|
|
29095
|
+
if (line.includes("|")) {
|
|
29096
|
+
const rowCells = line.split("|").map((cell) => cell.trim()).filter((cell) => cell.length > 0);
|
|
29097
|
+
if (rowCells.length >= 2) {
|
|
29098
|
+
dataRows.push(rowCells);
|
|
29099
|
+
}
|
|
29100
|
+
}
|
|
29101
|
+
}
|
|
29102
|
+
if (dataRows.length > 0 && dataRows[0].length > 0) {
|
|
29103
|
+
headerRow = dataRows[0].map((_, index) => `Column ${index + 1}`);
|
|
29104
|
+
}
|
|
29105
|
+
}
|
|
29106
|
+
if (headerRow.length > 0 && dataRows.length > 0) {
|
|
29107
|
+
let tableHtml = '<div class="overflow-x-auto my-4"><table class="min-w-full border-collapse border border-gray-300 rounded-lg shadow-sm">';
|
|
29108
|
+
tableHtml += '<thead class="bg-gray-50">';
|
|
29109
|
+
tableHtml += "<tr>";
|
|
29110
|
+
headerRow.forEach((header) => {
|
|
29111
|
+
tableHtml += `<th class="border border-gray-300 px-4 py-2 text-left font-semibold text-gray-900">${processInlineFormatting(header)}</th>`;
|
|
29112
|
+
});
|
|
29113
|
+
tableHtml += "</tr>";
|
|
29114
|
+
tableHtml += "</thead>";
|
|
29115
|
+
tableHtml += '<tbody class="bg-white">';
|
|
29116
|
+
dataRows.forEach((row, rowIndex) => {
|
|
29117
|
+
tableHtml += `<tr class="${rowIndex % 2 === 0 ? "bg-white" : "bg-gray-50"}">`;
|
|
29118
|
+
row.forEach((cell) => {
|
|
29119
|
+
tableHtml += `<td class="border border-gray-300 px-4 py-2 text-gray-800">${processInlineFormatting(cell)}</td>`;
|
|
29120
|
+
});
|
|
29121
|
+
tableHtml += "</tr>";
|
|
29122
|
+
});
|
|
29123
|
+
tableHtml += "</tbody>";
|
|
29124
|
+
tableHtml += "</table></div>";
|
|
29125
|
+
return { html: tableHtml, endIndex: i };
|
|
29126
|
+
}
|
|
29127
|
+
return { html: "", endIndex: startIndex };
|
|
29128
|
+
};
|
|
29129
|
+
const processedContent = content;
|
|
29130
|
+
const lines = processedContent.split("\n");
|
|
29131
|
+
const formattedLines = [];
|
|
29132
|
+
let inList = false;
|
|
29133
|
+
for (let i = 0; i < lines.length; i++) {
|
|
29134
|
+
let line = lines[i];
|
|
29135
|
+
const trimmedLine = line.trim();
|
|
29136
|
+
if (!trimmedLine) {
|
|
29137
|
+
if (inList) {
|
|
29138
|
+
formattedLines.push("</ul>");
|
|
29139
|
+
inList = false;
|
|
29140
|
+
}
|
|
29141
|
+
formattedLines.push("<br/>");
|
|
29142
|
+
continue;
|
|
29143
|
+
}
|
|
29144
|
+
if (trimmedLine.includes("|") && (trimmedLine.match(/\|/g) || []).length >= 1) {
|
|
29145
|
+
if (inList) {
|
|
29146
|
+
formattedLines.push("</ul>");
|
|
29147
|
+
inList = false;
|
|
29148
|
+
}
|
|
29149
|
+
const tableResult = parseTableFromText(lines, i);
|
|
29150
|
+
if (tableResult.html) {
|
|
29151
|
+
formattedLines.push(tableResult.html);
|
|
29152
|
+
i = tableResult.endIndex - 1;
|
|
29153
|
+
continue;
|
|
29154
|
+
}
|
|
29155
|
+
}
|
|
29156
|
+
if (trimmedLine.startsWith("###")) {
|
|
29157
|
+
if (inList) {
|
|
29158
|
+
formattedLines.push("</ul>");
|
|
29159
|
+
inList = false;
|
|
29160
|
+
}
|
|
29161
|
+
const headerText = processInlineFormatting(trimmedLine.replace(/^###\s*/, ""));
|
|
29162
|
+
formattedLines.push(`<h3 class="text-lg font-semibold text-gray-900 mt-4 mb-2">${headerText}</h3>`);
|
|
29163
|
+
continue;
|
|
29164
|
+
} else if (trimmedLine.startsWith("##")) {
|
|
29165
|
+
if (inList) {
|
|
29166
|
+
formattedLines.push("</ul>");
|
|
29167
|
+
inList = false;
|
|
29168
|
+
}
|
|
29169
|
+
const headerText = processInlineFormatting(trimmedLine.replace(/^##\s*/, ""));
|
|
29170
|
+
formattedLines.push(`<h2 class="text-xl font-semibold text-gray-900 mt-4 mb-2">${headerText}</h2>`);
|
|
29171
|
+
continue;
|
|
29172
|
+
} else if (trimmedLine.startsWith("#")) {
|
|
29173
|
+
if (inList) {
|
|
29174
|
+
formattedLines.push("</ul>");
|
|
29175
|
+
inList = false;
|
|
29176
|
+
}
|
|
29177
|
+
const headerText = processInlineFormatting(trimmedLine.replace(/^#\s*/, ""));
|
|
29178
|
+
formattedLines.push(`<h1 class="text-2xl font-bold text-gray-900 mt-4 mb-3">${headerText}</h1>`);
|
|
29179
|
+
continue;
|
|
29180
|
+
}
|
|
29181
|
+
const listMatch = trimmedLine.match(/^([-*•]\s+|\d+\.\s+|^\s*[-*•]\s+)/);
|
|
29182
|
+
if (listMatch) {
|
|
29183
|
+
if (!inList) {
|
|
29184
|
+
formattedLines.push('<ul class="space-y-1 mt-2 mb-2">');
|
|
29185
|
+
inList = true;
|
|
29186
|
+
}
|
|
29187
|
+
const listContent = processInlineFormatting(trimmedLine.replace(/^([-*•]\s+|\d+\.\s+|\s*[-*•]\s+)/, ""));
|
|
29188
|
+
formattedLines.push(`<li class="ml-4 text-gray-700 flex items-start"><span class="mr-2 text-gray-500">\u2022</span><span>${listContent}</span></li>`);
|
|
29189
|
+
continue;
|
|
29190
|
+
} else if (inList) {
|
|
29191
|
+
formattedLines.push("</ul>");
|
|
29192
|
+
inList = false;
|
|
29193
|
+
}
|
|
29194
|
+
if (trimmedLine.match(/^---+$/)) {
|
|
29195
|
+
formattedLines.push('<hr class="my-4 border-gray-200"/>');
|
|
29196
|
+
continue;
|
|
29197
|
+
}
|
|
29198
|
+
if (trimmedLine) {
|
|
29199
|
+
const processedLine = processInlineFormatting(line);
|
|
29200
|
+
if (trimmedLine.endsWith(":") && trimmedLine.length < 50 && !trimmedLine.includes("**")) {
|
|
29201
|
+
formattedLines.push(`<h3 class="text-lg font-semibold text-gray-900 mt-4 mb-2">${processedLine}</h3>`);
|
|
29202
|
+
} else {
|
|
29203
|
+
formattedLines.push(`<p class="text-gray-800 leading-relaxed mb-2">${processedLine}</p>`);
|
|
29204
|
+
}
|
|
29205
|
+
}
|
|
29206
|
+
}
|
|
29207
|
+
if (inList) {
|
|
29208
|
+
formattedLines.push("</ul>");
|
|
29209
|
+
}
|
|
29210
|
+
return formattedLines.join("");
|
|
28609
29211
|
};
|
|
28610
29212
|
const formatTime2 = (timestamp) => {
|
|
28611
|
-
|
|
29213
|
+
const date = new Date(timestamp);
|
|
29214
|
+
return date.toLocaleTimeString([], {
|
|
28612
29215
|
hour: "2-digit",
|
|
28613
29216
|
minute: "2-digit",
|
|
28614
29217
|
hour12: false
|
|
28615
29218
|
});
|
|
28616
29219
|
};
|
|
28617
|
-
|
|
28618
|
-
|
|
28619
|
-
|
|
28620
|
-
|
|
28621
|
-
|
|
28622
|
-
|
|
28623
|
-
|
|
28624
|
-
|
|
28625
|
-
|
|
28626
|
-
|
|
28627
|
-
|
|
28628
|
-
|
|
28629
|
-
|
|
28630
|
-
|
|
28631
|
-
|
|
28632
|
-
|
|
28633
|
-
|
|
28634
|
-
|
|
28635
|
-
|
|
28636
|
-
|
|
28637
|
-
|
|
28638
|
-
|
|
28639
|
-
] }) }) }),
|
|
28640
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
28641
|
-
"main",
|
|
29220
|
+
const displayMessages = [...messages];
|
|
29221
|
+
const effectiveThreadId = activeThreadId || pendingThreadId || void 0;
|
|
29222
|
+
const currentStreaming = getStreamingState(effectiveThreadId);
|
|
29223
|
+
const isCurrentThreadLoading = isThreadLoading(effectiveThreadId);
|
|
29224
|
+
if (isCurrentThreadLoading && currentStreaming.message) {
|
|
29225
|
+
displayMessages.push({
|
|
29226
|
+
id: -1,
|
|
29227
|
+
// Use -1 for streaming message to identify it
|
|
29228
|
+
thread_id: activeThreadId || "",
|
|
29229
|
+
role: "assistant",
|
|
29230
|
+
content: currentStreaming.message,
|
|
29231
|
+
reasoning: currentStreaming.reasoning || null,
|
|
29232
|
+
model_id: "gpt-4o-mini",
|
|
29233
|
+
token_usage: null,
|
|
29234
|
+
metadata: null,
|
|
29235
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
29236
|
+
position: messages.length
|
|
29237
|
+
});
|
|
29238
|
+
}
|
|
29239
|
+
const renderAssistantContent = (content) => {
|
|
29240
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
29241
|
+
"div",
|
|
28642
29242
|
{
|
|
28643
|
-
|
|
28644
|
-
|
|
28645
|
-
|
|
28646
|
-
|
|
28647
|
-
|
|
28648
|
-
|
|
28649
|
-
|
|
28650
|
-
|
|
28651
|
-
|
|
28652
|
-
|
|
28653
|
-
|
|
28654
|
-
|
|
28655
|
-
|
|
28656
|
-
|
|
28657
|
-
|
|
29243
|
+
className: "formatted-content",
|
|
29244
|
+
dangerouslySetInnerHTML: { __html: formatMessage(content) }
|
|
29245
|
+
}
|
|
29246
|
+
);
|
|
29247
|
+
};
|
|
29248
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-screen bg-white", children: [
|
|
29249
|
+
/* @__PURE__ */ jsxRuntime.jsx("style", { dangerouslySetInnerHTML: {
|
|
29250
|
+
__html: `
|
|
29251
|
+
@keyframes slideDown {
|
|
29252
|
+
0% {
|
|
29253
|
+
transform: translateY(-40vh);
|
|
29254
|
+
opacity: 1;
|
|
29255
|
+
}
|
|
29256
|
+
100% {
|
|
29257
|
+
transform: translateY(0);
|
|
29258
|
+
opacity: 1;
|
|
29259
|
+
}
|
|
29260
|
+
}
|
|
29261
|
+
`
|
|
29262
|
+
} }),
|
|
29263
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex-1 flex flex-col h-screen transition-all duration-300 ${isSidebarOpen ? "mr-80" : "mr-0"}`, children: [
|
|
29264
|
+
/* @__PURE__ */ jsxRuntime.jsx("header", { className: "flex-shrink-0 bg-white border-b border-gray-200 sticky top-0 z-10", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
29265
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
29266
|
+
"button",
|
|
29267
|
+
{
|
|
29268
|
+
onClick: () => navigate("/"),
|
|
29269
|
+
className: "flex items-center gap-2 text-gray-600 hover:text-gray-900 transition-colors",
|
|
29270
|
+
"aria-label": "Go back",
|
|
29271
|
+
children: [
|
|
29272
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { className: "w-5 h-5" }),
|
|
29273
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "Back" })
|
|
29274
|
+
]
|
|
29275
|
+
}
|
|
29276
|
+
) }),
|
|
29277
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center", children: [
|
|
29278
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
29279
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl sm:text-2xl md:text-3xl font-bold text-gray-800 tracking-tight leading-none", children: "Chat with Axel" }),
|
|
29280
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 w-2 rounded-full bg-blue-500 animate-pulse ring-2 ring-blue-500/30" })
|
|
29281
|
+
] }),
|
|
29282
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center mt-1", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-gray-500", children: /* @__PURE__ */ jsxRuntime.jsx(ISTTimer_default, {}) }) })
|
|
29283
|
+
] }),
|
|
29284
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
29285
|
+
"button",
|
|
29286
|
+
{
|
|
29287
|
+
onClick: () => setIsSidebarOpen(!isSidebarOpen),
|
|
29288
|
+
className: "relative p-2 hover:bg-gray-100 rounded-lg transition-colors",
|
|
29289
|
+
"aria-label": "Toggle sidebar",
|
|
29290
|
+
children: [
|
|
29291
|
+
isSidebarOpen ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "w-5 h-5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Menu, { className: "w-5 h-5" }),
|
|
29292
|
+
!isSidebarOpen && newChatCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -top-1 -right-1 bg-red-500 text-white text-xs rounded-full w-5 h-5 flex items-center justify-center font-medium", children: newChatCount })
|
|
29293
|
+
]
|
|
29294
|
+
}
|
|
29295
|
+
) })
|
|
29296
|
+
] }) }) }),
|
|
29297
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
29298
|
+
"main",
|
|
29299
|
+
{
|
|
29300
|
+
ref: containerRef,
|
|
29301
|
+
className: `flex-1 bg-gray-50/50 min-h-0 ${displayMessages.length === 0 && !isTransitioning ? "flex items-center justify-center" : "overflow-y-auto"}`,
|
|
29302
|
+
children: displayMessages.length === 0 && !isTransitioning ? (
|
|
29303
|
+
/* Centered welcome and input for new chat */
|
|
29304
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full max-w-3xl mx-auto px-4 sm:px-6 flex flex-col items-center justify-center space-y-12 -mt-16", children: [
|
|
29305
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
|
|
29306
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center mb-8", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-24 h-24 rounded-xl overflow-hidden shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
29307
|
+
"img",
|
|
29308
|
+
{
|
|
29309
|
+
src: axelProfilePng,
|
|
29310
|
+
alt: "Axel - AI Manufacturing Expert",
|
|
29311
|
+
className: "w-full h-full object-cover"
|
|
29312
|
+
}
|
|
29313
|
+
) }) }),
|
|
29314
|
+
/* @__PURE__ */ jsxRuntime.jsxs("h2", { className: "text-3xl font-semibold text-gray-900", children: [
|
|
29315
|
+
typedText,
|
|
29316
|
+
typedText.length < "Hi, I'm Axel - Your AI Supervisor".length && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "animate-pulse", children: "|" })
|
|
29317
|
+
] })
|
|
29318
|
+
] }),
|
|
29319
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full max-w-2xl", children: [
|
|
29320
|
+
activeThreadId && messages.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center mb-4", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
29321
|
+
"button",
|
|
29322
|
+
{
|
|
29323
|
+
onClick: handleNewThread,
|
|
29324
|
+
className: "inline-flex items-center gap-2 px-3 py-1.5 text-xs font-medium text-gray-500 hover:text-gray-700 hover:bg-gray-100 rounded-lg transition-colors",
|
|
29325
|
+
children: [
|
|
29326
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "w-3.5 h-3.5" }),
|
|
29327
|
+
"New conversation"
|
|
29328
|
+
]
|
|
29329
|
+
}
|
|
29330
|
+
) }),
|
|
29331
|
+
/* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, children: [
|
|
29332
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative bg-white rounded-3xl shadow-lg border border-gray-200 focus-within:border-gray-300 transition-all duration-200", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-end gap-2 p-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 relative", children: [
|
|
29333
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
29334
|
+
"textarea",
|
|
29335
|
+
{
|
|
29336
|
+
ref: textareaRef,
|
|
29337
|
+
value: inputValue,
|
|
29338
|
+
onChange: (e) => setInputValue(e.target.value),
|
|
29339
|
+
onKeyDown: handleKeyDown,
|
|
29340
|
+
placeholder: "Ask me about production optimization, quality metrics, or any manufacturing challenge...",
|
|
29341
|
+
className: "w-full resize-none bg-transparent px-2 py-2 pr-12 focus:outline-none placeholder-gray-500 text-gray-900 text-sm leading-relaxed",
|
|
29342
|
+
rows: 1,
|
|
29343
|
+
style: { minHeight: "24px", maxHeight: "120px" }
|
|
29344
|
+
}
|
|
29345
|
+
),
|
|
29346
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-2 bottom-2 flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
29347
|
+
"button",
|
|
29348
|
+
{
|
|
29349
|
+
type: "submit",
|
|
29350
|
+
disabled: !inputValue.trim() || isCurrentThreadLoading,
|
|
29351
|
+
className: "inline-flex items-center justify-center w-8 h-8 bg-gray-900 text-white rounded-full hover:bg-gray-800 transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus:ring-2 focus:ring-gray-500/20",
|
|
29352
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "w-4 h-4" })
|
|
29353
|
+
}
|
|
29354
|
+
) })
|
|
29355
|
+
] }) }) }),
|
|
29356
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center mt-2 text-xs text-gray-400", children: [
|
|
29357
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: isCurrentThreadLoading ? "You can type your next message while Axel responds" : "Press Enter to send \u2022 Shift+Enter for new line" }),
|
|
29358
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 ml-4", children: [
|
|
29359
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `w-1.5 h-1.5 rounded-full ${isCurrentThreadLoading ? "bg-orange-500" : "bg-green-500"}` }),
|
|
29360
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: isCurrentThreadLoading ? "Responding..." : "Connected" })
|
|
29361
|
+
] })
|
|
29362
|
+
] })
|
|
29363
|
+
] })
|
|
29364
|
+
] })
|
|
28658
29365
|
] })
|
|
28659
|
-
|
|
28660
|
-
|
|
28661
|
-
|
|
28662
|
-
|
|
28663
|
-
|
|
28664
|
-
|
|
28665
|
-
|
|
28666
|
-
|
|
28667
|
-
"
|
|
28668
|
-
|
|
28669
|
-
|
|
28670
|
-
|
|
28671
|
-
|
|
28672
|
-
|
|
28673
|
-
|
|
28674
|
-
|
|
28675
|
-
/* @__PURE__ */ jsxRuntime.
|
|
29366
|
+
) : isTransitioning ? (
|
|
29367
|
+
/* Transition state - show user message first, then thinking */
|
|
29368
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-4xl mx-auto px-4 sm:px-6 py-6 pb-32", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
|
|
29369
|
+
displayMessages.map((message, index) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
29370
|
+
"div",
|
|
29371
|
+
{
|
|
29372
|
+
className: `flex gap-4 ${message.role === "user" ? "justify-end" : "justify-start"}`,
|
|
29373
|
+
children: [
|
|
29374
|
+
message.role === "assistant" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-12 h-12 rounded-xl overflow-hidden shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
29375
|
+
"img",
|
|
29376
|
+
{
|
|
29377
|
+
src: axelProfilePng,
|
|
29378
|
+
alt: "Axel",
|
|
29379
|
+
className: "w-full h-full object-cover"
|
|
29380
|
+
}
|
|
29381
|
+
) }) }),
|
|
29382
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `max-w-none w-full group ${message.role === "user" ? "order-1" : ""}`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
28676
29383
|
"div",
|
|
28677
29384
|
{
|
|
28678
|
-
className: `relative px-5 py-4 rounded-2xl shadow-sm ${message.role === "user" ? "bg-blue-600 text-white
|
|
28679
|
-
children: [
|
|
28680
|
-
message.
|
|
28681
|
-
|
|
28682
|
-
|
|
28683
|
-
] }),
|
|
28684
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
28685
|
-
"div",
|
|
28686
|
-
{
|
|
28687
|
-
className: `prose prose-sm max-w-none ${message.role === "user" ? "text-white prose-headings:text-white prose-strong:text-white" : "text-gray-800 prose-headings:text-gray-900 prose-strong:text-gray-900"}`,
|
|
28688
|
-
dangerouslySetInnerHTML: {
|
|
28689
|
-
__html: message.role === "assistant" ? formatMessage(message.content) : message.content
|
|
28690
|
-
}
|
|
28691
|
-
}
|
|
28692
|
-
),
|
|
28693
|
-
message.role === "assistant" && !message.error && /* @__PURE__ */ jsxRuntime.jsx(
|
|
28694
|
-
"button",
|
|
28695
|
-
{
|
|
28696
|
-
onClick: () => copyToClipboard(message.content, message.id),
|
|
28697
|
-
className: "absolute top-3 right-3 opacity-0 group-hover:opacity-100 transition-opacity duration-200 p-1.5 hover:bg-gray-100 rounded-lg",
|
|
28698
|
-
title: "Copy message",
|
|
28699
|
-
children: copiedMessageId === message.id ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "w-4 h-4 text-green-600" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { className: "w-4 h-4 text-gray-500" })
|
|
28700
|
-
}
|
|
28701
|
-
)
|
|
28702
|
-
]
|
|
29385
|
+
className: `relative px-5 py-4 rounded-2xl shadow-sm ${message.role === "user" ? "bg-blue-600 text-white max-w-[85%] ml-auto" : "bg-white border border-gray-200/80 max-w-full"}`,
|
|
29386
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${message.role === "user" ? "text-white" : "text-gray-800"}`, children: [
|
|
29387
|
+
message.role === "assistant" ? renderAssistantContent(message.content) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "whitespace-pre-wrap leading-relaxed", children: message.content }),
|
|
29388
|
+
message.id === -1 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block w-0.5 h-4 bg-gray-400 animate-pulse ml-0.5" })
|
|
29389
|
+
] })
|
|
28703
29390
|
}
|
|
28704
|
-
)
|
|
28705
|
-
|
|
28706
|
-
|
|
28707
|
-
|
|
28708
|
-
|
|
28709
|
-
|
|
29391
|
+
) })
|
|
29392
|
+
]
|
|
29393
|
+
},
|
|
29394
|
+
message.id === -1 ? `streaming-${currentStreaming.message.length}` : `${message.id}-${index}`
|
|
29395
|
+
)),
|
|
29396
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-4 justify-start", children: [
|
|
29397
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-12 h-12 rounded-xl overflow-hidden shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
29398
|
+
"img",
|
|
29399
|
+
{
|
|
29400
|
+
src: axelProfilePng,
|
|
29401
|
+
alt: "Axel",
|
|
29402
|
+
className: "w-full h-full object-cover"
|
|
29403
|
+
}
|
|
29404
|
+
) }) }),
|
|
29405
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-white border border-gray-200/80 px-5 py-4 rounded-2xl shadow-sm max-w-full", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
29406
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex space-x-1", children: [
|
|
29407
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-bounce" }),
|
|
29408
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-bounce", style: { animationDelay: "0.1s" } }),
|
|
29409
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-bounce", style: { animationDelay: "0.2s" } })
|
|
29410
|
+
] }),
|
|
29411
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-600 text-sm", children: "Axel is thinking..." })
|
|
29412
|
+
] }) })
|
|
29413
|
+
] })
|
|
29414
|
+
] }) })
|
|
29415
|
+
) : (
|
|
29416
|
+
/* Regular chat view with messages */
|
|
29417
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-4xl mx-auto px-4 sm:px-6 py-6 pb-32", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
|
|
29418
|
+
displayMessages.map((message, index) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
29419
|
+
"div",
|
|
29420
|
+
{
|
|
29421
|
+
className: `flex gap-4 ${message.role === "user" ? "justify-end" : "justify-start"}`,
|
|
29422
|
+
children: [
|
|
29423
|
+
message.role === "assistant" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-12 h-12 rounded-xl overflow-hidden shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
29424
|
+
"img",
|
|
29425
|
+
{
|
|
29426
|
+
src: axelProfilePng,
|
|
29427
|
+
alt: "Axel",
|
|
29428
|
+
className: "w-full h-full object-cover"
|
|
29429
|
+
}
|
|
29430
|
+
) }) }),
|
|
29431
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `max-w-none w-full group ${message.role === "user" ? "order-1" : ""}`, children: [
|
|
29432
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
29433
|
+
"div",
|
|
29434
|
+
{
|
|
29435
|
+
className: `relative px-5 py-4 rounded-2xl shadow-sm ${message.role === "user" ? "bg-blue-600 text-white max-w-[85%] ml-auto" : "bg-white border border-gray-200/80 max-w-full"}`,
|
|
29436
|
+
children: [
|
|
29437
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${message.role === "user" ? "text-white" : "text-gray-800"}`, children: [
|
|
29438
|
+
message.role === "assistant" ? renderAssistantContent(message.content) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "whitespace-pre-wrap leading-relaxed", children: message.content }),
|
|
29439
|
+
message.id === -1 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block w-0.5 h-4 bg-gray-400 animate-pulse ml-0.5" })
|
|
29440
|
+
] }),
|
|
29441
|
+
message.role === "assistant" && message.id !== -1 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
29442
|
+
"button",
|
|
29443
|
+
{
|
|
29444
|
+
onClick: () => copyToClipboard(message.content, message.id.toString()),
|
|
29445
|
+
className: "absolute top-3 right-3 opacity-0 group-hover:opacity-100 transition-opacity duration-200 p-1.5 hover:bg-gray-100 rounded-lg",
|
|
29446
|
+
title: "Copy message",
|
|
29447
|
+
children: copiedMessageId === message.id.toString() ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "w-4 h-4 text-green-600" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { className: "w-4 h-4 text-gray-500" })
|
|
29448
|
+
}
|
|
29449
|
+
),
|
|
29450
|
+
message.reasoning && /* @__PURE__ */ jsxRuntime.jsxs("details", { className: "mt-3 pt-3 border-t border-gray-200", children: [
|
|
29451
|
+
/* @__PURE__ */ jsxRuntime.jsx("summary", { className: "cursor-pointer text-sm text-gray-600 hover:text-gray-800", children: "View reasoning" }),
|
|
29452
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 text-sm text-gray-600", children: message.reasoning })
|
|
29453
|
+
] })
|
|
29454
|
+
]
|
|
29455
|
+
}
|
|
29456
|
+
),
|
|
29457
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `mt-2 flex items-center gap-2 text-xs text-gray-400 ${message.role === "user" ? "justify-end" : "justify-start"}`, children: [
|
|
29458
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: formatTime2(message.created_at) }),
|
|
29459
|
+
message.role === "assistant" && message.id !== -1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
29460
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-1 h-1 bg-gray-300 rounded-full" }),
|
|
29461
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Axel" })
|
|
29462
|
+
] })
|
|
28710
29463
|
] })
|
|
28711
29464
|
] })
|
|
29465
|
+
]
|
|
29466
|
+
},
|
|
29467
|
+
message.id === -1 ? `streaming-${currentStreaming.message.length}` : `${message.id}-${index}`
|
|
29468
|
+
)),
|
|
29469
|
+
lastError && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-4 justify-start", children: [
|
|
29470
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-12 h-12 rounded-xl bg-red-100 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { className: "w-6 h-6 text-red-600" }) }) }),
|
|
29471
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-red-50 border border-red-200 px-5 py-4 rounded-2xl shadow-sm max-w-full", children: [
|
|
29472
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-red-800 text-sm", children: lastError }),
|
|
29473
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
29474
|
+
"button",
|
|
29475
|
+
{
|
|
29476
|
+
onClick: () => setLastError(null),
|
|
29477
|
+
className: "mt-2 text-xs text-red-600 hover:text-red-800 underline",
|
|
29478
|
+
children: "Dismiss"
|
|
29479
|
+
}
|
|
29480
|
+
)
|
|
29481
|
+
] })
|
|
29482
|
+
] }),
|
|
29483
|
+
isCurrentThreadLoading && !currentStreaming.message && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-4 justify-start", children: [
|
|
29484
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-12 h-12 rounded-xl overflow-hidden shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
29485
|
+
"img",
|
|
29486
|
+
{
|
|
29487
|
+
src: axelProfilePng,
|
|
29488
|
+
alt: "Axel",
|
|
29489
|
+
className: "w-full h-full object-cover"
|
|
29490
|
+
}
|
|
29491
|
+
) }) }),
|
|
29492
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-white border border-gray-200/80 px-5 py-4 rounded-2xl shadow-sm max-w-full", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
29493
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex space-x-1", children: [
|
|
29494
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-bounce" }),
|
|
29495
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-bounce", style: { animationDelay: "0.1s" } }),
|
|
29496
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-bounce", style: { animationDelay: "0.2s" } })
|
|
28712
29497
|
] }),
|
|
28713
|
-
|
|
28714
|
-
]
|
|
28715
|
-
},
|
|
28716
|
-
|
|
28717
|
-
))
|
|
28718
|
-
|
|
28719
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-12 h-12 rounded-xl overflow-hidden shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
28720
|
-
"img",
|
|
28721
|
-
{
|
|
28722
|
-
src: axelProfilePng,
|
|
28723
|
-
alt: "Axel",
|
|
28724
|
-
className: "w-full h-full object-cover"
|
|
28725
|
-
}
|
|
28726
|
-
) }) }),
|
|
28727
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-white border border-gray-200/80 px-5 py-4 rounded-2xl shadow-sm max-w-[75%]", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
28728
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex space-x-1", children: [
|
|
28729
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-bounce" }),
|
|
28730
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-bounce", style: { animationDelay: "0.1s" } }),
|
|
28731
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-bounce", style: { animationDelay: "0.2s" } })
|
|
28732
|
-
] }),
|
|
28733
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-600 text-sm", children: "Axel is analyzing your request..." })
|
|
28734
|
-
] }) })
|
|
28735
|
-
] }),
|
|
28736
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { ref: messagesEndRef })
|
|
28737
|
-
] })
|
|
28738
|
-
] })
|
|
28739
|
-
}
|
|
28740
|
-
),
|
|
28741
|
-
/* @__PURE__ */ jsxRuntime.jsx("footer", { className: "flex-shrink-0 border-t border-gray-200 bg-white sticky bottom-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-5xl mx-auto p-4 sm:p-6", children: [
|
|
28742
|
-
messages.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center mb-4", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
28743
|
-
"button",
|
|
28744
|
-
{
|
|
28745
|
-
onClick: clearConversation,
|
|
28746
|
-
className: "inline-flex items-center gap-2 px-3 py-1.5 text-xs font-medium text-gray-500 hover:text-gray-700 hover:bg-gray-100 rounded-lg transition-colors",
|
|
28747
|
-
children: [
|
|
28748
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "w-3.5 h-3.5" }),
|
|
28749
|
-
"Clear conversation"
|
|
28750
|
-
]
|
|
29498
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-600 text-sm", children: "Axel is thinking..." })
|
|
29499
|
+
] }) })
|
|
29500
|
+
] }),
|
|
29501
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { ref: messagesEndRef })
|
|
29502
|
+
] }) })
|
|
29503
|
+
)
|
|
28751
29504
|
}
|
|
28752
|
-
)
|
|
28753
|
-
/* @__PURE__ */ jsxRuntime.
|
|
28754
|
-
/* @__PURE__ */ jsxRuntime.
|
|
28755
|
-
|
|
28756
|
-
|
|
28757
|
-
|
|
28758
|
-
|
|
28759
|
-
|
|
28760
|
-
|
|
28761
|
-
|
|
28762
|
-
|
|
28763
|
-
|
|
28764
|
-
|
|
28765
|
-
|
|
28766
|
-
|
|
28767
|
-
|
|
28768
|
-
}
|
|
28769
|
-
),
|
|
28770
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-3 right-3 flex items-center gap-2", children: inputValue.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-gray-400 font-mono", children: inputValue.length }) })
|
|
28771
|
-
] }),
|
|
28772
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
28773
|
-
"button",
|
|
29505
|
+
),
|
|
29506
|
+
(displayMessages.length > 0 || isTransitioning) && /* @__PURE__ */ jsxRuntime.jsx("footer", { className: "fixed bottom-0 left-0 right-0 bg-gradient-to-t from-gray-50/50 to-transparent pointer-events-none", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-4xl mx-auto p-4 sm:p-6 pointer-events-auto", children: [
|
|
29507
|
+
activeThreadId && messages.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center mb-4", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
29508
|
+
"button",
|
|
29509
|
+
{
|
|
29510
|
+
onClick: handleNewThread,
|
|
29511
|
+
className: "inline-flex items-center gap-2 px-3 py-1.5 text-xs font-medium text-gray-500 hover:text-gray-700 hover:bg-gray-100 rounded-lg transition-colors",
|
|
29512
|
+
children: [
|
|
29513
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.RefreshCw, { className: "w-3.5 h-3.5" }),
|
|
29514
|
+
"New conversation"
|
|
29515
|
+
]
|
|
29516
|
+
}
|
|
29517
|
+
) }),
|
|
29518
|
+
/* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, children: [
|
|
29519
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
29520
|
+
"div",
|
|
28774
29521
|
{
|
|
28775
|
-
|
|
28776
|
-
|
|
28777
|
-
|
|
28778
|
-
|
|
28779
|
-
|
|
28780
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
28781
|
-
|
|
29522
|
+
className: `relative bg-white rounded-3xl shadow-lg border border-gray-200 focus-within:border-gray-300 transition-all duration-200 ${isTransitioning ? "animate-slide-down" : ""}`,
|
|
29523
|
+
style: isTransitioning ? {
|
|
29524
|
+
animation: "slideDown 0.8s cubic-bezier(0.4, 0, 0.2, 1) forwards"
|
|
29525
|
+
} : {},
|
|
29526
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-end gap-2 p-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 relative", children: [
|
|
29527
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
29528
|
+
"textarea",
|
|
29529
|
+
{
|
|
29530
|
+
ref: textareaRef,
|
|
29531
|
+
value: inputValue,
|
|
29532
|
+
onChange: (e) => setInputValue(e.target.value),
|
|
29533
|
+
onKeyDown: handleKeyDown,
|
|
29534
|
+
placeholder: "Ask me about production optimization, quality metrics, or any manufacturing challenge...",
|
|
29535
|
+
className: "w-full resize-none bg-transparent px-2 py-2 pr-12 focus:outline-none placeholder-gray-500 text-gray-900 text-sm leading-relaxed",
|
|
29536
|
+
rows: 1,
|
|
29537
|
+
style: { minHeight: "24px", maxHeight: "120px" }
|
|
29538
|
+
}
|
|
29539
|
+
),
|
|
29540
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-2 bottom-2 flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
29541
|
+
"button",
|
|
29542
|
+
{
|
|
29543
|
+
type: "submit",
|
|
29544
|
+
disabled: !inputValue.trim() || isCurrentThreadLoading,
|
|
29545
|
+
className: "inline-flex items-center justify-center w-8 h-8 bg-gray-900 text-white rounded-full hover:bg-gray-800 transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus:ring-2 focus:ring-gray-500/20",
|
|
29546
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "w-4 h-4" })
|
|
29547
|
+
}
|
|
29548
|
+
) })
|
|
29549
|
+
] }) })
|
|
28782
29550
|
}
|
|
28783
|
-
)
|
|
28784
|
-
|
|
28785
|
-
|
|
28786
|
-
|
|
28787
|
-
|
|
28788
|
-
|
|
28789
|
-
|
|
28790
|
-
] })
|
|
29551
|
+
),
|
|
29552
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center mt-2 text-xs text-gray-400", children: [
|
|
29553
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: isCurrentThreadLoading ? "You can type your next message while Axel responds" : "Press Enter to send \u2022 Shift+Enter for new line" }),
|
|
29554
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 ml-4", children: [
|
|
29555
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `w-1.5 h-1.5 rounded-full ${isCurrentThreadLoading ? "bg-orange-500" : "bg-green-500"}` }),
|
|
29556
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: isCurrentThreadLoading ? "Responding..." : "Connected" })
|
|
29557
|
+
] })
|
|
29558
|
+
] })
|
|
28791
29559
|
] })
|
|
28792
|
-
] })
|
|
28793
|
-
] })
|
|
29560
|
+
] }) })
|
|
29561
|
+
] }),
|
|
29562
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `${isSidebarOpen ? "w-80" : "w-0"} transition-all duration-300 overflow-hidden flex-shrink-0 border-l border-gray-200 h-screen fixed right-0 top-0 z-20`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
29563
|
+
ThreadSidebar,
|
|
29564
|
+
{
|
|
29565
|
+
activeThreadId,
|
|
29566
|
+
onSelectThread: setActiveThreadId,
|
|
29567
|
+
onNewThread: handleNewThread,
|
|
29568
|
+
className: "h-full"
|
|
29569
|
+
}
|
|
29570
|
+
) })
|
|
28794
29571
|
] });
|
|
28795
29572
|
};
|
|
28796
29573
|
var AIAgentView_default = AIAgentView;
|
|
@@ -31239,10 +32016,7 @@ var ShiftsView = ({
|
|
|
31239
32016
|
}
|
|
31240
32017
|
),
|
|
31241
32018
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex flex-col items-center", children: [
|
|
31242
|
-
/* @__PURE__ */ jsxRuntime.
|
|
31243
|
-
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl sm:text-2xl md:text-3xl font-bold text-gray-800 tracking-tight leading-none", children: "Shift Management" }),
|
|
31244
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 w-2 rounded-full bg-blue-500 animate-pulse ring-2 ring-blue-500/30" })
|
|
31245
|
-
] }),
|
|
32019
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl sm:text-2xl md:text-3xl font-bold text-gray-800 tracking-tight leading-none", children: "Shift Management" }) }),
|
|
31246
32020
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center mt-1", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-gray-500", children: /* @__PURE__ */ jsxRuntime.jsx(ISTTimer_default, {}) }) })
|
|
31247
32021
|
] }),
|
|
31248
32022
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-0 w-24" })
|
|
@@ -33543,6 +34317,131 @@ var S3Service = class {
|
|
|
33543
34317
|
}
|
|
33544
34318
|
}
|
|
33545
34319
|
};
|
|
34320
|
+
|
|
34321
|
+
// src/lib/api/optifye-agent.ts
|
|
34322
|
+
var OPTIFYE_API_URL = "https://optifye-agent-production.up.railway.app";
|
|
34323
|
+
var OptifyeAgentClient = class {
|
|
34324
|
+
constructor(apiUrl = OPTIFYE_API_URL) {
|
|
34325
|
+
this.apiUrl = apiUrl;
|
|
34326
|
+
}
|
|
34327
|
+
/**
|
|
34328
|
+
* Call Optifye Agent for manufacturing analysis
|
|
34329
|
+
*/
|
|
34330
|
+
async getManufacturingInsights(userQuestion, lineId, shiftId, companyId, context) {
|
|
34331
|
+
try {
|
|
34332
|
+
const requestData = {
|
|
34333
|
+
prompt: userQuestion,
|
|
34334
|
+
line_id: lineId,
|
|
34335
|
+
shift_id: shiftId,
|
|
34336
|
+
company_id: companyId
|
|
34337
|
+
};
|
|
34338
|
+
if (context) {
|
|
34339
|
+
requestData.context = context;
|
|
34340
|
+
}
|
|
34341
|
+
console.log("[OptifyeAgent] Sending request:", requestData);
|
|
34342
|
+
const response = await fetch(`${this.apiUrl}/api/custom-analysis`, {
|
|
34343
|
+
method: "POST",
|
|
34344
|
+
headers: {
|
|
34345
|
+
"Content-Type": "application/json"
|
|
34346
|
+
},
|
|
34347
|
+
body: JSON.stringify(requestData),
|
|
34348
|
+
signal: AbortSignal.timeout(6e4)
|
|
34349
|
+
// 60 second timeout
|
|
34350
|
+
});
|
|
34351
|
+
const responseText = await response.text();
|
|
34352
|
+
console.log("[OptifyeAgent] Response status:", response.status);
|
|
34353
|
+
console.log("[OptifyeAgent] Response text:", responseText);
|
|
34354
|
+
let result;
|
|
34355
|
+
try {
|
|
34356
|
+
result = JSON.parse(responseText);
|
|
34357
|
+
} catch (parseError) {
|
|
34358
|
+
console.error("[OptifyeAgent] Failed to parse response as JSON:", parseError);
|
|
34359
|
+
if (responseText.includes("'Agent' object has no attribute")) {
|
|
34360
|
+
return {
|
|
34361
|
+
success: false,
|
|
34362
|
+
error: "Server error: The AI agent service is experiencing issues. Please try again later or contact support."
|
|
34363
|
+
};
|
|
34364
|
+
}
|
|
34365
|
+
return {
|
|
34366
|
+
success: false,
|
|
34367
|
+
error: `Invalid response format from server: ${responseText.substring(0, 200)}`
|
|
34368
|
+
};
|
|
34369
|
+
}
|
|
34370
|
+
if (response.ok) {
|
|
34371
|
+
return {
|
|
34372
|
+
success: result.success ?? true,
|
|
34373
|
+
analysis: result.analysis || result.response || result.message || result.data,
|
|
34374
|
+
timestamp: result.timestamp,
|
|
34375
|
+
error: result.error
|
|
34376
|
+
};
|
|
34377
|
+
} else {
|
|
34378
|
+
const errorMsg = result.error || result.message || `API request failed: ${response.status}`;
|
|
34379
|
+
console.error("[OptifyeAgent] API error:", errorMsg);
|
|
34380
|
+
if (errorMsg.includes("'Agent' object has no attribute")) {
|
|
34381
|
+
return {
|
|
34382
|
+
success: false,
|
|
34383
|
+
error: "The AI service is currently being updated. Please try again in a few moments."
|
|
34384
|
+
};
|
|
34385
|
+
}
|
|
34386
|
+
return {
|
|
34387
|
+
success: false,
|
|
34388
|
+
error: errorMsg
|
|
34389
|
+
};
|
|
34390
|
+
}
|
|
34391
|
+
} catch (error) {
|
|
34392
|
+
const errorMsg = error instanceof Error ? `Failed to connect to Optifye Agent: ${error.message}` : "Failed to connect to Optifye Agent";
|
|
34393
|
+
console.error("[OptifyeAgent] Request failed:", error);
|
|
34394
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
34395
|
+
return {
|
|
34396
|
+
success: false,
|
|
34397
|
+
error: "Request timed out. The AI agent is taking too long to respond. Please try again."
|
|
34398
|
+
};
|
|
34399
|
+
}
|
|
34400
|
+
return {
|
|
34401
|
+
success: false,
|
|
34402
|
+
error: errorMsg
|
|
34403
|
+
};
|
|
34404
|
+
}
|
|
34405
|
+
}
|
|
34406
|
+
/**
|
|
34407
|
+
* Check if Optifye Agent API is healthy
|
|
34408
|
+
*/
|
|
34409
|
+
async checkHealth() {
|
|
34410
|
+
try {
|
|
34411
|
+
const response = await fetch(`${this.apiUrl}/health`, {
|
|
34412
|
+
signal: AbortSignal.timeout(1e4)
|
|
34413
|
+
// 10 second timeout
|
|
34414
|
+
});
|
|
34415
|
+
if (response.ok) {
|
|
34416
|
+
const healthData = await response.json();
|
|
34417
|
+
return healthData.status === "healthy";
|
|
34418
|
+
}
|
|
34419
|
+
return false;
|
|
34420
|
+
} catch (error) {
|
|
34421
|
+
console.error("[OptifyeAgent] Health check failed:", error);
|
|
34422
|
+
return false;
|
|
34423
|
+
}
|
|
34424
|
+
}
|
|
34425
|
+
};
|
|
34426
|
+
var optifyeAgentClient = new OptifyeAgentClient();
|
|
34427
|
+
async function getManufacturingInsights(userQuestion, lineId, shiftId, companyId, context) {
|
|
34428
|
+
if (!userQuestion || !userQuestion.trim()) {
|
|
34429
|
+
return {
|
|
34430
|
+
success: false,
|
|
34431
|
+
error: "Please provide a question"
|
|
34432
|
+
};
|
|
34433
|
+
}
|
|
34434
|
+
if (!lineId || !companyId) {
|
|
34435
|
+
console.warn("[OptifyeAgent] Missing required IDs:", { lineId, companyId });
|
|
34436
|
+
}
|
|
34437
|
+
return optifyeAgentClient.getManufacturingInsights(
|
|
34438
|
+
userQuestion,
|
|
34439
|
+
lineId,
|
|
34440
|
+
shiftId,
|
|
34441
|
+
companyId,
|
|
34442
|
+
context
|
|
34443
|
+
);
|
|
34444
|
+
}
|
|
33546
34445
|
function createStreamProxyHandler(config) {
|
|
33547
34446
|
const cloudFrontDomain = config?.cloudFrontDomain || "https://d1eiob0chi5jw.cloudfront.net";
|
|
33548
34447
|
return async function handler(req, res) {
|
|
@@ -33726,6 +34625,7 @@ exports.ProfileView = ProfileView_default;
|
|
|
33726
34625
|
exports.RegistryProvider = RegistryProvider;
|
|
33727
34626
|
exports.S3Service = S3Service;
|
|
33728
34627
|
exports.SOPComplianceChart = SOPComplianceChart;
|
|
34628
|
+
exports.SSEChatClient = SSEChatClient;
|
|
33729
34629
|
exports.Select = Select;
|
|
33730
34630
|
exports.SelectContent = SelectContent;
|
|
33731
34631
|
exports.SelectGroup = SelectGroup;
|
|
@@ -33744,6 +34644,7 @@ exports.Skeleton = Skeleton;
|
|
|
33744
34644
|
exports.SupabaseProvider = SupabaseProvider;
|
|
33745
34645
|
exports.TargetWorkspaceGrid = TargetWorkspaceGrid;
|
|
33746
34646
|
exports.TargetsView = TargetsView_default;
|
|
34647
|
+
exports.ThreadSidebar = ThreadSidebar;
|
|
33747
34648
|
exports.TimeDisplay = TimeDisplay_default;
|
|
33748
34649
|
exports.VideoCard = VideoCard;
|
|
33749
34650
|
exports.VideoGridView = VideoGridView;
|
|
@@ -33777,12 +34678,14 @@ exports.createStreamProxyHandler = createStreamProxyHandler;
|
|
|
33777
34678
|
exports.createSupabaseClient = createSupabaseClient;
|
|
33778
34679
|
exports.createThrottledReload = createThrottledReload;
|
|
33779
34680
|
exports.dashboardService = dashboardService;
|
|
34681
|
+
exports.deleteThread = deleteThread;
|
|
33780
34682
|
exports.formatDateInZone = formatDateInZone;
|
|
33781
34683
|
exports.formatDateTimeInZone = formatDateTimeInZone;
|
|
33782
34684
|
exports.formatISTDate = formatISTDate;
|
|
33783
34685
|
exports.formatIdleTime = formatIdleTime;
|
|
33784
34686
|
exports.formatTimeInZone = formatTimeInZone;
|
|
33785
34687
|
exports.fromUrlFriendlyName = fromUrlFriendlyName;
|
|
34688
|
+
exports.getAllThreadMessages = getAllThreadMessages;
|
|
33786
34689
|
exports.getAllWorkspaceDisplayNamesAsync = getAllWorkspaceDisplayNamesAsync;
|
|
33787
34690
|
exports.getAnonClient = getAnonClient;
|
|
33788
34691
|
exports.getCameraNumber = getCameraNumber;
|
|
@@ -33803,6 +34706,9 @@ exports.getS3VideoSrc = getS3VideoSrc;
|
|
|
33803
34706
|
exports.getShortWorkspaceDisplayName = getShortWorkspaceDisplayName;
|
|
33804
34707
|
exports.getShortWorkspaceDisplayNameAsync = getShortWorkspaceDisplayNameAsync;
|
|
33805
34708
|
exports.getStoredWorkspaceMappings = getStoredWorkspaceMappings;
|
|
34709
|
+
exports.getThreadMessages = getThreadMessages;
|
|
34710
|
+
exports.getUserThreads = getUserThreads;
|
|
34711
|
+
exports.getUserThreadsPaginated = getUserThreadsPaginated;
|
|
33806
34712
|
exports.getWorkspaceDisplayName = getWorkspaceDisplayName;
|
|
33807
34713
|
exports.getWorkspaceDisplayNameAsync = getWorkspaceDisplayNameAsync;
|
|
33808
34714
|
exports.getWorkspaceDisplayNamesMap = getWorkspaceDisplayNamesMap;
|
|
@@ -33834,6 +34740,7 @@ exports.throttledReloadDashboard = throttledReloadDashboard;
|
|
|
33834
34740
|
exports.toUrlFriendlyName = toUrlFriendlyName;
|
|
33835
34741
|
exports.trackCoreEvent = trackCoreEvent;
|
|
33836
34742
|
exports.trackCorePageView = trackCorePageView;
|
|
34743
|
+
exports.updateThreadTitle = updateThreadTitle;
|
|
33837
34744
|
exports.useAnalyticsConfig = useAnalyticsConfig;
|
|
33838
34745
|
exports.useAuth = useAuth;
|
|
33839
34746
|
exports.useAuthConfig = useAuthConfig;
|
|
@@ -33857,6 +34764,7 @@ exports.useLineDetailedMetrics = useLineDetailedMetrics;
|
|
|
33857
34764
|
exports.useLineKPIs = useLineKPIs;
|
|
33858
34765
|
exports.useLineMetrics = useLineMetrics;
|
|
33859
34766
|
exports.useLineWorkspaceMetrics = useLineWorkspaceMetrics;
|
|
34767
|
+
exports.useMessages = useMessages;
|
|
33860
34768
|
exports.useMetrics = useMetrics;
|
|
33861
34769
|
exports.useNavigation = useNavigation;
|
|
33862
34770
|
exports.useOverrides = useOverrides;
|
|
@@ -33870,6 +34778,7 @@ exports.useSupabaseClient = useSupabaseClient;
|
|
|
33870
34778
|
exports.useTargets = useTargets;
|
|
33871
34779
|
exports.useTheme = useTheme;
|
|
33872
34780
|
exports.useThemeConfig = useThemeConfig;
|
|
34781
|
+
exports.useThreads = useThreads;
|
|
33873
34782
|
exports.useWorkspaceConfig = useWorkspaceConfig;
|
|
33874
34783
|
exports.useWorkspaceDetailedMetrics = useWorkspaceDetailedMetrics;
|
|
33875
34784
|
exports.useWorkspaceDisplayName = useWorkspaceDisplayName;
|