@meetsmore-oss/use-ai-client 1.13.1 → 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 -273
- package/dist/bundled.js.map +1 -1
- package/dist/index.d.ts +79 -4
- package/dist/index.js +464 -273
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/bundled.js
CHANGED
|
@@ -1376,6 +1376,11 @@ var defaultStrings = {
|
|
|
1376
1376
|
/** Error for unknown/unexpected errors */
|
|
1377
1377
|
UNKNOWN_ERROR: "An unexpected error occurred. Please try again."
|
|
1378
1378
|
},
|
|
1379
|
+
// Non-error notices shown as system-style bubbles
|
|
1380
|
+
notices: {
|
|
1381
|
+
/** Shown as a separate bubble after the user aborts generation */
|
|
1382
|
+
aborted: "Generation stopped. You can continue the conversation."
|
|
1383
|
+
},
|
|
1379
1384
|
// Thinking/reasoning display
|
|
1380
1385
|
thinking: {
|
|
1381
1386
|
/** Label shown while thinking is in progress */
|
|
@@ -1434,6 +1439,8 @@ var defaultTheme = {
|
|
|
1434
1439
|
activeBackground: "#f0f0ff",
|
|
1435
1440
|
/** Disabled button background */
|
|
1436
1441
|
buttonDisabledBackground: "#e5e7eb",
|
|
1442
|
+
/** Stop (abort) button background — neutral so it doesn't read as a primary action */
|
|
1443
|
+
stopButtonBackground: "#e5e7eb",
|
|
1437
1444
|
// Text colors
|
|
1438
1445
|
/** Primary text color */
|
|
1439
1446
|
textColor: "#1f2937",
|
|
@@ -1578,10 +1585,29 @@ function mergeAssistantMessagesForDisplay(messages) {
|
|
|
1578
1585
|
let pendingTexts = [];
|
|
1579
1586
|
let pendingIds = [];
|
|
1580
1587
|
let pendingReasoningParts = [];
|
|
1588
|
+
const flushPending = () => {
|
|
1589
|
+
if (pendingTexts.length > 0 || pendingReasoningParts.length > 0) {
|
|
1590
|
+
result.push({
|
|
1591
|
+
id: `merged-${pendingIds.join("-")}`,
|
|
1592
|
+
role: "assistant",
|
|
1593
|
+
content: pendingTexts.join("\n\n"),
|
|
1594
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
1595
|
+
...pendingReasoningParts.length > 0 ? { reasoningParts: pendingReasoningParts } : {}
|
|
1596
|
+
});
|
|
1597
|
+
pendingTexts = [];
|
|
1598
|
+
pendingIds = [];
|
|
1599
|
+
pendingReasoningParts = [];
|
|
1600
|
+
}
|
|
1601
|
+
};
|
|
1581
1602
|
for (const msg of messages) {
|
|
1582
1603
|
if (msg.role === "tool") {
|
|
1583
1604
|
continue;
|
|
1584
1605
|
}
|
|
1606
|
+
if (msg.displayMode === "info") {
|
|
1607
|
+
flushPending();
|
|
1608
|
+
result.push(msg);
|
|
1609
|
+
continue;
|
|
1610
|
+
}
|
|
1585
1611
|
if (msg.role === "assistant") {
|
|
1586
1612
|
const text5 = getTextFromContent(msg.content);
|
|
1587
1613
|
if (msg.toolCalls && msg.toolCalls.length > 0) {
|
|
@@ -1606,30 +1632,11 @@ function mergeAssistantMessagesForDisplay(messages) {
|
|
|
1606
1632
|
pendingReasoningParts = [];
|
|
1607
1633
|
}
|
|
1608
1634
|
} else {
|
|
1609
|
-
|
|
1610
|
-
result.push({
|
|
1611
|
-
id: `merged-${pendingIds.join("-")}`,
|
|
1612
|
-
role: "assistant",
|
|
1613
|
-
content: pendingTexts.join("\n\n"),
|
|
1614
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
1615
|
-
...pendingReasoningParts.length > 0 ? { reasoningParts: pendingReasoningParts } : {}
|
|
1616
|
-
});
|
|
1617
|
-
pendingTexts = [];
|
|
1618
|
-
pendingIds = [];
|
|
1619
|
-
pendingReasoningParts = [];
|
|
1620
|
-
}
|
|
1635
|
+
flushPending();
|
|
1621
1636
|
result.push(msg);
|
|
1622
1637
|
}
|
|
1623
1638
|
}
|
|
1624
|
-
|
|
1625
|
-
result.push({
|
|
1626
|
-
id: `merged-${pendingIds.join("-")}`,
|
|
1627
|
-
role: "assistant",
|
|
1628
|
-
content: pendingTexts.join("\n\n"),
|
|
1629
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
1630
|
-
...pendingReasoningParts.length > 0 ? { reasoningParts: pendingReasoningParts } : {}
|
|
1631
|
-
});
|
|
1632
|
-
}
|
|
1639
|
+
flushPending();
|
|
1633
1640
|
return result;
|
|
1634
1641
|
}
|
|
1635
1642
|
|
|
@@ -14663,6 +14670,7 @@ function hasFileContent(content3) {
|
|
|
14663
14670
|
}
|
|
14664
14671
|
function UseAIChatPanel({
|
|
14665
14672
|
onSendMessage,
|
|
14673
|
+
onAbort,
|
|
14666
14674
|
messages,
|
|
14667
14675
|
loading,
|
|
14668
14676
|
connected,
|
|
@@ -15220,177 +15228,207 @@ function UseAIChatPanel({
|
|
|
15220
15228
|
]
|
|
15221
15229
|
}
|
|
15222
15230
|
),
|
|
15223
|
-
displayMessages.map((message) =>
|
|
15224
|
-
"
|
|
15225
|
-
|
|
15226
|
-
|
|
15227
|
-
|
|
15228
|
-
|
|
15229
|
-
|
|
15230
|
-
|
|
15231
|
-
|
|
15232
|
-
|
|
15233
|
-
|
|
15234
|
-
|
|
15235
|
-
|
|
15236
|
-
|
|
15237
|
-
|
|
15238
|
-
|
|
15239
|
-
|
|
15240
|
-
|
|
15241
|
-
|
|
15242
|
-
|
|
15243
|
-
|
|
15244
|
-
|
|
15245
|
-
|
|
15246
|
-
|
|
15247
|
-
|
|
15248
|
-
|
|
15249
|
-
|
|
15250
|
-
|
|
15251
|
-
|
|
15252
|
-
|
|
15253
|
-
|
|
15254
|
-
|
|
15255
|
-
|
|
15256
|
-
|
|
15257
|
-
|
|
15258
|
-
|
|
15259
|
-
|
|
15260
|
-
|
|
15261
|
-
|
|
15262
|
-
|
|
15263
|
-
|
|
15264
|
-
|
|
15265
|
-
|
|
15266
|
-
|
|
15267
|
-
|
|
15268
|
-
|
|
15269
|
-
|
|
15270
|
-
|
|
15271
|
-
|
|
15272
|
-
|
|
15273
|
-
|
|
15274
|
-
|
|
15275
|
-
|
|
15276
|
-
|
|
15277
|
-
e
|
|
15278
|
-
|
|
15279
|
-
|
|
15280
|
-
|
|
15281
|
-
|
|
15282
|
-
|
|
15283
|
-
|
|
15284
|
-
|
|
15285
|
-
|
|
15286
|
-
|
|
15287
|
-
|
|
15288
|
-
|
|
15289
|
-
|
|
15290
|
-
|
|
15291
|
-
|
|
15292
|
-
|
|
15293
|
-
|
|
15294
|
-
|
|
15295
|
-
|
|
15296
|
-
|
|
15297
|
-
|
|
15298
|
-
|
|
15299
|
-
|
|
15300
|
-
|
|
15301
|
-
|
|
15302
|
-
|
|
15303
|
-
|
|
15304
|
-
|
|
15305
|
-
|
|
15306
|
-
|
|
15307
|
-
|
|
15308
|
-
|
|
15309
|
-
|
|
15310
|
-
|
|
15311
|
-
|
|
15312
|
-
|
|
15231
|
+
displayMessages.map((message) => {
|
|
15232
|
+
if (message.displayMode === "info") {
|
|
15233
|
+
return /* @__PURE__ */ jsx12(
|
|
15234
|
+
"div",
|
|
15235
|
+
{
|
|
15236
|
+
"data-testid": "chat-message-info",
|
|
15237
|
+
className: "chat-message chat-message-info",
|
|
15238
|
+
style: { display: "flex", justifyContent: "center", padding: "2px 0" },
|
|
15239
|
+
children: /* @__PURE__ */ jsx12(
|
|
15240
|
+
"div",
|
|
15241
|
+
{
|
|
15242
|
+
style: {
|
|
15243
|
+
maxWidth: "80%",
|
|
15244
|
+
padding: "6px 12px",
|
|
15245
|
+
borderRadius: "12px",
|
|
15246
|
+
background: theme.assistantMessageBackground,
|
|
15247
|
+
color: theme.secondaryTextColor,
|
|
15248
|
+
fontSize: "12px",
|
|
15249
|
+
lineHeight: "1.4",
|
|
15250
|
+
textAlign: "center",
|
|
15251
|
+
wordWrap: "break-word"
|
|
15252
|
+
},
|
|
15253
|
+
children: getDisplayTextFromContent(message.content)
|
|
15254
|
+
}
|
|
15255
|
+
)
|
|
15256
|
+
},
|
|
15257
|
+
message.id
|
|
15258
|
+
);
|
|
15259
|
+
}
|
|
15260
|
+
return /* @__PURE__ */ jsxs9(
|
|
15261
|
+
"div",
|
|
15262
|
+
{
|
|
15263
|
+
"data-testid": `chat-message-${message.role}`,
|
|
15264
|
+
className: `chat-message chat-message-${message.role}`,
|
|
15265
|
+
style: {
|
|
15266
|
+
display: "flex",
|
|
15267
|
+
flexDirection: "column",
|
|
15268
|
+
alignItems: message.role === "user" ? "flex-end" : "flex-start"
|
|
15269
|
+
},
|
|
15270
|
+
onMouseEnter: () => message.role === "user" && setHoveredMessageId(message.id),
|
|
15271
|
+
onMouseLeave: () => setHoveredMessageId(null),
|
|
15272
|
+
children: [
|
|
15273
|
+
/* @__PURE__ */ jsxs9(
|
|
15274
|
+
"div",
|
|
15275
|
+
{
|
|
15276
|
+
style: {
|
|
15277
|
+
position: "relative",
|
|
15278
|
+
maxWidth: "80%"
|
|
15279
|
+
},
|
|
15280
|
+
children: [
|
|
15281
|
+
message.role === "user" && hoveredMessageId === message.id && onSaveCommand && !slashCommands.isSavingCommand(message.id) && /* @__PURE__ */ jsx12(
|
|
15282
|
+
"button",
|
|
15283
|
+
{
|
|
15284
|
+
"data-testid": "save-command-button",
|
|
15285
|
+
onClick: (e) => {
|
|
15286
|
+
e.stopPropagation();
|
|
15287
|
+
const messageText = getDisplayTextFromContent(message.content);
|
|
15288
|
+
slashCommands.startSavingCommand(message.id, messageText);
|
|
15289
|
+
},
|
|
15290
|
+
title: "Save as slash command",
|
|
15291
|
+
style: {
|
|
15292
|
+
position: "absolute",
|
|
15293
|
+
top: "-8px",
|
|
15294
|
+
right: "-8px",
|
|
15295
|
+
width: "24px",
|
|
15296
|
+
height: "24px",
|
|
15297
|
+
borderRadius: "50%",
|
|
15298
|
+
border: "none",
|
|
15299
|
+
background: theme.backgroundColor,
|
|
15300
|
+
boxShadow: "0 2px 6px rgba(0, 0, 0, 0.15)",
|
|
15301
|
+
cursor: "pointer",
|
|
15302
|
+
display: "flex",
|
|
15303
|
+
alignItems: "center",
|
|
15304
|
+
justifyContent: "center",
|
|
15305
|
+
color: theme.primaryColor,
|
|
15306
|
+
transition: "all 0.15s",
|
|
15307
|
+
zIndex: 10
|
|
15308
|
+
},
|
|
15309
|
+
onMouseEnter: (e) => {
|
|
15310
|
+
e.currentTarget.style.transform = "scale(1.1)";
|
|
15311
|
+
e.currentTarget.style.boxShadow = "0 3px 8px rgba(0, 0, 0, 0.2)";
|
|
15312
|
+
},
|
|
15313
|
+
onMouseLeave: (e) => {
|
|
15314
|
+
e.currentTarget.style.transform = "scale(1)";
|
|
15315
|
+
e.currentTarget.style.boxShadow = "0 2px 6px rgba(0, 0, 0, 0.15)";
|
|
15316
|
+
},
|
|
15317
|
+
children: /* @__PURE__ */ jsxs9("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
15318
|
+
/* @__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" }),
|
|
15319
|
+
/* @__PURE__ */ jsx12("polyline", { points: "17 21 17 13 7 13 7 21" }),
|
|
15320
|
+
/* @__PURE__ */ jsx12("polyline", { points: "7 3 7 8 15 8" })
|
|
15321
|
+
] })
|
|
15322
|
+
}
|
|
15323
|
+
),
|
|
15324
|
+
/* @__PURE__ */ jsxs9(
|
|
15325
|
+
"div",
|
|
15326
|
+
{
|
|
15327
|
+
"data-testid": "chat-message-content",
|
|
15328
|
+
className: `chat-message-content${message.role === "assistant" ? " markdown-content" : ""}`,
|
|
15329
|
+
style: {
|
|
15330
|
+
padding: "10px 14px",
|
|
15331
|
+
borderRadius: slashCommands.isSavingCommand(message.id) ? "12px 12px 0 0" : "12px",
|
|
15332
|
+
background: message.displayMode === "error" ? theme.errorBackground : message.role === "user" ? theme.primaryGradient : theme.assistantMessageBackground,
|
|
15333
|
+
color: message.displayMode === "error" ? theme.errorTextColor : message.role === "user" ? "white" : theme.textColor,
|
|
15334
|
+
fontSize: "14px",
|
|
15335
|
+
lineHeight: "1.5",
|
|
15336
|
+
wordWrap: "break-word"
|
|
15337
|
+
},
|
|
15338
|
+
children: [
|
|
15339
|
+
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(
|
|
15340
|
+
FilePlaceholder,
|
|
15313
15341
|
{
|
|
15314
|
-
|
|
15315
|
-
|
|
15316
|
-
|
|
15317
|
-
|
|
15318
|
-
),
|
|
15319
|
-
/* @__PURE__ */
|
|
15320
|
-
|
|
15321
|
-
|
|
15322
|
-
|
|
15323
|
-
|
|
15324
|
-
|
|
15325
|
-
|
|
15326
|
-
|
|
15327
|
-
|
|
15328
|
-
|
|
15329
|
-
|
|
15330
|
-
|
|
15342
|
+
name: part.file.name,
|
|
15343
|
+
size: part.file.size
|
|
15344
|
+
},
|
|
15345
|
+
idx
|
|
15346
|
+
)) }),
|
|
15347
|
+
message.role === "assistant" ? /* @__PURE__ */ jsxs9(Fragment, { children: [
|
|
15348
|
+
message.reasoningParts && message.reasoningParts.length > 0 && /* @__PURE__ */ jsx12(
|
|
15349
|
+
Reasoning,
|
|
15350
|
+
{
|
|
15351
|
+
reasoningParts: message.reasoningParts,
|
|
15352
|
+
theme,
|
|
15353
|
+
strings
|
|
15354
|
+
}
|
|
15355
|
+
),
|
|
15356
|
+
/* @__PURE__ */ jsx12(MarkdownContent, { content: getTextFromContent(message.content) })
|
|
15357
|
+
] }) : (
|
|
15358
|
+
// User/tool bubbles: display-only text so transformed_file
|
|
15359
|
+
// (e.g. OCR body) isn't dumped into the chat bubble.
|
|
15360
|
+
getDisplayTextFromContent(message.content)
|
|
15361
|
+
)
|
|
15362
|
+
]
|
|
15363
|
+
}
|
|
15364
|
+
),
|
|
15365
|
+
slashCommands.renderInlineSaveUI({
|
|
15366
|
+
messageId: message.id,
|
|
15367
|
+
messageText: getDisplayTextFromContent(message.content)
|
|
15368
|
+
})
|
|
15369
|
+
]
|
|
15370
|
+
}
|
|
15371
|
+
),
|
|
15372
|
+
message.role === "assistant" && message.traceId && feedbackEnabled && onFeedback && /* @__PURE__ */ jsxs9(
|
|
15373
|
+
"div",
|
|
15374
|
+
{
|
|
15375
|
+
"data-testid": "feedback-buttons",
|
|
15376
|
+
style: {
|
|
15377
|
+
display: "flex",
|
|
15378
|
+
gap: "4px",
|
|
15379
|
+
marginTop: "4px",
|
|
15380
|
+
padding: "0 4px"
|
|
15381
|
+
},
|
|
15382
|
+
children: [
|
|
15383
|
+
/* @__PURE__ */ jsx12(
|
|
15384
|
+
FeedbackButton,
|
|
15385
|
+
{
|
|
15386
|
+
type: "upvote",
|
|
15387
|
+
isSelected: message.feedback === "upvote",
|
|
15388
|
+
onClick: () => {
|
|
15389
|
+
const newFeedback = message.feedback === "upvote" ? null : "upvote";
|
|
15390
|
+
onFeedback(message.id, message.traceId, newFeedback);
|
|
15391
|
+
},
|
|
15392
|
+
selectedColor: theme.primaryColor,
|
|
15393
|
+
unselectedColor: theme.secondaryTextColor
|
|
15394
|
+
}
|
|
15395
|
+
),
|
|
15396
|
+
/* @__PURE__ */ jsx12(
|
|
15397
|
+
FeedbackButton,
|
|
15398
|
+
{
|
|
15399
|
+
type: "downvote",
|
|
15400
|
+
isSelected: message.feedback === "downvote",
|
|
15401
|
+
onClick: () => {
|
|
15402
|
+
const newFeedback = message.feedback === "downvote" ? null : "downvote";
|
|
15403
|
+
onFeedback(message.id, message.traceId, newFeedback);
|
|
15404
|
+
},
|
|
15405
|
+
selectedColor: theme.errorTextColor,
|
|
15406
|
+
unselectedColor: theme.secondaryTextColor
|
|
15407
|
+
}
|
|
15408
|
+
)
|
|
15409
|
+
]
|
|
15410
|
+
}
|
|
15411
|
+
),
|
|
15412
|
+
/* @__PURE__ */ jsx12(
|
|
15413
|
+
"div",
|
|
15414
|
+
{
|
|
15415
|
+
style: {
|
|
15416
|
+
fontSize: "11px",
|
|
15417
|
+
color: theme.secondaryTextColor,
|
|
15418
|
+
marginTop: "4px",
|
|
15419
|
+
padding: "0 4px"
|
|
15420
|
+
},
|
|
15421
|
+
children: message.createdAt.toLocaleTimeString([], {
|
|
15422
|
+
hour: "2-digit",
|
|
15423
|
+
minute: "2-digit"
|
|
15331
15424
|
})
|
|
15332
|
-
|
|
15333
|
-
|
|
15334
|
-
|
|
15335
|
-
|
|
15336
|
-
|
|
15337
|
-
|
|
15338
|
-
|
|
15339
|
-
style: {
|
|
15340
|
-
display: "flex",
|
|
15341
|
-
gap: "4px",
|
|
15342
|
-
marginTop: "4px",
|
|
15343
|
-
padding: "0 4px"
|
|
15344
|
-
},
|
|
15345
|
-
children: [
|
|
15346
|
-
/* @__PURE__ */ jsx12(
|
|
15347
|
-
FeedbackButton,
|
|
15348
|
-
{
|
|
15349
|
-
type: "upvote",
|
|
15350
|
-
isSelected: message.feedback === "upvote",
|
|
15351
|
-
onClick: () => {
|
|
15352
|
-
const newFeedback = message.feedback === "upvote" ? null : "upvote";
|
|
15353
|
-
onFeedback(message.id, message.traceId, newFeedback);
|
|
15354
|
-
},
|
|
15355
|
-
selectedColor: theme.primaryColor,
|
|
15356
|
-
unselectedColor: theme.secondaryTextColor
|
|
15357
|
-
}
|
|
15358
|
-
),
|
|
15359
|
-
/* @__PURE__ */ jsx12(
|
|
15360
|
-
FeedbackButton,
|
|
15361
|
-
{
|
|
15362
|
-
type: "downvote",
|
|
15363
|
-
isSelected: message.feedback === "downvote",
|
|
15364
|
-
onClick: () => {
|
|
15365
|
-
const newFeedback = message.feedback === "downvote" ? null : "downvote";
|
|
15366
|
-
onFeedback(message.id, message.traceId, newFeedback);
|
|
15367
|
-
},
|
|
15368
|
-
selectedColor: theme.errorTextColor,
|
|
15369
|
-
unselectedColor: theme.secondaryTextColor
|
|
15370
|
-
}
|
|
15371
|
-
)
|
|
15372
|
-
]
|
|
15373
|
-
}
|
|
15374
|
-
),
|
|
15375
|
-
/* @__PURE__ */ jsx12(
|
|
15376
|
-
"div",
|
|
15377
|
-
{
|
|
15378
|
-
style: {
|
|
15379
|
-
fontSize: "11px",
|
|
15380
|
-
color: theme.secondaryTextColor,
|
|
15381
|
-
marginTop: "4px",
|
|
15382
|
-
padding: "0 4px"
|
|
15383
|
-
},
|
|
15384
|
-
children: message.createdAt.toLocaleTimeString([], {
|
|
15385
|
-
hour: "2-digit",
|
|
15386
|
-
minute: "2-digit"
|
|
15387
|
-
})
|
|
15388
|
-
}
|
|
15389
|
-
)
|
|
15390
|
-
]
|
|
15391
|
-
},
|
|
15392
|
-
message.id
|
|
15393
|
-
)),
|
|
15425
|
+
}
|
|
15426
|
+
)
|
|
15427
|
+
]
|
|
15428
|
+
},
|
|
15429
|
+
message.id
|
|
15430
|
+
);
|
|
15431
|
+
}),
|
|
15394
15432
|
loading && /* @__PURE__ */ jsx12(
|
|
15395
15433
|
"div",
|
|
15396
15434
|
{
|
|
@@ -15615,33 +15653,65 @@ function UseAIChatPanel({
|
|
|
15615
15653
|
] })
|
|
15616
15654
|
}
|
|
15617
15655
|
) }),
|
|
15618
|
-
|
|
15619
|
-
|
|
15620
|
-
|
|
15621
|
-
|
|
15622
|
-
|
|
15623
|
-
|
|
15624
|
-
|
|
15625
|
-
|
|
15626
|
-
|
|
15627
|
-
|
|
15628
|
-
|
|
15629
|
-
|
|
15630
|
-
|
|
15631
|
-
|
|
15632
|
-
|
|
15633
|
-
|
|
15634
|
-
|
|
15635
|
-
|
|
15636
|
-
|
|
15637
|
-
|
|
15638
|
-
|
|
15639
|
-
|
|
15640
|
-
|
|
15641
|
-
|
|
15642
|
-
|
|
15656
|
+
(() => {
|
|
15657
|
+
const canAbort = loading && !!onAbort;
|
|
15658
|
+
const canSend = connected && !loading && pendingApprovals.length === 0 && (input.trim() || attachments.length > 0);
|
|
15659
|
+
if (loading && onAbort) {
|
|
15660
|
+
return /* @__PURE__ */ jsx12(
|
|
15661
|
+
"button",
|
|
15662
|
+
{
|
|
15663
|
+
"data-testid": "chat-stop-button",
|
|
15664
|
+
className: "chat-stop-button",
|
|
15665
|
+
onClick: onAbort,
|
|
15666
|
+
disabled: !canAbort,
|
|
15667
|
+
title: canAbort ? "Stop generating" : "Cannot stop while a tool is running",
|
|
15668
|
+
"aria-label": "Stop generating",
|
|
15669
|
+
style: {
|
|
15670
|
+
padding: "6px",
|
|
15671
|
+
background: canAbort ? theme.stopButtonBackground : theme.buttonDisabledBackground,
|
|
15672
|
+
color: theme.secondaryTextColor,
|
|
15673
|
+
border: "none",
|
|
15674
|
+
borderRadius: "50%",
|
|
15675
|
+
cursor: canAbort ? "pointer" : "not-allowed",
|
|
15676
|
+
display: "flex",
|
|
15677
|
+
alignItems: "center",
|
|
15678
|
+
justifyContent: "center",
|
|
15679
|
+
width: "32px",
|
|
15680
|
+
height: "32px",
|
|
15681
|
+
transition: "all 0.2s"
|
|
15682
|
+
},
|
|
15683
|
+
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" }) })
|
|
15684
|
+
}
|
|
15685
|
+
);
|
|
15643
15686
|
}
|
|
15644
|
-
|
|
15687
|
+
return /* @__PURE__ */ jsx12(
|
|
15688
|
+
"button",
|
|
15689
|
+
{
|
|
15690
|
+
"data-testid": "chat-send-button",
|
|
15691
|
+
className: "chat-send-button",
|
|
15692
|
+
onClick: handleSend,
|
|
15693
|
+
disabled: !canSend,
|
|
15694
|
+
style: {
|
|
15695
|
+
padding: "6px",
|
|
15696
|
+
background: canSend ? theme.primaryGradient : theme.buttonDisabledBackground,
|
|
15697
|
+
color: canSend ? "white" : theme.secondaryTextColor,
|
|
15698
|
+
border: "none",
|
|
15699
|
+
borderRadius: "50%",
|
|
15700
|
+
cursor: canSend ? "pointer" : "not-allowed",
|
|
15701
|
+
display: "flex",
|
|
15702
|
+
alignItems: "center",
|
|
15703
|
+
justifyContent: "center",
|
|
15704
|
+
width: "32px",
|
|
15705
|
+
height: "32px",
|
|
15706
|
+
transition: "all 0.2s"
|
|
15707
|
+
},
|
|
15708
|
+
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: [
|
|
15709
|
+
/* @__PURE__ */ jsx12("line", { x1: "12", y1: "19", x2: "12", y2: "5" }),
|
|
15710
|
+
/* @__PURE__ */ jsx12("polyline", { points: "5 12 12 5 19 12" })
|
|
15711
|
+
] })
|
|
15712
|
+
}
|
|
15713
|
+
);
|
|
15714
|
+
})()
|
|
15645
15715
|
]
|
|
15646
15716
|
}
|
|
15647
15717
|
)
|
|
@@ -15819,7 +15889,8 @@ function UseAIChat({ floating = false, submitMode }) {
|
|
|
15819
15889
|
onFeedback: ctx.feedback?.submit,
|
|
15820
15890
|
pendingApprovals: ctx.tools.pending.tools,
|
|
15821
15891
|
onApproveToolCall: ctx.tools.pending.tools.length > 0 ? ctx.tools.pending.approveAll : void 0,
|
|
15822
|
-
onRejectToolCall: ctx.tools.pending.tools.length > 0 ? ctx.tools.pending.rejectAll : void 0
|
|
15892
|
+
onRejectToolCall: ctx.tools.pending.tools.length > 0 ? ctx.tools.pending.rejectAll : void 0,
|
|
15893
|
+
onAbort: ctx.abortRun
|
|
15823
15894
|
};
|
|
15824
15895
|
if (floating) {
|
|
15825
15896
|
return /* @__PURE__ */ jsx14(
|
|
@@ -23663,6 +23734,7 @@ var ErrorCode;
|
|
|
23663
23734
|
ErrorCode2["API_OVERLOADED"] = "API_OVERLOADED";
|
|
23664
23735
|
ErrorCode2["RATE_LIMITED"] = "RATE_LIMITED";
|
|
23665
23736
|
ErrorCode2["CONNECTION_LOST"] = "CONNECTION_LOST";
|
|
23737
|
+
ErrorCode2["ABORTED"] = "ABORTED";
|
|
23666
23738
|
ErrorCode2["UNKNOWN_ERROR"] = "UNKNOWN_ERROR";
|
|
23667
23739
|
})(ErrorCode ||= {});
|
|
23668
23740
|
var TOOL_APPROVAL_REQUEST = "TOOL_APPROVAL_REQUEST";
|
|
@@ -23690,6 +23762,9 @@ var UseAIClient = class {
|
|
|
23690
23762
|
_tools = [];
|
|
23691
23763
|
_messages = [];
|
|
23692
23764
|
_state = null;
|
|
23765
|
+
// Tracks the in-flight run so abortRun() can target it. Set by sendPrompt
|
|
23766
|
+
// and cleared at RUN_FINISHED / RUN_ERROR.
|
|
23767
|
+
_currentRunId = null;
|
|
23693
23768
|
// Agent selection
|
|
23694
23769
|
_availableAgents = [];
|
|
23695
23770
|
_defaultAgent = null;
|
|
@@ -23779,6 +23854,7 @@ var UseAIClient = class {
|
|
|
23779
23854
|
this._pendingToolResults = [];
|
|
23780
23855
|
this._currentReasoningBlocks = [];
|
|
23781
23856
|
this._currentReasoningBlockText = "";
|
|
23857
|
+
this._currentMessageContent = "";
|
|
23782
23858
|
}
|
|
23783
23859
|
if (event.type === EventType.TEXT_MESSAGE_START) {
|
|
23784
23860
|
const e = event;
|
|
@@ -23869,38 +23945,10 @@ var UseAIClient = class {
|
|
|
23869
23945
|
this._currentReasoningBlocks = [];
|
|
23870
23946
|
}
|
|
23871
23947
|
} else if (event.type === EventType.RUN_FINISHED) {
|
|
23872
|
-
|
|
23873
|
-
|
|
23874
|
-
|
|
23875
|
-
|
|
23876
|
-
id: v4_default(),
|
|
23877
|
-
role: "assistant",
|
|
23878
|
-
content: "",
|
|
23879
|
-
toolCalls: this._currentAssistantToolCalls,
|
|
23880
|
-
...reasoningParts ? { reasoningParts } : {}
|
|
23881
|
-
};
|
|
23882
|
-
this._messages.push(toolCallMessage);
|
|
23883
|
-
this._messages.push(...this._pendingToolResults);
|
|
23884
|
-
const textMessage = {
|
|
23885
|
-
id: this._currentAssistantMessage.id,
|
|
23886
|
-
role: "assistant",
|
|
23887
|
-
content: this._currentAssistantMessage.content || ""
|
|
23888
|
-
};
|
|
23889
|
-
this._messages.push(textMessage);
|
|
23890
|
-
} else {
|
|
23891
|
-
const assistantMessage = {
|
|
23892
|
-
id: this._currentAssistantMessage.id,
|
|
23893
|
-
role: "assistant",
|
|
23894
|
-
content: this._currentAssistantMessage.content || "",
|
|
23895
|
-
...reasoningParts ? { reasoningParts } : {}
|
|
23896
|
-
};
|
|
23897
|
-
this._messages.push(assistantMessage);
|
|
23898
|
-
}
|
|
23899
|
-
this._currentAssistantMessage = null;
|
|
23900
|
-
this._currentAssistantToolCalls = [];
|
|
23901
|
-
this._pendingToolResults = [];
|
|
23902
|
-
this._currentReasoningBlockText = "";
|
|
23903
|
-
}
|
|
23948
|
+
this.finalizeRun({ aborted: false });
|
|
23949
|
+
}
|
|
23950
|
+
if (event.type === EventType.RUN_FINISHED || event.type === EventType.RUN_ERROR) {
|
|
23951
|
+
this._currentRunId = null;
|
|
23904
23952
|
}
|
|
23905
23953
|
this.eventHandlers.forEach((handler) => handler(event));
|
|
23906
23954
|
}
|
|
@@ -23964,10 +24012,12 @@ var UseAIClient = class {
|
|
|
23964
24012
|
// Type cast needed for Message type compatibility
|
|
23965
24013
|
};
|
|
23966
24014
|
this._messages.push(userMessage);
|
|
24015
|
+
const runId = v4_default();
|
|
24016
|
+
this._currentRunId = runId;
|
|
23967
24017
|
const runInput = {
|
|
23968
24018
|
threadId: this.threadId,
|
|
23969
24019
|
// Use getter to ensure non-null
|
|
23970
|
-
runId
|
|
24020
|
+
runId,
|
|
23971
24021
|
messages: this._messages,
|
|
23972
24022
|
tools: this._tools.map((t) => ({
|
|
23973
24023
|
name: t.name,
|
|
@@ -24022,6 +24072,115 @@ var UseAIClient = class {
|
|
|
24022
24072
|
this._pendingToolResults.push(toolResultMsg);
|
|
24023
24073
|
this.send(toolResultMessage);
|
|
24024
24074
|
}
|
|
24075
|
+
/**
|
|
24076
|
+
* Aborts the in-flight run, if any.
|
|
24077
|
+
* Sends an `abort_run` message to the server which cancels the AI stream
|
|
24078
|
+
* and rejects any pending tool/approval waits. The server then emits
|
|
24079
|
+
* `RUN_ERROR` with `ErrorCode.ABORTED`, which the client handles by
|
|
24080
|
+
* persisting the partial response.
|
|
24081
|
+
*
|
|
24082
|
+
* No-op when no run is in flight.
|
|
24083
|
+
*/
|
|
24084
|
+
abortRun() {
|
|
24085
|
+
const runId = this._currentRunId;
|
|
24086
|
+
if (!runId) return;
|
|
24087
|
+
this.send({
|
|
24088
|
+
type: "abort_run",
|
|
24089
|
+
data: { runId }
|
|
24090
|
+
});
|
|
24091
|
+
}
|
|
24092
|
+
/**
|
|
24093
|
+
* Flushes the final in-progress step into `_messages` when a run terminates.
|
|
24094
|
+
*
|
|
24095
|
+
* Only two terminations reach here. Truncation (maxOutputTokens / finish
|
|
24096
|
+
* reason 'length') and tool-execution errors never do — the server absorbs
|
|
24097
|
+
* them: truncation continues via a fallback step and ends as a normal
|
|
24098
|
+
* RUN_FINISHED, and tool errors come back as tool_results that keep the run
|
|
24099
|
+
* going. So the dispatch is binary:
|
|
24100
|
+
* - `aborted: false` (RUN_FINISHED): every tool-call step was already flushed
|
|
24101
|
+
* at STEP_FINISHED, so the in-progress step is always text-only.
|
|
24102
|
+
* - `aborted: true` (RUN_ERROR / ABORTED): the run may have been cut
|
|
24103
|
+
* mid-tool-call or mid-reasoning, so extra repair is needed.
|
|
24104
|
+
*
|
|
24105
|
+
* After this returns, `currentMessageContent` and `currentReasoningBlocks`
|
|
24106
|
+
* remain readable for the persistence helper. The next RUN_STARTED clears them.
|
|
24107
|
+
*/
|
|
24108
|
+
finalizeRun(opts) {
|
|
24109
|
+
if (opts.aborted) {
|
|
24110
|
+
this.finalizeAbortedRun();
|
|
24111
|
+
} else {
|
|
24112
|
+
this.finalizeCompletedRun();
|
|
24113
|
+
}
|
|
24114
|
+
}
|
|
24115
|
+
/**
|
|
24116
|
+
* Normal completion (RUN_FINISHED). The in-progress step is text-only —
|
|
24117
|
+
* tool-call steps were already flushed at STEP_FINISHED — so just push the
|
|
24118
|
+
* trailing assistant text with its reasoning.
|
|
24119
|
+
*/
|
|
24120
|
+
finalizeCompletedRun() {
|
|
24121
|
+
this._currentReasoningBlockText = "";
|
|
24122
|
+
if (!this._currentAssistantMessage) return;
|
|
24123
|
+
if (this._currentMessageContent) {
|
|
24124
|
+
const stepReasoning = this._currentReasoningBlocks.length > 0 ? [...this._currentReasoningBlocks] : void 0;
|
|
24125
|
+
this._messages.push({
|
|
24126
|
+
id: this._currentAssistantMessage.id || v4_default(),
|
|
24127
|
+
role: "assistant",
|
|
24128
|
+
content: this._currentMessageContent,
|
|
24129
|
+
...stepReasoning ? { reasoningParts: stepReasoning } : {}
|
|
24130
|
+
});
|
|
24131
|
+
}
|
|
24132
|
+
this._currentAssistantMessage = null;
|
|
24133
|
+
this._currentAssistantToolCalls = [];
|
|
24134
|
+
this._pendingToolResults = [];
|
|
24135
|
+
}
|
|
24136
|
+
/**
|
|
24137
|
+
* User-initiated abort (RUN_ERROR / ABORTED).
|
|
24138
|
+
*
|
|
24139
|
+
* Drops the in-progress step's reasoning blocks. A block gets its encrypted
|
|
24140
|
+
* signature on REASONING_ENCRYPTED_VALUE, which arrives after
|
|
24141
|
+
* REASONING_MESSAGE_END — so a mid-stream abort can leave signature-less
|
|
24142
|
+
* blocks. Persisting those would corrupt the next turn. Reasoning from
|
|
24143
|
+
* already-completed prior steps lives on STEP_FINISHED-flushed assistant
|
|
24144
|
+
* messages and is untouched. Aborted-step messages therefore never carry
|
|
24145
|
+
* reasoningParts.
|
|
24146
|
+
*/
|
|
24147
|
+
finalizeAbortedRun() {
|
|
24148
|
+
this._currentReasoningBlocks = [];
|
|
24149
|
+
this._currentReasoningBlockText = "";
|
|
24150
|
+
if (!this._currentAssistantMessage) return;
|
|
24151
|
+
if (this._currentAssistantToolCalls.length > 0) {
|
|
24152
|
+
this._messages.push({
|
|
24153
|
+
id: this._currentAssistantMessage.id || v4_default(),
|
|
24154
|
+
role: "assistant",
|
|
24155
|
+
content: this._currentMessageContent || "",
|
|
24156
|
+
toolCalls: [...this._currentAssistantToolCalls]
|
|
24157
|
+
});
|
|
24158
|
+
this._messages.push(...this._pendingToolResults);
|
|
24159
|
+
const respondedIds = new Set(
|
|
24160
|
+
this._pendingToolResults.map((m) => "toolCallId" in m ? m.toolCallId : void 0).filter((id) => typeof id === "string")
|
|
24161
|
+
);
|
|
24162
|
+
for (const tc of this._currentAssistantToolCalls) {
|
|
24163
|
+
if (!respondedIds.has(tc.id)) {
|
|
24164
|
+
this._messages.push({
|
|
24165
|
+
id: v4_default(),
|
|
24166
|
+
role: "tool",
|
|
24167
|
+
content: JSON.stringify({ aborted: true, reason: "Cancelled by user before tool finished" }),
|
|
24168
|
+
toolCallId: tc.id
|
|
24169
|
+
});
|
|
24170
|
+
}
|
|
24171
|
+
}
|
|
24172
|
+
this._currentMessageContent = "";
|
|
24173
|
+
} else if (this._currentMessageContent) {
|
|
24174
|
+
this._messages.push({
|
|
24175
|
+
id: this._currentAssistantMessage.id || v4_default(),
|
|
24176
|
+
role: "assistant",
|
|
24177
|
+
content: this._currentMessageContent
|
|
24178
|
+
});
|
|
24179
|
+
}
|
|
24180
|
+
this._currentAssistantMessage = null;
|
|
24181
|
+
this._currentAssistantToolCalls = [];
|
|
24182
|
+
this._pendingToolResults = [];
|
|
24183
|
+
}
|
|
24025
24184
|
/**
|
|
24026
24185
|
* Sends a tool approval response back to the server.
|
|
24027
24186
|
*
|
|
@@ -24116,6 +24275,12 @@ var UseAIClient = class {
|
|
|
24116
24275
|
get currentMessageContent() {
|
|
24117
24276
|
return this._currentMessageContent;
|
|
24118
24277
|
}
|
|
24278
|
+
/**
|
|
24279
|
+
* Gets the runId of the in-flight run, or null when no run is active.
|
|
24280
|
+
*/
|
|
24281
|
+
get currentRunId() {
|
|
24282
|
+
return this._currentRunId;
|
|
24283
|
+
}
|
|
24119
24284
|
/**
|
|
24120
24285
|
* Gets the current reasoning blocks collected during the current run.
|
|
24121
24286
|
*/
|
|
@@ -38348,7 +38513,7 @@ import { useState as useState7, useCallback as useCallback5, useRef as useRef5,
|
|
|
38348
38513
|
|
|
38349
38514
|
// src/utils/messageConversion.ts
|
|
38350
38515
|
function transformMessagesToClientFormat(persistedMessages) {
|
|
38351
|
-
return persistedMessages.map((msg) => {
|
|
38516
|
+
return persistedMessages.filter((msg) => msg.displayMode !== "info").map((msg) => {
|
|
38352
38517
|
switch (msg.role) {
|
|
38353
38518
|
case "tool":
|
|
38354
38519
|
return {
|
|
@@ -39321,6 +39486,7 @@ function useServerEvents({
|
|
|
39321
39486
|
const loadingRef = useRef10(loading);
|
|
39322
39487
|
loadingRef.current = loading;
|
|
39323
39488
|
const messageCountAtRunStartRef = useRef10(0);
|
|
39489
|
+
const runIdAtRunStartRef = useRef10(void 0);
|
|
39324
39490
|
const hasTextFromPriorStepRef = useRef10(false);
|
|
39325
39491
|
const [executingToolRaw, setExecutingTool] = useState13(null);
|
|
39326
39492
|
const executingToolFallbackRef = useRef10(null);
|
|
@@ -39333,11 +39499,37 @@ function useServerEvents({
|
|
|
39333
39499
|
saveAIResponseRef.current = saveAIResponse;
|
|
39334
39500
|
const stringsRef = useRef10(strings);
|
|
39335
39501
|
stringsRef.current = strings;
|
|
39502
|
+
const persistFinalResponse = useCallback11(async (client, opts) => {
|
|
39503
|
+
const content3 = client.currentMessageContent;
|
|
39504
|
+
const reasoningParts = client.currentReasoningBlocks.length > 0 ? [...client.currentReasoningBlocks] : void 0;
|
|
39505
|
+
const turnMessages = extractTurnMessages(client.messages, messageCountAtRunStartRef.current);
|
|
39506
|
+
if (opts.aborted) {
|
|
39507
|
+
const notice = stringsRef.current.notices.aborted;
|
|
39508
|
+
if (content3) {
|
|
39509
|
+
await saveAIResponseRef.current(content3, void 0, opts.traceId, turnMessages, reasoningParts);
|
|
39510
|
+
await saveAIResponseRef.current(notice, "info");
|
|
39511
|
+
} else {
|
|
39512
|
+
await saveAIResponseRef.current(notice, "info", opts.traceId, turnMessages);
|
|
39513
|
+
}
|
|
39514
|
+
return;
|
|
39515
|
+
}
|
|
39516
|
+
if (content3) {
|
|
39517
|
+
await saveAIResponseRef.current(content3, void 0, opts.traceId, turnMessages, reasoningParts);
|
|
39518
|
+
}
|
|
39519
|
+
}, []);
|
|
39520
|
+
const resetRunUiState = useCallback11(() => {
|
|
39521
|
+
setStreamingText("");
|
|
39522
|
+
setStreamingReasoning("");
|
|
39523
|
+
streamingChatIdRef.current = null;
|
|
39524
|
+
setExecutingTool(null);
|
|
39525
|
+
setLoading(false);
|
|
39526
|
+
}, []);
|
|
39336
39527
|
const handleServerEvent = useCallback11(async (client, event) => {
|
|
39337
39528
|
const ts = toolSystemRef.current;
|
|
39338
39529
|
const strs = stringsRef.current;
|
|
39339
39530
|
if (event.type === EventType.RUN_STARTED) {
|
|
39340
39531
|
messageCountAtRunStartRef.current = client.messages.length;
|
|
39532
|
+
runIdAtRunStartRef.current = client.currentRunId ?? void 0;
|
|
39341
39533
|
hasTextFromPriorStepRef.current = false;
|
|
39342
39534
|
setStreamingReasoning("");
|
|
39343
39535
|
} else if (event.type === EventType.REASONING_MESSAGE_START) {
|
|
@@ -39389,30 +39581,21 @@ function useServerEvents({
|
|
|
39389
39581
|
setStreamingText((prev) => prev + contentEvent.delta);
|
|
39390
39582
|
} else if (event.type === EventType.TEXT_MESSAGE_END) {
|
|
39391
39583
|
} else if (event.type === EventType.RUN_FINISHED) {
|
|
39392
|
-
const
|
|
39393
|
-
|
|
39394
|
-
|
|
39395
|
-
const traceId = finishedEvent.runId;
|
|
39396
|
-
const turnMessages = extractTurnMessages(client.messages, messageCountAtRunStartRef.current);
|
|
39397
|
-
const reasoningParts = client.currentReasoningBlocks.length > 0 ? [...client.currentReasoningBlocks] : void 0;
|
|
39398
|
-
saveAIResponseRef.current(content3, void 0, traceId, turnMessages, reasoningParts);
|
|
39399
|
-
}
|
|
39400
|
-
setStreamingText("");
|
|
39401
|
-
setStreamingReasoning("");
|
|
39402
|
-
streamingChatIdRef.current = null;
|
|
39403
|
-
setExecutingTool(null);
|
|
39404
|
-
setLoading(false);
|
|
39584
|
+
const finishedEvent = event;
|
|
39585
|
+
await persistFinalResponse(client, { aborted: false, traceId: finishedEvent.runId });
|
|
39586
|
+
resetRunUiState();
|
|
39405
39587
|
} else if (event.type === EventType.RUN_ERROR) {
|
|
39406
39588
|
const errorEvent = event;
|
|
39407
39589
|
const errorCode = errorEvent.message;
|
|
39408
|
-
|
|
39409
|
-
|
|
39410
|
-
|
|
39411
|
-
|
|
39412
|
-
|
|
39413
|
-
|
|
39414
|
-
|
|
39415
|
-
|
|
39590
|
+
if (errorCode === ErrorCode.ABORTED) {
|
|
39591
|
+
client.finalizeRun({ aborted: true });
|
|
39592
|
+
await persistFinalResponse(client, { aborted: true, traceId: runIdAtRunStartRef.current });
|
|
39593
|
+
} else {
|
|
39594
|
+
console.error("[ServerEvents] Run error:", errorCode);
|
|
39595
|
+
const userMessage = strs.errors[errorCode] || errorEvent.message || strs.errors[ErrorCode.UNKNOWN_ERROR];
|
|
39596
|
+
saveAIResponseRef.current(userMessage, "error");
|
|
39597
|
+
}
|
|
39598
|
+
resetRunUiState();
|
|
39416
39599
|
}
|
|
39417
39600
|
}, []);
|
|
39418
39601
|
const handleDisconnect = useCallback11(() => {
|
|
@@ -39582,6 +39765,8 @@ var noOpContextValue = {
|
|
|
39582
39765
|
},
|
|
39583
39766
|
delete: async () => {
|
|
39584
39767
|
}
|
|
39768
|
+
},
|
|
39769
|
+
abortRun: () => {
|
|
39585
39770
|
}
|
|
39586
39771
|
};
|
|
39587
39772
|
var DEFAULT_FILE_UPLOAD_CONFIG = {
|
|
@@ -39715,6 +39900,9 @@ function UseAIProvider({
|
|
|
39715
39900
|
console.error("Failed to register tools:", err);
|
|
39716
39901
|
}
|
|
39717
39902
|
}, [toolSystem.hasTools, toolSystem.aggregatedTools, connected]);
|
|
39903
|
+
const abortRun = useCallback13(() => {
|
|
39904
|
+
clientRef.current?.abortRun();
|
|
39905
|
+
}, []);
|
|
39718
39906
|
const handleSendMessage = useCallback13(async (message, attachments, messageForwardedProps) => {
|
|
39719
39907
|
if (!clientRef.current) return;
|
|
39720
39908
|
serverEvents.clearStreamingText();
|
|
@@ -39813,7 +40001,8 @@ function UseAIProvider({
|
|
|
39813
40001
|
save: saveCommand,
|
|
39814
40002
|
rename: renameCommand,
|
|
39815
40003
|
delete: deleteCommand
|
|
39816
|
-
}
|
|
40004
|
+
},
|
|
40005
|
+
abortRun
|
|
39817
40006
|
};
|
|
39818
40007
|
const effectiveStreamingText = serverEvents.streamingChatIdRef.current === chatManagement.displayedChatId ? serverEvents.streamingText : "";
|
|
39819
40008
|
const effectiveStreamingReasoning = serverEvents.streamingChatIdRef.current === chatManagement.displayedChatId ? serverEvents.streamingReasoning : "";
|
|
@@ -39821,6 +40010,7 @@ function UseAIProvider({
|
|
|
39821
40010
|
connected,
|
|
39822
40011
|
loading: serverEvents.loading,
|
|
39823
40012
|
sendMessage: handleSendMessage,
|
|
40013
|
+
abortRun,
|
|
39824
40014
|
messages,
|
|
39825
40015
|
streamingText: effectiveStreamingText,
|
|
39826
40016
|
streamingReasoning: effectiveStreamingReasoning,
|
|
@@ -39870,6 +40060,7 @@ function UseAIProvider({
|
|
|
39870
40060
|
const hasCustomChat = CustomChat !== void 0 && CustomChat !== null;
|
|
39871
40061
|
const chatPanelProps = {
|
|
39872
40062
|
onSendMessage: handleSendMessage,
|
|
40063
|
+
onAbort: abortRun,
|
|
39873
40064
|
messages,
|
|
39874
40065
|
loading: serverEvents.loading,
|
|
39875
40066
|
connected,
|
|
@@ -39917,6 +40108,7 @@ function UseAIProvider({
|
|
|
39917
40108
|
isOpen: isChatOpen,
|
|
39918
40109
|
onClose: () => handleSetChatOpen(false),
|
|
39919
40110
|
onSendMessage: handleSendMessage,
|
|
40111
|
+
onAbort: abortRun,
|
|
39920
40112
|
messages,
|
|
39921
40113
|
loading: serverEvents.loading,
|
|
39922
40114
|
connected,
|