Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zg/update evi ts example #73

Merged
merged 6 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions evi-typescript-example/.env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
VITE_HUME_API_KEY="YOUR_API_KEY"
VITE_HUME_SECRET_KEY="YOUR_SECRET_KEY"
VITE_HUME_API_KEY="<YOUR_API_KEY>"
VITE_HUME_SECRET_KEY="<YOUR_SECRET_KEY>"
VITE_HUME_CONFIG_ID="<YOUR_CONFIG_ID>"
7 changes: 4 additions & 3 deletions evi-typescript-example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,14 @@ After obtaining your API keys, you need to set them as environment variables. A
Note the `VITE` prefix to the environment variables. This prefix is required for vite to expose the environment variable to the client. For more information, see the [vite documentation](https://vitejs.dev/guide/env-and-mode) on environment variables and modes.

```sh
export VITE_HUME_API_KEY=<YOUR_API_KEY>
export VITE_HUME_SECRET_KEY=<YOUR_SECRET_KEY>
VITE_HUME_API_KEY="<YOUR_API_KEY>"
VITE_HUME_SECRET_KEY="<YOUR_SECRET_KEY>"
VITE_HUME_CONFIG_ID="<YOUR_CONFIG_ID>" // optional
```

You can make these environment variables persistent by adding them to a file named `.env` in the root folder of the repo.

> There is an example file called [`.env.example`](https://github.com/HumeAI/hume-api-examples/blob/main/evi-typescript-example/.env.example) with placeholder values, which you can simply rename to `.env`.
> There is an example file called [`.env.example`](https://github.com/HumeAI/hume-api-examples/blob/main/evi-typescript-example/.env.example). Create a `.env` file, copy/paste the contents of the `.env.example` file, and fill in your environment variables. The config ID is optional, however if a config is not specified EVI will be configured with the [default configuration options](https://dev.hume.ai/docs/empathic-voice-interface-evi/configuration#default-configuration).

## Serve project

Expand Down
2 changes: 1 addition & 1 deletion evi-typescript-example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"preview": "vite preview"
},
"dependencies": {
"hume": "^0.7.2"
"hume": "^0.8.3"
},
"devDependencies": {
"typescript": "^5.2.2",
Expand Down
13 changes: 9 additions & 4 deletions evi-typescript-example/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 30 additions & 19 deletions evi-typescript-example/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,13 @@ import './styles.css';
/**
* the WebSocket instance
*/
let socket: Hume.empathicVoice.StreamSocket | null = null;
let socket: Hume.empathicVoice.chat.ChatSocket | null = null;

/**
* flag which denotes the intended state of the WebSocket
*/
let connected = false;

/**
* The ChatGroup ID used to resume the chat if disconnected unexpectedly
*/
let chatGroupId: string | undefined;

/**
* the recorder responsible for recording the audio stream to be prepared as the audio input
*/
Expand All @@ -58,6 +53,16 @@ import './styles.css';
*/
let isPlaying = false;

/**
* flag which denotes whether to utilize chat resumability (preserve context from one chat to the next)
*/
let resumeChats = true;

/**
* The ChatGroup ID used to resume the chat if disconnected unexpectedly
*/
let chatGroupId: string | undefined;

/**
* audio playback queue
*/
Expand Down Expand Up @@ -85,14 +90,15 @@ import './styles.css';

// instantiates WebSocket and establishes an authenticated connection
socket = await client.empathicVoice.chat.connect({
// configId: '<YOUR_CONFIG_ID>',
configId: import.meta.env.VITE_HUME_CONFIG_ID || null,
resumedChatGroupId: chatGroupId,
onOpen: handleWebSocketOpenEvent,
onMessage: handleWebSocketMessageEvent,
onError: handleWebSocketErrorEvent,
onClose: handleWebSocketCloseEvent,
});

socket.on('open', handleWebSocketOpenEvent);
socket.on('message', handleWebSocketMessageEvent);
socket.on('error', handleWebSocketErrorEvent);
socket.on('close', handleWebSocketCloseEvent);

// update ui state
toggleBtnStates();
}
Expand All @@ -115,8 +121,10 @@ import './styles.css';
// set connected state to false to prevent automatic reconnect
connected = false;

// reset chatGroupId so a new conversation is started when reconnecting, comment out to utilize chat resumability
chatGroupId = undefined;
// IF resumeChats flag is false, reset chatGroupId so a new conversation is started when reconnecting
if (!resumeChats) {
chatGroupId = undefined;
}

// closed the Web Socket connection
socket?.close();
Expand Down Expand Up @@ -228,7 +236,9 @@ import './styles.css';
* - `audio_output`: https://dev.hume.ai/reference/empathic-voice-interface-evi/chat/chat#receive.Audio%20Output.type
* - `user_interruption`: https://dev.hume.ai/reference/empathic-voice-interface-evi/chat/chat#receive.User%20Interruption.type
*/
function handleWebSocketMessageEvent(message: Hume.empathicVoice.SubscribeEvent): void {
async function handleWebSocketMessageEvent(
message: Hume.empathicVoice.SubscribeEvent
): Promise<void> {
/* place logic here which you would like to invoke when receiving a message through the socket */

// handle messages received through the WebSocket (messages are distinguished by their "type" field.)
Expand Down Expand Up @@ -256,7 +266,7 @@ import './styles.css';
audioQueue.push(blob);

// play the next audio output
if (audioQueue.length === 1) playAudio();
if (audioQueue.length >= 1) playAudio();
break;

// stop audio playback, clear audio playback queue, and update audio playback state on interrupt
Expand All @@ -269,7 +279,7 @@ import './styles.css';
/**
* callback function to handle a WebSocket error event
*/
function handleWebSocketErrorEvent(error: Hume.empathicVoice.WebSocketError): void {
function handleWebSocketErrorEvent(error: Error): void {
/* place logic here which you would like invoked when receiving an error through the socket */
console.error(error);
}
Expand All @@ -281,9 +291,7 @@ import './styles.css';
/* place logic here which you would like invoked when the socket closes */

// reconnect to the socket if disconnect was unintentional
if (connected) {
await connect();
}
if (connected) await connect();

console.log('Web socket connection closed');
}
Expand All @@ -310,6 +318,9 @@ import './styles.css';

// append chat card to the UI
chat?.appendChild(chatCard.render());

// scroll to the bottom to view most recently added message
if (chat) chat.scrollTop = chat.scrollHeight;
}

/**
Expand Down
6 changes: 4 additions & 2 deletions evi-typescript-example/src/styles.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
body {
display: flex;
flex-direction: column;
height: 100vh;
align-items: center;
}

Expand Down Expand Up @@ -37,11 +36,11 @@ button:disabled {
font-family: Arial, sans-serif;
display: flex;
flex-direction: column;
height: 100vh;
width: 72%;
min-width: 900px;
padding: 24px;
margin: 0px;
overflow: hidden;
}

#btn-container {
Expand All @@ -52,6 +51,9 @@ button:disabled {
#chat {
display: flex;
flex-direction: column;
height: 560px;
overflow-y: auto;
padding: 0 16px;
}

.chat-card {
Expand Down