Spaces:
Running
Running
Upload 56 files (#3)
Browse files- Upload 56 files (3fe958fb5dbaa697900298c57bb618376172944b)
Co-authored-by: Théo Michel <[email protected]>
- Dockerfile +1 -1
- README.md +0 -3
- api.js +3 -0
- package-lock.json +13 -0
- package.json +1 -0
- src/eleven_labs.js +2 -1
- src/llm.js +3 -1
- src/shyguy.js +2 -2
- src/speech_to_text.js +54 -55
- vite.config.js +7 -1
Dockerfile
CHANGED
|
@@ -26,4 +26,4 @@ EXPOSE 7860
|
|
| 26 |
ENV BROWSER=none
|
| 27 |
|
| 28 |
# Start the Vite development server with specific configurations
|
| 29 |
-
CMD ["npm", "run", "dev", "--", "--host", "--port", "7860", "--strictPort"]
|
|
|
|
| 26 |
ENV BROWSER=none
|
| 27 |
|
| 28 |
# Start the Vite development server with specific configurations
|
| 29 |
+
CMD ["npm", "run", "dev", "--", "--host", "--port", "7860", "--strictPort"]
|
README.md
CHANGED
|
@@ -6,6 +6,3 @@ colorTo: pink
|
|
| 6 |
sdk: docker
|
| 7 |
pinned: false
|
| 8 |
---
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
Clone the repository and run npm run dev
|
|
|
|
| 6 |
sdk: docker
|
| 7 |
pinned: false
|
| 8 |
---
|
|
|
|
|
|
|
|
|
api.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
export const HUGGINGFACE_API_KEY = process.env.HUGGINGFACE_API_KEY;
|
| 2 |
+
export const ELEVENLABS_API_KEY = process.env.ELEVENLABS_API_KEY;
|
| 3 |
+
export const MISTRAL_API_KEY = process.env.MISTRAL_API_KEY;
|
package-lock.json
CHANGED
|
@@ -8,6 +8,7 @@
|
|
| 8 |
"name": "shyguys-wingman-js",
|
| 9 |
"version": "1.0.0",
|
| 10 |
"dependencies": {
|
|
|
|
| 11 |
"elevenlabs": "^1.50.4"
|
| 12 |
},
|
| 13 |
"devDependencies": {
|
|
@@ -844,6 +845,18 @@
|
|
| 844 |
"node": ">=0.4.0"
|
| 845 |
}
|
| 846 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 847 |
"node_modules/dunder-proto": {
|
| 848 |
"version": "1.0.1",
|
| 849 |
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
|
|
|
| 8 |
"name": "shyguys-wingman-js",
|
| 9 |
"version": "1.0.0",
|
| 10 |
"dependencies": {
|
| 11 |
+
"dotenv": "^16.4.7",
|
| 12 |
"elevenlabs": "^1.50.4"
|
| 13 |
},
|
| 14 |
"devDependencies": {
|
|
|
|
| 845 |
"node": ">=0.4.0"
|
| 846 |
}
|
| 847 |
},
|
| 848 |
+
"node_modules/dotenv": {
|
| 849 |
+
"version": "16.4.7",
|
| 850 |
+
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz",
|
| 851 |
+
"integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==",
|
| 852 |
+
"license": "BSD-2-Clause",
|
| 853 |
+
"engines": {
|
| 854 |
+
"node": ">=12"
|
| 855 |
+
},
|
| 856 |
+
"funding": {
|
| 857 |
+
"url": "https://dotenvx.com"
|
| 858 |
+
}
|
| 859 |
+
},
|
| 860 |
"node_modules/dunder-proto": {
|
| 861 |
"version": "1.0.1",
|
| 862 |
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
package.json
CHANGED
|
@@ -9,6 +9,7 @@
|
|
| 9 |
"preview": "vite preview"
|
| 10 |
},
|
| 11 |
"dependencies": {
|
|
|
|
| 12 |
"elevenlabs": "^1.50.4"
|
| 13 |
},
|
| 14 |
"devDependencies": {
|
|
|
|
| 9 |
"preview": "vite preview"
|
| 10 |
},
|
| 11 |
"dependencies": {
|
| 12 |
+
"dotenv": "^16.4.7",
|
| 13 |
"elevenlabs": "^1.50.4"
|
| 14 |
},
|
| 15 |
"devDependencies": {
|
src/eleven_labs.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
| 1 |
import { SHYGUY_LABEL, SISTER_LABEL, GIRL_LABEL, BAR_LABEL, DJ_LABEL, WINGMAN_LABEL } from "./constants.js";
|
|
|
|
| 2 |
|
| 3 |
export class ElevenLabsClient {
|
| 4 |
constructor() {
|
| 5 |
-
this.apiKey =
|
| 6 |
this.baseUrl = "https://api.elevenlabs.io/v1";
|
| 7 |
}
|
| 8 |
|
|
|
|
| 1 |
import { SHYGUY_LABEL, SISTER_LABEL, GIRL_LABEL, BAR_LABEL, DJ_LABEL, WINGMAN_LABEL } from "./constants.js";
|
| 2 |
+
import { ELEVENLABS_API_KEY } from "../api.js";
|
| 3 |
|
| 4 |
export class ElevenLabsClient {
|
| 5 |
constructor() {
|
| 6 |
+
this.apiKey = ELEVENLABS_API_KEY;
|
| 7 |
this.baseUrl = "https://api.elevenlabs.io/v1";
|
| 8 |
}
|
| 9 |
|
src/llm.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
|
|
|
|
|
| 1 |
export class LLM {
|
| 2 |
constructor() {
|
| 3 |
-
this.apiKey =
|
| 4 |
}
|
| 5 |
|
| 6 |
async getChatCompletion(systemPrompt, userInput) {
|
|
|
|
| 1 |
+
import { MISTRAL_API_KEY } from "../api.js";
|
| 2 |
+
|
| 3 |
export class LLM {
|
| 4 |
constructor() {
|
| 5 |
+
this.apiKey = MISTRAL_API_KEY;
|
| 6 |
}
|
| 7 |
|
| 8 |
async getChatCompletion(systemPrompt, userInput) {
|
src/shyguy.js
CHANGED
|
@@ -4,7 +4,7 @@ export class Shyguy {
|
|
| 4 |
constructor() {
|
| 5 |
this.num_beers = 0;
|
| 6 |
this.courage = 1;
|
| 7 |
-
this.personality = "This is the Shyguy. He is shy and introverted. He is also a bit of a nerd. He fell in love with Jessica. With Jessica, he talks about algorithms.";
|
| 8 |
this.lessons_learned = "";
|
| 9 |
this.conversation_history = "";
|
| 10 |
this.song_playing = "Let it be";
|
|
@@ -19,7 +19,7 @@ export class Shyguy {
|
|
| 19 |
return `This is Shyguy. He had two beers, so he feels relaxed and he can talk with anyone. Follow the following lessons: ${this.lessons_learned}`;
|
| 20 |
}
|
| 21 |
else {
|
| 22 |
-
return `${this.personality}.
|
| 23 |
}
|
| 24 |
}
|
| 25 |
|
|
|
|
| 4 |
constructor() {
|
| 5 |
this.num_beers = 0;
|
| 6 |
this.courage = 1;
|
| 7 |
+
this.personality = "This is the Shyguy. He is shy and introverted. He is also a bit of a nerd. He fell in love with Jessica. With Jessica, he talks about algorithms. He is super shy.";
|
| 8 |
this.lessons_learned = "";
|
| 9 |
this.conversation_history = "";
|
| 10 |
this.song_playing = "Let it be";
|
|
|
|
| 19 |
return `This is Shyguy. He had two beers, so he feels relaxed and he can talk with anyone. Follow the following lessons: ${this.lessons_learned}`;
|
| 20 |
}
|
| 21 |
else {
|
| 22 |
+
return `${this.personality}. His courage is ${this.courage} on the level 1 to 10. If his courage is higher than 5, he is self-confident. He is really shy and he fears talking with people. It is not easy to persuade him. He doe not want to drink at first.Follow the following lessons: ${this.lessons_learned}`;
|
| 23 |
}
|
| 24 |
}
|
| 25 |
|
src/speech_to_text.js
CHANGED
|
@@ -1,66 +1,65 @@
|
|
|
|
|
|
|
|
| 1 |
export class SpeechToTextClient {
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
this.mediaRecorder.ondataavailable = (event) => {
|
| 16 |
-
this.audioChunks.push(event.data);
|
| 17 |
-
};
|
| 18 |
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
console.error("Error starting recording:", error);
|
| 23 |
-
throw error;
|
| 24 |
-
}
|
| 25 |
-
}
|
| 26 |
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
const result = await this.transcribeAudio(audioBlob);
|
| 33 |
-
resolve(result);
|
| 34 |
-
} catch (error) {
|
| 35 |
-
reject(error);
|
| 36 |
-
}
|
| 37 |
-
};
|
| 38 |
-
|
| 39 |
-
this.mediaRecorder.stop();
|
| 40 |
-
this.isRecording = false;
|
| 41 |
-
this.mediaRecorder.stream.getTracks().forEach(track => track.stop());
|
| 42 |
-
});
|
| 43 |
}
|
|
|
|
| 44 |
|
| 45 |
-
|
|
|
|
|
|
|
| 46 |
try {
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
headers: {
|
| 51 |
-
"Accept": "application/json",
|
| 52 |
-
"Authorization": `Bearer ${this.apiKey}`,
|
| 53 |
-
"Content-Type": "audio/webm"
|
| 54 |
-
},
|
| 55 |
-
method: "POST",
|
| 56 |
-
body: audioBlob,
|
| 57 |
-
}
|
| 58 |
-
);
|
| 59 |
-
const result = await response.json();
|
| 60 |
-
return result;
|
| 61 |
} catch (error) {
|
| 62 |
-
|
| 63 |
-
throw error;
|
| 64 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
}
|
|
|
|
| 66 |
}
|
|
|
|
| 1 |
+
import { HUGGINGFACE_API_KEY } from "../api.js";
|
| 2 |
+
|
| 3 |
export class SpeechToTextClient {
|
| 4 |
+
constructor() {
|
| 5 |
+
this.apiKey = HUGGINGFACE_API_KEY;
|
| 6 |
+
this.isRecording = false;
|
| 7 |
+
this.mediaRecorder = null;
|
| 8 |
+
this.audioChunks = [];
|
| 9 |
+
}
|
| 10 |
|
| 11 |
+
async startRecording() {
|
| 12 |
+
try {
|
| 13 |
+
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
| 14 |
+
this.mediaRecorder = new MediaRecorder(stream);
|
| 15 |
+
this.audioChunks = [];
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
|
| 17 |
+
this.mediaRecorder.ondataavailable = (event) => {
|
| 18 |
+
this.audioChunks.push(event.data);
|
| 19 |
+
};
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
|
| 21 |
+
this.mediaRecorder.start();
|
| 22 |
+
this.isRecording = true;
|
| 23 |
+
} catch (error) {
|
| 24 |
+
console.error("Error starting recording:", error);
|
| 25 |
+
throw error;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
}
|
| 27 |
+
}
|
| 28 |
|
| 29 |
+
async stopRecording() {
|
| 30 |
+
return new Promise((resolve, reject) => {
|
| 31 |
+
this.mediaRecorder.onstop = async () => {
|
| 32 |
try {
|
| 33 |
+
const audioBlob = new Blob(this.audioChunks, { type: "audio/webm" });
|
| 34 |
+
const result = await this.transcribeAudio(audioBlob);
|
| 35 |
+
resolve(result);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
} catch (error) {
|
| 37 |
+
reject(error);
|
|
|
|
| 38 |
}
|
| 39 |
+
};
|
| 40 |
+
|
| 41 |
+
this.mediaRecorder.stop();
|
| 42 |
+
this.isRecording = false;
|
| 43 |
+
this.mediaRecorder.stream.getTracks().forEach((track) => track.stop());
|
| 44 |
+
});
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
async transcribeAudio(audioBlob) {
|
| 48 |
+
try {
|
| 49 |
+
const response = await fetch("https://q86j6jmwc3jujazp.us-east-1.aws.endpoints.huggingface.cloud", {
|
| 50 |
+
headers: {
|
| 51 |
+
Accept: "application/json",
|
| 52 |
+
Authorization: `Bearer ${this.apiKey}`,
|
| 53 |
+
"Content-Type": "audio/webm",
|
| 54 |
+
},
|
| 55 |
+
method: "POST",
|
| 56 |
+
body: audioBlob,
|
| 57 |
+
});
|
| 58 |
+
const result = await response.json();
|
| 59 |
+
return result;
|
| 60 |
+
} catch (error) {
|
| 61 |
+
console.error("Error transcribing audio:", error);
|
| 62 |
+
throw error;
|
| 63 |
}
|
| 64 |
+
}
|
| 65 |
}
|
vite.config.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
| 1 |
export default {
|
|
|
|
|
|
|
|
|
|
| 2 |
server: {
|
| 3 |
open: true,
|
| 4 |
-
allowedHosts: [
|
| 5 |
},
|
| 6 |
};
|
|
|
|
| 1 |
+
import dotenv from "dotenv";
|
| 2 |
+
dotenv.config();
|
| 3 |
+
|
| 4 |
export default {
|
| 5 |
+
define: {
|
| 6 |
+
"process.env": process.env,
|
| 7 |
+
},
|
| 8 |
server: {
|
| 9 |
open: true,
|
| 10 |
+
allowedHosts: ["jakubrada-shyguyswingman.hf.space"],
|
| 11 |
},
|
| 12 |
};
|