@kat-ai/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,995 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ CitationDialog: () => CitationDialog,
34
+ CitationDisplay: () => CitationDisplay,
35
+ MultiChoiceWidget: () => MultiChoiceWidget
36
+ });
37
+ module.exports = __toCommonJS(index_exports);
38
+
39
+ // src/citations/CitationDialog.tsx
40
+ var import_react = require("react");
41
+ var import_react_markdown = __toESM(require("react-markdown"));
42
+ var import_remark_math = __toESM(require("remark-math"));
43
+ var import_rehype_katex = __toESM(require("rehype-katex"));
44
+ var import_jsx_runtime = require("react/jsx-runtime");
45
+ function extractPageFromUrl(url) {
46
+ if (!url) return null;
47
+ try {
48
+ const parsed = new URL(url, typeof window !== "undefined" ? window.location.origin : "http://localhost");
49
+ const searchPage = parsed.searchParams.get("page");
50
+ const hashPart = url.split("#")[1];
51
+ const hashParams = new URLSearchParams(hashPart?.replace(/^\?/, "") || "");
52
+ const hashPage = hashParams.get("page");
53
+ const candidate = hashPage || searchPage;
54
+ if (candidate) {
55
+ const num = Number.parseInt(candidate, 10);
56
+ return Number.isFinite(num) && num > 0 ? num : null;
57
+ }
58
+ } catch {
59
+ }
60
+ return null;
61
+ }
62
+ function parseCitationMeta(url) {
63
+ if (!url) return null;
64
+ try {
65
+ const hashPart = url.split("#")[1];
66
+ const hashParams = new URLSearchParams(hashPart?.replace(/^\?/, "") || "");
67
+ const metaRaw = hashParams.get("meta");
68
+ if (!metaRaw) return null;
69
+ const parsed = JSON.parse(metaRaw);
70
+ return parsed;
71
+ } catch {
72
+ return null;
73
+ }
74
+ }
75
+ function CitationDialog({ url, isOpen, onClose, citation }) {
76
+ const [content, setContent] = (0, import_react.useState)("");
77
+ const [pdfUrl, setPdfUrl] = (0, import_react.useState)(null);
78
+ const [isPdf, setIsPdf] = (0, import_react.useState)(false);
79
+ const [pageNumber, setPageNumber] = (0, import_react.useState)(null);
80
+ const [citationMeta, setCitationMeta] = (0, import_react.useState)(null);
81
+ const [loading, setLoading] = (0, import_react.useState)(false);
82
+ const [error, setError] = (0, import_react.useState)(null);
83
+ (0, import_react.useEffect)(() => {
84
+ if (isOpen && (url || citation)) {
85
+ let cancelled = false;
86
+ const loadCitation = async () => {
87
+ setLoading(true);
88
+ setError(null);
89
+ setContent("");
90
+ setPdfUrl(null);
91
+ setIsPdf(false);
92
+ setPageNumber(null);
93
+ if (citation) {
94
+ const meta2 = {
95
+ label: citation.label,
96
+ source: citation.referenceSummary,
97
+ fileName: citation.fileName,
98
+ preview: citation.preview,
99
+ // Map other fields if available in reference metadata
100
+ ...citation.reference?.file?.metadata || {}
101
+ };
102
+ setCitationMeta(meta2);
103
+ if (citation.content) {
104
+ setContent(citation.content);
105
+ setLoading(false);
106
+ return;
107
+ }
108
+ }
109
+ const targetUrl = url || citation?.reference?.file?.signedUrl || citation?.reference?.file?.signed_url;
110
+ if (!targetUrl) {
111
+ if (citation?.content) {
112
+ setContent(citation.content);
113
+ setLoading(false);
114
+ } else {
115
+ setError("No content or URL available");
116
+ setLoading(false);
117
+ }
118
+ return;
119
+ }
120
+ const meta = parseCitationMeta(targetUrl);
121
+ if (!citationMeta) {
122
+ setCitationMeta(meta);
123
+ }
124
+ const [baseUrl, hashFragment] = targetUrl.split("#");
125
+ const fragment = hashFragment ? `#${hashFragment}` : "";
126
+ const apiUrlBase = baseUrl.startsWith("/api/citation") ? baseUrl : `/api/citation?url=${encodeURIComponent(baseUrl)}`;
127
+ const apiUrlWithFragment = `${apiUrlBase}${fragment}`;
128
+ const derivedPage = extractPageFromUrl(apiUrlWithFragment) ?? meta?.page ?? null;
129
+ setPageNumber(derivedPage);
130
+ let urlToCheck = baseUrl.toLowerCase();
131
+ try {
132
+ let decoded = urlToCheck;
133
+ for (let i = 0; i < 3; i++) {
134
+ const newDecoded = decodeURIComponent(decoded);
135
+ if (newDecoded === decoded) break;
136
+ decoded = newDecoded;
137
+ }
138
+ urlToCheck = decoded;
139
+ } catch {
140
+ }
141
+ const looksLikePdf = urlToCheck.includes(".pdf") || urlToCheck.includes("content-type=application/pdf") || urlToCheck.includes("application/pdf") || targetUrl.toLowerCase().includes("pdf") || citation?.contentType === "application/pdf";
142
+ if (looksLikePdf) {
143
+ if (!cancelled) {
144
+ setPdfUrl(apiUrlWithFragment);
145
+ setIsPdf(true);
146
+ setPageNumber(derivedPage);
147
+ setLoading(false);
148
+ }
149
+ return;
150
+ }
151
+ try {
152
+ const res = await fetch(apiUrlBase);
153
+ if (!res.ok) {
154
+ const errorData = await res.json().catch(() => ({ error: res.statusText }));
155
+ throw new Error(errorData.error || `Failed to fetch: ${res.status} ${res.statusText}`);
156
+ }
157
+ const contentType = res.headers.get("content-type") || "";
158
+ if (contentType.includes("application/pdf")) {
159
+ if (!cancelled) {
160
+ setPdfUrl(apiUrlWithFragment);
161
+ setIsPdf(true);
162
+ setPageNumber(derivedPage);
163
+ }
164
+ return;
165
+ }
166
+ const text = await res.text();
167
+ if (!cancelled) {
168
+ setContent(text);
169
+ }
170
+ } catch (err) {
171
+ console.error("Error fetching citation content:", err);
172
+ if (!cancelled) {
173
+ setError(err instanceof Error ? err.message : "Failed to load content");
174
+ }
175
+ } finally {
176
+ if (!cancelled) {
177
+ setLoading(false);
178
+ }
179
+ }
180
+ };
181
+ loadCitation();
182
+ return () => {
183
+ cancelled = true;
184
+ };
185
+ } else {
186
+ setContent("");
187
+ setError(null);
188
+ setPdfUrl(null);
189
+ setIsPdf(false);
190
+ setPageNumber(null);
191
+ setCitationMeta(null);
192
+ setLoading(false);
193
+ }
194
+ }, [isOpen, url, citation]);
195
+ (0, import_react.useEffect)(() => {
196
+ const handleEscape = (e) => {
197
+ if (e.key === "Escape" && isOpen) {
198
+ onClose();
199
+ }
200
+ };
201
+ if (isOpen) {
202
+ document.addEventListener("keydown", handleEscape);
203
+ document.body.style.overflow = "hidden";
204
+ }
205
+ return () => {
206
+ document.removeEventListener("keydown", handleEscape);
207
+ document.body.style.overflow = "unset";
208
+ };
209
+ }, [isOpen, onClose]);
210
+ const renderCitationInfo = () => {
211
+ if (!citationMeta && !pageNumber) return null;
212
+ const meta = citationMeta || {};
213
+ const infoItems = [
214
+ { label: "Page", value: pageNumber ?? meta.page ?? "Not provided" },
215
+ { label: "Label", value: meta.label },
216
+ { label: "Source", value: meta.source },
217
+ { label: "File", value: meta.fileName },
218
+ { label: "Row ID", value: meta.rowId },
219
+ { label: "Category", value: meta.category },
220
+ { label: "Source Type", value: meta.sourceType }
221
+ ].filter((item) => item.value !== void 0 && item.value !== null && item.value !== "");
222
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
223
+ padding: "12px 14px",
224
+ backgroundColor: "#1a1a1a",
225
+ border: "1px solid #2a2a2a",
226
+ borderRadius: "8px",
227
+ color: "#d0d0d0",
228
+ fontSize: "14px",
229
+ lineHeight: "1.6"
230
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: "10px", alignItems: "center" }, children: infoItems.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: {
231
+ padding: "6px 10px",
232
+ borderRadius: "6px",
233
+ backgroundColor: "#0f172a",
234
+ color: "#7dd3fc",
235
+ border: "1px solid #1f2937",
236
+ fontWeight: 600,
237
+ fontSize: "13px"
238
+ }, children: [
239
+ item.label,
240
+ ": ",
241
+ String(item.value)
242
+ ] }, item.label)) }) });
243
+ };
244
+ if (!isOpen) return null;
245
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
246
+ "div",
247
+ {
248
+ style: {
249
+ position: "fixed",
250
+ top: 0,
251
+ left: 0,
252
+ right: 0,
253
+ bottom: 0,
254
+ backgroundColor: "rgba(0, 0, 0, 0.8)",
255
+ backdropFilter: "blur(8px)",
256
+ zIndex: 1e3,
257
+ display: "flex",
258
+ alignItems: "center",
259
+ justifyContent: "center",
260
+ padding: "16px",
261
+ animation: "fadeIn 0.2s ease-out"
262
+ },
263
+ onClick: (e) => {
264
+ if (e.target === e.currentTarget) {
265
+ onClose();
266
+ }
267
+ },
268
+ children: [
269
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: `
270
+ @keyframes fadeIn {
271
+ from {
272
+ opacity: 0;
273
+ }
274
+ to {
275
+ opacity: 1;
276
+ }
277
+ }
278
+ @keyframes slideUp {
279
+ from {
280
+ opacity: 0;
281
+ transform: translateY(20px);
282
+ }
283
+ to {
284
+ opacity: 1;
285
+ transform: translateY(0);
286
+ }
287
+ }
288
+ @keyframes spin {
289
+ to {
290
+ transform: rotate(360deg);
291
+ }
292
+ }
293
+ .citation-dialog-scrollbar::-webkit-scrollbar {
294
+ width: 8px;
295
+ }
296
+ .citation-dialog-scrollbar::-webkit-scrollbar-track {
297
+ background: #111111;
298
+ border-radius: 4px;
299
+ }
300
+ .citation-dialog-scrollbar::-webkit-scrollbar-thumb {
301
+ background: #1a1a1a;
302
+ border-radius: 4px;
303
+ }
304
+ .citation-dialog-scrollbar::-webkit-scrollbar-thumb:hover {
305
+ background: #2a2a2a;
306
+ }
307
+ ` }),
308
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
309
+ "div",
310
+ {
311
+ style: {
312
+ backgroundColor: "#111111",
313
+ borderRadius: "12px",
314
+ border: "1px solid #1a1a1a",
315
+ width: "100%",
316
+ maxWidth: "950px",
317
+ maxHeight: "92vh",
318
+ display: "flex",
319
+ flexDirection: "column",
320
+ boxShadow: "0 20px 60px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.05)",
321
+ animation: "slideUp 0.3s ease-out",
322
+ overflow: "hidden"
323
+ },
324
+ onClick: (e) => e.stopPropagation(),
325
+ children: [
326
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
327
+ "div",
328
+ {
329
+ style: {
330
+ padding: "20px 28px",
331
+ borderBottom: "1px solid #1a1a1a",
332
+ display: "flex",
333
+ alignItems: "center",
334
+ justifyContent: "space-between",
335
+ background: "linear-gradient(to bottom, #111111, #0a0a0a)"
336
+ },
337
+ children: [
338
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "12px" }, children: [
339
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
340
+ "div",
341
+ {
342
+ style: {
343
+ width: "36px",
344
+ height: "36px",
345
+ borderRadius: "8px",
346
+ background: "linear-gradient(135deg, #0070f3 0%, #0051cc 100%)",
347
+ display: "flex",
348
+ alignItems: "center",
349
+ justifyContent: "center",
350
+ fontSize: "18px",
351
+ boxShadow: "0 2px 8px rgba(0, 112, 243, 0.3)"
352
+ },
353
+ children: "\u{1F4C4}"
354
+ }
355
+ ),
356
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
357
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { style: {
358
+ color: "#ffffff",
359
+ margin: 0,
360
+ fontSize: "20px",
361
+ fontWeight: "600",
362
+ letterSpacing: "-0.01em",
363
+ lineHeight: "1.2"
364
+ }, children: "Source Document" }),
365
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
366
+ fontSize: "13px",
367
+ color: "#888888",
368
+ marginTop: "4px",
369
+ fontWeight: "400"
370
+ }, children: "Reference information" })
371
+ ] })
372
+ ] }),
373
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
374
+ "button",
375
+ {
376
+ onClick: onClose,
377
+ style: {
378
+ background: "transparent",
379
+ border: "1px solid #1a1a1a",
380
+ color: "#888888",
381
+ fontSize: "20px",
382
+ cursor: "pointer",
383
+ padding: "8px",
384
+ lineHeight: 1,
385
+ borderRadius: "6px",
386
+ transition: "all 0.2s ease",
387
+ width: "36px",
388
+ height: "36px",
389
+ display: "flex",
390
+ alignItems: "center",
391
+ justifyContent: "center"
392
+ },
393
+ onMouseEnter: (e) => {
394
+ e.currentTarget.style.backgroundColor = "#1a1a1a";
395
+ e.currentTarget.style.borderColor = "#2a2a2a";
396
+ e.currentTarget.style.color = "#ffffff";
397
+ },
398
+ onMouseLeave: (e) => {
399
+ e.currentTarget.style.backgroundColor = "transparent";
400
+ e.currentTarget.style.borderColor = "#1a1a1a";
401
+ e.currentTarget.style.color = "#888888";
402
+ },
403
+ "aria-label": "Close dialog",
404
+ children: "\xD7"
405
+ }
406
+ )
407
+ ]
408
+ }
409
+ ),
410
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
411
+ "div",
412
+ {
413
+ className: "citation-dialog-scrollbar",
414
+ style: {
415
+ flex: 1,
416
+ overflowY: "auto",
417
+ padding: "24px",
418
+ color: "#ffffff",
419
+ background: "#111111"
420
+ },
421
+ children: [
422
+ loading && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: {
423
+ textAlign: "center",
424
+ padding: "4rem 2rem",
425
+ display: "flex",
426
+ flexDirection: "column",
427
+ alignItems: "center",
428
+ gap: "1rem"
429
+ }, children: [
430
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
431
+ "div",
432
+ {
433
+ style: {
434
+ width: "40px",
435
+ height: "40px",
436
+ border: "3px solid #2a2a2a",
437
+ borderTopColor: "#4a9eff",
438
+ borderRadius: "50%",
439
+ animation: "spin 0.8s linear infinite"
440
+ }
441
+ }
442
+ ),
443
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
444
+ color: "#a0a0a0",
445
+ fontSize: "0.95rem",
446
+ fontWeight: "500"
447
+ }, children: "Loading document..." })
448
+ ] }),
449
+ error && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
450
+ "div",
451
+ {
452
+ style: {
453
+ padding: "1.25rem 1.5rem",
454
+ backgroundColor: "#2a1a1a",
455
+ borderRadius: "8px",
456
+ color: "#ff6b6b",
457
+ border: "1px solid #4a2a2a",
458
+ display: "flex",
459
+ alignItems: "flex-start",
460
+ gap: "0.75rem"
461
+ },
462
+ children: [
463
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: "1.25rem" }, children: "\u26A0\uFE0F" }),
464
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
465
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { style: { display: "block", marginBottom: "0.25rem", fontSize: "0.95rem" }, children: "Error loading document" }),
466
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontSize: "0.875rem", color: "#ff9999" }, children: error })
467
+ ] })
468
+ ]
469
+ }
470
+ ),
471
+ !loading && !error && isPdf && pdfUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "16px" }, children: [
472
+ renderCitationInfo(),
473
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
474
+ borderRadius: "8px",
475
+ overflow: "hidden",
476
+ border: "1px solid #1a1a1a",
477
+ backgroundColor: "#0a0a0a",
478
+ minHeight: "60vh"
479
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
480
+ "object",
481
+ {
482
+ data: pdfUrl,
483
+ type: "application/pdf",
484
+ width: "100%",
485
+ height: "100%",
486
+ "aria-label": "PDF viewer",
487
+ style: { display: "block", minHeight: "70vh" },
488
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
489
+ "iframe",
490
+ {
491
+ src: pdfUrl,
492
+ title: "PDF viewer",
493
+ style: { width: "100%", height: "70vh", border: "none" }
494
+ }
495
+ )
496
+ }
497
+ ) }),
498
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: {
499
+ display: "flex",
500
+ alignItems: "center",
501
+ justifyContent: "space-between",
502
+ gap: "12px",
503
+ flexWrap: "wrap"
504
+ }, children: [
505
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { color: "#888888", fontSize: "13px" }, children: "Prefer a new tab? Open the PDF directly." }),
506
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
507
+ "button",
508
+ {
509
+ onClick: () => window.open(pdfUrl, "_blank", "noopener,noreferrer"),
510
+ style: {
511
+ display: "flex",
512
+ alignItems: "center",
513
+ gap: "8px",
514
+ padding: "10px 16px",
515
+ backgroundColor: "#0070f3",
516
+ color: "#ffffff",
517
+ border: "none",
518
+ borderRadius: "6px",
519
+ fontSize: "14px",
520
+ fontWeight: "600",
521
+ cursor: "pointer",
522
+ transition: "all 0.2s ease"
523
+ },
524
+ onMouseEnter: (e) => {
525
+ e.currentTarget.style.backgroundColor = "#0051cc";
526
+ e.currentTarget.style.transform = "translateY(-1px)";
527
+ },
528
+ onMouseLeave: (e) => {
529
+ e.currentTarget.style.backgroundColor = "#0070f3";
530
+ e.currentTarget.style.transform = "translateY(0)";
531
+ },
532
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "Open in new tab" })
533
+ }
534
+ )
535
+ ] })
536
+ ] }),
537
+ !loading && !error && !isPdf && content && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: {
538
+ maxWidth: "800px",
539
+ margin: "0 auto"
540
+ }, children: [
541
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { marginBottom: "16px" }, children: renderCitationInfo() }),
542
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
543
+ import_react_markdown.default,
544
+ {
545
+ remarkPlugins: [import_remark_math.default],
546
+ rehypePlugins: [import_rehype_katex.default],
547
+ components: {
548
+ p: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: {
549
+ marginBottom: "1.25rem",
550
+ marginTop: 0,
551
+ lineHeight: "1.75",
552
+ color: "#d0d0d0",
553
+ fontSize: "0.95rem"
554
+ }, children }),
555
+ h1: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", { style: {
556
+ fontSize: "2rem",
557
+ fontWeight: "700",
558
+ marginBottom: "1.25rem",
559
+ marginTop: "0",
560
+ color: "#fff",
561
+ borderBottom: "2px solid #2a2a2a",
562
+ paddingBottom: "0.75rem",
563
+ letterSpacing: "-0.02em",
564
+ lineHeight: "1.3"
565
+ }, children }),
566
+ h2: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { style: {
567
+ fontSize: "1.5rem",
568
+ fontWeight: "600",
569
+ marginBottom: "1rem",
570
+ marginTop: "1.75rem",
571
+ color: "#fff",
572
+ letterSpacing: "-0.01em",
573
+ lineHeight: "1.4"
574
+ }, children }),
575
+ h3: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { style: {
576
+ fontSize: "1.25rem",
577
+ fontWeight: "600",
578
+ marginBottom: "0.75rem",
579
+ marginTop: "1.5rem",
580
+ color: "#f0f0f0",
581
+ lineHeight: "1.4"
582
+ }, children }),
583
+ h4: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h4", { style: {
584
+ fontSize: "1.1rem",
585
+ fontWeight: "600",
586
+ marginBottom: "0.75rem",
587
+ marginTop: "1.25rem",
588
+ color: "#f0f0f0",
589
+ lineHeight: "1.4"
590
+ }, children }),
591
+ strong: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { style: {
592
+ fontWeight: "600",
593
+ color: "#fff"
594
+ }, children }),
595
+ em: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("em", { style: {
596
+ fontStyle: "italic",
597
+ color: "#d0d0d0"
598
+ }, children }),
599
+ ul: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { style: {
600
+ marginBottom: "1.25rem",
601
+ paddingLeft: "1.75rem",
602
+ listStyleType: "disc",
603
+ lineHeight: "1.75"
604
+ }, children }),
605
+ ol: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { style: {
606
+ marginBottom: "1.25rem",
607
+ paddingLeft: "1.75rem",
608
+ listStyleType: "decimal",
609
+ lineHeight: "1.75"
610
+ }, children }),
611
+ li: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { style: {
612
+ marginBottom: "0.5rem",
613
+ lineHeight: "1.75",
614
+ color: "#d0d0d0",
615
+ paddingLeft: "0.25rem"
616
+ }, children }),
617
+ code: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { style: {
618
+ backgroundColor: "#0f0f0f",
619
+ padding: "0.2rem 0.5rem",
620
+ borderRadius: "4px",
621
+ fontSize: "0.875em",
622
+ fontFamily: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace',
623
+ color: "#a0e0a0",
624
+ border: "1px solid #1a1a1a"
625
+ }, children }),
626
+ pre: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("pre", { style: {
627
+ backgroundColor: "#0f0f0f",
628
+ padding: "1.25rem",
629
+ borderRadius: "8px",
630
+ overflow: "auto",
631
+ marginBottom: "1.25rem",
632
+ border: "1px solid #2a2a2a",
633
+ fontSize: "0.875rem",
634
+ lineHeight: "1.6"
635
+ }, children }),
636
+ blockquote: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("blockquote", { style: {
637
+ borderLeft: "4px solid #4a9eff",
638
+ paddingLeft: "1.25rem",
639
+ marginLeft: 0,
640
+ marginBottom: "1.25rem",
641
+ color: "#c0c0c0",
642
+ fontStyle: "italic",
643
+ backgroundColor: "#1f1f1f",
644
+ padding: "1rem 1.25rem",
645
+ borderRadius: "0 6px 6px 0"
646
+ }, children }),
647
+ a: ({ href, children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
648
+ "a",
649
+ {
650
+ href,
651
+ target: "_blank",
652
+ rel: "noopener noreferrer",
653
+ style: {
654
+ color: "#4a9eff",
655
+ textDecoration: "none",
656
+ borderBottom: "1px solid rgba(74, 158, 255, 0.3)",
657
+ transition: "all 0.2s"
658
+ },
659
+ onMouseEnter: (e) => {
660
+ e.currentTarget.style.color = "#6bb0ff";
661
+ e.currentTarget.style.borderBottomColor = "rgba(107, 176, 255, 0.6)";
662
+ },
663
+ onMouseLeave: (e) => {
664
+ e.currentTarget.style.color = "#4a9eff";
665
+ e.currentTarget.style.borderBottomColor = "rgba(74, 158, 255, 0.3)";
666
+ },
667
+ children
668
+ }
669
+ ),
670
+ table: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: {
671
+ overflowX: "auto",
672
+ marginBottom: "1.25rem"
673
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("table", { style: {
674
+ width: "100%",
675
+ borderCollapse: "collapse"
676
+ }, children }) }),
677
+ th: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { style: {
678
+ border: "1px solid #2a2a2a",
679
+ padding: "0.75rem",
680
+ backgroundColor: "#1f1f1f",
681
+ textAlign: "left",
682
+ fontWeight: "600",
683
+ color: "#fff",
684
+ fontSize: "0.9rem"
685
+ }, children }),
686
+ td: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { style: {
687
+ border: "1px solid #2a2a2a",
688
+ padding: "0.75rem",
689
+ color: "#d0d0d0",
690
+ fontSize: "0.9rem"
691
+ }, children }),
692
+ hr: () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", { style: {
693
+ border: "none",
694
+ borderTop: "1px solid #2a2a2a",
695
+ margin: "2rem 0"
696
+ } })
697
+ },
698
+ children: content
699
+ }
700
+ )
701
+ ] })
702
+ ]
703
+ }
704
+ )
705
+ ]
706
+ }
707
+ )
708
+ ]
709
+ }
710
+ );
711
+ }
712
+
713
+ // src/citations/CitationDisplay.tsx
714
+ var import_jsx_runtime2 = require("react/jsx-runtime");
715
+ function stripMarkdown(text) {
716
+ if (!text) return "";
717
+ return text.replace(/^#+\s*/gm, "").replace(/\*\*([^*]+)\*\*/g, "$1").replace(/__([^_]+)__/g, "$1").replace(/\*([^*]+)\*/g, "$1").replace(/_([^_]+)_/g, "$1").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/`{1,3}[^`]*`{1,3}/g, "").replace(/\s+/g, " ").trim();
718
+ }
719
+ function formatReferenceSummary(summary, maxLength) {
720
+ if (!summary) return "";
721
+ const cleaned = stripMarkdown(summary);
722
+ if (cleaned.length <= maxLength) {
723
+ return cleaned;
724
+ }
725
+ return cleaned.substring(0, maxLength - 3) + "...";
726
+ }
727
+ function CitationDisplay({
728
+ citations,
729
+ onCitationClick,
730
+ chipColor = "#2a1a3a",
731
+ borderColor = "#4a2a5a",
732
+ maxSummaryLength = 40
733
+ }) {
734
+ if (!citations || citations.length === 0) {
735
+ return null;
736
+ }
737
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", flexWrap: "wrap", gap: "0.35rem", marginTop: "0.5rem" }, children: citations.map((citation, idx) => {
738
+ const displaySummary = formatReferenceSummary(citation.referenceSummary, maxSummaryLength);
739
+ const tooltipText = stripMarkdown(citation.preview || citation.referenceSummary || "");
740
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
741
+ "span",
742
+ {
743
+ title: tooltipText,
744
+ onClick: () => onCitationClick(citation),
745
+ style: {
746
+ padding: "0.35rem 0.5rem",
747
+ backgroundColor: chipColor,
748
+ borderRadius: "4px",
749
+ border: `1px solid ${borderColor}`,
750
+ fontSize: "0.75rem",
751
+ color: "#d0a0f0",
752
+ cursor: "pointer",
753
+ maxWidth: "100%",
754
+ overflow: "hidden",
755
+ textOverflow: "ellipsis",
756
+ whiteSpace: "nowrap",
757
+ display: "inline-flex",
758
+ alignItems: "center",
759
+ gap: "4px"
760
+ },
761
+ children: [
762
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: { fontWeight: 600 }, children: [
763
+ "[",
764
+ citation.label,
765
+ "]"
766
+ ] }),
767
+ displaySummary && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: displaySummary })
768
+ ]
769
+ },
770
+ citation.label || idx
771
+ );
772
+ }) });
773
+ }
774
+
775
+ // src/multichoice/MultiChoiceWidget.tsx
776
+ var import_react2 = require("react");
777
+ var import_jsx_runtime3 = require("react/jsx-runtime");
778
+ function MultiChoiceWidget({
779
+ options,
780
+ onSelect,
781
+ freeTextPlaceholder = "Or type your own answer...",
782
+ chipColor = "rgba(139, 92, 246, 0.15)",
783
+ borderColor = "rgba(139, 92, 246, 0.3)",
784
+ accentColor = "rgba(139, 92, 246, 0.5)",
785
+ textColor = "#d4b8ff",
786
+ disabled = false
787
+ }) {
788
+ const [showFreeText, setShowFreeText] = (0, import_react2.useState)(false);
789
+ const [freeTextValue, setFreeTextValue] = (0, import_react2.useState)("");
790
+ const handleOptionClick = (0, import_react2.useCallback)(
791
+ (option) => {
792
+ if (disabled) return;
793
+ onSelect(option.label);
794
+ },
795
+ [onSelect, disabled]
796
+ );
797
+ const handleOtherClick = (0, import_react2.useCallback)(() => {
798
+ if (disabled) return;
799
+ setShowFreeText(true);
800
+ }, [disabled]);
801
+ const handleFreeTextSubmit = (0, import_react2.useCallback)(() => {
802
+ if (disabled || !freeTextValue.trim()) return;
803
+ onSelect(freeTextValue.trim());
804
+ setFreeTextValue("");
805
+ setShowFreeText(false);
806
+ }, [onSelect, freeTextValue, disabled]);
807
+ const handleKeyDown = (0, import_react2.useCallback)(
808
+ (e) => {
809
+ if (e.key === "Enter") {
810
+ e.preventDefault();
811
+ handleFreeTextSubmit();
812
+ } else if (e.key === "Escape") {
813
+ setShowFreeText(false);
814
+ setFreeTextValue("");
815
+ }
816
+ },
817
+ [handleFreeTextSubmit]
818
+ );
819
+ const baseChipStyle = {
820
+ padding: "0.5rem 0.875rem",
821
+ backgroundColor: chipColor,
822
+ borderRadius: "9999px",
823
+ border: `1px solid ${borderColor}`,
824
+ fontSize: "0.875rem",
825
+ color: textColor,
826
+ cursor: disabled ? "not-allowed" : "pointer",
827
+ opacity: disabled ? 0.5 : 1,
828
+ transition: "all 0.15s ease",
829
+ display: "inline-flex",
830
+ alignItems: "center",
831
+ gap: "0.375rem"
832
+ };
833
+ const hoverChipStyle = {
834
+ ...baseChipStyle,
835
+ backgroundColor: accentColor,
836
+ borderColor: textColor
837
+ };
838
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
839
+ "div",
840
+ {
841
+ style: {
842
+ display: "flex",
843
+ flexDirection: "column",
844
+ gap: "0.75rem",
845
+ marginTop: "0.75rem"
846
+ },
847
+ children: [
848
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
849
+ "div",
850
+ {
851
+ style: {
852
+ display: "flex",
853
+ flexWrap: "wrap",
854
+ gap: "0.5rem"
855
+ },
856
+ children: [
857
+ options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
858
+ "button",
859
+ {
860
+ onClick: () => handleOptionClick(option),
861
+ disabled,
862
+ title: option.description,
863
+ style: baseChipStyle,
864
+ onMouseEnter: (e) => {
865
+ if (!disabled) {
866
+ Object.assign(e.currentTarget.style, hoverChipStyle);
867
+ }
868
+ },
869
+ onMouseLeave: (e) => {
870
+ Object.assign(e.currentTarget.style, baseChipStyle);
871
+ },
872
+ children: option.label
873
+ },
874
+ option.id
875
+ )),
876
+ !showFreeText && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
877
+ "button",
878
+ {
879
+ onClick: handleOtherClick,
880
+ disabled,
881
+ style: {
882
+ ...baseChipStyle,
883
+ backgroundColor: "transparent",
884
+ borderStyle: "dashed"
885
+ },
886
+ onMouseEnter: (e) => {
887
+ if (!disabled) {
888
+ e.currentTarget.style.backgroundColor = chipColor;
889
+ e.currentTarget.style.borderStyle = "solid";
890
+ }
891
+ },
892
+ onMouseLeave: (e) => {
893
+ e.currentTarget.style.backgroundColor = "transparent";
894
+ e.currentTarget.style.borderStyle = "dashed";
895
+ },
896
+ children: [
897
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { fontSize: "1rem", lineHeight: 1 }, children: "+" }),
898
+ "Other"
899
+ ]
900
+ }
901
+ )
902
+ ]
903
+ }
904
+ ),
905
+ showFreeText && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
906
+ "div",
907
+ {
908
+ style: {
909
+ display: "flex",
910
+ gap: "0.5rem",
911
+ alignItems: "center"
912
+ },
913
+ children: [
914
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
915
+ "input",
916
+ {
917
+ type: "text",
918
+ value: freeTextValue,
919
+ onChange: (e) => setFreeTextValue(e.target.value),
920
+ onKeyDown: handleKeyDown,
921
+ placeholder: freeTextPlaceholder,
922
+ disabled,
923
+ autoFocus: true,
924
+ style: {
925
+ flex: 1,
926
+ padding: "0.5rem 0.75rem",
927
+ backgroundColor: "rgba(0, 0, 0, 0.2)",
928
+ border: `1px solid ${borderColor}`,
929
+ borderRadius: "0.5rem",
930
+ color: textColor,
931
+ fontSize: "0.875rem",
932
+ outline: "none"
933
+ },
934
+ onFocus: (e) => {
935
+ e.currentTarget.style.borderColor = accentColor;
936
+ },
937
+ onBlur: (e) => {
938
+ e.currentTarget.style.borderColor = borderColor;
939
+ }
940
+ }
941
+ ),
942
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
943
+ "button",
944
+ {
945
+ onClick: handleFreeTextSubmit,
946
+ disabled: disabled || !freeTextValue.trim(),
947
+ style: {
948
+ padding: "0.5rem 1rem",
949
+ backgroundColor: freeTextValue.trim() ? accentColor : chipColor,
950
+ border: `1px solid ${freeTextValue.trim() ? textColor : borderColor}`,
951
+ borderRadius: "0.5rem",
952
+ color: textColor,
953
+ fontSize: "0.875rem",
954
+ cursor: disabled || !freeTextValue.trim() ? "not-allowed" : "pointer",
955
+ opacity: disabled || !freeTextValue.trim() ? 0.5 : 1,
956
+ transition: "all 0.15s ease"
957
+ },
958
+ children: "Send"
959
+ }
960
+ ),
961
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
962
+ "button",
963
+ {
964
+ onClick: () => {
965
+ setShowFreeText(false);
966
+ setFreeTextValue("");
967
+ },
968
+ disabled,
969
+ style: {
970
+ padding: "0.5rem",
971
+ backgroundColor: "transparent",
972
+ border: "none",
973
+ color: textColor,
974
+ fontSize: "1rem",
975
+ cursor: disabled ? "not-allowed" : "pointer",
976
+ opacity: disabled ? 0.5 : 0.7
977
+ },
978
+ title: "Cancel",
979
+ children: "\xD7"
980
+ }
981
+ )
982
+ ]
983
+ }
984
+ )
985
+ ]
986
+ }
987
+ );
988
+ }
989
+ // Annotate the CommonJS export names for ESM import in node:
990
+ 0 && (module.exports = {
991
+ CitationDialog,
992
+ CitationDisplay,
993
+ MultiChoiceWidget
994
+ });
995
+ //# sourceMappingURL=index.js.map