@meetsmore-oss/use-ai-client 1.13.1 → 1.14.1
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 +466 -273
- package/dist/bundled.js.map +1 -1
- package/dist/index.d.ts +79 -4
- package/dist/index.js +465 -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;
|
|
@@ -23867,40 +23943,13 @@ var UseAIClient = class {
|
|
|
23867
23943
|
this._currentAssistantToolCalls = [];
|
|
23868
23944
|
this._pendingToolResults = [];
|
|
23869
23945
|
this._currentReasoningBlocks = [];
|
|
23946
|
+
this._currentMessageContent = "";
|
|
23870
23947
|
}
|
|
23871
23948
|
} 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
|
-
}
|
|
23949
|
+
this.finalizeRun({ aborted: false });
|
|
23950
|
+
}
|
|
23951
|
+
if (event.type === EventType.RUN_FINISHED || event.type === EventType.RUN_ERROR) {
|
|
23952
|
+
this._currentRunId = null;
|
|
23904
23953
|
}
|
|
23905
23954
|
this.eventHandlers.forEach((handler) => handler(event));
|
|
23906
23955
|
}
|
|
@@ -23964,10 +24013,12 @@ var UseAIClient = class {
|
|
|
23964
24013
|
// Type cast needed for Message type compatibility
|
|
23965
24014
|
};
|
|
23966
24015
|
this._messages.push(userMessage);
|
|
24016
|
+
const runId = v4_default();
|
|
24017
|
+
this._currentRunId = runId;
|
|
23967
24018
|
const runInput = {
|
|
23968
24019
|
threadId: this.threadId,
|
|
23969
24020
|
// Use getter to ensure non-null
|
|
23970
|
-
runId
|
|
24021
|
+
runId,
|
|
23971
24022
|
messages: this._messages,
|
|
23972
24023
|
tools: this._tools.map((t) => ({
|
|
23973
24024
|
name: t.name,
|
|
@@ -24022,6 +24073,115 @@ var UseAIClient = class {
|
|
|
24022
24073
|
this._pendingToolResults.push(toolResultMsg);
|
|
24023
24074
|
this.send(toolResultMessage);
|
|
24024
24075
|
}
|
|
24076
|
+
/**
|
|
24077
|
+
* Aborts the in-flight run, if any.
|
|
24078
|
+
* Sends an `abort_run` message to the server which cancels the AI stream
|
|
24079
|
+
* and rejects any pending tool/approval waits. The server then emits
|
|
24080
|
+
* `RUN_ERROR` with `ErrorCode.ABORTED`, which the client handles by
|
|
24081
|
+
* persisting the partial response.
|
|
24082
|
+
*
|
|
24083
|
+
* No-op when no run is in flight.
|
|
24084
|
+
*/
|
|
24085
|
+
abortRun() {
|
|
24086
|
+
const runId = this._currentRunId;
|
|
24087
|
+
if (!runId) return;
|
|
24088
|
+
this.send({
|
|
24089
|
+
type: "abort_run",
|
|
24090
|
+
data: { runId }
|
|
24091
|
+
});
|
|
24092
|
+
}
|
|
24093
|
+
/**
|
|
24094
|
+
* Flushes the final in-progress step into `_messages` when a run terminates.
|
|
24095
|
+
*
|
|
24096
|
+
* Only two terminations reach here. Truncation (maxOutputTokens / finish
|
|
24097
|
+
* reason 'length') and tool-execution errors never do — the server absorbs
|
|
24098
|
+
* them: truncation continues via a fallback step and ends as a normal
|
|
24099
|
+
* RUN_FINISHED, and tool errors come back as tool_results that keep the run
|
|
24100
|
+
* going. So the dispatch is binary:
|
|
24101
|
+
* - `aborted: false` (RUN_FINISHED): every tool-call step was already flushed
|
|
24102
|
+
* at STEP_FINISHED, so the in-progress step is always text-only.
|
|
24103
|
+
* - `aborted: true` (RUN_ERROR / ABORTED): the run may have been cut
|
|
24104
|
+
* mid-tool-call or mid-reasoning, so extra repair is needed.
|
|
24105
|
+
*
|
|
24106
|
+
* After this returns, `currentMessageContent` and `currentReasoningBlocks`
|
|
24107
|
+
* remain readable for the persistence helper. The next RUN_STARTED clears them.
|
|
24108
|
+
*/
|
|
24109
|
+
finalizeRun(opts) {
|
|
24110
|
+
if (opts.aborted) {
|
|
24111
|
+
this.finalizeAbortedRun();
|
|
24112
|
+
} else {
|
|
24113
|
+
this.finalizeCompletedRun();
|
|
24114
|
+
}
|
|
24115
|
+
}
|
|
24116
|
+
/**
|
|
24117
|
+
* Normal completion (RUN_FINISHED). The in-progress step is text-only —
|
|
24118
|
+
* tool-call steps were already flushed at STEP_FINISHED — so just push the
|
|
24119
|
+
* trailing assistant text with its reasoning.
|
|
24120
|
+
*/
|
|
24121
|
+
finalizeCompletedRun() {
|
|
24122
|
+
this._currentReasoningBlockText = "";
|
|
24123
|
+
if (!this._currentAssistantMessage) return;
|
|
24124
|
+
if (this._currentMessageContent) {
|
|
24125
|
+
const stepReasoning = this._currentReasoningBlocks.length > 0 ? [...this._currentReasoningBlocks] : void 0;
|
|
24126
|
+
this._messages.push({
|
|
24127
|
+
id: this._currentAssistantMessage.id || v4_default(),
|
|
24128
|
+
role: "assistant",
|
|
24129
|
+
content: this._currentMessageContent,
|
|
24130
|
+
...stepReasoning ? { reasoningParts: stepReasoning } : {}
|
|
24131
|
+
});
|
|
24132
|
+
}
|
|
24133
|
+
this._currentAssistantMessage = null;
|
|
24134
|
+
this._currentAssistantToolCalls = [];
|
|
24135
|
+
this._pendingToolResults = [];
|
|
24136
|
+
}
|
|
24137
|
+
/**
|
|
24138
|
+
* User-initiated abort (RUN_ERROR / ABORTED).
|
|
24139
|
+
*
|
|
24140
|
+
* Drops the in-progress step's reasoning blocks. A block gets its encrypted
|
|
24141
|
+
* signature on REASONING_ENCRYPTED_VALUE, which arrives after
|
|
24142
|
+
* REASONING_MESSAGE_END — so a mid-stream abort can leave signature-less
|
|
24143
|
+
* blocks. Persisting those would corrupt the next turn. Reasoning from
|
|
24144
|
+
* already-completed prior steps lives on STEP_FINISHED-flushed assistant
|
|
24145
|
+
* messages and is untouched. Aborted-step messages therefore never carry
|
|
24146
|
+
* reasoningParts.
|
|
24147
|
+
*/
|
|
24148
|
+
finalizeAbortedRun() {
|
|
24149
|
+
this._currentReasoningBlocks = [];
|
|
24150
|
+
this._currentReasoningBlockText = "";
|
|
24151
|
+
if (!this._currentAssistantMessage) return;
|
|
24152
|
+
if (this._currentAssistantToolCalls.length > 0) {
|
|
24153
|
+
this._messages.push({
|
|
24154
|
+
id: this._currentAssistantMessage.id || v4_default(),
|
|
24155
|
+
role: "assistant",
|
|
24156
|
+
content: this._currentMessageContent || "",
|
|
24157
|
+
toolCalls: [...this._currentAssistantToolCalls]
|
|
24158
|
+
});
|
|
24159
|
+
this._messages.push(...this._pendingToolResults);
|
|
24160
|
+
const respondedIds = new Set(
|
|
24161
|
+
this._pendingToolResults.map((m) => "toolCallId" in m ? m.toolCallId : void 0).filter((id) => typeof id === "string")
|
|
24162
|
+
);
|
|
24163
|
+
for (const tc of this._currentAssistantToolCalls) {
|
|
24164
|
+
if (!respondedIds.has(tc.id)) {
|
|
24165
|
+
this._messages.push({
|
|
24166
|
+
id: v4_default(),
|
|
24167
|
+
role: "tool",
|
|
24168
|
+
content: JSON.stringify({ aborted: true, reason: "Cancelled by user before tool finished" }),
|
|
24169
|
+
toolCallId: tc.id
|
|
24170
|
+
});
|
|
24171
|
+
}
|
|
24172
|
+
}
|
|
24173
|
+
this._currentMessageContent = "";
|
|
24174
|
+
} else if (this._currentMessageContent) {
|
|
24175
|
+
this._messages.push({
|
|
24176
|
+
id: this._currentAssistantMessage.id || v4_default(),
|
|
24177
|
+
role: "assistant",
|
|
24178
|
+
content: this._currentMessageContent
|
|
24179
|
+
});
|
|
24180
|
+
}
|
|
24181
|
+
this._currentAssistantMessage = null;
|
|
24182
|
+
this._currentAssistantToolCalls = [];
|
|
24183
|
+
this._pendingToolResults = [];
|
|
24184
|
+
}
|
|
24025
24185
|
/**
|
|
24026
24186
|
* Sends a tool approval response back to the server.
|
|
24027
24187
|
*
|
|
@@ -24116,6 +24276,12 @@ var UseAIClient = class {
|
|
|
24116
24276
|
get currentMessageContent() {
|
|
24117
24277
|
return this._currentMessageContent;
|
|
24118
24278
|
}
|
|
24279
|
+
/**
|
|
24280
|
+
* Gets the runId of the in-flight run, or null when no run is active.
|
|
24281
|
+
*/
|
|
24282
|
+
get currentRunId() {
|
|
24283
|
+
return this._currentRunId;
|
|
24284
|
+
}
|
|
24119
24285
|
/**
|
|
24120
24286
|
* Gets the current reasoning blocks collected during the current run.
|
|
24121
24287
|
*/
|
|
@@ -38348,7 +38514,7 @@ import { useState as useState7, useCallback as useCallback5, useRef as useRef5,
|
|
|
38348
38514
|
|
|
38349
38515
|
// src/utils/messageConversion.ts
|
|
38350
38516
|
function transformMessagesToClientFormat(persistedMessages) {
|
|
38351
|
-
return persistedMessages.map((msg) => {
|
|
38517
|
+
return persistedMessages.filter((msg) => msg.displayMode !== "info").map((msg) => {
|
|
38352
38518
|
switch (msg.role) {
|
|
38353
38519
|
case "tool":
|
|
38354
38520
|
return {
|
|
@@ -39321,6 +39487,7 @@ function useServerEvents({
|
|
|
39321
39487
|
const loadingRef = useRef10(loading);
|
|
39322
39488
|
loadingRef.current = loading;
|
|
39323
39489
|
const messageCountAtRunStartRef = useRef10(0);
|
|
39490
|
+
const runIdAtRunStartRef = useRef10(void 0);
|
|
39324
39491
|
const hasTextFromPriorStepRef = useRef10(false);
|
|
39325
39492
|
const [executingToolRaw, setExecutingTool] = useState13(null);
|
|
39326
39493
|
const executingToolFallbackRef = useRef10(null);
|
|
@@ -39333,11 +39500,37 @@ function useServerEvents({
|
|
|
39333
39500
|
saveAIResponseRef.current = saveAIResponse;
|
|
39334
39501
|
const stringsRef = useRef10(strings);
|
|
39335
39502
|
stringsRef.current = strings;
|
|
39503
|
+
const persistFinalResponse = useCallback11(async (client, opts) => {
|
|
39504
|
+
const content3 = client.currentMessageContent;
|
|
39505
|
+
const reasoningParts = client.currentReasoningBlocks.length > 0 ? [...client.currentReasoningBlocks] : void 0;
|
|
39506
|
+
const turnMessages = extractTurnMessages(client.messages, messageCountAtRunStartRef.current);
|
|
39507
|
+
if (opts.aborted) {
|
|
39508
|
+
const notice = stringsRef.current.notices.aborted;
|
|
39509
|
+
if (content3) {
|
|
39510
|
+
await saveAIResponseRef.current(content3, void 0, opts.traceId, turnMessages, reasoningParts);
|
|
39511
|
+
await saveAIResponseRef.current(notice, "info");
|
|
39512
|
+
} else {
|
|
39513
|
+
await saveAIResponseRef.current(notice, "info", opts.traceId, turnMessages);
|
|
39514
|
+
}
|
|
39515
|
+
return;
|
|
39516
|
+
}
|
|
39517
|
+
if (content3) {
|
|
39518
|
+
await saveAIResponseRef.current(content3, void 0, opts.traceId, turnMessages, reasoningParts);
|
|
39519
|
+
}
|
|
39520
|
+
}, []);
|
|
39521
|
+
const resetRunUiState = useCallback11(() => {
|
|
39522
|
+
setStreamingText("");
|
|
39523
|
+
setStreamingReasoning("");
|
|
39524
|
+
streamingChatIdRef.current = null;
|
|
39525
|
+
setExecutingTool(null);
|
|
39526
|
+
setLoading(false);
|
|
39527
|
+
}, []);
|
|
39336
39528
|
const handleServerEvent = useCallback11(async (client, event) => {
|
|
39337
39529
|
const ts = toolSystemRef.current;
|
|
39338
39530
|
const strs = stringsRef.current;
|
|
39339
39531
|
if (event.type === EventType.RUN_STARTED) {
|
|
39340
39532
|
messageCountAtRunStartRef.current = client.messages.length;
|
|
39533
|
+
runIdAtRunStartRef.current = client.currentRunId ?? void 0;
|
|
39341
39534
|
hasTextFromPriorStepRef.current = false;
|
|
39342
39535
|
setStreamingReasoning("");
|
|
39343
39536
|
} else if (event.type === EventType.REASONING_MESSAGE_START) {
|
|
@@ -39389,30 +39582,21 @@ function useServerEvents({
|
|
|
39389
39582
|
setStreamingText((prev) => prev + contentEvent.delta);
|
|
39390
39583
|
} else if (event.type === EventType.TEXT_MESSAGE_END) {
|
|
39391
39584
|
} 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);
|
|
39585
|
+
const finishedEvent = event;
|
|
39586
|
+
await persistFinalResponse(client, { aborted: false, traceId: finishedEvent.runId });
|
|
39587
|
+
resetRunUiState();
|
|
39405
39588
|
} else if (event.type === EventType.RUN_ERROR) {
|
|
39406
39589
|
const errorEvent = event;
|
|
39407
39590
|
const errorCode = errorEvent.message;
|
|
39408
|
-
|
|
39409
|
-
|
|
39410
|
-
|
|
39411
|
-
|
|
39412
|
-
|
|
39413
|
-
|
|
39414
|
-
|
|
39415
|
-
|
|
39591
|
+
if (errorCode === ErrorCode.ABORTED) {
|
|
39592
|
+
client.finalizeRun({ aborted: true });
|
|
39593
|
+
await persistFinalResponse(client, { aborted: true, traceId: runIdAtRunStartRef.current });
|
|
39594
|
+
} else {
|
|
39595
|
+
console.error("[ServerEvents] Run error:", errorCode);
|
|
39596
|
+
const userMessage = strs.errors[errorCode] || errorEvent.message || strs.errors[ErrorCode.UNKNOWN_ERROR];
|
|
39597
|
+
saveAIResponseRef.current(userMessage, "error");
|
|
39598
|
+
}
|
|
39599
|
+
resetRunUiState();
|
|
39416
39600
|
}
|
|
39417
39601
|
}, []);
|
|
39418
39602
|
const handleDisconnect = useCallback11(() => {
|
|
@@ -39582,6 +39766,8 @@ var noOpContextValue = {
|
|
|
39582
39766
|
},
|
|
39583
39767
|
delete: async () => {
|
|
39584
39768
|
}
|
|
39769
|
+
},
|
|
39770
|
+
abortRun: () => {
|
|
39585
39771
|
}
|
|
39586
39772
|
};
|
|
39587
39773
|
var DEFAULT_FILE_UPLOAD_CONFIG = {
|
|
@@ -39715,6 +39901,9 @@ function UseAIProvider({
|
|
|
39715
39901
|
console.error("Failed to register tools:", err);
|
|
39716
39902
|
}
|
|
39717
39903
|
}, [toolSystem.hasTools, toolSystem.aggregatedTools, connected]);
|
|
39904
|
+
const abortRun = useCallback13(() => {
|
|
39905
|
+
clientRef.current?.abortRun();
|
|
39906
|
+
}, []);
|
|
39718
39907
|
const handleSendMessage = useCallback13(async (message, attachments, messageForwardedProps) => {
|
|
39719
39908
|
if (!clientRef.current) return;
|
|
39720
39909
|
serverEvents.clearStreamingText();
|
|
@@ -39813,7 +40002,8 @@ function UseAIProvider({
|
|
|
39813
40002
|
save: saveCommand,
|
|
39814
40003
|
rename: renameCommand,
|
|
39815
40004
|
delete: deleteCommand
|
|
39816
|
-
}
|
|
40005
|
+
},
|
|
40006
|
+
abortRun
|
|
39817
40007
|
};
|
|
39818
40008
|
const effectiveStreamingText = serverEvents.streamingChatIdRef.current === chatManagement.displayedChatId ? serverEvents.streamingText : "";
|
|
39819
40009
|
const effectiveStreamingReasoning = serverEvents.streamingChatIdRef.current === chatManagement.displayedChatId ? serverEvents.streamingReasoning : "";
|
|
@@ -39821,6 +40011,7 @@ function UseAIProvider({
|
|
|
39821
40011
|
connected,
|
|
39822
40012
|
loading: serverEvents.loading,
|
|
39823
40013
|
sendMessage: handleSendMessage,
|
|
40014
|
+
abortRun,
|
|
39824
40015
|
messages,
|
|
39825
40016
|
streamingText: effectiveStreamingText,
|
|
39826
40017
|
streamingReasoning: effectiveStreamingReasoning,
|
|
@@ -39870,6 +40061,7 @@ function UseAIProvider({
|
|
|
39870
40061
|
const hasCustomChat = CustomChat !== void 0 && CustomChat !== null;
|
|
39871
40062
|
const chatPanelProps = {
|
|
39872
40063
|
onSendMessage: handleSendMessage,
|
|
40064
|
+
onAbort: abortRun,
|
|
39873
40065
|
messages,
|
|
39874
40066
|
loading: serverEvents.loading,
|
|
39875
40067
|
connected,
|
|
@@ -39917,6 +40109,7 @@ function UseAIProvider({
|
|
|
39917
40109
|
isOpen: isChatOpen,
|
|
39918
40110
|
onClose: () => handleSetChatOpen(false),
|
|
39919
40111
|
onSendMessage: handleSendMessage,
|
|
40112
|
+
onAbort: abortRun,
|
|
39920
40113
|
messages,
|
|
39921
40114
|
loading: serverEvents.loading,
|
|
39922
40115
|
connected,
|