@skippr/live-agent-sdk 0.124.0 → 0.125.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/dist/esm/lib-exports.js +95 -36
- package/dist/skippr-sdk.js +89 -89
- package/dist/types/components/DomCapture.d.ts +2 -1
- package/dist/types/components/LiveAgent.d.ts +1 -0
- package/dist/types/hooks/useSessionHold.d.ts +1 -1
- package/dist/types/lib/agentSender.d.ts +2 -0
- package/dist/types/lib/hostStart.d.ts +6 -0
- package/package.json +1 -1
package/dist/esm/lib-exports.js
CHANGED
|
@@ -5508,7 +5508,7 @@ function usePlanUpdates() {
|
|
|
5508
5508
|
// src/hooks/useSession.ts
|
|
5509
5509
|
import { useCallback as useCallback15, useEffect as useEffect20, useRef as useRef15, useState as useState17 } from "react";
|
|
5510
5510
|
var API_URL4 = "https://app.skippr.ai/api";
|
|
5511
|
-
var SDK_VERSION = "0.
|
|
5511
|
+
var SDK_VERSION = "0.125.0";
|
|
5512
5512
|
async function fetchSessionMessages(sessionId, authedFetch) {
|
|
5513
5513
|
try {
|
|
5514
5514
|
const resp = await authedFetch(`${API_URL4}/v1/sessions/${sessionId}/messages`);
|
|
@@ -6054,6 +6054,21 @@ function useSplashOverlayOptOut(authedFetch, recordedForUser) {
|
|
|
6054
6054
|
return { optedOut: recordedForUser || recordedLocally, optOut };
|
|
6055
6055
|
}
|
|
6056
6056
|
|
|
6057
|
+
// src/lib/hostStart.ts
|
|
6058
|
+
var start = null;
|
|
6059
|
+
var requested = false;
|
|
6060
|
+
var live = false;
|
|
6061
|
+
function setHostSessionLive(isLive) {
|
|
6062
|
+
live = isLive;
|
|
6063
|
+
}
|
|
6064
|
+
function provideStartSession(fn) {
|
|
6065
|
+
start = fn;
|
|
6066
|
+
if (!fn || !requested)
|
|
6067
|
+
return;
|
|
6068
|
+
requested = false;
|
|
6069
|
+
fn();
|
|
6070
|
+
}
|
|
6071
|
+
|
|
6057
6072
|
// src/lib/launcher.ts
|
|
6058
6073
|
var DEFAULT_LAUNCHER_BOTTOM_PX = 48;
|
|
6059
6074
|
var LAUNCHER_HEIGHT_PX = 50;
|
|
@@ -6586,8 +6601,8 @@ function AgentCursor({
|
|
|
6586
6601
|
}
|
|
6587
6602
|
setPhase("travel");
|
|
6588
6603
|
const from = prevCursorRef.current ?? widgetEntryPoint(ctx?.position ?? "right", ctx?.launcherBottomPx ?? 0);
|
|
6589
|
-
const
|
|
6590
|
-
startGlide(from,
|
|
6604
|
+
const start2 = ringTopLeft(rect);
|
|
6605
|
+
startGlide(from, start2, glideDuration(from, start2), () => {
|
|
6591
6606
|
after(DRAW_START_DELAY_MS, () => {
|
|
6592
6607
|
const path = pathRef.current;
|
|
6593
6608
|
if (!path) {
|
|
@@ -6596,9 +6611,9 @@ function AgentCursor({
|
|
|
6596
6611
|
}
|
|
6597
6612
|
setPhase("drawing");
|
|
6598
6613
|
traceRef.current = traceRing(path, DRAW_MS, (eased) => {
|
|
6599
|
-
const
|
|
6614
|
+
const live2 = liveRectOf(element, rect);
|
|
6600
6615
|
const point = path.getPointAtLength(path.getTotalLength() * eased);
|
|
6601
|
-
moveCursorTo({ x:
|
|
6616
|
+
moveCursorTo({ x: live2.left - RING_PAD + point.x, y: live2.top - RING_PAD + point.y });
|
|
6602
6617
|
}, () => rest(liveRectOf(element, rect), SETTLE_TO_CENTER_MS, ACT_CLICK_DELAY_MS));
|
|
6603
6618
|
});
|
|
6604
6619
|
});
|
|
@@ -8001,7 +8016,11 @@ async function unpublishAndStopTrack(localParticipant, videoTrack) {
|
|
|
8001
8016
|
} catch {}
|
|
8002
8017
|
videoTrack.stop();
|
|
8003
8018
|
}
|
|
8004
|
-
function DomCapture({
|
|
8019
|
+
function DomCapture({
|
|
8020
|
+
pushOrTapMicMode = false,
|
|
8021
|
+
startMuted = false,
|
|
8022
|
+
suppressVideoPublish = false
|
|
8023
|
+
}) {
|
|
8005
8024
|
const { localParticipant } = useLocalParticipant5();
|
|
8006
8025
|
const connectionState = useConnectionState2();
|
|
8007
8026
|
const { isHeld, clearPausedCaptureRef } = useSessionHoldContext();
|
|
@@ -8045,18 +8064,20 @@ function DomCapture({ pushOrTapMicMode = false, startMuted = false }) {
|
|
|
8045
8064
|
if (!pushOrTapMicMode && !startMuted && !localParticipant.isMicrophoneEnabled) {
|
|
8046
8065
|
localParticipant.setMicrophoneEnabled(true).catch((error) => console.error("Failed to enable microphone:", error));
|
|
8047
8066
|
}
|
|
8048
|
-
|
|
8049
|
-
|
|
8050
|
-
|
|
8051
|
-
|
|
8052
|
-
|
|
8053
|
-
|
|
8054
|
-
|
|
8055
|
-
|
|
8056
|
-
|
|
8057
|
-
|
|
8058
|
-
track.
|
|
8059
|
-
|
|
8067
|
+
if (!suppressVideoPublish) {
|
|
8068
|
+
localParticipant.publishTrack(videoTrack, {
|
|
8069
|
+
source: Track3.Source.ScreenShare,
|
|
8070
|
+
videoEncoding: {
|
|
8071
|
+
maxBitrate: CAPTURE_BITRATE,
|
|
8072
|
+
maxFramerate: CAPTURE_FPS
|
|
8073
|
+
},
|
|
8074
|
+
simulcast: false
|
|
8075
|
+
}).catch((error) => {
|
|
8076
|
+
console.error("Failed to publish DOM capture track:", error);
|
|
8077
|
+
for (const track of canvasStream.getTracks())
|
|
8078
|
+
track.stop();
|
|
8079
|
+
});
|
|
8080
|
+
}
|
|
8060
8081
|
const commitPageLayerIfNewest = (sequence, page) => {
|
|
8061
8082
|
if (cancelled || pausedRef.current || sequence <= lastCommittedSequence)
|
|
8062
8083
|
return false;
|
|
@@ -8068,13 +8089,18 @@ function DomCapture({ pushOrTapMicMode = false, startMuted = false }) {
|
|
|
8068
8089
|
};
|
|
8069
8090
|
const rasterizeAndCommitWaitingOutTimeout = async (options) => {
|
|
8070
8091
|
const sequence = ++rasterizeSequence;
|
|
8092
|
+
const startedAt = performance.now();
|
|
8071
8093
|
const captureInProgress = rasterizeViewportToPageLayer(canvas.width, canvas.height, options);
|
|
8072
8094
|
const captureOrTimeout = await Promise.race([
|
|
8073
8095
|
captureInProgress,
|
|
8074
8096
|
new Promise((resolve) => setTimeout(() => resolve(RASTERIZE_TIMED_OUT), RASTERIZE_TIMEOUT_MS))
|
|
8075
8097
|
]);
|
|
8076
8098
|
if (captureOrTimeout === RASTERIZE_TIMED_OUT) {
|
|
8077
|
-
|
|
8099
|
+
console.warn(`[Skippr] Rasterize exceeded ${RASTERIZE_TIMEOUT_MS}ms; falling back to fast capture`);
|
|
8100
|
+
captureInProgress.then((lateCapture) => {
|
|
8101
|
+
console.warn(`[Skippr] Late rasterize finished in ${Math.round(performance.now() - startedAt)}ms`);
|
|
8102
|
+
return commitPageLayerIfNewest(sequence, lateCapture);
|
|
8103
|
+
}).catch(() => {
|
|
8078
8104
|
return;
|
|
8079
8105
|
});
|
|
8080
8106
|
return { timedOut: true };
|
|
@@ -8084,6 +8110,8 @@ function DomCapture({ pushOrTapMicMode = false, startMuted = false }) {
|
|
|
8084
8110
|
};
|
|
8085
8111
|
let followUpRefreshQueued = false;
|
|
8086
8112
|
const refreshPageAndComposite = async ({ queueWhenBusy = false } = {}) => {
|
|
8113
|
+
if (suppressVideoPublish)
|
|
8114
|
+
return;
|
|
8087
8115
|
if (cancelled || snapshotInFlight || pausedRef.current) {
|
|
8088
8116
|
if (snapshotInFlight && !cancelled && queueWhenBusy)
|
|
8089
8117
|
followUpRefreshQueued = true;
|
|
@@ -8245,11 +8273,19 @@ function DomCapture({ pushOrTapMicMode = false, startMuted = false }) {
|
|
|
8245
8273
|
cleanupCursorSubscription();
|
|
8246
8274
|
cleanupDomEventListeners();
|
|
8247
8275
|
cleanupSnapshotRequest();
|
|
8248
|
-
|
|
8276
|
+
if (!suppressVideoPublish)
|
|
8277
|
+
unpublishAndStopTrack(localParticipant, videoTrack);
|
|
8249
8278
|
for (const track of canvasStream.getTracks())
|
|
8250
8279
|
track.stop();
|
|
8251
8280
|
};
|
|
8252
|
-
}, [
|
|
8281
|
+
}, [
|
|
8282
|
+
connectionState,
|
|
8283
|
+
localParticipant,
|
|
8284
|
+
pushOrTapMicMode,
|
|
8285
|
+
startMuted,
|
|
8286
|
+
suppressVideoPublish,
|
|
8287
|
+
clearPausedCaptureRef
|
|
8288
|
+
]);
|
|
8253
8289
|
useEffect25(() => {
|
|
8254
8290
|
if (isHeld) {
|
|
8255
8291
|
freezeCaptureRef.current?.();
|
|
@@ -8263,6 +8299,14 @@ function DomCapture({ pushOrTapMicMode = false, startMuted = false }) {
|
|
|
8263
8299
|
// src/components/HighlightOverlay.tsx
|
|
8264
8300
|
import { useDataChannel, useLocalParticipant as useLocalParticipant6 } from "@livekit/components-react/hooks";
|
|
8265
8301
|
import { useCallback as useCallback18, useEffect as useEffect26, useRef as useRef20 } from "react";
|
|
8302
|
+
|
|
8303
|
+
// src/lib/agentSender.ts
|
|
8304
|
+
import { ParticipantKind } from "livekit-client";
|
|
8305
|
+
function isFromAgent(from) {
|
|
8306
|
+
return from?.kind === ParticipantKind.AGENT;
|
|
8307
|
+
}
|
|
8308
|
+
|
|
8309
|
+
// src/components/HighlightOverlay.tsx
|
|
8266
8310
|
var HIGHLIGHT_AUTO_CLEAR_MS = 30000;
|
|
8267
8311
|
var PAGE_CHECK_MS = 250;
|
|
8268
8312
|
var ACTED_REASON = "acted";
|
|
@@ -8315,6 +8359,8 @@ function HighlightOverlay() {
|
|
|
8315
8359
|
}).catch((error) => console.error("Failed to report highlight clear:", error));
|
|
8316
8360
|
}, [clear, localParticipant]);
|
|
8317
8361
|
const onHighlightMessage = useCallback18((msg) => {
|
|
8362
|
+
if (!isFromAgent(msg.from))
|
|
8363
|
+
return;
|
|
8318
8364
|
const parsed = parseHighlightMessage(msg.payload);
|
|
8319
8365
|
if (!parsed)
|
|
8320
8366
|
return;
|
|
@@ -9314,6 +9360,8 @@ function PageActionHandler() {
|
|
|
9314
9360
|
}
|
|
9315
9361
|
}, [runStep]);
|
|
9316
9362
|
const onMessage = useCallback19((msg) => {
|
|
9363
|
+
if (!isFromAgent(msg.from))
|
|
9364
|
+
return;
|
|
9317
9365
|
const action = parsePageAction(msg.payload);
|
|
9318
9366
|
if (!action)
|
|
9319
9367
|
return;
|
|
@@ -9833,7 +9881,7 @@ function SessionControlBar() {
|
|
|
9833
9881
|
const pushOrTapMicMode = isRequestResponseMicMode(micMode);
|
|
9834
9882
|
const isPushToTalk = micMode === MIC_MODE.PushToTalk;
|
|
9835
9883
|
const agentActive = state === "speaking" || state === "thinking";
|
|
9836
|
-
const { isCapturingSpeech, toggle: toggleTapToTalk, start, commit } = useVoiceTurnContext();
|
|
9884
|
+
const { isCapturingSpeech, toggle: toggleTapToTalk, start: start2, commit } = useVoiceTurnContext();
|
|
9837
9885
|
const liveUserTranscript = useLiveUserTranscript(isCapturingSpeech);
|
|
9838
9886
|
const { reportActivity } = useIdleAutoPause({
|
|
9839
9887
|
enabled: pushOrTapMicMode,
|
|
@@ -9846,9 +9894,9 @@ function SessionControlBar() {
|
|
|
9846
9894
|
});
|
|
9847
9895
|
const [pushToTalkHintSeen, setPushToTalkHintSeen] = useState25(false);
|
|
9848
9896
|
const startPushToTalk = useCallback22(() => {
|
|
9849
|
-
|
|
9897
|
+
start2();
|
|
9850
9898
|
reportActivity();
|
|
9851
|
-
}, [
|
|
9899
|
+
}, [start2, reportActivity]);
|
|
9852
9900
|
const commitPushToTalk = useCallback22(() => {
|
|
9853
9901
|
commit();
|
|
9854
9902
|
reportActivity();
|
|
@@ -11701,7 +11749,7 @@ function useSplash(surface, onDismiss) {
|
|
|
11701
11749
|
dismissSplash(surface);
|
|
11702
11750
|
onDismiss?.();
|
|
11703
11751
|
}, [commitOptOut, releaseScreen, dismissSplash, surface, onDismiss]);
|
|
11704
|
-
const
|
|
11752
|
+
const start2 = useCallback29(() => {
|
|
11705
11753
|
commitOptOut();
|
|
11706
11754
|
startPrimarySession();
|
|
11707
11755
|
}, [commitOptOut, startPrimarySession]);
|
|
@@ -11747,7 +11795,7 @@ function useSplash(surface, onDismiss) {
|
|
|
11747
11795
|
toggleStartMuted,
|
|
11748
11796
|
enableScreen,
|
|
11749
11797
|
startTip,
|
|
11750
|
-
start,
|
|
11798
|
+
start: start2,
|
|
11751
11799
|
dismiss,
|
|
11752
11800
|
optOutChecked,
|
|
11753
11801
|
toggleOptOut
|
|
@@ -11772,7 +11820,7 @@ function useSplash(surface, onDismiss) {
|
|
|
11772
11820
|
enableMic,
|
|
11773
11821
|
toggleStartMuted,
|
|
11774
11822
|
enableScreen,
|
|
11775
|
-
start,
|
|
11823
|
+
start: start2,
|
|
11776
11824
|
dismiss,
|
|
11777
11825
|
optOutChecked,
|
|
11778
11826
|
toggleOptOut
|
|
@@ -12055,7 +12103,7 @@ function SplashAlwaysOn({
|
|
|
12055
12103
|
toggleStartMuted,
|
|
12056
12104
|
enableScreen,
|
|
12057
12105
|
startTip,
|
|
12058
|
-
start,
|
|
12106
|
+
start: start2,
|
|
12059
12107
|
dismiss,
|
|
12060
12108
|
optOutChecked,
|
|
12061
12109
|
toggleOptOut,
|
|
@@ -12145,7 +12193,7 @@ function SplashAlwaysOn({
|
|
|
12145
12193
|
}, tip.goalId)) : /* @__PURE__ */ jsx44(TipRow, {
|
|
12146
12194
|
title: copy.tipsEmptyTitle,
|
|
12147
12195
|
subtext: copy.tipsEmptyDescription,
|
|
12148
|
-
onStart:
|
|
12196
|
+
onStart: start2
|
|
12149
12197
|
})
|
|
12150
12198
|
})
|
|
12151
12199
|
]
|
|
@@ -12167,7 +12215,7 @@ function SplashAlwaysOn({
|
|
|
12167
12215
|
/* @__PURE__ */ jsxs35("button", {
|
|
12168
12216
|
ref: ctaRef,
|
|
12169
12217
|
type: "button",
|
|
12170
|
-
onClick:
|
|
12218
|
+
onClick: start2,
|
|
12171
12219
|
className: `${FOCUS_RING3} skippr:flex skippr:w-full skippr:cursor-pointer skippr:items-center skippr:justify-center skippr:gap-2 skippr:rounded-full skippr:bg-primary skippr:px-5 skippr:py-[13px] skippr:text-[16px] skippr:font-semibold skippr:text-primary-foreground skippr:transition-all skippr:hover:bg-primary/90`,
|
|
12172
12220
|
children: [
|
|
12173
12221
|
headerIconUrl ? /* @__PURE__ */ jsx44("img", {
|
|
@@ -12256,7 +12304,7 @@ function SplashPrimary({
|
|
|
12256
12304
|
enableMic,
|
|
12257
12305
|
toggleStartMuted,
|
|
12258
12306
|
enableScreen,
|
|
12259
|
-
start,
|
|
12307
|
+
start: start2,
|
|
12260
12308
|
dismiss,
|
|
12261
12309
|
optOutChecked,
|
|
12262
12310
|
toggleOptOut,
|
|
@@ -12434,7 +12482,7 @@ function SplashPrimary({
|
|
|
12434
12482
|
/* @__PURE__ */ jsxs36("button", {
|
|
12435
12483
|
ref: ctaRef,
|
|
12436
12484
|
type: "button",
|
|
12437
|
-
onClick:
|
|
12485
|
+
onClick: start2,
|
|
12438
12486
|
className: `${FOCUS_RING3} skippr:flex skippr:w-full skippr:cursor-pointer skippr:items-center skippr:justify-center skippr:gap-2 skippr:rounded-full skippr:bg-primary skippr:px-5 skippr:py-[13px] skippr:text-[16px] skippr:font-semibold skippr:text-primary-foreground skippr:transition-all skippr:hover:bg-primary/90`,
|
|
12439
12487
|
children: [
|
|
12440
12488
|
headerIconUrl ? /* @__PURE__ */ jsx45("img", {
|
|
@@ -13597,8 +13645,8 @@ function VoiceBarFrame({
|
|
|
13597
13645
|
const { localParticipant } = useLocalParticipant13();
|
|
13598
13646
|
const isUserSpeaking = useIsSpeaking(localParticipant);
|
|
13599
13647
|
const { state } = useAgentVoiceState();
|
|
13600
|
-
const { isCapturingSpeech, toggle: toggleTapToTalk, start, commit } = useVoiceTurnContext();
|
|
13601
|
-
const holdPushToTalk = usePointerHold(
|
|
13648
|
+
const { isCapturingSpeech, toggle: toggleTapToTalk, start: start2, commit } = useVoiceTurnContext();
|
|
13649
|
+
const holdPushToTalk = usePointerHold(start2, commit);
|
|
13602
13650
|
const { isHeld, toggle: togglePause } = useSessionHoldContext();
|
|
13603
13651
|
const plan = usePlanUpdates();
|
|
13604
13652
|
const linkCard = useLinkCard();
|
|
@@ -13643,7 +13691,7 @@ function VoiceBarFrame({
|
|
|
13643
13691
|
}, [chatLineOpen, chatLineMounted]);
|
|
13644
13692
|
useKeyboardPushToTalk({
|
|
13645
13693
|
enabled: isConnected && isPushToTalk,
|
|
13646
|
-
onStart:
|
|
13694
|
+
onStart: start2,
|
|
13647
13695
|
onCommit: commit,
|
|
13648
13696
|
code: "Space",
|
|
13649
13697
|
requireCtrl: true
|
|
@@ -14668,6 +14716,7 @@ function LiveAgent(props) {
|
|
|
14668
14716
|
startSessionLabel = "Talk to Skippr",
|
|
14669
14717
|
autoFocusChat = true,
|
|
14670
14718
|
animateAgentCursor = false,
|
|
14719
|
+
suppressVideoPublish = false,
|
|
14671
14720
|
children
|
|
14672
14721
|
} = props;
|
|
14673
14722
|
const captureMode = props.captureMode ?? DEFAULT_CAPTURE_MODE;
|
|
@@ -15063,6 +15112,15 @@ function LiveAgent(props) {
|
|
|
15063
15112
|
selectModule,
|
|
15064
15113
|
startAdoptionSession
|
|
15065
15114
|
});
|
|
15115
|
+
useEffect51(() => {
|
|
15116
|
+
if (bearerToken === null || !hasResolvedModules || !defaultModule)
|
|
15117
|
+
return;
|
|
15118
|
+
provideStartSession(startDefaultSession);
|
|
15119
|
+
return () => provideStartSession(null);
|
|
15120
|
+
}, [bearerToken, hasResolvedModules, defaultModule, startDefaultSession]);
|
|
15121
|
+
useEffect51(() => {
|
|
15122
|
+
setHostSessionLive(isSessionLive);
|
|
15123
|
+
}, [isSessionLive]);
|
|
15066
15124
|
useEffect51(() => {
|
|
15067
15125
|
if (!autoStartAfterLogin)
|
|
15068
15126
|
return;
|
|
@@ -15380,7 +15438,8 @@ function LiveAgent(props) {
|
|
|
15380
15438
|
}),
|
|
15381
15439
|
connection && captureMode === CAPTURE_MODE.Auto && /* @__PURE__ */ jsx56(DomCapture, {
|
|
15382
15440
|
pushOrTapMicMode: isRequestResponseMicMode(agentControls?.micMode),
|
|
15383
|
-
startMuted
|
|
15441
|
+
startMuted,
|
|
15442
|
+
suppressVideoPublish
|
|
15384
15443
|
}),
|
|
15385
15444
|
/* @__PURE__ */ jsxs44(ShadowHost, {
|
|
15386
15445
|
accentColor: appearance?.accentColor ?? null,
|