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.
- package/.next/BUILD_ID +1 -0
- package/.next/app-build-manifest.json +42 -0
- package/.next/app-path-routes-manifest.json +6 -0
- package/.next/build-manifest.json +33 -0
- package/.next/cache/.previewinfo +1 -0
- package/.next/cache/.rscinfo +1 -0
- package/.next/cache/.tsbuildinfo +1 -0
- package/.next/cache/chrome-devtools-workspace-uuid +1 -0
- package/.next/cache/next-devtools-config.json +1 -0
- package/.next/cache/webpack/client-production/0.pack +0 -0
- package/.next/cache/webpack/client-production/1.pack +0 -0
- package/.next/cache/webpack/client-production/2.pack +0 -0
- package/.next/cache/webpack/client-production/3.pack +0 -0
- package/.next/cache/webpack/client-production/4.pack +0 -0
- package/.next/cache/webpack/client-production/index.pack +0 -0
- package/.next/cache/webpack/client-production/index.pack.old +0 -0
- package/.next/cache/webpack/edge-server-production/0.pack +0 -0
- package/.next/cache/webpack/edge-server-production/index.pack +0 -0
- package/.next/cache/webpack/server-production/0.pack +0 -0
- package/.next/cache/webpack/server-production/index.pack +0 -0
- package/.next/diagnostics/build-diagnostics.json +6 -0
- package/.next/diagnostics/framework.json +1 -0
- package/.next/export-marker.json +6 -0
- package/.next/images-manifest.json +58 -0
- package/.next/next-minimal-server.js.nft.json +1 -0
- package/.next/next-server.js.nft.json +1 -0
- package/.next/package.json +1 -0
- package/.next/prerender-manifest.json +61 -0
- package/.next/react-loadable-manifest.json +1 -0
- package/.next/required-server-files.json +320 -0
- package/.next/routes-manifest.json +53 -0
- package/.next/server/app/_not-found/page.js +5 -0
- package/.next/server/app/_not-found/page.js.nft.json +1 -0
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
- package/.next/server/app/_not-found.html +4 -0
- package/.next/server/app/_not-found.meta +8 -0
- package/.next/server/app/_not-found.rsc +15 -0
- package/.next/server/app/api/get-avatars/route.js +1 -0
- package/.next/server/app/api/get-avatars/route.js.nft.json +1 -0
- package/.next/server/app/api/get-avatars/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/start-session/route.js +1 -0
- package/.next/server/app/api/start-session/route.js.nft.json +1 -0
- package/.next/server/app/api/start-session/route_client-reference-manifest.js +1 -0
- package/.next/server/app/index.html +4 -0
- package/.next/server/app/index.meta +7 -0
- package/.next/server/app/index.rsc +16 -0
- package/.next/server/app/page.js +9 -0
- package/.next/server/app/page.js.nft.json +1 -0
- package/.next/server/app/page_client-reference-manifest.js +1 -0
- package/.next/server/app-paths-manifest.json +6 -0
- package/.next/server/chunks/361.js +9 -0
- package/.next/server/chunks/611.js +6 -0
- package/.next/server/chunks/873.js +22 -0
- package/.next/server/functions-config-manifest.json +4 -0
- package/.next/server/interception-route-rewrite-manifest.js +1 -0
- package/.next/server/middleware-build-manifest.js +1 -0
- package/.next/server/middleware-manifest.json +6 -0
- package/.next/server/middleware-react-loadable-manifest.js +1 -0
- package/.next/server/next-font-manifest.js +1 -0
- package/.next/server/next-font-manifest.json +1 -0
- package/.next/server/pages/404.html +4 -0
- package/.next/server/pages/500.html +1 -0
- package/.next/server/pages/_app.js +1 -0
- package/.next/server/pages/_app.js.nft.json +1 -0
- package/.next/server/pages/_document.js +1 -0
- package/.next/server/pages/_document.js.nft.json +1 -0
- package/.next/server/pages/_error.js +19 -0
- package/.next/server/pages/_error.js.nft.json +1 -0
- package/.next/server/pages-manifest.json +6 -0
- package/.next/server/server-reference-manifest.js +1 -0
- package/.next/server/server-reference-manifest.json +1 -0
- package/.next/server/webpack-runtime.js +1 -0
- package/.next/static/chunks/144d3bae-37bcc55d23f188ee.js +1 -0
- package/.next/static/chunks/255-35bf8c00c5dde345.js +1 -0
- package/.next/static/chunks/336-a66237a0a1db954a.js +1 -0
- package/.next/static/chunks/4bd1b696-c023c6e3521b1417.js +1 -0
- package/.next/static/chunks/app/_not-found/page-dfc6e5d8e6c6203c.js +1 -0
- package/.next/static/chunks/app/api/get-avatars/route-8017e1cff542d5d0.js +1 -0
- package/.next/static/chunks/app/api/start-session/route-8017e1cff542d5d0.js +1 -0
- package/.next/static/chunks/app/layout-ff675313cc8f8fcf.js +1 -0
- package/.next/static/chunks/app/page-9e4b703722bef650.js +1 -0
- package/.next/static/chunks/framework-de98b93a850cfc71.js +1 -0
- package/.next/static/chunks/main-1a0dcce460eb61ce.js +1 -0
- package/.next/static/chunks/main-app-e7f1007edc7ad7e1.js +1 -0
- package/.next/static/chunks/pages/_app-7d307437aca18ad4.js +1 -0
- package/.next/static/chunks/pages/_error-cb2a52f75f2162e2.js +1 -0
- package/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- package/.next/static/chunks/webpack-4a462cecab786e93.js +1 -0
- package/.next/static/css/bfd73afa11897439.css +3 -0
- package/.next/static/v_GdCj8lVweDVhmIhhEcM/_buildManifest.js +1 -0
- package/.next/static/v_GdCj8lVweDVhmIhhEcM/_ssgManifest.js +1 -0
- package/.next/trace +2 -0
- package/.next/types/app/api/get-avatars/route.ts +347 -0
- package/.next/types/app/api/start-session/route.ts +347 -0
- package/.next/types/app/layout.ts +84 -0
- package/.next/types/app/page.ts +84 -0
- package/.next/types/cache-life.d.ts +141 -0
- package/.next/types/package.json +1 -0
- package/.next/types/routes.d.ts +74 -0
- package/.next/types/validator.ts +88 -0
- package/README.md +241 -0
- package/app/api/config.ts +18 -0
- package/app/api/get-avatars/route.ts +117 -0
- package/app/api/start-session/route.ts +95 -0
- package/app/globals.css +3 -0
- package/app/layout.tsx +37 -0
- package/app/page.tsx +9 -0
- package/bin/cli.js +100 -0
- package/package.json +66 -0
- package/src/components/LiveAvatarSession.tsx +825 -0
- package/src/components/OpenClawDemo.tsx +399 -0
- package/src/gateway/client.ts +522 -0
- package/src/gateway/types.ts +83 -0
- package/src/liveavatar/context.tsx +750 -0
- package/src/liveavatar/index.ts +6 -0
- package/src/liveavatar/types.ts +10 -0
- package/src/liveavatar/useAvatarActions.ts +41 -0
- package/src/liveavatar/useChatHistory.ts +7 -0
- package/src/liveavatar/useSession.ts +37 -0
- package/src/liveavatar/useTextChat.ts +32 -0
- package/src/liveavatar/useVoiceChat.ts +70 -0
- 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,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,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
|
+
}
|