@informedai/react 0.4.8 → 0.4.10
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 +20 -3
- package/dist/index.mjs +20 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -536,13 +536,10 @@ function InformedAIProvider({ config, children }) {
|
|
|
536
536
|
};
|
|
537
537
|
}, [session?.id, startHeartbeat, stopHeartbeat, handleSessionDeleted, config]);
|
|
538
538
|
const handleSSEEvent = (0, import_react.useCallback)((event) => {
|
|
539
|
-
console.log("[InformedAI] SSE event:", event.type, event);
|
|
540
539
|
if (event.type === "content" && event.content) {
|
|
541
540
|
setStreamingContent((prev) => prev + event.content);
|
|
542
541
|
}
|
|
543
542
|
if (event.type === "done" || event.type === "session_update") {
|
|
544
|
-
console.log("[InformedAI] Done event - session:", event.session);
|
|
545
|
-
console.log("[InformedAI] Done event - widgetMessages:", event.session?.widgetMessages);
|
|
546
543
|
(0, import_react_dom.flushSync)(() => {
|
|
547
544
|
if (event.session) {
|
|
548
545
|
setSession(event.session);
|
|
@@ -564,6 +561,17 @@ function InformedAIProvider({ config, children }) {
|
|
|
564
561
|
const sendMessage = (0, import_react.useCallback)(async (message) => {
|
|
565
562
|
if (!clientRef.current || !session) return;
|
|
566
563
|
try {
|
|
564
|
+
const optimisticMessage = {
|
|
565
|
+
id: `temp-${Date.now()}`,
|
|
566
|
+
role: "user",
|
|
567
|
+
content: message,
|
|
568
|
+
type: "user_input",
|
|
569
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
570
|
+
};
|
|
571
|
+
setSession((prev) => prev ? {
|
|
572
|
+
...prev,
|
|
573
|
+
widgetMessages: [...prev.widgetMessages || [], optimisticMessage]
|
|
574
|
+
} : null);
|
|
567
575
|
setIsStreaming(true);
|
|
568
576
|
setStreamingContent("");
|
|
569
577
|
setError(null);
|
|
@@ -740,9 +748,17 @@ function AssistantWidget({ className, theme, position = "inline", defaultCollaps
|
|
|
740
748
|
const [isCollapsed, setIsCollapsed] = (0, import_react2.useState)(defaultCollapsed);
|
|
741
749
|
const [inputValue, setInputValue] = (0, import_react2.useState)("");
|
|
742
750
|
const messagesEndRef = (0, import_react2.useRef)(null);
|
|
751
|
+
const inputRef = (0, import_react2.useRef)(null);
|
|
752
|
+
const wasStreamingRef = (0, import_react2.useRef)(false);
|
|
743
753
|
(0, import_react2.useEffect)(() => {
|
|
744
754
|
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
745
755
|
}, [session?.widgetMessages, streamingContent]);
|
|
756
|
+
(0, import_react2.useEffect)(() => {
|
|
757
|
+
if (wasStreamingRef.current && !isStreaming) {
|
|
758
|
+
inputRef.current?.focus();
|
|
759
|
+
}
|
|
760
|
+
wasStreamingRef.current = isStreaming;
|
|
761
|
+
}, [isStreaming]);
|
|
746
762
|
const handleSubmit = async (e) => {
|
|
747
763
|
e.preventDefault();
|
|
748
764
|
if (!inputValue.trim() || isStreaming) return;
|
|
@@ -1019,6 +1035,7 @@ function AssistantWidget({ className, theme, position = "inline", defaultCollaps
|
|
|
1019
1035
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1020
1036
|
"input",
|
|
1021
1037
|
{
|
|
1038
|
+
ref: inputRef,
|
|
1022
1039
|
type: "text",
|
|
1023
1040
|
value: inputValue,
|
|
1024
1041
|
onChange: (e) => setInputValue(e.target.value),
|
package/dist/index.mjs
CHANGED
|
@@ -506,13 +506,10 @@ function InformedAIProvider({ config, children }) {
|
|
|
506
506
|
};
|
|
507
507
|
}, [session?.id, startHeartbeat, stopHeartbeat, handleSessionDeleted, config]);
|
|
508
508
|
const handleSSEEvent = useCallback((event) => {
|
|
509
|
-
console.log("[InformedAI] SSE event:", event.type, event);
|
|
510
509
|
if (event.type === "content" && event.content) {
|
|
511
510
|
setStreamingContent((prev) => prev + event.content);
|
|
512
511
|
}
|
|
513
512
|
if (event.type === "done" || event.type === "session_update") {
|
|
514
|
-
console.log("[InformedAI] Done event - session:", event.session);
|
|
515
|
-
console.log("[InformedAI] Done event - widgetMessages:", event.session?.widgetMessages);
|
|
516
513
|
flushSync(() => {
|
|
517
514
|
if (event.session) {
|
|
518
515
|
setSession(event.session);
|
|
@@ -534,6 +531,17 @@ function InformedAIProvider({ config, children }) {
|
|
|
534
531
|
const sendMessage = useCallback(async (message) => {
|
|
535
532
|
if (!clientRef.current || !session) return;
|
|
536
533
|
try {
|
|
534
|
+
const optimisticMessage = {
|
|
535
|
+
id: `temp-${Date.now()}`,
|
|
536
|
+
role: "user",
|
|
537
|
+
content: message,
|
|
538
|
+
type: "user_input",
|
|
539
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
540
|
+
};
|
|
541
|
+
setSession((prev) => prev ? {
|
|
542
|
+
...prev,
|
|
543
|
+
widgetMessages: [...prev.widgetMessages || [], optimisticMessage]
|
|
544
|
+
} : null);
|
|
537
545
|
setIsStreaming(true);
|
|
538
546
|
setStreamingContent("");
|
|
539
547
|
setError(null);
|
|
@@ -710,9 +718,17 @@ function AssistantWidget({ className, theme, position = "inline", defaultCollaps
|
|
|
710
718
|
const [isCollapsed, setIsCollapsed] = useState2(defaultCollapsed);
|
|
711
719
|
const [inputValue, setInputValue] = useState2("");
|
|
712
720
|
const messagesEndRef = useRef2(null);
|
|
721
|
+
const inputRef = useRef2(null);
|
|
722
|
+
const wasStreamingRef = useRef2(false);
|
|
713
723
|
useEffect2(() => {
|
|
714
724
|
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
715
725
|
}, [session?.widgetMessages, streamingContent]);
|
|
726
|
+
useEffect2(() => {
|
|
727
|
+
if (wasStreamingRef.current && !isStreaming) {
|
|
728
|
+
inputRef.current?.focus();
|
|
729
|
+
}
|
|
730
|
+
wasStreamingRef.current = isStreaming;
|
|
731
|
+
}, [isStreaming]);
|
|
716
732
|
const handleSubmit = async (e) => {
|
|
717
733
|
e.preventDefault();
|
|
718
734
|
if (!inputValue.trim() || isStreaming) return;
|
|
@@ -989,6 +1005,7 @@ function AssistantWidget({ className, theme, position = "inline", defaultCollaps
|
|
|
989
1005
|
/* @__PURE__ */ jsx2(
|
|
990
1006
|
"input",
|
|
991
1007
|
{
|
|
1008
|
+
ref: inputRef,
|
|
992
1009
|
type: "text",
|
|
993
1010
|
value: inputValue,
|
|
994
1011
|
onChange: (e) => setInputValue(e.target.value),
|