@informedai/react 0.4.2 → 0.4.4

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
@@ -359,19 +359,55 @@ function InformedAIProvider({ config, children }) {
359
359
  if (sessionIdToResume) {
360
360
  try {
361
361
  const resumedSession = await clientRef.current.getSession(sessionIdToResume);
362
- sess = resumedSession;
363
- doc = resumedSession.document;
364
- const embeddedDt = resumedSession.document.documentType;
365
- dt = {
366
- id: embeddedDt.id,
367
- name: embeddedDt.name,
368
- displayName: embeddedDt.displayName,
369
- schema: embeddedDt.schema,
370
- workspaceId: "",
371
- taskConfigs: {},
372
- createdAt: "",
373
- updatedAt: ""
374
- };
362
+ if (resumedSession.status === "ended") {
363
+ console.warn("Session was ended, creating new one");
364
+ if (shouldPersist && typeof window !== "undefined") {
365
+ try {
366
+ localStorage.removeItem(storageKey);
367
+ } catch (e) {
368
+ }
369
+ }
370
+ } else if (resumedSession.status === "abandoned") {
371
+ console.log("[InformedAI] Session was abandoned, resuming...");
372
+ try {
373
+ const activeSession = await clientRef.current.resumeSession(sessionIdToResume);
374
+ sess = activeSession;
375
+ doc = resumedSession.document;
376
+ const embeddedDt = resumedSession.document.documentType;
377
+ dt = {
378
+ id: embeddedDt.id,
379
+ name: embeddedDt.name,
380
+ displayName: embeddedDt.displayName,
381
+ schema: embeddedDt.schema,
382
+ workspaceId: "",
383
+ taskConfigs: {},
384
+ createdAt: "",
385
+ updatedAt: ""
386
+ };
387
+ } catch (resumeErr) {
388
+ console.error("[InformedAI] Failed to resume abandoned session:", resumeErr);
389
+ if (shouldPersist && typeof window !== "undefined") {
390
+ try {
391
+ localStorage.removeItem(storageKey);
392
+ } catch (e) {
393
+ }
394
+ }
395
+ }
396
+ } else {
397
+ sess = resumedSession;
398
+ doc = resumedSession.document;
399
+ const embeddedDt = resumedSession.document.documentType;
400
+ dt = {
401
+ id: embeddedDt.id,
402
+ name: embeddedDt.name,
403
+ displayName: embeddedDt.displayName,
404
+ schema: embeddedDt.schema,
405
+ workspaceId: "",
406
+ taskConfigs: {},
407
+ createdAt: "",
408
+ updatedAt: ""
409
+ };
410
+ }
375
411
  } catch (e) {
376
412
  console.warn("Failed to resume session, creating new one");
377
413
  if (shouldPersist && typeof window !== "undefined") {
@@ -477,17 +513,6 @@ function InformedAIProvider({ config, children }) {
477
513
  window.document.removeEventListener("visibilitychange", handleVisibilityChange);
478
514
  };
479
515
  }, [session?.id, startHeartbeat, stopHeartbeat, handleSessionDeleted, config]);
480
- (0, import_react.useEffect)(() => {
481
- const handleBeforeUnload = () => {
482
- if (clientRef.current && sessionIdRef.current) {
483
- clientRef.current.endSessionBeacon(sessionIdRef.current);
484
- }
485
- };
486
- window.addEventListener("beforeunload", handleBeforeUnload);
487
- return () => {
488
- window.removeEventListener("beforeunload", handleBeforeUnload);
489
- };
490
- }, []);
491
516
  const handleSSEEvent = (0, import_react.useCallback)((event) => {
492
517
  if (event.type === "content" && event.content) {
493
518
  setStreamingContent((prev) => prev + event.content);
@@ -516,13 +541,13 @@ function InformedAIProvider({ config, children }) {
516
541
  await clientRef.current.sendMessage(session.id, message, handleSSEEvent);
517
542
  } catch (err) {
518
543
  if (isSessionNotFoundError(err)) {
519
- setIsStreaming(false);
520
544
  await handleSessionDeleted();
521
545
  return;
522
546
  }
523
547
  const error2 = err instanceof Error ? err : new Error("Failed to send message");
524
548
  setError(error2);
525
549
  config.onError?.(error2);
550
+ } finally {
526
551
  setIsStreaming(false);
527
552
  }
528
553
  }, [session, handleSSEEvent, handleSessionDeleted, config]);
@@ -861,12 +886,13 @@ function AssistantWidget({ className, theme, position = "inline", defaultCollaps
861
886
  gap: "12px"
862
887
  },
863
888
  children: [
864
- session?.widgetMessages.map((msg) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
889
+ session?.widgetMessages.map((msg, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
865
890
  MessageBubble,
866
891
  {
867
892
  message: msg,
868
893
  theme,
869
- onQuickAction: handleQuickAction
894
+ onQuickAction: handleQuickAction,
895
+ isLatest: index === session.widgetMessages.length - 1
870
896
  },
871
897
  msg.id
872
898
  )),
@@ -1044,9 +1070,9 @@ function QuickActionButton({
1044
1070
  }
1045
1071
  );
1046
1072
  }
1047
- function MessageBubble({ message, theme, onQuickAction }) {
1073
+ function MessageBubble({ message, theme, onQuickAction, isLatest = false }) {
1048
1074
  const isUser = message.role === "user";
1049
- const hasQuickActions = message.quickActions && message.quickActions.length > 0;
1075
+ const hasQuickActions = isLatest && message.quickActions && message.quickActions.length > 0;
1050
1076
  if ((message.type === "quick_actions" || !message.content) && hasQuickActions) {
1051
1077
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
1052
1078
  display: "flex",
package/dist/index.mjs CHANGED
@@ -329,19 +329,55 @@ function InformedAIProvider({ config, children }) {
329
329
  if (sessionIdToResume) {
330
330
  try {
331
331
  const resumedSession = await clientRef.current.getSession(sessionIdToResume);
332
- sess = resumedSession;
333
- doc = resumedSession.document;
334
- const embeddedDt = resumedSession.document.documentType;
335
- dt = {
336
- id: embeddedDt.id,
337
- name: embeddedDt.name,
338
- displayName: embeddedDt.displayName,
339
- schema: embeddedDt.schema,
340
- workspaceId: "",
341
- taskConfigs: {},
342
- createdAt: "",
343
- updatedAt: ""
344
- };
332
+ if (resumedSession.status === "ended") {
333
+ console.warn("Session was ended, creating new one");
334
+ if (shouldPersist && typeof window !== "undefined") {
335
+ try {
336
+ localStorage.removeItem(storageKey);
337
+ } catch (e) {
338
+ }
339
+ }
340
+ } else if (resumedSession.status === "abandoned") {
341
+ console.log("[InformedAI] Session was abandoned, resuming...");
342
+ try {
343
+ const activeSession = await clientRef.current.resumeSession(sessionIdToResume);
344
+ sess = activeSession;
345
+ doc = resumedSession.document;
346
+ const embeddedDt = resumedSession.document.documentType;
347
+ dt = {
348
+ id: embeddedDt.id,
349
+ name: embeddedDt.name,
350
+ displayName: embeddedDt.displayName,
351
+ schema: embeddedDt.schema,
352
+ workspaceId: "",
353
+ taskConfigs: {},
354
+ createdAt: "",
355
+ updatedAt: ""
356
+ };
357
+ } catch (resumeErr) {
358
+ console.error("[InformedAI] Failed to resume abandoned session:", resumeErr);
359
+ if (shouldPersist && typeof window !== "undefined") {
360
+ try {
361
+ localStorage.removeItem(storageKey);
362
+ } catch (e) {
363
+ }
364
+ }
365
+ }
366
+ } else {
367
+ sess = resumedSession;
368
+ doc = resumedSession.document;
369
+ const embeddedDt = resumedSession.document.documentType;
370
+ dt = {
371
+ id: embeddedDt.id,
372
+ name: embeddedDt.name,
373
+ displayName: embeddedDt.displayName,
374
+ schema: embeddedDt.schema,
375
+ workspaceId: "",
376
+ taskConfigs: {},
377
+ createdAt: "",
378
+ updatedAt: ""
379
+ };
380
+ }
345
381
  } catch (e) {
346
382
  console.warn("Failed to resume session, creating new one");
347
383
  if (shouldPersist && typeof window !== "undefined") {
@@ -447,17 +483,6 @@ function InformedAIProvider({ config, children }) {
447
483
  window.document.removeEventListener("visibilitychange", handleVisibilityChange);
448
484
  };
449
485
  }, [session?.id, startHeartbeat, stopHeartbeat, handleSessionDeleted, config]);
450
- useEffect(() => {
451
- const handleBeforeUnload = () => {
452
- if (clientRef.current && sessionIdRef.current) {
453
- clientRef.current.endSessionBeacon(sessionIdRef.current);
454
- }
455
- };
456
- window.addEventListener("beforeunload", handleBeforeUnload);
457
- return () => {
458
- window.removeEventListener("beforeunload", handleBeforeUnload);
459
- };
460
- }, []);
461
486
  const handleSSEEvent = useCallback((event) => {
462
487
  if (event.type === "content" && event.content) {
463
488
  setStreamingContent((prev) => prev + event.content);
@@ -486,13 +511,13 @@ function InformedAIProvider({ config, children }) {
486
511
  await clientRef.current.sendMessage(session.id, message, handleSSEEvent);
487
512
  } catch (err) {
488
513
  if (isSessionNotFoundError(err)) {
489
- setIsStreaming(false);
490
514
  await handleSessionDeleted();
491
515
  return;
492
516
  }
493
517
  const error2 = err instanceof Error ? err : new Error("Failed to send message");
494
518
  setError(error2);
495
519
  config.onError?.(error2);
520
+ } finally {
496
521
  setIsStreaming(false);
497
522
  }
498
523
  }, [session, handleSSEEvent, handleSessionDeleted, config]);
@@ -831,12 +856,13 @@ function AssistantWidget({ className, theme, position = "inline", defaultCollaps
831
856
  gap: "12px"
832
857
  },
833
858
  children: [
834
- session?.widgetMessages.map((msg) => /* @__PURE__ */ jsx2(
859
+ session?.widgetMessages.map((msg, index) => /* @__PURE__ */ jsx2(
835
860
  MessageBubble,
836
861
  {
837
862
  message: msg,
838
863
  theme,
839
- onQuickAction: handleQuickAction
864
+ onQuickAction: handleQuickAction,
865
+ isLatest: index === session.widgetMessages.length - 1
840
866
  },
841
867
  msg.id
842
868
  )),
@@ -1014,9 +1040,9 @@ function QuickActionButton({
1014
1040
  }
1015
1041
  );
1016
1042
  }
1017
- function MessageBubble({ message, theme, onQuickAction }) {
1043
+ function MessageBubble({ message, theme, onQuickAction, isLatest = false }) {
1018
1044
  const isUser = message.role === "user";
1019
- const hasQuickActions = message.quickActions && message.quickActions.length > 0;
1045
+ const hasQuickActions = isLatest && message.quickActions && message.quickActions.length > 0;
1020
1046
  if ((message.type === "quick_actions" || !message.content) && hasQuickActions) {
1021
1047
  return /* @__PURE__ */ jsxs("div", { style: {
1022
1048
  display: "flex",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@informedai/react",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
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",