llmasaservice-ui 0.12.2 → 0.12.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.css +58 -0
- package/dist/index.js +86 -14
- package/dist/index.mjs +86 -14
- package/package.json +1 -1
- package/src/ChatPanel.css +69 -0
- package/src/ChatPanel.tsx +105 -30
- package/test_response_cleaning.js +0 -0
- package/test_tag_extraction.js +125 -0
- package/test_thinking_extraction.js +0 -0
- package/test_thinking_tag.js +0 -0
package/dist/index.css
CHANGED
|
@@ -395,6 +395,7 @@
|
|
|
395
395
|
display: flex;
|
|
396
396
|
align-items: center;
|
|
397
397
|
justify-content: center;
|
|
398
|
+
margin-top: 4px;
|
|
398
399
|
font-size: 10px;
|
|
399
400
|
color: #666;
|
|
400
401
|
opacity: 0.7;
|
|
@@ -720,3 +721,60 @@
|
|
|
720
721
|
.dark-theme .tool-status {
|
|
721
722
|
color: #999;
|
|
722
723
|
}
|
|
724
|
+
.reasoning-section,
|
|
725
|
+
.searching-section {
|
|
726
|
+
margin: 1rem 0;
|
|
727
|
+
padding: 0.75rem;
|
|
728
|
+
border-radius: var(--border-radius);
|
|
729
|
+
border-left: 4px solid;
|
|
730
|
+
background-color: var(--reasoning-background-color, #f8f9fa);
|
|
731
|
+
}
|
|
732
|
+
.reasoning-section {
|
|
733
|
+
border-left-color: var(--reasoning-border-color, #007bff);
|
|
734
|
+
background-color: var(--reasoning-background-color, #f0f8ff);
|
|
735
|
+
}
|
|
736
|
+
.searching-section {
|
|
737
|
+
border-left-color: var(--searching-border-color, #28a745);
|
|
738
|
+
background-color: var(--searching-background-color, #f0fff0);
|
|
739
|
+
}
|
|
740
|
+
.reasoning-header,
|
|
741
|
+
.searching-header {
|
|
742
|
+
font-weight: 600;
|
|
743
|
+
font-size: 0.9rem;
|
|
744
|
+
margin-bottom: 0.5rem;
|
|
745
|
+
color: var(--prompt-text-color);
|
|
746
|
+
opacity: 0.8;
|
|
747
|
+
}
|
|
748
|
+
.reasoning-content,
|
|
749
|
+
.searching-content {
|
|
750
|
+
font-size: 0.85rem;
|
|
751
|
+
line-height: 1.4;
|
|
752
|
+
color: var(--prompt-text-color);
|
|
753
|
+
opacity: 0.9;
|
|
754
|
+
font-style: italic;
|
|
755
|
+
}
|
|
756
|
+
.dark-theme .reasoning-section {
|
|
757
|
+
background-color: var(--reasoning-background-color-dark, #1a1a2e);
|
|
758
|
+
border-left-color: var(--reasoning-border-color-dark, #4a9eff);
|
|
759
|
+
}
|
|
760
|
+
.dark-theme .searching-section {
|
|
761
|
+
background-color: var(--searching-background-color-dark, #1a2e1a);
|
|
762
|
+
border-left-color: var(--searching-border-color-dark, #4ade80);
|
|
763
|
+
}
|
|
764
|
+
.dark-theme .reasoning-header,
|
|
765
|
+
.dark-theme .searching-header,
|
|
766
|
+
.dark-theme .reasoning-content,
|
|
767
|
+
.dark-theme .searching-content {
|
|
768
|
+
color: var(--response-text-color);
|
|
769
|
+
}
|
|
770
|
+
.streaming-response {
|
|
771
|
+
animation: fadeIn 0.3s ease-in-out;
|
|
772
|
+
}
|
|
773
|
+
@keyframes fadeIn {
|
|
774
|
+
from {
|
|
775
|
+
opacity: 0;
|
|
776
|
+
}
|
|
777
|
+
to {
|
|
778
|
+
opacity: 1;
|
|
779
|
+
}
|
|
780
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -272,30 +272,35 @@ var ChatPanel = ({
|
|
|
272
272
|
const [iframeUrl, setIframeUrl] = (0, import_react3.useState)(null);
|
|
273
273
|
const responseAreaRef = (0, import_react3.useRef)(null);
|
|
274
274
|
const extractLastThinkingTag = (text) => {
|
|
275
|
-
var _a2, _b;
|
|
275
|
+
var _a2, _b, _c, _d;
|
|
276
|
+
console.log("extractLastThinkingTag called with:", (text == null ? void 0 : text.length) ? `${text.substring(0, 100)}...` : "empty");
|
|
276
277
|
if (!text) return "Thinking";
|
|
277
|
-
const reasoningRegex = /<reasoning>(
|
|
278
|
-
const searchingRegex = /<searching>(
|
|
278
|
+
const reasoningRegex = /<reasoning>([\s\S]*?)<\/reasoning>/gi;
|
|
279
|
+
const searchingRegex = /<searching>([\s\S]*?)<\/searching>/gi;
|
|
279
280
|
const allMatches = [];
|
|
280
281
|
let reasoningMatch;
|
|
281
282
|
while ((reasoningMatch = reasoningRegex.exec(text)) !== null) {
|
|
283
|
+
console.log("Found reasoning match:", ((_a2 = reasoningMatch[1]) == null ? void 0 : _a2.substring(0, 50)) + "...");
|
|
282
284
|
allMatches.push({
|
|
283
|
-
content: ((
|
|
285
|
+
content: ((_b = reasoningMatch[1]) == null ? void 0 : _b.trim()) || "",
|
|
284
286
|
index: reasoningMatch.index,
|
|
285
287
|
type: "reasoning"
|
|
286
288
|
});
|
|
287
289
|
}
|
|
288
290
|
let searchingMatch;
|
|
289
291
|
while ((searchingMatch = searchingRegex.exec(text)) !== null) {
|
|
292
|
+
console.log("Found searching match:", ((_c = searchingMatch[1]) == null ? void 0 : _c.substring(0, 50)) + "...");
|
|
290
293
|
allMatches.push({
|
|
291
|
-
content: ((
|
|
294
|
+
content: ((_d = searchingMatch[1]) == null ? void 0 : _d.trim()) || "",
|
|
292
295
|
index: searchingMatch.index,
|
|
293
296
|
type: "searching"
|
|
294
297
|
});
|
|
295
298
|
}
|
|
299
|
+
console.log("Total matches found:", allMatches.length);
|
|
296
300
|
if (allMatches.length > 0) {
|
|
297
301
|
const lastMatch = allMatches.sort((a, b) => b.index - a.index)[0];
|
|
298
302
|
let content = (lastMatch == null ? void 0 : lastMatch.content) || "Thinking";
|
|
303
|
+
console.log("Last match content:", content == null ? void 0 : content.substring(0, 100));
|
|
299
304
|
content = content.replace(/\*\*(.*?)\*\*/g, "$1");
|
|
300
305
|
content = content.replace(/\*(.*?)\*/g, "$1");
|
|
301
306
|
content = content.replace(/\n+/g, " ");
|
|
@@ -304,16 +309,46 @@ var ChatPanel = ({
|
|
|
304
309
|
if (content.length > 80) {
|
|
305
310
|
content = content.substring(0, 77) + "...";
|
|
306
311
|
}
|
|
312
|
+
console.log("Final extracted content:", content);
|
|
307
313
|
return content || "Thinking";
|
|
308
314
|
}
|
|
315
|
+
console.log("No matches found, returning 'Thinking'");
|
|
309
316
|
return "Thinking";
|
|
310
317
|
};
|
|
311
|
-
const
|
|
318
|
+
const processResponseContent = (text, isStreaming = false) => {
|
|
312
319
|
if (!text) return "";
|
|
313
|
-
let
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
320
|
+
let processedText = text;
|
|
321
|
+
processedText = processedText.replace(
|
|
322
|
+
/<reasoning>([\s\S]*?)<\/reasoning>/gi,
|
|
323
|
+
(match, content) => {
|
|
324
|
+
const trimmedContent = content.trim();
|
|
325
|
+
if (!trimmedContent) return "";
|
|
326
|
+
return `
|
|
327
|
+
|
|
328
|
+
<div class="reasoning-section">
|
|
329
|
+
<div class="reasoning-header">\u{1F914} Reasoning</div>
|
|
330
|
+
<div class="reasoning-content">${trimmedContent}</div>
|
|
331
|
+
</div>
|
|
332
|
+
|
|
333
|
+
`;
|
|
334
|
+
}
|
|
335
|
+
);
|
|
336
|
+
processedText = processedText.replace(
|
|
337
|
+
/<searching>([\s\S]*?)<\/searching>/gi,
|
|
338
|
+
(match, content) => {
|
|
339
|
+
const trimmedContent = content.trim();
|
|
340
|
+
if (!trimmedContent) return "";
|
|
341
|
+
return `
|
|
342
|
+
|
|
343
|
+
<div class="searching-section">
|
|
344
|
+
<div class="searching-header">\u{1F50D} Searching</div>
|
|
345
|
+
<div class="searching-content">${trimmedContent}</div>
|
|
346
|
+
</div>
|
|
347
|
+
|
|
348
|
+
`;
|
|
349
|
+
}
|
|
350
|
+
);
|
|
351
|
+
return processedText;
|
|
317
352
|
};
|
|
318
353
|
const getBrowserInfo = () => {
|
|
319
354
|
try {
|
|
@@ -465,6 +500,16 @@ var ChatPanel = ({
|
|
|
465
500
|
};
|
|
466
501
|
})
|
|
467
502
|
});
|
|
503
|
+
(0, import_react3.useEffect)(() => {
|
|
504
|
+
console.log("Streaming state changed:", {
|
|
505
|
+
isLoading,
|
|
506
|
+
idle,
|
|
507
|
+
responseLength: (response == null ? void 0 : response.length) || 0,
|
|
508
|
+
lastCallId,
|
|
509
|
+
hasResponse: !!response,
|
|
510
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
511
|
+
});
|
|
512
|
+
}, [isLoading, idle, response, lastCallId]);
|
|
468
513
|
(0, import_react3.useEffect)(() => {
|
|
469
514
|
setShowEmailPanel(customerEmailCaptureMode !== "HIDE");
|
|
470
515
|
if (customerEmailCaptureMode === "REQUIRED") {
|
|
@@ -887,6 +932,14 @@ var ChatPanel = ({
|
|
|
887
932
|
});
|
|
888
933
|
(0, import_react3.useEffect)(() => {
|
|
889
934
|
if (response && response.length > 0) {
|
|
935
|
+
console.log("Response updated:", {
|
|
936
|
+
length: response.length,
|
|
937
|
+
isLoading,
|
|
938
|
+
idle,
|
|
939
|
+
hasReasoningTags: response.includes("<reasoning>"),
|
|
940
|
+
hasSearchingTags: response.includes("<searching>"),
|
|
941
|
+
preview: response.substring(0, 200) + "..."
|
|
942
|
+
});
|
|
890
943
|
setIsLoading(false);
|
|
891
944
|
let newResponse = response;
|
|
892
945
|
const toolRequests = [];
|
|
@@ -958,6 +1011,13 @@ var ChatPanel = ({
|
|
|
958
1011
|
} else {
|
|
959
1012
|
setPendingToolRequests([]);
|
|
960
1013
|
}
|
|
1014
|
+
const cleanedContent = processResponseContent(newResponse);
|
|
1015
|
+
console.log("Processed content:", {
|
|
1016
|
+
originalLength: newResponse.length,
|
|
1017
|
+
processedLength: cleanedContent.length,
|
|
1018
|
+
wasContentRemoved: newResponse.length !== cleanedContent.length,
|
|
1019
|
+
processedPreview: cleanedContent.substring(0, 200) + "..."
|
|
1020
|
+
});
|
|
961
1021
|
setHistory((prevHistory) => {
|
|
962
1022
|
const existingEntry = prevHistory[lastKey != null ? lastKey : ""] || {
|
|
963
1023
|
content: "",
|
|
@@ -966,7 +1026,7 @@ var ChatPanel = ({
|
|
|
966
1026
|
return __spreadProps(__spreadValues({}, prevHistory), {
|
|
967
1027
|
[lastKey != null ? lastKey : ""]: __spreadProps(__spreadValues({}, existingEntry), {
|
|
968
1028
|
// This preserves toolCalls and toolResponses
|
|
969
|
-
content:
|
|
1029
|
+
content: cleanedContent,
|
|
970
1030
|
callId: lastCallId
|
|
971
1031
|
})
|
|
972
1032
|
});
|
|
@@ -1184,7 +1244,7 @@ var ChatPanel = ({
|
|
|
1184
1244
|
setHistory((prevHistory) => {
|
|
1185
1245
|
return __spreadProps(__spreadValues({}, prevHistory), {
|
|
1186
1246
|
[lastKey != null ? lastKey : ""]: {
|
|
1187
|
-
content:
|
|
1247
|
+
content: processResponseContent(response) + "\n\n(response cancelled)",
|
|
1188
1248
|
callId: lastCallId
|
|
1189
1249
|
}
|
|
1190
1250
|
});
|
|
@@ -1212,7 +1272,7 @@ var ChatPanel = ({
|
|
|
1212
1272
|
messagesAndHistory.push({ role: "user", content: promptToSend });
|
|
1213
1273
|
messagesAndHistory.push({
|
|
1214
1274
|
role: "assistant",
|
|
1215
|
-
content:
|
|
1275
|
+
content: processResponseContent(response2.content)
|
|
1216
1276
|
});
|
|
1217
1277
|
});
|
|
1218
1278
|
let nextPromptToSend = suggestion != null ? suggestion : nextPrompt;
|
|
@@ -1579,7 +1639,19 @@ var ChatPanel = ({
|
|
|
1579
1639
|
var _a2, _b;
|
|
1580
1640
|
const isLastEntry = index === Object.keys(history).length - 1;
|
|
1581
1641
|
const hasToolData = !!((((_a2 = historyEntry == null ? void 0 : historyEntry.toolCalls) == null ? void 0 : _a2.length) || 0) > 0 || (((_b = historyEntry == null ? void 0 : historyEntry.toolResponses) == null ? void 0 : _b.length) || 0) > 0);
|
|
1582
|
-
return /* @__PURE__ */ import_react3.default.createElement("div", { className: "history-entry", key: index }, hideInitialPrompt && index === 0 ? null : /* @__PURE__ */ import_react3.default.createElement("div", { className: "prompt" }, formatPromptForDisplay(prompt)), /* @__PURE__ */ import_react3.default.createElement("div", { className: "response" }, index === Object.keys(history).length - 1 && isLoading
|
|
1642
|
+
return /* @__PURE__ */ import_react3.default.createElement("div", { className: "history-entry", key: index }, hideInitialPrompt && index === 0 ? null : /* @__PURE__ */ import_react3.default.createElement("div", { className: "prompt" }, formatPromptForDisplay(prompt)), /* @__PURE__ */ import_react3.default.createElement("div", { className: "response" }, index === Object.keys(history).length - 1 && isLoading ? /* @__PURE__ */ import_react3.default.createElement("div", { className: "streaming-response" }, response && response.length > 0 ? /* @__PURE__ */ import_react3.default.createElement(
|
|
1643
|
+
import_react_markdown.default,
|
|
1644
|
+
{
|
|
1645
|
+
className: markdownClass,
|
|
1646
|
+
remarkPlugins: [import_remark_gfm.default],
|
|
1647
|
+
rehypePlugins: [import_rehype_raw.default],
|
|
1648
|
+
components: {
|
|
1649
|
+
/*a: CustomLink,*/
|
|
1650
|
+
code: CodeBlock
|
|
1651
|
+
}
|
|
1652
|
+
},
|
|
1653
|
+
processResponseContent(response, true)
|
|
1654
|
+
) : /* @__PURE__ */ import_react3.default.createElement("div", { className: "loading-text" }, extractLastThinkingTag(response || ""), "\xA0", /* @__PURE__ */ import_react3.default.createElement("div", { className: "dot" }), /* @__PURE__ */ import_react3.default.createElement("div", { className: "dot" }), /* @__PURE__ */ import_react3.default.createElement("div", { className: "dot" }))) : /* @__PURE__ */ import_react3.default.createElement(
|
|
1583
1655
|
import_react_markdown.default,
|
|
1584
1656
|
{
|
|
1585
1657
|
className: markdownClass,
|
package/dist/index.mjs
CHANGED
|
@@ -244,30 +244,35 @@ var ChatPanel = ({
|
|
|
244
244
|
const [iframeUrl, setIframeUrl] = useState2(null);
|
|
245
245
|
const responseAreaRef = useRef(null);
|
|
246
246
|
const extractLastThinkingTag = (text) => {
|
|
247
|
-
var _a2, _b;
|
|
247
|
+
var _a2, _b, _c, _d;
|
|
248
|
+
console.log("extractLastThinkingTag called with:", (text == null ? void 0 : text.length) ? `${text.substring(0, 100)}...` : "empty");
|
|
248
249
|
if (!text) return "Thinking";
|
|
249
|
-
const reasoningRegex = /<reasoning>(
|
|
250
|
-
const searchingRegex = /<searching>(
|
|
250
|
+
const reasoningRegex = /<reasoning>([\s\S]*?)<\/reasoning>/gi;
|
|
251
|
+
const searchingRegex = /<searching>([\s\S]*?)<\/searching>/gi;
|
|
251
252
|
const allMatches = [];
|
|
252
253
|
let reasoningMatch;
|
|
253
254
|
while ((reasoningMatch = reasoningRegex.exec(text)) !== null) {
|
|
255
|
+
console.log("Found reasoning match:", ((_a2 = reasoningMatch[1]) == null ? void 0 : _a2.substring(0, 50)) + "...");
|
|
254
256
|
allMatches.push({
|
|
255
|
-
content: ((
|
|
257
|
+
content: ((_b = reasoningMatch[1]) == null ? void 0 : _b.trim()) || "",
|
|
256
258
|
index: reasoningMatch.index,
|
|
257
259
|
type: "reasoning"
|
|
258
260
|
});
|
|
259
261
|
}
|
|
260
262
|
let searchingMatch;
|
|
261
263
|
while ((searchingMatch = searchingRegex.exec(text)) !== null) {
|
|
264
|
+
console.log("Found searching match:", ((_c = searchingMatch[1]) == null ? void 0 : _c.substring(0, 50)) + "...");
|
|
262
265
|
allMatches.push({
|
|
263
|
-
content: ((
|
|
266
|
+
content: ((_d = searchingMatch[1]) == null ? void 0 : _d.trim()) || "",
|
|
264
267
|
index: searchingMatch.index,
|
|
265
268
|
type: "searching"
|
|
266
269
|
});
|
|
267
270
|
}
|
|
271
|
+
console.log("Total matches found:", allMatches.length);
|
|
268
272
|
if (allMatches.length > 0) {
|
|
269
273
|
const lastMatch = allMatches.sort((a, b) => b.index - a.index)[0];
|
|
270
274
|
let content = (lastMatch == null ? void 0 : lastMatch.content) || "Thinking";
|
|
275
|
+
console.log("Last match content:", content == null ? void 0 : content.substring(0, 100));
|
|
271
276
|
content = content.replace(/\*\*(.*?)\*\*/g, "$1");
|
|
272
277
|
content = content.replace(/\*(.*?)\*/g, "$1");
|
|
273
278
|
content = content.replace(/\n+/g, " ");
|
|
@@ -276,16 +281,46 @@ var ChatPanel = ({
|
|
|
276
281
|
if (content.length > 80) {
|
|
277
282
|
content = content.substring(0, 77) + "...";
|
|
278
283
|
}
|
|
284
|
+
console.log("Final extracted content:", content);
|
|
279
285
|
return content || "Thinking";
|
|
280
286
|
}
|
|
287
|
+
console.log("No matches found, returning 'Thinking'");
|
|
281
288
|
return "Thinking";
|
|
282
289
|
};
|
|
283
|
-
const
|
|
290
|
+
const processResponseContent = (text, isStreaming = false) => {
|
|
284
291
|
if (!text) return "";
|
|
285
|
-
let
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
292
|
+
let processedText = text;
|
|
293
|
+
processedText = processedText.replace(
|
|
294
|
+
/<reasoning>([\s\S]*?)<\/reasoning>/gi,
|
|
295
|
+
(match, content) => {
|
|
296
|
+
const trimmedContent = content.trim();
|
|
297
|
+
if (!trimmedContent) return "";
|
|
298
|
+
return `
|
|
299
|
+
|
|
300
|
+
<div class="reasoning-section">
|
|
301
|
+
<div class="reasoning-header">\u{1F914} Reasoning</div>
|
|
302
|
+
<div class="reasoning-content">${trimmedContent}</div>
|
|
303
|
+
</div>
|
|
304
|
+
|
|
305
|
+
`;
|
|
306
|
+
}
|
|
307
|
+
);
|
|
308
|
+
processedText = processedText.replace(
|
|
309
|
+
/<searching>([\s\S]*?)<\/searching>/gi,
|
|
310
|
+
(match, content) => {
|
|
311
|
+
const trimmedContent = content.trim();
|
|
312
|
+
if (!trimmedContent) return "";
|
|
313
|
+
return `
|
|
314
|
+
|
|
315
|
+
<div class="searching-section">
|
|
316
|
+
<div class="searching-header">\u{1F50D} Searching</div>
|
|
317
|
+
<div class="searching-content">${trimmedContent}</div>
|
|
318
|
+
</div>
|
|
319
|
+
|
|
320
|
+
`;
|
|
321
|
+
}
|
|
322
|
+
);
|
|
323
|
+
return processedText;
|
|
289
324
|
};
|
|
290
325
|
const getBrowserInfo = () => {
|
|
291
326
|
try {
|
|
@@ -437,6 +472,16 @@ var ChatPanel = ({
|
|
|
437
472
|
};
|
|
438
473
|
})
|
|
439
474
|
});
|
|
475
|
+
useEffect2(() => {
|
|
476
|
+
console.log("Streaming state changed:", {
|
|
477
|
+
isLoading,
|
|
478
|
+
idle,
|
|
479
|
+
responseLength: (response == null ? void 0 : response.length) || 0,
|
|
480
|
+
lastCallId,
|
|
481
|
+
hasResponse: !!response,
|
|
482
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
483
|
+
});
|
|
484
|
+
}, [isLoading, idle, response, lastCallId]);
|
|
440
485
|
useEffect2(() => {
|
|
441
486
|
setShowEmailPanel(customerEmailCaptureMode !== "HIDE");
|
|
442
487
|
if (customerEmailCaptureMode === "REQUIRED") {
|
|
@@ -859,6 +904,14 @@ var ChatPanel = ({
|
|
|
859
904
|
});
|
|
860
905
|
useEffect2(() => {
|
|
861
906
|
if (response && response.length > 0) {
|
|
907
|
+
console.log("Response updated:", {
|
|
908
|
+
length: response.length,
|
|
909
|
+
isLoading,
|
|
910
|
+
idle,
|
|
911
|
+
hasReasoningTags: response.includes("<reasoning>"),
|
|
912
|
+
hasSearchingTags: response.includes("<searching>"),
|
|
913
|
+
preview: response.substring(0, 200) + "..."
|
|
914
|
+
});
|
|
862
915
|
setIsLoading(false);
|
|
863
916
|
let newResponse = response;
|
|
864
917
|
const toolRequests = [];
|
|
@@ -930,6 +983,13 @@ var ChatPanel = ({
|
|
|
930
983
|
} else {
|
|
931
984
|
setPendingToolRequests([]);
|
|
932
985
|
}
|
|
986
|
+
const cleanedContent = processResponseContent(newResponse);
|
|
987
|
+
console.log("Processed content:", {
|
|
988
|
+
originalLength: newResponse.length,
|
|
989
|
+
processedLength: cleanedContent.length,
|
|
990
|
+
wasContentRemoved: newResponse.length !== cleanedContent.length,
|
|
991
|
+
processedPreview: cleanedContent.substring(0, 200) + "..."
|
|
992
|
+
});
|
|
933
993
|
setHistory((prevHistory) => {
|
|
934
994
|
const existingEntry = prevHistory[lastKey != null ? lastKey : ""] || {
|
|
935
995
|
content: "",
|
|
@@ -938,7 +998,7 @@ var ChatPanel = ({
|
|
|
938
998
|
return __spreadProps(__spreadValues({}, prevHistory), {
|
|
939
999
|
[lastKey != null ? lastKey : ""]: __spreadProps(__spreadValues({}, existingEntry), {
|
|
940
1000
|
// This preserves toolCalls and toolResponses
|
|
941
|
-
content:
|
|
1001
|
+
content: cleanedContent,
|
|
942
1002
|
callId: lastCallId
|
|
943
1003
|
})
|
|
944
1004
|
});
|
|
@@ -1156,7 +1216,7 @@ var ChatPanel = ({
|
|
|
1156
1216
|
setHistory((prevHistory) => {
|
|
1157
1217
|
return __spreadProps(__spreadValues({}, prevHistory), {
|
|
1158
1218
|
[lastKey != null ? lastKey : ""]: {
|
|
1159
|
-
content:
|
|
1219
|
+
content: processResponseContent(response) + "\n\n(response cancelled)",
|
|
1160
1220
|
callId: lastCallId
|
|
1161
1221
|
}
|
|
1162
1222
|
});
|
|
@@ -1184,7 +1244,7 @@ var ChatPanel = ({
|
|
|
1184
1244
|
messagesAndHistory.push({ role: "user", content: promptToSend });
|
|
1185
1245
|
messagesAndHistory.push({
|
|
1186
1246
|
role: "assistant",
|
|
1187
|
-
content:
|
|
1247
|
+
content: processResponseContent(response2.content)
|
|
1188
1248
|
});
|
|
1189
1249
|
});
|
|
1190
1250
|
let nextPromptToSend = suggestion != null ? suggestion : nextPrompt;
|
|
@@ -1551,7 +1611,19 @@ var ChatPanel = ({
|
|
|
1551
1611
|
var _a2, _b;
|
|
1552
1612
|
const isLastEntry = index === Object.keys(history).length - 1;
|
|
1553
1613
|
const hasToolData = !!((((_a2 = historyEntry == null ? void 0 : historyEntry.toolCalls) == null ? void 0 : _a2.length) || 0) > 0 || (((_b = historyEntry == null ? void 0 : historyEntry.toolResponses) == null ? void 0 : _b.length) || 0) > 0);
|
|
1554
|
-
return /* @__PURE__ */ React3.createElement("div", { className: "history-entry", key: index }, hideInitialPrompt && index === 0 ? null : /* @__PURE__ */ React3.createElement("div", { className: "prompt" }, formatPromptForDisplay(prompt)), /* @__PURE__ */ React3.createElement("div", { className: "response" }, index === Object.keys(history).length - 1 && isLoading
|
|
1614
|
+
return /* @__PURE__ */ React3.createElement("div", { className: "history-entry", key: index }, hideInitialPrompt && index === 0 ? null : /* @__PURE__ */ React3.createElement("div", { className: "prompt" }, formatPromptForDisplay(prompt)), /* @__PURE__ */ React3.createElement("div", { className: "response" }, index === Object.keys(history).length - 1 && isLoading ? /* @__PURE__ */ React3.createElement("div", { className: "streaming-response" }, response && response.length > 0 ? /* @__PURE__ */ React3.createElement(
|
|
1615
|
+
ReactMarkdown,
|
|
1616
|
+
{
|
|
1617
|
+
className: markdownClass,
|
|
1618
|
+
remarkPlugins: [remarkGfm],
|
|
1619
|
+
rehypePlugins: [rehypeRaw],
|
|
1620
|
+
components: {
|
|
1621
|
+
/*a: CustomLink,*/
|
|
1622
|
+
code: CodeBlock
|
|
1623
|
+
}
|
|
1624
|
+
},
|
|
1625
|
+
processResponseContent(response, true)
|
|
1626
|
+
) : /* @__PURE__ */ React3.createElement("div", { className: "loading-text" }, extractLastThinkingTag(response || ""), "\xA0", /* @__PURE__ */ React3.createElement("div", { className: "dot" }), /* @__PURE__ */ React3.createElement("div", { className: "dot" }), /* @__PURE__ */ React3.createElement("div", { className: "dot" }))) : /* @__PURE__ */ React3.createElement(
|
|
1555
1627
|
ReactMarkdown,
|
|
1556
1628
|
{
|
|
1557
1629
|
className: markdownClass,
|
package/package.json
CHANGED
package/src/ChatPanel.css
CHANGED
|
@@ -490,6 +490,7 @@
|
|
|
490
490
|
display: flex;
|
|
491
491
|
align-items: center;
|
|
492
492
|
justify-content: center;
|
|
493
|
+
margin-top: 4px;
|
|
493
494
|
font-size: 10px;
|
|
494
495
|
color: #666;
|
|
495
496
|
opacity: 0.7;
|
|
@@ -885,4 +886,72 @@
|
|
|
885
886
|
/* Dark theme support */
|
|
886
887
|
.dark-theme .tool-status {
|
|
887
888
|
color: #999;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
/* Reasoning and Searching Sections */
|
|
892
|
+
.reasoning-section, .searching-section {
|
|
893
|
+
margin: 1rem 0;
|
|
894
|
+
padding: 0.75rem;
|
|
895
|
+
border-radius: var(--border-radius);
|
|
896
|
+
border-left: 4px solid;
|
|
897
|
+
background-color: var(--reasoning-background-color, #f8f9fa);
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
.reasoning-section {
|
|
901
|
+
border-left-color: var(--reasoning-border-color, #007bff);
|
|
902
|
+
background-color: var(--reasoning-background-color, #f0f8ff);
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
.searching-section {
|
|
906
|
+
border-left-color: var(--searching-border-color, #28a745);
|
|
907
|
+
background-color: var(--searching-background-color, #f0fff0);
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
.reasoning-header, .searching-header {
|
|
911
|
+
font-weight: 600;
|
|
912
|
+
font-size: 0.9rem;
|
|
913
|
+
margin-bottom: 0.5rem;
|
|
914
|
+
color: var(--prompt-text-color);
|
|
915
|
+
opacity: 0.8;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
.reasoning-content, .searching-content {
|
|
919
|
+
font-size: 0.85rem;
|
|
920
|
+
line-height: 1.4;
|
|
921
|
+
color: var(--prompt-text-color);
|
|
922
|
+
opacity: 0.9;
|
|
923
|
+
font-style: italic;
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
/* Dark theme support for reasoning/searching */
|
|
927
|
+
.dark-theme .reasoning-section {
|
|
928
|
+
background-color: var(--reasoning-background-color-dark, #1a1a2e);
|
|
929
|
+
border-left-color: var(--reasoning-border-color-dark, #4a9eff);
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
.dark-theme .searching-section {
|
|
933
|
+
background-color: var(--searching-background-color-dark, #1a2e1a);
|
|
934
|
+
border-left-color: var(--searching-border-color-dark, #4ade80);
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
.dark-theme .reasoning-header,
|
|
938
|
+
.dark-theme .searching-header,
|
|
939
|
+
.dark-theme .reasoning-content,
|
|
940
|
+
.dark-theme .searching-content {
|
|
941
|
+
color: var(--response-text-color);
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
/* Streaming response styling */
|
|
945
|
+
.streaming-response {
|
|
946
|
+
/* Add a subtle animation to indicate streaming */
|
|
947
|
+
animation: fadeIn 0.3s ease-in-out;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
@keyframes fadeIn {
|
|
951
|
+
from {
|
|
952
|
+
opacity: 0;
|
|
953
|
+
}
|
|
954
|
+
to {
|
|
955
|
+
opacity: 1;
|
|
956
|
+
}
|
|
888
957
|
}
|
package/src/ChatPanel.tsx
CHANGED
|
@@ -232,17 +232,20 @@ const ChatPanel: React.FC<ChatPanelProps & ExtraProps> = ({
|
|
|
232
232
|
const responseAreaRef = useRef(null);
|
|
233
233
|
// Extract the last reasoning or searching tag from the response
|
|
234
234
|
const extractLastThinkingTag = (text: string): string => {
|
|
235
|
+
console.log("extractLastThinkingTag called with:", text?.length ? `${text.substring(0, 100)}...` : "empty");
|
|
236
|
+
|
|
235
237
|
if (!text) return "Thinking";
|
|
236
238
|
|
|
237
|
-
// Find all reasoning and searching tags using exec method
|
|
238
|
-
const reasoningRegex = /<reasoning>(
|
|
239
|
-
const searchingRegex = /<searching>(
|
|
239
|
+
// Find all reasoning and searching tags using exec method (with global and multiline flags)
|
|
240
|
+
const reasoningRegex = /<reasoning>([\s\S]*?)<\/reasoning>/gi;
|
|
241
|
+
const searchingRegex = /<searching>([\s\S]*?)<\/searching>/gi;
|
|
240
242
|
|
|
241
243
|
const allMatches: Array<{ content: string; index: number; type: string }> = [];
|
|
242
244
|
|
|
243
245
|
// Find all reasoning matches
|
|
244
246
|
let reasoningMatch;
|
|
245
247
|
while ((reasoningMatch = reasoningRegex.exec(text)) !== null) {
|
|
248
|
+
console.log("Found reasoning match:", reasoningMatch[1]?.substring(0, 50) + "...");
|
|
246
249
|
allMatches.push({
|
|
247
250
|
content: reasoningMatch[1]?.trim() || "",
|
|
248
251
|
index: reasoningMatch.index,
|
|
@@ -253,6 +256,7 @@ const ChatPanel: React.FC<ChatPanelProps & ExtraProps> = ({
|
|
|
253
256
|
// Find all searching matches
|
|
254
257
|
let searchingMatch;
|
|
255
258
|
while ((searchingMatch = searchingRegex.exec(text)) !== null) {
|
|
259
|
+
console.log("Found searching match:", searchingMatch[1]?.substring(0, 50) + "...");
|
|
256
260
|
allMatches.push({
|
|
257
261
|
content: searchingMatch[1]?.trim() || "",
|
|
258
262
|
index: searchingMatch.index,
|
|
@@ -260,11 +264,15 @@ const ChatPanel: React.FC<ChatPanelProps & ExtraProps> = ({
|
|
|
260
264
|
});
|
|
261
265
|
}
|
|
262
266
|
|
|
267
|
+
console.log("Total matches found:", allMatches.length);
|
|
268
|
+
|
|
263
269
|
// Sort by position and get the last one
|
|
264
270
|
if (allMatches.length > 0) {
|
|
265
271
|
const lastMatch = allMatches.sort((a, b) => b.index - a.index)[0];
|
|
266
272
|
let content = lastMatch?.content || "Thinking";
|
|
267
273
|
|
|
274
|
+
console.log("Last match content:", content?.substring(0, 100));
|
|
275
|
+
|
|
268
276
|
// Clean up the content - remove markdown formatting and limit length
|
|
269
277
|
content = content.replace(/\*\*(.*?)\*\*/g, '$1'); // Remove bold
|
|
270
278
|
content = content.replace(/\*(.*?)\*/g, '$1'); // Remove italics
|
|
@@ -277,26 +285,49 @@ const ChatPanel: React.FC<ChatPanelProps & ExtraProps> = ({
|
|
|
277
285
|
content = content.substring(0, 77) + '...';
|
|
278
286
|
}
|
|
279
287
|
|
|
288
|
+
console.log("Final extracted content:", content);
|
|
280
289
|
return content || "Thinking";
|
|
281
290
|
}
|
|
282
291
|
|
|
292
|
+
console.log("No matches found, returning 'Thinking'");
|
|
283
293
|
return "Thinking";
|
|
284
294
|
};
|
|
285
295
|
|
|
286
|
-
//
|
|
287
|
-
const
|
|
296
|
+
// Process response content to show reasoning/searching in a styled format
|
|
297
|
+
const processResponseContent = (text: string, isStreaming: boolean = false): string => {
|
|
288
298
|
if (!text) return "";
|
|
289
299
|
|
|
290
|
-
|
|
291
|
-
let cleanText = text.replace(/<reasoning>[\s\S]*?<\/reasoning>/gi, '');
|
|
300
|
+
let processedText = text;
|
|
292
301
|
|
|
293
|
-
//
|
|
294
|
-
|
|
302
|
+
// Replace reasoning tags with styled content
|
|
303
|
+
processedText = processedText.replace(
|
|
304
|
+
/<reasoning>([\s\S]*?)<\/reasoning>/gi,
|
|
305
|
+
(match, content) => {
|
|
306
|
+
const trimmedContent = content.trim();
|
|
307
|
+
if (!trimmedContent) return '';
|
|
308
|
+
|
|
309
|
+
return `\n\n<div class="reasoning-section">
|
|
310
|
+
<div class="reasoning-header">🤔 Reasoning</div>
|
|
311
|
+
<div class="reasoning-content">${trimmedContent}</div>
|
|
312
|
+
</div>\n\n`;
|
|
313
|
+
}
|
|
314
|
+
);
|
|
295
315
|
|
|
296
|
-
//
|
|
297
|
-
|
|
316
|
+
// Replace searching tags with styled content
|
|
317
|
+
processedText = processedText.replace(
|
|
318
|
+
/<searching>([\s\S]*?)<\/searching>/gi,
|
|
319
|
+
(match, content) => {
|
|
320
|
+
const trimmedContent = content.trim();
|
|
321
|
+
if (!trimmedContent) return '';
|
|
322
|
+
|
|
323
|
+
return `\n\n<div class="searching-section">
|
|
324
|
+
<div class="searching-header">🔍 Searching</div>
|
|
325
|
+
<div class="searching-content">${trimmedContent}</div>
|
|
326
|
+
</div>\n\n`;
|
|
327
|
+
}
|
|
328
|
+
);
|
|
298
329
|
|
|
299
|
-
return
|
|
330
|
+
return processedText;
|
|
300
331
|
};
|
|
301
332
|
|
|
302
333
|
const getBrowserInfo = () => {
|
|
@@ -477,6 +508,18 @@ const ChatPanel: React.FC<ChatPanelProps & ExtraProps> = ({
|
|
|
477
508
|
}) as [],
|
|
478
509
|
});
|
|
479
510
|
|
|
511
|
+
// Add logging for streaming states
|
|
512
|
+
useEffect(() => {
|
|
513
|
+
console.log("Streaming state changed:", {
|
|
514
|
+
isLoading,
|
|
515
|
+
idle,
|
|
516
|
+
responseLength: response?.length || 0,
|
|
517
|
+
lastCallId,
|
|
518
|
+
hasResponse: !!response,
|
|
519
|
+
timestamp: new Date().toISOString()
|
|
520
|
+
});
|
|
521
|
+
}, [isLoading, idle, response, lastCallId]);
|
|
522
|
+
|
|
480
523
|
useEffect(() => {
|
|
481
524
|
setShowEmailPanel(customerEmailCaptureMode !== "HIDE");
|
|
482
525
|
|
|
@@ -998,6 +1041,15 @@ const ChatPanel: React.FC<ChatPanelProps & ExtraProps> = ({
|
|
|
998
1041
|
|
|
999
1042
|
useEffect(() => {
|
|
1000
1043
|
if (response && response.length > 0) {
|
|
1044
|
+
console.log("Response updated:", {
|
|
1045
|
+
length: response.length,
|
|
1046
|
+
isLoading,
|
|
1047
|
+
idle,
|
|
1048
|
+
hasReasoningTags: response.includes('<reasoning>'),
|
|
1049
|
+
hasSearchingTags: response.includes('<searching>'),
|
|
1050
|
+
preview: response.substring(0, 200) + "..."
|
|
1051
|
+
});
|
|
1052
|
+
|
|
1001
1053
|
setIsLoading(false);
|
|
1002
1054
|
|
|
1003
1055
|
let newResponse = response;
|
|
@@ -1088,6 +1140,14 @@ const ChatPanel: React.FC<ChatPanelProps & ExtraProps> = ({
|
|
|
1088
1140
|
setPendingToolRequests([]);
|
|
1089
1141
|
}
|
|
1090
1142
|
|
|
1143
|
+
const cleanedContent = processResponseContent(newResponse);
|
|
1144
|
+
console.log("Processed content:", {
|
|
1145
|
+
originalLength: newResponse.length,
|
|
1146
|
+
processedLength: cleanedContent.length,
|
|
1147
|
+
wasContentRemoved: newResponse.length !== cleanedContent.length,
|
|
1148
|
+
processedPreview: cleanedContent.substring(0, 200) + "..."
|
|
1149
|
+
});
|
|
1150
|
+
|
|
1091
1151
|
setHistory((prevHistory) => {
|
|
1092
1152
|
// Get any existing tool data from the previous state
|
|
1093
1153
|
const existingEntry = prevHistory[lastKey ?? ""] || {
|
|
@@ -1099,7 +1159,7 @@ const ChatPanel: React.FC<ChatPanelProps & ExtraProps> = ({
|
|
|
1099
1159
|
...prevHistory,
|
|
1100
1160
|
[lastKey ?? ""]: {
|
|
1101
1161
|
...existingEntry, // This preserves toolCalls and toolResponses
|
|
1102
|
-
content:
|
|
1162
|
+
content: cleanedContent,
|
|
1103
1163
|
callId: lastCallId,
|
|
1104
1164
|
},
|
|
1105
1165
|
};
|
|
@@ -1374,7 +1434,7 @@ const ChatPanel: React.FC<ChatPanelProps & ExtraProps> = ({
|
|
|
1374
1434
|
return {
|
|
1375
1435
|
...prevHistory,
|
|
1376
1436
|
[lastKey ?? ""]: {
|
|
1377
|
-
content:
|
|
1437
|
+
content: processResponseContent(response) + "\n\n(response cancelled)",
|
|
1378
1438
|
callId: lastCallId,
|
|
1379
1439
|
},
|
|
1380
1440
|
};
|
|
@@ -1410,7 +1470,7 @@ const ChatPanel: React.FC<ChatPanelProps & ExtraProps> = ({
|
|
|
1410
1470
|
messagesAndHistory.push({ role: "user", content: promptToSend });
|
|
1411
1471
|
messagesAndHistory.push({
|
|
1412
1472
|
role: "assistant",
|
|
1413
|
-
content:
|
|
1473
|
+
content: processResponseContent(response.content),
|
|
1414
1474
|
});
|
|
1415
1475
|
});
|
|
1416
1476
|
|
|
@@ -1885,22 +1945,37 @@ const ChatPanel: React.FC<ChatPanelProps & ExtraProps> = ({
|
|
|
1885
1945
|
)}
|
|
1886
1946
|
|
|
1887
1947
|
<div className="response">
|
|
1888
|
-
{
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1948
|
+
{/* Show streaming response with reasoning/searching tags */}
|
|
1949
|
+
{index === Object.keys(history).length - 1 && isLoading ? (
|
|
1950
|
+
<div className="streaming-response">
|
|
1951
|
+
{response && response.length > 0 ? (
|
|
1952
|
+
<ReactMarkdown
|
|
1953
|
+
className={markdownClass}
|
|
1954
|
+
remarkPlugins={[remarkGfm]}
|
|
1955
|
+
rehypePlugins={[rehypeRaw]}
|
|
1956
|
+
components={{ /*a: CustomLink,*/ code: CodeBlock }}
|
|
1957
|
+
>
|
|
1958
|
+
{processResponseContent(response, true)}
|
|
1959
|
+
</ReactMarkdown>
|
|
1960
|
+
) : (
|
|
1961
|
+
<div className="loading-text">
|
|
1962
|
+
{extractLastThinkingTag(response || "")}
|
|
1963
|
+
<div className="dot"></div>
|
|
1964
|
+
<div className="dot"></div>
|
|
1965
|
+
<div className="dot"></div>
|
|
1966
|
+
</div>
|
|
1967
|
+
)}
|
|
1894
1968
|
</div>
|
|
1895
|
-
) :
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1969
|
+
) : (
|
|
1970
|
+
<ReactMarkdown
|
|
1971
|
+
className={markdownClass}
|
|
1972
|
+
remarkPlugins={[remarkGfm]}
|
|
1973
|
+
rehypePlugins={[rehypeRaw]}
|
|
1974
|
+
components={{ /*a: CustomLink,*/ code: CodeBlock }}
|
|
1975
|
+
>
|
|
1976
|
+
{historyEntry.content}
|
|
1977
|
+
</ReactMarkdown>
|
|
1978
|
+
)}
|
|
1904
1979
|
|
|
1905
1980
|
{isLastEntry && pendingToolRequests.length > 0 && (
|
|
1906
1981
|
<div className="approve-tools-panel">
|
|
File without changes
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// Test file to verify tag extraction functions
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
// Mock test data
|
|
6
|
+
const testTexts = [
|
|
7
|
+
"This is a simple response without any tags.",
|
|
8
|
+
"<reasoning>I need to think about this problem step by step.</reasoning>Here's my answer.",
|
|
9
|
+
"Some text <searching>Looking for information about cats</searching> more text",
|
|
10
|
+
"<reasoning>First, I'll analyze the problem.</reasoning>Then I'll search. <searching>Finding relevant data</searching>Final answer here.",
|
|
11
|
+
"Multiple <reasoning>First reasoning</reasoning> and <reasoning>Second reasoning</reasoning> tags.",
|
|
12
|
+
"Incomplete <reasoning>Missing closing tag...",
|
|
13
|
+
"<reasoning>\nMultiline reasoning\nwith several lines\nof content\n</reasoning>Response text here.",
|
|
14
|
+
"Mixed <reasoning>Some thinking</reasoning> and <searching>Some searching</searching> with final answer."
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
// Copy the extraction function from the React component
|
|
18
|
+
function extractLastThinkingTag(text) {
|
|
19
|
+
console.log("extractLastThinkingTag called with:", text?.length ? `${text.substring(0, 100)}...` : "empty");
|
|
20
|
+
|
|
21
|
+
if (!text) return "Thinking";
|
|
22
|
+
|
|
23
|
+
// Find all reasoning and searching tags using exec method (with global and multiline flags)
|
|
24
|
+
const reasoningRegex = /<reasoning>([\s\S]*?)<\/reasoning>/gi;
|
|
25
|
+
const searchingRegex = /<searching>([\s\S]*?)<\/searching>/gi;
|
|
26
|
+
|
|
27
|
+
const allMatches = [];
|
|
28
|
+
|
|
29
|
+
// Find all reasoning matches
|
|
30
|
+
let reasoningMatch;
|
|
31
|
+
while ((reasoningMatch = reasoningRegex.exec(text)) !== null) {
|
|
32
|
+
console.log("Found reasoning match:", reasoningMatch[1]?.substring(0, 50) + "...");
|
|
33
|
+
allMatches.push({
|
|
34
|
+
content: reasoningMatch[1]?.trim() || "",
|
|
35
|
+
index: reasoningMatch.index,
|
|
36
|
+
type: 'reasoning'
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Find all searching matches
|
|
41
|
+
let searchingMatch;
|
|
42
|
+
while ((searchingMatch = searchingRegex.exec(text)) !== null) {
|
|
43
|
+
console.log("Found searching match:", searchingMatch[1]?.substring(0, 50) + "...");
|
|
44
|
+
allMatches.push({
|
|
45
|
+
content: searchingMatch[1]?.trim() || "",
|
|
46
|
+
index: searchingMatch.index,
|
|
47
|
+
type: 'searching'
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
console.log("Total matches found:", allMatches.length);
|
|
52
|
+
|
|
53
|
+
// Sort by position and get the last one
|
|
54
|
+
if (allMatches.length > 0) {
|
|
55
|
+
const lastMatch = allMatches.sort((a, b) => b.index - a.index)[0];
|
|
56
|
+
let content = lastMatch?.content || "Thinking";
|
|
57
|
+
|
|
58
|
+
console.log("Last match content:", content?.substring(0, 100));
|
|
59
|
+
|
|
60
|
+
// Clean up the content - remove markdown formatting and limit length
|
|
61
|
+
content = content.replace(/\*\*(.*?)\*\*/g, '$1'); // Remove bold
|
|
62
|
+
content = content.replace(/\*(.*?)\*/g, '$1'); // Remove italics
|
|
63
|
+
content = content.replace(/\n+/g, ' '); // Replace newlines with spaces
|
|
64
|
+
content = content.replace(/\s+/g, ' '); // Normalize whitespace
|
|
65
|
+
content = content.trim();
|
|
66
|
+
|
|
67
|
+
// Limit length to keep UI clean
|
|
68
|
+
if (content.length > 80) {
|
|
69
|
+
content = content.substring(0, 77) + '...';
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
console.log("Final extracted content:", content);
|
|
73
|
+
return content || "Thinking";
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
console.log("No matches found, returning 'Thinking'");
|
|
77
|
+
return "Thinking";
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Copy the processing function from the React component
|
|
81
|
+
function processResponseContent(text, isStreaming = false) {
|
|
82
|
+
if (!text) return "";
|
|
83
|
+
|
|
84
|
+
let processedText = text;
|
|
85
|
+
|
|
86
|
+
// Replace reasoning tags with styled content
|
|
87
|
+
processedText = processedText.replace(
|
|
88
|
+
/<reasoning>([\s\S]*?)<\/reasoning>/gi,
|
|
89
|
+
(match, content) => {
|
|
90
|
+
const trimmedContent = content.trim();
|
|
91
|
+
if (!trimmedContent) return '';
|
|
92
|
+
|
|
93
|
+
return `\n\n<div class="reasoning-section">
|
|
94
|
+
<div class="reasoning-header">🤔 Reasoning</div>
|
|
95
|
+
<div class="reasoning-content">${trimmedContent}</div>
|
|
96
|
+
</div>\n\n`;
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
// Replace searching tags with styled content
|
|
101
|
+
processedText = processedText.replace(
|
|
102
|
+
/<searching>([\s\S]*?)<\/searching>/gi,
|
|
103
|
+
(match, content) => {
|
|
104
|
+
const trimmedContent = content.trim();
|
|
105
|
+
if (!trimmedContent) return '';
|
|
106
|
+
|
|
107
|
+
return `\n\n<div class="searching-section">
|
|
108
|
+
<div class="searching-header">🔍 Searching</div>
|
|
109
|
+
<div class="searching-content">${trimmedContent}</div>
|
|
110
|
+
</div>\n\n`;
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
return processedText;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
console.log("Testing tag extraction and processing functions...\n");
|
|
118
|
+
|
|
119
|
+
testTexts.forEach((text, index) => {
|
|
120
|
+
console.log(`\n=== Test ${index + 1} ===`);
|
|
121
|
+
console.log("Input:", text);
|
|
122
|
+
console.log("Extracted tag:", extractLastThinkingTag(text));
|
|
123
|
+
console.log("Processed content:", processResponseContent(text));
|
|
124
|
+
console.log("---");
|
|
125
|
+
});
|
|
File without changes
|
|
File without changes
|