@tavus/cvi-ui 0.0.1-beta.1

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.
Files changed (67) hide show
  1. package/.prettierrc.js +24 -0
  2. package/LICENSE +21 -0
  3. package/README.md +91 -0
  4. package/dev-components/components/cvi-provider/index.tsx +9 -0
  5. package/dev-components/hooks/README.md +499 -0
  6. package/dev-components/hooks/cvi-events-hooks.tsx +168 -0
  7. package/dev-components/hooks/use-cvi-call.tsx +24 -0
  8. package/dev-components/hooks/use-local-camera.tsx +20 -0
  9. package/dev-components/hooks/use-local-microphone.tsx +20 -0
  10. package/dev-components/hooks/use-local-screenshare.tsx +32 -0
  11. package/dev-components/hooks/use-remote-participant-ids.tsx +7 -0
  12. package/dev-components/hooks/use-replica-ids.tsx +9 -0
  13. package/dev-components/hooks/use-request-permissions.tsx +24 -0
  14. package/dev-components/hooks/use-start-haircheck.tsx +60 -0
  15. package/dist/index.js +237334 -0
  16. package/dist/types/cli/add.d.ts +20 -0
  17. package/dist/types/cli/info.d.ts +2 -0
  18. package/dist/types/cli/init.d.ts +23 -0
  19. package/dist/types/components/highlighter.d.ts +6 -0
  20. package/dist/types/components/logger.d.ts +8 -0
  21. package/dist/types/components/spinner.d.ts +4 -0
  22. package/dist/types/constants/components.d.ts +59 -0
  23. package/dist/types/constants/config.d.ts +5 -0
  24. package/dist/types/constants/errors.d.ts +5 -0
  25. package/dist/types/constants/frameworks.d.ts +39 -0
  26. package/dist/types/index.d.ts +1 -0
  27. package/dist/types/preflights/preflight-add.d.ts +15 -0
  28. package/dist/types/preflights/preflight-init.d.ts +9 -0
  29. package/dist/types/utils/add-components.d.ts +5 -0
  30. package/dist/types/utils/get-config.d.ts +51 -0
  31. package/dist/types/utils/get-package-info.d.ts +2 -0
  32. package/dist/types/utils/get-package-manager.d.ts +4 -0
  33. package/dist/types/utils/get-project-info.d.ts +10 -0
  34. package/dist/types/utils/handle-error.d.ts +1 -0
  35. package/dist/types/utils/resolve-components-tree.d.ts +4 -0
  36. package/dist/types/utils/resolve-import.d.ts +2 -0
  37. package/dist/types/utils/update-dependencies.d.ts +4 -0
  38. package/dist/types/utils/update-files.d.ts +14 -0
  39. package/dist/typescript-DhnEO4aV.js +12 -0
  40. package/dist/typescript-XxXP1Woc.js +14 -0
  41. package/eslint.config.js +12 -0
  42. package/package.json +67 -0
  43. package/prepare-scripts/convert-to-js.js +152 -0
  44. package/prepare-scripts/create-templates.js +265 -0
  45. package/rollup.config.js +28 -0
  46. package/src/cli/add.ts +124 -0
  47. package/src/cli/info.ts +21 -0
  48. package/src/cli/init.ts +131 -0
  49. package/src/components/highlighter.ts +8 -0
  50. package/src/components/logger.ts +22 -0
  51. package/src/components/spinner.ts +13 -0
  52. package/src/constants/config.ts +7 -0
  53. package/src/constants/errors.ts +5 -0
  54. package/src/constants/frameworks.ts +40 -0
  55. package/src/index.ts +26 -0
  56. package/src/preflights/preflight-add.ts +56 -0
  57. package/src/preflights/preflight-init.ts +77 -0
  58. package/src/utils/add-components.ts +52 -0
  59. package/src/utils/get-config.ts +60 -0
  60. package/src/utils/get-package-info.ts +14 -0
  61. package/src/utils/get-package-manager.ts +45 -0
  62. package/src/utils/get-project-info.ts +144 -0
  63. package/src/utils/handle-error.ts +34 -0
  64. package/src/utils/resolve-components-tree.ts +35 -0
  65. package/src/utils/update-dependencies.ts +37 -0
  66. package/src/utils/update-files.ts +212 -0
  67. package/tsconfig.json +23 -0
@@ -0,0 +1,168 @@
1
+ import { useAppMessage, useDailyEvent } from "@daily-co/daily-react";
2
+ import { useCallback } from "react";
3
+
4
+ type AppMessageUtterance = {
5
+ "message_type": "conversation",
6
+ "event_type": "conversation.utterance",
7
+ "conversation_id": string,
8
+ "inference_id": string,
9
+ "properties": {
10
+ "role": "user" | "replica",
11
+ "speech": string,
12
+ "visual_context": string
13
+ }
14
+ }
15
+
16
+ type AppMessageToolCall<T> = {
17
+ "message_type": "conversation",
18
+ "event_type": "conversation.tool_call",
19
+ "conversation_id": string,
20
+ "inference_id": string,
21
+ "properties": T
22
+ }
23
+
24
+ type AppMessagePerceptionToolCall<T> = {
25
+ "message_type": "conversation",
26
+ "event_type": "conversation.perception_tool_call",
27
+ "conversation_id": string,
28
+ "properties": T
29
+ }
30
+
31
+ type AppMessagePerceptionAnalysis = {
32
+ "message_type": "conversation",
33
+ "event_type": "conversation.perception_analysis",
34
+ "conversation_id": string,
35
+ "properties": {
36
+ "analysis": string
37
+ }
38
+ }
39
+
40
+ type AppMessageReplicaStartedSpeaking = {
41
+ "message_type": "conversation",
42
+ "event_type": "conversation.replica.started_speaking",
43
+ "inference_id": string
44
+ }
45
+
46
+ type AppMessageReplicaStoppedSpeaking = {
47
+ "message_type": "conversation",
48
+ "event_type": "conversation.replica.stopped_speaking",
49
+ "inference_id": string
50
+ }
51
+
52
+ type AppMessageUserStartedSpeaking = {
53
+ "message_type": "conversation",
54
+ "event_type": "conversation.user.started_speaking",
55
+ "inference_id": string
56
+ }
57
+
58
+ type AppMessageUserStoppedSpeaking = {
59
+ "message_type": "conversation",
60
+ "event_type": "conversation.user.stopped_speaking",
61
+ "inference_id": string
62
+ }
63
+
64
+ type AppMessageReplicaInterrupted = {
65
+ "message_type": "conversation",
66
+ "event_type": "conversation.replica_interrupted",
67
+ "conversation_id": string,
68
+ "inference_id": string
69
+ }
70
+
71
+ type AppMessage<T> = {
72
+ data: AppMessageUtterance |
73
+ AppMessageToolCall<T> |
74
+ AppMessagePerceptionToolCall<T> |
75
+ AppMessagePerceptionAnalysis |
76
+ AppMessageReplicaStartedSpeaking |
77
+ AppMessageReplicaStoppedSpeaking |
78
+ AppMessageUserStartedSpeaking |
79
+ AppMessageUserStoppedSpeaking |
80
+ AppMessageReplicaInterrupted
81
+ };
82
+
83
+ export function useObservableEvent<T>(callback: (event: AppMessage<T>['data']) => void): void {
84
+ return useDailyEvent(
85
+ "app-message",
86
+ useCallback(
87
+ (event: AppMessage<T>) => {
88
+ callback(event.data);
89
+ },
90
+ [callback],
91
+ ),
92
+ )
93
+ }
94
+
95
+ type AppMessageEcho = {
96
+ "message_type": "conversation",
97
+ "event_type": "conversation.echo",
98
+ "conversation_id": string,
99
+ "properties": {
100
+ "modality": "audio" | "text",
101
+ "text": string,
102
+ "audio": string,
103
+ "sample_rate": number,
104
+ "inference_id": string,
105
+ "done": boolean
106
+ }
107
+ }
108
+
109
+ type AppMessageRespond = {
110
+ "message_type": "conversation",
111
+ "event_type": "conversation.respond",
112
+ "conversation_id": string,
113
+ "properties": {
114
+ "text": string
115
+ }
116
+ }
117
+
118
+ type AppMessageInterrupt = {
119
+ "message_type": "conversation",
120
+ "event_type": "conversation.interrupt",
121
+ "conversation_id": string
122
+ }
123
+
124
+ type AppMessageOverwriteLlmContext = {
125
+ "message_type": "conversation",
126
+ "event_type": "conversation.overwrite_llm_context",
127
+ "conversation_id": string,
128
+ "properties": {
129
+ "context": string
130
+ }
131
+ }
132
+
133
+ type AppMessageAppendLlmContext = {
134
+ "message_type": "conversation",
135
+ "event_type": "conversation.append_llm_context",
136
+ "conversation_id": string,
137
+ "properties": {
138
+ "context": string
139
+ }
140
+ }
141
+
142
+ type Sensitivity = "superlow" | "verylow" | "low" | "medium" | "high" | "auto"
143
+
144
+ type AppMessageSensitivity = {
145
+ "message_type": "conversation",
146
+ "event_type": "conversation.sensitivity",
147
+ "conversation_id": string,
148
+ "properties": {
149
+ "participant_pause_sensitivity": Sensitivity,
150
+ "participant_interrupt_sensitivity": Sensitivity
151
+ }
152
+ }
153
+
154
+ type SendAppMessageProps =
155
+ AppMessageEcho |
156
+ AppMessageRespond |
157
+ AppMessageInterrupt |
158
+ AppMessageOverwriteLlmContext |
159
+ AppMessageAppendLlmContext |
160
+ AppMessageSensitivity
161
+
162
+ export function useSendAppMessage(): (message: SendAppMessageProps) => void {
163
+ const sendAppMessage = useAppMessage();
164
+
165
+ return useCallback((message: SendAppMessageProps) => {
166
+ sendAppMessage({ msg: message }, '*');
167
+ }, [sendAppMessage]);
168
+ }
@@ -0,0 +1,24 @@
1
+ import { useCallback } from 'react';
2
+ import { useDaily } from '@daily-co/daily-react';
3
+
4
+ export const useCVICall = (): {
5
+ joinCall: (props: { url: string }) => void;
6
+ leaveCall: () => void;
7
+ } => {
8
+ const daily = useDaily();
9
+
10
+ const joinCall = useCallback(
11
+ ({ url }: { url: string }) => {
12
+ daily?.join({
13
+ url: url,
14
+ });
15
+ },
16
+ [daily]
17
+ );
18
+
19
+ const leaveCall = useCallback(() => {
20
+ daily?.leave();
21
+ }, [daily]);
22
+
23
+ return { joinCall, leaveCall };
24
+ };
@@ -0,0 +1,20 @@
1
+ import { useCallback, useMemo } from 'react';
2
+ import { useDaily, useDevices, useLocalSessionId, useVideoTrack } from '@daily-co/daily-react';
3
+
4
+ export const useLocalCamera = () => {
5
+ const daily = useDaily();
6
+ const localSessionId = useLocalSessionId();
7
+ const { isOff: isCamMuted } = useVideoTrack(localSessionId);
8
+ const { camState } = useDevices();
9
+ const isCamReady = useMemo(() => camState === 'granted', [camState]);
10
+
11
+ const onToggleCamera = useCallback(() => {
12
+ daily?.setLocalVideo(isCamMuted);
13
+ }, [daily, isCamMuted]);
14
+
15
+ return {
16
+ onToggleCamera,
17
+ isCamReady,
18
+ isCamMuted,
19
+ };
20
+ };
@@ -0,0 +1,20 @@
1
+ import { useCallback, useMemo } from 'react';
2
+ import { useAudioTrack, useDaily, useDevices, useLocalSessionId } from '@daily-co/daily-react';
3
+
4
+ export const useLocalMicrophone = () => {
5
+ const daily = useDaily();
6
+ const localSessionId = useLocalSessionId();
7
+ const { isOff: isMicMuted } = useAudioTrack(localSessionId);
8
+ const { micState } = useDevices();
9
+ const isMicReady = useMemo(() => micState === 'granted', [micState]);
10
+
11
+ const onToggleMicrophone = useCallback(() => {
12
+ daily?.setLocalAudio(isMicMuted);
13
+ }, [daily, isMicMuted]);
14
+
15
+ return {
16
+ onToggleMicrophone,
17
+ isMicReady,
18
+ isMicMuted,
19
+ };
20
+ };
@@ -0,0 +1,32 @@
1
+ import { useCallback } from 'react';
2
+ import { useDaily, useLocalSessionId, useScreenVideoTrack } from '@daily-co/daily-react';
3
+
4
+ export const useLocalScreenshare = () => {
5
+ const daily = useDaily();
6
+ const localSessionId = useLocalSessionId();
7
+ const { isOff } = useScreenVideoTrack(localSessionId);
8
+ const isScreenSharing = !isOff;
9
+
10
+ const onToggleScreenshare = useCallback(() => {
11
+ if (isScreenSharing) {
12
+ daily?.stopScreenShare();
13
+ } else {
14
+ daily?.startScreenShare({
15
+ displayMediaOptions: {
16
+ audio: false,
17
+ selfBrowserSurface: 'exclude',
18
+ surfaceSwitching: 'include',
19
+ video: {
20
+ width: 1920,
21
+ height: 1080,
22
+ },
23
+ },
24
+ });
25
+ }
26
+ }, [daily, isScreenSharing]);
27
+
28
+ return {
29
+ onToggleScreenshare,
30
+ isScreenSharing,
31
+ };
32
+ };
@@ -0,0 +1,7 @@
1
+ import { useParticipantIds } from '@daily-co/daily-react';
2
+
3
+ export const useRemoteParticipantIDs = () => {
4
+ const remoteParticipantIds = useParticipantIds({ filter: 'remote' });
5
+
6
+ return remoteParticipantIds;
7
+ };
@@ -0,0 +1,9 @@
1
+ import { useParticipantIds } from '@daily-co/daily-react';
2
+
3
+ export const useReplicaIDs = () => {
4
+ const replicasIDs = useParticipantIds({
5
+ filter: (participant) => participant.user_id.includes('tavus-replica'),
6
+ });
7
+
8
+ return replicasIDs;
9
+ };
@@ -0,0 +1,24 @@
1
+ import { useCallback } from 'react';
2
+ import { useDaily } from '@daily-co/daily-react';
3
+ import type { DailyDeviceInfos } from '@daily-co/daily-js';
4
+
5
+ export const useRequestPermissions = (): (() => Promise<DailyDeviceInfos>) => {
6
+ const daily = useDaily();
7
+
8
+ const requestPermissions = useCallback(async () => {
9
+ return await daily!.startCamera({
10
+ startVideoOff: false,
11
+ startAudioOff: false,
12
+ audioSource: 'default',
13
+ inputSettings: {
14
+ audio: {
15
+ processor: {
16
+ type: 'noise-cancellation',
17
+ },
18
+ },
19
+ },
20
+ });
21
+ }, [daily]);
22
+
23
+ return requestPermissions;
24
+ };
@@ -0,0 +1,60 @@
1
+ import { useCallback, useEffect, useMemo, useState } from 'react';
2
+ import { useDaily, useDevices } from '@daily-co/daily-react';
3
+
4
+ export const useStartHaircheck = () => {
5
+ const daily = useDaily();
6
+ const { micState } = useDevices();
7
+
8
+ const [permissionState, setPermissionState] = useState<PermissionState | null>(null);
9
+
10
+ useEffect(() => {
11
+ navigator.permissions
12
+ .query({ name: 'microphone' as PermissionName })
13
+ .then((permissionStatus) => {
14
+ setPermissionState(permissionStatus.state);
15
+ permissionStatus.onchange = () => {
16
+ setPermissionState(permissionStatus.state);
17
+ };
18
+ });
19
+ }, []);
20
+
21
+ const requestPermissions = useCallback(() => {
22
+ if (!daily) return;
23
+ daily.startCamera({
24
+ startVideoOff: false,
25
+ startAudioOff: false,
26
+ audioSource: 'default',
27
+ inputSettings: {
28
+ audio: {
29
+ processor: {
30
+ type: 'noise-cancellation',
31
+ },
32
+ },
33
+ },
34
+ });
35
+ }, [daily]);
36
+
37
+ const isPermissionsPrompt = useMemo(() => {
38
+ return permissionState === 'prompt';
39
+ }, [permissionState]);
40
+
41
+ const isPermissionsLoading = useMemo(() => {
42
+ return (permissionState === null || permissionState === 'granted') && micState === 'idle';
43
+ }, [permissionState, micState]);
44
+
45
+ const isPermissionsGranted = useMemo(() => {
46
+ return permissionState === 'granted';
47
+ }, [permissionState]);
48
+
49
+ const isPermissionsDenied = useMemo(() => {
50
+ return permissionState === 'denied';
51
+ }, [permissionState]);
52
+
53
+ return {
54
+ isPermissionsPrompt,
55
+ isPermissionsLoading,
56
+ isPermissionsGranted,
57
+ isPermissionsDenied,
58
+ requestPermissions,
59
+ };
60
+ };