@hef2024/llmasaservice-ui 0.24.4 → 0.24.6
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.css +24 -0
- package/dist/index.d.mts +27 -14
- package/dist/index.d.ts +27 -14
- package/dist/index.js +442 -132
- package/dist/index.mjs +442 -132
- package/index.ts +8 -1
- package/package.json +1 -1
- package/src/AIAgentPanel.tsx +213 -41
- package/src/AIChatPanel.css +14 -0
- package/src/AIChatPanel.tsx +333 -129
- package/src/ChatPanel.css +15 -1
- package/src/ChatPanel.tsx +45 -38
- package/src/components/ui/ThinkingBlock.tsx +25 -1
package/dist/index.js
CHANGED
|
@@ -624,6 +624,25 @@ var SearchingIcon = () => /* @__PURE__ */ import_react10.default.createElement(
|
|
|
624
624
|
/* @__PURE__ */ import_react10.default.createElement("circle", { cx: "11", cy: "11", r: "8" }),
|
|
625
625
|
/* @__PURE__ */ import_react10.default.createElement("path", { d: "m21 21-4.3-4.3" })
|
|
626
626
|
);
|
|
627
|
+
var PlanningIcon = () => /* @__PURE__ */ import_react10.default.createElement(
|
|
628
|
+
"svg",
|
|
629
|
+
{
|
|
630
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
631
|
+
viewBox: "0 0 24 24",
|
|
632
|
+
fill: "none",
|
|
633
|
+
stroke: "currentColor",
|
|
634
|
+
strokeWidth: "2",
|
|
635
|
+
strokeLinecap: "round",
|
|
636
|
+
strokeLinejoin: "round",
|
|
637
|
+
className: "thinking-block__icon"
|
|
638
|
+
},
|
|
639
|
+
/* @__PURE__ */ import_react10.default.createElement("path", { d: "M9 5h11" }),
|
|
640
|
+
/* @__PURE__ */ import_react10.default.createElement("path", { d: "M9 12h11" }),
|
|
641
|
+
/* @__PURE__ */ import_react10.default.createElement("path", { d: "M9 19h11" }),
|
|
642
|
+
/* @__PURE__ */ import_react10.default.createElement("path", { d: "m4 5 1.5 1.5L7 4.5" }),
|
|
643
|
+
/* @__PURE__ */ import_react10.default.createElement("path", { d: "m4 12 1.5 1.5L7 11.5" }),
|
|
644
|
+
/* @__PURE__ */ import_react10.default.createElement("path", { d: "m4 19 1.5 1.5L7 18.5" })
|
|
645
|
+
);
|
|
627
646
|
var ChevronIcon = ({ isCollapsed }) => /* @__PURE__ */ import_react10.default.createElement(
|
|
628
647
|
"svg",
|
|
629
648
|
{
|
|
@@ -646,6 +665,8 @@ var getIcon = (type) => {
|
|
|
646
665
|
return /* @__PURE__ */ import_react10.default.createElement(ReasoningIcon, null);
|
|
647
666
|
case "searching":
|
|
648
667
|
return /* @__PURE__ */ import_react10.default.createElement(SearchingIcon, null);
|
|
668
|
+
case "planning":
|
|
669
|
+
return /* @__PURE__ */ import_react10.default.createElement(PlanningIcon, null);
|
|
649
670
|
}
|
|
650
671
|
};
|
|
651
672
|
var getDefaultTitle = (type) => {
|
|
@@ -656,6 +677,8 @@ var getDefaultTitle = (type) => {
|
|
|
656
677
|
return "Reasoning";
|
|
657
678
|
case "searching":
|
|
658
679
|
return "Searching";
|
|
680
|
+
case "planning":
|
|
681
|
+
return "Planning";
|
|
659
682
|
}
|
|
660
683
|
};
|
|
661
684
|
var ThinkingBlock = ({
|
|
@@ -1414,46 +1437,51 @@ var ChatPanel = ({
|
|
|
1414
1437
|
const urlToFetch = `${publicAPIUrl}/tools/${encodeURIComponent(
|
|
1415
1438
|
m.url
|
|
1416
1439
|
)}`;
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
if (!response2.ok) {
|
|
1426
|
-
console.error(
|
|
1427
|
-
`Error fetching tools from ${m.url}: ${response2.status} ${response2.statusText}`
|
|
1428
|
-
);
|
|
1429
|
-
const errorBody = yield response2.text();
|
|
1430
|
-
console.error(`Error body: ${errorBody}`);
|
|
1431
|
-
throw new Error(
|
|
1432
|
-
`HTTP ${response2.status}: ${response2.statusText}`
|
|
1433
|
-
);
|
|
1434
|
-
}
|
|
1435
|
-
const toolsFromServer = yield response2.json();
|
|
1436
|
-
if (Array.isArray(toolsFromServer)) {
|
|
1437
|
-
return toolsFromServer.map((tool) => __spreadProps(__spreadValues({}, tool), {
|
|
1438
|
-
url: m.url,
|
|
1439
|
-
accessToken: m.accessToken || "",
|
|
1440
|
-
headers: requestHeaders
|
|
1441
|
-
}));
|
|
1442
|
-
} else {
|
|
1443
|
-
return [];
|
|
1444
|
-
}
|
|
1445
|
-
} catch (fetchError) {
|
|
1440
|
+
const requestHeaders = yield buildMcpRequestHeaders({
|
|
1441
|
+
phase: "list",
|
|
1442
|
+
mcpServer: m
|
|
1443
|
+
});
|
|
1444
|
+
const response2 = yield fetch(urlToFetch, {
|
|
1445
|
+
headers: requestHeaders
|
|
1446
|
+
});
|
|
1447
|
+
if (!response2.ok) {
|
|
1446
1448
|
console.error(
|
|
1447
|
-
`
|
|
1448
|
-
fetchError
|
|
1449
|
+
`Error fetching tools from ${m.url}: ${response2.status} ${response2.statusText}`
|
|
1449
1450
|
);
|
|
1450
|
-
|
|
1451
|
+
const errorBody = yield response2.text();
|
|
1452
|
+
console.error(`Error body: ${errorBody}`);
|
|
1453
|
+
throw new Error(
|
|
1454
|
+
`HTTP ${response2.status}: ${response2.statusText}`
|
|
1455
|
+
);
|
|
1456
|
+
}
|
|
1457
|
+
const toolsFromServer = yield response2.json();
|
|
1458
|
+
if (Array.isArray(toolsFromServer)) {
|
|
1459
|
+
return toolsFromServer.map((tool) => __spreadProps(__spreadValues({}, tool), {
|
|
1460
|
+
url: m.url,
|
|
1461
|
+
accessToken: m.accessToken || "",
|
|
1462
|
+
headers: requestHeaders
|
|
1463
|
+
}));
|
|
1451
1464
|
}
|
|
1465
|
+
return [];
|
|
1452
1466
|
}));
|
|
1453
|
-
const
|
|
1454
|
-
const allTools =
|
|
1467
|
+
const settledResults = yield Promise.allSettled(fetchPromises);
|
|
1468
|
+
const allTools = settledResults.flatMap((result, index) => {
|
|
1469
|
+
if (result.status === "fulfilled") {
|
|
1470
|
+
return result.value;
|
|
1471
|
+
}
|
|
1472
|
+
const server = mcpServers == null ? void 0 : mcpServers[index];
|
|
1473
|
+
const failingUrl = typeof (server == null ? void 0 : server.url) === "string" ? server.url : `mcp[${index}]`;
|
|
1474
|
+
console.error(
|
|
1475
|
+
`Network or parsing error fetching tools from ${failingUrl}:`,
|
|
1476
|
+
result.reason
|
|
1477
|
+
);
|
|
1478
|
+
return [];
|
|
1479
|
+
});
|
|
1480
|
+
const failedCount = settledResults.filter(
|
|
1481
|
+
(result) => result.status === "rejected"
|
|
1482
|
+
).length;
|
|
1455
1483
|
setToolList(allTools);
|
|
1456
|
-
setToolsFetchError(
|
|
1484
|
+
setToolsFetchError(failedCount > 0 && allTools.length === 0);
|
|
1457
1485
|
} catch (error2) {
|
|
1458
1486
|
console.error(
|
|
1459
1487
|
"An error occurred while processing tool fetches:",
|
|
@@ -4797,6 +4825,87 @@ var buildThinkingBlockMarker = (type, signature) => {
|
|
|
4797
4825
|
normalizedSignature
|
|
4798
4826
|
)}${INLINE_THINKING_MARKER_SUFFIX}`;
|
|
4799
4827
|
};
|
|
4828
|
+
var PLAN_STEP_REGEX = /^\s*\[plan-step\]\s*([a-zA-Z_-]+)\s*:\s*(.+?)\s*$/i;
|
|
4829
|
+
var normalizePlanningStatus = (value) => {
|
|
4830
|
+
const normalized = String(value || "").trim().toLowerCase();
|
|
4831
|
+
if (normalized === "doing" || normalized === "in_progress" || normalized === "in-progress") {
|
|
4832
|
+
return "doing";
|
|
4833
|
+
}
|
|
4834
|
+
if (normalized === "done" || normalized === "completed") {
|
|
4835
|
+
return "done";
|
|
4836
|
+
}
|
|
4837
|
+
return "todo";
|
|
4838
|
+
};
|
|
4839
|
+
var formatPlanningStatus = (status) => {
|
|
4840
|
+
if (status === "doing") return "Doing";
|
|
4841
|
+
if (status === "done") return "Done";
|
|
4842
|
+
return "Todo";
|
|
4843
|
+
};
|
|
4844
|
+
var parsePlanningStep = (line) => {
|
|
4845
|
+
const match = PLAN_STEP_REGEX.exec(String(line || ""));
|
|
4846
|
+
if (!match) return null;
|
|
4847
|
+
const title = String(match[2] || "").trim();
|
|
4848
|
+
if (!title) return null;
|
|
4849
|
+
return {
|
|
4850
|
+
status: normalizePlanningStatus(match[1] || ""),
|
|
4851
|
+
title
|
|
4852
|
+
};
|
|
4853
|
+
};
|
|
4854
|
+
var buildPlanningBlockContent = (steps) => {
|
|
4855
|
+
return steps.filter((step) => !!step && typeof step.title === "string" && step.title.trim().length > 0).map((step) => `${formatPlanningStatus(step.status)}: ${step.title.trim()}`).join("\n");
|
|
4856
|
+
};
|
|
4857
|
+
var extractPlanningBlocks = (text) => {
|
|
4858
|
+
const source = typeof text === "string" ? text : "";
|
|
4859
|
+
if (!source) {
|
|
4860
|
+
return {
|
|
4861
|
+
textWithMarkers: "",
|
|
4862
|
+
planningBlocks: []
|
|
4863
|
+
};
|
|
4864
|
+
}
|
|
4865
|
+
const lines = source.split("\n");
|
|
4866
|
+
const planningBlocks = [];
|
|
4867
|
+
const rebuiltSegments = [];
|
|
4868
|
+
let currentOffset = 0;
|
|
4869
|
+
let pendingSteps = [];
|
|
4870
|
+
let pendingIndex = 0;
|
|
4871
|
+
const flushPendingPlanning = () => {
|
|
4872
|
+
if (pendingSteps.length === 0) return;
|
|
4873
|
+
const signature = `planning-${pendingIndex}`;
|
|
4874
|
+
planningBlocks.push({
|
|
4875
|
+
type: "planning",
|
|
4876
|
+
content: buildPlanningBlockContent(pendingSteps),
|
|
4877
|
+
index: pendingIndex,
|
|
4878
|
+
signature,
|
|
4879
|
+
steps: pendingSteps
|
|
4880
|
+
});
|
|
4881
|
+
rebuiltSegments.push(`
|
|
4882
|
+
|
|
4883
|
+
${buildThinkingBlockMarker("planning", signature)}
|
|
4884
|
+
|
|
4885
|
+
`);
|
|
4886
|
+
pendingSteps = [];
|
|
4887
|
+
};
|
|
4888
|
+
lines.forEach((line, index) => {
|
|
4889
|
+
const lineWithNewline = index < lines.length - 1 ? `${line}
|
|
4890
|
+
` : line;
|
|
4891
|
+
const planningStep = parsePlanningStep(line);
|
|
4892
|
+
if (planningStep) {
|
|
4893
|
+
if (pendingSteps.length === 0) {
|
|
4894
|
+
pendingIndex = currentOffset;
|
|
4895
|
+
}
|
|
4896
|
+
pendingSteps = [...pendingSteps, planningStep];
|
|
4897
|
+
} else {
|
|
4898
|
+
flushPendingPlanning();
|
|
4899
|
+
rebuiltSegments.push(lineWithNewline);
|
|
4900
|
+
}
|
|
4901
|
+
currentOffset += lineWithNewline.length;
|
|
4902
|
+
});
|
|
4903
|
+
flushPendingPlanning();
|
|
4904
|
+
return {
|
|
4905
|
+
textWithMarkers: rebuiltSegments.join(""),
|
|
4906
|
+
planningBlocks
|
|
4907
|
+
};
|
|
4908
|
+
};
|
|
4800
4909
|
var buildInlineToolMarker = (toolName, callId) => {
|
|
4801
4910
|
const normalizedToolName = String(toolName || "").trim() || "tool";
|
|
4802
4911
|
const normalizedCallId = String(callId || "").trim() || `${normalizedToolName}-call`;
|
|
@@ -4862,7 +4971,7 @@ var parseInlineThinkingMarkers = (text) => {
|
|
|
4862
4971
|
signature = encodedSignature;
|
|
4863
4972
|
}
|
|
4864
4973
|
const normalizedType = String(rawType || "").trim().toLowerCase();
|
|
4865
|
-
const type = normalizedType === "reasoning" ? "reasoning" : normalizedType === "searching" ? "searching" : "thinking";
|
|
4974
|
+
const type = normalizedType === "reasoning" ? "reasoning" : normalizedType === "searching" ? "searching" : normalizedType === "planning" ? "planning" : "thinking";
|
|
4866
4975
|
markers.push({
|
|
4867
4976
|
type,
|
|
4868
4977
|
signature: String(signature || "").trim()
|
|
@@ -5263,6 +5372,7 @@ var AIChatPanel = ({
|
|
|
5263
5372
|
const [lastPrompt, setLastPrompt] = (0, import_react14.useState)(null);
|
|
5264
5373
|
const [lastKey, setLastKey] = (0, import_react14.useState)(null);
|
|
5265
5374
|
const [currentConversation, setCurrentConversation] = (0, import_react14.useState)(conversation);
|
|
5375
|
+
const ensuredConversationIdsRef = (0, import_react14.useRef)(/* @__PURE__ */ new Set());
|
|
5266
5376
|
const [followOnQuestionsState, setFollowOnQuestionsState] = (0, import_react14.useState)(followOnQuestions);
|
|
5267
5377
|
const [thinkingBlocks, setThinkingBlocks] = (0, import_react14.useState)([]);
|
|
5268
5378
|
const [currentThinkingIndex, setCurrentThinkingIndex] = (0, import_react14.useState)(0);
|
|
@@ -5418,7 +5528,7 @@ var AIChatPanel = ({
|
|
|
5418
5528
|
return;
|
|
5419
5529
|
}
|
|
5420
5530
|
try {
|
|
5421
|
-
const
|
|
5531
|
+
const settled = yield Promise.allSettled(
|
|
5422
5532
|
mcpServers.map((server) => __async(void 0, null, function* () {
|
|
5423
5533
|
const resolved = yield resolveMcpAuthHeaders({
|
|
5424
5534
|
phase: "list",
|
|
@@ -5433,6 +5543,18 @@ var AIChatPanel = ({
|
|
|
5433
5543
|
});
|
|
5434
5544
|
}))
|
|
5435
5545
|
);
|
|
5546
|
+
const enriched = settled.map((result, index) => {
|
|
5547
|
+
var _a2;
|
|
5548
|
+
if (result.status === "fulfilled") {
|
|
5549
|
+
return result.value;
|
|
5550
|
+
}
|
|
5551
|
+
const failingUrl = typeof ((_a2 = mcpServers == null ? void 0 : mcpServers[index]) == null ? void 0 : _a2.url) === "string" ? mcpServers[index].url : `mcp[${index}]`;
|
|
5552
|
+
console.error(
|
|
5553
|
+
`[AIChatPanel] Failed to resolve MCP auth headers for ${failingUrl}:`,
|
|
5554
|
+
result.reason
|
|
5555
|
+
);
|
|
5556
|
+
return mcpServers[index];
|
|
5557
|
+
});
|
|
5436
5558
|
if (!cancelled) setResolvedMcpServers(enriched);
|
|
5437
5559
|
} catch (error2) {
|
|
5438
5560
|
console.error("[AIChatPanel] Failed to resolve MCP auth headers:", error2);
|
|
@@ -5524,10 +5646,22 @@ var AIChatPanel = ({
|
|
|
5524
5646
|
headers: requestHeaders
|
|
5525
5647
|
}));
|
|
5526
5648
|
}));
|
|
5527
|
-
const
|
|
5528
|
-
const allTools =
|
|
5649
|
+
const settled = yield Promise.allSettled(fetchPromises);
|
|
5650
|
+
const allTools = settled.flatMap((result, index) => {
|
|
5651
|
+
var _a2;
|
|
5652
|
+
if (result.status === "fulfilled") {
|
|
5653
|
+
return result.value;
|
|
5654
|
+
}
|
|
5655
|
+
const failingUrl = typeof ((_a2 = resolvedMcpServers == null ? void 0 : resolvedMcpServers[index]) == null ? void 0 : _a2.url) === "string" ? resolvedMcpServers[index].url : `mcp[${index}]`;
|
|
5656
|
+
console.error(
|
|
5657
|
+
`[AIChatPanel] Failed to load MCP tools from ${failingUrl}:`,
|
|
5658
|
+
result.reason
|
|
5659
|
+
);
|
|
5660
|
+
return [];
|
|
5661
|
+
});
|
|
5662
|
+
const failedCount = settled.filter((result) => result.status === "rejected").length;
|
|
5529
5663
|
setToolList(allTools);
|
|
5530
|
-
setToolsFetchError(
|
|
5664
|
+
setToolsFetchError(failedCount > 0 && allTools.length === 0);
|
|
5531
5665
|
} catch (error2) {
|
|
5532
5666
|
console.error("[AIChatPanel] Failed to load MCP tools:", error2);
|
|
5533
5667
|
setToolList([]);
|
|
@@ -5598,22 +5732,25 @@ var AIChatPanel = ({
|
|
|
5598
5732
|
}, [propOnToggleSection]);
|
|
5599
5733
|
const ensureConversation = (0, import_react14.useCallback)(() => {
|
|
5600
5734
|
const normalizedConversationId = typeof currentConversation === "string" ? currentConversation.trim() : "";
|
|
5735
|
+
const hasConversationHistory = Object.keys(latestHistoryRef.current || {}).length > 0;
|
|
5736
|
+
const shouldInitializeProvidedConversation = normalizedConversationId.length > 10 && createConversationOnFirstChat && !hasConversationHistory && !ensuredConversationIdsRef.current.has(normalizedConversationId);
|
|
5601
5737
|
console.log("ensureConversation - called with:", {
|
|
5602
5738
|
currentConversation: normalizedConversationId || null,
|
|
5603
5739
|
createConversationOnFirstChat,
|
|
5740
|
+
shouldInitializeProvidedConversation,
|
|
5604
5741
|
project_id,
|
|
5605
5742
|
publicAPIUrl
|
|
5606
5743
|
});
|
|
5607
|
-
if (normalizedConversationId) {
|
|
5744
|
+
if (normalizedConversationId && !shouldInitializeProvidedConversation) {
|
|
5608
5745
|
console.log("ensureConversation - using existing conversation:", normalizedConversationId);
|
|
5609
5746
|
return Promise.resolve(normalizedConversationId);
|
|
5610
5747
|
}
|
|
5611
5748
|
if (!createConversationOnFirstChat) {
|
|
5612
|
-
return Promise.resolve("");
|
|
5749
|
+
return Promise.resolve(normalizedConversationId || "");
|
|
5613
5750
|
}
|
|
5614
5751
|
if (!project_id) {
|
|
5615
5752
|
console.error("ensureConversation - Cannot create conversation without project_id");
|
|
5616
|
-
return Promise.resolve("");
|
|
5753
|
+
return Promise.resolve(normalizedConversationId || "");
|
|
5617
5754
|
}
|
|
5618
5755
|
const createConversation = () => {
|
|
5619
5756
|
var _a2, _b;
|
|
@@ -5625,6 +5762,9 @@ var AIChatPanel = ({
|
|
|
5625
5762
|
timezone: browserInfo == null ? void 0 : browserInfo.userTimezone,
|
|
5626
5763
|
language: browserInfo == null ? void 0 : browserInfo.userLanguage
|
|
5627
5764
|
};
|
|
5765
|
+
if (shouldInitializeProvidedConversation) {
|
|
5766
|
+
requestBody.conversationId = normalizedConversationId;
|
|
5767
|
+
}
|
|
5628
5768
|
console.log("ensureConversation - Creating conversation with:", requestBody);
|
|
5629
5769
|
console.log("ensureConversation - API URL:", `${publicAPIUrl}/conversations`);
|
|
5630
5770
|
return fetch(`${publicAPIUrl}/conversations`, {
|
|
@@ -5645,16 +5785,31 @@ var AIChatPanel = ({
|
|
|
5645
5785
|
var _a3;
|
|
5646
5786
|
console.log("ensureConversation - API response:", newConvo);
|
|
5647
5787
|
const createdId = typeof (newConvo == null ? void 0 : newConvo.id) === "string" && newConvo.id.trim() || typeof (newConvo == null ? void 0 : newConvo.conversationId) === "string" && newConvo.conversationId.trim() || typeof (newConvo == null ? void 0 : newConvo.conversation_id) === "string" && newConvo.conversation_id.trim() || typeof ((_a3 = newConvo == null ? void 0 : newConvo.conversation) == null ? void 0 : _a3.id) === "string" && newConvo.conversation.id.trim() || "";
|
|
5788
|
+
const resolvedConversationId = normalizedConversationId || createdId;
|
|
5648
5789
|
if (createdId) {
|
|
5649
5790
|
console.log("ensureConversation - New conversation ID:", createdId);
|
|
5791
|
+
}
|
|
5792
|
+
if (resolvedConversationId) {
|
|
5793
|
+
ensuredConversationIdsRef.current.add(resolvedConversationId);
|
|
5794
|
+
}
|
|
5795
|
+
if (normalizedConversationId && createdId && createdId !== normalizedConversationId) {
|
|
5796
|
+
console.warn(
|
|
5797
|
+
"ensureConversation - API returned a different ID than supplied conversationId; keeping caller-provided ID",
|
|
5798
|
+
{ suppliedConversationId: normalizedConversationId, returnedConversationId: createdId }
|
|
5799
|
+
);
|
|
5800
|
+
}
|
|
5801
|
+
if (!normalizedConversationId && createdId) {
|
|
5650
5802
|
setCurrentConversation(createdId);
|
|
5651
5803
|
return createdId;
|
|
5652
5804
|
}
|
|
5805
|
+
if (resolvedConversationId) {
|
|
5806
|
+
return resolvedConversationId;
|
|
5807
|
+
}
|
|
5653
5808
|
console.warn("ensureConversation - No ID in response");
|
|
5654
|
-
return "";
|
|
5809
|
+
return normalizedConversationId || "";
|
|
5655
5810
|
}).catch((error2) => {
|
|
5656
5811
|
console.error("Error creating new conversation", error2);
|
|
5657
|
-
return "";
|
|
5812
|
+
return normalizedConversationId || "";
|
|
5658
5813
|
});
|
|
5659
5814
|
};
|
|
5660
5815
|
return createConversation();
|
|
@@ -6438,6 +6593,13 @@ ${buildThinkingBlockMarker(type, signature)}
|
|
|
6438
6593
|
`;
|
|
6439
6594
|
}
|
|
6440
6595
|
);
|
|
6596
|
+
const {
|
|
6597
|
+
textWithMarkers: textWithArtifactMarkers,
|
|
6598
|
+
planningBlocks
|
|
6599
|
+
} = extractPlanningBlocks(textWithCompleteMarkers);
|
|
6600
|
+
if (planningBlocks.length > 0) {
|
|
6601
|
+
completedBlocks.push(...planningBlocks);
|
|
6602
|
+
}
|
|
6441
6603
|
let activeBlock = null;
|
|
6442
6604
|
const tagTypes = ["thinking", "reasoning", "searching"];
|
|
6443
6605
|
let latestIncompletePos = -1;
|
|
@@ -6467,7 +6629,7 @@ ${buildThinkingBlockMarker(type, signature)}
|
|
|
6467
6629
|
}
|
|
6468
6630
|
}
|
|
6469
6631
|
}
|
|
6470
|
-
let cleanedText =
|
|
6632
|
+
let cleanedText = textWithArtifactMarkers.replace(/<think(?:i(?:n(?:g)?)?)?$/i, "").replace(/<reas(?:o(?:n(?:i(?:n(?:g)?)?)?)?)?$/i, "").replace(/<sear(?:c(?:h(?:i(?:n(?:g)?)?)?)?)?$/i, "").replace(/<thinking>[\s\S]*$/i, "").replace(/<reasoning>[\s\S]*$/i, "").replace(/<searching>[\s\S]*$/i, "").trim();
|
|
6471
6633
|
let lastThinkingContent = "Thinking";
|
|
6472
6634
|
if (completedBlocks.length > 0) {
|
|
6473
6635
|
const lastBlock = completedBlocks[completedBlocks.length - 1];
|
|
@@ -6490,6 +6652,13 @@ ${buildThinkingBlockMarker(type, signature)}
|
|
|
6490
6652
|
if (incomingSupersetPrefix) {
|
|
6491
6653
|
return incoming;
|
|
6492
6654
|
}
|
|
6655
|
+
const incomingSignaturePrefix = incoming.length >= existing.length && existing.every((block, index) => {
|
|
6656
|
+
const next = incoming[index];
|
|
6657
|
+
return !!next && next.type === block.type && next.signature === block.signature;
|
|
6658
|
+
});
|
|
6659
|
+
if (incomingSignaturePrefix) {
|
|
6660
|
+
return incoming;
|
|
6661
|
+
}
|
|
6493
6662
|
const merged = [...existing];
|
|
6494
6663
|
const seen = new Set(existing.map((block) => block.signature || `${block.type}::${block.content}`));
|
|
6495
6664
|
for (const block of incoming) {
|
|
@@ -6708,7 +6877,6 @@ ${traceSummary}` : traceSummary;
|
|
|
6708
6877
|
hasAutoCollapsedRef.current = false;
|
|
6709
6878
|
prevBlockCountRef.current = 0;
|
|
6710
6879
|
setError(null);
|
|
6711
|
-
lastProcessedErrorRef.current = null;
|
|
6712
6880
|
setUserHasScrolled(false);
|
|
6713
6881
|
prevResponseLengthRef.current = 0;
|
|
6714
6882
|
setResponse("");
|
|
@@ -6994,6 +7162,7 @@ ${traceSummary}` : traceSummary;
|
|
|
6994
7162
|
});
|
|
6995
7163
|
prevBlockCountRef.current = mergedBlocks.length;
|
|
6996
7164
|
}
|
|
7165
|
+
const planningBlocks = mergedBlocks.filter((block) => block.type === "planning");
|
|
6997
7166
|
setHistory((prev) => {
|
|
6998
7167
|
const newHistory = __spreadValues({}, prev);
|
|
6999
7168
|
const existingEntry = newHistory[lastKey] || { content: "", callId: "" };
|
|
@@ -7004,7 +7173,9 @@ ${traceSummary}` : traceSummary;
|
|
|
7004
7173
|
newHistory[lastKey] = __spreadProps(__spreadValues({}, existingEntry), {
|
|
7005
7174
|
content: nextContent,
|
|
7006
7175
|
// Store raw content without tool JSON or thinking tags
|
|
7007
|
-
callId: lastCallId || existingEntry.callId || ""
|
|
7176
|
+
callId: lastCallId || existingEntry.callId || "",
|
|
7177
|
+
artifactBlocks: mergedBlocks,
|
|
7178
|
+
planningBlocks
|
|
7008
7179
|
});
|
|
7009
7180
|
latestHistoryRef.current = newHistory;
|
|
7010
7181
|
return newHistory;
|
|
@@ -7148,69 +7319,74 @@ ${traceSummary}` : traceSummary;
|
|
|
7148
7319
|
}
|
|
7149
7320
|
}, [followOnPrompt, continueChat]);
|
|
7150
7321
|
(0, import_react14.useEffect)(() => {
|
|
7151
|
-
|
|
7152
|
-
|
|
7153
|
-
|
|
7154
|
-
|
|
7155
|
-
|
|
7156
|
-
|
|
7157
|
-
|
|
7158
|
-
|
|
7159
|
-
|
|
7160
|
-
|
|
7161
|
-
|
|
7162
|
-
|
|
7163
|
-
|
|
7164
|
-
|
|
7165
|
-
|
|
7166
|
-
|
|
7167
|
-
|
|
7168
|
-
|
|
7169
|
-
|
|
7170
|
-
|
|
7171
|
-
|
|
7172
|
-
|
|
7173
|
-
|
|
7174
|
-
|
|
7175
|
-
|
|
7322
|
+
const normalizedError = typeof llmError === "string" ? llmError.trim() : "";
|
|
7323
|
+
if (!normalizedError) {
|
|
7324
|
+
lastProcessedErrorRef.current = null;
|
|
7325
|
+
return;
|
|
7326
|
+
}
|
|
7327
|
+
if (lastProcessedErrorRef.current === normalizedError) {
|
|
7328
|
+
console.log("[AIChatPanel] Skipping duplicate error:", normalizedError);
|
|
7329
|
+
return;
|
|
7330
|
+
}
|
|
7331
|
+
console.log("[AIChatPanel] Error detected:", normalizedError);
|
|
7332
|
+
lastProcessedErrorRef.current = normalizedError;
|
|
7333
|
+
const errorMessage = normalizedError;
|
|
7334
|
+
const currentLastKey = lastKeyRef.current;
|
|
7335
|
+
const currentLastCallId = lastCallIdRef.current;
|
|
7336
|
+
const isAbortError = errorMessage.toLowerCase().includes("abort") || errorMessage.toLowerCase().includes("canceled") || errorMessage.toLowerCase().includes("cancelled");
|
|
7337
|
+
if (isAbortError) {
|
|
7338
|
+
console.log("[AIChatPanel] Request was aborted by user (useEffect)");
|
|
7339
|
+
} else if (errorMessage.includes("413") || errorMessage.toLowerCase().includes("content too large")) {
|
|
7340
|
+
setError({
|
|
7341
|
+
message: "The context is too large to process. Please start a new conversation or reduce the amount of context.",
|
|
7342
|
+
code: "413"
|
|
7343
|
+
});
|
|
7344
|
+
if (currentLastKey) {
|
|
7345
|
+
setHistory((prev) => {
|
|
7346
|
+
const existingEntry = prev[currentLastKey] || { content: "", callId: "" };
|
|
7347
|
+
return __spreadProps(__spreadValues({}, prev), {
|
|
7348
|
+
[currentLastKey]: __spreadProps(__spreadValues({}, existingEntry), {
|
|
7349
|
+
content: `Error: ${errorMessage}`,
|
|
7350
|
+
callId: currentLastCallId || existingEntry.callId || ""
|
|
7351
|
+
})
|
|
7176
7352
|
});
|
|
7177
|
-
}
|
|
7178
|
-
} else if (errorMessage.toLowerCase().includes("network error") || errorMessage.toLowerCase().includes("fetch")) {
|
|
7179
|
-
setError({
|
|
7180
|
-
message: "Network error. Please check your connection and try again.",
|
|
7181
|
-
code: "NETWORK_ERROR"
|
|
7182
7353
|
});
|
|
7183
|
-
|
|
7184
|
-
|
|
7185
|
-
|
|
7186
|
-
|
|
7187
|
-
|
|
7188
|
-
|
|
7189
|
-
|
|
7190
|
-
|
|
7191
|
-
|
|
7354
|
+
}
|
|
7355
|
+
} else if (errorMessage.toLowerCase().includes("network error") || errorMessage.toLowerCase().includes("fetch")) {
|
|
7356
|
+
setError({
|
|
7357
|
+
message: "Network error. Please check your connection and try again.",
|
|
7358
|
+
code: "NETWORK_ERROR"
|
|
7359
|
+
});
|
|
7360
|
+
if (currentLastKey) {
|
|
7361
|
+
setHistory((prev) => {
|
|
7362
|
+
const existingEntry = prev[currentLastKey] || { content: "", callId: "" };
|
|
7363
|
+
return __spreadProps(__spreadValues({}, prev), {
|
|
7364
|
+
[currentLastKey]: __spreadProps(__spreadValues({}, existingEntry), {
|
|
7365
|
+
content: `Error: ${errorMessage}`,
|
|
7366
|
+
callId: currentLastCallId || existingEntry.callId || ""
|
|
7367
|
+
})
|
|
7192
7368
|
});
|
|
7193
|
-
}
|
|
7194
|
-
} else {
|
|
7195
|
-
setError({
|
|
7196
|
-
message: errorMessage,
|
|
7197
|
-
code: "UNKNOWN_ERROR"
|
|
7198
7369
|
});
|
|
7199
|
-
|
|
7200
|
-
|
|
7201
|
-
|
|
7202
|
-
|
|
7203
|
-
|
|
7204
|
-
|
|
7205
|
-
|
|
7206
|
-
|
|
7207
|
-
|
|
7370
|
+
}
|
|
7371
|
+
} else {
|
|
7372
|
+
setError({
|
|
7373
|
+
message: errorMessage,
|
|
7374
|
+
code: "UNKNOWN_ERROR"
|
|
7375
|
+
});
|
|
7376
|
+
if (currentLastKey) {
|
|
7377
|
+
setHistory((prev) => {
|
|
7378
|
+
const existingEntry = prev[currentLastKey] || { content: "", callId: "" };
|
|
7379
|
+
return __spreadProps(__spreadValues({}, prev), {
|
|
7380
|
+
[currentLastKey]: __spreadProps(__spreadValues({}, existingEntry), {
|
|
7381
|
+
content: `Error: ${errorMessage}`,
|
|
7382
|
+
callId: currentLastCallId || existingEntry.callId || ""
|
|
7383
|
+
})
|
|
7208
7384
|
});
|
|
7209
|
-
}
|
|
7385
|
+
});
|
|
7210
7386
|
}
|
|
7211
|
-
setIsLoading(false);
|
|
7212
7387
|
}
|
|
7213
|
-
|
|
7388
|
+
setIsLoading(false);
|
|
7389
|
+
}, [llmError]);
|
|
7214
7390
|
(0, import_react14.useEffect)(() => {
|
|
7215
7391
|
const existingLinks = document.querySelectorAll(
|
|
7216
7392
|
'link[data-source="ai-chat-panel"]'
|
|
@@ -8468,6 +8644,61 @@ var truncatePromptForTitle = (prompt) => {
|
|
|
8468
8644
|
}
|
|
8469
8645
|
return prompt;
|
|
8470
8646
|
};
|
|
8647
|
+
var stripHistoryPromptTimestamp = (prompt) => {
|
|
8648
|
+
const isoMatch = prompt.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z:(.+)/);
|
|
8649
|
+
if (isoMatch && isoMatch[1]) {
|
|
8650
|
+
return isoMatch[1];
|
|
8651
|
+
}
|
|
8652
|
+
return prompt.replace(/^\d+:/, "");
|
|
8653
|
+
};
|
|
8654
|
+
var upsertConversationSummary = (conversations, summary) => {
|
|
8655
|
+
const normalizedSummary = normalizeConversationListPayload([summary])[0];
|
|
8656
|
+
if (!normalizedSummary) {
|
|
8657
|
+
return conversations;
|
|
8658
|
+
}
|
|
8659
|
+
const dedupedById = /* @__PURE__ */ new Map();
|
|
8660
|
+
for (const conv of conversations) {
|
|
8661
|
+
dedupedById.set(conv.conversationId, conv);
|
|
8662
|
+
}
|
|
8663
|
+
const existing = dedupedById.get(normalizedSummary.conversationId);
|
|
8664
|
+
const existingUpdatedAt = existing ? new Date(existing.updatedAt).getTime() : 0;
|
|
8665
|
+
const incomingUpdatedAt = new Date(normalizedSummary.updatedAt).getTime();
|
|
8666
|
+
const preferIncoming = !existing || incomingUpdatedAt >= existingUpdatedAt;
|
|
8667
|
+
const latest = preferIncoming ? normalizedSummary : existing;
|
|
8668
|
+
const fallback = preferIncoming ? existing : normalizedSummary;
|
|
8669
|
+
dedupedById.set(normalizedSummary.conversationId, __spreadProps(__spreadValues(__spreadValues({}, fallback || {}), latest || {}), {
|
|
8670
|
+
createdAt: (existing == null ? void 0 : existing.createdAt) || normalizedSummary.createdAt,
|
|
8671
|
+
updatedAt: (latest == null ? void 0 : latest.updatedAt) || (fallback == null ? void 0 : fallback.updatedAt) || normalizedSummary.updatedAt,
|
|
8672
|
+
title: (latest == null ? void 0 : latest.title) || (fallback == null ? void 0 : fallback.title) || "",
|
|
8673
|
+
summary: (latest == null ? void 0 : latest.summary) || (fallback == null ? void 0 : fallback.summary),
|
|
8674
|
+
agentId: (latest == null ? void 0 : latest.agentId) || (fallback == null ? void 0 : fallback.agentId),
|
|
8675
|
+
messageCount: typeof (latest == null ? void 0 : latest.messageCount) === "number" ? latest.messageCount : fallback == null ? void 0 : fallback.messageCount
|
|
8676
|
+
}));
|
|
8677
|
+
return Array.from(dedupedById.values()).sort(
|
|
8678
|
+
(a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
|
|
8679
|
+
);
|
|
8680
|
+
};
|
|
8681
|
+
var buildOptimisticConversationSummary = (conversation) => {
|
|
8682
|
+
const conversationId = typeof conversation.conversationId === "string" ? conversation.conversationId.trim() : "";
|
|
8683
|
+
if (!conversationId || conversationId.startsWith("new-")) {
|
|
8684
|
+
return null;
|
|
8685
|
+
}
|
|
8686
|
+
const historyKeys = Object.keys(conversation.history || {});
|
|
8687
|
+
if (historyKeys.length === 0 && conversation.title === "New conversation") {
|
|
8688
|
+
return null;
|
|
8689
|
+
}
|
|
8690
|
+
const firstPrompt = historyKeys[0] ? stripHistoryPromptTimestamp(historyKeys[0]) : "";
|
|
8691
|
+
const title = truncatePromptForTitle(firstPrompt || conversation.title || "New conversation");
|
|
8692
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
8693
|
+
return {
|
|
8694
|
+
conversationId,
|
|
8695
|
+
title,
|
|
8696
|
+
createdAt: now,
|
|
8697
|
+
updatedAt: now,
|
|
8698
|
+
agentId: conversation.agentId,
|
|
8699
|
+
messageCount: historyKeys.length > 0 ? historyKeys.length * 2 : void 0
|
|
8700
|
+
};
|
|
8701
|
+
};
|
|
8471
8702
|
var EMPTY_ARRAY = [];
|
|
8472
8703
|
var EMPTY_HISTORY = {};
|
|
8473
8704
|
var ChatPanelWrapper = ({
|
|
@@ -8871,9 +9102,13 @@ var AIAgentPanel = import_react16.default.forwardRef(({
|
|
|
8871
9102
|
buildAgentAwarenessInstructions,
|
|
8872
9103
|
agentList
|
|
8873
9104
|
} = useAgentRegistry(agentIds, { url, localOverrides });
|
|
9105
|
+
const getAgentRef = (0, import_react16.useRef)(getAgent);
|
|
9106
|
+
(0, import_react16.useEffect)(() => {
|
|
9107
|
+
getAgentRef.current = getAgent;
|
|
9108
|
+
}, [getAgent]);
|
|
8874
9109
|
const fetchInProgressRef = (0, import_react16.useRef)(false);
|
|
8875
9110
|
const loadingTranscriptIdsRef = (0, import_react16.useRef)(/* @__PURE__ */ new Set());
|
|
8876
|
-
const
|
|
9111
|
+
const [conversationListRefreshNonce, setConversationListRefreshNonce] = (0, import_react16.useState)(0);
|
|
8877
9112
|
const checkedPromptsRef = (0, import_react16.useRef)(/* @__PURE__ */ new Set());
|
|
8878
9113
|
const fetchingPromptsRef = (0, import_react16.useRef)(/* @__PURE__ */ new Set());
|
|
8879
9114
|
const failedPromptsRef = (0, import_react16.useRef)(/* @__PURE__ */ new Map());
|
|
@@ -8881,6 +9116,34 @@ var AIAgentPanel = import_react16.default.forwardRef(({
|
|
|
8881
9116
|
activeConversationsRef.current = activeConversations;
|
|
8882
9117
|
const currentConversationIdRef = (0, import_react16.useRef)(currentConversationId);
|
|
8883
9118
|
currentConversationIdRef.current = currentConversationId;
|
|
9119
|
+
const controlledConversationIdRef = (0, import_react16.useRef)(controlledConversationId);
|
|
9120
|
+
controlledConversationIdRef.current = controlledConversationId;
|
|
9121
|
+
const requestConversationListRefresh = (0, import_react16.useCallback)(() => {
|
|
9122
|
+
setConversationListRefreshNonce((prev) => prev + 1);
|
|
9123
|
+
}, []);
|
|
9124
|
+
const upsertApiConversationFromHistory = (0, import_react16.useCallback)(
|
|
9125
|
+
(conversationId, history, fallbackTitle) => {
|
|
9126
|
+
const firstPromptKey = Object.keys(history)[0];
|
|
9127
|
+
const firstPrompt = firstPromptKey ? stripHistoryPromptTimestamp(firstPromptKey) : "";
|
|
9128
|
+
const title = truncatePromptForTitle(firstPrompt || fallbackTitle || "New conversation");
|
|
9129
|
+
const messageCount = Object.keys(history).length * 2;
|
|
9130
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
9131
|
+
setApiConversations(
|
|
9132
|
+
(prev) => {
|
|
9133
|
+
var _a2, _b2;
|
|
9134
|
+
return upsertConversationSummary(prev, {
|
|
9135
|
+
conversationId,
|
|
9136
|
+
title,
|
|
9137
|
+
createdAt: ((_a2 = prev.find((conversation2) => conversation2.conversationId === conversationId)) == null ? void 0 : _a2.createdAt) || timestamp,
|
|
9138
|
+
updatedAt: timestamp,
|
|
9139
|
+
agentId: ((_b2 = prev.find((conversation2) => conversation2.conversationId === conversationId)) == null ? void 0 : _b2.agentId) || currentAgentId,
|
|
9140
|
+
messageCount
|
|
9141
|
+
});
|
|
9142
|
+
}
|
|
9143
|
+
);
|
|
9144
|
+
},
|
|
9145
|
+
[currentAgentId]
|
|
9146
|
+
);
|
|
8884
9147
|
const commitConversationSelection = (0, import_react16.useCallback)(
|
|
8885
9148
|
(conversationId, notifyChange) => {
|
|
8886
9149
|
const shouldSyncLocalState = !isConversationControlled || !notifyChange || controlledConversationId === conversationId;
|
|
@@ -8948,7 +9211,7 @@ var AIAgentPanel = import_react16.default.forwardRef(({
|
|
|
8948
9211
|
fetchingPromptsRef.current.add(conversationId);
|
|
8949
9212
|
setLoadingPrompts((prev) => new Set(prev).add(conversationId));
|
|
8950
9213
|
const agentIdToUse = agentIdForConversation || currentAgentId;
|
|
8951
|
-
const agentProfile =
|
|
9214
|
+
const agentProfile = getAgentRef.current(agentIdToUse);
|
|
8952
9215
|
const projectId = (_a2 = agentProfile == null ? void 0 : agentProfile.metadata) == null ? void 0 : _a2.projectId;
|
|
8953
9216
|
if (!apiKey || !projectId) {
|
|
8954
9217
|
fetchingPromptsRef.current.delete(conversationId);
|
|
@@ -9013,11 +9276,8 @@ var AIAgentPanel = import_react16.default.forwardRef(({
|
|
|
9013
9276
|
return next;
|
|
9014
9277
|
});
|
|
9015
9278
|
}
|
|
9016
|
-
}), [apiKey, currentAgentId
|
|
9017
|
-
const fetchConversations = (0, import_react16.useCallback)((agentId, signal) => __async(void 0, null, function* () {
|
|
9018
|
-
var _a2;
|
|
9019
|
-
const agentProfile = getAgent(agentId);
|
|
9020
|
-
const projectId = (_a2 = agentProfile == null ? void 0 : agentProfile.metadata) == null ? void 0 : _a2.projectId;
|
|
9279
|
+
}), [apiKey, currentAgentId]);
|
|
9280
|
+
const fetchConversations = (0, import_react16.useCallback)((agentId, projectId, signal) => __async(void 0, null, function* () {
|
|
9021
9281
|
if (!agentId || !apiKey || !projectId) {
|
|
9022
9282
|
setApiConversations([]);
|
|
9023
9283
|
return;
|
|
@@ -9043,7 +9303,38 @@ var AIAgentPanel = import_react16.default.forwardRef(({
|
|
|
9043
9303
|
const payload = yield response.json();
|
|
9044
9304
|
const normalized = normalizeConversationListPayload(payload);
|
|
9045
9305
|
if (!(signal == null ? void 0 : signal.aborted)) {
|
|
9046
|
-
setApiConversations(
|
|
9306
|
+
setApiConversations((prev) => {
|
|
9307
|
+
const next = [...normalized];
|
|
9308
|
+
const optimisticIds = /* @__PURE__ */ new Set();
|
|
9309
|
+
const trackedConversationId = controlledConversationIdRef.current;
|
|
9310
|
+
if (trackedConversationId) {
|
|
9311
|
+
optimisticIds.add(trackedConversationId);
|
|
9312
|
+
}
|
|
9313
|
+
activeConversationsRef.current.forEach((conversation2) => {
|
|
9314
|
+
const optimisticSummary = buildOptimisticConversationSummary(conversation2);
|
|
9315
|
+
if (!optimisticSummary) {
|
|
9316
|
+
return;
|
|
9317
|
+
}
|
|
9318
|
+
optimisticIds.add(optimisticSummary.conversationId);
|
|
9319
|
+
const existing = prev.find(
|
|
9320
|
+
(candidate) => candidate.conversationId === optimisticSummary.conversationId
|
|
9321
|
+
);
|
|
9322
|
+
next.push(__spreadProps(__spreadValues({}, optimisticSummary), {
|
|
9323
|
+
createdAt: (existing == null ? void 0 : existing.createdAt) || optimisticSummary.createdAt,
|
|
9324
|
+
updatedAt: optimisticSummary.updatedAt
|
|
9325
|
+
}));
|
|
9326
|
+
});
|
|
9327
|
+
let merged = normalizeConversationListPayload(next);
|
|
9328
|
+
if (optimisticIds.size > 0) {
|
|
9329
|
+
prev.forEach((conversation2) => {
|
|
9330
|
+
if (!optimisticIds.has(conversation2.conversationId)) {
|
|
9331
|
+
return;
|
|
9332
|
+
}
|
|
9333
|
+
merged = upsertConversationSummary(merged, conversation2);
|
|
9334
|
+
});
|
|
9335
|
+
}
|
|
9336
|
+
return merged;
|
|
9337
|
+
});
|
|
9047
9338
|
const now = /* @__PURE__ */ new Date();
|
|
9048
9339
|
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
9049
9340
|
const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1e3);
|
|
@@ -9064,7 +9355,7 @@ var AIAgentPanel = import_react16.default.forwardRef(({
|
|
|
9064
9355
|
setConversationsLoading(false);
|
|
9065
9356
|
}
|
|
9066
9357
|
}
|
|
9067
|
-
}), [apiKey, customerId,
|
|
9358
|
+
}), [apiKey, customerId, fetchFirstPrompt]);
|
|
9068
9359
|
const loadConversationTranscript = (0, import_react16.useCallback)((conversationId, agentIdForConversation, title, notifyConversationChange = true) => __async(void 0, null, function* () {
|
|
9069
9360
|
var _a2;
|
|
9070
9361
|
const existingActive = activeConversationsRef.current.get(conversationId);
|
|
@@ -9077,7 +9368,7 @@ var AIAgentPanel = import_react16.default.forwardRef(({
|
|
|
9077
9368
|
return;
|
|
9078
9369
|
}
|
|
9079
9370
|
const agentIdToUse = agentIdForConversation || currentAgentId;
|
|
9080
|
-
const agentProfile =
|
|
9371
|
+
const agentProfile = getAgentRef.current(agentIdToUse);
|
|
9081
9372
|
const projectId = (_a2 = agentProfile == null ? void 0 : agentProfile.metadata) == null ? void 0 : _a2.projectId;
|
|
9082
9373
|
if (!apiKey || !projectId) {
|
|
9083
9374
|
setConversationsError("Missing API key or project ID");
|
|
@@ -9153,7 +9444,7 @@ var AIAgentPanel = import_react16.default.forwardRef(({
|
|
|
9153
9444
|
loadingTranscriptIdsRef.current.delete(conversationId);
|
|
9154
9445
|
setLoadingConversationId((prev) => prev === conversationId ? null : prev);
|
|
9155
9446
|
}
|
|
9156
|
-
}), [apiKey, commitConversationSelection, conversationFirstPrompts, currentAgentId
|
|
9447
|
+
}), [apiKey, commitConversationSelection, conversationFirstPrompts, currentAgentId]);
|
|
9157
9448
|
(0, import_react16.useEffect)(() => {
|
|
9158
9449
|
if (!isConversationControlled) return;
|
|
9159
9450
|
const targetConversationId = controlledConversationId;
|
|
@@ -9218,21 +9509,32 @@ var AIAgentPanel = import_react16.default.forwardRef(({
|
|
|
9218
9509
|
loadConversationTranscript,
|
|
9219
9510
|
loadingConversationId
|
|
9220
9511
|
]);
|
|
9512
|
+
const currentAgentProjectId = (0, import_react16.useMemo)(() => {
|
|
9513
|
+
var _a2;
|
|
9514
|
+
const agentProfile = getAgent(currentAgentId);
|
|
9515
|
+
return ((_a2 = agentProfile == null ? void 0 : agentProfile.metadata) == null ? void 0 : _a2.projectId) || "";
|
|
9516
|
+
}, [currentAgentId, getAgent]);
|
|
9221
9517
|
const handleRefreshConversations = (0, import_react16.useCallback)(() => {
|
|
9222
|
-
|
|
9223
|
-
}, [
|
|
9518
|
+
requestConversationListRefresh();
|
|
9519
|
+
}, [requestConversationListRefresh]);
|
|
9224
9520
|
(0, import_react16.useEffect)(() => {
|
|
9225
|
-
var _a2;
|
|
9226
9521
|
if (!showConversationHistory) return;
|
|
9227
9522
|
if (!agentsLoading && currentAgentId && apiKey) {
|
|
9228
|
-
|
|
9229
|
-
|
|
9230
|
-
|
|
9231
|
-
|
|
9232
|
-
fetchConversations(currentAgentId);
|
|
9523
|
+
if (currentAgentProjectId) {
|
|
9524
|
+
const controller = new AbortController();
|
|
9525
|
+
fetchConversations(currentAgentId, currentAgentProjectId, controller.signal);
|
|
9526
|
+
return () => controller.abort();
|
|
9233
9527
|
}
|
|
9234
9528
|
}
|
|
9235
|
-
}, [
|
|
9529
|
+
}, [
|
|
9530
|
+
agentsLoading,
|
|
9531
|
+
apiKey,
|
|
9532
|
+
conversationListRefreshNonce,
|
|
9533
|
+
currentAgentId,
|
|
9534
|
+
currentAgentProjectId,
|
|
9535
|
+
fetchConversations,
|
|
9536
|
+
showConversationHistory
|
|
9537
|
+
]);
|
|
9236
9538
|
const handleNewConversation = (0, import_react16.useCallback)(() => {
|
|
9237
9539
|
const tempId = createDraftConversation(currentAgentId);
|
|
9238
9540
|
commitConversationSelection(tempId, true);
|
|
@@ -9556,11 +9858,7 @@ var AIAgentPanel = import_react16.default.forwardRef(({
|
|
|
9556
9858
|
if (title === "New conversation" && Object.keys(history).length > 0) {
|
|
9557
9859
|
const firstPrompt = Object.keys(history)[0];
|
|
9558
9860
|
if (firstPrompt) {
|
|
9559
|
-
|
|
9560
|
-
const isoMatch = cleanPrompt.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z:(.+)/);
|
|
9561
|
-
if (isoMatch && isoMatch[1]) {
|
|
9562
|
-
cleanPrompt = isoMatch[1];
|
|
9563
|
-
}
|
|
9861
|
+
const cleanPrompt = stripHistoryPromptTimestamp(firstPrompt);
|
|
9564
9862
|
title = cleanPrompt.length > 60 ? cleanPrompt.slice(0, 57) + "..." : cleanPrompt;
|
|
9565
9863
|
}
|
|
9566
9864
|
}
|
|
@@ -9573,6 +9871,12 @@ var AIAgentPanel = import_react16.default.forwardRef(({
|
|
|
9573
9871
|
}
|
|
9574
9872
|
return prev;
|
|
9575
9873
|
});
|
|
9874
|
+
const existingActiveConversation = activeConversationsRef.current.get(targetConversationId);
|
|
9875
|
+
upsertApiConversationFromHistory(
|
|
9876
|
+
targetConversationId,
|
|
9877
|
+
history,
|
|
9878
|
+
existingActiveConversation == null ? void 0 : existingActiveConversation.title
|
|
9879
|
+
);
|
|
9576
9880
|
}
|
|
9577
9881
|
const lastEntry = Object.entries(history).pop();
|
|
9578
9882
|
if (lastEntry) {
|
|
@@ -9592,9 +9896,11 @@ var AIAgentPanel = import_react16.default.forwardRef(({
|
|
|
9592
9896
|
}
|
|
9593
9897
|
},
|
|
9594
9898
|
[
|
|
9899
|
+
activeConversationsRef,
|
|
9595
9900
|
currentAgentId,
|
|
9596
9901
|
historyChangedCallback,
|
|
9597
|
-
agents
|
|
9902
|
+
agents,
|
|
9903
|
+
upsertApiConversationFromHistory
|
|
9598
9904
|
]
|
|
9599
9905
|
);
|
|
9600
9906
|
const handleLoadingChange = (0, import_react16.useCallback)((isLoading, conversationId) => {
|
|
@@ -9603,6 +9909,9 @@ var AIAgentPanel = import_react16.default.forwardRef(({
|
|
|
9603
9909
|
setActiveConversations((prev) => {
|
|
9604
9910
|
const existing = prev.get(targetConversationId);
|
|
9605
9911
|
if (existing && existing.isLoading !== isLoading) {
|
|
9912
|
+
if (existing.isLoading && !isLoading) {
|
|
9913
|
+
requestConversationListRefresh();
|
|
9914
|
+
}
|
|
9606
9915
|
const next = new Map(prev);
|
|
9607
9916
|
next.set(targetConversationId, __spreadProps(__spreadValues({}, existing), {
|
|
9608
9917
|
isLoading
|
|
@@ -9612,7 +9921,7 @@ var AIAgentPanel = import_react16.default.forwardRef(({
|
|
|
9612
9921
|
return prev;
|
|
9613
9922
|
});
|
|
9614
9923
|
}
|
|
9615
|
-
}, []);
|
|
9924
|
+
}, [requestConversationListRefresh]);
|
|
9616
9925
|
const handleHandoffConfirm = (0, import_react16.useCallback)(() => {
|
|
9617
9926
|
if (suggestedAgent) {
|
|
9618
9927
|
handleAgentSwitch(suggestedAgent);
|
|
@@ -9658,7 +9967,8 @@ var AIAgentPanel = import_react16.default.forwardRef(({
|
|
|
9658
9967
|
if (currentConversationIdRef.current === tempId) {
|
|
9659
9968
|
commitConversationSelection(realId, true);
|
|
9660
9969
|
}
|
|
9661
|
-
|
|
9970
|
+
requestConversationListRefresh();
|
|
9971
|
+
}, [commitConversationSelection, requestConversationListRefresh]);
|
|
9662
9972
|
const toggleCollapse = (0, import_react16.useCallback)(() => {
|
|
9663
9973
|
if (!collapsible) return;
|
|
9664
9974
|
const newValue = !isCollapsed;
|