@usecrow/ui 0.1.10 → 0.1.12
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 +183 -69
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +183 -69
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -119,7 +119,9 @@ function useChat({
|
|
|
119
119
|
message,
|
|
120
120
|
conversation_id: conversationId,
|
|
121
121
|
identity_token: identityToken,
|
|
122
|
-
model: selectedModel
|
|
122
|
+
model: selectedModel,
|
|
123
|
+
user_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
124
|
+
user_local_time: (/* @__PURE__ */ new Date()).toLocaleString()
|
|
123
125
|
}),
|
|
124
126
|
signal: abortControllerRef.current.signal
|
|
125
127
|
});
|
|
@@ -389,7 +391,9 @@ function useChat({
|
|
|
389
391
|
tool_name: toolName,
|
|
390
392
|
result,
|
|
391
393
|
identity_token: identityToken,
|
|
392
|
-
model: selectedModel
|
|
394
|
+
model: selectedModel,
|
|
395
|
+
user_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
396
|
+
user_local_time: (/* @__PURE__ */ new Date()).toLocaleString()
|
|
393
397
|
})
|
|
394
398
|
});
|
|
395
399
|
if (!response.ok) {
|
|
@@ -648,6 +652,16 @@ function useWorkflow({
|
|
|
648
652
|
exitWorkflow
|
|
649
653
|
};
|
|
650
654
|
}
|
|
655
|
+
var SDK_DEFAULT_TOOLS = {
|
|
656
|
+
refreshPage: async () => {
|
|
657
|
+
try {
|
|
658
|
+
window.location.reload();
|
|
659
|
+
return { status: "success", data: { message: "Page refresh initiated" } };
|
|
660
|
+
} catch (error) {
|
|
661
|
+
return { status: "error", error: String(error) };
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
};
|
|
651
665
|
function useCrowAPI({ onIdentified, onReset } = {}) {
|
|
652
666
|
const onIdentifiedRef = React3.useRef(onIdentified);
|
|
653
667
|
const onResetRef = React3.useRef(onReset);
|
|
@@ -657,6 +671,15 @@ function useCrowAPI({ onIdentified, onReset } = {}) {
|
|
|
657
671
|
onResetRef.current = onReset;
|
|
658
672
|
});
|
|
659
673
|
React3.useEffect(() => {
|
|
674
|
+
if (!window.__crow_client_tools) {
|
|
675
|
+
window.__crow_client_tools = {};
|
|
676
|
+
}
|
|
677
|
+
for (const [toolName, handler] of Object.entries(SDK_DEFAULT_TOOLS)) {
|
|
678
|
+
if (!window.__crow_client_tools[toolName]) {
|
|
679
|
+
window.__crow_client_tools[toolName] = handler;
|
|
680
|
+
console.log(`[Crow] Registered default tool: ${toolName}`);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
660
683
|
window.crow = function(command, options) {
|
|
661
684
|
const opts = options;
|
|
662
685
|
switch (command) {
|
|
@@ -1149,7 +1172,9 @@ function useWidgetStyles2() {
|
|
|
1149
1172
|
const context = React3.useContext(WidgetStyleContext);
|
|
1150
1173
|
return context?.styles ?? DEFAULT_WIDGET_STYLES;
|
|
1151
1174
|
}
|
|
1152
|
-
var CopilotStyleContext = React3.createContext(
|
|
1175
|
+
var CopilotStyleContext = React3.createContext(
|
|
1176
|
+
null
|
|
1177
|
+
);
|
|
1153
1178
|
function CopilotStyleProvider({
|
|
1154
1179
|
children,
|
|
1155
1180
|
styles,
|
|
@@ -1175,6 +1200,7 @@ function useCopilotStyles2() {
|
|
|
1175
1200
|
const context = React3.useContext(CopilotStyleContext);
|
|
1176
1201
|
return context?.styles ?? DEFAULT_COPILOT_STYLES;
|
|
1177
1202
|
}
|
|
1203
|
+
var PASSTHROUGH_KEYS = /* @__PURE__ */ new Set(["Escape", "Tab"]);
|
|
1178
1204
|
function ShadowContainer({
|
|
1179
1205
|
children,
|
|
1180
1206
|
styles,
|
|
@@ -1189,6 +1215,51 @@ function ShadowContainer({
|
|
|
1189
1215
|
setShadowRoot(shadow);
|
|
1190
1216
|
}
|
|
1191
1217
|
}, []);
|
|
1218
|
+
React3.useEffect(() => {
|
|
1219
|
+
if (!shadowRoot || !hostRef.current) return;
|
|
1220
|
+
const hostElement = hostRef.current;
|
|
1221
|
+
const stopPropagationHandler = (e) => {
|
|
1222
|
+
const keyEvent = e;
|
|
1223
|
+
if (keyEvent.key && PASSTHROUGH_KEYS.has(keyEvent.key)) {
|
|
1224
|
+
return;
|
|
1225
|
+
}
|
|
1226
|
+
e.stopPropagation();
|
|
1227
|
+
};
|
|
1228
|
+
shadowRoot.addEventListener("keydown", stopPropagationHandler);
|
|
1229
|
+
shadowRoot.addEventListener("keyup", stopPropagationHandler);
|
|
1230
|
+
shadowRoot.addEventListener("keypress", stopPropagationHandler);
|
|
1231
|
+
let lastFocusedElement = null;
|
|
1232
|
+
const trackFocus = (e) => {
|
|
1233
|
+
lastFocusedElement = e.target;
|
|
1234
|
+
};
|
|
1235
|
+
const protectFocus = (e) => {
|
|
1236
|
+
if (e.key && PASSTHROUGH_KEYS.has(e.key)) {
|
|
1237
|
+
return;
|
|
1238
|
+
}
|
|
1239
|
+
const path = e.composedPath();
|
|
1240
|
+
if (!path.includes(hostElement) && !path.includes(shadowRoot)) {
|
|
1241
|
+
return;
|
|
1242
|
+
}
|
|
1243
|
+
if (lastFocusedElement) {
|
|
1244
|
+
const elementToRestore = lastFocusedElement;
|
|
1245
|
+
queueMicrotask(() => {
|
|
1246
|
+
const activeInShadow = shadowRoot.activeElement;
|
|
1247
|
+
if (!activeInShadow) {
|
|
1248
|
+
elementToRestore.focus();
|
|
1249
|
+
}
|
|
1250
|
+
});
|
|
1251
|
+
}
|
|
1252
|
+
};
|
|
1253
|
+
shadowRoot.addEventListener("focusin", trackFocus);
|
|
1254
|
+
document.addEventListener("keydown", protectFocus, { capture: true });
|
|
1255
|
+
return () => {
|
|
1256
|
+
shadowRoot.removeEventListener("keydown", stopPropagationHandler);
|
|
1257
|
+
shadowRoot.removeEventListener("keyup", stopPropagationHandler);
|
|
1258
|
+
shadowRoot.removeEventListener("keypress", stopPropagationHandler);
|
|
1259
|
+
shadowRoot.removeEventListener("focusin", trackFocus);
|
|
1260
|
+
document.removeEventListener("keydown", protectFocus, { capture: true });
|
|
1261
|
+
};
|
|
1262
|
+
}, [shadowRoot]);
|
|
1192
1263
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: hostRef, id: hostId, className: hostClassName, children: shadowRoot && reactDom.createPortal(
|
|
1193
1264
|
/* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1194
1265
|
/* @__PURE__ */ jsxRuntime.jsx("style", { children: styles }),
|
|
@@ -1382,7 +1453,14 @@ function StreamingText({
|
|
|
1382
1453
|
...props,
|
|
1383
1454
|
children
|
|
1384
1455
|
}
|
|
1385
|
-
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1456
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1457
|
+
"code",
|
|
1458
|
+
{
|
|
1459
|
+
className: `crow-text-gray-200 ${className || ""}`,
|
|
1460
|
+
...props,
|
|
1461
|
+
children
|
|
1462
|
+
}
|
|
1463
|
+
);
|
|
1386
1464
|
},
|
|
1387
1465
|
pre: ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "crow-bg-gray-800 crow-text-gray-200 crow-p-3 crow-rounded-lg crow-my-2 crow-overflow-x-auto crow-text-sm", children })
|
|
1388
1466
|
},
|
|
@@ -1496,7 +1574,12 @@ function ShimmeringContent({ children }) {
|
|
|
1496
1574
|
}
|
|
1497
1575
|
);
|
|
1498
1576
|
}
|
|
1499
|
-
function ReasoningTrace({
|
|
1577
|
+
function ReasoningTrace({
|
|
1578
|
+
thinking,
|
|
1579
|
+
isComplete,
|
|
1580
|
+
toolCalls = [],
|
|
1581
|
+
isWaiting = false
|
|
1582
|
+
}) {
|
|
1500
1583
|
const hasThinking = !!thinking && thinking.trim().length > 0;
|
|
1501
1584
|
const hasToolCalls = toolCalls.length > 0;
|
|
1502
1585
|
if (!isWaiting && !hasThinking && !hasToolCalls) return null;
|
|
@@ -1512,7 +1595,10 @@ function WaitingIndicator() {
|
|
|
1512
1595
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "crow-font-medium", children: /* @__PURE__ */ jsxRuntime.jsx(ShimmeringContent, { children: getRandomThinkingMessage() }) })
|
|
1513
1596
|
] });
|
|
1514
1597
|
}
|
|
1515
|
-
function ThinkingBlock({
|
|
1598
|
+
function ThinkingBlock({
|
|
1599
|
+
thinking,
|
|
1600
|
+
isComplete
|
|
1601
|
+
}) {
|
|
1516
1602
|
const [isExpanded, setIsExpanded] = React3.useState(!isComplete);
|
|
1517
1603
|
React3.useLayoutEffect(() => {
|
|
1518
1604
|
setIsExpanded(!isComplete);
|
|
@@ -1706,64 +1792,62 @@ function MessageList({
|
|
|
1706
1792
|
msg.id
|
|
1707
1793
|
)) });
|
|
1708
1794
|
}
|
|
1709
|
-
var MessagesContainer = React3.forwardRef(
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
const
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
const
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
container.
|
|
1726
|
-
|
|
1727
|
-
behavior: "smooth"
|
|
1728
|
-
});
|
|
1729
|
-
}, [containerRef]);
|
|
1730
|
-
React3.useEffect(() => {
|
|
1731
|
-
const container = containerRef.current;
|
|
1732
|
-
if (!container) return;
|
|
1733
|
-
const handleScroll = () => {
|
|
1734
|
-
isUserScrollingRef.current = !isNearBottom();
|
|
1735
|
-
};
|
|
1736
|
-
container.addEventListener("scroll", handleScroll, { passive: true });
|
|
1737
|
-
return () => container.removeEventListener("scroll", handleScroll);
|
|
1738
|
-
}, [containerRef, isNearBottom]);
|
|
1739
|
-
React3.useEffect(() => {
|
|
1740
|
-
const container = containerRef.current;
|
|
1741
|
-
if (!container) return;
|
|
1742
|
-
const currentHeight = container.scrollHeight;
|
|
1743
|
-
const heightChanged = currentHeight !== lastScrollHeightRef.current;
|
|
1744
|
-
if (heightChanged) {
|
|
1745
|
-
lastScrollHeightRef.current = currentHeight;
|
|
1746
|
-
if (!isUserScrollingRef.current || isNearBottom()) {
|
|
1747
|
-
scrollToBottom();
|
|
1748
|
-
}
|
|
1749
|
-
}
|
|
1795
|
+
var MessagesContainer = React3.forwardRef(({ children }, ref) => {
|
|
1796
|
+
const styles = useWidgetStyles2();
|
|
1797
|
+
const internalRef = React3.useRef(null);
|
|
1798
|
+
const lastScrollHeightRef = React3.useRef(0);
|
|
1799
|
+
const isUserScrollingRef = React3.useRef(false);
|
|
1800
|
+
const containerRef = ref || internalRef;
|
|
1801
|
+
const isNearBottom = React3.useCallback(() => {
|
|
1802
|
+
const container = containerRef.current;
|
|
1803
|
+
if (!container) return true;
|
|
1804
|
+
const threshold = 100;
|
|
1805
|
+
return container.scrollHeight - container.scrollTop - container.clientHeight < threshold;
|
|
1806
|
+
}, [containerRef]);
|
|
1807
|
+
const scrollToBottom = React3.useCallback(() => {
|
|
1808
|
+
const container = containerRef.current;
|
|
1809
|
+
if (!container) return;
|
|
1810
|
+
container.scrollTo({
|
|
1811
|
+
top: container.scrollHeight,
|
|
1812
|
+
behavior: "smooth"
|
|
1750
1813
|
});
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1814
|
+
}, [containerRef]);
|
|
1815
|
+
React3.useEffect(() => {
|
|
1816
|
+
const container = containerRef.current;
|
|
1817
|
+
if (!container) return;
|
|
1818
|
+
const handleScroll = () => {
|
|
1819
|
+
isUserScrollingRef.current = !isNearBottom();
|
|
1820
|
+
};
|
|
1821
|
+
container.addEventListener("scroll", handleScroll, { passive: true });
|
|
1822
|
+
return () => container.removeEventListener("scroll", handleScroll);
|
|
1823
|
+
}, [containerRef, isNearBottom]);
|
|
1824
|
+
React3.useEffect(() => {
|
|
1825
|
+
const container = containerRef.current;
|
|
1826
|
+
if (!container) return;
|
|
1827
|
+
const currentHeight = container.scrollHeight;
|
|
1828
|
+
const heightChanged = currentHeight !== lastScrollHeightRef.current;
|
|
1829
|
+
if (heightChanged) {
|
|
1830
|
+
lastScrollHeightRef.current = currentHeight;
|
|
1831
|
+
if (!isUserScrollingRef.current || isNearBottom()) {
|
|
1832
|
+
scrollToBottom();
|
|
1763
1833
|
}
|
|
1764
|
-
|
|
1765
|
-
}
|
|
1766
|
-
|
|
1834
|
+
}
|
|
1835
|
+
});
|
|
1836
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1837
|
+
framerMotion.motion.div,
|
|
1838
|
+
{
|
|
1839
|
+
ref: containerRef,
|
|
1840
|
+
id: MESSAGES_CONTAINER_ID,
|
|
1841
|
+
initial: { opacity: 0 },
|
|
1842
|
+
animate: { opacity: 1 },
|
|
1843
|
+
exit: { opacity: 0 },
|
|
1844
|
+
transition: { duration: styles.animations.duration },
|
|
1845
|
+
className: "crow-relative crow-flex-1 crow-min-h-0 crow-rounded-2xl crow-mb-3 crow-overflow-y-auto crow-p-4 crow-space-y-3 crow-pointer-events-auto",
|
|
1846
|
+
style: { background: styles.colors.messagesBackground },
|
|
1847
|
+
children
|
|
1848
|
+
}
|
|
1849
|
+
);
|
|
1850
|
+
});
|
|
1767
1851
|
MessagesContainer.displayName = "MessagesContainer";
|
|
1768
1852
|
function ConversationList({
|
|
1769
1853
|
conversations,
|
|
@@ -2035,7 +2119,13 @@ var PromptInput = React3__default.default.forwardRef(
|
|
|
2035
2119
|
}
|
|
2036
2120
|
);
|
|
2037
2121
|
PromptInput.displayName = "PromptInput";
|
|
2038
|
-
var PromptInputTextarea = ({
|
|
2122
|
+
var PromptInputTextarea = ({
|
|
2123
|
+
className,
|
|
2124
|
+
onKeyDown,
|
|
2125
|
+
disableAutosize = false,
|
|
2126
|
+
placeholder,
|
|
2127
|
+
...props
|
|
2128
|
+
}) => {
|
|
2039
2129
|
const { value, setValue, maxHeight, onSubmit, disabled } = usePromptInput();
|
|
2040
2130
|
const textareaRef = React3__default.default.useRef(null);
|
|
2041
2131
|
React3__default.default.useEffect(() => {
|
|
@@ -2068,7 +2158,14 @@ var PromptInputActions = ({
|
|
|
2068
2158
|
children,
|
|
2069
2159
|
className,
|
|
2070
2160
|
...props
|
|
2071
|
-
}) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2161
|
+
}) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2162
|
+
"div",
|
|
2163
|
+
{
|
|
2164
|
+
className: cn("crow-flex crow-items-center crow-gap-2", className),
|
|
2165
|
+
...props,
|
|
2166
|
+
children
|
|
2167
|
+
}
|
|
2168
|
+
);
|
|
2072
2169
|
var PromptInputAction = ({
|
|
2073
2170
|
tooltip,
|
|
2074
2171
|
children,
|
|
@@ -2115,7 +2212,13 @@ var PromptInputBox = React3__default.default.forwardRef(
|
|
|
2115
2212
|
disabled: isLoading,
|
|
2116
2213
|
ref: ref || promptBoxRef,
|
|
2117
2214
|
children: [
|
|
2118
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "crow-transition-all crow-duration-300 crow-opacity-100", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2215
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "crow-transition-all crow-duration-300 crow-opacity-100", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2216
|
+
PromptInputTextarea,
|
|
2217
|
+
{
|
|
2218
|
+
placeholder,
|
|
2219
|
+
className: "crow-text-base"
|
|
2220
|
+
}
|
|
2221
|
+
) }),
|
|
2119
2222
|
/* @__PURE__ */ jsxRuntime.jsxs(PromptInputActions, { className: "crow-flex crow-items-center crow-justify-between crow-gap-2 crow-p-0 crow-pt-1", children: [
|
|
2120
2223
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "crow-flex crow-items-center", children: availableModels.length > 0 && onModelChange && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2121
2224
|
ModelSelector,
|
|
@@ -2148,10 +2251,21 @@ var PromptInputBox = React3__default.default.forwardRef(
|
|
|
2148
2251
|
handleSubmit();
|
|
2149
2252
|
}
|
|
2150
2253
|
},
|
|
2151
|
-
children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2254
|
+
children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2255
|
+
lucideReact.Square,
|
|
2256
|
+
{
|
|
2257
|
+
className: "crow-h-3.5 crow-w-3.5 crow-text-white",
|
|
2258
|
+
style: { fill: "white" }
|
|
2259
|
+
}
|
|
2260
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2261
|
+
lucideReact.ArrowUp,
|
|
2262
|
+
{
|
|
2263
|
+
className: cn(
|
|
2264
|
+
"crow-h-3.5 crow-w-3.5",
|
|
2265
|
+
hasContent ? "crow-text-white" : "crow-text-gray-400"
|
|
2266
|
+
)
|
|
2267
|
+
}
|
|
2268
|
+
)
|
|
2155
2269
|
}
|
|
2156
2270
|
)
|
|
2157
2271
|
}
|