@coral-ai/chat 0.5.0 → 0.6.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/README.md +14 -0
- package/dist/index.d.ts +2 -5
- package/dist/index.js +59 -229
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -22,4 +22,18 @@ import { Chat } from "@coral-ai/chat";
|
|
|
22
22
|
`ChatChunk`s, or a `ChatResponse`. A backend URL can also be supplied via the
|
|
23
23
|
`api` prop or `coral.config.json`'s `chat.api`.
|
|
24
24
|
|
|
25
|
+
`disclaimer?: React.ReactNode` adds optional content beneath the input. By
|
|
26
|
+
default no disclaimer or footer space is rendered; `undefined`, `null`, and
|
|
27
|
+
`false` also hide it. To retain the previous built-in text, opt in explicitly:
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
<Chat api="/api/chat" disclaimer="AI makes mistakes. Check outputs." />
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Custom React content, such as a policy link, is also supported.
|
|
34
|
+
|
|
25
35
|
See [coral-ai](https://github.com/mochimilk/coral-ai) for the full project.
|
|
36
|
+
|
|
37
|
+
## Migrating to 0.6
|
|
38
|
+
|
|
39
|
+
User-message editing and `useChatContext().editMessage` have been removed. Assistant Copy/Regenerate and error Retry remain. The disclaimer is opt-in: pass `disclaimer` to render footer content; omission reserves no space. Sidecars use the true default 15px assistant font. Message rows use a 0px gap; footer buttons are small with a 2px gap.
|
package/dist/index.d.ts
CHANGED
|
@@ -227,6 +227,8 @@ interface ChatProps {
|
|
|
227
227
|
* to invoke `sendMessage(text)` on click.
|
|
228
228
|
*/
|
|
229
229
|
promptSuggestions?: React__default.ReactNode;
|
|
230
|
+
/** Optional content below the input. Omit or pass null to render no footer or reserved space. */
|
|
231
|
+
disclaimer?: React__default.ReactNode;
|
|
230
232
|
/**
|
|
231
233
|
* Pass `null` to disable the chat's built-in surface motion (input slide to
|
|
232
234
|
* bottom on first message). Omit / leave undefined for default motion.
|
|
@@ -550,11 +552,6 @@ interface ChatContextValue {
|
|
|
550
552
|
* If `messageId` targets a user message, the existing assistant reply for that turn is discarded and re-generated.
|
|
551
553
|
*/
|
|
552
554
|
regenerate: (messageId?: string) => Promise<void>;
|
|
553
|
-
/**
|
|
554
|
-
* Replaces the content of an existing user message and re-runs from that point.
|
|
555
|
-
* Truncates everything after the edited message and re-invokes the handler.
|
|
556
|
-
*/
|
|
557
|
-
editMessage: (messageId: string, newContent: string) => Promise<void>;
|
|
558
555
|
scrollToBottom: () => void;
|
|
559
556
|
/** Pre-binds navigator.clipboard.writeText + the onCopy prop callback. */
|
|
560
557
|
handleCopy: (content: string) => void;
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// src/Chat.tsx
|
|
2
|
-
import { useLayoutEffect as useLayoutEffect3, useRef as useRef7, useState as useState7 } from "react";
|
|
3
2
|
import {
|
|
4
|
-
Caption1 as
|
|
3
|
+
Caption1 as Caption13,
|
|
5
4
|
Title3,
|
|
6
5
|
makeStyles as makeStyles10,
|
|
7
6
|
motionTokens
|
|
@@ -183,7 +182,7 @@ var useStyles2 = makeStyles2({
|
|
|
183
182
|
zIndex: 1e3,
|
|
184
183
|
cursor: "pointer",
|
|
185
184
|
boxShadow: tokens2.shadow8,
|
|
186
|
-
marginBottom: "
|
|
185
|
+
marginBottom: "12px",
|
|
187
186
|
backgroundColor: "var(--colorNeutralBackgroundAlpha2)",
|
|
188
187
|
backdropFilter: "blur(40px) saturate(150%)"
|
|
189
188
|
}
|
|
@@ -675,29 +674,12 @@ var ChatCanvas = ({
|
|
|
675
674
|
const baseMessages = messages.slice(0, userIdx + 1);
|
|
676
675
|
await runHandler(userMsg.content, baseMessages, []);
|
|
677
676
|
};
|
|
678
|
-
const editMessage = async (messageId, newContent) => {
|
|
679
|
-
const idx = messages.findIndex((m) => m.id === messageId);
|
|
680
|
-
if (idx === -1) return;
|
|
681
|
-
if (messages[idx].role !== "user") return;
|
|
682
|
-
const trimmed = newContent.replace(/^[\n\r]+|[\n\r]+$/g, "");
|
|
683
|
-
if (!trimmed.trim()) return;
|
|
684
|
-
const editedMessage = {
|
|
685
|
-
...messages[idx],
|
|
686
|
-
content: trimmed
|
|
687
|
-
};
|
|
688
|
-
const baseMessages = [
|
|
689
|
-
...messages.slice(0, idx),
|
|
690
|
-
editedMessage
|
|
691
|
-
];
|
|
692
|
-
await runHandler(trimmed, baseMessages, []);
|
|
693
|
-
};
|
|
694
677
|
return /* @__PURE__ */ jsx2(
|
|
695
678
|
ChatContext.Provider,
|
|
696
679
|
{
|
|
697
680
|
value: {
|
|
698
681
|
sendMessage,
|
|
699
682
|
regenerate,
|
|
700
|
-
editMessage,
|
|
701
683
|
scrollToBottom,
|
|
702
684
|
handleCopy,
|
|
703
685
|
messages,
|
|
@@ -733,6 +715,7 @@ var ChatCanvas = ({
|
|
|
733
715
|
Button2,
|
|
734
716
|
{
|
|
735
717
|
onClick: scrollToBottom,
|
|
718
|
+
"aria-label": "Scroll to bottom",
|
|
736
719
|
className: styles.scrollToBottom,
|
|
737
720
|
shape: "circular",
|
|
738
721
|
style: {
|
|
@@ -755,15 +738,12 @@ import React5, { useEffect as useEffect4, useLayoutEffect as useLayoutEffect2, u
|
|
|
755
738
|
import {
|
|
756
739
|
Body1 as Body15,
|
|
757
740
|
Button as Button4,
|
|
758
|
-
Caption1 as Caption12,
|
|
759
741
|
makeStyles as makeStyles7,
|
|
760
742
|
tokens as tokens7
|
|
761
743
|
} from "@fluentui/react-components";
|
|
762
744
|
import {
|
|
763
745
|
ArrowClockwise,
|
|
764
|
-
Copy
|
|
765
|
-
Edit as EditIcon,
|
|
766
|
-
Info
|
|
746
|
+
Copy
|
|
767
747
|
} from "@coral-ai/bundleicons";
|
|
768
748
|
import {
|
|
769
749
|
CoralMarkdown
|
|
@@ -1228,7 +1208,7 @@ var Chat_TodoList_default = ChatTodoList;
|
|
|
1228
1208
|
// src/Chat.Messages.tsx
|
|
1229
1209
|
import { CoralChart } from "@coral-ai/charts";
|
|
1230
1210
|
import { CheckmarkCircle20Filled } from "@fluentui/react-icons";
|
|
1231
|
-
import {
|
|
1211
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1232
1212
|
function resolveBlocks(msg) {
|
|
1233
1213
|
if (msg.blocks) return msg.blocks;
|
|
1234
1214
|
const legacy = [];
|
|
@@ -1256,7 +1236,7 @@ var useStyles7 = makeStyles7({
|
|
|
1256
1236
|
messageWrapper: {
|
|
1257
1237
|
display: "flex",
|
|
1258
1238
|
flexDirection: "column",
|
|
1259
|
-
gap: "
|
|
1239
|
+
gap: "0px",
|
|
1260
1240
|
width: "100%",
|
|
1261
1241
|
maxWidth: "768px",
|
|
1262
1242
|
padding: "0 16px",
|
|
@@ -1286,51 +1266,12 @@ var useStyles7 = makeStyles7({
|
|
|
1286
1266
|
display: "flex",
|
|
1287
1267
|
justifyContent: "flex-end",
|
|
1288
1268
|
marginTop: "6px",
|
|
1289
|
-
marginRight: "-10px",
|
|
1290
1269
|
opacity: 0,
|
|
1291
1270
|
transition: "opacity 120ms ease-in-out"
|
|
1292
1271
|
},
|
|
1293
1272
|
userActions: {
|
|
1294
|
-
display: "flex"
|
|
1295
|
-
},
|
|
1296
|
-
// ── Inline edit mode ──
|
|
1297
|
-
userEditWrap: {
|
|
1298
1273
|
display: "flex",
|
|
1299
|
-
|
|
1300
|
-
alignItems: "stretch",
|
|
1301
|
-
// width: "min(640px, 80vw)",
|
|
1302
|
-
gap: "8px"
|
|
1303
|
-
},
|
|
1304
|
-
userEditTextarea: {
|
|
1305
|
-
backgroundColor: tokens7.colorNeutralBackground2,
|
|
1306
|
-
color: tokens7.colorNeutralForeground2,
|
|
1307
|
-
border: `1px solid ${tokens7.colorNeutralStroke1}`,
|
|
1308
|
-
padding: "8px 12px",
|
|
1309
|
-
borderRadius: tokens7.borderRadiusLarge,
|
|
1310
|
-
fontFamily: tokens7.fontFamilyBase,
|
|
1311
|
-
fontSize: tokens7.fontSizeBase300,
|
|
1312
|
-
lineHeight: tokens7.lineHeightBase300,
|
|
1313
|
-
resize: "none",
|
|
1314
|
-
outline: "none",
|
|
1315
|
-
width: "100%",
|
|
1316
|
-
boxSizing: "border-box",
|
|
1317
|
-
minHeight: "40px",
|
|
1318
|
-
"&:focus": {
|
|
1319
|
-
border: `1px solid ${tokens7.colorNeutralStroke3}`
|
|
1320
|
-
}
|
|
1321
|
-
},
|
|
1322
|
-
userEditFooter: {
|
|
1323
|
-
display: "flex",
|
|
1324
|
-
marginTop: "8px",
|
|
1325
|
-
// marginLeft: "12px",
|
|
1326
|
-
color: `${tokens7.colorNeutralForeground3}`,
|
|
1327
|
-
gap: "12px",
|
|
1328
|
-
alignItems: "center"
|
|
1329
|
-
},
|
|
1330
|
-
userEditActions: {
|
|
1331
|
-
display: "flex",
|
|
1332
|
-
justifyContent: "flex-end",
|
|
1333
|
-
gap: "8px"
|
|
1274
|
+
gap: "2px"
|
|
1334
1275
|
},
|
|
1335
1276
|
// ── Assistant message ──
|
|
1336
1277
|
messageAssistant: {
|
|
@@ -1347,20 +1288,20 @@ var useStyles7 = makeStyles7({
|
|
|
1347
1288
|
display: "flex",
|
|
1348
1289
|
justifyContent: "space-between",
|
|
1349
1290
|
marginTop: "6px",
|
|
1350
|
-
marginLeft: "-10px",
|
|
1351
1291
|
// Hover-only by default; the latest message overrides this to stay visible.
|
|
1352
1292
|
opacity: 0,
|
|
1353
1293
|
transition: "opacity 120ms ease-in-out"
|
|
1354
1294
|
},
|
|
1355
1295
|
assistantActions: {
|
|
1356
|
-
display: "flex"
|
|
1296
|
+
display: "flex",
|
|
1297
|
+
gap: "2px"
|
|
1357
1298
|
},
|
|
1358
1299
|
copiedBadge: {
|
|
1359
1300
|
display: "inline-flex",
|
|
1360
1301
|
alignItems: "center",
|
|
1361
1302
|
justifyContent: "center",
|
|
1362
|
-
width: "
|
|
1363
|
-
height: "
|
|
1303
|
+
width: "24px",
|
|
1304
|
+
height: "24px",
|
|
1364
1305
|
color: tokens7.colorPaletteSeafoamForeground2
|
|
1365
1306
|
},
|
|
1366
1307
|
footerIconButton: {
|
|
@@ -1387,7 +1328,6 @@ var ChatMessages = ({
|
|
|
1387
1328
|
thinkingStatus,
|
|
1388
1329
|
sendMessage,
|
|
1389
1330
|
regenerate,
|
|
1390
|
-
editMessage,
|
|
1391
1331
|
handleCopy,
|
|
1392
1332
|
lastUserInputRef,
|
|
1393
1333
|
registerMessagesContainer,
|
|
@@ -1402,55 +1342,10 @@ var ChatMessages = ({
|
|
|
1402
1342
|
const isSidecar = surface === "panel-right";
|
|
1403
1343
|
const [copiedKey, setCopiedKey] = useState5(null);
|
|
1404
1344
|
const copiedTimerRef = useRef4(null);
|
|
1405
|
-
const [editingId, setEditingId] = useState5(null);
|
|
1406
|
-
const [editDraft, setEditDraft] = useState5("");
|
|
1407
|
-
const editTextareaRef = useRef4(null);
|
|
1408
1345
|
useEffect4(() => {
|
|
1409
1346
|
registerMessagesContainer(containerRef.current);
|
|
1410
1347
|
return () => registerMessagesContainer(null);
|
|
1411
1348
|
}, []);
|
|
1412
|
-
useLayoutEffect2(() => {
|
|
1413
|
-
if (editingId && editTextareaRef.current) {
|
|
1414
|
-
const ta = editTextareaRef.current;
|
|
1415
|
-
ta.focus();
|
|
1416
|
-
ta.setSelectionRange(ta.value.length, ta.value.length);
|
|
1417
|
-
ta.style.height = "auto";
|
|
1418
|
-
ta.style.height = `${ta.scrollHeight}px`;
|
|
1419
|
-
}
|
|
1420
|
-
}, [editingId]);
|
|
1421
|
-
const startEdit = (msg) => {
|
|
1422
|
-
if (!msg.id) return;
|
|
1423
|
-
setEditingId(msg.id);
|
|
1424
|
-
setEditDraft(msg.content);
|
|
1425
|
-
};
|
|
1426
|
-
const cancelEdit = () => {
|
|
1427
|
-
setEditingId(null);
|
|
1428
|
-
setEditDraft("");
|
|
1429
|
-
};
|
|
1430
|
-
const saveEdit = async () => {
|
|
1431
|
-
if (!editingId) return;
|
|
1432
|
-
const trimmed = editDraft.trim();
|
|
1433
|
-
if (!trimmed) return;
|
|
1434
|
-
const id = editingId;
|
|
1435
|
-
setEditingId(null);
|
|
1436
|
-
setEditDraft("");
|
|
1437
|
-
await editMessage(id, trimmed);
|
|
1438
|
-
};
|
|
1439
|
-
const handleEditTextareaInput = (e) => {
|
|
1440
|
-
setEditDraft(e.target.value);
|
|
1441
|
-
const ta = e.target;
|
|
1442
|
-
ta.style.height = "auto";
|
|
1443
|
-
ta.style.height = `${ta.scrollHeight}px`;
|
|
1444
|
-
};
|
|
1445
|
-
const handleEditKeyDown = (e) => {
|
|
1446
|
-
if (e.key === "Escape") {
|
|
1447
|
-
e.preventDefault();
|
|
1448
|
-
cancelEdit();
|
|
1449
|
-
} else if (e.key === "Enter" && !e.shiftKey) {
|
|
1450
|
-
e.preventDefault();
|
|
1451
|
-
void saveEdit();
|
|
1452
|
-
}
|
|
1453
|
-
};
|
|
1454
1349
|
const onCopyMerged = (content, key) => {
|
|
1455
1350
|
handleCopy(content);
|
|
1456
1351
|
onCopy?.(content);
|
|
@@ -1460,7 +1355,6 @@ var ChatMessages = ({
|
|
|
1460
1355
|
};
|
|
1461
1356
|
const renderUserMessage = (msg, index) => {
|
|
1462
1357
|
const key = msg.id ?? `idx-${index}`;
|
|
1463
|
-
const isEditing = !!msg.id && editingId === msg.id;
|
|
1464
1358
|
const attachments = Array.isArray(msg.metadata?.attachments) ? msg.metadata.attachments : null;
|
|
1465
1359
|
return /* @__PURE__ */ jsxs7("div", { className: styles.userRow, children: [
|
|
1466
1360
|
attachments && /* @__PURE__ */ jsx7(
|
|
@@ -1506,73 +1400,21 @@ var ChatMessages = ({
|
|
|
1506
1400
|
)
|
|
1507
1401
|
}
|
|
1508
1402
|
),
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
{
|
|
1525
|
-
style: {
|
|
1526
|
-
marginRight: "6px",
|
|
1527
|
-
color: `${tokens7.colorNeutralForeground3}`,
|
|
1528
|
-
fontSize: "20px",
|
|
1529
|
-
boxSizing: "border-box",
|
|
1530
|
-
flexShrink: 0
|
|
1531
|
-
}
|
|
1532
|
-
}
|
|
1533
|
-
),
|
|
1534
|
-
/* @__PURE__ */ jsx7(Caption12, { children: "Editing this message will discard the current response and regenerate from here." }),
|
|
1535
|
-
/* @__PURE__ */ jsxs7("div", { className: styles.userEditActions, children: [
|
|
1536
|
-
/* @__PURE__ */ jsx7(Button4, { appearance: "subtle", onClick: cancelEdit, children: "Cancel" }),
|
|
1537
|
-
/* @__PURE__ */ jsx7(
|
|
1538
|
-
Button4,
|
|
1539
|
-
{
|
|
1540
|
-
appearance: "primary",
|
|
1541
|
-
onClick: saveEdit,
|
|
1542
|
-
disabled: !editDraft.trim(),
|
|
1543
|
-
children: "Save"
|
|
1544
|
-
}
|
|
1545
|
-
)
|
|
1546
|
-
] })
|
|
1547
|
-
] })
|
|
1548
|
-
] }) : /* @__PURE__ */ jsxs7(Fragment, { children: [
|
|
1549
|
-
/* @__PURE__ */ jsx7("div", { className: styles.userBubble, children: /* @__PURE__ */ jsx7(Body15, { children: msg.content.split("\n").map((line, i, arr) => /* @__PURE__ */ jsxs7(React5.Fragment, { children: [
|
|
1550
|
-
line,
|
|
1551
|
-
i < arr.length - 1 && /* @__PURE__ */ jsx7("br", {})
|
|
1552
|
-
] }, i)) }) }),
|
|
1553
|
-
msg.id && /* @__PURE__ */ jsx7("div", { className: `${styles.userFooter} coral-user-footer`, children: /* @__PURE__ */ jsxs7("div", { className: styles.userActions, children: [
|
|
1554
|
-
copiedKey === `user-${key}` ? /* @__PURE__ */ jsx7("span", { className: styles.copiedBadge, children: /* @__PURE__ */ jsx7(CheckmarkCircle20Filled, {}) }) : /* @__PURE__ */ jsx7(
|
|
1555
|
-
Button4,
|
|
1556
|
-
{
|
|
1557
|
-
onClick: () => onCopyMerged(msg.content, `user-${key}`),
|
|
1558
|
-
title: "Copy message",
|
|
1559
|
-
appearance: "subtle",
|
|
1560
|
-
className: styles.footerIconButton,
|
|
1561
|
-
icon: /* @__PURE__ */ jsx7(Copy, {})
|
|
1562
|
-
}
|
|
1563
|
-
),
|
|
1564
|
-
/* @__PURE__ */ jsx7(
|
|
1565
|
-
Button4,
|
|
1566
|
-
{
|
|
1567
|
-
onClick: () => startEdit(msg),
|
|
1568
|
-
title: "Edit message",
|
|
1569
|
-
appearance: "subtle",
|
|
1570
|
-
className: styles.footerIconButton,
|
|
1571
|
-
icon: /* @__PURE__ */ jsx7(EditIcon, {})
|
|
1572
|
-
}
|
|
1573
|
-
)
|
|
1574
|
-
] }) })
|
|
1575
|
-
] })
|
|
1403
|
+
/* @__PURE__ */ jsx7("div", { className: styles.userBubble, children: /* @__PURE__ */ jsx7(Body15, { children: msg.content.split("\n").map((line, i, arr) => /* @__PURE__ */ jsxs7(React5.Fragment, { children: [
|
|
1404
|
+
line,
|
|
1405
|
+
i < arr.length - 1 && /* @__PURE__ */ jsx7("br", {})
|
|
1406
|
+
] }, i)) }) }),
|
|
1407
|
+
msg.id && /* @__PURE__ */ jsx7("div", { className: `${styles.userFooter} coral-user-footer`, children: /* @__PURE__ */ jsx7("div", { className: styles.userActions, children: copiedKey === `user-${key}` ? /* @__PURE__ */ jsx7("span", { className: styles.copiedBadge, children: /* @__PURE__ */ jsx7(CheckmarkCircle20Filled, {}) }) : /* @__PURE__ */ jsx7(
|
|
1408
|
+
Button4,
|
|
1409
|
+
{
|
|
1410
|
+
onClick: () => onCopyMerged(msg.content, `user-${key}`),
|
|
1411
|
+
title: "Copy message",
|
|
1412
|
+
appearance: "subtle",
|
|
1413
|
+
size: "small",
|
|
1414
|
+
className: styles.footerIconButton,
|
|
1415
|
+
icon: /* @__PURE__ */ jsx7(Copy, {})
|
|
1416
|
+
}
|
|
1417
|
+
) }) })
|
|
1576
1418
|
] }, key);
|
|
1577
1419
|
};
|
|
1578
1420
|
const renderAssistantMessage = (msg, index) => {
|
|
@@ -1651,6 +1493,7 @@ var ChatMessages = ({
|
|
|
1651
1493
|
onClick: () => onCopyMerged(msg.content, `assistant-${key}`),
|
|
1652
1494
|
title: "Copy response",
|
|
1653
1495
|
appearance: "subtle",
|
|
1496
|
+
size: "small",
|
|
1654
1497
|
className: styles.footerIconButton,
|
|
1655
1498
|
icon: /* @__PURE__ */ jsx7(Copy, {})
|
|
1656
1499
|
}
|
|
@@ -1661,6 +1504,7 @@ var ChatMessages = ({
|
|
|
1661
1504
|
onClick: () => regenerate(msg.id),
|
|
1662
1505
|
title: "Regenerate response",
|
|
1663
1506
|
appearance: "subtle",
|
|
1507
|
+
size: "small",
|
|
1664
1508
|
className: styles.footerIconButton,
|
|
1665
1509
|
icon: /* @__PURE__ */ jsx7(ArrowClockwise, {})
|
|
1666
1510
|
}
|
|
@@ -1674,7 +1518,7 @@ var ChatMessages = ({
|
|
|
1674
1518
|
"div",
|
|
1675
1519
|
{
|
|
1676
1520
|
className: styles.messageWrapper,
|
|
1677
|
-
style: isSidecar ? { padding: "0
|
|
1521
|
+
style: isSidecar ? { padding: "0 16px" } : void 0,
|
|
1678
1522
|
children: [
|
|
1679
1523
|
messages.map((msg, index) => {
|
|
1680
1524
|
if (msg.role === "user") {
|
|
@@ -1728,7 +1572,7 @@ import {
|
|
|
1728
1572
|
MenuItem
|
|
1729
1573
|
} from "@fluentui/react-components";
|
|
1730
1574
|
import { Add, DocumentAdd, ImageAdd } from "@coral-ai/bundleicons";
|
|
1731
|
-
import { Fragment
|
|
1575
|
+
import { Fragment, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1732
1576
|
var ChatAttachButton = ({
|
|
1733
1577
|
types = ["files", "photos"]
|
|
1734
1578
|
}) => {
|
|
@@ -1737,7 +1581,7 @@ var ChatAttachButton = ({
|
|
|
1737
1581
|
const photoRef = useRef5(null);
|
|
1738
1582
|
const showFiles = types.includes("files");
|
|
1739
1583
|
const showPhotos = types.includes("photos");
|
|
1740
|
-
return /* @__PURE__ */ jsxs8(
|
|
1584
|
+
return /* @__PURE__ */ jsxs8(Fragment, { children: [
|
|
1741
1585
|
showFiles && /* @__PURE__ */ jsx8(
|
|
1742
1586
|
"input",
|
|
1743
1587
|
{
|
|
@@ -1812,9 +1656,6 @@ var useStyles8 = makeStyles8({
|
|
|
1812
1656
|
boxSizing: "border-box",
|
|
1813
1657
|
overflow: "hidden"
|
|
1814
1658
|
},
|
|
1815
|
-
cardFocused: {
|
|
1816
|
-
boxShadow: tokens8.shadow28
|
|
1817
|
-
},
|
|
1818
1659
|
cardDisabled: {
|
|
1819
1660
|
opacity: "0.3",
|
|
1820
1661
|
pointerEvents: "none"
|
|
@@ -1990,7 +1831,7 @@ var ChatInput = forwardRef(
|
|
|
1990
1831
|
return /* @__PURE__ */ jsx9("div", { ref: containerRef, className: styles.wrapper, style, children: /* @__PURE__ */ jsxs9(
|
|
1991
1832
|
"div",
|
|
1992
1833
|
{
|
|
1993
|
-
className: `${styles.card}${
|
|
1834
|
+
className: `${styles.card}${disabled ? ` ${styles.cardDisabled}` : ""}`,
|
|
1994
1835
|
style: {
|
|
1995
1836
|
border: isFocused ? `1px solid ${tokens8.colorNeutralStroke1}` : `1px solid ${tokens8.colorNeutralStroke2}`
|
|
1996
1837
|
},
|
|
@@ -2064,7 +1905,7 @@ var ChatInput = forwardRef(
|
|
|
2064
1905
|
var Chat_Input_default = ChatInput;
|
|
2065
1906
|
|
|
2066
1907
|
// src/Chat.Approval.tsx
|
|
2067
|
-
import { Body1 as Body17, Body1Strong, Button as Button7, Caption1 as
|
|
1908
|
+
import { Body1 as Body17, Body1Strong, Button as Button7, Caption1 as Caption12, makeStyles as makeStyles9, tokens as tokens9 } from "@fluentui/react-components";
|
|
2068
1909
|
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2069
1910
|
var useStyles9 = makeStyles9({
|
|
2070
1911
|
root: {
|
|
@@ -2159,7 +2000,7 @@ var ChatApproval = ({
|
|
|
2159
2000
|
opt.id
|
|
2160
2001
|
);
|
|
2161
2002
|
}) }),
|
|
2162
|
-
awaitingFreeform && !isAnswered && /* @__PURE__ */ jsx10(
|
|
2003
|
+
awaitingFreeform && !isAnswered && /* @__PURE__ */ jsx10(Caption12, { className: styles.hint, children: "Type your reply in the message box below." })
|
|
2163
2004
|
]
|
|
2164
2005
|
}
|
|
2165
2006
|
);
|
|
@@ -2167,7 +2008,7 @@ var ChatApproval = ({
|
|
|
2167
2008
|
var Chat_Approval_default = ChatApproval;
|
|
2168
2009
|
|
|
2169
2010
|
// src/Chat.tsx
|
|
2170
|
-
import { Fragment as
|
|
2011
|
+
import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2171
2012
|
var useStyles10 = makeStyles10({
|
|
2172
2013
|
emptySlot: {
|
|
2173
2014
|
width: "100%",
|
|
@@ -2208,15 +2049,10 @@ var useStyles10 = makeStyles10({
|
|
|
2208
2049
|
justifyContent: "center"
|
|
2209
2050
|
}
|
|
2210
2051
|
});
|
|
2211
|
-
var remapFontSizeForSurface = (size, surface) => {
|
|
2212
|
-
if (surface === "panel-right" && (size === void 0 || size === "default")) {
|
|
2213
|
-
return "small";
|
|
2214
|
-
}
|
|
2215
|
-
return size;
|
|
2216
|
-
};
|
|
2217
2052
|
var ChatLayout = ({
|
|
2218
2053
|
welcomeMessage,
|
|
2219
2054
|
promptSuggestions,
|
|
2055
|
+
disclaimer,
|
|
2220
2056
|
surfaceMotion,
|
|
2221
2057
|
placeholder,
|
|
2222
2058
|
disabled,
|
|
@@ -2231,13 +2067,6 @@ var ChatLayout = ({
|
|
|
2231
2067
|
const welcomeIsFill = welcomeMessage !== void 0 && typeof welcomeMessage !== "string";
|
|
2232
2068
|
const welcomeNode = typeof welcomeMessage === "string" ? /* @__PURE__ */ jsx11(Title3, { children: welcomeMessage }) : welcomeMessage;
|
|
2233
2069
|
const styles = useStyles10();
|
|
2234
|
-
const surfaceProbeRef = useRef7(null);
|
|
2235
|
-
const [surface, setSurface] = useState7(null);
|
|
2236
|
-
useLayoutEffect3(() => {
|
|
2237
|
-
const el = surfaceProbeRef.current?.closest("[data-coral-surface]");
|
|
2238
|
-
setSurface(el?.getAttribute("data-coral-surface") ?? null);
|
|
2239
|
-
}, []);
|
|
2240
|
-
const effectiveFontSize = remapFontSizeForSurface(fontSize, surface);
|
|
2241
2070
|
const { messages, isTyping, pendingApproval, awaitingFreeformApproval } = useChatContext();
|
|
2242
2071
|
const empty = messages.every((m) => m.role === "system") && !isTyping;
|
|
2243
2072
|
const approvalLocksInput = pendingApproval !== null && awaitingFreeformApproval === null;
|
|
@@ -2246,11 +2075,10 @@ var ChatLayout = ({
|
|
|
2246
2075
|
const curve = motionTokens.curveDecelerateMax;
|
|
2247
2076
|
const spacerTransition = motionEnabled ? `flex-grow 300ms ${curve}` : "none";
|
|
2248
2077
|
const gapTransition = motionEnabled ? `height 300ms ${curve}` : "none";
|
|
2249
|
-
return /* @__PURE__ */ jsxs11(
|
|
2078
|
+
return /* @__PURE__ */ jsxs11(Fragment2, { children: [
|
|
2250
2079
|
/* @__PURE__ */ jsx11(
|
|
2251
2080
|
"div",
|
|
2252
2081
|
{
|
|
2253
|
-
ref: surfaceProbeRef,
|
|
2254
2082
|
style: {
|
|
2255
2083
|
flexGrow: empty && !welcomeIsFill ? 1 : 0,
|
|
2256
2084
|
flexShrink: 1,
|
|
@@ -2285,7 +2113,7 @@ var ChatLayout = ({
|
|
|
2285
2113
|
components,
|
|
2286
2114
|
onCopy,
|
|
2287
2115
|
onNavigate,
|
|
2288
|
-
fontSize
|
|
2116
|
+
fontSize,
|
|
2289
2117
|
fontFamily
|
|
2290
2118
|
}
|
|
2291
2119
|
)
|
|
@@ -2317,8 +2145,8 @@ var ChatLayout = ({
|
|
|
2317
2145
|
}
|
|
2318
2146
|
}
|
|
2319
2147
|
),
|
|
2320
|
-
/* @__PURE__ */ jsx11(
|
|
2321
|
-
|
|
2148
|
+
disclaimer != null && disclaimer !== false && /* @__PURE__ */ jsx11(
|
|
2149
|
+
Caption13,
|
|
2322
2150
|
{
|
|
2323
2151
|
style: {
|
|
2324
2152
|
display: "flex",
|
|
@@ -2327,7 +2155,7 @@ var ChatLayout = ({
|
|
|
2327
2155
|
height: "32px",
|
|
2328
2156
|
opacity: 0.5
|
|
2329
2157
|
},
|
|
2330
|
-
children:
|
|
2158
|
+
children: disclaimer
|
|
2331
2159
|
}
|
|
2332
2160
|
)
|
|
2333
2161
|
] });
|
|
@@ -2347,6 +2175,7 @@ var Chat = ({
|
|
|
2347
2175
|
onStop,
|
|
2348
2176
|
welcomeMessage,
|
|
2349
2177
|
promptSuggestions,
|
|
2178
|
+
disclaimer,
|
|
2350
2179
|
surfaceMotion,
|
|
2351
2180
|
components,
|
|
2352
2181
|
onCopy,
|
|
@@ -2381,6 +2210,7 @@ var Chat = ({
|
|
|
2381
2210
|
{
|
|
2382
2211
|
welcomeMessage,
|
|
2383
2212
|
promptSuggestions,
|
|
2213
|
+
disclaimer,
|
|
2384
2214
|
surfaceMotion,
|
|
2385
2215
|
placeholder,
|
|
2386
2216
|
disabled,
|
|
@@ -2737,13 +2567,13 @@ function createAgentHandler(options) {
|
|
|
2737
2567
|
}
|
|
2738
2568
|
|
|
2739
2569
|
// src/Chat.Threads.tsx
|
|
2740
|
-
import * as
|
|
2570
|
+
import * as React8 from "react";
|
|
2741
2571
|
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
2742
|
-
var ChatThreadsContext =
|
|
2572
|
+
var ChatThreadsContext = React8.createContext(
|
|
2743
2573
|
null
|
|
2744
2574
|
);
|
|
2745
2575
|
function useChatThreads() {
|
|
2746
|
-
const value =
|
|
2576
|
+
const value = React8.useContext(ChatThreadsContext);
|
|
2747
2577
|
if (!value) {
|
|
2748
2578
|
throw new Error(
|
|
2749
2579
|
"useChatThreads must be used inside <ChatThreadsProvider>."
|
|
@@ -2789,25 +2619,25 @@ function ChatThreadsProvider({
|
|
|
2789
2619
|
onActiveThreadChange,
|
|
2790
2620
|
children
|
|
2791
2621
|
}) {
|
|
2792
|
-
const adapter =
|
|
2622
|
+
const adapter = React8.useMemo(
|
|
2793
2623
|
() => providedAdapter ?? createMemoryThreadsAdapter(),
|
|
2794
2624
|
[providedAdapter]
|
|
2795
2625
|
);
|
|
2796
|
-
const [threads, setThreads] =
|
|
2797
|
-
const [uncontrolledId, setUncontrolledId] =
|
|
2626
|
+
const [threads, setThreads] = React8.useState([]);
|
|
2627
|
+
const [uncontrolledId, setUncontrolledId] = React8.useState(
|
|
2798
2628
|
defaultActiveThreadId
|
|
2799
2629
|
);
|
|
2800
|
-
const [isLoading, setIsLoading] =
|
|
2630
|
+
const [isLoading, setIsLoading] = React8.useState(true);
|
|
2801
2631
|
const isControlled = controlledId !== void 0;
|
|
2802
2632
|
const activeThreadId = isControlled ? controlledId : uncontrolledId;
|
|
2803
|
-
const setActiveThreadId =
|
|
2633
|
+
const setActiveThreadId = React8.useCallback(
|
|
2804
2634
|
(id) => {
|
|
2805
2635
|
if (!isControlled) setUncontrolledId(id);
|
|
2806
2636
|
onActiveThreadChange?.(id);
|
|
2807
2637
|
},
|
|
2808
2638
|
[isControlled, onActiveThreadChange]
|
|
2809
2639
|
);
|
|
2810
|
-
|
|
2640
|
+
React8.useEffect(() => {
|
|
2811
2641
|
let cancelled = false;
|
|
2812
2642
|
(async () => {
|
|
2813
2643
|
setIsLoading(true);
|
|
@@ -2820,7 +2650,7 @@ function ChatThreadsProvider({
|
|
|
2820
2650
|
cancelled = true;
|
|
2821
2651
|
};
|
|
2822
2652
|
}, [adapter]);
|
|
2823
|
-
const createThread =
|
|
2653
|
+
const createThread = React8.useCallback(
|
|
2824
2654
|
async (initial) => {
|
|
2825
2655
|
const thread = await adapter.create(initial);
|
|
2826
2656
|
setThreads((prev) => [thread, ...prev.filter((t) => t.id !== thread.id)]);
|
|
@@ -2828,7 +2658,7 @@ function ChatThreadsProvider({
|
|
|
2828
2658
|
},
|
|
2829
2659
|
[adapter]
|
|
2830
2660
|
);
|
|
2831
|
-
const renameThread =
|
|
2661
|
+
const renameThread = React8.useCallback(
|
|
2832
2662
|
async (id, newTitle) => {
|
|
2833
2663
|
await adapter.rename(id, newTitle);
|
|
2834
2664
|
setThreads(
|
|
@@ -2839,7 +2669,7 @@ function ChatThreadsProvider({
|
|
|
2839
2669
|
},
|
|
2840
2670
|
[adapter]
|
|
2841
2671
|
);
|
|
2842
|
-
const removeThread =
|
|
2672
|
+
const removeThread = React8.useCallback(
|
|
2843
2673
|
async (id) => {
|
|
2844
2674
|
await adapter.remove(id);
|
|
2845
2675
|
setThreads((prev) => prev.filter((t) => t.id !== id));
|
|
@@ -2847,9 +2677,9 @@ function ChatThreadsProvider({
|
|
|
2847
2677
|
},
|
|
2848
2678
|
[adapter, activeThreadId, setActiveThreadId]
|
|
2849
2679
|
);
|
|
2850
|
-
const threadsRef =
|
|
2680
|
+
const threadsRef = React8.useRef(threads);
|
|
2851
2681
|
threadsRef.current = threads;
|
|
2852
|
-
const updateThreadMessages =
|
|
2682
|
+
const updateThreadMessages = React8.useCallback(
|
|
2853
2683
|
(id, messages) => {
|
|
2854
2684
|
const existing = threadsRef.current.find((t) => t.id === id);
|
|
2855
2685
|
if (!existing) return;
|
|
@@ -2863,11 +2693,11 @@ function ChatThreadsProvider({
|
|
|
2863
2693
|
},
|
|
2864
2694
|
[adapter]
|
|
2865
2695
|
);
|
|
2866
|
-
const activeThread =
|
|
2696
|
+
const activeThread = React8.useMemo(
|
|
2867
2697
|
() => threads.find((t) => t.id === activeThreadId),
|
|
2868
2698
|
[threads, activeThreadId]
|
|
2869
2699
|
);
|
|
2870
|
-
const value =
|
|
2700
|
+
const value = React8.useMemo(
|
|
2871
2701
|
() => ({
|
|
2872
2702
|
threads,
|
|
2873
2703
|
activeThreadId,
|