@agno-hq/chat-react 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -5
- package/dist/chat/index.cjs +94 -82
- package/dist/chat/index.d.cts +72 -17
- package/dist/chat/index.d.ts +72 -17
- package/dist/chat/index.js +1 -1
- package/dist/{chunk-JEPFGKHH.cjs → chunk-3IEYJIYJ.cjs} +249 -222
- package/dist/chunk-3IEYJIYJ.cjs.map +1 -0
- package/dist/{chunk-BZC2674Z.js → chunk-E4CFQ457.js} +103 -79
- package/dist/chunk-E4CFQ457.js.map +1 -0
- package/dist/index.cjs +95 -83
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/styles.css +57 -19
- package/package.json +9 -11
- package/dist/chunk-BZC2674Z.js.map +0 -1
- package/dist/chunk-JEPFGKHH.cjs.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { AgnoClient, activityLabel, isSubRunEvent, applySubRunEvent, isStepEvent, applyStepEvent, isStartedEvent, isToolEvent, toolsFromEvent, mergeTool, isContentEvent, applyContentEvent, isReasoningStepEvent, isReasoningCompletedEvent, isFollowupsCompletedEvent, isPausedEvent, isCompletedEvent, isCancelledEvent, isErrorEvent, sessionRunsToMessages, isToolCompletedEvent } from './chunk-6V2YIPHF.js';
|
|
2
|
-
import
|
|
2
|
+
import React8, { createContext, useMemo, useState, useRef, useEffect, useCallback, useContext, useId, isValidElement, cloneElement, useLayoutEffect, useReducer } from 'react';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
import { createPortal } from 'react-dom';
|
|
5
|
-
import {
|
|
5
|
+
import { ChevronDown as ChevronDown$1, ArrowUp as ArrowUp$1, Paperclip as Paperclip$1, File, FileType2, FileAudio as FileAudio$1, FileVideo as FileVideo$1, Wrench as Wrench$1, BookOpen as BookOpen$1, Globe as Globe$1, Link, Brain as Brain$1, Box as Box$1, Plus as Plus$1, Check as Check$1, Copy as Copy$1, X, MemoryStick, RefreshCcw, Activity, Trash2, MessageSquare, LoaderCircle, Square } from 'lucide-react';
|
|
6
6
|
import { Streamdown } from 'streamdown';
|
|
7
7
|
|
|
8
8
|
var messageCounter = 0;
|
|
@@ -656,9 +656,7 @@ var Pulse = icon(Activity);
|
|
|
656
656
|
var Trash = icon(Trash2);
|
|
657
657
|
var ChatBubble = icon(MessageSquare);
|
|
658
658
|
var Spinner = icon(LoaderCircle, 12);
|
|
659
|
-
|
|
660
|
-
return /* @__PURE__ */ jsx(Square, { size, className, fill: "currentColor", strokeWidth: 0 });
|
|
661
|
-
}
|
|
659
|
+
var Stop = icon(Square, 10.67);
|
|
662
660
|
function AgnoMark({ size = 24, className }) {
|
|
663
661
|
return /* @__PURE__ */ jsxs(
|
|
664
662
|
"svg",
|
|
@@ -1094,15 +1092,18 @@ function ChatInput({
|
|
|
1094
1092
|
}
|
|
1095
1093
|
)
|
|
1096
1094
|
] });
|
|
1097
|
-
const primary = isBusy && stop ?
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1095
|
+
const primary = isBusy && stop ? (
|
|
1096
|
+
// The same button the arrow sends from, with AgentOS's square-stop in it.
|
|
1097
|
+
/* @__PURE__ */ jsx(
|
|
1098
|
+
"button",
|
|
1099
|
+
{
|
|
1100
|
+
type: "button",
|
|
1101
|
+
className: cx("agno-btn", "agno-btn--icon", cn.stopButton),
|
|
1102
|
+
onClick: stop,
|
|
1103
|
+
"aria-label": "Stop",
|
|
1104
|
+
children: /* @__PURE__ */ jsx(Stop, {})
|
|
1105
|
+
}
|
|
1106
|
+
)
|
|
1106
1107
|
) : /* @__PURE__ */ jsx(
|
|
1107
1108
|
"button",
|
|
1108
1109
|
{
|
|
@@ -1392,11 +1393,14 @@ function sourceHost(url) {
|
|
|
1392
1393
|
}
|
|
1393
1394
|
}
|
|
1394
1395
|
function faviconUrl(url) {
|
|
1395
|
-
|
|
1396
|
+
return faviconFallbacks(url)[0];
|
|
1397
|
+
}
|
|
1398
|
+
function faviconFallbacks(url) {
|
|
1399
|
+
if (!url) return [];
|
|
1396
1400
|
try {
|
|
1397
|
-
return
|
|
1401
|
+
return ["/favicon.ico", "/favicon.svg"].map((path) => new URL(path, url).href);
|
|
1398
1402
|
} catch {
|
|
1399
|
-
return
|
|
1403
|
+
return [];
|
|
1400
1404
|
}
|
|
1401
1405
|
}
|
|
1402
1406
|
function displayUrl(url) {
|
|
@@ -1648,10 +1652,11 @@ function Favicon({
|
|
|
1648
1652
|
size = 14,
|
|
1649
1653
|
className
|
|
1650
1654
|
}) {
|
|
1651
|
-
const
|
|
1652
|
-
const [
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
+
const candidates = useMemo(() => faviconFallbacks(url), [url]);
|
|
1656
|
+
const [attempt, setAttempt] = useState(0);
|
|
1657
|
+
const src = candidates[attempt];
|
|
1658
|
+
useEffect(() => setAttempt(0), [url]);
|
|
1659
|
+
if (kind === "document" || !src) {
|
|
1655
1660
|
const Glyph2 = kind === "document" ? BookOpen : Globe;
|
|
1656
1661
|
return /* @__PURE__ */ jsx("span", { className: cx("agno-favicon", "agno-favicon--glyph", className), "aria-hidden": true, children: /* @__PURE__ */ jsx(Glyph2, { size }) });
|
|
1657
1662
|
}
|
|
@@ -1665,7 +1670,7 @@ function Favicon({
|
|
|
1665
1670
|
height: size,
|
|
1666
1671
|
loading: "lazy",
|
|
1667
1672
|
decoding: "async",
|
|
1668
|
-
onError: () =>
|
|
1673
|
+
onError: () => setAttempt((n) => n + 1),
|
|
1669
1674
|
"aria-hidden": true
|
|
1670
1675
|
}
|
|
1671
1676
|
);
|
|
@@ -1796,45 +1801,6 @@ function HoverPreview({
|
|
|
1796
1801
|
}
|
|
1797
1802
|
);
|
|
1798
1803
|
}
|
|
1799
|
-
function el(tag, className) {
|
|
1800
|
-
return function Element({ node: _node, className: _theirs, ...rest }) {
|
|
1801
|
-
return React7.createElement(tag, { className, ...rest });
|
|
1802
|
-
};
|
|
1803
|
-
}
|
|
1804
|
-
function sourceForUrl(url, sources) {
|
|
1805
|
-
return url ? sources.find((s) => s.url === url) : void 0;
|
|
1806
|
-
}
|
|
1807
|
-
function citationForLink(label2, href, ctx) {
|
|
1808
|
-
if (!/^\d+$/.test(label2.trim())) return void 0;
|
|
1809
|
-
return sourceForUrl(href, ctx.sources) ?? ctx.sources.find((s) => s.index === Number(label2.trim()));
|
|
1810
|
-
}
|
|
1811
|
-
function labelOf(children) {
|
|
1812
|
-
if (typeof children === "string") return children;
|
|
1813
|
-
if (Array.isArray(children) && children.length === 1 && typeof children[0] === "string") {
|
|
1814
|
-
return children[0];
|
|
1815
|
-
}
|
|
1816
|
-
return "";
|
|
1817
|
-
}
|
|
1818
|
-
function CitationMarker({
|
|
1819
|
-
source,
|
|
1820
|
-
className,
|
|
1821
|
-
Link
|
|
1822
|
-
}) {
|
|
1823
|
-
const props = {
|
|
1824
|
-
className: cx("agno-cite", className),
|
|
1825
|
-
href: source.url ?? `#${source.anchorId}`,
|
|
1826
|
-
"aria-label": `Source ${source.index}: ${source.title}`
|
|
1827
|
-
};
|
|
1828
|
-
return /* @__PURE__ */ jsx(HoverPreview, { source, className: "agno-cite__wrap", children: Link && source.url ? /* @__PURE__ */ jsx(Link, { ...props, children: source.index }) : /* @__PURE__ */ jsx(
|
|
1829
|
-
"a",
|
|
1830
|
-
{
|
|
1831
|
-
...props,
|
|
1832
|
-
target: source.url ? "_blank" : void 0,
|
|
1833
|
-
rel: source.url ? "noreferrer noopener" : void 0,
|
|
1834
|
-
children: source.index
|
|
1835
|
-
}
|
|
1836
|
-
) });
|
|
1837
|
-
}
|
|
1838
1804
|
var COPIED_FOR = 1600;
|
|
1839
1805
|
var CLIPBOARD_TIMEOUT = 400;
|
|
1840
1806
|
async function writeClipboard(text) {
|
|
@@ -1860,7 +1826,7 @@ async function writeClipboard(text) {
|
|
|
1860
1826
|
return false;
|
|
1861
1827
|
}
|
|
1862
1828
|
}
|
|
1863
|
-
function CopyButton({ text, className }) {
|
|
1829
|
+
function CopyButton({ text, label: label2 = "Copy", size = 14, className }) {
|
|
1864
1830
|
const [copied, setCopied] = useState(false);
|
|
1865
1831
|
useEffect(() => {
|
|
1866
1832
|
if (!copied) return;
|
|
@@ -1868,30 +1834,70 @@ function CopyButton({ text, className }) {
|
|
|
1868
1834
|
return () => clearTimeout(timer);
|
|
1869
1835
|
}, [copied]);
|
|
1870
1836
|
const copy = async () => {
|
|
1871
|
-
if (await writeClipboard(text())) setCopied(true);
|
|
1837
|
+
if (await writeClipboard(typeof text === "function" ? text() : text)) setCopied(true);
|
|
1872
1838
|
};
|
|
1839
|
+
const name = copied ? "Copied" : label2;
|
|
1873
1840
|
return /* @__PURE__ */ jsx(
|
|
1874
1841
|
"button",
|
|
1875
1842
|
{
|
|
1876
1843
|
type: "button",
|
|
1877
|
-
className: cx("agno-
|
|
1844
|
+
className: cx("agno-copy", copied && "is-copied", className),
|
|
1878
1845
|
onClick: copy,
|
|
1879
|
-
"aria-label":
|
|
1880
|
-
title:
|
|
1881
|
-
children: copied ? /* @__PURE__ */ jsx(Check, { size
|
|
1846
|
+
"aria-label": name,
|
|
1847
|
+
title: name,
|
|
1848
|
+
children: copied ? /* @__PURE__ */ jsx(Check, { size }) : /* @__PURE__ */ jsx(Copy, { size })
|
|
1882
1849
|
}
|
|
1883
1850
|
);
|
|
1884
1851
|
}
|
|
1852
|
+
function el(tag, className) {
|
|
1853
|
+
return function Element({ node: _node, className: _theirs, ...rest }) {
|
|
1854
|
+
return React8.createElement(tag, { className, ...rest });
|
|
1855
|
+
};
|
|
1856
|
+
}
|
|
1857
|
+
function sourceForUrl(url, sources) {
|
|
1858
|
+
return url ? sources.find((s) => s.url === url) : void 0;
|
|
1859
|
+
}
|
|
1860
|
+
function citationForLink(label2, href, ctx) {
|
|
1861
|
+
if (!/^\d+$/.test(label2.trim())) return void 0;
|
|
1862
|
+
return sourceForUrl(href, ctx.sources) ?? ctx.sources.find((s) => s.index === Number(label2.trim()));
|
|
1863
|
+
}
|
|
1864
|
+
function labelOf(children) {
|
|
1865
|
+
if (typeof children === "string") return children;
|
|
1866
|
+
if (Array.isArray(children) && children.length === 1 && typeof children[0] === "string") {
|
|
1867
|
+
return children[0];
|
|
1868
|
+
}
|
|
1869
|
+
return "";
|
|
1870
|
+
}
|
|
1871
|
+
function CitationMarker({
|
|
1872
|
+
source,
|
|
1873
|
+
className,
|
|
1874
|
+
Link
|
|
1875
|
+
}) {
|
|
1876
|
+
const props = {
|
|
1877
|
+
className: cx("agno-cite", className),
|
|
1878
|
+
href: source.url ?? `#${source.anchorId}`,
|
|
1879
|
+
"aria-label": `Source ${source.index}: ${source.title}`
|
|
1880
|
+
};
|
|
1881
|
+
return /* @__PURE__ */ jsx(HoverPreview, { source, className: "agno-cite__wrap", children: Link && source.url ? /* @__PURE__ */ jsx(Link, { ...props, children: source.index }) : /* @__PURE__ */ jsx(
|
|
1882
|
+
"a",
|
|
1883
|
+
{
|
|
1884
|
+
...props,
|
|
1885
|
+
target: source.url ? "_blank" : void 0,
|
|
1886
|
+
rel: source.url ? "noreferrer noopener" : void 0,
|
|
1887
|
+
children: source.index
|
|
1888
|
+
}
|
|
1889
|
+
) });
|
|
1890
|
+
}
|
|
1885
1891
|
function textOf(children) {
|
|
1886
1892
|
if (typeof children === "string") return children;
|
|
1887
1893
|
if (typeof children === "number") return String(children);
|
|
1888
1894
|
if (Array.isArray(children)) return children.map(textOf).join("");
|
|
1889
|
-
if (
|
|
1895
|
+
if (React8.isValidElement(children)) return textOf(children.props.children);
|
|
1890
1896
|
return "";
|
|
1891
1897
|
}
|
|
1892
1898
|
function fencedCode(children) {
|
|
1893
1899
|
const child = Array.isArray(children) ? children[0] : children;
|
|
1894
|
-
if (!
|
|
1900
|
+
if (!React8.isValidElement(child)) {
|
|
1895
1901
|
return { code: textOf(children) };
|
|
1896
1902
|
}
|
|
1897
1903
|
const language = /(?:^|\s)language-([^\s]+)/.exec(child.props.className ?? "")?.[1];
|
|
@@ -1912,9 +1918,9 @@ function CodeBlock({
|
|
|
1912
1918
|
return /* @__PURE__ */ jsxs("div", { className: "agno-md-code-block", "data-language": label2, children: [
|
|
1913
1919
|
/* @__PURE__ */ jsxs("div", { className: "agno-md-code-head", children: [
|
|
1914
1920
|
/* @__PURE__ */ jsx("span", { className: "agno-md-code-lang", children: label2 }),
|
|
1915
|
-
codeCopy && /* @__PURE__ */ jsx(CopyButton, { className: copyClass, text: () => code })
|
|
1921
|
+
codeCopy && /* @__PURE__ */ jsx(CopyButton, { className: cx("agno-md-copy", copyClass), text: () => code, label: "Copy code", size: 13 })
|
|
1916
1922
|
] }),
|
|
1917
|
-
/* @__PURE__ */ jsx("pre", { className: "agno-md-pre", style: { "--agno-code-gutter": `${String(lines.length).length}ch` }, children: /* @__PURE__ */ jsx("code", { className: language ? `language-${language}` : void 0, children: lines.map((tokens, i) => /* @__PURE__ */ jsxs(
|
|
1923
|
+
/* @__PURE__ */ jsx("pre", { className: "agno-md-pre", style: { "--agno-code-gutter": `${String(lines.length).length}ch` }, children: /* @__PURE__ */ jsx("code", { className: language ? `language-${language}` : void 0, children: lines.map((tokens, i) => /* @__PURE__ */ jsxs(React8.Fragment, { children: [
|
|
1918
1924
|
/* @__PURE__ */ jsx("span", { className: "agno-md-line", children: tokens.map((token, j) => /* @__PURE__ */ jsx("span", { style: token.htmlStyle, children: token.content }, j)) }),
|
|
1919
1925
|
i < lines.length - 1 && "\n"
|
|
1920
1926
|
] }, i)) }) })
|
|
@@ -2574,6 +2580,20 @@ function Citations({
|
|
|
2574
2580
|
] })
|
|
2575
2581
|
] });
|
|
2576
2582
|
}
|
|
2583
|
+
function MessageActions({
|
|
2584
|
+
message,
|
|
2585
|
+
hideCopy,
|
|
2586
|
+
children,
|
|
2587
|
+
className,
|
|
2588
|
+
classNames
|
|
2589
|
+
}) {
|
|
2590
|
+
const cn = useResolvedClassNames(classNames);
|
|
2591
|
+
if (hideCopy && !children) return null;
|
|
2592
|
+
return /* @__PURE__ */ jsxs("div", { className: cx("agno-msg__actions", cn.messageActions, className), role: "toolbar", "aria-label": "Message actions", children: [
|
|
2593
|
+
!hideCopy && /* @__PURE__ */ jsx(CopyButton, { className: cx("agno-msg__action", cn.messageCopyButton), text: message.content, label: "Copy message" }),
|
|
2594
|
+
children
|
|
2595
|
+
] });
|
|
2596
|
+
}
|
|
2577
2597
|
function audioSrc(a) {
|
|
2578
2598
|
if (a.url) return a.url;
|
|
2579
2599
|
if (a.base64_audio) return `data:${a.mime_type ?? "audio/mpeg"};base64,${a.base64_audio}`;
|
|
@@ -2614,6 +2634,8 @@ function Message({
|
|
|
2614
2634
|
hideReasoning,
|
|
2615
2635
|
hideTools,
|
|
2616
2636
|
hideSources,
|
|
2637
|
+
hideActions,
|
|
2638
|
+
actions,
|
|
2617
2639
|
onFollowup
|
|
2618
2640
|
}) {
|
|
2619
2641
|
const cn = useResolvedClassNames(classNames);
|
|
@@ -2624,10 +2646,11 @@ function Message({
|
|
|
2624
2646
|
}, [message.references, message.citations, message.content, uid]);
|
|
2625
2647
|
const isUser = message.role === "user";
|
|
2626
2648
|
const isAgent = message.role === "agent";
|
|
2627
|
-
const
|
|
2649
|
+
const hasSources = isAgent && !hideSources && sources.length > 0;
|
|
2650
|
+
const showSources = hasSources && !message.streaming;
|
|
2628
2651
|
const content = useMemo(
|
|
2629
|
-
() =>
|
|
2630
|
-
[message.content,
|
|
2652
|
+
() => hasSources && message.content ? withoutSourcesLine(message.content) : message.content,
|
|
2653
|
+
[message.content, hasSources]
|
|
2631
2654
|
);
|
|
2632
2655
|
const hasActivity = !message.content && !hasBehindTheScenes(message, { hideReasoning, hideTools });
|
|
2633
2656
|
const kind = isUser ? "user" : isAgent ? entityType : "system";
|
|
@@ -2679,7 +2702,8 @@ function Message({
|
|
|
2679
2702
|
showSources && /* @__PURE__ */ jsx(Citations, { sources, classNames: cn }),
|
|
2680
2703
|
isAgent && onFollowup && !message.streaming && /* @__PURE__ */ jsx(Followups, { items: message.followups, onSelect: onFollowup, classNames: cn }),
|
|
2681
2704
|
message.error && /* @__PURE__ */ jsx("div", { className: "agno-msg__error", children: message.error }),
|
|
2682
|
-
children
|
|
2705
|
+
children,
|
|
2706
|
+
isAgent && !hideActions && !message.streaming && message.content && /* @__PURE__ */ jsx(MessageActions, { message, classNames: cn, children: actions })
|
|
2683
2707
|
] }) })
|
|
2684
2708
|
]
|
|
2685
2709
|
}
|
|
@@ -2739,7 +2763,7 @@ function MessageList({
|
|
|
2739
2763
|
items.length === 0 ? /* @__PURE__ */ jsx("div", { className: cx("agno-list__empty", cn.empty), children: emptyState ?? "Start the conversation." }) : /* @__PURE__ */ jsxs("div", { className: "agno-list__inner", children: [
|
|
2740
2764
|
items.map((m) => {
|
|
2741
2765
|
const live = m.streaming && runStatus === "streaming" ? runActivity : void 0;
|
|
2742
|
-
return renderMessage ? /* @__PURE__ */ jsx(
|
|
2766
|
+
return renderMessage ? /* @__PURE__ */ jsx(React8.Fragment, { children: renderMessage(m, live) }, m.id) : /* @__PURE__ */ jsx(
|
|
2743
2767
|
Message,
|
|
2744
2768
|
{
|
|
2745
2769
|
message: m,
|
|
@@ -3496,6 +3520,6 @@ function EventLog({
|
|
|
3496
3520
|
] });
|
|
3497
3521
|
}
|
|
3498
3522
|
|
|
3499
|
-
export { AgnoChat, AgnoMark, ArrowUp, BehindTheScenes, BookOpen, Box, Brain, ChatBubble, ChatInput, ChatLauncher, ChatProvider, ChatWindow, Check, ChevronDown, Citations, Close, Copy, EntityBadge, EntitySelector, EventLog, Favicon, FileAudio, FileIcon, FilePreview, FileType, FileVideo, Followups, Globe, GridLoader, HoverPreview, HumanInput, LinkIcon, LinkPreviewCard, Markdown, MemberResponses, Memory, Message, MessageList, Multimedia, Paperclip, Plus, Pulse, QuickPrompts, Reasoning, Rerun, SessionList, SourceCard, SourcesProvider, Spinner, StatusIndicator, Stop, TeamGlyph, ToolCalls, Trash, WorkflowSteps, Wrench, admitFiles, behindTheScenesItems, behindTheScenesLabel, collectSources, cx, displayUrl, faviconUrl, fileAccepted, getProviderIcon, hasBehindTheScenes, linkCitations, normalizeFollowups, quickPromptLabel, quickPromptText, sourceHost, sourcesFromMarkdown, useAgnoChat, useChatContext, useLinkComponent, useLinkPreview, useOptionalChatContext, useResolvedChat, useResolvedClassNames, useSources, withoutSourcesLine, writeClipboard };
|
|
3500
|
-
//# sourceMappingURL=chunk-
|
|
3501
|
-
//# sourceMappingURL=chunk-
|
|
3523
|
+
export { AgnoChat, AgnoMark, ArrowUp, BehindTheScenes, BookOpen, Box, Brain, ChatBubble, ChatInput, ChatLauncher, ChatProvider, ChatWindow, Check, ChevronDown, Citations, Close, Copy, CopyButton, EntityBadge, EntitySelector, EventLog, Favicon, FileAudio, FileIcon, FilePreview, FileType, FileVideo, Followups, Globe, GridLoader, HoverPreview, HumanInput, LinkIcon, LinkPreviewCard, Markdown, MemberResponses, Memory, Message, MessageActions, MessageList, Multimedia, Paperclip, Plus, Pulse, QuickPrompts, Reasoning, Rerun, SessionList, SourceCard, SourcesProvider, Spinner, StatusIndicator, Stop, TeamGlyph, ToolCalls, Trash, WorkflowSteps, Wrench, admitFiles, behindTheScenesItems, behindTheScenesLabel, collectSources, cx, displayUrl, faviconFallbacks, faviconUrl, fileAccepted, getProviderIcon, hasBehindTheScenes, linkCitations, normalizeFollowups, quickPromptLabel, quickPromptText, sourceHost, sourcesFromMarkdown, useAgnoChat, useChatContext, useLinkComponent, useLinkPreview, useOptionalChatContext, useResolvedChat, useResolvedClassNames, useSources, withoutSourcesLine, writeClipboard };
|
|
3524
|
+
//# sourceMappingURL=chunk-E4CFQ457.js.map
|
|
3525
|
+
//# sourceMappingURL=chunk-E4CFQ457.js.map
|