llm-message-react 0.1.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/index.js ADDED
@@ -0,0 +1,703 @@
1
+ export { createShikiHighlighter } from './chunk-S3LNINQ5.js';
2
+ import { clsx } from 'clsx';
3
+ import { useMemo, useState, useRef, useEffect } from 'react';
4
+ import ReactMarkdown from 'react-markdown';
5
+ import rehypeKatex from 'rehype-katex';
6
+ import remarkGfm from 'remark-gfm';
7
+ import remarkMath from 'remark-math';
8
+ import katex from 'katex';
9
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
10
+
11
+ function completePartialTokens(text, options) {
12
+ if (!text) return text;
13
+ const showUnfinishedLatexBlocks = options?.showUnfinishedLatexBlocks ?? true;
14
+ if (hasUnclosedCodeFence(text)) {
15
+ return text;
16
+ }
17
+ const protectedSpans = [];
18
+ const protect = (value) => `\0llmph${protectedSpans.push(value) - 1}\0`;
19
+ let working = text.replace(/```[\s\S]*?```/g, (match) => protect(match));
20
+ working = working.replace(/``[\s\S]*?``/g, (match) => protect(match));
21
+ working = working.replace(/`[^`\n]+`/g, (match) => protect(match));
22
+ const lastBacktick = working.lastIndexOf("`");
23
+ if (lastBacktick !== -1) {
24
+ const newline = working.indexOf("\n", lastBacktick);
25
+ const end = newline === -1 ? working.length : newline;
26
+ const span = working.slice(lastBacktick, end);
27
+ working = working.slice(0, lastBacktick) + protect(`${span}\``) + working.slice(end);
28
+ }
29
+ working = repairIncompleteMath(working, showUnfinishedLatexBlocks);
30
+ working = hideIncompleteLink(working);
31
+ working = completePartialTable(working);
32
+ working = hideDanglingListMarker(working);
33
+ working = closeUnbalancedEmphasis(working);
34
+ return working.replace(
35
+ /\u0000llmph(\d+)\u0000/g,
36
+ (_match, index) => protectedSpans[Number(index)] ?? ""
37
+ );
38
+ }
39
+ function completePartialTable(text) {
40
+ const lines = text.split("\n");
41
+ if (lines.length < 2) return text;
42
+ const last = lines[lines.length - 1];
43
+ if (!/-/.test(last) || !/^[\s|:-]*$/.test(last)) return text;
44
+ const header = lines[lines.length - 2];
45
+ if (!header.includes("|")) return text;
46
+ for (let i = lines.length - 2; i >= 0; i--) {
47
+ const line = lines[i];
48
+ if (!line.includes("|")) break;
49
+ if (/-/.test(line) && /^[\s|:-]*$/.test(line)) return text;
50
+ }
51
+ const columns = countTableColumns(header);
52
+ lines[lines.length - 1] = buildDelimiterRow(last, columns);
53
+ return lines.join("\n");
54
+ }
55
+ function countTableColumns(row) {
56
+ let inner = row.trim();
57
+ if (inner.startsWith("|")) inner = inner.slice(1);
58
+ if (inner.endsWith("|")) inner = inner.slice(0, -1);
59
+ return inner.split("|").length;
60
+ }
61
+ function buildDelimiterRow(fragment, columns) {
62
+ let inner = fragment.trim();
63
+ if (inner.startsWith("|")) inner = inner.slice(1);
64
+ if (inner.endsWith("|")) inner = inner.slice(0, -1);
65
+ const existing = inner.split("|").map((cell) => cell.trim());
66
+ const cells = Array.from({ length: columns }, (_unused, index) => {
67
+ const spec = existing[index] ?? "";
68
+ const left = spec.startsWith(":");
69
+ const right = spec.endsWith(":");
70
+ if (left && right) return ":---:";
71
+ if (right) return "---:";
72
+ if (left) return ":---";
73
+ return "---";
74
+ });
75
+ return `| ${cells.join(" | ")} |`;
76
+ }
77
+ function hideDanglingListMarker(text) {
78
+ const match = text.match(/\n[ \t]{0,3}-+[ \t]*$/);
79
+ if (match?.index == null) return text;
80
+ const before = text.slice(0, match.index);
81
+ const prevLine = before.slice(before.lastIndexOf("\n") + 1);
82
+ if (prevLine.trim() === "") return text;
83
+ return before;
84
+ }
85
+ function hasUnclosedCodeFence(text) {
86
+ const backticks = (text.match(/^[ \t]{0,3}```/gm) ?? []).length;
87
+ const tildes = (text.match(/^[ \t]{0,3}~~~/gm) ?? []).length;
88
+ return backticks % 2 === 1 || tildes % 2 === 1;
89
+ }
90
+ function hideIncompleteLink(text) {
91
+ let open = -1;
92
+ for (let i = text.length - 1; i >= 0; i--) {
93
+ if (text[i] === "[" && text[i - 1] !== "\\") {
94
+ open = i;
95
+ break;
96
+ }
97
+ }
98
+ if (open === -1) return text;
99
+ const start = open > 0 && text[open - 1] === "!" ? open - 1 : open;
100
+ const rest = text.slice(open);
101
+ if (!rest.includes("]")) {
102
+ return text.slice(0, start);
103
+ }
104
+ if (/^\[[^\]]*\]\([^)]*$/.test(rest)) {
105
+ return text.slice(0, start);
106
+ }
107
+ return text;
108
+ }
109
+ function repairIncompleteMath(text, showUnfinishedLatexBlocks) {
110
+ const countOf = (pattern) => (text.match(pattern) ?? []).length;
111
+ const opens = [];
112
+ if (countOf(/\\\[/g) > countOf(/\\\]/g)) {
113
+ opens.push({
114
+ index: text.lastIndexOf("\\["),
115
+ open: "\\[",
116
+ close: "\\]",
117
+ block: true,
118
+ display: true
119
+ });
120
+ }
121
+ if (countOf(/\\\(/g) > countOf(/\\\)/g)) {
122
+ opens.push({
123
+ index: text.lastIndexOf("\\("),
124
+ open: "\\(",
125
+ close: "",
126
+ block: false,
127
+ display: false
128
+ });
129
+ }
130
+ if (countOf(/\$\$/g) % 2 === 1) {
131
+ opens.push({
132
+ index: text.lastIndexOf("$$"),
133
+ open: "$$",
134
+ close: "$$",
135
+ block: true,
136
+ display: true
137
+ });
138
+ } else {
139
+ const masked = text.replace(/\$\$/g, " ");
140
+ let lastDollar = -1;
141
+ for (const match of masked.matchAll(/(?<!\\)\$(?!\d)/g)) {
142
+ lastDollar = match.index;
143
+ }
144
+ const singles = masked.match(/(?<!\\)\$(?!\d)/g) ?? [];
145
+ if (singles.length % 2 === 1 && lastDollar !== -1) {
146
+ opens.push({
147
+ index: lastDollar,
148
+ open: "$",
149
+ close: "",
150
+ block: false,
151
+ display: false
152
+ });
153
+ }
154
+ }
155
+ const valid = opens.filter((entry) => entry.index >= 0);
156
+ if (valid.length === 0) return text;
157
+ const open = valid.reduce((a, b) => b.index < a.index ? b : a);
158
+ const before = text.slice(0, open.index);
159
+ if (!open.block) {
160
+ return before;
161
+ }
162
+ if (!showUnfinishedLatexBlocks) {
163
+ return before;
164
+ }
165
+ const inner = text.slice(open.index + open.open.length);
166
+ const body = bestRenderableMathBody(inner, open.display);
167
+ if (body == null) return before;
168
+ const blockLayout = /^[ \t]*\r?\n/.test(inner);
169
+ if (!blockLayout) {
170
+ return before + open.open + body + open.close;
171
+ }
172
+ const opener = before === "" || before.endsWith("\n") ? open.open : `
173
+ ${open.open}`;
174
+ return `${before}${opener}${body.replace(/\s+$/, "")}
175
+ ${open.close}`;
176
+ }
177
+ function bestRenderableMathBody(inner, display) {
178
+ const candidates = unclosedEnvironments(inner).length > 0 ? [closeOpenMathConstructs(truncateToLastRow(inner)), closeOpenMathConstructs(trimIncompleteMathTail(inner))] : [closeOpenMathConstructs(trimIncompleteMathTail(inner))];
179
+ for (const candidate of candidates) {
180
+ if (!hasRenderableMathContent(candidate)) continue;
181
+ if (isRenderableMath(candidate, display)) return candidate;
182
+ }
183
+ return null;
184
+ }
185
+ function hasRenderableMathContent(body) {
186
+ const stripped = body.replace(/\\(?:begin|end)\s*\{[^}]*\}/g, "").replace(/[\s{}]/g, "");
187
+ return stripped.length > 0;
188
+ }
189
+ function isRenderableMath(body, display) {
190
+ try {
191
+ katex.renderToString(body, {
192
+ displayMode: display,
193
+ throwOnError: true,
194
+ strict: false
195
+ });
196
+ return true;
197
+ } catch {
198
+ return false;
199
+ }
200
+ }
201
+ function truncateToLastRow(inner) {
202
+ const lastRow = inner.lastIndexOf("\\\\");
203
+ if (lastRow === -1) return "";
204
+ return inner.slice(0, lastRow + 2);
205
+ }
206
+ function trimIncompleteMathTail(inner) {
207
+ let result = inner;
208
+ let previous;
209
+ do {
210
+ previous = result;
211
+ result = result.replace(/\s+$/, "");
212
+ const backslashes = result.match(/\\+$/);
213
+ if (backslashes != null && backslashes[0].length % 2 === 1) {
214
+ result = result.slice(0, -1);
215
+ }
216
+ result = result.replace(/\\[a-zA-Z]+\*?$/, "");
217
+ result = result.replace(/[_^]$/, "");
218
+ } while (result !== previous);
219
+ return result;
220
+ }
221
+ function closeOpenMathConstructs(inner) {
222
+ let result = inner;
223
+ const lefts = (result.match(/\\left(?![a-zA-Z])/g) ?? []).length;
224
+ const rights = (result.match(/\\right(?![a-zA-Z])/g) ?? []).length;
225
+ result += "\\right.".repeat(Math.max(0, lefts - rights));
226
+ result += "}".repeat(openBraceDepth(result));
227
+ const environments = unclosedEnvironments(result);
228
+ for (let i = environments.length - 1; i >= 0; i--) {
229
+ result += `\\end{${environments[i]}}`;
230
+ }
231
+ return result;
232
+ }
233
+ function openBraceDepth(text) {
234
+ let depth = 0;
235
+ for (let i = 0; i < text.length; i++) {
236
+ const char = text[i];
237
+ if (char === "\\") {
238
+ i++;
239
+ continue;
240
+ }
241
+ if (char === "{") depth++;
242
+ else if (char === "}" && depth > 0) depth--;
243
+ }
244
+ return depth;
245
+ }
246
+ function unclosedEnvironments(text) {
247
+ const stack = [];
248
+ const pattern = /\\(begin|end)\s*\{([^}]*)\}/g;
249
+ let match;
250
+ while ((match = pattern.exec(text)) != null) {
251
+ const name = match[2];
252
+ if (match[1] === "begin") {
253
+ stack.push(name);
254
+ } else {
255
+ const index = stack.lastIndexOf(name);
256
+ if (index !== -1) stack.splice(index, 1);
257
+ else stack.pop();
258
+ }
259
+ }
260
+ return stack;
261
+ }
262
+ function closeUnbalancedEmphasis(text) {
263
+ let result = text;
264
+ result = closeRunMarker(result, "~~");
265
+ result = closeSingleAsterisk(result);
266
+ result = closeRunMarker(result, "**");
267
+ result = closeSingleUnderscore(result);
268
+ result = closeDoubleUnderscore(result);
269
+ return result;
270
+ }
271
+ function opensAtWordBoundary(text, index) {
272
+ if (index <= 0) return true;
273
+ return !/[\p{L}\p{N}_]/u.test(text[index - 1]);
274
+ }
275
+ function closeSingleUnderscore(text) {
276
+ const masked = text.replace(/__/g, "");
277
+ const count = (masked.match(/_/g) ?? []).length;
278
+ if (count % 2 === 0) return text;
279
+ const lastIndex = text.lastIndexOf("_");
280
+ const after = text.slice(lastIndex + 1);
281
+ if (after.length === 0 || /^[\s_]/.test(after)) return text;
282
+ if (!opensAtWordBoundary(text, lastIndex)) return text;
283
+ return insertBeforeTrailingWhitespace(text, "_");
284
+ }
285
+ function closeDoubleUnderscore(text) {
286
+ const count = (text.match(/__/g) ?? []).length;
287
+ if (count % 2 === 0) return text;
288
+ const lastIndex = text.lastIndexOf("__");
289
+ const after = text.slice(lastIndex + 2);
290
+ if (after.length === 0 || /^\s/.test(after)) return text;
291
+ if (!opensAtWordBoundary(text, lastIndex)) return text;
292
+ return insertBeforeTrailingWhitespace(text, "__");
293
+ }
294
+ function closeRunMarker(text, marker) {
295
+ const escaped = marker.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
296
+ const count = (text.match(new RegExp(escaped, "g")) ?? []).length;
297
+ if (count % 2 === 0) return text;
298
+ const lastIndex = text.lastIndexOf(marker);
299
+ const after = text.slice(lastIndex + marker.length);
300
+ if (after.length === 0 || /^\s/.test(after)) return text;
301
+ return insertBeforeTrailingWhitespace(text, marker);
302
+ }
303
+ function closeSingleAsterisk(text) {
304
+ const masked = text.replace(/\*\*/g, "");
305
+ const count = (masked.match(/\*/g) ?? []).length;
306
+ if (count % 2 === 0) return text;
307
+ const lastIndex = text.lastIndexOf("*");
308
+ const after = text.slice(lastIndex + 1);
309
+ if (after.length === 0 || /^[\s*]/.test(after)) return text;
310
+ return insertBeforeTrailingWhitespace(text, "*");
311
+ }
312
+ function insertBeforeTrailingWhitespace(text, marker) {
313
+ const trailing = text.match(/\s+$/)?.[0] ?? "";
314
+ const core = text.slice(0, text.length - trailing.length);
315
+ return core + marker + trailing;
316
+ }
317
+ function CopyIcon() {
318
+ return /* @__PURE__ */ jsxs(
319
+ "svg",
320
+ {
321
+ viewBox: "0 0 24 24",
322
+ width: "1em",
323
+ height: "1em",
324
+ fill: "none",
325
+ stroke: "currentColor",
326
+ strokeWidth: "2",
327
+ strokeLinecap: "round",
328
+ strokeLinejoin: "round",
329
+ "aria-hidden": "true",
330
+ children: [
331
+ /* @__PURE__ */ jsx("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2", ry: "2" }),
332
+ /* @__PURE__ */ jsx("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
333
+ ]
334
+ }
335
+ );
336
+ }
337
+ function CheckIcon() {
338
+ return /* @__PURE__ */ jsx(
339
+ "svg",
340
+ {
341
+ viewBox: "0 0 24 24",
342
+ width: "1em",
343
+ height: "1em",
344
+ fill: "none",
345
+ stroke: "currentColor",
346
+ strokeWidth: "2",
347
+ strokeLinecap: "round",
348
+ strokeLinejoin: "round",
349
+ "aria-hidden": "true",
350
+ children: /* @__PURE__ */ jsx("path", { d: "M20 6 9 17l-5-5" })
351
+ }
352
+ );
353
+ }
354
+ function CopyButton({ text, className }) {
355
+ const [copied, setCopied] = useState(false);
356
+ const timeoutRef = useRef(null);
357
+ useEffect(() => {
358
+ return () => {
359
+ if (timeoutRef.current != null) clearTimeout(timeoutRef.current);
360
+ };
361
+ }, []);
362
+ const copy = () => {
363
+ const clipboard = navigator.clipboard;
364
+ if (!clipboard) return;
365
+ void clipboard.writeText(text).then(() => {
366
+ setCopied(true);
367
+ if (timeoutRef.current != null) clearTimeout(timeoutRef.current);
368
+ timeoutRef.current = setTimeout(() => setCopied(false), 2e3);
369
+ }).catch(() => {
370
+ });
371
+ };
372
+ return /* @__PURE__ */ jsx(
373
+ "button",
374
+ {
375
+ type: "button",
376
+ onClick: copy,
377
+ className,
378
+ "aria-label": copied ? "Copied" : "Copy code",
379
+ "data-copied": copied ? "" : void 0,
380
+ children: copied ? /* @__PURE__ */ jsx(CheckIcon, {}) : /* @__PURE__ */ jsx(CopyIcon, {})
381
+ }
382
+ );
383
+ }
384
+
385
+ // src/preprocess.ts
386
+ var CODE_SPAN = /```[\s\S]*?```|`[^`\n]+`/;
387
+ function preprocessLaTeX(content) {
388
+ const codeBlocks = [];
389
+ content = content.replace(
390
+ new RegExp(`(${CODE_SPAN.source})`, "g"),
391
+ (_match, code) => {
392
+ codeBlocks.push(code);
393
+ return `<<CODE_BLOCK_${codeBlocks.length - 1}>>`;
394
+ }
395
+ );
396
+ const latexExpressions = [];
397
+ content = content.replace(
398
+ /(\$\$[\s\S]*?\$\$|\\\[[\s\S]*?\\\]|\\\(.*?\\\))/g,
399
+ (match) => {
400
+ latexExpressions.push(match);
401
+ return `<<LATEX_${latexExpressions.length - 1}>>`;
402
+ }
403
+ );
404
+ content = content.replace(/\$(?=\d)/g, "\\$");
405
+ content = content.replace(
406
+ /<<LATEX_(\d+)>>/g,
407
+ (_, index) => latexExpressions[parseInt(index, 10)]
408
+ );
409
+ content = content.replace(
410
+ /<<CODE_BLOCK_(\d+)>>/g,
411
+ (_, index) => codeBlocks[parseInt(index, 10)]
412
+ );
413
+ content = escapeBrackets(content);
414
+ content = escapeMhchem(content);
415
+ return content;
416
+ }
417
+ function escapeBrackets(text) {
418
+ const pattern = new RegExp(
419
+ `(${CODE_SPAN.source})|` + /\\\[((?:[\s\S]*?[^\\])?)\\]|\\\((.*?)\\\)/.source,
420
+ "g"
421
+ );
422
+ return text.replace(
423
+ pattern,
424
+ (match, codeBlock, squareBracket, roundBracket) => {
425
+ if (codeBlock != null) {
426
+ return codeBlock;
427
+ } else if (squareBracket != null) {
428
+ return `$$${squareBracket}$$`;
429
+ } else if (roundBracket != null) {
430
+ return `$${roundBracket}$`;
431
+ }
432
+ return match;
433
+ }
434
+ );
435
+ }
436
+ function escapeMhchem(text) {
437
+ return text.replaceAll("$\\ce{", "$\\\\ce{").replaceAll("$\\pu{", "$\\\\pu{");
438
+ }
439
+ var remarkPlugins = [remarkGfm, remarkMath];
440
+ var rehypePlugins = [rehypeKatex];
441
+ function cx(...inputs) {
442
+ const result = clsx(inputs);
443
+ return result === "" ? void 0 : result;
444
+ }
445
+ function buildComponents(classNames, overrides, highlighter) {
446
+ const cn = classNames ?? {};
447
+ const o = overrides ?? {};
448
+ const Highlighter = highlighter;
449
+ return {
450
+ code({ node: _node, className, children, ...props }) {
451
+ const match = /language-(\w+)/.exec(className || "");
452
+ const codeText = String(children).replace(/\n$/, "");
453
+ const isBlock = match != null || String(children).includes("\n");
454
+ if (isBlock) {
455
+ const language = match?.[1] ?? "";
456
+ if (o.codeBlock) {
457
+ const CodeBlock = o.codeBlock;
458
+ return /* @__PURE__ */ jsx(
459
+ CodeBlock,
460
+ {
461
+ code: codeText,
462
+ language,
463
+ className: cn.codeBlock
464
+ }
465
+ );
466
+ }
467
+ return /* @__PURE__ */ jsxs("div", { className: cx("llm-code-block", cn.codeBlock), children: [
468
+ /* @__PURE__ */ jsxs("div", { className: cx("llm-code-header", cn.codeHeader), children: [
469
+ /* @__PURE__ */ jsx("span", { className: cx("llm-code-language", cn.codeLanguage), children: language }),
470
+ o.copyButton ? /* @__PURE__ */ jsx(o.copyButton, { text: codeText, className: cn.copyButton }) : /* @__PURE__ */ jsx(
471
+ CopyButton,
472
+ {
473
+ text: codeText,
474
+ className: cx("llm-copy-button", cn.copyButton)
475
+ }
476
+ )
477
+ ] }),
478
+ /* @__PURE__ */ jsx("div", { className: "llm-code-body", children: Highlighter ? /* @__PURE__ */ jsx(Highlighter, { code: codeText, language }) : /* @__PURE__ */ jsx("code", { className: "llm-code-plain", children: codeText }) })
479
+ ] });
480
+ }
481
+ if (o.code) {
482
+ const InlineCode = o.code;
483
+ return /* @__PURE__ */ jsx(InlineCode, { className: cx("llm-code", cn.code, className), children });
484
+ }
485
+ return /* @__PURE__ */ jsx("code", { className: cx("llm-code", cn.code, className), ...props, children });
486
+ },
487
+ pre({ children }) {
488
+ if (o.pre) {
489
+ return /* @__PURE__ */ jsx(o.pre, { children });
490
+ }
491
+ return /* @__PURE__ */ jsx(Fragment, { children });
492
+ },
493
+ table({ children }) {
494
+ if (o.table) {
495
+ return /* @__PURE__ */ jsx(o.table, { className: cn.table, children });
496
+ }
497
+ return /* @__PURE__ */ jsx("div", { className: cx("llm-table-wrapper", cn.tableWrapper), children: /* @__PURE__ */ jsx("table", { className: cx("llm-table", cn.table), children }) });
498
+ },
499
+ th({ children }) {
500
+ if (o.th) {
501
+ return /* @__PURE__ */ jsx(o.th, { className: cn.th, children });
502
+ }
503
+ return /* @__PURE__ */ jsx("th", { className: cx("llm-th", cn.th), children });
504
+ },
505
+ td({ children }) {
506
+ if (o.td) {
507
+ return /* @__PURE__ */ jsx(o.td, { className: cn.td, children });
508
+ }
509
+ return /* @__PURE__ */ jsx("td", { className: cx("llm-td", cn.td), children });
510
+ },
511
+ blockquote({ children }) {
512
+ if (o.blockquote) {
513
+ return /* @__PURE__ */ jsx(o.blockquote, { className: cn.blockquote, children });
514
+ }
515
+ return /* @__PURE__ */ jsx("blockquote", { className: cx("llm-blockquote", cn.blockquote), children });
516
+ },
517
+ ul({ children }) {
518
+ if (o.ul) {
519
+ return /* @__PURE__ */ jsx(o.ul, { className: cn.ul, children });
520
+ }
521
+ return /* @__PURE__ */ jsx("ul", { className: cx("llm-ul", cn.ul), children });
522
+ },
523
+ ol({ children }) {
524
+ if (o.ol) {
525
+ return /* @__PURE__ */ jsx(o.ol, { className: cn.ol, children });
526
+ }
527
+ return /* @__PURE__ */ jsx("ol", { className: cx("llm-ol", cn.ol), children });
528
+ },
529
+ li({ children }) {
530
+ if (o.li) {
531
+ return /* @__PURE__ */ jsx(o.li, { className: cn.li, children });
532
+ }
533
+ return /* @__PURE__ */ jsx("li", { className: cx("llm-li", cn.li), children });
534
+ },
535
+ p({ children }) {
536
+ if (o.p) {
537
+ return /* @__PURE__ */ jsx(o.p, { className: cn.p, children });
538
+ }
539
+ return /* @__PURE__ */ jsx("p", { className: cx("llm-p", cn.p), children });
540
+ },
541
+ h1({ children }) {
542
+ if (o.h1) {
543
+ return /* @__PURE__ */ jsx(o.h1, { className: cn.h1, children });
544
+ }
545
+ return /* @__PURE__ */ jsx("h1", { className: cx("llm-h1", cn.h1), children });
546
+ },
547
+ h2({ children }) {
548
+ if (o.h2) {
549
+ return /* @__PURE__ */ jsx(o.h2, { className: cn.h2, children });
550
+ }
551
+ return /* @__PURE__ */ jsx("h2", { className: cx("llm-h2", cn.h2), children });
552
+ },
553
+ h3({ children }) {
554
+ if (o.h3) {
555
+ return /* @__PURE__ */ jsx(o.h3, { className: cn.h3, children });
556
+ }
557
+ return /* @__PURE__ */ jsx("h3", { className: cx("llm-h3", cn.h3), children });
558
+ },
559
+ h4({ children }) {
560
+ if (o.h4) {
561
+ return /* @__PURE__ */ jsx(o.h4, { className: cn.h4, children });
562
+ }
563
+ return /* @__PURE__ */ jsx("h4", { className: cx("llm-h4", cn.h4), children });
564
+ },
565
+ h5({ children }) {
566
+ if (o.h5) {
567
+ return /* @__PURE__ */ jsx(o.h5, { className: cn.h5, children });
568
+ }
569
+ return /* @__PURE__ */ jsx("h5", { className: cx("llm-h5", cn.h5), children });
570
+ },
571
+ h6({ children }) {
572
+ if (o.h6) {
573
+ return /* @__PURE__ */ jsx(o.h6, { className: cn.h6, children });
574
+ }
575
+ return /* @__PURE__ */ jsx("h6", { className: cx("llm-h6", cn.h6), children });
576
+ },
577
+ input({ node: _node, type, checked, disabled, ...props }) {
578
+ if (type === "checkbox") {
579
+ if (o.checkbox) {
580
+ return /* @__PURE__ */ jsx(o.checkbox, { checked: Boolean(checked), className: cn.checkbox });
581
+ }
582
+ return /* @__PURE__ */ jsx(
583
+ "input",
584
+ {
585
+ type: "checkbox",
586
+ checked: Boolean(checked),
587
+ disabled: true,
588
+ "aria-label": checked ? "Completed task" : "Incomplete task",
589
+ className: cx("llm-checkbox", cn.checkbox),
590
+ readOnly: true
591
+ }
592
+ );
593
+ }
594
+ return /* @__PURE__ */ jsx(
595
+ "input",
596
+ {
597
+ type,
598
+ checked,
599
+ disabled,
600
+ readOnly: true,
601
+ ...props
602
+ }
603
+ );
604
+ },
605
+ a({ href, children }) {
606
+ if (o.a) {
607
+ return /* @__PURE__ */ jsx(o.a, { href, className: cn.a, children });
608
+ }
609
+ return /* @__PURE__ */ jsx(
610
+ "a",
611
+ {
612
+ href,
613
+ target: "_blank",
614
+ rel: "noopener noreferrer",
615
+ className: cx("llm-a", cn.a),
616
+ children
617
+ }
618
+ );
619
+ },
620
+ img({ node: _node, src, alt, title, className: _className, ...props }) {
621
+ if (o.img) {
622
+ const Image = o.img;
623
+ return /* @__PURE__ */ jsx(
624
+ Image,
625
+ {
626
+ src: typeof src === "string" ? src : void 0,
627
+ alt,
628
+ title,
629
+ className: cn.img
630
+ }
631
+ );
632
+ }
633
+ return /* @__PURE__ */ jsx(
634
+ "img",
635
+ {
636
+ src: typeof src === "string" ? src : void 0,
637
+ alt,
638
+ title,
639
+ className: cx("llm-img", cn.img),
640
+ ...props
641
+ }
642
+ );
643
+ },
644
+ hr() {
645
+ if (o.hr) {
646
+ return /* @__PURE__ */ jsx(o.hr, { className: cn.hr });
647
+ }
648
+ return /* @__PURE__ */ jsx("hr", { className: cx("llm-hr", cn.hr) });
649
+ },
650
+ strong({ children }) {
651
+ if (o.strong) {
652
+ return /* @__PURE__ */ jsx(o.strong, { className: cn.strong, children });
653
+ }
654
+ return /* @__PURE__ */ jsx("strong", { className: cx("llm-strong", cn.strong), children });
655
+ },
656
+ em({ children }) {
657
+ if (o.em) {
658
+ return /* @__PURE__ */ jsx(o.em, { className: cn.em, children });
659
+ }
660
+ return /* @__PURE__ */ jsx("em", { className: cx("llm-em", cn.em), children });
661
+ },
662
+ del({ children }) {
663
+ if (o.del) {
664
+ return /* @__PURE__ */ jsx(o.del, { className: cn.del, children });
665
+ }
666
+ return /* @__PURE__ */ jsx("del", { className: cx("llm-del", cn.del), children });
667
+ }
668
+ };
669
+ }
670
+ function LLMMessage({
671
+ children,
672
+ content,
673
+ className,
674
+ classNames,
675
+ components,
676
+ completePartialTokens: repairPartialTokens = true,
677
+ showUnfinishedLatexBlocks = true,
678
+ highlighter,
679
+ ...rest
680
+ }) {
681
+ const source = content ?? children ?? "";
682
+ const markdownComponents = useMemo(
683
+ () => buildComponents(classNames, components, highlighter),
684
+ [classNames, components, highlighter]
685
+ );
686
+ const processed = useMemo(() => {
687
+ const repaired = repairPartialTokens ? completePartialTokens(source, { showUnfinishedLatexBlocks }) : source;
688
+ return preprocessLaTeX(repaired);
689
+ }, [source, repairPartialTokens, showUnfinishedLatexBlocks]);
690
+ return /* @__PURE__ */ jsx("div", { className: cx("llm-message", classNames?.root, className), ...rest, children: /* @__PURE__ */ jsx(
691
+ ReactMarkdown,
692
+ {
693
+ remarkPlugins,
694
+ rehypePlugins,
695
+ components: markdownComponents,
696
+ children: processed
697
+ }
698
+ ) });
699
+ }
700
+
701
+ export { LLMMessage, completePartialTokens, escapeBrackets, escapeMhchem, preprocessLaTeX };
702
+ //# sourceMappingURL=index.js.map
703
+ //# sourceMappingURL=index.js.map