@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 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),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@informedai/react",
3
- "version": "0.4.8",
3
+ "version": "0.4.10",
4
4
  "description": "React SDK for InformedAI Assistant - AI-powered content creation widget",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",