@skippr/live-agent-sdk 0.26.0 → 0.27.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 +2 -2
- package/dist/esm/lib-exports.js +203 -163
- package/dist/skippr-sdk.css +1 -1
- package/dist/skippr-sdk.js +107 -107
- package/dist/types/components/AgentStateBanner.d.ts +1 -0
- package/dist/types/components/LiveAgent.d.ts +2 -2
- package/dist/types/components/SessionAgenda.d.ts +2 -1
- package/dist/types/hooks/useAgentVoiceState.d.ts +1 -2
- package/package.json +1 -1
- package/dist/types/components/ObservingBanner.d.ts +0 -1
package/README.md
CHANGED
|
@@ -193,7 +193,7 @@ Self-contained widget component. Renders a floating button that opens a sidebar
|
|
|
193
193
|
| `welcomeMessage` | `string` | — | Message shown on the minimized bubble |
|
|
194
194
|
| `startSessionLabel` | `string` | `'Talk to Skippr'` | Label for the start-session button |
|
|
195
195
|
| `autoFocusChat` | `boolean` | `true` | Whether the chat input auto-focuses when opened |
|
|
196
|
-
| `
|
|
196
|
+
| `showAgentStateBanner` | `boolean` | `true` | Whether to show the top-pinned status banner (talking / thinking / listening / observing) while connected |
|
|
197
197
|
|
|
198
198
|
### `useLiveAgent()`
|
|
199
199
|
|
|
@@ -232,7 +232,7 @@ All hooks must be called within `<LiveAgent>`.
|
|
|
232
232
|
| Hook | Returns | Description |
|
|
233
233
|
|------|---------|-------------|
|
|
234
234
|
| `useMediaControls()` | `{ isMuted, isScreenSharing, toggleMute, toggleScreenShare }` | Mic and screen share state and toggles |
|
|
235
|
-
| `useAgentVoiceState()` | `{ isSpeaking,
|
|
235
|
+
| `useAgentVoiceState()` | `{ state, isSpeaking, isListening }` | Agent voice activity state — `state` is the full agent state (`'listening' \| 'thinking' \| 'speaking' \| ...`) |
|
|
236
236
|
| `useIsLocalSpeaking()` | `boolean` | Whether the local user is currently speaking |
|
|
237
237
|
| `useElapsedSeconds(isRunning)` | `number` | Drift-safe elapsed seconds since the flag flipped to `true` |
|
|
238
238
|
|
package/dist/esm/lib-exports.js
CHANGED
|
@@ -283,36 +283,6 @@ function useSession({ agentId, authToken, appKey, userToken }) {
|
|
|
283
283
|
pendingScreenStream
|
|
284
284
|
};
|
|
285
285
|
}
|
|
286
|
-
|
|
287
|
-
// src/components/AutoStartMedia.tsx
|
|
288
|
-
import { useConnectionState, useLocalParticipant } from "@livekit/components-react";
|
|
289
|
-
import { ConnectionState, Track } from "livekit-client";
|
|
290
|
-
import { useEffect as useEffect3, useRef } from "react";
|
|
291
|
-
function AutoStartMedia({ pendingScreenStream }) {
|
|
292
|
-
const { localParticipant } = useLocalParticipant();
|
|
293
|
-
const connectionState = useConnectionState();
|
|
294
|
-
const didStartRef = useRef(false);
|
|
295
|
-
useEffect3(() => {
|
|
296
|
-
if (didStartRef.current)
|
|
297
|
-
return;
|
|
298
|
-
if (connectionState !== ConnectionState.Connected)
|
|
299
|
-
return;
|
|
300
|
-
didStartRef.current = true;
|
|
301
|
-
localParticipant.setMicrophoneEnabled(true).catch((error) => console.error("Failed to enable microphone:", error));
|
|
302
|
-
if (pendingScreenStream) {
|
|
303
|
-
const videoTrack = pendingScreenStream.getVideoTracks()[0];
|
|
304
|
-
if (videoTrack) {
|
|
305
|
-
videoTrack.contentHint = "detail";
|
|
306
|
-
localParticipant.publishTrack(videoTrack, { source: Track.Source.ScreenShare }).catch((error) => {
|
|
307
|
-
console.error("Failed to publish screen share track:", error);
|
|
308
|
-
for (const track of pendingScreenStream.getTracks())
|
|
309
|
-
track.stop();
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
}, [connectionState, localParticipant, pendingScreenStream]);
|
|
314
|
-
return null;
|
|
315
|
-
}
|
|
316
286
|
// ../../node_modules/.bun/lucide-react@1.8.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/createLucideIcon.js
|
|
317
287
|
import { forwardRef as forwardRef2, createElement as createElement3 } from "react";
|
|
318
288
|
|
|
@@ -542,9 +512,6 @@ var __iconNode16 = [
|
|
|
542
512
|
["path", { d: "m21.854 2.147-10.94 10.939", key: "12cjpa" }]
|
|
543
513
|
];
|
|
544
514
|
var Send = createLucideIcon("send", __iconNode16);
|
|
545
|
-
// src/components/MinimizedBubble.tsx
|
|
546
|
-
import { useEffect as useEffect4 } from "react";
|
|
547
|
-
|
|
548
515
|
// src/hooks/useAgentVoiceState.ts
|
|
549
516
|
import { useVoiceAssistant } from "@livekit/components-react";
|
|
550
517
|
function useAgentVoiceState() {
|
|
@@ -568,7 +535,7 @@ function useLiveAgent() {
|
|
|
568
535
|
}
|
|
569
536
|
|
|
570
537
|
// src/hooks/useMediaControls.ts
|
|
571
|
-
import { useLocalParticipant
|
|
538
|
+
import { useLocalParticipant } from "@livekit/components-react";
|
|
572
539
|
import { ScreenSharePresets } from "livekit-client";
|
|
573
540
|
import { useCallback as useCallback3 } from "react";
|
|
574
541
|
var SCREEN_SHARE_OPTIONS = {
|
|
@@ -577,7 +544,7 @@ var SCREEN_SHARE_OPTIONS = {
|
|
|
577
544
|
contentHint: "detail"
|
|
578
545
|
};
|
|
579
546
|
function useMediaControls() {
|
|
580
|
-
const { localParticipant } =
|
|
547
|
+
const { localParticipant } = useLocalParticipant();
|
|
581
548
|
const isMuted = !localParticipant.isMicrophoneEnabled;
|
|
582
549
|
const isScreenSharing = localParticipant.isScreenShareEnabled;
|
|
583
550
|
const toggleMute = useCallback3(async () => {
|
|
@@ -597,6 +564,156 @@ function useMediaControls() {
|
|
|
597
564
|
return { isMuted, toggleMute, isScreenSharing, toggleScreenShare };
|
|
598
565
|
}
|
|
599
566
|
|
|
567
|
+
// src/components/AgentStateBanner.tsx
|
|
568
|
+
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
569
|
+
function AgentStateBanner() {
|
|
570
|
+
const { isConnected } = useLiveAgent();
|
|
571
|
+
const { isScreenSharing } = useMediaControls();
|
|
572
|
+
const { state } = useAgentVoiceState();
|
|
573
|
+
if (!isConnected)
|
|
574
|
+
return null;
|
|
575
|
+
return /* @__PURE__ */ jsx("div", {
|
|
576
|
+
className: "skippr:fixed skippr:top-0 skippr:left-0 skippr:right-0 skippr:z-[2147483647] skippr:flex skippr:justify-center skippr:pointer-events-none",
|
|
577
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
578
|
+
className: "skippr:pointer-events-auto skippr:flex skippr:items-center skippr:gap-2 skippr:bg-indigo-500/95 skippr:backdrop-blur-sm skippr:text-white skippr:text-xs skippr:font-medium skippr:px-4 skippr:py-1.5 skippr:rounded-b-lg skippr:shadow-lg",
|
|
579
|
+
children: /* @__PURE__ */ jsx(BannerContent, {
|
|
580
|
+
state,
|
|
581
|
+
isScreenSharing
|
|
582
|
+
})
|
|
583
|
+
})
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
function BannerContent({
|
|
587
|
+
state,
|
|
588
|
+
isScreenSharing
|
|
589
|
+
}) {
|
|
590
|
+
if (state === "speaking") {
|
|
591
|
+
return /* @__PURE__ */ jsxs(Fragment, {
|
|
592
|
+
children: [
|
|
593
|
+
/* @__PURE__ */ jsx(SpeakingBars, {}),
|
|
594
|
+
/* @__PURE__ */ jsx("span", {
|
|
595
|
+
children: "Skippr is talking"
|
|
596
|
+
})
|
|
597
|
+
]
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
if (state === "thinking") {
|
|
601
|
+
return /* @__PURE__ */ jsxs(Fragment, {
|
|
602
|
+
children: [
|
|
603
|
+
/* @__PURE__ */ jsx(ThinkingDots, {}),
|
|
604
|
+
/* @__PURE__ */ jsx("span", {
|
|
605
|
+
children: "Skippr is thinking"
|
|
606
|
+
})
|
|
607
|
+
]
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
if (state === "listening" && isScreenSharing) {
|
|
611
|
+
return /* @__PURE__ */ jsxs(Fragment, {
|
|
612
|
+
children: [
|
|
613
|
+
/* @__PURE__ */ jsx(ObservingDot, {}),
|
|
614
|
+
/* @__PURE__ */ jsx(Eye, {
|
|
615
|
+
className: "skippr:size-3.5"
|
|
616
|
+
}),
|
|
617
|
+
/* @__PURE__ */ jsx("span", {
|
|
618
|
+
children: "Skippr is observing this page"
|
|
619
|
+
})
|
|
620
|
+
]
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
return /* @__PURE__ */ jsxs(Fragment, {
|
|
624
|
+
children: [
|
|
625
|
+
/* @__PURE__ */ jsx(ObservingDot, {}),
|
|
626
|
+
/* @__PURE__ */ jsx("span", {
|
|
627
|
+
children: "Skippr is connected"
|
|
628
|
+
})
|
|
629
|
+
]
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
function ObservingDot() {
|
|
633
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
634
|
+
className: "skippr:relative skippr:flex skippr:size-1.5",
|
|
635
|
+
children: [
|
|
636
|
+
/* @__PURE__ */ jsx("span", {
|
|
637
|
+
className: "skippr:absolute skippr:inline-flex skippr:size-full skippr:animate-ping skippr:rounded-full skippr:bg-emerald-400 skippr:opacity-75"
|
|
638
|
+
}),
|
|
639
|
+
/* @__PURE__ */ jsx("span", {
|
|
640
|
+
className: "skippr:relative skippr:inline-flex skippr:size-1.5 skippr:rounded-full skippr:bg-emerald-400"
|
|
641
|
+
})
|
|
642
|
+
]
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
function ThinkingDots() {
|
|
646
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
647
|
+
className: "skippr:flex skippr:items-center skippr:gap-[3px]",
|
|
648
|
+
children: [
|
|
649
|
+
/* @__PURE__ */ jsx("span", {
|
|
650
|
+
className: "skippr:size-1 skippr:rounded-full skippr:bg-white skippr:animate-bounce skippr:[animation-delay:0ms]"
|
|
651
|
+
}),
|
|
652
|
+
/* @__PURE__ */ jsx("span", {
|
|
653
|
+
className: "skippr:size-1 skippr:rounded-full skippr:bg-white skippr:animate-bounce skippr:[animation-delay:150ms]"
|
|
654
|
+
}),
|
|
655
|
+
/* @__PURE__ */ jsx("span", {
|
|
656
|
+
className: "skippr:size-1 skippr:rounded-full skippr:bg-white skippr:animate-bounce skippr:[animation-delay:300ms]"
|
|
657
|
+
})
|
|
658
|
+
]
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
function SpeakingBars() {
|
|
662
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
663
|
+
className: "skippr:flex skippr:items-center skippr:gap-[2px] skippr:h-3.5",
|
|
664
|
+
children: [
|
|
665
|
+
/* @__PURE__ */ jsx("span", {
|
|
666
|
+
className: "skippr:w-[2px] skippr:rounded-sm skippr:bg-white skippr:animate-[skippr-speak_1.1s_ease-in-out_infinite] skippr:h-1.5"
|
|
667
|
+
}),
|
|
668
|
+
/* @__PURE__ */ jsx("span", {
|
|
669
|
+
className: "skippr:w-[2px] skippr:rounded-sm skippr:bg-white skippr:animate-[skippr-speak_1.1s_ease-in-out_0.15s_infinite] skippr:h-3"
|
|
670
|
+
}),
|
|
671
|
+
/* @__PURE__ */ jsx("span", {
|
|
672
|
+
className: "skippr:w-[2px] skippr:rounded-sm skippr:bg-white skippr:animate-[skippr-speak_1.1s_ease-in-out_0.3s_infinite] skippr:h-2"
|
|
673
|
+
}),
|
|
674
|
+
/* @__PURE__ */ jsx("span", {
|
|
675
|
+
className: "skippr:w-[2px] skippr:rounded-sm skippr:bg-white skippr:animate-[skippr-speak_1.1s_ease-in-out_0.45s_infinite] skippr:h-3.5"
|
|
676
|
+
}),
|
|
677
|
+
/* @__PURE__ */ jsx("span", {
|
|
678
|
+
className: "skippr:w-[2px] skippr:rounded-sm skippr:bg-white skippr:animate-[skippr-speak_1.1s_ease-in-out_0.6s_infinite] skippr:h-1"
|
|
679
|
+
})
|
|
680
|
+
]
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// src/components/AutoStartMedia.tsx
|
|
685
|
+
import { useConnectionState, useLocalParticipant as useLocalParticipant2 } from "@livekit/components-react";
|
|
686
|
+
import { ConnectionState, Track } from "livekit-client";
|
|
687
|
+
import { useEffect as useEffect3, useRef } from "react";
|
|
688
|
+
function AutoStartMedia({ pendingScreenStream }) {
|
|
689
|
+
const { localParticipant } = useLocalParticipant2();
|
|
690
|
+
const connectionState = useConnectionState();
|
|
691
|
+
const didStartRef = useRef(false);
|
|
692
|
+
useEffect3(() => {
|
|
693
|
+
if (didStartRef.current)
|
|
694
|
+
return;
|
|
695
|
+
if (connectionState !== ConnectionState.Connected)
|
|
696
|
+
return;
|
|
697
|
+
didStartRef.current = true;
|
|
698
|
+
localParticipant.setMicrophoneEnabled(true).catch((error) => console.error("Failed to enable microphone:", error));
|
|
699
|
+
if (pendingScreenStream) {
|
|
700
|
+
const videoTrack = pendingScreenStream.getVideoTracks()[0];
|
|
701
|
+
if (videoTrack) {
|
|
702
|
+
videoTrack.contentHint = "detail";
|
|
703
|
+
localParticipant.publishTrack(videoTrack, { source: Track.Source.ScreenShare }).catch((error) => {
|
|
704
|
+
console.error("Failed to publish screen share track:", error);
|
|
705
|
+
for (const track of pendingScreenStream.getTracks())
|
|
706
|
+
track.stop();
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
}, [connectionState, localParticipant, pendingScreenStream]);
|
|
711
|
+
return null;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
// src/components/MinimizedBubble.tsx
|
|
715
|
+
import { useEffect as useEffect4 } from "react";
|
|
716
|
+
|
|
600
717
|
// src/lib/utils.ts
|
|
601
718
|
import { clsx } from "clsx";
|
|
602
719
|
import { twMerge } from "tailwind-merge";
|
|
@@ -606,12 +723,12 @@ function cn(...inputs) {
|
|
|
606
723
|
|
|
607
724
|
// src/components/Logo.tsx
|
|
608
725
|
import { useId } from "react";
|
|
609
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
726
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
610
727
|
function Logo({ className }) {
|
|
611
728
|
const reactId = useId().replace(/:/g, "");
|
|
612
729
|
const clipId = `skippr-logo-clip-${reactId}`;
|
|
613
730
|
const gradientId = `skippr-logo-gradient-${reactId}`;
|
|
614
|
-
return /* @__PURE__ */
|
|
731
|
+
return /* @__PURE__ */ jsxs2("svg", {
|
|
615
732
|
width: "1em",
|
|
616
733
|
height: "1em",
|
|
617
734
|
viewBox: "0 0 30 30",
|
|
@@ -621,14 +738,14 @@ function Logo({ className }) {
|
|
|
621
738
|
"aria-label": "Skippr",
|
|
622
739
|
className,
|
|
623
740
|
children: [
|
|
624
|
-
/* @__PURE__ */
|
|
741
|
+
/* @__PURE__ */ jsxs2("g", {
|
|
625
742
|
clipPath: `url(#${clipId})`,
|
|
626
743
|
children: [
|
|
627
|
-
/* @__PURE__ */
|
|
744
|
+
/* @__PURE__ */ jsx2("path", {
|
|
628
745
|
d: "M0 10C0 4.47715 4.47715 0 10 0H20C25.5228 0 30 4.47715 30 10V20C30 25.5228 25.5228 30 20 30H10C4.47715 30 0 25.5228 0 20V10Z",
|
|
629
746
|
fill: "#2D2D3F"
|
|
630
747
|
}),
|
|
631
|
-
/* @__PURE__ */
|
|
748
|
+
/* @__PURE__ */ jsx2("rect", {
|
|
632
749
|
x: "7.83325",
|
|
633
750
|
y: "14.9404",
|
|
634
751
|
width: "12.4083",
|
|
@@ -637,11 +754,11 @@ function Logo({ className }) {
|
|
|
637
754
|
transform: "rotate(-45 7.83325 14.9404)",
|
|
638
755
|
fill: "#52FFF9"
|
|
639
756
|
}),
|
|
640
|
-
/* @__PURE__ */
|
|
757
|
+
/* @__PURE__ */ jsx2("path", {
|
|
641
758
|
d: "M18.8975 12.5928C20.2728 12.5928 21.3877 13.647 21.3877 14.9474C21.3877 16.2479 20.2728 17.3021 18.8975 17.3021L11.4269 17.3021C10.0516 17.3021 8.93665 16.2479 8.93665 14.9474C8.93665 13.647 10.0516 12.5928 11.4269 12.5928L18.8975 12.5928Z",
|
|
642
759
|
fill: `url(#${gradientId})`
|
|
643
760
|
}),
|
|
644
|
-
/* @__PURE__ */
|
|
761
|
+
/* @__PURE__ */ jsx2("rect", {
|
|
645
762
|
x: "10.1665",
|
|
646
763
|
y: "20.4404",
|
|
647
764
|
width: "12.4083",
|
|
@@ -652,9 +769,9 @@ function Logo({ className }) {
|
|
|
652
769
|
})
|
|
653
770
|
]
|
|
654
771
|
}),
|
|
655
|
-
/* @__PURE__ */
|
|
772
|
+
/* @__PURE__ */ jsxs2("defs", {
|
|
656
773
|
children: [
|
|
657
|
-
/* @__PURE__ */
|
|
774
|
+
/* @__PURE__ */ jsxs2("linearGradient", {
|
|
658
775
|
id: gradientId,
|
|
659
776
|
x1: "18.9237",
|
|
660
777
|
y1: "16.9997",
|
|
@@ -662,19 +779,19 @@ function Logo({ className }) {
|
|
|
662
779
|
y2: "14.1904",
|
|
663
780
|
gradientUnits: "userSpaceOnUse",
|
|
664
781
|
children: [
|
|
665
|
-
/* @__PURE__ */
|
|
782
|
+
/* @__PURE__ */ jsx2("stop", {
|
|
666
783
|
offset: "0.473958",
|
|
667
784
|
stopColor: "white"
|
|
668
785
|
}),
|
|
669
|
-
/* @__PURE__ */
|
|
786
|
+
/* @__PURE__ */ jsx2("stop", {
|
|
670
787
|
offset: "1",
|
|
671
788
|
stopColor: "#52FFF9"
|
|
672
789
|
})
|
|
673
790
|
]
|
|
674
791
|
}),
|
|
675
|
-
/* @__PURE__ */
|
|
792
|
+
/* @__PURE__ */ jsx2("clipPath", {
|
|
676
793
|
id: clipId,
|
|
677
|
-
children: /* @__PURE__ */
|
|
794
|
+
children: /* @__PURE__ */ jsx2("rect", {
|
|
678
795
|
width: "30",
|
|
679
796
|
height: "30",
|
|
680
797
|
fill: "white"
|
|
@@ -687,18 +804,18 @@ function Logo({ className }) {
|
|
|
687
804
|
}
|
|
688
805
|
|
|
689
806
|
// src/components/ui/tooltip.tsx
|
|
690
|
-
import { jsx as
|
|
807
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
691
808
|
var ALIGN_CLASSES = {
|
|
692
809
|
center: "skippr:left-1/2 skippr:-translate-x-1/2",
|
|
693
810
|
start: "skippr:left-0",
|
|
694
811
|
end: "skippr:right-0"
|
|
695
812
|
};
|
|
696
813
|
function Tooltip({ label, children, position = "top", align = "center" }) {
|
|
697
|
-
return /* @__PURE__ */
|
|
814
|
+
return /* @__PURE__ */ jsxs3("span", {
|
|
698
815
|
className: "skippr:relative skippr:inline-flex skippr:group",
|
|
699
816
|
children: [
|
|
700
817
|
children,
|
|
701
|
-
/* @__PURE__ */
|
|
818
|
+
/* @__PURE__ */ jsx3("span", {
|
|
702
819
|
className: cn("skippr:pointer-events-none skippr:absolute skippr:z-10", "skippr:whitespace-nowrap skippr:rounded-md skippr:bg-foreground skippr:px-2 skippr:py-1", "skippr:text-[11px] skippr:text-background skippr:font-medium", "skippr:opacity-0 skippr:scale-95 skippr:transition-all skippr:duration-150", "skippr:group-hover:opacity-100 skippr:group-hover:scale-100", "skippr:group-focus-within:opacity-100 skippr:group-focus-within:scale-100", ALIGN_CLASSES[align], position === "top" && "skippr:bottom-full skippr:mb-1.5", position === "bottom" && "skippr:top-full skippr:mt-1.5"),
|
|
703
820
|
"aria-hidden": "true",
|
|
704
821
|
children: label
|
|
@@ -708,111 +825,67 @@ function Tooltip({ label, children, position = "top", align = "center" }) {
|
|
|
708
825
|
}
|
|
709
826
|
|
|
710
827
|
// src/components/MinimizedBubble.tsx
|
|
711
|
-
import { jsx as
|
|
828
|
+
import { jsx as jsx4, jsxs as jsxs4, Fragment as Fragment2 } from "react/jsx-runtime";
|
|
712
829
|
var BUBBLE_BUTTON = "skippr:flex skippr:size-12 skippr:cursor-pointer skippr:items-center skippr:justify-center skippr:rounded-[14px] skippr:shadow-[0_4px_16px_rgba(45,43,61,0.45),0_2px_4px_rgba(0,0,0,0.1)] skippr:transition-all skippr:hover:-translate-y-0.5 skippr:active:translate-y-0";
|
|
713
|
-
function AgentBubbleContent({ agentState }) {
|
|
714
|
-
if (agentState === "speaking") {
|
|
715
|
-
return /* @__PURE__ */ jsxs3("div", {
|
|
716
|
-
className: "skippr:flex skippr:h-5 skippr:items-center skippr:justify-center skippr:gap-[3px]",
|
|
717
|
-
children: [
|
|
718
|
-
/* @__PURE__ */ jsx3("span", {
|
|
719
|
-
className: "skippr:w-[3px] skippr:h-2 skippr:rounded-sm skippr:bg-white skippr:animate-[skippr-speak_1.1s_ease-in-out_infinite]"
|
|
720
|
-
}),
|
|
721
|
-
/* @__PURE__ */ jsx3("span", {
|
|
722
|
-
className: "skippr:w-[3px] skippr:h-3.5 skippr:rounded-sm skippr:bg-white skippr:animate-[skippr-speak_1.1s_ease-in-out_0.15s_infinite]"
|
|
723
|
-
}),
|
|
724
|
-
/* @__PURE__ */ jsx3("span", {
|
|
725
|
-
className: "skippr:w-[3px] skippr:h-2.5 skippr:rounded-sm skippr:bg-white skippr:animate-[skippr-speak_1.1s_ease-in-out_0.3s_infinite]"
|
|
726
|
-
}),
|
|
727
|
-
/* @__PURE__ */ jsx3("span", {
|
|
728
|
-
className: "skippr:w-[3px] skippr:h-4 skippr:rounded-sm skippr:bg-white skippr:animate-[skippr-speak_1.1s_ease-in-out_0.45s_infinite]"
|
|
729
|
-
}),
|
|
730
|
-
/* @__PURE__ */ jsx3("span", {
|
|
731
|
-
className: "skippr:w-[3px] skippr:h-1.5 skippr:rounded-sm skippr:bg-white skippr:animate-[skippr-speak_1.1s_ease-in-out_0.6s_infinite]"
|
|
732
|
-
})
|
|
733
|
-
]
|
|
734
|
-
});
|
|
735
|
-
}
|
|
736
|
-
if (agentState === "thinking") {
|
|
737
|
-
return /* @__PURE__ */ jsxs3("div", {
|
|
738
|
-
className: "skippr:flex skippr:items-center skippr:justify-center skippr:gap-[4px]",
|
|
739
|
-
children: [
|
|
740
|
-
/* @__PURE__ */ jsx3("span", {
|
|
741
|
-
className: "skippr:size-1.5 skippr:rounded-full skippr:bg-white skippr:animate-bounce skippr:[animation-delay:0ms]"
|
|
742
|
-
}),
|
|
743
|
-
/* @__PURE__ */ jsx3("span", {
|
|
744
|
-
className: "skippr:size-1.5 skippr:rounded-full skippr:bg-white skippr:animate-bounce skippr:[animation-delay:150ms]"
|
|
745
|
-
}),
|
|
746
|
-
/* @__PURE__ */ jsx3("span", {
|
|
747
|
-
className: "skippr:size-1.5 skippr:rounded-full skippr:bg-white skippr:animate-bounce skippr:[animation-delay:300ms]"
|
|
748
|
-
})
|
|
749
|
-
]
|
|
750
|
-
});
|
|
751
|
-
}
|
|
752
|
-
return /* @__PURE__ */ jsx3(Logo, {
|
|
753
|
-
className: "skippr:size-7"
|
|
754
|
-
});
|
|
755
|
-
}
|
|
756
830
|
function ConnectedBubbleContent() {
|
|
757
831
|
const { expandPanel, disconnect, position } = useLiveAgent();
|
|
758
|
-
const { state: agentState } = useAgentVoiceState();
|
|
759
832
|
const { isMuted, toggleMute, isScreenSharing, toggleScreenShare } = useMediaControls();
|
|
760
833
|
const tooltipAlign = position === "right" ? "end" : "start";
|
|
761
|
-
return /* @__PURE__ */
|
|
834
|
+
return /* @__PURE__ */ jsxs4(Fragment2, {
|
|
762
835
|
children: [
|
|
763
|
-
/* @__PURE__ */
|
|
836
|
+
/* @__PURE__ */ jsx4(Tooltip, {
|
|
764
837
|
label: isMuted ? "Unmute" : "Mute",
|
|
765
838
|
align: tooltipAlign,
|
|
766
|
-
children: /* @__PURE__ */
|
|
839
|
+
children: /* @__PURE__ */ jsx4("button", {
|
|
767
840
|
type: "button",
|
|
768
841
|
onClick: toggleMute,
|
|
769
842
|
"aria-label": isMuted ? "Unmute" : "Mute",
|
|
770
843
|
className: cn(BUBBLE_BUTTON, isMuted ? "skippr:bg-destructive skippr:text-destructive-foreground skippr:hover:bg-destructive/90" : "skippr:bg-white skippr:text-foreground skippr:hover:bg-muted"),
|
|
771
|
-
children: isMuted ? /* @__PURE__ */
|
|
844
|
+
children: isMuted ? /* @__PURE__ */ jsx4(MicOff, {
|
|
772
845
|
className: "skippr:size-5"
|
|
773
|
-
}) : /* @__PURE__ */
|
|
846
|
+
}) : /* @__PURE__ */ jsx4(Mic, {
|
|
774
847
|
className: "skippr:size-5"
|
|
775
848
|
})
|
|
776
849
|
})
|
|
777
850
|
}),
|
|
778
|
-
/* @__PURE__ */
|
|
851
|
+
/* @__PURE__ */ jsx4(Tooltip, {
|
|
779
852
|
label: isScreenSharing ? "Stop sharing" : "Share screen",
|
|
780
853
|
align: tooltipAlign,
|
|
781
|
-
children: /* @__PURE__ */
|
|
854
|
+
children: /* @__PURE__ */ jsx4("button", {
|
|
782
855
|
type: "button",
|
|
783
856
|
onClick: toggleScreenShare,
|
|
784
857
|
"aria-label": isScreenSharing ? "Stop sharing screen" : "Share screen",
|
|
785
858
|
className: cn(BUBBLE_BUTTON, isScreenSharing ? "skippr:bg-bubble skippr:text-white skippr:hover:brightness-110" : "skippr:bg-white skippr:text-foreground skippr:hover:bg-muted"),
|
|
786
|
-
children: isScreenSharing ? /* @__PURE__ */
|
|
859
|
+
children: isScreenSharing ? /* @__PURE__ */ jsx4(MonitorOff, {
|
|
787
860
|
className: "skippr:size-5"
|
|
788
|
-
}) : /* @__PURE__ */
|
|
861
|
+
}) : /* @__PURE__ */ jsx4(Monitor, {
|
|
789
862
|
className: "skippr:size-5"
|
|
790
863
|
})
|
|
791
864
|
})
|
|
792
865
|
}),
|
|
793
|
-
/* @__PURE__ */
|
|
866
|
+
/* @__PURE__ */ jsx4(Tooltip, {
|
|
794
867
|
label: "End session",
|
|
795
868
|
align: tooltipAlign,
|
|
796
|
-
children: /* @__PURE__ */
|
|
869
|
+
children: /* @__PURE__ */ jsx4("button", {
|
|
797
870
|
type: "button",
|
|
798
871
|
onClick: () => disconnect(),
|
|
799
872
|
"aria-label": "End session",
|
|
800
873
|
className: cn(BUBBLE_BUTTON, "skippr:bg-destructive skippr:text-destructive-foreground skippr:hover:bg-destructive/90"),
|
|
801
|
-
children: /* @__PURE__ */
|
|
874
|
+
children: /* @__PURE__ */ jsx4(PhoneOff, {
|
|
802
875
|
className: "skippr:size-5"
|
|
803
876
|
})
|
|
804
877
|
})
|
|
805
878
|
}),
|
|
806
|
-
/* @__PURE__ */
|
|
879
|
+
/* @__PURE__ */ jsx4(Tooltip, {
|
|
807
880
|
label: "Open chat & transcript",
|
|
808
881
|
align: tooltipAlign,
|
|
809
|
-
children: /* @__PURE__ */
|
|
882
|
+
children: /* @__PURE__ */ jsx4("button", {
|
|
810
883
|
type: "button",
|
|
811
884
|
onClick: expandPanel,
|
|
812
885
|
"aria-label": "Open chat & transcript",
|
|
813
886
|
className: cn(BUBBLE_BUTTON, "skippr:bg-bubble skippr:hover:brightness-110"),
|
|
814
|
-
children: /* @__PURE__ */
|
|
815
|
-
|
|
887
|
+
children: /* @__PURE__ */ jsx4(Logo, {
|
|
888
|
+
className: "skippr:size-7"
|
|
816
889
|
})
|
|
817
890
|
})
|
|
818
891
|
})
|
|
@@ -822,19 +895,19 @@ function ConnectedBubbleContent() {
|
|
|
822
895
|
function IdleBubbleContent() {
|
|
823
896
|
const { expandPanel, position } = useLiveAgent();
|
|
824
897
|
const tooltipAlign = position === "right" ? "end" : "start";
|
|
825
|
-
return /* @__PURE__ */
|
|
898
|
+
return /* @__PURE__ */ jsx4(Tooltip, {
|
|
826
899
|
label: "Open Skippr assistant",
|
|
827
900
|
align: tooltipAlign,
|
|
828
|
-
children: /* @__PURE__ */
|
|
901
|
+
children: /* @__PURE__ */ jsxs4("button", {
|
|
829
902
|
type: "button",
|
|
830
903
|
onClick: expandPanel,
|
|
831
904
|
"aria-label": "Skippr assistant",
|
|
832
905
|
className: cn(BUBBLE_BUTTON, "skippr:relative skippr:bg-bubble skippr:hover:brightness-110"),
|
|
833
906
|
children: [
|
|
834
|
-
/* @__PURE__ */
|
|
907
|
+
/* @__PURE__ */ jsx4(Logo, {
|
|
835
908
|
className: "skippr:relative skippr:z-10 skippr:size-7"
|
|
836
909
|
}),
|
|
837
|
-
/* @__PURE__ */
|
|
910
|
+
/* @__PURE__ */ jsx4("span", {
|
|
838
911
|
className: "skippr:absolute skippr:-inset-[3px] skippr:animate-pulse skippr:rounded-[17px] skippr:border-2 skippr:border-bubble/50"
|
|
839
912
|
})
|
|
840
913
|
]
|
|
@@ -850,14 +923,14 @@ function WelcomeBubble({
|
|
|
850
923
|
const timer = setTimeout(onDismiss, 5000);
|
|
851
924
|
return () => clearTimeout(timer);
|
|
852
925
|
}, [onDismiss]);
|
|
853
|
-
return /* @__PURE__ */
|
|
926
|
+
return /* @__PURE__ */ jsxs4("button", {
|
|
854
927
|
type: "button",
|
|
855
928
|
className: cn("skippr:absolute skippr:bottom-full skippr:mb-3", "skippr:max-w-64 skippr:rounded-xl skippr:bg-card skippr:shadow-lg", "skippr:border skippr:border-border skippr:px-4 skippr:py-3", "skippr:text-sm skippr:text-foreground skippr:leading-relaxed skippr:text-left", "skippr:animate-[skippr-fade-in_0.3s_ease-out]", "skippr:cursor-pointer", position === "right" ? "skippr:right-0" : "skippr:left-0"),
|
|
856
929
|
onClick: onDismiss,
|
|
857
930
|
"aria-label": "Dismiss",
|
|
858
931
|
children: [
|
|
859
932
|
message,
|
|
860
|
-
/* @__PURE__ */
|
|
933
|
+
/* @__PURE__ */ jsx4("span", {
|
|
861
934
|
className: cn("skippr:absolute skippr:top-full skippr:size-2.5", "skippr:border-l skippr:border-t skippr:border-border skippr:bg-card", "skippr:rotate-[225deg]", position === "right" ? "skippr:right-5" : "skippr:left-5", "skippr:-mt-[5px]")
|
|
862
935
|
})
|
|
863
936
|
]
|
|
@@ -870,53 +943,19 @@ function MinimizedBubble({
|
|
|
870
943
|
}) {
|
|
871
944
|
const { isConnected, isStarting, position } = useLiveAgent();
|
|
872
945
|
const inSession = isConnected || isStarting;
|
|
873
|
-
return /* @__PURE__ */
|
|
946
|
+
return /* @__PURE__ */ jsxs4("div", {
|
|
874
947
|
className: cn("skippr:fixed skippr:bottom-6 skippr:z-[9999]", "skippr:flex skippr:items-center skippr:gap-2", position === "right" ? "skippr:right-6" : "skippr:left-6"),
|
|
875
948
|
children: [
|
|
876
|
-
welcomeMessage && !inSession && !welcomeDismissed && /* @__PURE__ */
|
|
949
|
+
welcomeMessage && !inSession && !welcomeDismissed && /* @__PURE__ */ jsx4(WelcomeBubble, {
|
|
877
950
|
message: welcomeMessage,
|
|
878
951
|
position,
|
|
879
952
|
onDismiss: onDismissWelcome
|
|
880
953
|
}),
|
|
881
|
-
inSession ? /* @__PURE__ */
|
|
954
|
+
inSession ? /* @__PURE__ */ jsx4(ConnectedBubbleContent, {}) : /* @__PURE__ */ jsx4(IdleBubbleContent, {})
|
|
882
955
|
]
|
|
883
956
|
});
|
|
884
957
|
}
|
|
885
958
|
|
|
886
|
-
// src/components/ObservingBanner.tsx
|
|
887
|
-
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
888
|
-
function ObservingBanner() {
|
|
889
|
-
const { isConnected } = useLiveAgent();
|
|
890
|
-
const { isScreenSharing } = useMediaControls();
|
|
891
|
-
if (!isConnected || !isScreenSharing)
|
|
892
|
-
return null;
|
|
893
|
-
return /* @__PURE__ */ jsx4("div", {
|
|
894
|
-
className: "skippr:fixed skippr:top-0 skippr:left-0 skippr:right-0 skippr:z-[2147483647] skippr:flex skippr:justify-center skippr:pointer-events-none",
|
|
895
|
-
children: /* @__PURE__ */ jsxs4("div", {
|
|
896
|
-
className: "skippr:pointer-events-auto skippr:flex skippr:items-center skippr:gap-2 skippr:bg-indigo-500/95 skippr:backdrop-blur-sm skippr:text-white skippr:text-xs skippr:font-medium skippr:px-4 skippr:py-1.5 skippr:rounded-b-lg skippr:shadow-lg",
|
|
897
|
-
children: [
|
|
898
|
-
/* @__PURE__ */ jsxs4("span", {
|
|
899
|
-
className: "skippr:relative skippr:flex skippr:size-1.5",
|
|
900
|
-
children: [
|
|
901
|
-
/* @__PURE__ */ jsx4("span", {
|
|
902
|
-
className: "skippr:absolute skippr:inline-flex skippr:size-full skippr:animate-ping skippr:rounded-full skippr:bg-emerald-400 skippr:opacity-75"
|
|
903
|
-
}),
|
|
904
|
-
/* @__PURE__ */ jsx4("span", {
|
|
905
|
-
className: "skippr:relative skippr:inline-flex skippr:size-1.5 skippr:rounded-full skippr:bg-emerald-400"
|
|
906
|
-
})
|
|
907
|
-
]
|
|
908
|
-
}),
|
|
909
|
-
/* @__PURE__ */ jsx4(Eye, {
|
|
910
|
-
className: "skippr:size-3.5"
|
|
911
|
-
}),
|
|
912
|
-
/* @__PURE__ */ jsx4("span", {
|
|
913
|
-
children: "Skippr is observing this page"
|
|
914
|
-
})
|
|
915
|
-
]
|
|
916
|
-
})
|
|
917
|
-
});
|
|
918
|
-
}
|
|
919
|
-
|
|
920
959
|
// src/components/Sidebar.tsx
|
|
921
960
|
import { useEffect as useEffect11 } from "react";
|
|
922
961
|
|
|
@@ -1719,8 +1758,8 @@ function MessageList({
|
|
|
1719
1758
|
|
|
1720
1759
|
// src/components/SessionAgenda.tsx
|
|
1721
1760
|
import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1722
|
-
function SessionAgenda({ phases }) {
|
|
1723
|
-
if (phases.length === 0) {
|
|
1761
|
+
function SessionAgenda({ phases, hasStarted }) {
|
|
1762
|
+
if (phases.length === 0 || !hasStarted) {
|
|
1724
1763
|
return /* @__PURE__ */ jsx14("div", {
|
|
1725
1764
|
className: "skippr:flex skippr:flex-1 skippr:items-center skippr:justify-center",
|
|
1726
1765
|
children: /* @__PURE__ */ jsx14(LoadingDots, {
|
|
@@ -1816,7 +1855,7 @@ function StartSessionPrompt({
|
|
|
1816
1855
|
}
|
|
1817
1856
|
|
|
1818
1857
|
// src/components/Sidebar.tsx
|
|
1819
|
-
import { jsx as jsx17, jsxs as jsxs15, Fragment as
|
|
1858
|
+
import { jsx as jsx17, jsxs as jsxs15, Fragment as Fragment3 } from "react/jsx-runtime";
|
|
1820
1859
|
function Sidebar({
|
|
1821
1860
|
hideControls = false,
|
|
1822
1861
|
hideHeader = false,
|
|
@@ -1899,7 +1938,7 @@ function AuthenticatedContent({
|
|
|
1899
1938
|
startSessionLabel,
|
|
1900
1939
|
autoFocusChat
|
|
1901
1940
|
}) {
|
|
1902
|
-
return /* @__PURE__ */ jsxs15(
|
|
1941
|
+
return /* @__PURE__ */ jsxs15(Fragment3, {
|
|
1903
1942
|
children: [
|
|
1904
1943
|
isConnected && /* @__PURE__ */ jsx17(ConnectedBanner, {}),
|
|
1905
1944
|
/* @__PURE__ */ jsxs15("div", {
|
|
@@ -1937,7 +1976,7 @@ function AuthenticatedContent({
|
|
|
1937
1976
|
}),
|
|
1938
1977
|
/* @__PURE__ */ jsx17("div", {
|
|
1939
1978
|
className: "skippr:flex skippr:min-h-0 skippr:flex-1 skippr:flex-col",
|
|
1940
|
-
children: isConnected ? /* @__PURE__ */ jsx17(ConnectedBody, {
|
|
1979
|
+
children: isConnected || isStarting ? /* @__PURE__ */ jsx17(ConnectedBody, {
|
|
1941
1980
|
activeTab,
|
|
1942
1981
|
autoFocusChat
|
|
1943
1982
|
}) : /* @__PURE__ */ jsx17("div", {
|
|
@@ -1972,7 +2011,8 @@ function ConnectedBody({
|
|
|
1972
2011
|
return /* @__PURE__ */ jsx17("div", {
|
|
1973
2012
|
className: "skippr:min-h-0 skippr:flex-1 skippr:overflow-y-auto skippr:animate-skippr-tab-fade",
|
|
1974
2013
|
children: /* @__PURE__ */ jsx17(SessionAgenda, {
|
|
1975
|
-
phases
|
|
2014
|
+
phases,
|
|
2015
|
+
hasStarted: allMessages.length > 0 || agentState === "speaking"
|
|
1976
2016
|
})
|
|
1977
2017
|
}, "agenda");
|
|
1978
2018
|
}
|
|
@@ -2025,7 +2065,7 @@ function LiveAgent({
|
|
|
2025
2065
|
hideHeader = false,
|
|
2026
2066
|
startSessionLabel = "Talk to Skippr",
|
|
2027
2067
|
autoFocusChat = true,
|
|
2028
|
-
|
|
2068
|
+
showAgentStateBanner = true,
|
|
2029
2069
|
children
|
|
2030
2070
|
}) {
|
|
2031
2071
|
const auth = useAuth({ appKey });
|
|
@@ -2158,7 +2198,7 @@ function LiveAgent({
|
|
|
2158
2198
|
onDisconnected: disconnect,
|
|
2159
2199
|
children: [
|
|
2160
2200
|
connection && /* @__PURE__ */ jsx19(RoomAudioRenderer, {}),
|
|
2161
|
-
|
|
2201
|
+
showAgentStateBanner && /* @__PURE__ */ jsx19(AgentStateBanner, {}),
|
|
2162
2202
|
connection && /* @__PURE__ */ jsx19(AutoStartMedia, {
|
|
2163
2203
|
pendingScreenStream
|
|
2164
2204
|
}),
|