@skippr/live-agent-sdk 0.129.0 → 0.130.0

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.
@@ -4954,7 +4954,8 @@ var MATCH_DEBOUNCE_MS = 400;
4954
4954
  function useAdoptionGoals({
4955
4955
  enabled,
4956
4956
  bearerToken,
4957
- authedFetch
4957
+ authedFetch,
4958
+ agentId
4958
4959
  }) {
4959
4960
  const [candidates, setCandidates] = useState11([]);
4960
4961
  const [deepLinkedGoal, setDeepLinkedGoal] = useState11(null);
@@ -4968,7 +4969,8 @@ function useAdoptionGoals({
4968
4969
  headers: { "Content-Type": "application/json" },
4969
4970
  body: JSON.stringify({
4970
4971
  url: window.location.origin + window.location.pathname,
4971
- ...tipSlug ? { tipSlug } : {}
4972
+ ...tipSlug ? { tipSlug } : {},
4973
+ ...agentId ? { agentId } : {}
4972
4974
  })
4973
4975
  });
4974
4976
  if (!resp.ok) {
@@ -4986,7 +4988,7 @@ function useAdoptionGoals({
4986
4988
  } finally {
4987
4989
  setHasResolved(true);
4988
4990
  }
4989
- }, [authedFetch, tipSlug]);
4991
+ }, [authedFetch, tipSlug, agentId]);
4990
4992
  useEffect13(() => {
4991
4993
  if (!enabled || !bearerToken) {
4992
4994
  setCandidates([]);
@@ -5021,17 +5023,7 @@ function useAdoptionGoals({
5021
5023
  return hashSpecific;
5022
5024
  return candidates.filter((goal) => goal.hashPattern === null);
5023
5025
  }, [candidates, hash]);
5024
- const postStatus = useCallback11((goalId, status) => {
5025
- authedFetch(`${API_URL}/v1/adoption/goals/${goalId}/status`, {
5026
- method: "POST",
5027
- headers: { "Content-Type": "application/json" },
5028
- body: JSON.stringify({ status })
5029
- }).catch((e) => console.warn("[Skippr] adoption status update failed", e));
5030
- }, [authedFetch]);
5031
- const attendGoal = useCallback11((goalId) => {
5032
- postStatus(goalId, "attended" /* Attended */);
5033
- }, [postStatus]);
5034
- return { goals, deepLinkedGoal, hasTipSlug: tipSlug !== null, hasResolved, attendGoal };
5026
+ return { goals, deepLinkedGoal, hasTipSlug: tipSlug !== null, hasResolved };
5035
5027
  }
5036
5028
 
5037
5029
  // src/hooks/useAuth.ts
@@ -5553,7 +5545,7 @@ function usePlanUpdates() {
5553
5545
  // src/hooks/useSession.ts
5554
5546
  import { useCallback as useCallback15, useEffect as useEffect20, useRef as useRef15, useState as useState17 } from "react";
5555
5547
  var API_URL4 = "https://app.skippr.ai/api";
5556
- var SDK_VERSION = "0.129.0";
5548
+ var SDK_VERSION = "0.130.0";
5557
5549
  async function fetchSessionMessages(sessionId, authedFetch) {
5558
5550
  try {
5559
5551
  const resp = await authedFetch(`${API_URL4}/v1/sessions/${sessionId}/messages`);
@@ -8600,7 +8592,20 @@ function HighlightOverlay() {
8600
8592
  }
8601
8593
 
8602
8594
  // src/components/MinimizedBubble.tsx
8603
- import { useContext as useContext11, useEffect as useEffect28, useRef as useRef22, useState as useState22 } from "react";
8595
+ import { useContext as useContext12, useEffect as useEffect28, useRef as useRef22, useState as useState22 } from "react";
8596
+
8597
+ // src/hooks/useAdoptionTips.ts
8598
+ import { useContext as useContext11 } from "react";
8599
+ function useAdoptionTips() {
8600
+ const ctx = useContext11(LiveAgentContext);
8601
+ if (!ctx) {
8602
+ throw new Error("useAdoptionTips must be used within a <LiveAgent> provider");
8603
+ }
8604
+ const { adoptionGoals, hasResolvedModules } = ctx;
8605
+ if (hasLiveSession(ctx) || !hasResolvedModules || adoptionGoals.length === 0)
8606
+ return [];
8607
+ return adoptionGoals.slice(0, MAX_ADOPTION_TIPS);
8608
+ }
8604
8609
 
8605
8610
  // src/hooks/useLauncherDrag.ts
8606
8611
  import { useEffect as useEffect27, useRef as useRef21 } from "react";
@@ -9024,7 +9029,7 @@ function MinimizedBubble({
9024
9029
  onDismissWelcome
9025
9030
  }) {
9026
9031
  const copy = useChromeCopy();
9027
- const ctx = useContext11(LiveAgentContext);
9032
+ const ctx = useContext12(LiveAgentContext);
9028
9033
  if (!ctx) {
9029
9034
  throw new Error("MinimizedBubble must be used within a <LiveAgent> provider");
9030
9035
  }
@@ -9033,13 +9038,11 @@ function MinimizedBubble({
9033
9038
  position,
9034
9039
  launcherBottomPx,
9035
9040
  popsDown,
9036
- adoptionGoals,
9037
9041
  startAdoptionSession,
9038
9042
  isAuthenticated,
9039
9043
  displayModules,
9040
9044
  defaultAgentId,
9041
9045
  startDefaultSession,
9042
- hasResolvedModules,
9043
9046
  isLoadingModules,
9044
9047
  selectModule,
9045
9048
  expandPanel,
@@ -9092,7 +9095,8 @@ function MinimizedBubble({
9092
9095
  const pillCandidates = actionableModules.filter((module) => module.mode !== AGENT_MODE.AlwaysOn);
9093
9096
  const onboardingModule = pillCandidates.find((module) => module.type === "onboarding");
9094
9097
  const modulePills = onboardingModule ? [onboardingModule] : pillCandidates.slice(0, MAX_MODULE_PILLS).reverse();
9095
- const goalsEligible = adoptionGoals.length > 0 && !onboardingModule && hasResolvedModules;
9098
+ const tips = useAdoptionTips();
9099
+ const goalsEligible = tips.length > 0;
9096
9100
  useEffect28(() => {
9097
9101
  if (!goalsEligible)
9098
9102
  return;
@@ -9105,7 +9109,7 @@ function MinimizedBubble({
9105
9109
  const timer = setTimeout(() => setGoalsAutoHidden(true), GOALS_AUTO_HIDE_MS);
9106
9110
  return () => clearTimeout(timer);
9107
9111
  }, [goalsEligible, visitHref]);
9108
- const matchedGoals = goalsEligible ? adoptionGoals.slice(0, MAX_GOAL_BUBBLES) : [];
9112
+ const matchedGoals = goalsEligible ? tips.slice(0, MAX_GOAL_BUBBLES) : [];
9109
9113
  const goalsHidden = goalsAutoHidden && !isLauncherHovered;
9110
9114
  const [goalsUnmounted, setGoalsUnmounted] = useState22(false);
9111
9115
  useEffect28(() => {
@@ -9161,7 +9165,7 @@ function MinimizedBubble({
9161
9165
  }, module.id))
9162
9166
  ]
9163
9167
  }),
9164
- welcomeMessage && !welcomeDismissed && adoptionGoals.length === 0 && modulePills.length === 0 && /* @__PURE__ */ jsx22(WelcomeBubble, {
9168
+ welcomeMessage && !welcomeDismissed && tips.length === 0 && modulePills.length === 0 && /* @__PURE__ */ jsx22(WelcomeBubble, {
9165
9169
  message: welcomeMessage,
9166
9170
  position,
9167
9171
  popsDown,
@@ -9604,7 +9608,7 @@ function PageActionHandler() {
9604
9608
  }
9605
9609
 
9606
9610
  // src/components/SessionControlBar.tsx
9607
- import { useCallback as useCallback22, useContext as useContext12, useEffect as useEffect33, useState as useState25 } from "react";
9611
+ import { useCallback as useCallback22, useContext as useContext13, useEffect as useEffect33, useState as useState25 } from "react";
9608
9612
 
9609
9613
  // src/hooks/useActionControl.ts
9610
9614
  import { useLocalParticipant as useLocalParticipant7 } from "@livekit/components-react/hooks";
@@ -10060,7 +10064,7 @@ function SessionControlBar() {
10060
10064
  variant,
10061
10065
  agentControls
10062
10066
  } = useLiveAgent();
10063
- const internalCtx = useContext12(LiveAgentContext);
10067
+ const internalCtx = useContext13(LiveAgentContext);
10064
10068
  if (!internalCtx) {
10065
10069
  throw new Error("SessionControlBar must be used within a <LiveAgent> provider");
10066
10070
  }
@@ -10423,10 +10427,10 @@ function ShadowHost({
10423
10427
  }
10424
10428
 
10425
10429
  // src/components/Sidebar.tsx
10426
- import { useCallback as useCallback28, useContext as useContext19, useEffect as useEffect41, useRef as useRef35 } from "react";
10430
+ import { useCallback as useCallback28, useContext as useContext20, useEffect as useEffect41, useRef as useRef35 } from "react";
10427
10431
 
10428
10432
  // src/hooks/useCombinedMessages.ts
10429
- import { useContext as useContext13, useMemo as useMemo9 } from "react";
10433
+ import { useContext as useContext14, useMemo as useMemo9 } from "react";
10430
10434
 
10431
10435
  // src/hooks/useChatMessages.ts
10432
10436
  import { useChat, useLocalParticipant as useLocalParticipant10 } from "@livekit/components-react/hooks";
@@ -10508,7 +10512,7 @@ function useCombinedMessages() {
10508
10512
  const { transcriptMessages } = useStreamingTranscript();
10509
10513
  const { chatMessages, sendChatMessage, isSendingChat } = useChatMessages();
10510
10514
  const { state: agentState } = useAgentVoiceState();
10511
- const historyMessages = useContext13(LiveAgentContext)?.historyMessages ?? [];
10515
+ const historyMessages = useContext14(LiveAgentContext)?.historyMessages ?? [];
10512
10516
  const liveMessages = useMemo9(() => {
10513
10517
  if (chatMessages.length === 0)
10514
10518
  return transcriptMessages;
@@ -10556,7 +10560,7 @@ function useLinkCard() {
10556
10560
  }
10557
10561
 
10558
10562
  // src/hooks/usePhaseUpdates.ts
10559
- import { useCallback as useCallback24, useContext as useContext14, useEffect as useEffect34, useMemo as useMemo10 } from "react";
10563
+ import { useCallback as useCallback24, useContext as useContext15, useEffect as useEffect34, useMemo as useMemo10 } from "react";
10560
10564
  function parsePhases(json) {
10561
10565
  try {
10562
10566
  const data = JSON.parse(json);
@@ -10569,7 +10573,7 @@ function parsePhases(json) {
10569
10573
  function usePhaseUpdates() {
10570
10574
  const parse = useCallback24(parsePhases, []);
10571
10575
  const livePhases = useAgentState("phases", parse, []);
10572
- const ctx = useContext14(LiveAgentContext);
10576
+ const ctx = useContext15(LiveAgentContext);
10573
10577
  useEffect34(() => {
10574
10578
  if (livePhases.length > 0)
10575
10579
  ctx?.setPhasesSnapshot(livePhases);
@@ -10792,14 +10796,14 @@ function panelTransformOrigin(popsDown, isLeftAligned) {
10792
10796
  }
10793
10797
 
10794
10798
  // src/components/ChatHeader.tsx
10795
- import { useContext as useContext16 } from "react";
10799
+ import { useContext as useContext17 } from "react";
10796
10800
 
10797
10801
  // src/hooks/useTextMode.ts
10798
10802
  import { useLocalParticipant as useLocalParticipant12 } from "@livekit/components-react/hooks";
10799
- import { useCallback as useCallback25, useContext as useContext15, useRef as useRef31 } from "react";
10803
+ import { useCallback as useCallback25, useContext as useContext16, useRef as useRef31 } from "react";
10800
10804
  var textEncoder7 = new TextEncoder;
10801
10805
  function useTextMode() {
10802
- const ctx = useContext15(LiveAgentContext);
10806
+ const ctx = useContext16(LiveAgentContext);
10803
10807
  if (!ctx) {
10804
10808
  throw new Error("useTextMode must be used within a <LiveAgent> provider");
10805
10809
  }
@@ -10832,7 +10836,7 @@ import { jsx as jsx29, jsxs as jsxs22 } from "react/jsx-runtime";
10832
10836
  var TABS_PILL_BASE = "skippr:cursor-pointer skippr:rounded-full skippr:border-none skippr:bg-transparent skippr:px-[9px] skippr:py-[3px] skippr:text-[11.5px] skippr:font-semibold skippr:text-[#8b877f] skippr:transition-colors";
10833
10837
  var TABS_PILL_ACTIVE = "skippr:bg-white skippr:text-[#2D2D3F] skippr:shadow-[0_1px_2px_rgba(45,45,63,0.08)]";
10834
10838
  function ChatHeader({ wasDraggedRef, draggable, headerRef }) {
10835
- const ctx = useContext16(LiveAgentContext);
10839
+ const ctx = useContext17(LiveAgentContext);
10836
10840
  if (!ctx) {
10837
10841
  throw new Error("ChatHeader must be used within a <LiveAgent> provider");
10838
10842
  }
@@ -10988,11 +10992,11 @@ function AgentStatusLine({ status, detail, stage = "settling" }) {
10988
10992
  }
10989
10993
 
10990
10994
  // src/components/ChatInput.tsx
10991
- import { useContext as useContext17, useEffect as useEffect37, useRef as useRef32, useState as useState29 } from "react";
10995
+ import { useContext as useContext18, useEffect as useEffect37, useRef as useRef32, useState as useState29 } from "react";
10992
10996
  import { jsx as jsx32, jsxs as jsxs25 } from "react/jsx-runtime";
10993
10997
  var MAX_INPUT_HEIGHT = 60;
10994
10998
  function ChatInput({ sendChatMessage, isSendingChat, autoFocus = false }) {
10995
- const ctx = useContext17(LiveAgentContext);
10999
+ const ctx = useContext18(LiveAgentContext);
10996
11000
  const copy = useChromeCopy();
10997
11001
  const reportChatActivity = ctx?.reportChatActivity;
10998
11002
  const isPanelOpen = ctx?.isPanelOpen;
@@ -11486,10 +11490,10 @@ function MessageList({
11486
11490
  }
11487
11491
 
11488
11492
  // src/components/SessionAgenda.tsx
11489
- import { useContext as useContext18 } from "react";
11493
+ import { useContext as useContext19 } from "react";
11490
11494
  import { jsx as jsx38, jsxs as jsxs31 } from "react/jsx-runtime";
11491
11495
  function SessionAgenda({ phases, hasStarted }) {
11492
- const ctx = useContext18(LiveAgentContext);
11496
+ const ctx = useContext19(LiveAgentContext);
11493
11497
  const copy = useChromeCopy();
11494
11498
  const sessionTitle = ctx?.phaseLabels.agentId && ctx.phaseLabels.agentId === ctx.agentId ? ctx.phaseLabels.agentName : undefined;
11495
11499
  const title = sessionTitle ?? ctx?.activeModule?.name ?? copy.agendaTitle;
@@ -11617,7 +11621,7 @@ function Sidebar({
11617
11621
  displayModules
11618
11622
  } = useLiveAgent();
11619
11623
  const copy = useChromeCopy();
11620
- const internalCtx = useContext19(LiveAgentContext);
11624
+ const internalCtx = useContext20(LiveAgentContext);
11621
11625
  const defaultAgentId = internalCtx?.defaultAgentId ?? null;
11622
11626
  const startDefaultSession = internalCtx?.startDefaultSession ?? (() => {});
11623
11627
  const talkDisabled = !(internalCtx?.hasResolvedModules ?? false);
@@ -11931,7 +11935,7 @@ function ConnectedBody({
11931
11935
  }
11932
11936
 
11933
11937
  // src/components/SidebarTrigger.tsx
11934
- import { useContext as useContext20 } from "react";
11938
+ import { useContext as useContext21 } from "react";
11935
11939
 
11936
11940
  // src/components/Logo.tsx
11937
11941
  import { jsx as jsx41, jsxs as jsxs33 } from "react/jsx-runtime";
@@ -11996,7 +12000,7 @@ function SidebarTrigger() {
11996
12000
  isPausing
11997
12001
  } = useLiveAgent();
11998
12002
  const copy = useChromeCopy();
11999
- const internalCtx = useContext20(LiveAgentContext);
12003
+ const internalCtx = useContext21(LiveAgentContext);
12000
12004
  const launcherBottomPx = internalCtx?.launcherBottomPx ?? DEFAULT_LAUNCHER_BOTTOM_PX;
12001
12005
  const popsDown = internalCtx?.popsDown ?? false;
12002
12006
  const logoUrl = internalCtx?.appearance?.logoUrl ?? null;
@@ -12067,20 +12071,6 @@ function resolveSplashPresentation(splash) {
12067
12071
  };
12068
12072
  }
12069
12073
 
12070
- // src/hooks/useAdoptionTips.ts
12071
- import { useContext as useContext21 } from "react";
12072
- function useAdoptionTips() {
12073
- const ctx = useContext21(LiveAgentContext);
12074
- if (!ctx) {
12075
- throw new Error("useAdoptionTips must be used within a <LiveAgent> provider");
12076
- }
12077
- const { adoptionGoals, agentMode, hasResolvedModules } = ctx;
12078
- const inStandardSession = hasLiveSession(ctx) && agentMode !== AGENT_MODE.AlwaysOn;
12079
- if (inStandardSession || !hasResolvedModules || adoptionGoals.length === 0)
12080
- return [];
12081
- return adoptionGoals.slice(0, MAX_ADOPTION_TIPS);
12082
- }
12083
-
12084
12074
  // src/hooks/useSplash.ts
12085
12075
  function useSplash(surface, onDismiss) {
12086
12076
  const ctx = useContext22(LiveAgentContext);
@@ -13049,26 +13039,18 @@ function useBarNotifications() {
13049
13039
  displayModules,
13050
13040
  defaultAgentId,
13051
13041
  activeModule,
13052
- agentMode,
13053
13042
  hasResolvedModules,
13054
- isConnected,
13055
13043
  previewStart,
13056
- selectModule,
13057
- attendGoal
13044
+ selectModule
13058
13045
  } = ctx;
13059
13046
  const tips = useAdoptionTips();
13060
- const { sendChatMessage } = useChatMessages();
13061
- const inAlwaysOnSession = isConnected && agentMode === AGENT_MODE.AlwaysOn;
13062
13047
  const inSession = hasLiveSession(ctx);
13063
13048
  const tipNotifications = tips.map((goal) => ({
13064
13049
  id: goal.goalId,
13065
13050
  kind: NOTIFICATION_KIND.Tip,
13066
13051
  message: goal.displayMessage,
13067
13052
  accentColor: NOTIF_ACCENT_COLOR,
13068
- activate: inAlwaysOnSession ? () => {
13069
- attendGoal(goal.goalId);
13070
- sendChatMessage(goal.objective).catch((e) => console.warn("[Skippr] tip prompt send failed", e));
13071
- } : () => previewStart({ kind: PENDING_START_KIND.Goal, goal })
13053
+ activate: () => previewStart({ kind: PENDING_START_KIND.Goal, goal })
13072
13054
  }));
13073
13055
  const moduleNotifications = !hasResolvedModules ? [] : displayModules.filter((module) => module.id !== defaultAgentId && module.id !== activeModule?.id).filter((module) => {
13074
13056
  const state = getModuleSessionState(module.currentSession, module.mode);
@@ -15246,12 +15228,12 @@ function LiveAgent(props) {
15246
15228
  goals: adoptionGoals,
15247
15229
  deepLinkedGoal,
15248
15230
  hasTipSlug,
15249
- hasResolved: hasResolvedAdoptionGoals,
15250
- attendGoal
15231
+ hasResolved: hasResolvedAdoptionGoals
15251
15232
  } = useAdoptionGoals({
15252
- enabled: !isSessionLive || activeModule?.mode === AGENT_MODE.AlwaysOn || sessionAgentMode === AGENT_MODE.AlwaysOn,
15233
+ enabled: !isSessionLive,
15253
15234
  bearerToken,
15254
- authedFetch
15235
+ authedFetch,
15236
+ agentId: hostAgentId ?? undefined
15255
15237
  });
15256
15238
  const buddyActive = isBuddyActive(appearance) && variant !== "sidebar" && !hostAgentId;
15257
15239
  const buddyShape = appearance?.buddy?.shape ?? DEFAULT_BUDDY_SHAPE;
@@ -15320,18 +15302,6 @@ function LiveAgent(props) {
15320
15302
  autoStarted: opts?.autoStarted
15321
15303
  });
15322
15304
  }, [availableModules, startSession, isSessionLive, operatingModule, disconnect]);
15323
- const startAdoptionSession = useCallback36((goal) => {
15324
- attendGoal(goal.goalId);
15325
- const found = availableModules.find((m) => m.id === goal.agentId);
15326
- if (found)
15327
- setActiveModule(found);
15328
- setSessionAgentMode(AGENT_MODE.AlwaysOn);
15329
- startSession({
15330
- agentId: goal.agentId,
15331
- agentControls: found?.controls,
15332
- adoptionGoalId: goal.goalId
15333
- });
15334
- }, [attendGoal, availableModules, startSession]);
15335
15305
  const previewStart = useCallback36((pending) => {
15336
15306
  setPendingStart(pending);
15337
15307
  setIsMinimized(false);
@@ -15470,7 +15440,7 @@ function LiveAgent(props) {
15470
15440
  await pauseSession();
15471
15441
  minimizePanel();
15472
15442
  }, [pauseSession, minimizePanel]);
15473
- const startDefaultSession = useCallback36(() => {
15443
+ const startDefault = useCallback36((adoptionGoalId) => {
15474
15444
  const target = availableModules.find((m) => m.id === defaultAgentId);
15475
15445
  if (!target)
15476
15446
  return;
@@ -15479,9 +15449,12 @@ function LiveAgent(props) {
15479
15449
  startSession({
15480
15450
  agentId: target.id,
15481
15451
  agentControls: target.controls,
15482
- existingSessionId: defaultSelection.sessionId ?? undefined
15452
+ existingSessionId: defaultSelection.sessionId ?? undefined,
15453
+ adoptionGoalId
15483
15454
  });
15484
15455
  }, [defaultAgentId, availableModules, defaultSelection.sessionId, startSession]);
15456
+ const startDefaultSession = useCallback36(() => startDefault(), [startDefault]);
15457
+ const startAdoptionSession = useCallback36((goal) => startDefault(goal.goalId), [startDefault]);
15485
15458
  const startPrimarySession = useCallback36(() => {
15486
15459
  if (pendingStart) {
15487
15460
  const pending = pendingStart;
@@ -15703,7 +15676,6 @@ function LiveAgent(props) {
15703
15676
  adoptionGoals,
15704
15677
  hasResolvedAdoptionGoals,
15705
15678
  startAdoptionSession,
15706
- attendGoal,
15707
15679
  buddyActive,
15708
15680
  buddyShape,
15709
15681
  setAutoStartAfterLogin
@@ -15801,7 +15773,6 @@ function LiveAgent(props) {
15801
15773
  adoptionGoals,
15802
15774
  hasResolvedAdoptionGoals,
15803
15775
  startAdoptionSession,
15804
- attendGoal,
15805
15776
  buddyActive,
15806
15777
  buddyShape
15807
15778
  ]);