@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.mjs
CHANGED
|
@@ -583,6 +583,25 @@ var SearchingIcon = () => /* @__PURE__ */ React10.createElement(
|
|
|
583
583
|
/* @__PURE__ */ React10.createElement("circle", { cx: "11", cy: "11", r: "8" }),
|
|
584
584
|
/* @__PURE__ */ React10.createElement("path", { d: "m21 21-4.3-4.3" })
|
|
585
585
|
);
|
|
586
|
+
var PlanningIcon = () => /* @__PURE__ */ React10.createElement(
|
|
587
|
+
"svg",
|
|
588
|
+
{
|
|
589
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
590
|
+
viewBox: "0 0 24 24",
|
|
591
|
+
fill: "none",
|
|
592
|
+
stroke: "currentColor",
|
|
593
|
+
strokeWidth: "2",
|
|
594
|
+
strokeLinecap: "round",
|
|
595
|
+
strokeLinejoin: "round",
|
|
596
|
+
className: "thinking-block__icon"
|
|
597
|
+
},
|
|
598
|
+
/* @__PURE__ */ React10.createElement("path", { d: "M9 5h11" }),
|
|
599
|
+
/* @__PURE__ */ React10.createElement("path", { d: "M9 12h11" }),
|
|
600
|
+
/* @__PURE__ */ React10.createElement("path", { d: "M9 19h11" }),
|
|
601
|
+
/* @__PURE__ */ React10.createElement("path", { d: "m4 5 1.5 1.5L7 4.5" }),
|
|
602
|
+
/* @__PURE__ */ React10.createElement("path", { d: "m4 12 1.5 1.5L7 11.5" }),
|
|
603
|
+
/* @__PURE__ */ React10.createElement("path", { d: "m4 19 1.5 1.5L7 18.5" })
|
|
604
|
+
);
|
|
586
605
|
var ChevronIcon = ({ isCollapsed }) => /* @__PURE__ */ React10.createElement(
|
|
587
606
|
"svg",
|
|
588
607
|
{
|
|
@@ -605,6 +624,8 @@ var getIcon = (type) => {
|
|
|
605
624
|
return /* @__PURE__ */ React10.createElement(ReasoningIcon, null);
|
|
606
625
|
case "searching":
|
|
607
626
|
return /* @__PURE__ */ React10.createElement(SearchingIcon, null);
|
|
627
|
+
case "planning":
|
|
628
|
+
return /* @__PURE__ */ React10.createElement(PlanningIcon, null);
|
|
608
629
|
}
|
|
609
630
|
};
|
|
610
631
|
var getDefaultTitle = (type) => {
|
|
@@ -615,6 +636,8 @@ var getDefaultTitle = (type) => {
|
|
|
615
636
|
return "Reasoning";
|
|
616
637
|
case "searching":
|
|
617
638
|
return "Searching";
|
|
639
|
+
case "planning":
|
|
640
|
+
return "Planning";
|
|
618
641
|
}
|
|
619
642
|
};
|
|
620
643
|
var ThinkingBlock = ({
|
|
@@ -1373,46 +1396,51 @@ var ChatPanel = ({
|
|
|
1373
1396
|
const urlToFetch = `${publicAPIUrl}/tools/${encodeURIComponent(
|
|
1374
1397
|
m.url
|
|
1375
1398
|
)}`;
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
if (!response2.ok) {
|
|
1385
|
-
console.error(
|
|
1386
|
-
`Error fetching tools from ${m.url}: ${response2.status} ${response2.statusText}`
|
|
1387
|
-
);
|
|
1388
|
-
const errorBody = yield response2.text();
|
|
1389
|
-
console.error(`Error body: ${errorBody}`);
|
|
1390
|
-
throw new Error(
|
|
1391
|
-
`HTTP ${response2.status}: ${response2.statusText}`
|
|
1392
|
-
);
|
|
1393
|
-
}
|
|
1394
|
-
const toolsFromServer = yield response2.json();
|
|
1395
|
-
if (Array.isArray(toolsFromServer)) {
|
|
1396
|
-
return toolsFromServer.map((tool) => __spreadProps(__spreadValues({}, tool), {
|
|
1397
|
-
url: m.url,
|
|
1398
|
-
accessToken: m.accessToken || "",
|
|
1399
|
-
headers: requestHeaders
|
|
1400
|
-
}));
|
|
1401
|
-
} else {
|
|
1402
|
-
return [];
|
|
1403
|
-
}
|
|
1404
|
-
} catch (fetchError) {
|
|
1399
|
+
const requestHeaders = yield buildMcpRequestHeaders({
|
|
1400
|
+
phase: "list",
|
|
1401
|
+
mcpServer: m
|
|
1402
|
+
});
|
|
1403
|
+
const response2 = yield fetch(urlToFetch, {
|
|
1404
|
+
headers: requestHeaders
|
|
1405
|
+
});
|
|
1406
|
+
if (!response2.ok) {
|
|
1405
1407
|
console.error(
|
|
1406
|
-
`
|
|
1407
|
-
fetchError
|
|
1408
|
+
`Error fetching tools from ${m.url}: ${response2.status} ${response2.statusText}`
|
|
1408
1409
|
);
|
|
1409
|
-
|
|
1410
|
+
const errorBody = yield response2.text();
|
|
1411
|
+
console.error(`Error body: ${errorBody}`);
|
|
1412
|
+
throw new Error(
|
|
1413
|
+
`HTTP ${response2.status}: ${response2.statusText}`
|
|
1414
|
+
);
|
|
1415
|
+
}
|
|
1416
|
+
const toolsFromServer = yield response2.json();
|
|
1417
|
+
if (Array.isArray(toolsFromServer)) {
|
|
1418
|
+
return toolsFromServer.map((tool) => __spreadProps(__spreadValues({}, tool), {
|
|
1419
|
+
url: m.url,
|
|
1420
|
+
accessToken: m.accessToken || "",
|
|
1421
|
+
headers: requestHeaders
|
|
1422
|
+
}));
|
|
1410
1423
|
}
|
|
1424
|
+
return [];
|
|
1411
1425
|
}));
|
|
1412
|
-
const
|
|
1413
|
-
const allTools =
|
|
1426
|
+
const settledResults = yield Promise.allSettled(fetchPromises);
|
|
1427
|
+
const allTools = settledResults.flatMap((result, index) => {
|
|
1428
|
+
if (result.status === "fulfilled") {
|
|
1429
|
+
return result.value;
|
|
1430
|
+
}
|
|
1431
|
+
const server = mcpServers == null ? void 0 : mcpServers[index];
|
|
1432
|
+
const failingUrl = typeof (server == null ? void 0 : server.url) === "string" ? server.url : `mcp[${index}]`;
|
|
1433
|
+
console.error(
|
|
1434
|
+
`Network or parsing error fetching tools from ${failingUrl}:`,
|
|
1435
|
+
result.reason
|
|
1436
|
+
);
|
|
1437
|
+
return [];
|
|
1438
|
+
});
|
|
1439
|
+
const failedCount = settledResults.filter(
|
|
1440
|
+
(result) => result.status === "rejected"
|
|
1441
|
+
).length;
|
|
1414
1442
|
setToolList(allTools);
|
|
1415
|
-
setToolsFetchError(
|
|
1443
|
+
setToolsFetchError(failedCount > 0 && allTools.length === 0);
|
|
1416
1444
|
} catch (error2) {
|
|
1417
1445
|
console.error(
|
|
1418
1446
|
"An error occurred while processing tool fetches:",
|
|
@@ -4762,6 +4790,87 @@ var buildThinkingBlockMarker = (type, signature) => {
|
|
|
4762
4790
|
normalizedSignature
|
|
4763
4791
|
)}${INLINE_THINKING_MARKER_SUFFIX}`;
|
|
4764
4792
|
};
|
|
4793
|
+
var PLAN_STEP_REGEX = /^\s*\[plan-step\]\s*([a-zA-Z_-]+)\s*:\s*(.+?)\s*$/i;
|
|
4794
|
+
var normalizePlanningStatus = (value) => {
|
|
4795
|
+
const normalized = String(value || "").trim().toLowerCase();
|
|
4796
|
+
if (normalized === "doing" || normalized === "in_progress" || normalized === "in-progress") {
|
|
4797
|
+
return "doing";
|
|
4798
|
+
}
|
|
4799
|
+
if (normalized === "done" || normalized === "completed") {
|
|
4800
|
+
return "done";
|
|
4801
|
+
}
|
|
4802
|
+
return "todo";
|
|
4803
|
+
};
|
|
4804
|
+
var formatPlanningStatus = (status) => {
|
|
4805
|
+
if (status === "doing") return "Doing";
|
|
4806
|
+
if (status === "done") return "Done";
|
|
4807
|
+
return "Todo";
|
|
4808
|
+
};
|
|
4809
|
+
var parsePlanningStep = (line) => {
|
|
4810
|
+
const match = PLAN_STEP_REGEX.exec(String(line || ""));
|
|
4811
|
+
if (!match) return null;
|
|
4812
|
+
const title = String(match[2] || "").trim();
|
|
4813
|
+
if (!title) return null;
|
|
4814
|
+
return {
|
|
4815
|
+
status: normalizePlanningStatus(match[1] || ""),
|
|
4816
|
+
title
|
|
4817
|
+
};
|
|
4818
|
+
};
|
|
4819
|
+
var buildPlanningBlockContent = (steps) => {
|
|
4820
|
+
return steps.filter((step) => !!step && typeof step.title === "string" && step.title.trim().length > 0).map((step) => `${formatPlanningStatus(step.status)}: ${step.title.trim()}`).join("\n");
|
|
4821
|
+
};
|
|
4822
|
+
var extractPlanningBlocks = (text) => {
|
|
4823
|
+
const source = typeof text === "string" ? text : "";
|
|
4824
|
+
if (!source) {
|
|
4825
|
+
return {
|
|
4826
|
+
textWithMarkers: "",
|
|
4827
|
+
planningBlocks: []
|
|
4828
|
+
};
|
|
4829
|
+
}
|
|
4830
|
+
const lines = source.split("\n");
|
|
4831
|
+
const planningBlocks = [];
|
|
4832
|
+
const rebuiltSegments = [];
|
|
4833
|
+
let currentOffset = 0;
|
|
4834
|
+
let pendingSteps = [];
|
|
4835
|
+
let pendingIndex = 0;
|
|
4836
|
+
const flushPendingPlanning = () => {
|
|
4837
|
+
if (pendingSteps.length === 0) return;
|
|
4838
|
+
const signature = `planning-${pendingIndex}`;
|
|
4839
|
+
planningBlocks.push({
|
|
4840
|
+
type: "planning",
|
|
4841
|
+
content: buildPlanningBlockContent(pendingSteps),
|
|
4842
|
+
index: pendingIndex,
|
|
4843
|
+
signature,
|
|
4844
|
+
steps: pendingSteps
|
|
4845
|
+
});
|
|
4846
|
+
rebuiltSegments.push(`
|
|
4847
|
+
|
|
4848
|
+
${buildThinkingBlockMarker("planning", signature)}
|
|
4849
|
+
|
|
4850
|
+
`);
|
|
4851
|
+
pendingSteps = [];
|
|
4852
|
+
};
|
|
4853
|
+
lines.forEach((line, index) => {
|
|
4854
|
+
const lineWithNewline = index < lines.length - 1 ? `${line}
|
|
4855
|
+
` : line;
|
|
4856
|
+
const planningStep = parsePlanningStep(line);
|
|
4857
|
+
if (planningStep) {
|
|
4858
|
+
if (pendingSteps.length === 0) {
|
|
4859
|
+
pendingIndex = currentOffset;
|
|
4860
|
+
}
|
|
4861
|
+
pendingSteps = [...pendingSteps, planningStep];
|
|
4862
|
+
} else {
|
|
4863
|
+
flushPendingPlanning();
|
|
4864
|
+
rebuiltSegments.push(lineWithNewline);
|
|
4865
|
+
}
|
|
4866
|
+
currentOffset += lineWithNewline.length;
|
|
4867
|
+
});
|
|
4868
|
+
flushPendingPlanning();
|
|
4869
|
+
return {
|
|
4870
|
+
textWithMarkers: rebuiltSegments.join(""),
|
|
4871
|
+
planningBlocks
|
|
4872
|
+
};
|
|
4873
|
+
};
|
|
4765
4874
|
var buildInlineToolMarker = (toolName, callId) => {
|
|
4766
4875
|
const normalizedToolName = String(toolName || "").trim() || "tool";
|
|
4767
4876
|
const normalizedCallId = String(callId || "").trim() || `${normalizedToolName}-call`;
|
|
@@ -4827,7 +4936,7 @@ var parseInlineThinkingMarkers = (text) => {
|
|
|
4827
4936
|
signature = encodedSignature;
|
|
4828
4937
|
}
|
|
4829
4938
|
const normalizedType = String(rawType || "").trim().toLowerCase();
|
|
4830
|
-
const type = normalizedType === "reasoning" ? "reasoning" : normalizedType === "searching" ? "searching" : "thinking";
|
|
4939
|
+
const type = normalizedType === "reasoning" ? "reasoning" : normalizedType === "searching" ? "searching" : normalizedType === "planning" ? "planning" : "thinking";
|
|
4831
4940
|
markers.push({
|
|
4832
4941
|
type,
|
|
4833
4942
|
signature: String(signature || "").trim()
|
|
@@ -5228,6 +5337,7 @@ var AIChatPanel = ({
|
|
|
5228
5337
|
const [lastPrompt, setLastPrompt] = useState7(null);
|
|
5229
5338
|
const [lastKey, setLastKey] = useState7(null);
|
|
5230
5339
|
const [currentConversation, setCurrentConversation] = useState7(conversation);
|
|
5340
|
+
const ensuredConversationIdsRef = useRef6(/* @__PURE__ */ new Set());
|
|
5231
5341
|
const [followOnQuestionsState, setFollowOnQuestionsState] = useState7(followOnQuestions);
|
|
5232
5342
|
const [thinkingBlocks, setThinkingBlocks] = useState7([]);
|
|
5233
5343
|
const [currentThinkingIndex, setCurrentThinkingIndex] = useState7(0);
|
|
@@ -5383,7 +5493,7 @@ var AIChatPanel = ({
|
|
|
5383
5493
|
return;
|
|
5384
5494
|
}
|
|
5385
5495
|
try {
|
|
5386
|
-
const
|
|
5496
|
+
const settled = yield Promise.allSettled(
|
|
5387
5497
|
mcpServers.map((server) => __async(void 0, null, function* () {
|
|
5388
5498
|
const resolved = yield resolveMcpAuthHeaders({
|
|
5389
5499
|
phase: "list",
|
|
@@ -5398,6 +5508,18 @@ var AIChatPanel = ({
|
|
|
5398
5508
|
});
|
|
5399
5509
|
}))
|
|
5400
5510
|
);
|
|
5511
|
+
const enriched = settled.map((result, index) => {
|
|
5512
|
+
var _a2;
|
|
5513
|
+
if (result.status === "fulfilled") {
|
|
5514
|
+
return result.value;
|
|
5515
|
+
}
|
|
5516
|
+
const failingUrl = typeof ((_a2 = mcpServers == null ? void 0 : mcpServers[index]) == null ? void 0 : _a2.url) === "string" ? mcpServers[index].url : `mcp[${index}]`;
|
|
5517
|
+
console.error(
|
|
5518
|
+
`[AIChatPanel] Failed to resolve MCP auth headers for ${failingUrl}:`,
|
|
5519
|
+
result.reason
|
|
5520
|
+
);
|
|
5521
|
+
return mcpServers[index];
|
|
5522
|
+
});
|
|
5401
5523
|
if (!cancelled) setResolvedMcpServers(enriched);
|
|
5402
5524
|
} catch (error2) {
|
|
5403
5525
|
console.error("[AIChatPanel] Failed to resolve MCP auth headers:", error2);
|
|
@@ -5489,10 +5611,22 @@ var AIChatPanel = ({
|
|
|
5489
5611
|
headers: requestHeaders
|
|
5490
5612
|
}));
|
|
5491
5613
|
}));
|
|
5492
|
-
const
|
|
5493
|
-
const allTools =
|
|
5614
|
+
const settled = yield Promise.allSettled(fetchPromises);
|
|
5615
|
+
const allTools = settled.flatMap((result, index) => {
|
|
5616
|
+
var _a2;
|
|
5617
|
+
if (result.status === "fulfilled") {
|
|
5618
|
+
return result.value;
|
|
5619
|
+
}
|
|
5620
|
+
const failingUrl = typeof ((_a2 = resolvedMcpServers == null ? void 0 : resolvedMcpServers[index]) == null ? void 0 : _a2.url) === "string" ? resolvedMcpServers[index].url : `mcp[${index}]`;
|
|
5621
|
+
console.error(
|
|
5622
|
+
`[AIChatPanel] Failed to load MCP tools from ${failingUrl}:`,
|
|
5623
|
+
result.reason
|
|
5624
|
+
);
|
|
5625
|
+
return [];
|
|
5626
|
+
});
|
|
5627
|
+
const failedCount = settled.filter((result) => result.status === "rejected").length;
|
|
5494
5628
|
setToolList(allTools);
|
|
5495
|
-
setToolsFetchError(
|
|
5629
|
+
setToolsFetchError(failedCount > 0 && allTools.length === 0);
|
|
5496
5630
|
} catch (error2) {
|
|
5497
5631
|
console.error("[AIChatPanel] Failed to load MCP tools:", error2);
|
|
5498
5632
|
setToolList([]);
|
|
@@ -5563,22 +5697,25 @@ var AIChatPanel = ({
|
|
|
5563
5697
|
}, [propOnToggleSection]);
|
|
5564
5698
|
const ensureConversation = useCallback2(() => {
|
|
5565
5699
|
const normalizedConversationId = typeof currentConversation === "string" ? currentConversation.trim() : "";
|
|
5700
|
+
const hasConversationHistory = Object.keys(latestHistoryRef.current || {}).length > 0;
|
|
5701
|
+
const shouldInitializeProvidedConversation = normalizedConversationId.length > 10 && createConversationOnFirstChat && !hasConversationHistory && !ensuredConversationIdsRef.current.has(normalizedConversationId);
|
|
5566
5702
|
console.log("ensureConversation - called with:", {
|
|
5567
5703
|
currentConversation: normalizedConversationId || null,
|
|
5568
5704
|
createConversationOnFirstChat,
|
|
5705
|
+
shouldInitializeProvidedConversation,
|
|
5569
5706
|
project_id,
|
|
5570
5707
|
publicAPIUrl
|
|
5571
5708
|
});
|
|
5572
|
-
if (normalizedConversationId) {
|
|
5709
|
+
if (normalizedConversationId && !shouldInitializeProvidedConversation) {
|
|
5573
5710
|
console.log("ensureConversation - using existing conversation:", normalizedConversationId);
|
|
5574
5711
|
return Promise.resolve(normalizedConversationId);
|
|
5575
5712
|
}
|
|
5576
5713
|
if (!createConversationOnFirstChat) {
|
|
5577
|
-
return Promise.resolve("");
|
|
5714
|
+
return Promise.resolve(normalizedConversationId || "");
|
|
5578
5715
|
}
|
|
5579
5716
|
if (!project_id) {
|
|
5580
5717
|
console.error("ensureConversation - Cannot create conversation without project_id");
|
|
5581
|
-
return Promise.resolve("");
|
|
5718
|
+
return Promise.resolve(normalizedConversationId || "");
|
|
5582
5719
|
}
|
|
5583
5720
|
const createConversation = () => {
|
|
5584
5721
|
var _a2, _b;
|
|
@@ -5590,6 +5727,9 @@ var AIChatPanel = ({
|
|
|
5590
5727
|
timezone: browserInfo == null ? void 0 : browserInfo.userTimezone,
|
|
5591
5728
|
language: browserInfo == null ? void 0 : browserInfo.userLanguage
|
|
5592
5729
|
};
|
|
5730
|
+
if (shouldInitializeProvidedConversation) {
|
|
5731
|
+
requestBody.conversationId = normalizedConversationId;
|
|
5732
|
+
}
|
|
5593
5733
|
console.log("ensureConversation - Creating conversation with:", requestBody);
|
|
5594
5734
|
console.log("ensureConversation - API URL:", `${publicAPIUrl}/conversations`);
|
|
5595
5735
|
return fetch(`${publicAPIUrl}/conversations`, {
|
|
@@ -5610,16 +5750,31 @@ var AIChatPanel = ({
|
|
|
5610
5750
|
var _a3;
|
|
5611
5751
|
console.log("ensureConversation - API response:", newConvo);
|
|
5612
5752
|
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() || "";
|
|
5753
|
+
const resolvedConversationId = normalizedConversationId || createdId;
|
|
5613
5754
|
if (createdId) {
|
|
5614
5755
|
console.log("ensureConversation - New conversation ID:", createdId);
|
|
5756
|
+
}
|
|
5757
|
+
if (resolvedConversationId) {
|
|
5758
|
+
ensuredConversationIdsRef.current.add(resolvedConversationId);
|
|
5759
|
+
}
|
|
5760
|
+
if (normalizedConversationId && createdId && createdId !== normalizedConversationId) {
|
|
5761
|
+
console.warn(
|
|
5762
|
+
"ensureConversation - API returned a different ID than supplied conversationId; keeping caller-provided ID",
|
|
5763
|
+
{ suppliedConversationId: normalizedConversationId, returnedConversationId: createdId }
|
|
5764
|
+
);
|
|
5765
|
+
}
|
|
5766
|
+
if (!normalizedConversationId && createdId) {
|
|
5615
5767
|
setCurrentConversation(createdId);
|
|
5616
5768
|
return createdId;
|
|
5617
5769
|
}
|
|
5770
|
+
if (resolvedConversationId) {
|
|
5771
|
+
return resolvedConversationId;
|
|
5772
|
+
}
|
|
5618
5773
|
console.warn("ensureConversation - No ID in response");
|
|
5619
|
-
return "";
|
|
5774
|
+
return normalizedConversationId || "";
|
|
5620
5775
|
}).catch((error2) => {
|
|
5621
5776
|
console.error("Error creating new conversation", error2);
|
|
5622
|
-
return "";
|
|
5777
|
+
return normalizedConversationId || "";
|
|
5623
5778
|
});
|
|
5624
5779
|
};
|
|
5625
5780
|
return createConversation();
|
|
@@ -6403,6 +6558,13 @@ ${buildThinkingBlockMarker(type, signature)}
|
|
|
6403
6558
|
`;
|
|
6404
6559
|
}
|
|
6405
6560
|
);
|
|
6561
|
+
const {
|
|
6562
|
+
textWithMarkers: textWithArtifactMarkers,
|
|
6563
|
+
planningBlocks
|
|
6564
|
+
} = extractPlanningBlocks(textWithCompleteMarkers);
|
|
6565
|
+
if (planningBlocks.length > 0) {
|
|
6566
|
+
completedBlocks.push(...planningBlocks);
|
|
6567
|
+
}
|
|
6406
6568
|
let activeBlock = null;
|
|
6407
6569
|
const tagTypes = ["thinking", "reasoning", "searching"];
|
|
6408
6570
|
let latestIncompletePos = -1;
|
|
@@ -6432,7 +6594,7 @@ ${buildThinkingBlockMarker(type, signature)}
|
|
|
6432
6594
|
}
|
|
6433
6595
|
}
|
|
6434
6596
|
}
|
|
6435
|
-
let cleanedText =
|
|
6597
|
+
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();
|
|
6436
6598
|
let lastThinkingContent = "Thinking";
|
|
6437
6599
|
if (completedBlocks.length > 0) {
|
|
6438
6600
|
const lastBlock = completedBlocks[completedBlocks.length - 1];
|
|
@@ -6455,6 +6617,13 @@ ${buildThinkingBlockMarker(type, signature)}
|
|
|
6455
6617
|
if (incomingSupersetPrefix) {
|
|
6456
6618
|
return incoming;
|
|
6457
6619
|
}
|
|
6620
|
+
const incomingSignaturePrefix = incoming.length >= existing.length && existing.every((block, index) => {
|
|
6621
|
+
const next = incoming[index];
|
|
6622
|
+
return !!next && next.type === block.type && next.signature === block.signature;
|
|
6623
|
+
});
|
|
6624
|
+
if (incomingSignaturePrefix) {
|
|
6625
|
+
return incoming;
|
|
6626
|
+
}
|
|
6458
6627
|
const merged = [...existing];
|
|
6459
6628
|
const seen = new Set(existing.map((block) => block.signature || `${block.type}::${block.content}`));
|
|
6460
6629
|
for (const block of incoming) {
|
|
@@ -6673,7 +6842,6 @@ ${traceSummary}` : traceSummary;
|
|
|
6673
6842
|
hasAutoCollapsedRef.current = false;
|
|
6674
6843
|
prevBlockCountRef.current = 0;
|
|
6675
6844
|
setError(null);
|
|
6676
|
-
lastProcessedErrorRef.current = null;
|
|
6677
6845
|
setUserHasScrolled(false);
|
|
6678
6846
|
prevResponseLengthRef.current = 0;
|
|
6679
6847
|
setResponse("");
|
|
@@ -6959,6 +7127,7 @@ ${traceSummary}` : traceSummary;
|
|
|
6959
7127
|
});
|
|
6960
7128
|
prevBlockCountRef.current = mergedBlocks.length;
|
|
6961
7129
|
}
|
|
7130
|
+
const planningBlocks = mergedBlocks.filter((block) => block.type === "planning");
|
|
6962
7131
|
setHistory((prev) => {
|
|
6963
7132
|
const newHistory = __spreadValues({}, prev);
|
|
6964
7133
|
const existingEntry = newHistory[lastKey] || { content: "", callId: "" };
|
|
@@ -6969,7 +7138,9 @@ ${traceSummary}` : traceSummary;
|
|
|
6969
7138
|
newHistory[lastKey] = __spreadProps(__spreadValues({}, existingEntry), {
|
|
6970
7139
|
content: nextContent,
|
|
6971
7140
|
// Store raw content without tool JSON or thinking tags
|
|
6972
|
-
callId: lastCallId || existingEntry.callId || ""
|
|
7141
|
+
callId: lastCallId || existingEntry.callId || "",
|
|
7142
|
+
artifactBlocks: mergedBlocks,
|
|
7143
|
+
planningBlocks
|
|
6973
7144
|
});
|
|
6974
7145
|
latestHistoryRef.current = newHistory;
|
|
6975
7146
|
return newHistory;
|
|
@@ -7113,69 +7284,74 @@ ${traceSummary}` : traceSummary;
|
|
|
7113
7284
|
}
|
|
7114
7285
|
}, [followOnPrompt, continueChat]);
|
|
7115
7286
|
useEffect8(() => {
|
|
7116
|
-
|
|
7117
|
-
|
|
7118
|
-
|
|
7119
|
-
|
|
7120
|
-
|
|
7121
|
-
|
|
7122
|
-
|
|
7123
|
-
|
|
7124
|
-
|
|
7125
|
-
|
|
7126
|
-
|
|
7127
|
-
|
|
7128
|
-
|
|
7129
|
-
|
|
7130
|
-
|
|
7131
|
-
|
|
7132
|
-
|
|
7133
|
-
|
|
7134
|
-
|
|
7135
|
-
|
|
7136
|
-
|
|
7137
|
-
|
|
7138
|
-
|
|
7139
|
-
|
|
7140
|
-
|
|
7287
|
+
const normalizedError = typeof llmError === "string" ? llmError.trim() : "";
|
|
7288
|
+
if (!normalizedError) {
|
|
7289
|
+
lastProcessedErrorRef.current = null;
|
|
7290
|
+
return;
|
|
7291
|
+
}
|
|
7292
|
+
if (lastProcessedErrorRef.current === normalizedError) {
|
|
7293
|
+
console.log("[AIChatPanel] Skipping duplicate error:", normalizedError);
|
|
7294
|
+
return;
|
|
7295
|
+
}
|
|
7296
|
+
console.log("[AIChatPanel] Error detected:", normalizedError);
|
|
7297
|
+
lastProcessedErrorRef.current = normalizedError;
|
|
7298
|
+
const errorMessage = normalizedError;
|
|
7299
|
+
const currentLastKey = lastKeyRef.current;
|
|
7300
|
+
const currentLastCallId = lastCallIdRef.current;
|
|
7301
|
+
const isAbortError = errorMessage.toLowerCase().includes("abort") || errorMessage.toLowerCase().includes("canceled") || errorMessage.toLowerCase().includes("cancelled");
|
|
7302
|
+
if (isAbortError) {
|
|
7303
|
+
console.log("[AIChatPanel] Request was aborted by user (useEffect)");
|
|
7304
|
+
} else if (errorMessage.includes("413") || errorMessage.toLowerCase().includes("content too large")) {
|
|
7305
|
+
setError({
|
|
7306
|
+
message: "The context is too large to process. Please start a new conversation or reduce the amount of context.",
|
|
7307
|
+
code: "413"
|
|
7308
|
+
});
|
|
7309
|
+
if (currentLastKey) {
|
|
7310
|
+
setHistory((prev) => {
|
|
7311
|
+
const existingEntry = prev[currentLastKey] || { content: "", callId: "" };
|
|
7312
|
+
return __spreadProps(__spreadValues({}, prev), {
|
|
7313
|
+
[currentLastKey]: __spreadProps(__spreadValues({}, existingEntry), {
|
|
7314
|
+
content: `Error: ${errorMessage}`,
|
|
7315
|
+
callId: currentLastCallId || existingEntry.callId || ""
|
|
7316
|
+
})
|
|
7141
7317
|
});
|
|
7142
|
-
}
|
|
7143
|
-
} else if (errorMessage.toLowerCase().includes("network error") || errorMessage.toLowerCase().includes("fetch")) {
|
|
7144
|
-
setError({
|
|
7145
|
-
message: "Network error. Please check your connection and try again.",
|
|
7146
|
-
code: "NETWORK_ERROR"
|
|
7147
7318
|
});
|
|
7148
|
-
|
|
7149
|
-
|
|
7150
|
-
|
|
7151
|
-
|
|
7152
|
-
|
|
7153
|
-
|
|
7154
|
-
|
|
7155
|
-
|
|
7156
|
-
|
|
7319
|
+
}
|
|
7320
|
+
} else if (errorMessage.toLowerCase().includes("network error") || errorMessage.toLowerCase().includes("fetch")) {
|
|
7321
|
+
setError({
|
|
7322
|
+
message: "Network error. Please check your connection and try again.",
|
|
7323
|
+
code: "NETWORK_ERROR"
|
|
7324
|
+
});
|
|
7325
|
+
if (currentLastKey) {
|
|
7326
|
+
setHistory((prev) => {
|
|
7327
|
+
const existingEntry = prev[currentLastKey] || { content: "", callId: "" };
|
|
7328
|
+
return __spreadProps(__spreadValues({}, prev), {
|
|
7329
|
+
[currentLastKey]: __spreadProps(__spreadValues({}, existingEntry), {
|
|
7330
|
+
content: `Error: ${errorMessage}`,
|
|
7331
|
+
callId: currentLastCallId || existingEntry.callId || ""
|
|
7332
|
+
})
|
|
7157
7333
|
});
|
|
7158
|
-
}
|
|
7159
|
-
} else {
|
|
7160
|
-
setError({
|
|
7161
|
-
message: errorMessage,
|
|
7162
|
-
code: "UNKNOWN_ERROR"
|
|
7163
7334
|
});
|
|
7164
|
-
|
|
7165
|
-
|
|
7166
|
-
|
|
7167
|
-
|
|
7168
|
-
|
|
7169
|
-
|
|
7170
|
-
|
|
7171
|
-
|
|
7172
|
-
|
|
7335
|
+
}
|
|
7336
|
+
} else {
|
|
7337
|
+
setError({
|
|
7338
|
+
message: errorMessage,
|
|
7339
|
+
code: "UNKNOWN_ERROR"
|
|
7340
|
+
});
|
|
7341
|
+
if (currentLastKey) {
|
|
7342
|
+
setHistory((prev) => {
|
|
7343
|
+
const existingEntry = prev[currentLastKey] || { content: "", callId: "" };
|
|
7344
|
+
return __spreadProps(__spreadValues({}, prev), {
|
|
7345
|
+
[currentLastKey]: __spreadProps(__spreadValues({}, existingEntry), {
|
|
7346
|
+
content: `Error: ${errorMessage}`,
|
|
7347
|
+
callId: currentLastCallId || existingEntry.callId || ""
|
|
7348
|
+
})
|
|
7173
7349
|
});
|
|
7174
|
-
}
|
|
7350
|
+
});
|
|
7175
7351
|
}
|
|
7176
|
-
setIsLoading(false);
|
|
7177
7352
|
}
|
|
7178
|
-
|
|
7353
|
+
setIsLoading(false);
|
|
7354
|
+
}, [llmError]);
|
|
7179
7355
|
useEffect8(() => {
|
|
7180
7356
|
const existingLinks = document.querySelectorAll(
|
|
7181
7357
|
'link[data-source="ai-chat-panel"]'
|
|
@@ -8433,6 +8609,61 @@ var truncatePromptForTitle = (prompt) => {
|
|
|
8433
8609
|
}
|
|
8434
8610
|
return prompt;
|
|
8435
8611
|
};
|
|
8612
|
+
var stripHistoryPromptTimestamp = (prompt) => {
|
|
8613
|
+
const isoMatch = prompt.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z:(.+)/);
|
|
8614
|
+
if (isoMatch && isoMatch[1]) {
|
|
8615
|
+
return isoMatch[1];
|
|
8616
|
+
}
|
|
8617
|
+
return prompt.replace(/^\d+:/, "");
|
|
8618
|
+
};
|
|
8619
|
+
var upsertConversationSummary = (conversations, summary) => {
|
|
8620
|
+
const normalizedSummary = normalizeConversationListPayload([summary])[0];
|
|
8621
|
+
if (!normalizedSummary) {
|
|
8622
|
+
return conversations;
|
|
8623
|
+
}
|
|
8624
|
+
const dedupedById = /* @__PURE__ */ new Map();
|
|
8625
|
+
for (const conv of conversations) {
|
|
8626
|
+
dedupedById.set(conv.conversationId, conv);
|
|
8627
|
+
}
|
|
8628
|
+
const existing = dedupedById.get(normalizedSummary.conversationId);
|
|
8629
|
+
const existingUpdatedAt = existing ? new Date(existing.updatedAt).getTime() : 0;
|
|
8630
|
+
const incomingUpdatedAt = new Date(normalizedSummary.updatedAt).getTime();
|
|
8631
|
+
const preferIncoming = !existing || incomingUpdatedAt >= existingUpdatedAt;
|
|
8632
|
+
const latest = preferIncoming ? normalizedSummary : existing;
|
|
8633
|
+
const fallback = preferIncoming ? existing : normalizedSummary;
|
|
8634
|
+
dedupedById.set(normalizedSummary.conversationId, __spreadProps(__spreadValues(__spreadValues({}, fallback || {}), latest || {}), {
|
|
8635
|
+
createdAt: (existing == null ? void 0 : existing.createdAt) || normalizedSummary.createdAt,
|
|
8636
|
+
updatedAt: (latest == null ? void 0 : latest.updatedAt) || (fallback == null ? void 0 : fallback.updatedAt) || normalizedSummary.updatedAt,
|
|
8637
|
+
title: (latest == null ? void 0 : latest.title) || (fallback == null ? void 0 : fallback.title) || "",
|
|
8638
|
+
summary: (latest == null ? void 0 : latest.summary) || (fallback == null ? void 0 : fallback.summary),
|
|
8639
|
+
agentId: (latest == null ? void 0 : latest.agentId) || (fallback == null ? void 0 : fallback.agentId),
|
|
8640
|
+
messageCount: typeof (latest == null ? void 0 : latest.messageCount) === "number" ? latest.messageCount : fallback == null ? void 0 : fallback.messageCount
|
|
8641
|
+
}));
|
|
8642
|
+
return Array.from(dedupedById.values()).sort(
|
|
8643
|
+
(a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
|
|
8644
|
+
);
|
|
8645
|
+
};
|
|
8646
|
+
var buildOptimisticConversationSummary = (conversation) => {
|
|
8647
|
+
const conversationId = typeof conversation.conversationId === "string" ? conversation.conversationId.trim() : "";
|
|
8648
|
+
if (!conversationId || conversationId.startsWith("new-")) {
|
|
8649
|
+
return null;
|
|
8650
|
+
}
|
|
8651
|
+
const historyKeys = Object.keys(conversation.history || {});
|
|
8652
|
+
if (historyKeys.length === 0 && conversation.title === "New conversation") {
|
|
8653
|
+
return null;
|
|
8654
|
+
}
|
|
8655
|
+
const firstPrompt = historyKeys[0] ? stripHistoryPromptTimestamp(historyKeys[0]) : "";
|
|
8656
|
+
const title = truncatePromptForTitle(firstPrompt || conversation.title || "New conversation");
|
|
8657
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
8658
|
+
return {
|
|
8659
|
+
conversationId,
|
|
8660
|
+
title,
|
|
8661
|
+
createdAt: now,
|
|
8662
|
+
updatedAt: now,
|
|
8663
|
+
agentId: conversation.agentId,
|
|
8664
|
+
messageCount: historyKeys.length > 0 ? historyKeys.length * 2 : void 0
|
|
8665
|
+
};
|
|
8666
|
+
};
|
|
8436
8667
|
var EMPTY_ARRAY = [];
|
|
8437
8668
|
var EMPTY_HISTORY = {};
|
|
8438
8669
|
var ChatPanelWrapper = ({
|
|
@@ -8836,9 +9067,13 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
8836
9067
|
buildAgentAwarenessInstructions,
|
|
8837
9068
|
agentList
|
|
8838
9069
|
} = useAgentRegistry(agentIds, { url, localOverrides });
|
|
9070
|
+
const getAgentRef = useRef7(getAgent);
|
|
9071
|
+
useEffect10(() => {
|
|
9072
|
+
getAgentRef.current = getAgent;
|
|
9073
|
+
}, [getAgent]);
|
|
8839
9074
|
const fetchInProgressRef = useRef7(false);
|
|
8840
9075
|
const loadingTranscriptIdsRef = useRef7(/* @__PURE__ */ new Set());
|
|
8841
|
-
const
|
|
9076
|
+
const [conversationListRefreshNonce, setConversationListRefreshNonce] = useState9(0);
|
|
8842
9077
|
const checkedPromptsRef = useRef7(/* @__PURE__ */ new Set());
|
|
8843
9078
|
const fetchingPromptsRef = useRef7(/* @__PURE__ */ new Set());
|
|
8844
9079
|
const failedPromptsRef = useRef7(/* @__PURE__ */ new Map());
|
|
@@ -8846,6 +9081,34 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
8846
9081
|
activeConversationsRef.current = activeConversations;
|
|
8847
9082
|
const currentConversationIdRef = useRef7(currentConversationId);
|
|
8848
9083
|
currentConversationIdRef.current = currentConversationId;
|
|
9084
|
+
const controlledConversationIdRef = useRef7(controlledConversationId);
|
|
9085
|
+
controlledConversationIdRef.current = controlledConversationId;
|
|
9086
|
+
const requestConversationListRefresh = useCallback4(() => {
|
|
9087
|
+
setConversationListRefreshNonce((prev) => prev + 1);
|
|
9088
|
+
}, []);
|
|
9089
|
+
const upsertApiConversationFromHistory = useCallback4(
|
|
9090
|
+
(conversationId, history, fallbackTitle) => {
|
|
9091
|
+
const firstPromptKey = Object.keys(history)[0];
|
|
9092
|
+
const firstPrompt = firstPromptKey ? stripHistoryPromptTimestamp(firstPromptKey) : "";
|
|
9093
|
+
const title = truncatePromptForTitle(firstPrompt || fallbackTitle || "New conversation");
|
|
9094
|
+
const messageCount = Object.keys(history).length * 2;
|
|
9095
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
9096
|
+
setApiConversations(
|
|
9097
|
+
(prev) => {
|
|
9098
|
+
var _a2, _b2;
|
|
9099
|
+
return upsertConversationSummary(prev, {
|
|
9100
|
+
conversationId,
|
|
9101
|
+
title,
|
|
9102
|
+
createdAt: ((_a2 = prev.find((conversation2) => conversation2.conversationId === conversationId)) == null ? void 0 : _a2.createdAt) || timestamp,
|
|
9103
|
+
updatedAt: timestamp,
|
|
9104
|
+
agentId: ((_b2 = prev.find((conversation2) => conversation2.conversationId === conversationId)) == null ? void 0 : _b2.agentId) || currentAgentId,
|
|
9105
|
+
messageCount
|
|
9106
|
+
});
|
|
9107
|
+
}
|
|
9108
|
+
);
|
|
9109
|
+
},
|
|
9110
|
+
[currentAgentId]
|
|
9111
|
+
);
|
|
8849
9112
|
const commitConversationSelection = useCallback4(
|
|
8850
9113
|
(conversationId, notifyChange) => {
|
|
8851
9114
|
const shouldSyncLocalState = !isConversationControlled || !notifyChange || controlledConversationId === conversationId;
|
|
@@ -8913,7 +9176,7 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
8913
9176
|
fetchingPromptsRef.current.add(conversationId);
|
|
8914
9177
|
setLoadingPrompts((prev) => new Set(prev).add(conversationId));
|
|
8915
9178
|
const agentIdToUse = agentIdForConversation || currentAgentId;
|
|
8916
|
-
const agentProfile =
|
|
9179
|
+
const agentProfile = getAgentRef.current(agentIdToUse);
|
|
8917
9180
|
const projectId = (_a2 = agentProfile == null ? void 0 : agentProfile.metadata) == null ? void 0 : _a2.projectId;
|
|
8918
9181
|
if (!apiKey || !projectId) {
|
|
8919
9182
|
fetchingPromptsRef.current.delete(conversationId);
|
|
@@ -8978,11 +9241,8 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
8978
9241
|
return next;
|
|
8979
9242
|
});
|
|
8980
9243
|
}
|
|
8981
|
-
}), [apiKey, currentAgentId
|
|
8982
|
-
const fetchConversations = useCallback4((agentId, signal) => __async(void 0, null, function* () {
|
|
8983
|
-
var _a2;
|
|
8984
|
-
const agentProfile = getAgent(agentId);
|
|
8985
|
-
const projectId = (_a2 = agentProfile == null ? void 0 : agentProfile.metadata) == null ? void 0 : _a2.projectId;
|
|
9244
|
+
}), [apiKey, currentAgentId]);
|
|
9245
|
+
const fetchConversations = useCallback4((agentId, projectId, signal) => __async(void 0, null, function* () {
|
|
8986
9246
|
if (!agentId || !apiKey || !projectId) {
|
|
8987
9247
|
setApiConversations([]);
|
|
8988
9248
|
return;
|
|
@@ -9008,7 +9268,38 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
9008
9268
|
const payload = yield response.json();
|
|
9009
9269
|
const normalized = normalizeConversationListPayload(payload);
|
|
9010
9270
|
if (!(signal == null ? void 0 : signal.aborted)) {
|
|
9011
|
-
setApiConversations(
|
|
9271
|
+
setApiConversations((prev) => {
|
|
9272
|
+
const next = [...normalized];
|
|
9273
|
+
const optimisticIds = /* @__PURE__ */ new Set();
|
|
9274
|
+
const trackedConversationId = controlledConversationIdRef.current;
|
|
9275
|
+
if (trackedConversationId) {
|
|
9276
|
+
optimisticIds.add(trackedConversationId);
|
|
9277
|
+
}
|
|
9278
|
+
activeConversationsRef.current.forEach((conversation2) => {
|
|
9279
|
+
const optimisticSummary = buildOptimisticConversationSummary(conversation2);
|
|
9280
|
+
if (!optimisticSummary) {
|
|
9281
|
+
return;
|
|
9282
|
+
}
|
|
9283
|
+
optimisticIds.add(optimisticSummary.conversationId);
|
|
9284
|
+
const existing = prev.find(
|
|
9285
|
+
(candidate) => candidate.conversationId === optimisticSummary.conversationId
|
|
9286
|
+
);
|
|
9287
|
+
next.push(__spreadProps(__spreadValues({}, optimisticSummary), {
|
|
9288
|
+
createdAt: (existing == null ? void 0 : existing.createdAt) || optimisticSummary.createdAt,
|
|
9289
|
+
updatedAt: optimisticSummary.updatedAt
|
|
9290
|
+
}));
|
|
9291
|
+
});
|
|
9292
|
+
let merged = normalizeConversationListPayload(next);
|
|
9293
|
+
if (optimisticIds.size > 0) {
|
|
9294
|
+
prev.forEach((conversation2) => {
|
|
9295
|
+
if (!optimisticIds.has(conversation2.conversationId)) {
|
|
9296
|
+
return;
|
|
9297
|
+
}
|
|
9298
|
+
merged = upsertConversationSummary(merged, conversation2);
|
|
9299
|
+
});
|
|
9300
|
+
}
|
|
9301
|
+
return merged;
|
|
9302
|
+
});
|
|
9012
9303
|
const now = /* @__PURE__ */ new Date();
|
|
9013
9304
|
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
9014
9305
|
const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1e3);
|
|
@@ -9029,7 +9320,7 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
9029
9320
|
setConversationsLoading(false);
|
|
9030
9321
|
}
|
|
9031
9322
|
}
|
|
9032
|
-
}), [apiKey, customerId,
|
|
9323
|
+
}), [apiKey, customerId, fetchFirstPrompt]);
|
|
9033
9324
|
const loadConversationTranscript = useCallback4((conversationId, agentIdForConversation, title, notifyConversationChange = true) => __async(void 0, null, function* () {
|
|
9034
9325
|
var _a2;
|
|
9035
9326
|
const existingActive = activeConversationsRef.current.get(conversationId);
|
|
@@ -9042,7 +9333,7 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
9042
9333
|
return;
|
|
9043
9334
|
}
|
|
9044
9335
|
const agentIdToUse = agentIdForConversation || currentAgentId;
|
|
9045
|
-
const agentProfile =
|
|
9336
|
+
const agentProfile = getAgentRef.current(agentIdToUse);
|
|
9046
9337
|
const projectId = (_a2 = agentProfile == null ? void 0 : agentProfile.metadata) == null ? void 0 : _a2.projectId;
|
|
9047
9338
|
if (!apiKey || !projectId) {
|
|
9048
9339
|
setConversationsError("Missing API key or project ID");
|
|
@@ -9118,7 +9409,7 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
9118
9409
|
loadingTranscriptIdsRef.current.delete(conversationId);
|
|
9119
9410
|
setLoadingConversationId((prev) => prev === conversationId ? null : prev);
|
|
9120
9411
|
}
|
|
9121
|
-
}), [apiKey, commitConversationSelection, conversationFirstPrompts, currentAgentId
|
|
9412
|
+
}), [apiKey, commitConversationSelection, conversationFirstPrompts, currentAgentId]);
|
|
9122
9413
|
useEffect10(() => {
|
|
9123
9414
|
if (!isConversationControlled) return;
|
|
9124
9415
|
const targetConversationId = controlledConversationId;
|
|
@@ -9183,21 +9474,32 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
9183
9474
|
loadConversationTranscript,
|
|
9184
9475
|
loadingConversationId
|
|
9185
9476
|
]);
|
|
9477
|
+
const currentAgentProjectId = useMemo4(() => {
|
|
9478
|
+
var _a2;
|
|
9479
|
+
const agentProfile = getAgent(currentAgentId);
|
|
9480
|
+
return ((_a2 = agentProfile == null ? void 0 : agentProfile.metadata) == null ? void 0 : _a2.projectId) || "";
|
|
9481
|
+
}, [currentAgentId, getAgent]);
|
|
9186
9482
|
const handleRefreshConversations = useCallback4(() => {
|
|
9187
|
-
|
|
9188
|
-
}, [
|
|
9483
|
+
requestConversationListRefresh();
|
|
9484
|
+
}, [requestConversationListRefresh]);
|
|
9189
9485
|
useEffect10(() => {
|
|
9190
|
-
var _a2;
|
|
9191
9486
|
if (!showConversationHistory) return;
|
|
9192
9487
|
if (!agentsLoading && currentAgentId && apiKey) {
|
|
9193
|
-
|
|
9194
|
-
|
|
9195
|
-
|
|
9196
|
-
|
|
9197
|
-
fetchConversations(currentAgentId);
|
|
9488
|
+
if (currentAgentProjectId) {
|
|
9489
|
+
const controller = new AbortController();
|
|
9490
|
+
fetchConversations(currentAgentId, currentAgentProjectId, controller.signal);
|
|
9491
|
+
return () => controller.abort();
|
|
9198
9492
|
}
|
|
9199
9493
|
}
|
|
9200
|
-
}, [
|
|
9494
|
+
}, [
|
|
9495
|
+
agentsLoading,
|
|
9496
|
+
apiKey,
|
|
9497
|
+
conversationListRefreshNonce,
|
|
9498
|
+
currentAgentId,
|
|
9499
|
+
currentAgentProjectId,
|
|
9500
|
+
fetchConversations,
|
|
9501
|
+
showConversationHistory
|
|
9502
|
+
]);
|
|
9201
9503
|
const handleNewConversation = useCallback4(() => {
|
|
9202
9504
|
const tempId = createDraftConversation(currentAgentId);
|
|
9203
9505
|
commitConversationSelection(tempId, true);
|
|
@@ -9521,11 +9823,7 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
9521
9823
|
if (title === "New conversation" && Object.keys(history).length > 0) {
|
|
9522
9824
|
const firstPrompt = Object.keys(history)[0];
|
|
9523
9825
|
if (firstPrompt) {
|
|
9524
|
-
|
|
9525
|
-
const isoMatch = cleanPrompt.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z:(.+)/);
|
|
9526
|
-
if (isoMatch && isoMatch[1]) {
|
|
9527
|
-
cleanPrompt = isoMatch[1];
|
|
9528
|
-
}
|
|
9826
|
+
const cleanPrompt = stripHistoryPromptTimestamp(firstPrompt);
|
|
9529
9827
|
title = cleanPrompt.length > 60 ? cleanPrompt.slice(0, 57) + "..." : cleanPrompt;
|
|
9530
9828
|
}
|
|
9531
9829
|
}
|
|
@@ -9538,6 +9836,12 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
9538
9836
|
}
|
|
9539
9837
|
return prev;
|
|
9540
9838
|
});
|
|
9839
|
+
const existingActiveConversation = activeConversationsRef.current.get(targetConversationId);
|
|
9840
|
+
upsertApiConversationFromHistory(
|
|
9841
|
+
targetConversationId,
|
|
9842
|
+
history,
|
|
9843
|
+
existingActiveConversation == null ? void 0 : existingActiveConversation.title
|
|
9844
|
+
);
|
|
9541
9845
|
}
|
|
9542
9846
|
const lastEntry = Object.entries(history).pop();
|
|
9543
9847
|
if (lastEntry) {
|
|
@@ -9557,9 +9861,11 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
9557
9861
|
}
|
|
9558
9862
|
},
|
|
9559
9863
|
[
|
|
9864
|
+
activeConversationsRef,
|
|
9560
9865
|
currentAgentId,
|
|
9561
9866
|
historyChangedCallback,
|
|
9562
|
-
agents
|
|
9867
|
+
agents,
|
|
9868
|
+
upsertApiConversationFromHistory
|
|
9563
9869
|
]
|
|
9564
9870
|
);
|
|
9565
9871
|
const handleLoadingChange = useCallback4((isLoading, conversationId) => {
|
|
@@ -9568,6 +9874,9 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
9568
9874
|
setActiveConversations((prev) => {
|
|
9569
9875
|
const existing = prev.get(targetConversationId);
|
|
9570
9876
|
if (existing && existing.isLoading !== isLoading) {
|
|
9877
|
+
if (existing.isLoading && !isLoading) {
|
|
9878
|
+
requestConversationListRefresh();
|
|
9879
|
+
}
|
|
9571
9880
|
const next = new Map(prev);
|
|
9572
9881
|
next.set(targetConversationId, __spreadProps(__spreadValues({}, existing), {
|
|
9573
9882
|
isLoading
|
|
@@ -9577,7 +9886,7 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
9577
9886
|
return prev;
|
|
9578
9887
|
});
|
|
9579
9888
|
}
|
|
9580
|
-
}, []);
|
|
9889
|
+
}, [requestConversationListRefresh]);
|
|
9581
9890
|
const handleHandoffConfirm = useCallback4(() => {
|
|
9582
9891
|
if (suggestedAgent) {
|
|
9583
9892
|
handleAgentSwitch(suggestedAgent);
|
|
@@ -9623,7 +9932,8 @@ var AIAgentPanel = React15.forwardRef(({
|
|
|
9623
9932
|
if (currentConversationIdRef.current === tempId) {
|
|
9624
9933
|
commitConversationSelection(realId, true);
|
|
9625
9934
|
}
|
|
9626
|
-
|
|
9935
|
+
requestConversationListRefresh();
|
|
9936
|
+
}, [commitConversationSelection, requestConversationListRefresh]);
|
|
9627
9937
|
const toggleCollapse = useCallback4(() => {
|
|
9628
9938
|
if (!collapsible) return;
|
|
9629
9939
|
const newValue = !isCollapsed;
|