@meetsmore-oss/use-ai-client 1.13.0 → 1.14.0
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/bundled.js +465 -272
- package/dist/bundled.js.map +1 -1
- package/dist/index.d.ts +79 -4
- package/dist/index.js +464 -272
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -99,6 +99,11 @@ var defaultStrings = {
|
|
|
99
99
|
/** Error for unknown/unexpected errors */
|
|
100
100
|
UNKNOWN_ERROR: "An unexpected error occurred. Please try again."
|
|
101
101
|
},
|
|
102
|
+
// Non-error notices shown as system-style bubbles
|
|
103
|
+
notices: {
|
|
104
|
+
/** Shown as a separate bubble after the user aborts generation */
|
|
105
|
+
aborted: "Generation stopped. You can continue the conversation."
|
|
106
|
+
},
|
|
102
107
|
// Thinking/reasoning display
|
|
103
108
|
thinking: {
|
|
104
109
|
/** Label shown while thinking is in progress */
|
|
@@ -157,6 +162,8 @@ var defaultTheme = {
|
|
|
157
162
|
activeBackground: "#f0f0ff",
|
|
158
163
|
/** Disabled button background */
|
|
159
164
|
buttonDisabledBackground: "#e5e7eb",
|
|
165
|
+
/** Stop (abort) button background — neutral so it doesn't read as a primary action */
|
|
166
|
+
stopButtonBackground: "#e5e7eb",
|
|
160
167
|
// Text colors
|
|
161
168
|
/** Primary text color */
|
|
162
169
|
textColor: "#1f2937",
|
|
@@ -301,10 +308,29 @@ function mergeAssistantMessagesForDisplay(messages) {
|
|
|
301
308
|
let pendingTexts = [];
|
|
302
309
|
let pendingIds = [];
|
|
303
310
|
let pendingReasoningParts = [];
|
|
311
|
+
const flushPending = () => {
|
|
312
|
+
if (pendingTexts.length > 0 || pendingReasoningParts.length > 0) {
|
|
313
|
+
result.push({
|
|
314
|
+
id: `merged-${pendingIds.join("-")}`,
|
|
315
|
+
role: "assistant",
|
|
316
|
+
content: pendingTexts.join("\n\n"),
|
|
317
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
318
|
+
...pendingReasoningParts.length > 0 ? { reasoningParts: pendingReasoningParts } : {}
|
|
319
|
+
});
|
|
320
|
+
pendingTexts = [];
|
|
321
|
+
pendingIds = [];
|
|
322
|
+
pendingReasoningParts = [];
|
|
323
|
+
}
|
|
324
|
+
};
|
|
304
325
|
for (const msg of messages) {
|
|
305
326
|
if (msg.role === "tool") {
|
|
306
327
|
continue;
|
|
307
328
|
}
|
|
329
|
+
if (msg.displayMode === "info") {
|
|
330
|
+
flushPending();
|
|
331
|
+
result.push(msg);
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
308
334
|
if (msg.role === "assistant") {
|
|
309
335
|
const text = getTextFromContent(msg.content);
|
|
310
336
|
if (msg.toolCalls && msg.toolCalls.length > 0) {
|
|
@@ -329,30 +355,11 @@ function mergeAssistantMessagesForDisplay(messages) {
|
|
|
329
355
|
pendingReasoningParts = [];
|
|
330
356
|
}
|
|
331
357
|
} else {
|
|
332
|
-
|
|
333
|
-
result.push({
|
|
334
|
-
id: `merged-${pendingIds.join("-")}`,
|
|
335
|
-
role: "assistant",
|
|
336
|
-
content: pendingTexts.join("\n\n"),
|
|
337
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
338
|
-
...pendingReasoningParts.length > 0 ? { reasoningParts: pendingReasoningParts } : {}
|
|
339
|
-
});
|
|
340
|
-
pendingTexts = [];
|
|
341
|
-
pendingIds = [];
|
|
342
|
-
pendingReasoningParts = [];
|
|
343
|
-
}
|
|
358
|
+
flushPending();
|
|
344
359
|
result.push(msg);
|
|
345
360
|
}
|
|
346
361
|
}
|
|
347
|
-
|
|
348
|
-
result.push({
|
|
349
|
-
id: `merged-${pendingIds.join("-")}`,
|
|
350
|
-
role: "assistant",
|
|
351
|
-
content: pendingTexts.join("\n\n"),
|
|
352
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
353
|
-
...pendingReasoningParts.length > 0 ? { reasoningParts: pendingReasoningParts } : {}
|
|
354
|
-
});
|
|
355
|
-
}
|
|
362
|
+
flushPending();
|
|
356
363
|
return result;
|
|
357
364
|
}
|
|
358
365
|
|
|
@@ -2161,6 +2168,7 @@ function hasFileContent(content) {
|
|
|
2161
2168
|
}
|
|
2162
2169
|
function UseAIChatPanel({
|
|
2163
2170
|
onSendMessage,
|
|
2171
|
+
onAbort,
|
|
2164
2172
|
messages,
|
|
2165
2173
|
loading,
|
|
2166
2174
|
connected,
|
|
@@ -2718,177 +2726,207 @@ function UseAIChatPanel({
|
|
|
2718
2726
|
]
|
|
2719
2727
|
}
|
|
2720
2728
|
),
|
|
2721
|
-
displayMessages.map((message) =>
|
|
2722
|
-
"
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
e
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2729
|
+
displayMessages.map((message) => {
|
|
2730
|
+
if (message.displayMode === "info") {
|
|
2731
|
+
return /* @__PURE__ */ jsx12(
|
|
2732
|
+
"div",
|
|
2733
|
+
{
|
|
2734
|
+
"data-testid": "chat-message-info",
|
|
2735
|
+
className: "chat-message chat-message-info",
|
|
2736
|
+
style: { display: "flex", justifyContent: "center", padding: "2px 0" },
|
|
2737
|
+
children: /* @__PURE__ */ jsx12(
|
|
2738
|
+
"div",
|
|
2739
|
+
{
|
|
2740
|
+
style: {
|
|
2741
|
+
maxWidth: "80%",
|
|
2742
|
+
padding: "6px 12px",
|
|
2743
|
+
borderRadius: "12px",
|
|
2744
|
+
background: theme.assistantMessageBackground,
|
|
2745
|
+
color: theme.secondaryTextColor,
|
|
2746
|
+
fontSize: "12px",
|
|
2747
|
+
lineHeight: "1.4",
|
|
2748
|
+
textAlign: "center",
|
|
2749
|
+
wordWrap: "break-word"
|
|
2750
|
+
},
|
|
2751
|
+
children: getDisplayTextFromContent(message.content)
|
|
2752
|
+
}
|
|
2753
|
+
)
|
|
2754
|
+
},
|
|
2755
|
+
message.id
|
|
2756
|
+
);
|
|
2757
|
+
}
|
|
2758
|
+
return /* @__PURE__ */ jsxs9(
|
|
2759
|
+
"div",
|
|
2760
|
+
{
|
|
2761
|
+
"data-testid": `chat-message-${message.role}`,
|
|
2762
|
+
className: `chat-message chat-message-${message.role}`,
|
|
2763
|
+
style: {
|
|
2764
|
+
display: "flex",
|
|
2765
|
+
flexDirection: "column",
|
|
2766
|
+
alignItems: message.role === "user" ? "flex-end" : "flex-start"
|
|
2767
|
+
},
|
|
2768
|
+
onMouseEnter: () => message.role === "user" && setHoveredMessageId(message.id),
|
|
2769
|
+
onMouseLeave: () => setHoveredMessageId(null),
|
|
2770
|
+
children: [
|
|
2771
|
+
/* @__PURE__ */ jsxs9(
|
|
2772
|
+
"div",
|
|
2773
|
+
{
|
|
2774
|
+
style: {
|
|
2775
|
+
position: "relative",
|
|
2776
|
+
maxWidth: "80%"
|
|
2777
|
+
},
|
|
2778
|
+
children: [
|
|
2779
|
+
message.role === "user" && hoveredMessageId === message.id && onSaveCommand && !slashCommands.isSavingCommand(message.id) && /* @__PURE__ */ jsx12(
|
|
2780
|
+
"button",
|
|
2781
|
+
{
|
|
2782
|
+
"data-testid": "save-command-button",
|
|
2783
|
+
onClick: (e) => {
|
|
2784
|
+
e.stopPropagation();
|
|
2785
|
+
const messageText = getDisplayTextFromContent(message.content);
|
|
2786
|
+
slashCommands.startSavingCommand(message.id, messageText);
|
|
2787
|
+
},
|
|
2788
|
+
title: "Save as slash command",
|
|
2789
|
+
style: {
|
|
2790
|
+
position: "absolute",
|
|
2791
|
+
top: "-8px",
|
|
2792
|
+
right: "-8px",
|
|
2793
|
+
width: "24px",
|
|
2794
|
+
height: "24px",
|
|
2795
|
+
borderRadius: "50%",
|
|
2796
|
+
border: "none",
|
|
2797
|
+
background: theme.backgroundColor,
|
|
2798
|
+
boxShadow: "0 2px 6px rgba(0, 0, 0, 0.15)",
|
|
2799
|
+
cursor: "pointer",
|
|
2800
|
+
display: "flex",
|
|
2801
|
+
alignItems: "center",
|
|
2802
|
+
justifyContent: "center",
|
|
2803
|
+
color: theme.primaryColor,
|
|
2804
|
+
transition: "all 0.15s",
|
|
2805
|
+
zIndex: 10
|
|
2806
|
+
},
|
|
2807
|
+
onMouseEnter: (e) => {
|
|
2808
|
+
e.currentTarget.style.transform = "scale(1.1)";
|
|
2809
|
+
e.currentTarget.style.boxShadow = "0 3px 8px rgba(0, 0, 0, 0.2)";
|
|
2810
|
+
},
|
|
2811
|
+
onMouseLeave: (e) => {
|
|
2812
|
+
e.currentTarget.style.transform = "scale(1)";
|
|
2813
|
+
e.currentTarget.style.boxShadow = "0 2px 6px rgba(0, 0, 0, 0.15)";
|
|
2814
|
+
},
|
|
2815
|
+
children: /* @__PURE__ */ jsxs9("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
2816
|
+
/* @__PURE__ */ jsx12("path", { d: "M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z" }),
|
|
2817
|
+
/* @__PURE__ */ jsx12("polyline", { points: "17 21 17 13 7 13 7 21" }),
|
|
2818
|
+
/* @__PURE__ */ jsx12("polyline", { points: "7 3 7 8 15 8" })
|
|
2819
|
+
] })
|
|
2820
|
+
}
|
|
2821
|
+
),
|
|
2822
|
+
/* @__PURE__ */ jsxs9(
|
|
2823
|
+
"div",
|
|
2824
|
+
{
|
|
2825
|
+
"data-testid": "chat-message-content",
|
|
2826
|
+
className: `chat-message-content${message.role === "assistant" ? " markdown-content" : ""}`,
|
|
2827
|
+
style: {
|
|
2828
|
+
padding: "10px 14px",
|
|
2829
|
+
borderRadius: slashCommands.isSavingCommand(message.id) ? "12px 12px 0 0" : "12px",
|
|
2830
|
+
background: message.displayMode === "error" ? theme.errorBackground : message.role === "user" ? theme.primaryGradient : theme.assistantMessageBackground,
|
|
2831
|
+
color: message.displayMode === "error" ? theme.errorTextColor : message.role === "user" ? "white" : theme.textColor,
|
|
2832
|
+
fontSize: "14px",
|
|
2833
|
+
lineHeight: "1.5",
|
|
2834
|
+
wordWrap: "break-word"
|
|
2835
|
+
},
|
|
2836
|
+
children: [
|
|
2837
|
+
message.role === "user" && hasFileContent(message.content) && /* @__PURE__ */ jsx12("div", { style: { display: "flex", flexWrap: "wrap", gap: "6px", marginBottom: "8px" }, children: message.content.filter((part) => part.type === "file").map((part, idx) => /* @__PURE__ */ jsx12(
|
|
2838
|
+
FilePlaceholder,
|
|
2811
2839
|
{
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
),
|
|
2817
|
-
/* @__PURE__ */
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2840
|
+
name: part.file.name,
|
|
2841
|
+
size: part.file.size
|
|
2842
|
+
},
|
|
2843
|
+
idx
|
|
2844
|
+
)) }),
|
|
2845
|
+
message.role === "assistant" ? /* @__PURE__ */ jsxs9(Fragment, { children: [
|
|
2846
|
+
message.reasoningParts && message.reasoningParts.length > 0 && /* @__PURE__ */ jsx12(
|
|
2847
|
+
Reasoning,
|
|
2848
|
+
{
|
|
2849
|
+
reasoningParts: message.reasoningParts,
|
|
2850
|
+
theme,
|
|
2851
|
+
strings
|
|
2852
|
+
}
|
|
2853
|
+
),
|
|
2854
|
+
/* @__PURE__ */ jsx12(MarkdownContent, { content: getTextFromContent(message.content) })
|
|
2855
|
+
] }) : (
|
|
2856
|
+
// User/tool bubbles: display-only text so transformed_file
|
|
2857
|
+
// (e.g. OCR body) isn't dumped into the chat bubble.
|
|
2858
|
+
getDisplayTextFromContent(message.content)
|
|
2859
|
+
)
|
|
2860
|
+
]
|
|
2861
|
+
}
|
|
2862
|
+
),
|
|
2863
|
+
slashCommands.renderInlineSaveUI({
|
|
2864
|
+
messageId: message.id,
|
|
2865
|
+
messageText: getDisplayTextFromContent(message.content)
|
|
2866
|
+
})
|
|
2867
|
+
]
|
|
2868
|
+
}
|
|
2869
|
+
),
|
|
2870
|
+
message.role === "assistant" && message.traceId && feedbackEnabled && onFeedback && /* @__PURE__ */ jsxs9(
|
|
2871
|
+
"div",
|
|
2872
|
+
{
|
|
2873
|
+
"data-testid": "feedback-buttons",
|
|
2874
|
+
style: {
|
|
2875
|
+
display: "flex",
|
|
2876
|
+
gap: "4px",
|
|
2877
|
+
marginTop: "4px",
|
|
2878
|
+
padding: "0 4px"
|
|
2879
|
+
},
|
|
2880
|
+
children: [
|
|
2881
|
+
/* @__PURE__ */ jsx12(
|
|
2882
|
+
FeedbackButton,
|
|
2883
|
+
{
|
|
2884
|
+
type: "upvote",
|
|
2885
|
+
isSelected: message.feedback === "upvote",
|
|
2886
|
+
onClick: () => {
|
|
2887
|
+
const newFeedback = message.feedback === "upvote" ? null : "upvote";
|
|
2888
|
+
onFeedback(message.id, message.traceId, newFeedback);
|
|
2889
|
+
},
|
|
2890
|
+
selectedColor: theme.primaryColor,
|
|
2891
|
+
unselectedColor: theme.secondaryTextColor
|
|
2892
|
+
}
|
|
2893
|
+
),
|
|
2894
|
+
/* @__PURE__ */ jsx12(
|
|
2895
|
+
FeedbackButton,
|
|
2896
|
+
{
|
|
2897
|
+
type: "downvote",
|
|
2898
|
+
isSelected: message.feedback === "downvote",
|
|
2899
|
+
onClick: () => {
|
|
2900
|
+
const newFeedback = message.feedback === "downvote" ? null : "downvote";
|
|
2901
|
+
onFeedback(message.id, message.traceId, newFeedback);
|
|
2902
|
+
},
|
|
2903
|
+
selectedColor: theme.errorTextColor,
|
|
2904
|
+
unselectedColor: theme.secondaryTextColor
|
|
2905
|
+
}
|
|
2906
|
+
)
|
|
2907
|
+
]
|
|
2908
|
+
}
|
|
2909
|
+
),
|
|
2910
|
+
/* @__PURE__ */ jsx12(
|
|
2911
|
+
"div",
|
|
2912
|
+
{
|
|
2913
|
+
style: {
|
|
2914
|
+
fontSize: "11px",
|
|
2915
|
+
color: theme.secondaryTextColor,
|
|
2916
|
+
marginTop: "4px",
|
|
2917
|
+
padding: "0 4px"
|
|
2918
|
+
},
|
|
2919
|
+
children: message.createdAt.toLocaleTimeString([], {
|
|
2920
|
+
hour: "2-digit",
|
|
2921
|
+
minute: "2-digit"
|
|
2829
2922
|
})
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
style: {
|
|
2838
|
-
display: "flex",
|
|
2839
|
-
gap: "4px",
|
|
2840
|
-
marginTop: "4px",
|
|
2841
|
-
padding: "0 4px"
|
|
2842
|
-
},
|
|
2843
|
-
children: [
|
|
2844
|
-
/* @__PURE__ */ jsx12(
|
|
2845
|
-
FeedbackButton,
|
|
2846
|
-
{
|
|
2847
|
-
type: "upvote",
|
|
2848
|
-
isSelected: message.feedback === "upvote",
|
|
2849
|
-
onClick: () => {
|
|
2850
|
-
const newFeedback = message.feedback === "upvote" ? null : "upvote";
|
|
2851
|
-
onFeedback(message.id, message.traceId, newFeedback);
|
|
2852
|
-
},
|
|
2853
|
-
selectedColor: theme.primaryColor,
|
|
2854
|
-
unselectedColor: theme.secondaryTextColor
|
|
2855
|
-
}
|
|
2856
|
-
),
|
|
2857
|
-
/* @__PURE__ */ jsx12(
|
|
2858
|
-
FeedbackButton,
|
|
2859
|
-
{
|
|
2860
|
-
type: "downvote",
|
|
2861
|
-
isSelected: message.feedback === "downvote",
|
|
2862
|
-
onClick: () => {
|
|
2863
|
-
const newFeedback = message.feedback === "downvote" ? null : "downvote";
|
|
2864
|
-
onFeedback(message.id, message.traceId, newFeedback);
|
|
2865
|
-
},
|
|
2866
|
-
selectedColor: theme.errorTextColor,
|
|
2867
|
-
unselectedColor: theme.secondaryTextColor
|
|
2868
|
-
}
|
|
2869
|
-
)
|
|
2870
|
-
]
|
|
2871
|
-
}
|
|
2872
|
-
),
|
|
2873
|
-
/* @__PURE__ */ jsx12(
|
|
2874
|
-
"div",
|
|
2875
|
-
{
|
|
2876
|
-
style: {
|
|
2877
|
-
fontSize: "11px",
|
|
2878
|
-
color: theme.secondaryTextColor,
|
|
2879
|
-
marginTop: "4px",
|
|
2880
|
-
padding: "0 4px"
|
|
2881
|
-
},
|
|
2882
|
-
children: message.createdAt.toLocaleTimeString([], {
|
|
2883
|
-
hour: "2-digit",
|
|
2884
|
-
minute: "2-digit"
|
|
2885
|
-
})
|
|
2886
|
-
}
|
|
2887
|
-
)
|
|
2888
|
-
]
|
|
2889
|
-
},
|
|
2890
|
-
message.id
|
|
2891
|
-
)),
|
|
2923
|
+
}
|
|
2924
|
+
)
|
|
2925
|
+
]
|
|
2926
|
+
},
|
|
2927
|
+
message.id
|
|
2928
|
+
);
|
|
2929
|
+
}),
|
|
2892
2930
|
loading && /* @__PURE__ */ jsx12(
|
|
2893
2931
|
"div",
|
|
2894
2932
|
{
|
|
@@ -3113,33 +3151,65 @@ function UseAIChatPanel({
|
|
|
3113
3151
|
] })
|
|
3114
3152
|
}
|
|
3115
3153
|
) }),
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3154
|
+
(() => {
|
|
3155
|
+
const canAbort = loading && !!onAbort;
|
|
3156
|
+
const canSend = connected && !loading && pendingApprovals.length === 0 && (input.trim() || attachments.length > 0);
|
|
3157
|
+
if (loading && onAbort) {
|
|
3158
|
+
return /* @__PURE__ */ jsx12(
|
|
3159
|
+
"button",
|
|
3160
|
+
{
|
|
3161
|
+
"data-testid": "chat-stop-button",
|
|
3162
|
+
className: "chat-stop-button",
|
|
3163
|
+
onClick: onAbort,
|
|
3164
|
+
disabled: !canAbort,
|
|
3165
|
+
title: canAbort ? "Stop generating" : "Cannot stop while a tool is running",
|
|
3166
|
+
"aria-label": "Stop generating",
|
|
3167
|
+
style: {
|
|
3168
|
+
padding: "6px",
|
|
3169
|
+
background: canAbort ? theme.stopButtonBackground : theme.buttonDisabledBackground,
|
|
3170
|
+
color: theme.secondaryTextColor,
|
|
3171
|
+
border: "none",
|
|
3172
|
+
borderRadius: "50%",
|
|
3173
|
+
cursor: canAbort ? "pointer" : "not-allowed",
|
|
3174
|
+
display: "flex",
|
|
3175
|
+
alignItems: "center",
|
|
3176
|
+
justifyContent: "center",
|
|
3177
|
+
width: "32px",
|
|
3178
|
+
height: "32px",
|
|
3179
|
+
transition: "all 0.2s"
|
|
3180
|
+
},
|
|
3181
|
+
children: /* @__PURE__ */ jsx12("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor", stroke: "none", children: /* @__PURE__ */ jsx12("rect", { x: "6", y: "6", width: "12", height: "12", rx: "2" }) })
|
|
3182
|
+
}
|
|
3183
|
+
);
|
|
3141
3184
|
}
|
|
3142
|
-
|
|
3185
|
+
return /* @__PURE__ */ jsx12(
|
|
3186
|
+
"button",
|
|
3187
|
+
{
|
|
3188
|
+
"data-testid": "chat-send-button",
|
|
3189
|
+
className: "chat-send-button",
|
|
3190
|
+
onClick: handleSend,
|
|
3191
|
+
disabled: !canSend,
|
|
3192
|
+
style: {
|
|
3193
|
+
padding: "6px",
|
|
3194
|
+
background: canSend ? theme.primaryGradient : theme.buttonDisabledBackground,
|
|
3195
|
+
color: canSend ? "white" : theme.secondaryTextColor,
|
|
3196
|
+
border: "none",
|
|
3197
|
+
borderRadius: "50%",
|
|
3198
|
+
cursor: canSend ? "pointer" : "not-allowed",
|
|
3199
|
+
display: "flex",
|
|
3200
|
+
alignItems: "center",
|
|
3201
|
+
justifyContent: "center",
|
|
3202
|
+
width: "32px",
|
|
3203
|
+
height: "32px",
|
|
3204
|
+
transition: "all 0.2s"
|
|
3205
|
+
},
|
|
3206
|
+
children: /* @__PURE__ */ jsxs9("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
3207
|
+
/* @__PURE__ */ jsx12("line", { x1: "12", y1: "19", x2: "12", y2: "5" }),
|
|
3208
|
+
/* @__PURE__ */ jsx12("polyline", { points: "5 12 12 5 19 12" })
|
|
3209
|
+
] })
|
|
3210
|
+
}
|
|
3211
|
+
);
|
|
3212
|
+
})()
|
|
3143
3213
|
]
|
|
3144
3214
|
}
|
|
3145
3215
|
)
|
|
@@ -3317,7 +3387,8 @@ function UseAIChat({ floating = false, submitMode }) {
|
|
|
3317
3387
|
onFeedback: ctx.feedback?.submit,
|
|
3318
3388
|
pendingApprovals: ctx.tools.pending.tools,
|
|
3319
3389
|
onApproveToolCall: ctx.tools.pending.tools.length > 0 ? ctx.tools.pending.approveAll : void 0,
|
|
3320
|
-
onRejectToolCall: ctx.tools.pending.tools.length > 0 ? ctx.tools.pending.rejectAll : void 0
|
|
3390
|
+
onRejectToolCall: ctx.tools.pending.tools.length > 0 ? ctx.tools.pending.rejectAll : void 0,
|
|
3391
|
+
onAbort: ctx.abortRun
|
|
3321
3392
|
};
|
|
3322
3393
|
if (floating) {
|
|
3323
3394
|
return /* @__PURE__ */ jsx14(
|
|
@@ -3364,6 +3435,9 @@ var UseAIClient = class {
|
|
|
3364
3435
|
_tools = [];
|
|
3365
3436
|
_messages = [];
|
|
3366
3437
|
_state = null;
|
|
3438
|
+
// Tracks the in-flight run so abortRun() can target it. Set by sendPrompt
|
|
3439
|
+
// and cleared at RUN_FINISHED / RUN_ERROR.
|
|
3440
|
+
_currentRunId = null;
|
|
3367
3441
|
// Agent selection
|
|
3368
3442
|
_availableAgents = [];
|
|
3369
3443
|
_defaultAgent = null;
|
|
@@ -3453,6 +3527,7 @@ var UseAIClient = class {
|
|
|
3453
3527
|
this._pendingToolResults = [];
|
|
3454
3528
|
this._currentReasoningBlocks = [];
|
|
3455
3529
|
this._currentReasoningBlockText = "";
|
|
3530
|
+
this._currentMessageContent = "";
|
|
3456
3531
|
}
|
|
3457
3532
|
if (event.type === EventType.TEXT_MESSAGE_START) {
|
|
3458
3533
|
const e = event;
|
|
@@ -3543,37 +3618,10 @@ var UseAIClient = class {
|
|
|
3543
3618
|
this._currentReasoningBlocks = [];
|
|
3544
3619
|
}
|
|
3545
3620
|
} else if (event.type === EventType.RUN_FINISHED) {
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
id: uuidv42(),
|
|
3551
|
-
role: "assistant",
|
|
3552
|
-
content: "",
|
|
3553
|
-
toolCalls: this._currentAssistantToolCalls,
|
|
3554
|
-
...reasoningParts ? { reasoningParts } : {}
|
|
3555
|
-
};
|
|
3556
|
-
this._messages.push(toolCallMessage);
|
|
3557
|
-
this._messages.push(...this._pendingToolResults);
|
|
3558
|
-
const textMessage = {
|
|
3559
|
-
id: this._currentAssistantMessage.id,
|
|
3560
|
-
role: "assistant",
|
|
3561
|
-
content: this._currentAssistantMessage.content || ""
|
|
3562
|
-
};
|
|
3563
|
-
this._messages.push(textMessage);
|
|
3564
|
-
} else {
|
|
3565
|
-
const assistantMessage = {
|
|
3566
|
-
id: this._currentAssistantMessage.id,
|
|
3567
|
-
role: "assistant",
|
|
3568
|
-
content: this._currentAssistantMessage.content || "",
|
|
3569
|
-
...reasoningParts ? { reasoningParts } : {}
|
|
3570
|
-
};
|
|
3571
|
-
this._messages.push(assistantMessage);
|
|
3572
|
-
}
|
|
3573
|
-
this._currentAssistantMessage = null;
|
|
3574
|
-
this._currentAssistantToolCalls = [];
|
|
3575
|
-
this._pendingToolResults = [];
|
|
3576
|
-
}
|
|
3621
|
+
this.finalizeRun({ aborted: false });
|
|
3622
|
+
}
|
|
3623
|
+
if (event.type === EventType.RUN_FINISHED || event.type === EventType.RUN_ERROR) {
|
|
3624
|
+
this._currentRunId = null;
|
|
3577
3625
|
}
|
|
3578
3626
|
this.eventHandlers.forEach((handler) => handler(event));
|
|
3579
3627
|
}
|
|
@@ -3637,10 +3685,12 @@ var UseAIClient = class {
|
|
|
3637
3685
|
// Type cast needed for Message type compatibility
|
|
3638
3686
|
};
|
|
3639
3687
|
this._messages.push(userMessage);
|
|
3688
|
+
const runId = uuidv42();
|
|
3689
|
+
this._currentRunId = runId;
|
|
3640
3690
|
const runInput = {
|
|
3641
3691
|
threadId: this.threadId,
|
|
3642
3692
|
// Use getter to ensure non-null
|
|
3643
|
-
runId
|
|
3693
|
+
runId,
|
|
3644
3694
|
messages: this._messages,
|
|
3645
3695
|
tools: this._tools.map((t) => ({
|
|
3646
3696
|
name: t.name,
|
|
@@ -3695,6 +3745,115 @@ var UseAIClient = class {
|
|
|
3695
3745
|
this._pendingToolResults.push(toolResultMsg);
|
|
3696
3746
|
this.send(toolResultMessage);
|
|
3697
3747
|
}
|
|
3748
|
+
/**
|
|
3749
|
+
* Aborts the in-flight run, if any.
|
|
3750
|
+
* Sends an `abort_run` message to the server which cancels the AI stream
|
|
3751
|
+
* and rejects any pending tool/approval waits. The server then emits
|
|
3752
|
+
* `RUN_ERROR` with `ErrorCode.ABORTED`, which the client handles by
|
|
3753
|
+
* persisting the partial response.
|
|
3754
|
+
*
|
|
3755
|
+
* No-op when no run is in flight.
|
|
3756
|
+
*/
|
|
3757
|
+
abortRun() {
|
|
3758
|
+
const runId = this._currentRunId;
|
|
3759
|
+
if (!runId) return;
|
|
3760
|
+
this.send({
|
|
3761
|
+
type: "abort_run",
|
|
3762
|
+
data: { runId }
|
|
3763
|
+
});
|
|
3764
|
+
}
|
|
3765
|
+
/**
|
|
3766
|
+
* Flushes the final in-progress step into `_messages` when a run terminates.
|
|
3767
|
+
*
|
|
3768
|
+
* Only two terminations reach here. Truncation (maxOutputTokens / finish
|
|
3769
|
+
* reason 'length') and tool-execution errors never do — the server absorbs
|
|
3770
|
+
* them: truncation continues via a fallback step and ends as a normal
|
|
3771
|
+
* RUN_FINISHED, and tool errors come back as tool_results that keep the run
|
|
3772
|
+
* going. So the dispatch is binary:
|
|
3773
|
+
* - `aborted: false` (RUN_FINISHED): every tool-call step was already flushed
|
|
3774
|
+
* at STEP_FINISHED, so the in-progress step is always text-only.
|
|
3775
|
+
* - `aborted: true` (RUN_ERROR / ABORTED): the run may have been cut
|
|
3776
|
+
* mid-tool-call or mid-reasoning, so extra repair is needed.
|
|
3777
|
+
*
|
|
3778
|
+
* After this returns, `currentMessageContent` and `currentReasoningBlocks`
|
|
3779
|
+
* remain readable for the persistence helper. The next RUN_STARTED clears them.
|
|
3780
|
+
*/
|
|
3781
|
+
finalizeRun(opts) {
|
|
3782
|
+
if (opts.aborted) {
|
|
3783
|
+
this.finalizeAbortedRun();
|
|
3784
|
+
} else {
|
|
3785
|
+
this.finalizeCompletedRun();
|
|
3786
|
+
}
|
|
3787
|
+
}
|
|
3788
|
+
/**
|
|
3789
|
+
* Normal completion (RUN_FINISHED). The in-progress step is text-only —
|
|
3790
|
+
* tool-call steps were already flushed at STEP_FINISHED — so just push the
|
|
3791
|
+
* trailing assistant text with its reasoning.
|
|
3792
|
+
*/
|
|
3793
|
+
finalizeCompletedRun() {
|
|
3794
|
+
this._currentReasoningBlockText = "";
|
|
3795
|
+
if (!this._currentAssistantMessage) return;
|
|
3796
|
+
if (this._currentMessageContent) {
|
|
3797
|
+
const stepReasoning = this._currentReasoningBlocks.length > 0 ? [...this._currentReasoningBlocks] : void 0;
|
|
3798
|
+
this._messages.push({
|
|
3799
|
+
id: this._currentAssistantMessage.id || uuidv42(),
|
|
3800
|
+
role: "assistant",
|
|
3801
|
+
content: this._currentMessageContent,
|
|
3802
|
+
...stepReasoning ? { reasoningParts: stepReasoning } : {}
|
|
3803
|
+
});
|
|
3804
|
+
}
|
|
3805
|
+
this._currentAssistantMessage = null;
|
|
3806
|
+
this._currentAssistantToolCalls = [];
|
|
3807
|
+
this._pendingToolResults = [];
|
|
3808
|
+
}
|
|
3809
|
+
/**
|
|
3810
|
+
* User-initiated abort (RUN_ERROR / ABORTED).
|
|
3811
|
+
*
|
|
3812
|
+
* Drops the in-progress step's reasoning blocks. A block gets its encrypted
|
|
3813
|
+
* signature on REASONING_ENCRYPTED_VALUE, which arrives after
|
|
3814
|
+
* REASONING_MESSAGE_END — so a mid-stream abort can leave signature-less
|
|
3815
|
+
* blocks. Persisting those would corrupt the next turn. Reasoning from
|
|
3816
|
+
* already-completed prior steps lives on STEP_FINISHED-flushed assistant
|
|
3817
|
+
* messages and is untouched. Aborted-step messages therefore never carry
|
|
3818
|
+
* reasoningParts.
|
|
3819
|
+
*/
|
|
3820
|
+
finalizeAbortedRun() {
|
|
3821
|
+
this._currentReasoningBlocks = [];
|
|
3822
|
+
this._currentReasoningBlockText = "";
|
|
3823
|
+
if (!this._currentAssistantMessage) return;
|
|
3824
|
+
if (this._currentAssistantToolCalls.length > 0) {
|
|
3825
|
+
this._messages.push({
|
|
3826
|
+
id: this._currentAssistantMessage.id || uuidv42(),
|
|
3827
|
+
role: "assistant",
|
|
3828
|
+
content: this._currentMessageContent || "",
|
|
3829
|
+
toolCalls: [...this._currentAssistantToolCalls]
|
|
3830
|
+
});
|
|
3831
|
+
this._messages.push(...this._pendingToolResults);
|
|
3832
|
+
const respondedIds = new Set(
|
|
3833
|
+
this._pendingToolResults.map((m) => "toolCallId" in m ? m.toolCallId : void 0).filter((id) => typeof id === "string")
|
|
3834
|
+
);
|
|
3835
|
+
for (const tc of this._currentAssistantToolCalls) {
|
|
3836
|
+
if (!respondedIds.has(tc.id)) {
|
|
3837
|
+
this._messages.push({
|
|
3838
|
+
id: uuidv42(),
|
|
3839
|
+
role: "tool",
|
|
3840
|
+
content: JSON.stringify({ aborted: true, reason: "Cancelled by user before tool finished" }),
|
|
3841
|
+
toolCallId: tc.id
|
|
3842
|
+
});
|
|
3843
|
+
}
|
|
3844
|
+
}
|
|
3845
|
+
this._currentMessageContent = "";
|
|
3846
|
+
} else if (this._currentMessageContent) {
|
|
3847
|
+
this._messages.push({
|
|
3848
|
+
id: this._currentAssistantMessage.id || uuidv42(),
|
|
3849
|
+
role: "assistant",
|
|
3850
|
+
content: this._currentMessageContent
|
|
3851
|
+
});
|
|
3852
|
+
}
|
|
3853
|
+
this._currentAssistantMessage = null;
|
|
3854
|
+
this._currentAssistantToolCalls = [];
|
|
3855
|
+
this._pendingToolResults = [];
|
|
3856
|
+
}
|
|
3698
3857
|
/**
|
|
3699
3858
|
* Sends a tool approval response back to the server.
|
|
3700
3859
|
*
|
|
@@ -3789,6 +3948,12 @@ var UseAIClient = class {
|
|
|
3789
3948
|
get currentMessageContent() {
|
|
3790
3949
|
return this._currentMessageContent;
|
|
3791
3950
|
}
|
|
3951
|
+
/**
|
|
3952
|
+
* Gets the runId of the in-flight run, or null when no run is active.
|
|
3953
|
+
*/
|
|
3954
|
+
get currentRunId() {
|
|
3955
|
+
return this._currentRunId;
|
|
3956
|
+
}
|
|
3792
3957
|
/**
|
|
3793
3958
|
* Gets the current reasoning blocks collected during the current run.
|
|
3794
3959
|
*/
|
|
@@ -4254,7 +4419,7 @@ import { useState as useState7, useCallback as useCallback5, useRef as useRef5,
|
|
|
4254
4419
|
|
|
4255
4420
|
// src/utils/messageConversion.ts
|
|
4256
4421
|
function transformMessagesToClientFormat(persistedMessages) {
|
|
4257
|
-
return persistedMessages.map((msg) => {
|
|
4422
|
+
return persistedMessages.filter((msg) => msg.displayMode !== "info").map((msg) => {
|
|
4258
4423
|
switch (msg.role) {
|
|
4259
4424
|
case "tool":
|
|
4260
4425
|
return {
|
|
@@ -5232,6 +5397,7 @@ function useServerEvents({
|
|
|
5232
5397
|
const loadingRef = useRef10(loading);
|
|
5233
5398
|
loadingRef.current = loading;
|
|
5234
5399
|
const messageCountAtRunStartRef = useRef10(0);
|
|
5400
|
+
const runIdAtRunStartRef = useRef10(void 0);
|
|
5235
5401
|
const hasTextFromPriorStepRef = useRef10(false);
|
|
5236
5402
|
const [executingToolRaw, setExecutingTool] = useState13(null);
|
|
5237
5403
|
const executingToolFallbackRef = useRef10(null);
|
|
@@ -5244,11 +5410,37 @@ function useServerEvents({
|
|
|
5244
5410
|
saveAIResponseRef.current = saveAIResponse;
|
|
5245
5411
|
const stringsRef = useRef10(strings);
|
|
5246
5412
|
stringsRef.current = strings;
|
|
5413
|
+
const persistFinalResponse = useCallback11(async (client, opts) => {
|
|
5414
|
+
const content = client.currentMessageContent;
|
|
5415
|
+
const reasoningParts = client.currentReasoningBlocks.length > 0 ? [...client.currentReasoningBlocks] : void 0;
|
|
5416
|
+
const turnMessages = extractTurnMessages(client.messages, messageCountAtRunStartRef.current);
|
|
5417
|
+
if (opts.aborted) {
|
|
5418
|
+
const notice = stringsRef.current.notices.aborted;
|
|
5419
|
+
if (content) {
|
|
5420
|
+
await saveAIResponseRef.current(content, void 0, opts.traceId, turnMessages, reasoningParts);
|
|
5421
|
+
await saveAIResponseRef.current(notice, "info");
|
|
5422
|
+
} else {
|
|
5423
|
+
await saveAIResponseRef.current(notice, "info", opts.traceId, turnMessages);
|
|
5424
|
+
}
|
|
5425
|
+
return;
|
|
5426
|
+
}
|
|
5427
|
+
if (content) {
|
|
5428
|
+
await saveAIResponseRef.current(content, void 0, opts.traceId, turnMessages, reasoningParts);
|
|
5429
|
+
}
|
|
5430
|
+
}, []);
|
|
5431
|
+
const resetRunUiState = useCallback11(() => {
|
|
5432
|
+
setStreamingText("");
|
|
5433
|
+
setStreamingReasoning("");
|
|
5434
|
+
streamingChatIdRef.current = null;
|
|
5435
|
+
setExecutingTool(null);
|
|
5436
|
+
setLoading(false);
|
|
5437
|
+
}, []);
|
|
5247
5438
|
const handleServerEvent = useCallback11(async (client, event) => {
|
|
5248
5439
|
const ts = toolSystemRef.current;
|
|
5249
5440
|
const strs = stringsRef.current;
|
|
5250
5441
|
if (event.type === EventType2.RUN_STARTED) {
|
|
5251
5442
|
messageCountAtRunStartRef.current = client.messages.length;
|
|
5443
|
+
runIdAtRunStartRef.current = client.currentRunId ?? void 0;
|
|
5252
5444
|
hasTextFromPriorStepRef.current = false;
|
|
5253
5445
|
setStreamingReasoning("");
|
|
5254
5446
|
} else if (event.type === EventType2.REASONING_MESSAGE_START) {
|
|
@@ -5300,30 +5492,21 @@ function useServerEvents({
|
|
|
5300
5492
|
setStreamingText((prev) => prev + contentEvent.delta);
|
|
5301
5493
|
} else if (event.type === EventType2.TEXT_MESSAGE_END) {
|
|
5302
5494
|
} else if (event.type === EventType2.RUN_FINISHED) {
|
|
5303
|
-
const
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
const traceId = finishedEvent.runId;
|
|
5307
|
-
const turnMessages = extractTurnMessages(client.messages, messageCountAtRunStartRef.current);
|
|
5308
|
-
const reasoningParts = client.currentReasoningBlocks.length > 0 ? [...client.currentReasoningBlocks] : void 0;
|
|
5309
|
-
saveAIResponseRef.current(content, void 0, traceId, turnMessages, reasoningParts);
|
|
5310
|
-
}
|
|
5311
|
-
setStreamingText("");
|
|
5312
|
-
setStreamingReasoning("");
|
|
5313
|
-
streamingChatIdRef.current = null;
|
|
5314
|
-
setExecutingTool(null);
|
|
5315
|
-
setLoading(false);
|
|
5495
|
+
const finishedEvent = event;
|
|
5496
|
+
await persistFinalResponse(client, { aborted: false, traceId: finishedEvent.runId });
|
|
5497
|
+
resetRunUiState();
|
|
5316
5498
|
} else if (event.type === EventType2.RUN_ERROR) {
|
|
5317
5499
|
const errorEvent = event;
|
|
5318
5500
|
const errorCode = errorEvent.message;
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5501
|
+
if (errorCode === ErrorCode.ABORTED) {
|
|
5502
|
+
client.finalizeRun({ aborted: true });
|
|
5503
|
+
await persistFinalResponse(client, { aborted: true, traceId: runIdAtRunStartRef.current });
|
|
5504
|
+
} else {
|
|
5505
|
+
console.error("[ServerEvents] Run error:", errorCode);
|
|
5506
|
+
const userMessage = strs.errors[errorCode] || errorEvent.message || strs.errors[ErrorCode.UNKNOWN_ERROR];
|
|
5507
|
+
saveAIResponseRef.current(userMessage, "error");
|
|
5508
|
+
}
|
|
5509
|
+
resetRunUiState();
|
|
5327
5510
|
}
|
|
5328
5511
|
}, []);
|
|
5329
5512
|
const handleDisconnect = useCallback11(() => {
|
|
@@ -5493,6 +5676,8 @@ var noOpContextValue = {
|
|
|
5493
5676
|
},
|
|
5494
5677
|
delete: async () => {
|
|
5495
5678
|
}
|
|
5679
|
+
},
|
|
5680
|
+
abortRun: () => {
|
|
5496
5681
|
}
|
|
5497
5682
|
};
|
|
5498
5683
|
var DEFAULT_FILE_UPLOAD_CONFIG = {
|
|
@@ -5626,6 +5811,9 @@ function UseAIProvider({
|
|
|
5626
5811
|
console.error("Failed to register tools:", err);
|
|
5627
5812
|
}
|
|
5628
5813
|
}, [toolSystem.hasTools, toolSystem.aggregatedTools, connected]);
|
|
5814
|
+
const abortRun = useCallback13(() => {
|
|
5815
|
+
clientRef.current?.abortRun();
|
|
5816
|
+
}, []);
|
|
5629
5817
|
const handleSendMessage = useCallback13(async (message, attachments, messageForwardedProps) => {
|
|
5630
5818
|
if (!clientRef.current) return;
|
|
5631
5819
|
serverEvents.clearStreamingText();
|
|
@@ -5724,7 +5912,8 @@ function UseAIProvider({
|
|
|
5724
5912
|
save: saveCommand,
|
|
5725
5913
|
rename: renameCommand,
|
|
5726
5914
|
delete: deleteCommand
|
|
5727
|
-
}
|
|
5915
|
+
},
|
|
5916
|
+
abortRun
|
|
5728
5917
|
};
|
|
5729
5918
|
const effectiveStreamingText = serverEvents.streamingChatIdRef.current === chatManagement.displayedChatId ? serverEvents.streamingText : "";
|
|
5730
5919
|
const effectiveStreamingReasoning = serverEvents.streamingChatIdRef.current === chatManagement.displayedChatId ? serverEvents.streamingReasoning : "";
|
|
@@ -5732,6 +5921,7 @@ function UseAIProvider({
|
|
|
5732
5921
|
connected,
|
|
5733
5922
|
loading: serverEvents.loading,
|
|
5734
5923
|
sendMessage: handleSendMessage,
|
|
5924
|
+
abortRun,
|
|
5735
5925
|
messages,
|
|
5736
5926
|
streamingText: effectiveStreamingText,
|
|
5737
5927
|
streamingReasoning: effectiveStreamingReasoning,
|
|
@@ -5781,6 +5971,7 @@ function UseAIProvider({
|
|
|
5781
5971
|
const hasCustomChat = CustomChat !== void 0 && CustomChat !== null;
|
|
5782
5972
|
const chatPanelProps = {
|
|
5783
5973
|
onSendMessage: handleSendMessage,
|
|
5974
|
+
onAbort: abortRun,
|
|
5784
5975
|
messages,
|
|
5785
5976
|
loading: serverEvents.loading,
|
|
5786
5977
|
connected,
|
|
@@ -5828,6 +6019,7 @@ function UseAIProvider({
|
|
|
5828
6019
|
isOpen: isChatOpen,
|
|
5829
6020
|
onClose: () => handleSetChatOpen(false),
|
|
5830
6021
|
onSendMessage: handleSendMessage,
|
|
6022
|
+
onAbort: abortRun,
|
|
5831
6023
|
messages,
|
|
5832
6024
|
loading: serverEvents.loading,
|
|
5833
6025
|
connected,
|