@nextclaw/agent-chat-ui 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +9 -0
- package/dist/index.js +119 -63
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -128,6 +128,7 @@ type ChatInputBarProps = {
|
|
|
128
128
|
placeholder: string;
|
|
129
129
|
disabled: boolean;
|
|
130
130
|
onNodesChange: (nodes: ChatComposerNode[]) => void;
|
|
131
|
+
onFilesAdd?: (files: File[]) => Promise<void> | void;
|
|
131
132
|
onSlashQueryChange?: (query: string | null) => void;
|
|
132
133
|
};
|
|
133
134
|
slashMenu: Pick<ChatSlashMenuProps, 'isLoading' | 'items' | 'texts'>;
|
|
@@ -155,6 +156,14 @@ type ChatMessagePartViewModel = {
|
|
|
155
156
|
} | {
|
|
156
157
|
type: 'tool-card';
|
|
157
158
|
card: ChatToolPartViewModel;
|
|
159
|
+
} | {
|
|
160
|
+
type: 'file';
|
|
161
|
+
file: {
|
|
162
|
+
label: string;
|
|
163
|
+
mimeType: string;
|
|
164
|
+
dataUrl?: string;
|
|
165
|
+
isImage: boolean;
|
|
166
|
+
};
|
|
158
167
|
} | {
|
|
159
168
|
type: 'unknown';
|
|
160
169
|
label: string;
|
package/dist/index.js
CHANGED
|
@@ -1082,22 +1082,14 @@ var ChatComposerController = class {
|
|
|
1082
1082
|
this.selection = { start: nextOffset, end: nextOffset };
|
|
1083
1083
|
return this.getSnapshot();
|
|
1084
1084
|
};
|
|
1085
|
+
this.insertFileToken = (tokenKey, label) => {
|
|
1086
|
+
return this.insertToken("file", tokenKey, label);
|
|
1087
|
+
};
|
|
1085
1088
|
this.insertSkillToken = (tokenKey, label) => {
|
|
1086
1089
|
if (this.getSelectedSkillKeys().includes(tokenKey)) {
|
|
1087
1090
|
return this.getSnapshot();
|
|
1088
1091
|
}
|
|
1089
|
-
|
|
1090
|
-
const documentLength = this.getDocumentLength();
|
|
1091
|
-
const replaceStart = trigger?.start ?? this.selection?.start ?? documentLength;
|
|
1092
|
-
const replaceEnd = trigger?.end ?? this.selection?.end ?? replaceStart;
|
|
1093
|
-
this.nodes = replaceChatComposerRange(
|
|
1094
|
-
this.nodes,
|
|
1095
|
-
replaceStart,
|
|
1096
|
-
replaceEnd,
|
|
1097
|
-
[createChatComposerTokenNode({ tokenKind: "skill", tokenKey, label })]
|
|
1098
|
-
);
|
|
1099
|
-
this.selection = { start: replaceStart + 1, end: replaceStart + 1 };
|
|
1100
|
-
return this.getSnapshot();
|
|
1092
|
+
return this.insertToken("skill", tokenKey, label, this.getSlashTrigger());
|
|
1101
1093
|
};
|
|
1102
1094
|
this.syncSelectedSkills = (nextKeys, options) => {
|
|
1103
1095
|
const selectedSkillKeys = this.getSelectedSkillKeys();
|
|
@@ -1150,6 +1142,19 @@ var ChatComposerController = class {
|
|
|
1150
1142
|
this.getSelectedSkillKeys = () => {
|
|
1151
1143
|
return extractChatComposerTokenKeys(this.nodes, "skill");
|
|
1152
1144
|
};
|
|
1145
|
+
this.insertToken = (tokenKind, tokenKey, label, trigger = null) => {
|
|
1146
|
+
const documentLength = this.getDocumentLength();
|
|
1147
|
+
const replaceStart = trigger?.start ?? this.selection?.start ?? documentLength;
|
|
1148
|
+
const replaceEnd = trigger?.end ?? this.selection?.end ?? replaceStart;
|
|
1149
|
+
this.nodes = replaceChatComposerRange(
|
|
1150
|
+
this.nodes,
|
|
1151
|
+
replaceStart,
|
|
1152
|
+
replaceEnd,
|
|
1153
|
+
[createChatComposerTokenNode({ tokenKind, tokenKey, label })]
|
|
1154
|
+
);
|
|
1155
|
+
this.selection = { start: replaceStart + 1, end: replaceStart + 1 };
|
|
1156
|
+
return this.getSnapshot();
|
|
1157
|
+
};
|
|
1153
1158
|
this.getSlashTrigger = () => {
|
|
1154
1159
|
return resolveChatComposerSlashTrigger(this.nodes, this.selection);
|
|
1155
1160
|
};
|
|
@@ -1443,7 +1448,13 @@ var ChatComposerViewController = class {
|
|
|
1443
1448
|
}
|
|
1444
1449
|
};
|
|
1445
1450
|
this.handlePaste = (params) => {
|
|
1446
|
-
const { event, commitSnapshot } = params;
|
|
1451
|
+
const { event, onFilesAdd, commitSnapshot } = params;
|
|
1452
|
+
const files = Array.from(event.clipboardData.files ?? []);
|
|
1453
|
+
if (files.length > 0 && onFilesAdd) {
|
|
1454
|
+
event.preventDefault();
|
|
1455
|
+
void onFilesAdd(files);
|
|
1456
|
+
return;
|
|
1457
|
+
}
|
|
1447
1458
|
const text = event.clipboardData.getData("text/plain");
|
|
1448
1459
|
if (!text) {
|
|
1449
1460
|
return;
|
|
@@ -1497,6 +1508,9 @@ var ChatComposerRuntime = class {
|
|
|
1497
1508
|
insertSlashItem: (item) => {
|
|
1498
1509
|
this.viewController.insertSlashItem(item, this.commitSnapshot);
|
|
1499
1510
|
},
|
|
1511
|
+
insertFileToken: (tokenKey, label) => {
|
|
1512
|
+
this.commitSnapshot(this.controller.insertFileToken(tokenKey, label));
|
|
1513
|
+
},
|
|
1500
1514
|
syncSelectedSkills: (nextKeys, options) => {
|
|
1501
1515
|
this.viewController.syncSelectedSkills(nextKeys, options, this.commitSnapshot);
|
|
1502
1516
|
}
|
|
@@ -1558,6 +1572,12 @@ var ChatComposerRuntime = class {
|
|
|
1558
1572
|
};
|
|
1559
1573
|
this.handleKeyDown = (event) => {
|
|
1560
1574
|
const config = this.requireConfig();
|
|
1575
|
+
if (this.rootElement && !this.isComposing) {
|
|
1576
|
+
const nextSnapshot = this.viewController.syncSelectionFromRoot(this.rootElement);
|
|
1577
|
+
this.selection = nextSnapshot.selection;
|
|
1578
|
+
this.selectedRange = nextSnapshot.selection;
|
|
1579
|
+
this.snapshot = nextSnapshot;
|
|
1580
|
+
}
|
|
1561
1581
|
const activeSlashItem = config.slashItems[config.activeSlashIndex] ?? null;
|
|
1562
1582
|
this.viewController.handleKeyDown({
|
|
1563
1583
|
event,
|
|
@@ -1575,6 +1595,7 @@ var ChatComposerRuntime = class {
|
|
|
1575
1595
|
this.handlePaste = (event) => {
|
|
1576
1596
|
this.viewController.handlePaste({
|
|
1577
1597
|
event,
|
|
1598
|
+
onFilesAdd: this.requireConfig().onFilesAdd,
|
|
1578
1599
|
commitSnapshot: this.commitSnapshot
|
|
1579
1600
|
});
|
|
1580
1601
|
};
|
|
@@ -1605,6 +1626,7 @@ var ChatComposerRuntime = class {
|
|
|
1605
1626
|
};
|
|
1606
1627
|
this.syncSlashState = (nextSnapshot) => {
|
|
1607
1628
|
const config = this.requireConfig();
|
|
1629
|
+
config.onSlashTriggerChange?.(nextSnapshot.slashTrigger);
|
|
1608
1630
|
config.onSlashQueryChange?.(nextSnapshot.slashTrigger?.query ?? null);
|
|
1609
1631
|
config.onSlashOpenChange(nextSnapshot.slashTrigger !== null);
|
|
1610
1632
|
};
|
|
@@ -1630,7 +1652,9 @@ var ChatInputBarTokenizedComposer = forwardRef6(function ChatInputBarTokenizedCo
|
|
|
1630
1652
|
slashItems,
|
|
1631
1653
|
actions,
|
|
1632
1654
|
onNodesChange,
|
|
1655
|
+
onFilesAdd,
|
|
1633
1656
|
onSlashQueryChange,
|
|
1657
|
+
onSlashTriggerChange,
|
|
1634
1658
|
onSlashOpenChange,
|
|
1635
1659
|
onSlashActiveIndexChange,
|
|
1636
1660
|
activeSlashIndex
|
|
@@ -1655,7 +1679,9 @@ var ChatInputBarTokenizedComposer = forwardRef6(function ChatInputBarTokenizedCo
|
|
|
1655
1679
|
slashItems,
|
|
1656
1680
|
actions,
|
|
1657
1681
|
onNodesChange,
|
|
1682
|
+
onFilesAdd,
|
|
1658
1683
|
onSlashQueryChange,
|
|
1684
|
+
onSlashTriggerChange,
|
|
1659
1685
|
onSlashOpenChange,
|
|
1660
1686
|
onSlashActiveIndexChange,
|
|
1661
1687
|
activeSlashIndex,
|
|
@@ -1722,7 +1748,9 @@ function ChatInputBar(props) {
|
|
|
1722
1748
|
const composerRef = useRef4(null);
|
|
1723
1749
|
const [slashQuery, setSlashQuery] = useState4(null);
|
|
1724
1750
|
const [activeSlashIndex, setActiveSlashIndex] = useState4(0);
|
|
1725
|
-
const
|
|
1751
|
+
const [activeSlashTriggerStart, setActiveSlashTriggerStart] = useState4(null);
|
|
1752
|
+
const [dismissedSlashTriggerStart, setDismissedSlashTriggerStart] = useState4(null);
|
|
1753
|
+
const isSlashPanelOpen = activeSlashTriggerStart !== null && dismissedSlashTriggerStart !== activeSlashTriggerStart;
|
|
1726
1754
|
const activeSlashItem = props.slashMenu.items[activeSlashIndex] ?? null;
|
|
1727
1755
|
useEffect4(() => {
|
|
1728
1756
|
setActiveSlashIndex((current) => {
|
|
@@ -1737,6 +1765,11 @@ function ChatInputBar(props) {
|
|
|
1737
1765
|
setActiveSlashIndex(0);
|
|
1738
1766
|
}
|
|
1739
1767
|
}, [slashQuery]);
|
|
1768
|
+
useEffect4(() => {
|
|
1769
|
+
if (activeSlashTriggerStart === null && dismissedSlashTriggerStart !== null) {
|
|
1770
|
+
setDismissedSlashTriggerStart(null);
|
|
1771
|
+
}
|
|
1772
|
+
}, [activeSlashTriggerStart, dismissedSlashTriggerStart]);
|
|
1740
1773
|
const toolbar = useMemo3(() => {
|
|
1741
1774
|
if (!props.toolbar.skillPicker) {
|
|
1742
1775
|
return props.toolbar;
|
|
@@ -1764,13 +1797,17 @@ function ChatInputBar(props) {
|
|
|
1764
1797
|
actions: props.toolbar.actions,
|
|
1765
1798
|
activeSlashIndex,
|
|
1766
1799
|
onNodesChange: props.composer.onNodesChange,
|
|
1800
|
+
onFilesAdd: props.composer.onFilesAdd,
|
|
1767
1801
|
onSlashQueryChange: (query) => {
|
|
1768
1802
|
setSlashQuery(query);
|
|
1769
1803
|
props.composer.onSlashQueryChange?.(query);
|
|
1770
1804
|
},
|
|
1805
|
+
onSlashTriggerChange: (trigger) => {
|
|
1806
|
+
setActiveSlashTriggerStart(trigger?.start ?? null);
|
|
1807
|
+
},
|
|
1771
1808
|
onSlashOpenChange: (open) => {
|
|
1772
|
-
if (!open) {
|
|
1773
|
-
|
|
1809
|
+
if (!open && activeSlashTriggerStart !== null) {
|
|
1810
|
+
setDismissedSlashTriggerStart(activeSlashTriggerStart);
|
|
1774
1811
|
}
|
|
1775
1812
|
},
|
|
1776
1813
|
onSlashActiveIndexChange: setActiveSlashIndex
|
|
@@ -1786,11 +1823,12 @@ function ChatInputBar(props) {
|
|
|
1786
1823
|
activeItem: activeSlashItem,
|
|
1787
1824
|
texts: props.slashMenu.texts,
|
|
1788
1825
|
onSelectItem: (item) => {
|
|
1826
|
+
setDismissedSlashTriggerStart(null);
|
|
1789
1827
|
composerRef.current?.insertSlashItem(item);
|
|
1790
1828
|
},
|
|
1791
1829
|
onOpenChange: (open) => {
|
|
1792
|
-
if (!open) {
|
|
1793
|
-
|
|
1830
|
+
if (!open && activeSlashTriggerStart !== null) {
|
|
1831
|
+
setDismissedSlashTriggerStart(activeSlashTriggerStart);
|
|
1794
1832
|
}
|
|
1795
1833
|
},
|
|
1796
1834
|
onSetActiveIndex: setActiveSlashIndex
|
|
@@ -2077,12 +2115,27 @@ function ChatMessageMarkdown(props) {
|
|
|
2077
2115
|
return /* @__PURE__ */ jsx14("div", { className: cn("chat-markdown", isUser ? "chat-markdown-user" : "chat-markdown-assistant"), children: /* @__PURE__ */ jsx14(ReactMarkdown, { skipHtml: true, remarkPlugins: [remarkGfm], components: markdownComponents, children: trimMarkdown(props.text) }) });
|
|
2078
2116
|
}
|
|
2079
2117
|
|
|
2080
|
-
// src/components/chat/ui/chat-message-list/chat-
|
|
2118
|
+
// src/components/chat/ui/chat-message-list/chat-message-file.tsx
|
|
2081
2119
|
import { jsx as jsx15, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2120
|
+
function ChatMessageFile({ file }) {
|
|
2121
|
+
if (file.isImage && file.dataUrl) {
|
|
2122
|
+
return /* @__PURE__ */ jsxs8("figure", { className: "overflow-hidden rounded-2xl border border-black/8 bg-black/6", children: [
|
|
2123
|
+
/* @__PURE__ */ jsx15("img", { src: file.dataUrl, alt: file.label, className: "block max-h-80 w-full object-contain" }),
|
|
2124
|
+
/* @__PURE__ */ jsx15("figcaption", { className: "border-t border-black/8 px-3 py-2 text-xs opacity-80", children: file.label })
|
|
2125
|
+
] });
|
|
2126
|
+
}
|
|
2127
|
+
return /* @__PURE__ */ jsxs8("div", { className: "rounded-2xl border border-black/8 bg-black/6 px-3 py-2 text-sm", children: [
|
|
2128
|
+
/* @__PURE__ */ jsx15("div", { className: "font-medium", children: file.label }),
|
|
2129
|
+
/* @__PURE__ */ jsx15("div", { className: "text-xs opacity-75", children: file.mimeType })
|
|
2130
|
+
] });
|
|
2131
|
+
}
|
|
2132
|
+
|
|
2133
|
+
// src/components/chat/ui/chat-message-list/chat-reasoning-block.tsx
|
|
2134
|
+
import { jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2082
2135
|
function ChatReasoningBlock(props) {
|
|
2083
|
-
return /* @__PURE__ */
|
|
2084
|
-
/* @__PURE__ */
|
|
2085
|
-
/* @__PURE__ */
|
|
2136
|
+
return /* @__PURE__ */ jsxs9("details", { className: "mt-3", open: true, children: [
|
|
2137
|
+
/* @__PURE__ */ jsx16("summary", { className: cn("cursor-pointer text-xs", props.isUser ? "text-primary-100" : "text-gray-500"), children: props.label }),
|
|
2138
|
+
/* @__PURE__ */ jsx16(
|
|
2086
2139
|
"pre",
|
|
2087
2140
|
{
|
|
2088
2141
|
className: cn(
|
|
@@ -2097,87 +2150,90 @@ function ChatReasoningBlock(props) {
|
|
|
2097
2150
|
|
|
2098
2151
|
// src/components/chat/ui/chat-message-list/chat-tool-card.tsx
|
|
2099
2152
|
import { Clock3, FileSearch, Globe, Search as Search2, SendHorizontal, Terminal, Wrench as Wrench2 } from "lucide-react";
|
|
2100
|
-
import { jsx as
|
|
2153
|
+
import { jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2101
2154
|
var TOOL_OUTPUT_PREVIEW_MAX = 220;
|
|
2102
2155
|
function renderToolIcon(toolName) {
|
|
2103
2156
|
const lowered = toolName.toLowerCase();
|
|
2104
2157
|
if (lowered.includes("exec") || lowered.includes("shell") || lowered.includes("command")) {
|
|
2105
|
-
return /* @__PURE__ */
|
|
2158
|
+
return /* @__PURE__ */ jsx17(Terminal, { className: "h-3.5 w-3.5" });
|
|
2106
2159
|
}
|
|
2107
2160
|
if (lowered.includes("search")) {
|
|
2108
|
-
return /* @__PURE__ */
|
|
2161
|
+
return /* @__PURE__ */ jsx17(Search2, { className: "h-3.5 w-3.5" });
|
|
2109
2162
|
}
|
|
2110
2163
|
if (lowered.includes("fetch") || lowered.includes("http") || lowered.includes("web")) {
|
|
2111
|
-
return /* @__PURE__ */
|
|
2164
|
+
return /* @__PURE__ */ jsx17(Globe, { className: "h-3.5 w-3.5" });
|
|
2112
2165
|
}
|
|
2113
2166
|
if (lowered.includes("read") || lowered.includes("file")) {
|
|
2114
|
-
return /* @__PURE__ */
|
|
2167
|
+
return /* @__PURE__ */ jsx17(FileSearch, { className: "h-3.5 w-3.5" });
|
|
2115
2168
|
}
|
|
2116
2169
|
if (lowered.includes("message") || lowered.includes("send")) {
|
|
2117
|
-
return /* @__PURE__ */
|
|
2170
|
+
return /* @__PURE__ */ jsx17(SendHorizontal, { className: "h-3.5 w-3.5" });
|
|
2118
2171
|
}
|
|
2119
2172
|
if (lowered.includes("cron") || lowered.includes("schedule")) {
|
|
2120
|
-
return /* @__PURE__ */
|
|
2173
|
+
return /* @__PURE__ */ jsx17(Clock3, { className: "h-3.5 w-3.5" });
|
|
2121
2174
|
}
|
|
2122
|
-
return /* @__PURE__ */
|
|
2175
|
+
return /* @__PURE__ */ jsx17(Wrench2, { className: "h-3.5 w-3.5" });
|
|
2123
2176
|
}
|
|
2124
2177
|
function ChatToolCard({ card }) {
|
|
2125
2178
|
const output = card.output?.trim() ?? "";
|
|
2126
2179
|
const showDetails = output.length > TOOL_OUTPUT_PREVIEW_MAX || output.includes("\n");
|
|
2127
2180
|
const preview = showDetails ? `${output.slice(0, TOOL_OUTPUT_PREVIEW_MAX)}...` : output;
|
|
2128
2181
|
const showOutputSection = card.kind === "result" || card.hasResult;
|
|
2129
|
-
return /* @__PURE__ */
|
|
2130
|
-
/* @__PURE__ */
|
|
2182
|
+
return /* @__PURE__ */ jsxs10("div", { className: "rounded-xl border border-amber-200/80 bg-amber-50/60 px-3 py-2.5", children: [
|
|
2183
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex flex-wrap items-center gap-2 text-xs font-semibold text-amber-800", children: [
|
|
2131
2184
|
renderToolIcon(card.toolName),
|
|
2132
|
-
/* @__PURE__ */
|
|
2133
|
-
/* @__PURE__ */
|
|
2185
|
+
/* @__PURE__ */ jsx17("span", { children: card.titleLabel }),
|
|
2186
|
+
/* @__PURE__ */ jsx17("span", { className: "font-mono text-[11px] text-amber-900/80", children: card.toolName })
|
|
2134
2187
|
] }),
|
|
2135
|
-
card.summary ? /* @__PURE__ */
|
|
2136
|
-
showOutputSection ? /* @__PURE__ */
|
|
2137
|
-
/* @__PURE__ */
|
|
2138
|
-
/* @__PURE__ */
|
|
2139
|
-
] }) : /* @__PURE__ */
|
|
2188
|
+
card.summary ? /* @__PURE__ */ jsx17("div", { className: "mt-1 break-words font-mono text-[11px] text-amber-800/90", children: card.summary }) : null,
|
|
2189
|
+
showOutputSection ? /* @__PURE__ */ jsx17("div", { className: "mt-2", children: !output ? /* @__PURE__ */ jsx17("div", { className: "text-[11px] text-amber-700/80", children: card.emptyLabel }) : showDetails ? /* @__PURE__ */ jsxs10("details", { className: "group", children: [
|
|
2190
|
+
/* @__PURE__ */ jsx17("summary", { className: "cursor-pointer text-[11px] text-amber-700", children: card.outputLabel }),
|
|
2191
|
+
/* @__PURE__ */ jsx17("pre", { className: "mt-2 whitespace-pre-wrap break-words rounded-lg border border-amber-200 bg-amber-100/40 p-2 text-[11px] text-amber-900", children: output })
|
|
2192
|
+
] }) : /* @__PURE__ */ jsx17("pre", { className: "rounded-lg border border-amber-200 bg-amber-100/40 p-2 text-[11px] whitespace-pre-wrap break-words text-amber-900", children: preview }) }) : null
|
|
2140
2193
|
] });
|
|
2141
2194
|
}
|
|
2142
2195
|
|
|
2143
2196
|
// src/components/chat/ui/chat-message-list/chat-unknown-part.tsx
|
|
2144
|
-
import { jsx as
|
|
2197
|
+
import { jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2145
2198
|
function ChatUnknownPart(props) {
|
|
2146
|
-
return /* @__PURE__ */
|
|
2147
|
-
/* @__PURE__ */
|
|
2199
|
+
return /* @__PURE__ */ jsxs11("div", { className: "rounded-lg border border-gray-200 bg-gray-50 px-2.5 py-2 text-xs text-gray-600", children: [
|
|
2200
|
+
/* @__PURE__ */ jsxs11("div", { className: "font-semibold text-gray-700", children: [
|
|
2148
2201
|
props.label,
|
|
2149
2202
|
": ",
|
|
2150
2203
|
props.rawType
|
|
2151
2204
|
] }),
|
|
2152
|
-
props.text ? /* @__PURE__ */
|
|
2205
|
+
props.text ? /* @__PURE__ */ jsx18("pre", { className: "mt-1 whitespace-pre-wrap break-words text-[11px] text-gray-500", children: props.text }) : null
|
|
2153
2206
|
] });
|
|
2154
2207
|
}
|
|
2155
2208
|
|
|
2156
2209
|
// src/components/chat/ui/chat-message-list/chat-message.tsx
|
|
2157
|
-
import { jsx as
|
|
2210
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
2158
2211
|
function ChatMessage(props) {
|
|
2159
2212
|
const { message, texts } = props;
|
|
2160
2213
|
const { role } = message;
|
|
2161
2214
|
const isUser = role === "user";
|
|
2162
|
-
return /* @__PURE__ */
|
|
2215
|
+
return /* @__PURE__ */ jsx19(
|
|
2163
2216
|
"div",
|
|
2164
2217
|
{
|
|
2165
2218
|
className: cn(
|
|
2166
2219
|
"inline-block w-fit max-w-full rounded-2xl border px-4 py-3 shadow-sm",
|
|
2167
2220
|
isUser ? "border-primary bg-primary text-white" : role === "assistant" ? "border-gray-200 bg-white text-gray-900" : "border-orange-200/80 bg-orange-50/70 text-gray-900"
|
|
2168
2221
|
),
|
|
2169
|
-
children: /* @__PURE__ */
|
|
2222
|
+
children: /* @__PURE__ */ jsx19("div", { className: "space-y-2", children: message.parts.map((part, index) => {
|
|
2170
2223
|
if (part.type === "markdown") {
|
|
2171
|
-
return /* @__PURE__ */
|
|
2224
|
+
return /* @__PURE__ */ jsx19(ChatMessageMarkdown, { text: part.text, role, texts }, `markdown-${index}`);
|
|
2172
2225
|
}
|
|
2173
2226
|
if (part.type === "reasoning") {
|
|
2174
|
-
return /* @__PURE__ */
|
|
2227
|
+
return /* @__PURE__ */ jsx19(ChatReasoningBlock, { label: part.label, text: part.text, isUser }, `reasoning-${index}`);
|
|
2175
2228
|
}
|
|
2176
2229
|
if (part.type === "tool-card") {
|
|
2177
|
-
return /* @__PURE__ */
|
|
2230
|
+
return /* @__PURE__ */ jsx19("div", { className: "mt-0.5", children: /* @__PURE__ */ jsx19(ChatToolCard, { card: part.card }) }, `tool-${index}`);
|
|
2231
|
+
}
|
|
2232
|
+
if (part.type === "file") {
|
|
2233
|
+
return /* @__PURE__ */ jsx19(ChatMessageFile, { file: part.file }, `file-${index}`);
|
|
2178
2234
|
}
|
|
2179
2235
|
if (part.type === "unknown") {
|
|
2180
|
-
return /* @__PURE__ */
|
|
2236
|
+
return /* @__PURE__ */ jsx19(ChatUnknownPart, { label: part.label, rawType: part.rawType, text: part.text }, `unknown-${index}`);
|
|
2181
2237
|
}
|
|
2182
2238
|
return null;
|
|
2183
2239
|
}) })
|
|
@@ -2186,9 +2242,9 @@ function ChatMessage(props) {
|
|
|
2186
2242
|
}
|
|
2187
2243
|
|
|
2188
2244
|
// src/components/chat/ui/chat-message-list/chat-message-meta.tsx
|
|
2189
|
-
import { jsxs as
|
|
2245
|
+
import { jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2190
2246
|
function ChatMessageMeta(props) {
|
|
2191
|
-
return /* @__PURE__ */
|
|
2247
|
+
return /* @__PURE__ */ jsxs12(
|
|
2192
2248
|
"div",
|
|
2193
2249
|
{
|
|
2194
2250
|
className: cn(
|
|
@@ -2205,7 +2261,7 @@ function ChatMessageMeta(props) {
|
|
|
2205
2261
|
}
|
|
2206
2262
|
|
|
2207
2263
|
// src/components/chat/ui/chat-message-list/chat-message-list.tsx
|
|
2208
|
-
import { jsx as
|
|
2264
|
+
import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2209
2265
|
var INVISIBLE_ONLY_TEXT_PATTERN = /\u200B|\u200C|\u200D|\u2060|\uFEFF/g;
|
|
2210
2266
|
function hasRenderableText(value) {
|
|
2211
2267
|
const trimmed = value.trim();
|
|
@@ -2227,21 +2283,21 @@ function ChatMessageList(props) {
|
|
|
2227
2283
|
const hasRenderableAssistantDraft = visibleMessages.some(
|
|
2228
2284
|
(message) => message.role === "assistant" && (message.status === "streaming" || message.status === "pending")
|
|
2229
2285
|
);
|
|
2230
|
-
return /* @__PURE__ */
|
|
2286
|
+
return /* @__PURE__ */ jsxs13("div", { className: cn("space-y-5", props.className), children: [
|
|
2231
2287
|
visibleMessages.map((message) => {
|
|
2232
2288
|
const isUser = message.role === "user";
|
|
2233
|
-
return /* @__PURE__ */
|
|
2234
|
-
!isUser ? /* @__PURE__ */
|
|
2235
|
-
/* @__PURE__ */
|
|
2236
|
-
/* @__PURE__ */
|
|
2237
|
-
/* @__PURE__ */
|
|
2289
|
+
return /* @__PURE__ */ jsxs13("div", { className: cn("flex gap-3", isUser ? "justify-end" : "justify-start"), children: [
|
|
2290
|
+
!isUser ? /* @__PURE__ */ jsx20(ChatMessageAvatar, { role: message.role }) : null,
|
|
2291
|
+
/* @__PURE__ */ jsxs13("div", { className: cn("w-fit max-w-[92%] space-y-2", isUser && "flex flex-col items-end"), children: [
|
|
2292
|
+
/* @__PURE__ */ jsx20(ChatMessage, { message, texts: props.texts }),
|
|
2293
|
+
/* @__PURE__ */ jsx20(ChatMessageMeta, { roleLabel: message.roleLabel, timestampLabel: message.timestampLabel, isUser })
|
|
2238
2294
|
] }),
|
|
2239
|
-
isUser ? /* @__PURE__ */
|
|
2295
|
+
isUser ? /* @__PURE__ */ jsx20(ChatMessageAvatar, { role: message.role }) : null
|
|
2240
2296
|
] }, message.id);
|
|
2241
2297
|
}),
|
|
2242
|
-
props.isSending && !hasRenderableAssistantDraft ? /* @__PURE__ */
|
|
2243
|
-
/* @__PURE__ */
|
|
2244
|
-
/* @__PURE__ */
|
|
2298
|
+
props.isSending && !hasRenderableAssistantDraft ? /* @__PURE__ */ jsxs13("div", { className: "flex justify-start gap-3", children: [
|
|
2299
|
+
/* @__PURE__ */ jsx20(ChatMessageAvatar, { role: "assistant" }),
|
|
2300
|
+
/* @__PURE__ */ jsx20("div", { className: "rounded-2xl border border-gray-200 bg-white px-4 py-3 text-sm text-gray-500 shadow-sm", children: props.texts.typingLabel })
|
|
2245
2301
|
] }) : null
|
|
2246
2302
|
] });
|
|
2247
2303
|
}
|