@arbidocs/react 0.3.103 → 0.3.105
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.cjs +773 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +245 -3
- package/dist/index.d.ts +245 -3
- package/dist/index.js +752 -3
- package/dist/index.js.map +1 -1
- package/package.json +8 -3
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import React__default, { createContext, forwardRef, useMemo, useContext, useState, useCallback, useEffect
|
|
2
|
+
import React__default, { createContext, forwardRef, useMemo, useContext, useState, useRef, useCallback, useEffect } from 'react';
|
|
3
3
|
import { Arbi, resolveCitations, summarizeCitations } from '@arbidocs/sdk/browser';
|
|
4
4
|
export { Arbi, ArbiError } from '@arbidocs/sdk/browser';
|
|
5
5
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -11,7 +11,12 @@ import * as AvatarPrimitive from '@radix-ui/react-avatar';
|
|
|
11
11
|
import { cva } from 'class-variance-authority';
|
|
12
12
|
import { Slot } from '@radix-ui/react-slot';
|
|
13
13
|
import * as HoverCardPrimitive from '@radix-ui/react-hover-card';
|
|
14
|
-
import {
|
|
14
|
+
import { diffWords } from 'diff';
|
|
15
|
+
import ReactMarkdown from 'react-markdown';
|
|
16
|
+
import remarkGfm from 'remark-gfm';
|
|
17
|
+
import rehypeRaw from 'rehype-raw';
|
|
18
|
+
import { MoreVertical, Loader2, AlertTriangle, ShieldCheck, Check, Copy, Sparkles, FileText, GitCompareArrows, Download, Search, CornerDownLeft, Send, Tags, Eye, FolderOpen, Bot, Calendar, Folder, StickyNote, Hash, List, SquareCheckBig, Package } from 'lucide-react';
|
|
19
|
+
import { AnimatePresence, motion } from 'framer-motion';
|
|
15
20
|
import { AgGridReact } from 'ag-grid-react';
|
|
16
21
|
import { ModuleRegistry, AllCommunityModule } from 'ag-grid-community';
|
|
17
22
|
import { create } from 'zustand';
|
|
@@ -1392,6 +1397,7 @@ var badgeVariants = cva(
|
|
|
1392
1397
|
variants: {
|
|
1393
1398
|
variant: {
|
|
1394
1399
|
default: "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",
|
|
1400
|
+
accent: "border-transparent bg-ai-accent-soft text-ai-accent",
|
|
1395
1401
|
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
1396
1402
|
destructive: "border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80",
|
|
1397
1403
|
outline: "text-foreground"
|
|
@@ -1411,6 +1417,7 @@ var buttonVariants = cva(
|
|
|
1411
1417
|
variants: {
|
|
1412
1418
|
variant: {
|
|
1413
1419
|
default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
|
|
1420
|
+
accent: "bg-ai-accent text-ai-accent-foreground shadow hover:bg-ai-accent/90",
|
|
1414
1421
|
destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
|
1415
1422
|
outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
|
|
1416
1423
|
secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
|
|
@@ -1453,6 +1460,748 @@ var HoverCardContent = React.forwardRef(({ className, align = "center", sideOffs
|
|
|
1453
1460
|
}
|
|
1454
1461
|
) }));
|
|
1455
1462
|
HoverCardContent.displayName = HoverCardPrimitive.Content.displayName;
|
|
1463
|
+
function Card({ className, ...props }) {
|
|
1464
|
+
return /* @__PURE__ */ jsx(
|
|
1465
|
+
"div",
|
|
1466
|
+
{
|
|
1467
|
+
"data-slot": "card",
|
|
1468
|
+
className: cn(
|
|
1469
|
+
"rounded-xl border border-border bg-card text-card-foreground shadow-sm",
|
|
1470
|
+
className
|
|
1471
|
+
),
|
|
1472
|
+
...props
|
|
1473
|
+
}
|
|
1474
|
+
);
|
|
1475
|
+
}
|
|
1476
|
+
function CardHeader({ className, ...props }) {
|
|
1477
|
+
return /* @__PURE__ */ jsx(
|
|
1478
|
+
"div",
|
|
1479
|
+
{
|
|
1480
|
+
"data-slot": "card-header",
|
|
1481
|
+
className: cn("flex flex-col gap-1.5 p-6", className),
|
|
1482
|
+
...props
|
|
1483
|
+
}
|
|
1484
|
+
);
|
|
1485
|
+
}
|
|
1486
|
+
function CardTitle({ className, ...props }) {
|
|
1487
|
+
return /* @__PURE__ */ jsx(
|
|
1488
|
+
"div",
|
|
1489
|
+
{
|
|
1490
|
+
"data-slot": "card-title",
|
|
1491
|
+
className: cn("text-lg font-semibold leading-none tracking-tight", className),
|
|
1492
|
+
...props
|
|
1493
|
+
}
|
|
1494
|
+
);
|
|
1495
|
+
}
|
|
1496
|
+
function CardDescription({ className, ...props }) {
|
|
1497
|
+
return /* @__PURE__ */ jsx(
|
|
1498
|
+
"div",
|
|
1499
|
+
{
|
|
1500
|
+
"data-slot": "card-description",
|
|
1501
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
1502
|
+
...props
|
|
1503
|
+
}
|
|
1504
|
+
);
|
|
1505
|
+
}
|
|
1506
|
+
function CardContent({ className, ...props }) {
|
|
1507
|
+
return /* @__PURE__ */ jsx("div", { "data-slot": "card-content", className: cn("p-6 pt-0", className), ...props });
|
|
1508
|
+
}
|
|
1509
|
+
function CardFooter({ className, ...props }) {
|
|
1510
|
+
return /* @__PURE__ */ jsx(
|
|
1511
|
+
"div",
|
|
1512
|
+
{
|
|
1513
|
+
"data-slot": "card-footer",
|
|
1514
|
+
className: cn("flex items-center p-6 pt-0", className),
|
|
1515
|
+
...props
|
|
1516
|
+
}
|
|
1517
|
+
);
|
|
1518
|
+
}
|
|
1519
|
+
function Input({ className, type, ...props }) {
|
|
1520
|
+
return /* @__PURE__ */ jsx(
|
|
1521
|
+
"input",
|
|
1522
|
+
{
|
|
1523
|
+
type,
|
|
1524
|
+
"data-slot": "input",
|
|
1525
|
+
className: cn(
|
|
1526
|
+
"flex h-9 w-full rounded-md border border-input bg-card px-3 py-1 text-sm shadow-sm transition-colors",
|
|
1527
|
+
"placeholder:text-muted-foreground/70",
|
|
1528
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:border-ring/60",
|
|
1529
|
+
"disabled:cursor-not-allowed disabled:opacity-50 file:border-0 file:bg-transparent file:text-sm file:font-medium",
|
|
1530
|
+
className
|
|
1531
|
+
),
|
|
1532
|
+
...props
|
|
1533
|
+
}
|
|
1534
|
+
);
|
|
1535
|
+
}
|
|
1536
|
+
function useWorkspaceDocs(workspaceId) {
|
|
1537
|
+
const { data: docs = [], isLoading, isError } = useDocuments(workspaceId);
|
|
1538
|
+
const docIds = useMemo(
|
|
1539
|
+
() => docs.map((d) => d.external_id).filter((id) => !!id),
|
|
1540
|
+
[docs]
|
|
1541
|
+
);
|
|
1542
|
+
return { wsId: workspaceId, docs, docIds, isLoading, isError, ready: docIds.length > 0 };
|
|
1543
|
+
}
|
|
1544
|
+
function useAiTask() {
|
|
1545
|
+
const mutation = useAssistantQuery();
|
|
1546
|
+
const [status, setStatus] = useState("idle");
|
|
1547
|
+
const [text, setText] = useState("");
|
|
1548
|
+
const [stepCount, setStepCount] = useState(0);
|
|
1549
|
+
const [error, setError] = useState(null);
|
|
1550
|
+
const [responseId, setResponseId] = useState(null);
|
|
1551
|
+
const [artifacts, setArtifacts] = useState([]);
|
|
1552
|
+
const bufferRef = useRef("");
|
|
1553
|
+
const artifactsRef = useRef(/* @__PURE__ */ new Map());
|
|
1554
|
+
const reset = useCallback(() => {
|
|
1555
|
+
setStatus("idle");
|
|
1556
|
+
setText("");
|
|
1557
|
+
setStepCount(0);
|
|
1558
|
+
setError(null);
|
|
1559
|
+
setResponseId(null);
|
|
1560
|
+
setArtifacts([]);
|
|
1561
|
+
artifactsRef.current = /* @__PURE__ */ new Map();
|
|
1562
|
+
bufferRef.current = "";
|
|
1563
|
+
}, []);
|
|
1564
|
+
const run = useCallback(
|
|
1565
|
+
async (question, docIds, opts) => {
|
|
1566
|
+
setStatus("running");
|
|
1567
|
+
setText("");
|
|
1568
|
+
setStepCount(0);
|
|
1569
|
+
setError(null);
|
|
1570
|
+
setArtifacts([]);
|
|
1571
|
+
artifactsRef.current = /* @__PURE__ */ new Map();
|
|
1572
|
+
bufferRef.current = "";
|
|
1573
|
+
let streamError = null;
|
|
1574
|
+
try {
|
|
1575
|
+
const result = await mutation.mutateAsync({
|
|
1576
|
+
question,
|
|
1577
|
+
docIds,
|
|
1578
|
+
previousResponseId: opts?.previousResponseId ?? void 0,
|
|
1579
|
+
model: opts?.model,
|
|
1580
|
+
onToken: (c) => {
|
|
1581
|
+
bufferRef.current += c;
|
|
1582
|
+
setText(bufferRef.current);
|
|
1583
|
+
},
|
|
1584
|
+
onAgentStep: () => setStepCount((n) => n + 1),
|
|
1585
|
+
onArtifact: (a) => {
|
|
1586
|
+
artifactsRef.current.set(a.doc_ext_id, a);
|
|
1587
|
+
setArtifacts([...artifactsRef.current.values()]);
|
|
1588
|
+
},
|
|
1589
|
+
onError: (m) => {
|
|
1590
|
+
streamError = m;
|
|
1591
|
+
}
|
|
1592
|
+
});
|
|
1593
|
+
const finalText = result.text || bufferRef.current;
|
|
1594
|
+
setText(finalText);
|
|
1595
|
+
setResponseId(result.assistantMessageExtId);
|
|
1596
|
+
setStepCount(result.agentSteps.length || 0);
|
|
1597
|
+
if (result.artifacts?.length) {
|
|
1598
|
+
for (const a of result.artifacts) artifactsRef.current.set(a.doc_ext_id, a);
|
|
1599
|
+
setArtifacts([...artifactsRef.current.values()]);
|
|
1600
|
+
}
|
|
1601
|
+
const err = streamError || result.errors[0] || null;
|
|
1602
|
+
if (err && !finalText) {
|
|
1603
|
+
setError(err);
|
|
1604
|
+
setStatus("error");
|
|
1605
|
+
} else {
|
|
1606
|
+
setStatus("done");
|
|
1607
|
+
}
|
|
1608
|
+
return result;
|
|
1609
|
+
} catch (e) {
|
|
1610
|
+
setError(e instanceof Error ? e.message : "The assistant request failed.");
|
|
1611
|
+
setStatus("error");
|
|
1612
|
+
return null;
|
|
1613
|
+
}
|
|
1614
|
+
},
|
|
1615
|
+
[mutation]
|
|
1616
|
+
);
|
|
1617
|
+
return {
|
|
1618
|
+
status,
|
|
1619
|
+
text,
|
|
1620
|
+
stepCount,
|
|
1621
|
+
error,
|
|
1622
|
+
responseId,
|
|
1623
|
+
artifacts,
|
|
1624
|
+
run,
|
|
1625
|
+
reset,
|
|
1626
|
+
isRunning: status === "running",
|
|
1627
|
+
isDone: status === "done"
|
|
1628
|
+
};
|
|
1629
|
+
}
|
|
1630
|
+
function useSemanticSearch(docIds) {
|
|
1631
|
+
const arbi = useArbi();
|
|
1632
|
+
const [results, setResults] = useState([]);
|
|
1633
|
+
const [status, setStatus] = useState("idle");
|
|
1634
|
+
const [error, setError] = useState(null);
|
|
1635
|
+
const [query, setQuery] = useState("");
|
|
1636
|
+
const search = useCallback(
|
|
1637
|
+
async (q, mode = "hybrid") => {
|
|
1638
|
+
const trimmed = q.trim();
|
|
1639
|
+
setQuery(trimmed);
|
|
1640
|
+
if (!trimmed || docIds.length === 0) {
|
|
1641
|
+
setResults([]);
|
|
1642
|
+
setStatus("idle");
|
|
1643
|
+
return;
|
|
1644
|
+
}
|
|
1645
|
+
setStatus("running");
|
|
1646
|
+
setError(null);
|
|
1647
|
+
try {
|
|
1648
|
+
const res = await arbi.assistant.retrieve(trimmed, docIds, { searchMode: mode });
|
|
1649
|
+
const byTool = res.retrieval_chunk?.tool_responses ?? {};
|
|
1650
|
+
const chunks = Object.values(byTool).flat().map(
|
|
1651
|
+
(c) => ({
|
|
1652
|
+
docId: c.metadata.doc_ext_id,
|
|
1653
|
+
docTitle: c.metadata.doc_title,
|
|
1654
|
+
page: c.metadata.page_number,
|
|
1655
|
+
score: c.metadata.rerank_score ?? c.metadata.score,
|
|
1656
|
+
content: c.content
|
|
1657
|
+
})
|
|
1658
|
+
).sort((a, b) => (b.score ?? 0) - (a.score ?? 0));
|
|
1659
|
+
setResults(chunks);
|
|
1660
|
+
setStatus("done");
|
|
1661
|
+
} catch (e) {
|
|
1662
|
+
setError(e instanceof Error ? e.message : "Search failed.");
|
|
1663
|
+
setStatus("error");
|
|
1664
|
+
}
|
|
1665
|
+
},
|
|
1666
|
+
[arbi, docIds]
|
|
1667
|
+
);
|
|
1668
|
+
return { query, results, status, error, search, isRunning: status === "running" };
|
|
1669
|
+
}
|
|
1670
|
+
function toRedlineMarkdown(original, revised) {
|
|
1671
|
+
const parts = diffWords(original ?? "", revised ?? "");
|
|
1672
|
+
return parts.map((p) => {
|
|
1673
|
+
if (p.added) return `<ins>${p.value}</ins>`;
|
|
1674
|
+
if (p.removed) return `<del>${p.value}</del>`;
|
|
1675
|
+
return p.value;
|
|
1676
|
+
}).join("");
|
|
1677
|
+
}
|
|
1678
|
+
function redlineStats(original, revised) {
|
|
1679
|
+
let added = 0;
|
|
1680
|
+
let removed = 0;
|
|
1681
|
+
for (const p of diffWords(original ?? "", revised ?? "")) {
|
|
1682
|
+
const words = p.value.trim() ? p.value.trim().split(/\s+/).length : 0;
|
|
1683
|
+
if (p.added) added += words;
|
|
1684
|
+
else if (p.removed) removed += words;
|
|
1685
|
+
}
|
|
1686
|
+
return { added, removed };
|
|
1687
|
+
}
|
|
1688
|
+
function textToArtifact(title, content, opts) {
|
|
1689
|
+
return {
|
|
1690
|
+
type: "arbi.artifact",
|
|
1691
|
+
doc_ext_id: opts?.id ?? `local-${title.replace(/\W+/g, "-").toLowerCase()}`,
|
|
1692
|
+
title,
|
|
1693
|
+
mode: opts?.mode ?? "markdown",
|
|
1694
|
+
content,
|
|
1695
|
+
is_complete: opts?.isComplete ?? true,
|
|
1696
|
+
version: opts?.version ?? 1,
|
|
1697
|
+
message_ext_id: null,
|
|
1698
|
+
t: null
|
|
1699
|
+
};
|
|
1700
|
+
}
|
|
1701
|
+
function AiMarkdown({ children, className }) {
|
|
1702
|
+
return /* @__PURE__ */ jsx(
|
|
1703
|
+
"div",
|
|
1704
|
+
{
|
|
1705
|
+
className: cn("text-sm leading-relaxed text-foreground", className),
|
|
1706
|
+
"data-testid": "ai-markdown",
|
|
1707
|
+
children: /* @__PURE__ */ jsx(
|
|
1708
|
+
ReactMarkdown,
|
|
1709
|
+
{
|
|
1710
|
+
remarkPlugins: [remarkGfm],
|
|
1711
|
+
rehypePlugins: [rehypeRaw],
|
|
1712
|
+
components: {
|
|
1713
|
+
h1: (p) => /* @__PURE__ */ jsx("h1", { className: "mb-2 mt-4 text-lg font-semibold text-foreground first:mt-0", ...p }),
|
|
1714
|
+
h2: (p) => /* @__PURE__ */ jsx("h2", { className: "mb-2 mt-4 text-base font-semibold text-foreground first:mt-0", ...p }),
|
|
1715
|
+
h3: (p) => /* @__PURE__ */ jsx("h3", { className: "mb-1.5 mt-3 text-sm font-semibold text-foreground first:mt-0", ...p }),
|
|
1716
|
+
p: (p) => /* @__PURE__ */ jsx("p", { className: "mb-3 last:mb-0", ...p }),
|
|
1717
|
+
ul: (p) => /* @__PURE__ */ jsx("ul", { className: "mb-3 list-disc space-y-1 pl-5 last:mb-0", ...p }),
|
|
1718
|
+
ol: (p) => /* @__PURE__ */ jsx("ol", { className: "mb-3 list-decimal space-y-1 pl-5 last:mb-0", ...p }),
|
|
1719
|
+
li: (p) => /* @__PURE__ */ jsx("li", { className: "pl-1", ...p }),
|
|
1720
|
+
strong: (p) => /* @__PURE__ */ jsx("strong", { className: "font-semibold text-foreground", ...p }),
|
|
1721
|
+
a: (p) => /* @__PURE__ */ jsx("a", { className: "text-ai-accent underline underline-offset-2", ...p }),
|
|
1722
|
+
// Redline marks: deletions in red strike, <ins>/<mark> additions accented.
|
|
1723
|
+
del: (p) => /* @__PURE__ */ jsx(
|
|
1724
|
+
"del",
|
|
1725
|
+
{
|
|
1726
|
+
className: "rounded bg-destructive/10 text-destructive decoration-destructive/60",
|
|
1727
|
+
...p
|
|
1728
|
+
}
|
|
1729
|
+
),
|
|
1730
|
+
ins: (p) => /* @__PURE__ */ jsx("ins", { className: "rounded bg-ai-accent-soft px-0.5 text-ai-accent no-underline", ...p }),
|
|
1731
|
+
mark: (p) => /* @__PURE__ */ jsx("mark", { className: "rounded bg-ai-accent-soft px-0.5 text-ai-accent", ...p }),
|
|
1732
|
+
code: (p) => /* @__PURE__ */ jsx("code", { className: "rounded bg-secondary px-1 py-0.5 font-mono text-[0.8em]", ...p }),
|
|
1733
|
+
blockquote: (p) => /* @__PURE__ */ jsx(
|
|
1734
|
+
"blockquote",
|
|
1735
|
+
{
|
|
1736
|
+
className: "my-3 border-l-2 border-ai-accent/40 pl-3 italic text-muted-foreground",
|
|
1737
|
+
...p
|
|
1738
|
+
}
|
|
1739
|
+
),
|
|
1740
|
+
table: (p) => /* @__PURE__ */ jsx("div", { className: "my-3 overflow-x-auto rounded-lg border border-border", children: /* @__PURE__ */ jsx("table", { className: "w-full border-collapse text-xs", ...p }) }),
|
|
1741
|
+
thead: (p) => /* @__PURE__ */ jsx("thead", { className: "bg-secondary/60", ...p }),
|
|
1742
|
+
th: (p) => /* @__PURE__ */ jsx(
|
|
1743
|
+
"th",
|
|
1744
|
+
{
|
|
1745
|
+
className: "border-b border-border px-3 py-2 text-left font-semibold text-foreground",
|
|
1746
|
+
...p
|
|
1747
|
+
}
|
|
1748
|
+
),
|
|
1749
|
+
td: (p) => /* @__PURE__ */ jsx(
|
|
1750
|
+
"td",
|
|
1751
|
+
{
|
|
1752
|
+
className: "border-b border-border px-3 py-2 align-top text-muted-foreground",
|
|
1753
|
+
...p
|
|
1754
|
+
}
|
|
1755
|
+
)
|
|
1756
|
+
},
|
|
1757
|
+
children
|
|
1758
|
+
}
|
|
1759
|
+
)
|
|
1760
|
+
}
|
|
1761
|
+
);
|
|
1762
|
+
}
|
|
1763
|
+
function AiAnswer({
|
|
1764
|
+
status,
|
|
1765
|
+
text,
|
|
1766
|
+
stepCount,
|
|
1767
|
+
error,
|
|
1768
|
+
className,
|
|
1769
|
+
emptyHint,
|
|
1770
|
+
groundedNote = "Grounded in the live workspace \xB7 verify citations before relying on it",
|
|
1771
|
+
runningHint = "Reading the documents\u2026",
|
|
1772
|
+
testId = "ai-answer"
|
|
1773
|
+
}) {
|
|
1774
|
+
const [copied, setCopied] = useState(false);
|
|
1775
|
+
const running = status === "running";
|
|
1776
|
+
const hasText = text.trim().length > 0;
|
|
1777
|
+
const copy = async () => {
|
|
1778
|
+
await navigator.clipboard.writeText(text);
|
|
1779
|
+
setCopied(true);
|
|
1780
|
+
setTimeout(() => setCopied(false), 1600);
|
|
1781
|
+
};
|
|
1782
|
+
if (status === "idle" && !hasText) {
|
|
1783
|
+
return emptyHint ? /* @__PURE__ */ jsx("p", { className: cn("text-sm text-muted-foreground", className), "data-testid": `${testId}-empty`, children: emptyHint }) : null;
|
|
1784
|
+
}
|
|
1785
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-3", className), "data-testid": testId, "data-status": status, children: [
|
|
1786
|
+
running && /* @__PURE__ */ jsxs(
|
|
1787
|
+
"div",
|
|
1788
|
+
{
|
|
1789
|
+
className: "flex items-center gap-2 text-xs font-medium text-ai-accent",
|
|
1790
|
+
"data-testid": `${testId}-thinking`,
|
|
1791
|
+
children: [
|
|
1792
|
+
/* @__PURE__ */ jsx(Loader2, { className: "size-3.5 animate-spin" }),
|
|
1793
|
+
stepCount && stepCount > 0 ? `Working \u2014 ${stepCount} step${stepCount === 1 ? "" : "s"}\u2026` : "Thinking\u2026"
|
|
1794
|
+
]
|
|
1795
|
+
}
|
|
1796
|
+
),
|
|
1797
|
+
status === "error" && !hasText && /* @__PURE__ */ jsxs(
|
|
1798
|
+
"div",
|
|
1799
|
+
{
|
|
1800
|
+
className: "flex items-start gap-2 rounded-lg border border-destructive/30 bg-destructive/5 p-3 text-sm text-destructive",
|
|
1801
|
+
"data-testid": `${testId}-error`,
|
|
1802
|
+
children: [
|
|
1803
|
+
/* @__PURE__ */ jsx(AlertTriangle, { className: "mt-0.5 size-4 shrink-0" }),
|
|
1804
|
+
/* @__PURE__ */ jsx("span", { children: error ?? "The assistant request failed." })
|
|
1805
|
+
]
|
|
1806
|
+
}
|
|
1807
|
+
),
|
|
1808
|
+
hasText && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1809
|
+
/* @__PURE__ */ jsx(AiMarkdown, { children: text }),
|
|
1810
|
+
!running && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-t border-border pt-2.5", children: [
|
|
1811
|
+
/* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 text-xs text-muted-foreground", children: [
|
|
1812
|
+
/* @__PURE__ */ jsx(ShieldCheck, { className: "size-3.5 text-ai-accent" }),
|
|
1813
|
+
groundedNote
|
|
1814
|
+
] }),
|
|
1815
|
+
/* @__PURE__ */ jsxs(
|
|
1816
|
+
"button",
|
|
1817
|
+
{
|
|
1818
|
+
type: "button",
|
|
1819
|
+
onClick: copy,
|
|
1820
|
+
className: "inline-flex items-center gap-1 text-xs font-medium text-muted-foreground hover:text-foreground",
|
|
1821
|
+
"data-testid": `${testId}-copy`,
|
|
1822
|
+
children: [
|
|
1823
|
+
copied ? /* @__PURE__ */ jsx(Check, { className: "size-3.5 text-ai-accent" }) : /* @__PURE__ */ jsx(Copy, { className: "size-3.5" }),
|
|
1824
|
+
copied ? "Copied" : "Copy"
|
|
1825
|
+
]
|
|
1826
|
+
}
|
|
1827
|
+
)
|
|
1828
|
+
] })
|
|
1829
|
+
] }),
|
|
1830
|
+
running && !hasText && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-sm text-muted-foreground", children: [
|
|
1831
|
+
/* @__PURE__ */ jsx(Sparkles, { className: "size-4 animate-pulse text-ai-accent" }),
|
|
1832
|
+
" ",
|
|
1833
|
+
runningHint
|
|
1834
|
+
] })
|
|
1835
|
+
] });
|
|
1836
|
+
}
|
|
1837
|
+
function AiActionCard({
|
|
1838
|
+
icon: Icon = Sparkles,
|
|
1839
|
+
title,
|
|
1840
|
+
description,
|
|
1841
|
+
prompt,
|
|
1842
|
+
docIds,
|
|
1843
|
+
runLabel = "Run",
|
|
1844
|
+
noDocsHint = "Connect to the workspace to run this.",
|
|
1845
|
+
disabled,
|
|
1846
|
+
testId
|
|
1847
|
+
}) {
|
|
1848
|
+
const task = useAiTask();
|
|
1849
|
+
const noDocs = docIds.length === 0;
|
|
1850
|
+
const onRun = () => {
|
|
1851
|
+
const p = typeof prompt === "function" ? prompt() : prompt;
|
|
1852
|
+
void task.run(p, docIds);
|
|
1853
|
+
};
|
|
1854
|
+
return /* @__PURE__ */ jsxs(Card, { className: "p-5", "data-testid": testId, children: [
|
|
1855
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-4", children: [
|
|
1856
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
|
|
1857
|
+
/* @__PURE__ */ jsx("div", { className: "flex size-9 shrink-0 items-center justify-center rounded-lg bg-ai-accent-soft text-ai-accent", children: /* @__PURE__ */ jsx(Icon, { className: "size-4" }) }),
|
|
1858
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
1859
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-foreground", children: title }),
|
|
1860
|
+
/* @__PURE__ */ jsx("p", { className: "mt-0.5 text-xs leading-relaxed text-muted-foreground", children: description })
|
|
1861
|
+
] })
|
|
1862
|
+
] }),
|
|
1863
|
+
/* @__PURE__ */ jsxs(
|
|
1864
|
+
Button,
|
|
1865
|
+
{
|
|
1866
|
+
variant: task.isDone ? "outline" : "accent",
|
|
1867
|
+
size: "sm",
|
|
1868
|
+
onClick: onRun,
|
|
1869
|
+
disabled: disabled || noDocs || task.isRunning,
|
|
1870
|
+
"data-testid": testId && `${testId}-run`,
|
|
1871
|
+
children: [
|
|
1872
|
+
/* @__PURE__ */ jsx(Sparkles, { className: "size-3.5" }),
|
|
1873
|
+
task.isRunning ? "Running\u2026" : task.isDone ? "Re-run" : runLabel
|
|
1874
|
+
]
|
|
1875
|
+
}
|
|
1876
|
+
)
|
|
1877
|
+
] }),
|
|
1878
|
+
(task.status !== "idle" || noDocs) && /* @__PURE__ */ jsx("div", { className: "mt-4", children: noDocs ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: noDocsHint }) : /* @__PURE__ */ jsx(
|
|
1879
|
+
AiAnswer,
|
|
1880
|
+
{
|
|
1881
|
+
status: task.status,
|
|
1882
|
+
text: task.text,
|
|
1883
|
+
stepCount: task.stepCount,
|
|
1884
|
+
error: task.error,
|
|
1885
|
+
testId: testId && `${testId}-answer`
|
|
1886
|
+
}
|
|
1887
|
+
) })
|
|
1888
|
+
] });
|
|
1889
|
+
}
|
|
1890
|
+
function ArtifactCanvas({
|
|
1891
|
+
artifacts,
|
|
1892
|
+
className,
|
|
1893
|
+
emptyHint = "Draft artifacts produced by the agent will open here.",
|
|
1894
|
+
busy = false,
|
|
1895
|
+
busyHint = "The agent is working through the documents\u2026",
|
|
1896
|
+
stepCount,
|
|
1897
|
+
error = null
|
|
1898
|
+
}) {
|
|
1899
|
+
const [activeId, setActiveId] = useState(null);
|
|
1900
|
+
const [copied, setCopied] = useState(false);
|
|
1901
|
+
useEffect(() => {
|
|
1902
|
+
if (artifacts.length && (!activeId || !artifacts.some((a) => a.doc_ext_id === activeId))) {
|
|
1903
|
+
setActiveId(artifacts[artifacts.length - 1].doc_ext_id);
|
|
1904
|
+
}
|
|
1905
|
+
}, [artifacts, activeId]);
|
|
1906
|
+
if (artifacts.length === 0) {
|
|
1907
|
+
if (error && !busy) {
|
|
1908
|
+
return /* @__PURE__ */ jsxs(
|
|
1909
|
+
"div",
|
|
1910
|
+
{
|
|
1911
|
+
className: cn(
|
|
1912
|
+
"flex h-full min-h-[280px] flex-col items-center justify-center rounded-xl border border-destructive/30 bg-destructive/5 p-8 text-center",
|
|
1913
|
+
className
|
|
1914
|
+
),
|
|
1915
|
+
"data-testid": "artifact-canvas-error",
|
|
1916
|
+
children: [
|
|
1917
|
+
/* @__PURE__ */ jsx(AlertTriangle, { className: "size-8 text-destructive/70" }),
|
|
1918
|
+
/* @__PURE__ */ jsx("p", { className: "mt-3 max-w-md text-sm text-foreground", children: error })
|
|
1919
|
+
]
|
|
1920
|
+
}
|
|
1921
|
+
);
|
|
1922
|
+
}
|
|
1923
|
+
if (busy) {
|
|
1924
|
+
return /* @__PURE__ */ jsxs(
|
|
1925
|
+
"div",
|
|
1926
|
+
{
|
|
1927
|
+
className: cn(
|
|
1928
|
+
"flex h-full min-h-[280px] flex-col items-center justify-center rounded-xl border border-border bg-ai-surface/40 p-8 text-center",
|
|
1929
|
+
className
|
|
1930
|
+
),
|
|
1931
|
+
"data-testid": "artifact-canvas-busy",
|
|
1932
|
+
children: [
|
|
1933
|
+
/* @__PURE__ */ jsx(Loader2, { className: "size-8 animate-spin text-ai-accent" }),
|
|
1934
|
+
/* @__PURE__ */ jsx("p", { className: "mt-4 max-w-xs text-sm font-medium text-foreground", children: busyHint }),
|
|
1935
|
+
typeof stepCount === "number" && stepCount > 0 && /* @__PURE__ */ jsxs("p", { className: "mt-1 text-xs text-muted-foreground", "data-testid": "artifact-canvas-steps", children: [
|
|
1936
|
+
stepCount,
|
|
1937
|
+
" ",
|
|
1938
|
+
stepCount === 1 ? "step" : "steps",
|
|
1939
|
+
" so far"
|
|
1940
|
+
] })
|
|
1941
|
+
]
|
|
1942
|
+
}
|
|
1943
|
+
);
|
|
1944
|
+
}
|
|
1945
|
+
return /* @__PURE__ */ jsxs(
|
|
1946
|
+
"div",
|
|
1947
|
+
{
|
|
1948
|
+
className: cn(
|
|
1949
|
+
"flex h-full min-h-[280px] flex-col items-center justify-center rounded-xl border border-dashed border-border bg-secondary/30 p-8 text-center",
|
|
1950
|
+
className
|
|
1951
|
+
),
|
|
1952
|
+
"data-testid": "artifact-canvas-empty",
|
|
1953
|
+
children: [
|
|
1954
|
+
/* @__PURE__ */ jsx(FileText, { className: "size-8 text-muted-foreground/50" }),
|
|
1955
|
+
/* @__PURE__ */ jsx("p", { className: "mt-3 max-w-xs text-sm text-muted-foreground", children: emptyHint })
|
|
1956
|
+
]
|
|
1957
|
+
}
|
|
1958
|
+
);
|
|
1959
|
+
}
|
|
1960
|
+
const active = artifacts.find((a) => a.doc_ext_id === activeId) ?? artifacts[artifacts.length - 1];
|
|
1961
|
+
const isRedline = /~~|<ins|<del|<mark/i.test(active.content);
|
|
1962
|
+
const copy = async () => {
|
|
1963
|
+
await navigator.clipboard.writeText(active.content);
|
|
1964
|
+
setCopied(true);
|
|
1965
|
+
setTimeout(() => setCopied(false), 1600);
|
|
1966
|
+
};
|
|
1967
|
+
const download = () => {
|
|
1968
|
+
const ext = active.mode === "html" ? "html" : active.mode === "text" ? "txt" : "md";
|
|
1969
|
+
const blob = new Blob([active.content], { type: "text/plain" });
|
|
1970
|
+
const url = URL.createObjectURL(blob);
|
|
1971
|
+
const a = document.createElement("a");
|
|
1972
|
+
a.href = url;
|
|
1973
|
+
a.download = `${active.title.replace(/[^\w.-]+/g, "_") || "artifact"}.${ext}`;
|
|
1974
|
+
a.click();
|
|
1975
|
+
URL.revokeObjectURL(url);
|
|
1976
|
+
};
|
|
1977
|
+
return /* @__PURE__ */ jsxs(
|
|
1978
|
+
"div",
|
|
1979
|
+
{
|
|
1980
|
+
className: cn(
|
|
1981
|
+
"flex h-full flex-col overflow-hidden rounded-xl border border-border bg-card",
|
|
1982
|
+
className
|
|
1983
|
+
),
|
|
1984
|
+
"data-testid": "artifact-canvas",
|
|
1985
|
+
children: [
|
|
1986
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border-b border-border bg-secondary/40 px-4 py-2.5", children: [
|
|
1987
|
+
/* @__PURE__ */ jsx(FileText, { className: "size-4 shrink-0 text-ai-accent" }),
|
|
1988
|
+
/* @__PURE__ */ jsx(
|
|
1989
|
+
"span",
|
|
1990
|
+
{
|
|
1991
|
+
className: "min-w-0 flex-1 truncate text-sm font-medium text-foreground",
|
|
1992
|
+
"data-testid": "artifact-title",
|
|
1993
|
+
children: active.title
|
|
1994
|
+
}
|
|
1995
|
+
),
|
|
1996
|
+
isRedline && /* @__PURE__ */ jsxs(Badge, { variant: "accent", className: "gap-1", children: [
|
|
1997
|
+
/* @__PURE__ */ jsx(GitCompareArrows, { className: "size-3" }),
|
|
1998
|
+
" Redline"
|
|
1999
|
+
] }),
|
|
2000
|
+
/* @__PURE__ */ jsxs(Badge, { variant: "secondary", children: [
|
|
2001
|
+
"v",
|
|
2002
|
+
active.version
|
|
2003
|
+
] }),
|
|
2004
|
+
!active.is_complete ? /* @__PURE__ */ jsxs(
|
|
2005
|
+
"span",
|
|
2006
|
+
{
|
|
2007
|
+
className: "inline-flex items-center gap-1 text-xs text-ai-accent",
|
|
2008
|
+
"data-testid": "artifact-streaming",
|
|
2009
|
+
children: [
|
|
2010
|
+
/* @__PURE__ */ jsx(Loader2, { className: "size-3 animate-spin" }),
|
|
2011
|
+
" drafting"
|
|
2012
|
+
]
|
|
2013
|
+
}
|
|
2014
|
+
) : /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
2015
|
+
/* @__PURE__ */ jsx(
|
|
2016
|
+
"button",
|
|
2017
|
+
{
|
|
2018
|
+
onClick: copy,
|
|
2019
|
+
className: "rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
2020
|
+
title: "Copy",
|
|
2021
|
+
"data-testid": "artifact-copy",
|
|
2022
|
+
children: copied ? /* @__PURE__ */ jsx(Check, { className: "size-3.5 text-ai-accent" }) : /* @__PURE__ */ jsx(Copy, { className: "size-3.5" })
|
|
2023
|
+
}
|
|
2024
|
+
),
|
|
2025
|
+
/* @__PURE__ */ jsx(
|
|
2026
|
+
"button",
|
|
2027
|
+
{
|
|
2028
|
+
onClick: download,
|
|
2029
|
+
className: "rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
2030
|
+
title: "Download",
|
|
2031
|
+
"data-testid": "artifact-download",
|
|
2032
|
+
children: /* @__PURE__ */ jsx(Download, { className: "size-3.5" })
|
|
2033
|
+
}
|
|
2034
|
+
)
|
|
2035
|
+
] })
|
|
2036
|
+
] }),
|
|
2037
|
+
artifacts.length > 1 && /* @__PURE__ */ jsx("div", { className: "flex gap-1 overflow-x-auto border-b border-border bg-card px-2 py-1.5", children: artifacts.map((a) => /* @__PURE__ */ jsx(
|
|
2038
|
+
"button",
|
|
2039
|
+
{
|
|
2040
|
+
onClick: () => setActiveId(a.doc_ext_id),
|
|
2041
|
+
className: cn(
|
|
2042
|
+
"shrink-0 rounded-md px-2.5 py-1 text-xs font-medium",
|
|
2043
|
+
a.doc_ext_id === active.doc_ext_id ? "bg-ai-accent-soft text-ai-accent" : "text-muted-foreground hover:bg-accent"
|
|
2044
|
+
),
|
|
2045
|
+
children: a.title.slice(0, 28)
|
|
2046
|
+
},
|
|
2047
|
+
a.doc_ext_id
|
|
2048
|
+
)) }),
|
|
2049
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto bg-ai-surface/40 p-6", children: /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsx(
|
|
2050
|
+
motion.div,
|
|
2051
|
+
{
|
|
2052
|
+
initial: { opacity: 0, y: 6 },
|
|
2053
|
+
animate: { opacity: 1, y: 0 },
|
|
2054
|
+
transition: { duration: 0.2 },
|
|
2055
|
+
className: "mx-auto max-w-2xl rounded-lg bg-card p-8 shadow-sm ring-1 ring-border",
|
|
2056
|
+
children: active.mode === "html" ? /* @__PURE__ */ jsx("div", { className: "text-sm", dangerouslySetInnerHTML: { __html: active.content } }) : active.mode === "text" ? /* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap font-mono text-xs text-foreground", children: active.content }) : /* @__PURE__ */ jsx(AiMarkdown, { children: active.content })
|
|
2057
|
+
},
|
|
2058
|
+
active.doc_ext_id
|
|
2059
|
+
) }) })
|
|
2060
|
+
]
|
|
2061
|
+
}
|
|
2062
|
+
);
|
|
2063
|
+
}
|
|
2064
|
+
function DocSearch({
|
|
2065
|
+
docIds,
|
|
2066
|
+
onOpenDoc,
|
|
2067
|
+
placeholder = "Semantic search across your documents\u2026",
|
|
2068
|
+
className
|
|
2069
|
+
}) {
|
|
2070
|
+
const { results, status, error, search, isRunning, query } = useSemanticSearch(docIds);
|
|
2071
|
+
const [value, setValue] = useState("");
|
|
2072
|
+
const submit = () => {
|
|
2073
|
+
if (value.trim()) void search(value, "hybrid");
|
|
2074
|
+
};
|
|
2075
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-3", className), "data-testid": "doc-search", children: [
|
|
2076
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
2077
|
+
/* @__PURE__ */ jsx(Search, { className: "pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" }),
|
|
2078
|
+
isRunning && /* @__PURE__ */ jsx(Loader2, { className: "absolute right-3 top-1/2 size-4 -translate-y-1/2 animate-spin text-ai-accent" }),
|
|
2079
|
+
/* @__PURE__ */ jsx(
|
|
2080
|
+
"input",
|
|
2081
|
+
{
|
|
2082
|
+
value,
|
|
2083
|
+
onChange: (e) => setValue(e.target.value),
|
|
2084
|
+
onKeyDown: (e) => e.key === "Enter" && (e.preventDefault(), submit()),
|
|
2085
|
+
placeholder,
|
|
2086
|
+
className: "h-11 w-full rounded-lg border border-input bg-background pl-9 pr-24 text-sm outline-none focus:border-ai-accent/50 focus:ring-2 focus:ring-ai-accent/15",
|
|
2087
|
+
"data-testid": "doc-search-input"
|
|
2088
|
+
}
|
|
2089
|
+
),
|
|
2090
|
+
/* @__PURE__ */ jsxs(
|
|
2091
|
+
"button",
|
|
2092
|
+
{
|
|
2093
|
+
type: "button",
|
|
2094
|
+
onClick: submit,
|
|
2095
|
+
className: "absolute right-2 top-1/2 flex -translate-y-1/2 items-center gap-1 rounded-md bg-ai-accent px-2.5 py-1 text-xs font-medium text-ai-accent-foreground",
|
|
2096
|
+
"data-testid": "doc-search-submit",
|
|
2097
|
+
children: [
|
|
2098
|
+
"Search ",
|
|
2099
|
+
/* @__PURE__ */ jsx(CornerDownLeft, { className: "size-3" })
|
|
2100
|
+
]
|
|
2101
|
+
}
|
|
2102
|
+
)
|
|
2103
|
+
] }),
|
|
2104
|
+
status === "error" && /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", "data-testid": "doc-search-error", children: error }),
|
|
2105
|
+
status === "done" && /* @__PURE__ */ jsxs("div", { className: "space-y-2", "data-testid": "doc-search-results", children: [
|
|
2106
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: results.length === 0 ? `No passages matched \u201C${query}\u201D.` : `${results.length} passage${results.length === 1 ? "" : "s"} for \u201C${query}\u201D` }),
|
|
2107
|
+
results.slice(0, 8).map((r, i) => /* @__PURE__ */ jsxs(
|
|
2108
|
+
Card,
|
|
2109
|
+
{
|
|
2110
|
+
className: cn(
|
|
2111
|
+
"p-3",
|
|
2112
|
+
onOpenDoc && r.docId && "cursor-pointer transition-colors hover:border-ai-accent/40"
|
|
2113
|
+
),
|
|
2114
|
+
onClick: () => r.docId && onOpenDoc?.(r.docId),
|
|
2115
|
+
"data-testid": `doc-search-hit-${i}`,
|
|
2116
|
+
children: [
|
|
2117
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-1 flex items-center gap-2", children: [
|
|
2118
|
+
/* @__PURE__ */ jsx(FileText, { className: "size-3.5 text-ai-accent" }),
|
|
2119
|
+
/* @__PURE__ */ jsx("span", { className: "truncate text-xs font-medium text-foreground", children: r.docTitle ?? "Document" }),
|
|
2120
|
+
r.page != null && /* @__PURE__ */ jsxs(Badge, { variant: "secondary", children: [
|
|
2121
|
+
"p.",
|
|
2122
|
+
r.page
|
|
2123
|
+
] }),
|
|
2124
|
+
r.score != null && /* @__PURE__ */ jsxs("span", { className: "ml-auto text-[10px] text-muted-foreground", children: [
|
|
2125
|
+
"score ",
|
|
2126
|
+
r.score.toFixed(2)
|
|
2127
|
+
] })
|
|
2128
|
+
] }),
|
|
2129
|
+
/* @__PURE__ */ jsx("p", { className: "line-clamp-3 text-xs leading-relaxed text-muted-foreground", children: r.content })
|
|
2130
|
+
]
|
|
2131
|
+
},
|
|
2132
|
+
`${r.docId}-${r.page}-${i}`
|
|
2133
|
+
))
|
|
2134
|
+
] })
|
|
2135
|
+
] });
|
|
2136
|
+
}
|
|
2137
|
+
function DocQaPanel({ docId, docName }) {
|
|
2138
|
+
const task = useAiTask();
|
|
2139
|
+
const [q, setQ] = useState("");
|
|
2140
|
+
const ask = () => {
|
|
2141
|
+
const question = q.trim();
|
|
2142
|
+
if (!question || task.isRunning) return;
|
|
2143
|
+
void task.run(
|
|
2144
|
+
`You are answering strictly from the single document "${docName ?? docId}". Cite the page/section for each point and say if the document does not address the question.
|
|
2145
|
+
|
|
2146
|
+
Question: ${question}`,
|
|
2147
|
+
[docId]
|
|
2148
|
+
);
|
|
2149
|
+
};
|
|
2150
|
+
const suggestTags = () => void task.run(
|
|
2151
|
+
`Suggest 3-6 concise, reusable labels for the document "${docName ?? docId}" \u2014 covering document type, the key issues it touches, and any key parties. Return them as a short comma-separated list with a one-line rationale for each.`,
|
|
2152
|
+
[docId]
|
|
2153
|
+
);
|
|
2154
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-3", "data-testid": "doc-qa", children: [
|
|
2155
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2156
|
+
/* @__PURE__ */ jsx(
|
|
2157
|
+
Input,
|
|
2158
|
+
{
|
|
2159
|
+
value: q,
|
|
2160
|
+
onChange: (e) => setQ(e.target.value),
|
|
2161
|
+
onKeyDown: (e) => e.key === "Enter" && (e.preventDefault(), ask()),
|
|
2162
|
+
placeholder: "Ask about this document\u2026",
|
|
2163
|
+
"data-testid": "doc-qa-input"
|
|
2164
|
+
}
|
|
2165
|
+
),
|
|
2166
|
+
/* @__PURE__ */ jsx(
|
|
2167
|
+
Button,
|
|
2168
|
+
{
|
|
2169
|
+
variant: "accent",
|
|
2170
|
+
size: "icon",
|
|
2171
|
+
onClick: ask,
|
|
2172
|
+
disabled: task.isRunning || !q.trim(),
|
|
2173
|
+
"data-testid": "doc-qa-send",
|
|
2174
|
+
children: /* @__PURE__ */ jsx(Send, { className: "size-4" })
|
|
2175
|
+
}
|
|
2176
|
+
),
|
|
2177
|
+
/* @__PURE__ */ jsxs(
|
|
2178
|
+
Button,
|
|
2179
|
+
{
|
|
2180
|
+
variant: "outline",
|
|
2181
|
+
size: "sm",
|
|
2182
|
+
onClick: suggestTags,
|
|
2183
|
+
disabled: task.isRunning,
|
|
2184
|
+
"data-testid": "doc-qa-tags",
|
|
2185
|
+
children: [
|
|
2186
|
+
/* @__PURE__ */ jsx(Tags, { className: "size-4" }),
|
|
2187
|
+
" Tags"
|
|
2188
|
+
]
|
|
2189
|
+
}
|
|
2190
|
+
)
|
|
2191
|
+
] }),
|
|
2192
|
+
/* @__PURE__ */ jsx(
|
|
2193
|
+
AiAnswer,
|
|
2194
|
+
{
|
|
2195
|
+
status: task.status,
|
|
2196
|
+
text: task.text,
|
|
2197
|
+
stepCount: task.stepCount,
|
|
2198
|
+
error: task.error,
|
|
2199
|
+
emptyHint: "Ask a question, or suggest tags \u2014 answered from this document only.",
|
|
2200
|
+
testId: "doc-qa-answer"
|
|
2201
|
+
}
|
|
2202
|
+
)
|
|
2203
|
+
] });
|
|
2204
|
+
}
|
|
1456
2205
|
|
|
1457
2206
|
// src/icons/colors.ts
|
|
1458
2207
|
var NEUTRAL_GRAY = "#64748b";
|
|
@@ -2462,6 +3211,6 @@ function DocumentTable({
|
|
|
2462
3211
|
) });
|
|
2463
3212
|
}
|
|
2464
3213
|
|
|
2465
|
-
export { ArbiChat, ArbiChatPanel, ArbiProvider, AudIcon, Avatar, AvatarFallback, AvatarImage, Badge, Button, DocumentEntity, DocumentTable, EmlIcon, EntityPill, FILE_TYPE_COLORS, FileIcon, HoverCard, HoverCardContent, HoverCardTrigger, ImgIcon, PdfIcon, ProjectEntity, TagEntity, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, VidIcon, arbiQueryKeys, badgeVariants, buttonVariants, cn, useAgents, useArbi, useArbiUiStore, useAssistantQuery, useConfigs, useConversations, useDeleteAgents, useDocuments, useHealth, useMemories, useSessions, useTags, useTasks, useWorkspaces };
|
|
3214
|
+
export { AiActionCard, AiAnswer, AiMarkdown, ArbiChat, ArbiChatPanel, ArbiProvider, ArtifactCanvas, AudIcon, Avatar, AvatarFallback, AvatarImage, Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, DocQaPanel, DocSearch, DocumentEntity, DocumentTable, EmlIcon, EntityPill, FILE_TYPE_COLORS, FileIcon, HoverCard, HoverCardContent, HoverCardTrigger, ImgIcon, Input, PdfIcon, ProjectEntity, TagEntity, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, VidIcon, arbiQueryKeys, badgeVariants, buttonVariants, cn, redlineStats, textToArtifact, toRedlineMarkdown, useAgents, useAiTask, useArbi, useArbiUiStore, useAssistantQuery, useConfigs, useConversations, useDeleteAgents, useDocuments, useHealth, useMemories, useSemanticSearch, useSessions, useTags, useTasks, useWorkspaceDocs, useWorkspaces };
|
|
2466
3215
|
//# sourceMappingURL=index.js.map
|
|
2467
3216
|
//# sourceMappingURL=index.js.map
|