openclaw-liveavatar 1.0.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.
Files changed (122) hide show
  1. package/.next/BUILD_ID +1 -0
  2. package/.next/app-build-manifest.json +42 -0
  3. package/.next/app-path-routes-manifest.json +6 -0
  4. package/.next/build-manifest.json +33 -0
  5. package/.next/cache/.previewinfo +1 -0
  6. package/.next/cache/.rscinfo +1 -0
  7. package/.next/cache/.tsbuildinfo +1 -0
  8. package/.next/cache/chrome-devtools-workspace-uuid +1 -0
  9. package/.next/cache/next-devtools-config.json +1 -0
  10. package/.next/cache/webpack/client-production/0.pack +0 -0
  11. package/.next/cache/webpack/client-production/1.pack +0 -0
  12. package/.next/cache/webpack/client-production/2.pack +0 -0
  13. package/.next/cache/webpack/client-production/3.pack +0 -0
  14. package/.next/cache/webpack/client-production/4.pack +0 -0
  15. package/.next/cache/webpack/client-production/index.pack +0 -0
  16. package/.next/cache/webpack/client-production/index.pack.old +0 -0
  17. package/.next/cache/webpack/edge-server-production/0.pack +0 -0
  18. package/.next/cache/webpack/edge-server-production/index.pack +0 -0
  19. package/.next/cache/webpack/server-production/0.pack +0 -0
  20. package/.next/cache/webpack/server-production/index.pack +0 -0
  21. package/.next/diagnostics/build-diagnostics.json +6 -0
  22. package/.next/diagnostics/framework.json +1 -0
  23. package/.next/export-marker.json +6 -0
  24. package/.next/images-manifest.json +58 -0
  25. package/.next/next-minimal-server.js.nft.json +1 -0
  26. package/.next/next-server.js.nft.json +1 -0
  27. package/.next/package.json +1 -0
  28. package/.next/prerender-manifest.json +61 -0
  29. package/.next/react-loadable-manifest.json +1 -0
  30. package/.next/required-server-files.json +320 -0
  31. package/.next/routes-manifest.json +53 -0
  32. package/.next/server/app/_not-found/page.js +5 -0
  33. package/.next/server/app/_not-found/page.js.nft.json +1 -0
  34. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
  35. package/.next/server/app/_not-found.html +4 -0
  36. package/.next/server/app/_not-found.meta +8 -0
  37. package/.next/server/app/_not-found.rsc +15 -0
  38. package/.next/server/app/api/get-avatars/route.js +1 -0
  39. package/.next/server/app/api/get-avatars/route.js.nft.json +1 -0
  40. package/.next/server/app/api/get-avatars/route_client-reference-manifest.js +1 -0
  41. package/.next/server/app/api/start-session/route.js +1 -0
  42. package/.next/server/app/api/start-session/route.js.nft.json +1 -0
  43. package/.next/server/app/api/start-session/route_client-reference-manifest.js +1 -0
  44. package/.next/server/app/index.html +4 -0
  45. package/.next/server/app/index.meta +7 -0
  46. package/.next/server/app/index.rsc +16 -0
  47. package/.next/server/app/page.js +9 -0
  48. package/.next/server/app/page.js.nft.json +1 -0
  49. package/.next/server/app/page_client-reference-manifest.js +1 -0
  50. package/.next/server/app-paths-manifest.json +6 -0
  51. package/.next/server/chunks/361.js +9 -0
  52. package/.next/server/chunks/611.js +6 -0
  53. package/.next/server/chunks/873.js +22 -0
  54. package/.next/server/functions-config-manifest.json +4 -0
  55. package/.next/server/interception-route-rewrite-manifest.js +1 -0
  56. package/.next/server/middleware-build-manifest.js +1 -0
  57. package/.next/server/middleware-manifest.json +6 -0
  58. package/.next/server/middleware-react-loadable-manifest.js +1 -0
  59. package/.next/server/next-font-manifest.js +1 -0
  60. package/.next/server/next-font-manifest.json +1 -0
  61. package/.next/server/pages/404.html +4 -0
  62. package/.next/server/pages/500.html +1 -0
  63. package/.next/server/pages/_app.js +1 -0
  64. package/.next/server/pages/_app.js.nft.json +1 -0
  65. package/.next/server/pages/_document.js +1 -0
  66. package/.next/server/pages/_document.js.nft.json +1 -0
  67. package/.next/server/pages/_error.js +19 -0
  68. package/.next/server/pages/_error.js.nft.json +1 -0
  69. package/.next/server/pages-manifest.json +6 -0
  70. package/.next/server/server-reference-manifest.js +1 -0
  71. package/.next/server/server-reference-manifest.json +1 -0
  72. package/.next/server/webpack-runtime.js +1 -0
  73. package/.next/static/chunks/144d3bae-37bcc55d23f188ee.js +1 -0
  74. package/.next/static/chunks/255-35bf8c00c5dde345.js +1 -0
  75. package/.next/static/chunks/336-a66237a0a1db954a.js +1 -0
  76. package/.next/static/chunks/4bd1b696-c023c6e3521b1417.js +1 -0
  77. package/.next/static/chunks/app/_not-found/page-dfc6e5d8e6c6203c.js +1 -0
  78. package/.next/static/chunks/app/api/get-avatars/route-8017e1cff542d5d0.js +1 -0
  79. package/.next/static/chunks/app/api/start-session/route-8017e1cff542d5d0.js +1 -0
  80. package/.next/static/chunks/app/layout-ff675313cc8f8fcf.js +1 -0
  81. package/.next/static/chunks/app/page-9e4b703722bef650.js +1 -0
  82. package/.next/static/chunks/framework-de98b93a850cfc71.js +1 -0
  83. package/.next/static/chunks/main-1a0dcce460eb61ce.js +1 -0
  84. package/.next/static/chunks/main-app-e7f1007edc7ad7e1.js +1 -0
  85. package/.next/static/chunks/pages/_app-7d307437aca18ad4.js +1 -0
  86. package/.next/static/chunks/pages/_error-cb2a52f75f2162e2.js +1 -0
  87. package/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  88. package/.next/static/chunks/webpack-4a462cecab786e93.js +1 -0
  89. package/.next/static/css/bfd73afa11897439.css +3 -0
  90. package/.next/static/v_GdCj8lVweDVhmIhhEcM/_buildManifest.js +1 -0
  91. package/.next/static/v_GdCj8lVweDVhmIhhEcM/_ssgManifest.js +1 -0
  92. package/.next/trace +2 -0
  93. package/.next/types/app/api/get-avatars/route.ts +347 -0
  94. package/.next/types/app/api/start-session/route.ts +347 -0
  95. package/.next/types/app/layout.ts +84 -0
  96. package/.next/types/app/page.ts +84 -0
  97. package/.next/types/cache-life.d.ts +141 -0
  98. package/.next/types/package.json +1 -0
  99. package/.next/types/routes.d.ts +74 -0
  100. package/.next/types/validator.ts +88 -0
  101. package/README.md +241 -0
  102. package/app/api/config.ts +18 -0
  103. package/app/api/get-avatars/route.ts +117 -0
  104. package/app/api/start-session/route.ts +95 -0
  105. package/app/globals.css +3 -0
  106. package/app/layout.tsx +37 -0
  107. package/app/page.tsx +9 -0
  108. package/bin/cli.js +100 -0
  109. package/package.json +66 -0
  110. package/src/components/LiveAvatarSession.tsx +825 -0
  111. package/src/components/OpenClawDemo.tsx +399 -0
  112. package/src/gateway/client.ts +522 -0
  113. package/src/gateway/types.ts +83 -0
  114. package/src/liveavatar/context.tsx +750 -0
  115. package/src/liveavatar/index.ts +6 -0
  116. package/src/liveavatar/types.ts +10 -0
  117. package/src/liveavatar/useAvatarActions.ts +41 -0
  118. package/src/liveavatar/useChatHistory.ts +7 -0
  119. package/src/liveavatar/useSession.ts +37 -0
  120. package/src/liveavatar/useTextChat.ts +32 -0
  121. package/src/liveavatar/useVoiceChat.ts +70 -0
  122. package/tsconfig.json +40 -0
@@ -0,0 +1,6 @@
1
+ export { LiveAvatarContextProvider, useLiveAvatarContext } from "./context";
2
+ export * from "./types";
3
+ export { useChatHistory } from "./useChatHistory";
4
+ export { useSession } from "./useSession";
5
+ export { useVoiceChat } from "./useVoiceChat";
6
+ export { useTextChat } from "./useTextChat";
@@ -0,0 +1,10 @@
1
+ export enum MessageSender {
2
+ USER = "user",
3
+ AVATAR = "avatar",
4
+ }
5
+
6
+ export interface LiveAvatarSessionMessage {
7
+ sender: MessageSender;
8
+ message: string;
9
+ timestamp: number;
10
+ }
@@ -0,0 +1,41 @@
1
+ import { useCallback } from "react";
2
+ import { useLiveAvatarContext } from "./context";
3
+
4
+ export const useAvatarActions = (mode: "FULL" | "CUSTOM") => {
5
+ const { sessionRef } = useLiveAvatarContext();
6
+
7
+ const interrupt = useCallback(() => {
8
+ return sessionRef.current.interrupt();
9
+ }, [sessionRef]);
10
+
11
+ const repeat = useCallback(
12
+ async (message: string) => {
13
+ if (mode === "FULL") {
14
+ return sessionRef.current.repeat(message);
15
+ } else if (mode === "CUSTOM") {
16
+ const res = await fetch("/api/elevenlabs-text-to-speech", {
17
+ method: "POST",
18
+ body: JSON.stringify({ text: message }),
19
+ });
20
+ const { audio } = await res.json();
21
+ return sessionRef.current.repeatAudio(audio);
22
+ }
23
+ },
24
+ [sessionRef, mode],
25
+ );
26
+
27
+ const startListening = useCallback(() => {
28
+ return sessionRef.current.startListening();
29
+ }, [sessionRef]);
30
+
31
+ const stopListening = useCallback(() => {
32
+ return sessionRef.current.stopListening();
33
+ }, [sessionRef]);
34
+
35
+ return {
36
+ interrupt,
37
+ repeat,
38
+ startListening,
39
+ stopListening,
40
+ };
41
+ };
@@ -0,0 +1,7 @@
1
+ import { useLiveAvatarContext } from "./context";
2
+
3
+ export const useChatHistory = () => {
4
+ const { messages } = useLiveAvatarContext();
5
+
6
+ return messages;
7
+ };
@@ -0,0 +1,37 @@
1
+ import { useCallback } from "react";
2
+ import { useLiveAvatarContext } from "./context";
3
+
4
+ export const useSession = () => {
5
+ const { sessionRef, sessionState, isStreamReady, connectionQuality } =
6
+ useLiveAvatarContext();
7
+
8
+ const startSession = useCallback(async () => {
9
+ return await sessionRef.current.start();
10
+ }, [sessionRef]);
11
+
12
+ const stopSession = useCallback(async () => {
13
+ return await sessionRef.current.stop();
14
+ }, [sessionRef]);
15
+
16
+ const keepAlive = useCallback(async () => {
17
+ return await sessionRef.current.keepAlive();
18
+ }, [sessionRef]);
19
+
20
+ const attachElement = useCallback(
21
+ (element: HTMLMediaElement) => {
22
+ return sessionRef.current.attach(element);
23
+ },
24
+ [sessionRef],
25
+ );
26
+
27
+ return {
28
+ sessionState,
29
+ isStreamReady,
30
+ connectionQuality,
31
+ startSession,
32
+ stopSession,
33
+ keepAlive,
34
+ attachElement,
35
+ sessionRef,
36
+ };
37
+ };
@@ -0,0 +1,32 @@
1
+ import { useCallback } from "react";
2
+ import { useLiveAvatarContext } from "./context";
3
+
4
+ export const useTextChat = (mode: "FULL" | "CUSTOM") => {
5
+ const { sessionRef } = useLiveAvatarContext();
6
+
7
+ const sendMessage = useCallback(
8
+ async (message: string) => {
9
+ if (mode === "FULL") {
10
+ return sessionRef.current.message(message);
11
+ } else if (mode === "CUSTOM") {
12
+ const response = await fetch("/api/openai-chat-complete", {
13
+ method: "POST",
14
+ body: JSON.stringify({ message }),
15
+ });
16
+ const { response: chatResponseText } = await response.json();
17
+ const res = await fetch("/api/elevenlabs-text-to-speech", {
18
+ method: "POST",
19
+ body: JSON.stringify({ text: chatResponseText }),
20
+ });
21
+ const { audio } = await res.json();
22
+ // Have the avatar repeat the audio
23
+ return sessionRef.current.repeatAudio(audio);
24
+ }
25
+ },
26
+ [sessionRef, mode],
27
+ );
28
+
29
+ return {
30
+ sendMessage,
31
+ };
32
+ };
@@ -0,0 +1,70 @@
1
+ import { useCallback, useMemo } from "react";
2
+ import { useLiveAvatarContext } from "./context";
3
+ import { VoiceChatState } from "@heygen/liveavatar-web-sdk";
4
+
5
+ export const useVoiceChat = () => {
6
+ const {
7
+ sessionRef,
8
+ isMuted,
9
+ voiceChatState,
10
+ isUserTalking,
11
+ isAvatarTalking,
12
+ } = useLiveAvatarContext();
13
+
14
+ const mute = useCallback(async () => {
15
+ return await sessionRef.current.voiceChat.mute();
16
+ }, [sessionRef]);
17
+
18
+ const unmute = useCallback(async () => {
19
+ return await sessionRef.current.voiceChat.unmute();
20
+ }, [sessionRef]);
21
+
22
+ const start = useCallback(async (deviceId?: string) => {
23
+ return await sessionRef.current.voiceChat.start(
24
+ deviceId ? { deviceId, defaultMuted: false } : { defaultMuted: false }
25
+ );
26
+ }, [sessionRef]);
27
+
28
+ const stop = useCallback(() => {
29
+ return sessionRef.current.voiceChat.stop();
30
+ }, [sessionRef]);
31
+
32
+ // Restart voice chat with a new device
33
+ const restartWithDevice = useCallback(async (deviceId: string) => {
34
+ console.log("Restarting voice chat with device:", deviceId);
35
+ try {
36
+ // Stop current voice chat
37
+ sessionRef.current.voiceChat.stop();
38
+ // Wait a bit for cleanup
39
+ await new Promise(resolve => setTimeout(resolve, 100));
40
+ // Start with new device
41
+ await sessionRef.current.voiceChat.start({ deviceId, defaultMuted: false });
42
+ console.log("Voice chat restarted successfully");
43
+ return true;
44
+ } catch (err) {
45
+ console.error("Failed to restart voice chat:", err);
46
+ return false;
47
+ }
48
+ }, [sessionRef]);
49
+
50
+ const isLoading = useMemo(() => {
51
+ return voiceChatState === VoiceChatState.STARTING;
52
+ }, [voiceChatState]);
53
+
54
+ const isActive = useMemo(() => {
55
+ return voiceChatState === VoiceChatState.ACTIVE;
56
+ }, [voiceChatState]);
57
+
58
+ return {
59
+ mute,
60
+ unmute,
61
+ start,
62
+ stop,
63
+ restartWithDevice,
64
+ isLoading,
65
+ isActive,
66
+ isMuted,
67
+ isUserTalking,
68
+ isAvatarTalking,
69
+ };
70
+ };
package/tsconfig.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "compilerOptions": {
3
+ "lib": [
4
+ "dom",
5
+ "dom.iterable",
6
+ "esnext"
7
+ ],
8
+ "allowJs": true,
9
+ "skipLibCheck": true,
10
+ "strict": true,
11
+ "noEmit": true,
12
+ "esModuleInterop": true,
13
+ "module": "esnext",
14
+ "moduleResolution": "bundler",
15
+ "resolveJsonModule": true,
16
+ "isolatedModules": true,
17
+ "jsx": "preserve",
18
+ "incremental": true,
19
+ "plugins": [
20
+ {
21
+ "name": "next"
22
+ }
23
+ ],
24
+ "paths": {
25
+ "@/*": [
26
+ "./*"
27
+ ]
28
+ },
29
+ "target": "ES2017"
30
+ },
31
+ "include": [
32
+ "next-env.d.ts",
33
+ "**/*.ts",
34
+ "**/*.tsx",
35
+ ".next/types/**/*.ts"
36
+ ],
37
+ "exclude": [
38
+ "node_modules"
39
+ ]
40
+ }