@skippr/live-agent-sdk 0.102.0 → 0.104.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.
- package/README.md +0 -1
- package/dist/esm/lib-exports.js +64 -38
- package/dist/skippr-sdk.js +107 -107
- package/dist/types/context/LiveAgentContext.d.ts +2 -1
- package/dist/types/lib/session.d.ts +8 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -56,7 +56,6 @@ The widget opens with a picker of your active modules — the user chooses which
|
|
|
56
56
|
|
|
57
57
|
```tsx
|
|
58
58
|
import { LiveAgent } from '@skippr/live-agent-sdk';
|
|
59
|
-
import '@skippr/live-agent-sdk/styles';
|
|
60
59
|
|
|
61
60
|
function App() {
|
|
62
61
|
return <LiveAgent appKey="pk_live_your_key" />;
|
package/dist/esm/lib-exports.js
CHANGED
|
@@ -3745,6 +3745,9 @@ function mapApiMessages(messages) {
|
|
|
3745
3745
|
timestamp: new Date(message.createdAt).getTime()
|
|
3746
3746
|
}));
|
|
3747
3747
|
}
|
|
3748
|
+
function hasLiveSession(flags) {
|
|
3749
|
+
return flags.isConnected || flags.isStarting || flags.isPausing || flags.isDisconnecting || flags.isExchanging;
|
|
3750
|
+
}
|
|
3748
3751
|
function getResumableSessionId(currentSession, mode) {
|
|
3749
3752
|
if (!currentSession)
|
|
3750
3753
|
return;
|
|
@@ -9640,17 +9643,8 @@ function useAdoptionTips() {
|
|
|
9640
9643
|
if (!ctx) {
|
|
9641
9644
|
throw new Error("useAdoptionTips must be used within a <LiveAgent> provider");
|
|
9642
9645
|
}
|
|
9643
|
-
const {
|
|
9644
|
-
|
|
9645
|
-
agentMode,
|
|
9646
|
-
hasResolvedModules,
|
|
9647
|
-
isConnected,
|
|
9648
|
-
isStarting,
|
|
9649
|
-
isPausing,
|
|
9650
|
-
isDisconnecting
|
|
9651
|
-
} = ctx;
|
|
9652
|
-
const sessionLive = isConnected || isStarting || isPausing || isDisconnecting;
|
|
9653
|
-
const inStandardSession = sessionLive && agentMode !== AGENT_MODE.AlwaysOn;
|
|
9646
|
+
const { adoptionGoals, agentMode, hasResolvedModules } = ctx;
|
|
9647
|
+
const inStandardSession = hasLiveSession(ctx) && agentMode !== AGENT_MODE.AlwaysOn;
|
|
9654
9648
|
if (inStandardSession || !hasResolvedModules || adoptionGoals.length === 0)
|
|
9655
9649
|
return [];
|
|
9656
9650
|
return adoptionGoals.slice(0, MAX_ADOPTION_TIPS);
|
|
@@ -9670,11 +9664,13 @@ function useBarNotifications() {
|
|
|
9670
9664
|
hasResolvedModules,
|
|
9671
9665
|
isConnected,
|
|
9672
9666
|
previewStart,
|
|
9667
|
+
selectModule,
|
|
9673
9668
|
attendGoal
|
|
9674
9669
|
} = ctx;
|
|
9675
9670
|
const tips = useAdoptionTips();
|
|
9676
9671
|
const { sendChatMessage } = useChatMessages();
|
|
9677
9672
|
const inAlwaysOnSession = isConnected && agentMode === AGENT_MODE.AlwaysOn;
|
|
9673
|
+
const inSession = hasLiveSession(ctx);
|
|
9678
9674
|
const tipNotifications = tips.map((goal) => ({
|
|
9679
9675
|
id: goal.goalId,
|
|
9680
9676
|
kind: NOTIFICATION_KIND.Tip,
|
|
@@ -9693,7 +9689,7 @@ function useBarNotifications() {
|
|
|
9693
9689
|
kind: NOTIFICATION_KIND.Module,
|
|
9694
9690
|
message: module.name,
|
|
9695
9691
|
accentColor: MODULE_ACCENT_COLOR,
|
|
9696
|
-
activate: () => previewStart({ kind: PENDING_START_KIND.Module, moduleId: module.id })
|
|
9692
|
+
activate: inSession ? () => void selectModule(module.id) : () => previewStart({ kind: PENDING_START_KIND.Module, moduleId: module.id })
|
|
9697
9693
|
}));
|
|
9698
9694
|
return [...tipNotifications, ...moduleNotifications];
|
|
9699
9695
|
}
|
|
@@ -10613,8 +10609,8 @@ function VoiceBarFrame({
|
|
|
10613
10609
|
const {
|
|
10614
10610
|
isConnected,
|
|
10615
10611
|
isStarting,
|
|
10612
|
+
isExchanging,
|
|
10616
10613
|
isPausing,
|
|
10617
|
-
isDisconnecting,
|
|
10618
10614
|
isAuthenticated,
|
|
10619
10615
|
usesHostAuth,
|
|
10620
10616
|
defaultAgentId,
|
|
@@ -10709,7 +10705,8 @@ function VoiceBarFrame({
|
|
|
10709
10705
|
code: "Space",
|
|
10710
10706
|
requireCtrl: true
|
|
10711
10707
|
});
|
|
10712
|
-
const sessionLive =
|
|
10708
|
+
const sessionLive = hasLiveSession(ctx);
|
|
10709
|
+
const isLoading = isStarting || isExchanging;
|
|
10713
10710
|
const canStart = isAuthenticated && (!!defaultAgentId || !!pendingStart);
|
|
10714
10711
|
const showClose = canFold || sessionLive;
|
|
10715
10712
|
const logoUrl = appearance?.logoUrl ?? null;
|
|
@@ -10725,7 +10722,7 @@ function VoiceBarFrame({
|
|
|
10725
10722
|
minimizePanel();
|
|
10726
10723
|
}
|
|
10727
10724
|
};
|
|
10728
|
-
useKeyboardStop({ enabled: sessionLive, onStop: closeBar });
|
|
10725
|
+
useKeyboardStop({ enabled: sessionLive && !isPausing && !isLoading, onStop: closeBar });
|
|
10729
10726
|
const hintSeenRef = useRef39(false);
|
|
10730
10727
|
const requestPillBg = isCapturingSpeech ? "var(--skippr-brand-active)" : "var(--skippr-brand, #2bc0ae)";
|
|
10731
10728
|
const agentStateLabel = state === "thinking" ? "thinking…" : state === "speaking" ? "talking…" : null;
|
|
@@ -10777,7 +10774,7 @@ function VoiceBarFrame({
|
|
|
10777
10774
|
const linkCardActive = !!visibleLinkCard && isConnected && !planCardActive && !(isRoomChat && chatOpen) && !isCapturingSpeech && !isHeld && !autoOffClosing;
|
|
10778
10775
|
const bannerActive = hasNotifications && bannerOpen;
|
|
10779
10776
|
const slotClaimed = chatOpen || bannerActive || lineBlockOpen;
|
|
10780
|
-
const autoBase = !
|
|
10777
|
+
const autoBase = !isLoading && isConnected && !textMode && !pushOrTap && !autoOffClosing;
|
|
10781
10778
|
const showHeldStrip = !slotClaimed && autoBase && isHeld;
|
|
10782
10779
|
const showLiveStrip = !slotClaimed && autoBase && !isHeld && !planCardActive && (state === "thinking" || showActionControl);
|
|
10783
10780
|
const showTimerStrip = !slotClaimed && !autoOffClosing && !isCapturingSpeech && !planCardActive && !showLiveStrip && !showHeldStrip && !!sessionTimer;
|
|
@@ -10980,9 +10977,9 @@ function VoiceBarFrame({
|
|
|
10980
10977
|
showClose && /* @__PURE__ */ jsxs37("button", {
|
|
10981
10978
|
type: "button",
|
|
10982
10979
|
onClick: ifNotDragged(closeBar),
|
|
10983
|
-
disabled: isPausing ||
|
|
10980
|
+
disabled: isPausing || isLoading,
|
|
10984
10981
|
"aria-label": sessionLive ? "End session" : "Close",
|
|
10985
|
-
className: cn(EDGE_BUTTON, "skippr:relative skippr:size-[26px]",
|
|
10982
|
+
className: cn(EDGE_BUTTON, "skippr:relative skippr:size-[26px]", isLoading && "skippr:cursor-not-allowed skippr:opacity-40 skippr:hover:bg-transparent skippr:hover:text-[#b8b4ac]"),
|
|
10986
10983
|
children: [
|
|
10987
10984
|
isPausing && /* @__PURE__ */ jsx45(BusyRing, {
|
|
10988
10985
|
tone: "brand"
|
|
@@ -10993,8 +10990,8 @@ function VoiceBarFrame({
|
|
|
10993
10990
|
})
|
|
10994
10991
|
]
|
|
10995
10992
|
}),
|
|
10996
|
-
|
|
10997
|
-
className: cn(PILL, "skippr:bg-[#F1EFEA] skippr:overflow-hidden skippr:[animation:skippr-fade-in_0.25s_ease]"),
|
|
10993
|
+
isLoading && /* @__PURE__ */ jsxs37("div", {
|
|
10994
|
+
className: cn(PILL, "skippr:bg-[#F1EFEA] skippr:overflow-hidden", !isExchanging && "skippr:[animation:skippr-fade-in_0.25s_ease]"),
|
|
10998
10995
|
children: [
|
|
10999
10996
|
/* @__PURE__ */ jsx45(LoadingAvatar, {
|
|
11000
10997
|
logoUrl
|
|
@@ -11019,7 +11016,7 @@ function VoiceBarFrame({
|
|
|
11019
11016
|
})
|
|
11020
11017
|
]
|
|
11021
11018
|
}),
|
|
11022
|
-
!
|
|
11019
|
+
!isLoading && isConnected && !textMode && pushOrTap && /* @__PURE__ */ jsx45(ShortcutHint, {
|
|
11023
11020
|
enabled: isPushToTalk,
|
|
11024
11021
|
seenRef: hintSeenRef,
|
|
11025
11022
|
suppressed: hintSuppressed,
|
|
@@ -11050,7 +11047,7 @@ function VoiceBarFrame({
|
|
|
11050
11047
|
]
|
|
11051
11048
|
})
|
|
11052
11049
|
}),
|
|
11053
|
-
!
|
|
11050
|
+
!isLoading && isConnected && !textMode && !pushOrTap && /* @__PURE__ */ jsxs37("div", {
|
|
11054
11051
|
style: { background: livePillBg, color: "var(--skippr-brand-foreground, #2d2b3d)" },
|
|
11055
11052
|
className: cn(PILL, "skippr:gap-[9px] skippr:px-[8px]"),
|
|
11056
11053
|
children: [
|
|
@@ -11123,7 +11120,7 @@ function VoiceBarFrame({
|
|
|
11123
11120
|
})
|
|
11124
11121
|
]
|
|
11125
11122
|
}),
|
|
11126
|
-
!
|
|
11123
|
+
!isLoading && isConnected && textMode && /* @__PURE__ */ jsxs37("div", {
|
|
11127
11124
|
className: cn(PILL, "skippr:gap-[7px] skippr:bg-[#F1EFEA] skippr:text-[#5a5650] skippr:[animation:skippr-fade-in_0.25s_ease]"),
|
|
11128
11125
|
children: [
|
|
11129
11126
|
/* @__PURE__ */ jsx45(MessageSquare, {
|
|
@@ -11164,9 +11161,9 @@ function VoiceBarFrame({
|
|
|
11164
11161
|
(sessionLive || isRoomChat) && /* @__PURE__ */ jsx45("button", {
|
|
11165
11162
|
type: "button",
|
|
11166
11163
|
onClick: ifNotDragged(toggleChat),
|
|
11167
|
-
disabled:
|
|
11164
|
+
disabled: isLoading,
|
|
11168
11165
|
"aria-label": "Open chat",
|
|
11169
|
-
className: cn(EDGE_BUTTON, "skippr:size-[30px] skippr:text-[#8b877f]",
|
|
11166
|
+
className: cn(EDGE_BUTTON, "skippr:size-[30px] skippr:text-[#8b877f]", isLoading && "skippr:cursor-not-allowed skippr:opacity-40 skippr:hover:bg-transparent skippr:hover:text-[#8b877f]"),
|
|
11170
11167
|
children: /* @__PURE__ */ jsx45(MessageSquare, {
|
|
11171
11168
|
className: "skippr:size-[15px]",
|
|
11172
11169
|
strokeWidth: 2
|
|
@@ -11662,10 +11659,6 @@ function VoiceBar({ revealed }) {
|
|
|
11662
11659
|
throw new Error("VoiceBar must be used within a <LiveAgent> provider");
|
|
11663
11660
|
}
|
|
11664
11661
|
const {
|
|
11665
|
-
isConnected,
|
|
11666
|
-
isStarting,
|
|
11667
|
-
isPausing,
|
|
11668
|
-
isDisconnecting,
|
|
11669
11662
|
isMinimized,
|
|
11670
11663
|
isAuthenticated,
|
|
11671
11664
|
usesHostAuth,
|
|
@@ -11687,7 +11680,7 @@ function VoiceBar({ revealed }) {
|
|
|
11687
11680
|
if (!revealed)
|
|
11688
11681
|
return null;
|
|
11689
11682
|
const launcherMode = appearance?.launcherMode ?? DEFAULT_LAUNCHER_MODE;
|
|
11690
|
-
const sessionLive =
|
|
11683
|
+
const sessionLive = hasLiveSession(ctx);
|
|
11691
11684
|
const canFold = launcherMode !== LAUNCHER_MODE.None;
|
|
11692
11685
|
const needsLogin = !usesHostAuth && !isAuthenticated;
|
|
11693
11686
|
const launcherEdge = appearance?.position === "left" ? "left" : "right";
|
|
@@ -11794,6 +11787,7 @@ function LiveAgent(props) {
|
|
|
11794
11787
|
const effectiveAuthToken = usesHostAuth ? authTokenProp : auth.authToken ?? undefined;
|
|
11795
11788
|
const [activeModule, setActiveModule] = useState39(null);
|
|
11796
11789
|
const [sessionAgentMode, setSessionAgentMode] = useState39(null);
|
|
11790
|
+
const [isExchanging, setIsExchanging] = useState39(false);
|
|
11797
11791
|
const minimizeOnSessionStart = useCallback33(() => {
|
|
11798
11792
|
if (minimizable) {
|
|
11799
11793
|
setIsMinimized(true);
|
|
@@ -11804,7 +11798,10 @@ function LiveAgent(props) {
|
|
|
11804
11798
|
setIsMinimized(false);
|
|
11805
11799
|
setIsPanelOpen(true);
|
|
11806
11800
|
}, []);
|
|
11801
|
+
const isExchangeDisconnectingRef = useRef42(false);
|
|
11807
11802
|
const minimizeOnSessionDisconnect = useCallback33(() => {
|
|
11803
|
+
if (isExchangeDisconnectingRef.current)
|
|
11804
|
+
return;
|
|
11808
11805
|
setActiveModule(null);
|
|
11809
11806
|
setSessionAgentMode(null);
|
|
11810
11807
|
if (minimizable) {
|
|
@@ -11841,14 +11838,21 @@ function LiveAgent(props) {
|
|
|
11841
11838
|
onStartError: expandOnSessionStartError,
|
|
11842
11839
|
onDisconnect: minimizeOnSessionDisconnect
|
|
11843
11840
|
});
|
|
11844
|
-
const
|
|
11845
|
-
|
|
11841
|
+
const isConnected = connection !== null;
|
|
11842
|
+
const isSessionLive = hasLiveSession({
|
|
11843
|
+
isConnected,
|
|
11844
|
+
isStarting,
|
|
11845
|
+
isPausing,
|
|
11846
|
+
isDisconnecting,
|
|
11847
|
+
isExchanging
|
|
11848
|
+
});
|
|
11849
|
+
const isRoomReleasedRef = useRef42(false);
|
|
11850
|
+
isRoomReleasedRef.current = !isConnected || isPausing || isDisconnecting;
|
|
11846
11851
|
const handleRoomDisconnected = useCallback33(() => {
|
|
11847
|
-
if (
|
|
11852
|
+
if (isExchangeDisconnectingRef.current || isRoomReleasedRef.current)
|
|
11848
11853
|
return;
|
|
11849
11854
|
disconnect();
|
|
11850
11855
|
}, [disconnect]);
|
|
11851
|
-
const isSessionLive = connection !== null || isStarting || isPausing || isDisconnecting;
|
|
11852
11856
|
const [isPanelOpen, setIsPanelOpen] = useState39(defaultOpen);
|
|
11853
11857
|
const [isMinimized, setIsMinimized] = useState39(minimizable && !defaultOpen);
|
|
11854
11858
|
const [pendingStart, setPendingStart] = useState39(null);
|
|
@@ -11864,7 +11868,6 @@ function LiveAgent(props) {
|
|
|
11864
11868
|
const setTextModeState = useCallback33((enabled) => {
|
|
11865
11869
|
setTextMode(enabled);
|
|
11866
11870
|
}, []);
|
|
11867
|
-
const isConnected = connection !== null;
|
|
11868
11871
|
const showControlBar = isConnected || isStarting || isPausing;
|
|
11869
11872
|
useEffect49(() => {
|
|
11870
11873
|
if (!isConnected)
|
|
@@ -11921,19 +11924,40 @@ function LiveAgent(props) {
|
|
|
11921
11924
|
existingSessionId: resumableSession.id
|
|
11922
11925
|
});
|
|
11923
11926
|
}, [resumableSession, operatingModule, startSession, baseAgentControls]);
|
|
11924
|
-
const selectModule = useCallback33((moduleId, opts) => {
|
|
11927
|
+
const selectModule = useCallback33(async (moduleId, opts) => {
|
|
11928
|
+
if (isExchangeDisconnectingRef.current)
|
|
11929
|
+
return;
|
|
11925
11930
|
const found = availableModules.find((m) => m.id === moduleId);
|
|
11926
11931
|
if (!found)
|
|
11927
11932
|
return;
|
|
11933
|
+
if (isSessionLive && found.id !== operatingModule?.id) {
|
|
11934
|
+
isExchangeDisconnectingRef.current = true;
|
|
11935
|
+
setIsExchanging(true);
|
|
11936
|
+
try {
|
|
11937
|
+
await disconnect();
|
|
11938
|
+
setActiveModule(found);
|
|
11939
|
+
setSessionAgentMode(found.mode);
|
|
11940
|
+
await startSession({
|
|
11941
|
+
agentId: found.id,
|
|
11942
|
+
agentControls: found.controls,
|
|
11943
|
+
existingSessionId: getResumableSessionId(found.currentSession, found.mode),
|
|
11944
|
+
autoStarted: opts?.autoStarted
|
|
11945
|
+
});
|
|
11946
|
+
} finally {
|
|
11947
|
+
isExchangeDisconnectingRef.current = false;
|
|
11948
|
+
setIsExchanging(false);
|
|
11949
|
+
}
|
|
11950
|
+
return;
|
|
11951
|
+
}
|
|
11928
11952
|
setActiveModule(found);
|
|
11929
11953
|
setSessionAgentMode(found.mode);
|
|
11930
|
-
startSession({
|
|
11954
|
+
await startSession({
|
|
11931
11955
|
agentId: found.id,
|
|
11932
11956
|
agentControls: found.controls,
|
|
11933
11957
|
existingSessionId: getResumableSessionId(found.currentSession, found.mode),
|
|
11934
11958
|
autoStarted: opts?.autoStarted
|
|
11935
11959
|
});
|
|
11936
|
-
}, [availableModules, startSession]);
|
|
11960
|
+
}, [availableModules, startSession, isSessionLive, operatingModule, disconnect]);
|
|
11937
11961
|
const startAdoptionSession = useCallback33((goal) => {
|
|
11938
11962
|
attendGoal(goal.goalId);
|
|
11939
11963
|
const found = availableModules.find((m) => m.id === goal.agentId);
|
|
@@ -12136,6 +12160,7 @@ function LiveAgent(props) {
|
|
|
12136
12160
|
shouldConnect,
|
|
12137
12161
|
isConnected,
|
|
12138
12162
|
isStarting,
|
|
12163
|
+
isExchanging,
|
|
12139
12164
|
isDisconnecting,
|
|
12140
12165
|
isPausing,
|
|
12141
12166
|
error,
|
|
@@ -12222,6 +12247,7 @@ function LiveAgent(props) {
|
|
|
12222
12247
|
shouldConnect,
|
|
12223
12248
|
isConnected,
|
|
12224
12249
|
isStarting,
|
|
12250
|
+
isExchanging,
|
|
12225
12251
|
isDisconnecting,
|
|
12226
12252
|
isPausing,
|
|
12227
12253
|
error,
|