diff --git a/main.py b/main.py new file mode 100644 index 0000000..d2f0ae4 --- /dev/null +++ b/main.py @@ -0,0 +1,32 @@ +from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Request +from fastapi.responses import HTMLResponse +from fastapi.staticfiles import StaticFiles +from fastapi.templating import Jinja2Templates +import uvicorn +from langchain_cohere import ChatCohere +from langchain_core.messages import HumanMessage + +app = FastAPI() + +llm = ChatCohere(cohere_api_key='lMQ2FCVWccphyyB10tGpZg3oinBjGOixW0D3fmPd') + +app.mount("/static", StaticFiles(directory="static"), name="static") +templates = Jinja2Templates(directory="templates") + +@app.get("/", response_class=HTMLResponse) +async def index(request: Request): + return templates.TemplateResponse("index.html", {"request": request}) + +@app.websocket("/transcribe") +async def transcribe(websocket: WebSocket): + await websocket.accept() + + while True: + human_input = await websocket.receive_text() + if human_input: + human_message = [HumanMessage(content=human_input)] + response = llm.invoke(human_message, max_tokens=80) + await websocket.send_text(response.content) + +if __name__ == "__main__": + uvicorn.run(app, host="0.0.0.0", port=5000, reload=True) diff --git a/static/css/style.css b/static/css/style.css new file mode 100644 index 0000000..6ca7169 --- /dev/null +++ b/static/css/style.css @@ -0,0 +1,34 @@ +/* Speech recognition output */ +.output-box { + background-color: rgb(248 245 245); + padding: 20px; + border-radius: 10px; + min-height: 150px; + overflow-y: auto; +} + +/* Theme toggle button styles */ +.theme-toggle { + position: fixed; + top: 20px; + right: 20px; + z-index: 9999; + background-color: #9a69dc; + color: white; + border: none; + border-radius: 50%; + width: 50px; + height: 50px; + font-size: 24px; + cursor: pointer; +} + +/* Recording button styles */ +.recording-button { + font-size: 24px; + border-radius: 50%; + width: 90px; + height: 90px; + margin: 0 10px; + background-color: #9a69dc; +} diff --git a/static/js/index.js b/static/js/index.js new file mode 100644 index 0000000..8da3a35 --- /dev/null +++ b/static/js/index.js @@ -0,0 +1,116 @@ +// Theme toggle +const body = document.body; +const themeToggle = document.getElementById("themeToggle"); +// WebSocket +var httpProtocol = 'http://'; +var wsProtocol = 'ws://'; +if (window.location.protocol === 'https:') { + httpProtocol = 'https://'; + wsProtocol = 'wss://'; +} +const socket = new WebSocket(wsProtocol + window.location.host + "/transcribe"); +// Recording Button +const recordingButton = document.getElementById("recordingButton"); +// Output Box +const output = document.getElementById("output"); +let isRecording = false; + +// Theme toggle functionality +themeToggle.addEventListener("click", () => { + body.classList.toggle("bg-dark"); + const isDarkTheme = body.classList.contains("bg-dark"); + themeToggle.innerHTML = isDarkTheme + ? '' + : ''; +}); + +// Initialize speech recognition +const SpeechRecognition = + window.SpeechRecognition || window.webkitSpeechRecognition; +const recognition = new SpeechRecognition(); + +recognition.interimResults = false; // Enable interim results +recognition.continuous = false; +recognition.lang = "en-US"; + +// Event listeners for start and stop buttons +recordingButton.addEventListener("click", toggleRecording); +function toggleRecording() { + isRecording = !isRecording; + recordingButton.innerHTML = isRecording + ? '' + : ''; + if (isRecording) { + startRecording(); + } else { + stopRecording(); + } +} + +// Event listener for when speech recognition starts +recognition.onstart = function () { + console.log("Speech recognition started..."); + output.innerHTML = ""; + output.innerHTML = '

Listening...

'; +}; + +// Event listener for interim results +recognition.onresult = function (event) { + const interimTranscript = Array.from(event.results) + .map((result) => result[0].transcript) + .join(""); + output.innerHTML = `

${interimTranscript}

`; + socket.send(interimTranscript); +}; + +// Event listener for when speech recognition ends +recognition.onend = function () { + console.log("Speech recognition ended."); + isRecording = !isRecording; + recordingButton.innerHTML = isRecording + ? '' + : ''; +}; + +// Function to start recording +function startRecording() { + navigator.mediaDevices + .getUserMedia({ audio: true }) + .then(() => { + recognition.start(); // Start recognition + speechSynthesis.cancel(); + isRecording = true + }) + .catch((error) => { + // Microphone is not enabled or available + console.error("Microphone is not enabled or available:", error); + alert( + "Microphone is not enabled or available. Please enable your microphone and refresh the page." + ); + }); +} + +function stopRecording() { + recognition.stop(); + isRecording = false + output.innerHTML = '

Start Recording to begin.

' +} + +// On reciveing message from socket +socket.onmessage = function (event) { + stopRecording(); + output.innerHTML = `

${event.data}

`; + textToSpeech(event.data); +}; + +// Speak recieved text from AI +function textToSpeech(phrase) { + const audio = new Audio(); + const speechSettings = new SpeechSynthesisUtterance(phrase); + speechSynthesis.speak(speechSettings); +} + +// Stop speaking +function stopSpeaker() { + speechSynthesis.cancel(); +} diff --git a/static/logo/talkgenie-icon.png b/static/logo/talkgenie-icon.png new file mode 100644 index 0000000..7355df8 Binary files /dev/null and b/static/logo/talkgenie-icon.png differ diff --git a/static/logo/talkgenie-logo.png b/static/logo/talkgenie-logo.png new file mode 100644 index 0000000..9a2087a Binary files /dev/null and b/static/logo/talkgenie-logo.png differ diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..1e30fc1 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,41 @@ + + + + + + + TalkGenie + + + + + + + + + + + +
+ +

TalkGenie grant your voice wishes, utilizing advanced AI to understand your + commands and provide swift and accurate responses tailored to your needs.

+
+ +
+
+

Start Recording to begin.

+
+
+ + + + + + + \ No newline at end of file