@nexo-labs/chat-agent 1.6.17 → 1.6.19
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/react.d.mts +73 -0
- package/dist/react.d.mts.map +1 -0
- package/dist/{index.mjs → react.mjs} +4 -280
- package/dist/react.mjs.map +1 -0
- package/dist/{index.d.mts → server.d.mts} +3 -72
- package/dist/server.d.mts.map +1 -0
- package/dist/server.mjs +280 -0
- package/dist/server.mjs.map +1 -0
- package/package.json +14 -8
- package/src/components/ChatInput.tsx +40 -0
- package/src/components/ChatInterface.tsx +199 -0
- package/src/components/ChatMenuDropdown.tsx +154 -0
- package/src/components/ChatMessages.tsx +103 -0
- package/src/components/DocumentSelector.tsx +292 -0
- package/src/components/FloatingChatManager.tsx +45 -0
- package/src/components/FloatingChatPanel.tsx +172 -0
- package/src/components/MainButton.tsx +98 -0
- package/src/components/SourcesList.tsx +410 -0
- package/src/components/UsageDisplay.tsx +47 -0
- package/src/components/buttons/FloatingChatButton.tsx +37 -0
- package/src/components/buttons/ViewMoreLink.tsx +55 -0
- package/src/components/chat-context.tsx +168 -0
- package/src/components/icons/ArticleIcon.tsx +28 -0
- package/src/components/icons/BookIcon.tsx +26 -0
- package/src/components/icons/ChevronDownIcon.tsx +26 -0
- package/src/components/icons/CloseXIcon.tsx +33 -0
- package/src/components/icons/ExpandIcon.tsx +32 -0
- package/src/components/icons/ListIcon.tsx +23 -0
- package/src/components/icons/SearchIcon.tsx +25 -0
- package/src/components/icons/index.ts +7 -0
- package/src/components/index.ts +4 -0
- package/src/components/useDocumentSelector.ts +185 -0
- package/src/hooks/useChatMessages.ts +317 -0
- package/src/hooks/useChatSession.ts +118 -0
- package/src/hooks/useChunkLoader.ts +125 -0
- package/src/index.ts +6 -0
- package/src/react.ts +5 -0
- package/src/server.ts +20 -0
- package/src/types/components.tsx +54 -0
- package/src/usage/limits.ts +284 -0
- package/src/usage/token-calculator.ts +188 -0
- package/dist/index.d.mts.map +0 -1
- package/dist/index.mjs.map +0 -1
package/dist/react.d.mts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import React, { ReactNode } from "react";
|
|
2
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
3
|
+
import { BaseUser } from "@nexo-labs/payload-stripe-inventory";
|
|
4
|
+
|
|
5
|
+
//#region src/components/chat-context.d.ts
|
|
6
|
+
|
|
7
|
+
declare const ChatProvider: ({
|
|
8
|
+
children
|
|
9
|
+
}: {
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
}) => react_jsx_runtime0.JSX.Element;
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/types/components.d.ts
|
|
14
|
+
/**
|
|
15
|
+
* Props for a Link component that can be injected
|
|
16
|
+
* Compatible with next/link and regular <a> tags
|
|
17
|
+
*/
|
|
18
|
+
interface LinkComponentProps {
|
|
19
|
+
href: string;
|
|
20
|
+
children: React.ReactNode;
|
|
21
|
+
onClick?: () => void;
|
|
22
|
+
className?: string;
|
|
23
|
+
target?: string;
|
|
24
|
+
'aria-label'?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Type for a Link component that can be injected from outside
|
|
28
|
+
* Default fallback is a regular <a> tag
|
|
29
|
+
*/
|
|
30
|
+
type LinkComponent = React.ComponentType<LinkComponentProps>;
|
|
31
|
+
/**
|
|
32
|
+
* Props for an Image component that can be injected
|
|
33
|
+
* Compatible with next/image and regular <img> tags
|
|
34
|
+
*/
|
|
35
|
+
interface ImageComponentProps {
|
|
36
|
+
src: string;
|
|
37
|
+
alt: string;
|
|
38
|
+
width?: number;
|
|
39
|
+
height?: number;
|
|
40
|
+
className?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Type for an Image component that can be injected from outside
|
|
44
|
+
* Default fallback is a regular <img> tag
|
|
45
|
+
*/
|
|
46
|
+
type ImageComponent = React.ComponentType<ImageComponentProps>;
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region src/components/FloatingChatManager.d.ts
|
|
49
|
+
interface FloatingChatManagerProps {
|
|
50
|
+
aiIcon: string;
|
|
51
|
+
useUser: () => {
|
|
52
|
+
user: BaseUser | null;
|
|
53
|
+
};
|
|
54
|
+
generateHref: (props: {
|
|
55
|
+
type: string;
|
|
56
|
+
value: {
|
|
57
|
+
id: number;
|
|
58
|
+
slug?: string | null;
|
|
59
|
+
};
|
|
60
|
+
}) => string;
|
|
61
|
+
LinkComponent?: LinkComponent;
|
|
62
|
+
ImageComponent?: ImageComponent;
|
|
63
|
+
}
|
|
64
|
+
declare const FloatingChatManager: ({
|
|
65
|
+
aiIcon,
|
|
66
|
+
useUser,
|
|
67
|
+
generateHref,
|
|
68
|
+
LinkComponent,
|
|
69
|
+
ImageComponent
|
|
70
|
+
}: FloatingChatManagerProps) => react_jsx_runtime0.JSX.Element | null;
|
|
71
|
+
//#endregion
|
|
72
|
+
export { ChatProvider, FloatingChatManager };
|
|
73
|
+
//# sourceMappingURL=react.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.d.mts","names":[],"sources":["../src/components/chat-context.tsx","../src/types/components.tsx","../src/components/FloatingChatManager.tsx"],"sourcesContent":[],"mappings":";;;;;;AEgByB,cFuBZ,YEvBY,EAAA,CAAA;EAAA;CAAA,EAAA;EAAA,QAAA,EFuB8B,SEvB9B;CAAA,EAAA,GFuByC,kBAAA,CAAA,GAAA,CAAA,OEvBzC;;;;;;;AFuBZ,UCjCI,kBAAA,CDyJhB;EAxHwB,IAAA,EAAA,MAAA;EAA8B,QAAA,EC/B3C,KAAA,CAAM,SD+BqC;EAAW,OAAA,CAAA,EAAA,GAAA,GAAA,IAAA;EAwHjE,SAAA,CAAA,EAAA,MAAA;;;;ACzJD;AAaA;AAMA;AAYA;KAlBY,aAAA,GAAgB,KAAA,CAAM,cAAc;;;ACbsB;;AAMpD,UDaD,mBAAA,CCbC;EACC,GAAA,EAAA,MAAA;EAAc,GAAA,EAAA,MAAA;EAG3B,KAAA,CAAA,EAAA,MAAA;EAAmB,MAAA,CAAA,EAAA,MAAA;EAAA,SAAA,CAAA,EAAA,MAAA;;;;;;AAME,KDef,cAAA,GAAiB,KAAA,CAAM,aCfR,CDesB,mBCftB,CAAA;;;UAdjB,wBAAA;;;IF+BG,IAAA,EE7BY,QFqJxB,GAAA,IAAA;EAxHwB,CAAA;EAA8B,YAAA,EAAA,CAAA,KAAA,EAAA;IAAW,IAAA,EAAA,MAAA;IAwHjE,KAAA,EAAA;;;;ECzJgB,CAAA,EAAA,GAAA,MAAA;EAaL,aAAA,CAAA,ECPM,aDO8B;EAM/B,cAAA,CAAA,ECZE,cDYiB;AAYpC;cCrBM;;;;;;GAMH,6BAAwB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
1
3
|
import React, { createContext, forwardRef, useCallback, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
2
4
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
5
|
import clsx from "clsx";
|
|
@@ -1811,283 +1813,5 @@ const FloatingChatManager = ({ aiIcon, useUser, generateHref, LinkComponent, Ima
|
|
|
1811
1813
|
var FloatingChatManager_default = FloatingChatManager;
|
|
1812
1814
|
|
|
1813
1815
|
//#endregion
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
free: 1e3,
|
|
1817
|
-
basic: 5e3,
|
|
1818
|
-
pro: 2e4,
|
|
1819
|
-
enterprise: 1e5
|
|
1820
|
-
};
|
|
1821
|
-
/**
|
|
1822
|
-
* Get the daily token limit for a user based on their Stripe subscription
|
|
1823
|
-
*/
|
|
1824
|
-
async function getUserDailyLimit(payload, userId) {
|
|
1825
|
-
try {
|
|
1826
|
-
const user = await payload.findByID({
|
|
1827
|
-
collection: "users",
|
|
1828
|
-
id: userId,
|
|
1829
|
-
depth: 2
|
|
1830
|
-
});
|
|
1831
|
-
if (!user) {
|
|
1832
|
-
console.warn("[Token Limits] User not found:", userId);
|
|
1833
|
-
return DEFAULT_LIMITS.free;
|
|
1834
|
-
}
|
|
1835
|
-
const userTyped = user;
|
|
1836
|
-
if (userTyped.daily_token_limit && userTyped.daily_token_limit > 0) return userTyped.daily_token_limit;
|
|
1837
|
-
const limitFromStripe = await getLimitFromStripeSubscription(user);
|
|
1838
|
-
if (limitFromStripe > 0) return limitFromStripe;
|
|
1839
|
-
return DEFAULT_LIMITS.free;
|
|
1840
|
-
} catch (error) {
|
|
1841
|
-
console.error("[Token Limits] Error getting user limit:", error);
|
|
1842
|
-
return DEFAULT_LIMITS.free;
|
|
1843
|
-
}
|
|
1844
|
-
}
|
|
1845
|
-
/**
|
|
1846
|
-
* Extract token limit from user's active Stripe subscription
|
|
1847
|
-
*/
|
|
1848
|
-
async function getLimitFromStripeSubscription(user) {
|
|
1849
|
-
try {
|
|
1850
|
-
const customer = user?.customer;
|
|
1851
|
-
if (!customer || typeof customer === "string" || typeof customer === "number") return 0;
|
|
1852
|
-
const inventory = customer?.inventory;
|
|
1853
|
-
if (!inventory || !inventory.subscriptions) return 0;
|
|
1854
|
-
const activeSubscription = Object.values(inventory.subscriptions).find((sub) => sub.status === "active" || sub.status === "trialing");
|
|
1855
|
-
if (!activeSubscription) return 0;
|
|
1856
|
-
const items = activeSubscription.items?.data || [];
|
|
1857
|
-
for (const item of items) {
|
|
1858
|
-
const product = item.price?.product;
|
|
1859
|
-
if (!product) continue;
|
|
1860
|
-
if (typeof product === "string") continue;
|
|
1861
|
-
if (product.deleted) continue;
|
|
1862
|
-
const metadata = product.metadata;
|
|
1863
|
-
if (metadata && metadata.daily_token_limit) {
|
|
1864
|
-
const limit = parseInt(metadata.daily_token_limit, 10);
|
|
1865
|
-
if (!isNaN(limit) && limit > 0) return limit;
|
|
1866
|
-
}
|
|
1867
|
-
}
|
|
1868
|
-
return 0;
|
|
1869
|
-
} catch (error) {
|
|
1870
|
-
console.error("[Token Limits] Error extracting limit from Stripe:", error);
|
|
1871
|
-
return 0;
|
|
1872
|
-
}
|
|
1873
|
-
}
|
|
1874
|
-
/**
|
|
1875
|
-
* Get the current daily usage for a user by querying chat-sessions
|
|
1876
|
-
* Counts tokens from spending entries that occurred today
|
|
1877
|
-
*/
|
|
1878
|
-
async function getCurrentDailyUsage(payload, userId) {
|
|
1879
|
-
const today = /* @__PURE__ */ new Date();
|
|
1880
|
-
today.setUTCHours(0, 0, 0, 0);
|
|
1881
|
-
today.toISOString();
|
|
1882
|
-
const resetAt = getNextResetTime();
|
|
1883
|
-
try {
|
|
1884
|
-
const sessions = await payload.find({
|
|
1885
|
-
collection: "chat-sessions",
|
|
1886
|
-
where: { user: { equals: userId } },
|
|
1887
|
-
limit: 1e3,
|
|
1888
|
-
pagination: false
|
|
1889
|
-
});
|
|
1890
|
-
let totalTokens = 0;
|
|
1891
|
-
for (const session of sessions.docs) {
|
|
1892
|
-
const spending = session.spending || [];
|
|
1893
|
-
for (const entry of spending) if (new Date(entry.timestamp) >= today) totalTokens += entry.tokens.total || 0;
|
|
1894
|
-
}
|
|
1895
|
-
return {
|
|
1896
|
-
date: today.toISOString().split("T")[0] ?? "",
|
|
1897
|
-
tokens_used: totalTokens,
|
|
1898
|
-
reset_at: resetAt.toISOString()
|
|
1899
|
-
};
|
|
1900
|
-
} catch (error) {
|
|
1901
|
-
console.error("[Token Limits] Error calculating daily usage:", error);
|
|
1902
|
-
return {
|
|
1903
|
-
date: today.toISOString().split("T")[0] ?? "",
|
|
1904
|
-
tokens_used: 0,
|
|
1905
|
-
reset_at: resetAt.toISOString()
|
|
1906
|
-
};
|
|
1907
|
-
}
|
|
1908
|
-
}
|
|
1909
|
-
/**
|
|
1910
|
-
* Get the next reset time (midnight UTC)
|
|
1911
|
-
*/
|
|
1912
|
-
function getNextResetTime() {
|
|
1913
|
-
const now = /* @__PURE__ */ new Date();
|
|
1914
|
-
const tomorrow = new Date(now);
|
|
1915
|
-
tomorrow.setUTCDate(tomorrow.getUTCDate() + 1);
|
|
1916
|
-
tomorrow.setUTCHours(0, 0, 0, 0);
|
|
1917
|
-
return tomorrow;
|
|
1918
|
-
}
|
|
1919
|
-
/**
|
|
1920
|
-
* Check if a user can use the specified number of tokens
|
|
1921
|
-
*/
|
|
1922
|
-
async function checkTokenLimit(payload, userId, tokensToUse) {
|
|
1923
|
-
try {
|
|
1924
|
-
const limit = await getUserDailyLimit(payload, userId);
|
|
1925
|
-
const currentUsage = await getCurrentDailyUsage(payload, userId);
|
|
1926
|
-
const remaining = Math.max(0, limit - currentUsage.tokens_used);
|
|
1927
|
-
const allowed = currentUsage.tokens_used + tokensToUse <= limit;
|
|
1928
|
-
return {
|
|
1929
|
-
allowed,
|
|
1930
|
-
limit,
|
|
1931
|
-
used: currentUsage.tokens_used,
|
|
1932
|
-
remaining,
|
|
1933
|
-
reset_at: currentUsage.reset_at,
|
|
1934
|
-
message: allowed ? void 0 : `Daily token limit exceeded. Resets at ${currentUsage.reset_at}`
|
|
1935
|
-
};
|
|
1936
|
-
} catch (error) {
|
|
1937
|
-
console.error("[Token Limits] Error checking limit:", error);
|
|
1938
|
-
return {
|
|
1939
|
-
allowed: false,
|
|
1940
|
-
limit: 0,
|
|
1941
|
-
used: 0,
|
|
1942
|
-
remaining: 0,
|
|
1943
|
-
reset_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1944
|
-
message: "Error checking token limit"
|
|
1945
|
-
};
|
|
1946
|
-
}
|
|
1947
|
-
}
|
|
1948
|
-
/**
|
|
1949
|
-
* Get usage statistics for a user (for display in UI)
|
|
1950
|
-
*/
|
|
1951
|
-
async function getUserUsageStats(payload, userId) {
|
|
1952
|
-
const limit = await getUserDailyLimit(payload, userId);
|
|
1953
|
-
const currentUsage = await getCurrentDailyUsage(payload, userId);
|
|
1954
|
-
const remaining = Math.max(0, limit - currentUsage.tokens_used);
|
|
1955
|
-
const percentage = limit > 0 ? currentUsage.tokens_used / limit * 100 : 0;
|
|
1956
|
-
return {
|
|
1957
|
-
limit,
|
|
1958
|
-
used: currentUsage.tokens_used,
|
|
1959
|
-
remaining,
|
|
1960
|
-
percentage: Math.min(100, percentage),
|
|
1961
|
-
reset_at: currentUsage.reset_at
|
|
1962
|
-
};
|
|
1963
|
-
}
|
|
1964
|
-
|
|
1965
|
-
//#endregion
|
|
1966
|
-
//#region src/usage/token-calculator.ts
|
|
1967
|
-
/**
|
|
1968
|
-
* Token Calculator and Cost Estimator
|
|
1969
|
-
* Utility functions for calculating token usage and estimating costs for AI services
|
|
1970
|
-
*/
|
|
1971
|
-
const PRICING = {
|
|
1972
|
-
"text-embedding-3-large": { input: 13e-5 / 1e3 },
|
|
1973
|
-
"gpt-4o-mini": {
|
|
1974
|
-
input: .15 / 1e6,
|
|
1975
|
-
output: .6 / 1e6
|
|
1976
|
-
},
|
|
1977
|
-
"openai/gpt-4o-mini": {
|
|
1978
|
-
input: .15 / 1e6,
|
|
1979
|
-
output: .6 / 1e6
|
|
1980
|
-
}
|
|
1981
|
-
};
|
|
1982
|
-
/**
|
|
1983
|
-
* Calculate the cost in USD for a given model and token usage
|
|
1984
|
-
*/
|
|
1985
|
-
function calculateCost(model, tokens) {
|
|
1986
|
-
const pricing = PRICING[model];
|
|
1987
|
-
if (!pricing) {
|
|
1988
|
-
console.warn(`[Token Calculator] No pricing data for model: ${model}`);
|
|
1989
|
-
return 0;
|
|
1990
|
-
}
|
|
1991
|
-
let cost = 0;
|
|
1992
|
-
if ("input" in pricing && "output" in pricing) {
|
|
1993
|
-
cost += (tokens.input || 0) * pricing.input;
|
|
1994
|
-
cost += (tokens.output || 0) * pricing.output;
|
|
1995
|
-
} else if ("input" in pricing) cost += tokens.total * pricing.input;
|
|
1996
|
-
return cost;
|
|
1997
|
-
}
|
|
1998
|
-
/**
|
|
1999
|
-
* Create a spending entry for embedding operations
|
|
2000
|
-
*/
|
|
2001
|
-
function createEmbeddingSpending(model, tokens, timestamp) {
|
|
2002
|
-
const tokenUsage = {
|
|
2003
|
-
input: tokens,
|
|
2004
|
-
total: tokens
|
|
2005
|
-
};
|
|
2006
|
-
return {
|
|
2007
|
-
service: "openai_embedding",
|
|
2008
|
-
model,
|
|
2009
|
-
tokens: tokenUsage,
|
|
2010
|
-
cost_usd: calculateCost(model, tokenUsage),
|
|
2011
|
-
timestamp: (timestamp || /* @__PURE__ */ new Date()).toISOString()
|
|
2012
|
-
};
|
|
2013
|
-
}
|
|
2014
|
-
/**
|
|
2015
|
-
* Create a spending entry for LLM operations
|
|
2016
|
-
*/
|
|
2017
|
-
function createLLMSpending(model, inputTokens, outputTokens, timestamp) {
|
|
2018
|
-
const tokenUsage = {
|
|
2019
|
-
input: inputTokens,
|
|
2020
|
-
output: outputTokens,
|
|
2021
|
-
total: inputTokens + outputTokens
|
|
2022
|
-
};
|
|
2023
|
-
return {
|
|
2024
|
-
service: "openai_llm",
|
|
2025
|
-
model,
|
|
2026
|
-
tokens: tokenUsage,
|
|
2027
|
-
cost_usd: calculateCost(model, tokenUsage),
|
|
2028
|
-
timestamp: (timestamp || /* @__PURE__ */ new Date()).toISOString()
|
|
2029
|
-
};
|
|
2030
|
-
}
|
|
2031
|
-
/**
|
|
2032
|
-
* Calculate total tokens from an array of spending entries
|
|
2033
|
-
*/
|
|
2034
|
-
function calculateTotalTokens(spending) {
|
|
2035
|
-
return spending.reduce((total, entry) => total + entry.tokens.total, 0);
|
|
2036
|
-
}
|
|
2037
|
-
/**
|
|
2038
|
-
* Calculate total cost from an array of spending entries
|
|
2039
|
-
*/
|
|
2040
|
-
function calculateTotalCost(spending) {
|
|
2041
|
-
return spending.reduce((total, entry) => total + (entry.cost_usd || 0), 0);
|
|
2042
|
-
}
|
|
2043
|
-
/**
|
|
2044
|
-
* Estimate tokens from text length (rough approximation: 1 token ≈ 4 characters)
|
|
2045
|
-
*/
|
|
2046
|
-
function estimateTokensFromText(text) {
|
|
2047
|
-
return Math.ceil(text.length / 4);
|
|
2048
|
-
}
|
|
2049
|
-
/**
|
|
2050
|
-
* Format cost in USD with appropriate precision
|
|
2051
|
-
*/
|
|
2052
|
-
function formatCost(cost) {
|
|
2053
|
-
if (cost < .01) return `$${cost.toFixed(6)}`;
|
|
2054
|
-
else if (cost < 1) return `$${cost.toFixed(4)}`;
|
|
2055
|
-
else return `$${cost.toFixed(2)}`;
|
|
2056
|
-
}
|
|
2057
|
-
/**
|
|
2058
|
-
* Get spending breakdown by service
|
|
2059
|
-
*/
|
|
2060
|
-
function getSpendingBreakdown(spending) {
|
|
2061
|
-
const breakdown = {
|
|
2062
|
-
embedding: {
|
|
2063
|
-
tokens: 0,
|
|
2064
|
-
cost: 0
|
|
2065
|
-
},
|
|
2066
|
-
llm: {
|
|
2067
|
-
tokens: 0,
|
|
2068
|
-
cost: 0
|
|
2069
|
-
},
|
|
2070
|
-
total: {
|
|
2071
|
-
tokens: 0,
|
|
2072
|
-
cost: 0
|
|
2073
|
-
}
|
|
2074
|
-
};
|
|
2075
|
-
for (const entry of spending) {
|
|
2076
|
-
const tokens = entry.tokens.total;
|
|
2077
|
-
const cost = entry.cost_usd || 0;
|
|
2078
|
-
if (entry.service === "openai_embedding") {
|
|
2079
|
-
breakdown.embedding.tokens += tokens;
|
|
2080
|
-
breakdown.embedding.cost += cost;
|
|
2081
|
-
} else if (entry.service === "openai_llm") {
|
|
2082
|
-
breakdown.llm.tokens += tokens;
|
|
2083
|
-
breakdown.llm.cost += cost;
|
|
2084
|
-
}
|
|
2085
|
-
breakdown.total.tokens += tokens;
|
|
2086
|
-
breakdown.total.cost += cost;
|
|
2087
|
-
}
|
|
2088
|
-
return breakdown;
|
|
2089
|
-
}
|
|
2090
|
-
|
|
2091
|
-
//#endregion
|
|
2092
|
-
export { ChatProvider, FloatingChatManager_default as FloatingChatManager, calculateCost, calculateTotalCost, calculateTotalTokens, checkTokenLimit, createEmbeddingSpending, createLLMSpending, estimateTokensFromText, formatCost, getCurrentDailyUsage, getSpendingBreakdown, getUserDailyLimit, getUserUsageStats };
|
|
2093
|
-
//# sourceMappingURL=index.mjs.map
|
|
1816
|
+
export { ChatProvider, FloatingChatManager_default as FloatingChatManager };
|
|
1817
|
+
//# sourceMappingURL=react.mjs.map
|