datbkpro commited on
Commit
24a5f5e
·
verified ·
1 Parent(s): 3aba5ae

Create voice_coding_service.py

Browse files
Files changed (1) hide show
  1. services/voice_coding_service.py +133 -0
services/voice_coding_service.py ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import numpy as np
3
+ import base64
4
+ import re
5
+ from groq import Groq
6
+ from gradio_webrtc import (
7
+ WebRTC,
8
+ ReplyOnStopWords,
9
+ AdditionalOutputs,
10
+ audio_to_bytes,
11
+ get_twilio_turn_credentials,
12
+ )
13
+
14
+ class VoiceCodingService:
15
+ """Dịch vụ Voice Coding sử dụng Groq + WebRTC"""
16
+
17
+ def __init__(self, groq_client: Groq):
18
+ self.groq_client = groq_client
19
+ self.rtc_configuration = get_twilio_turn_credentials()
20
+
21
+ # HTML templates
22
+ self.spinner_html = """
23
+ <div style="text-align: center; padding: 20px;">
24
+ <div class="spinner"></div>
25
+ <p>🦙 Llama đang code...</p>
26
+ </div>
27
+ <style>
28
+ .spinner {
29
+ border: 4px solid #f3f3f3;
30
+ border-top: 4px solid #3498db;
31
+ border-radius: 50%;
32
+ width: 40px;
33
+ height: 40px;
34
+ animation: spin 2s linear infinite;
35
+ margin: 0 auto;
36
+ }
37
+ @keyframes spin {
38
+ 0% { transform: rotate(0deg); }
39
+ 100% { transform: rotate(360deg); }
40
+ }
41
+ </style>
42
+ """
43
+
44
+ self.sandbox_html = """
45
+ <div style="text-align: center; padding: 20px;">
46
+ <h3>🎮 Sandbox Preview</h3>
47
+ <p>Code sẽ được hiển thị ở đây sau khi generate</p>
48
+ </div>
49
+ """
50
+
51
+ self.something_happened_html = """
52
+ <div style="text-align: center; padding: 20px; color: #e74c3c;">
53
+ <h3>❌ Có lỗi xảy ra</h3>
54
+ <p>Không thể generate code. Vui lòng thử lại.</p>
55
+ </div>
56
+ """
57
+
58
+ # Prompts
59
+ self.system_prompt = "You are an AI coding assistant. Your task is to write single-file HTML applications based on a user's request. Only return the necessary code. Include all necessary imports and styles. You may also be asked to edit your original response. Respond in Vietnamese when appropriate."
60
+ self.user_prompt = "Please write a single-file HTML application to fulfill the following request.\nThe message:{user_message}\nCurrent code you have written:{code}"
61
+
62
+ def extract_html_content(self, text):
63
+ """Extract content including HTML tags."""
64
+ match = re.search(r"<!DOCTYPE html>.*?</html>", text, re.DOTALL)
65
+ return match.group(0) if match else None
66
+
67
+ def display_in_sandbox(self, code):
68
+ """Hiển thị code trong sandbox iframe"""
69
+ if not code:
70
+ return self.sandbox_html
71
+
72
+ try:
73
+ encoded_html = base64.b64encode(code.encode("utf-8")).decode("utf-8")
74
+ data_uri = f"data:text/html;charset=utf-8;base64,{encoded_html}"
75
+ return f'<iframe src="{data_uri}" width="100%" height="600px" style="border: 1px solid #ccc;"></iframe>'
76
+ except Exception as e:
77
+ print(f"❌ Lỗi display sandbox: {e}")
78
+ return self.something_happened_html
79
+
80
+ def generate_code(self, user_message: tuple[int, np.ndarray], history: list[dict], code: str):
81
+ """Generate code từ voice input"""
82
+ yield AdditionalOutputs(history, self.spinner_html)
83
+
84
+ try:
85
+ # Chuyển audio sang text
86
+ sr, audio = user_message
87
+ audio = audio.squeeze()
88
+
89
+ print("🎤 Converting speech to text...")
90
+ text = self.groq_client.audio.transcriptions.create(
91
+ file=("audio-file.mp3", audio_to_bytes((sr, audio))),
92
+ model="whisper-large-v3-turbo",
93
+ response_format="verbose_json",
94
+ ).text
95
+
96
+ print(f"📝 Transcription: {text}")
97
+
98
+ # Format user message
99
+ user_msg_formatted = self.user_prompt.format(user_message=text, code=code)
100
+ history.append({"role": "user", "content": user_msg_formatted})
101
+
102
+ # Generate code với Groq
103
+ print("🦙 Generating code with Llama...")
104
+ response = self.groq_client.chat.completions.create(
105
+ model="llama-3.1-8b-instant",
106
+ messages=history,
107
+ temperature=1,
108
+ max_tokens=2048,
109
+ top_p=1,
110
+ stream=False,
111
+ )
112
+
113
+ output = response.choices[0].message.content
114
+ print("✅ Code generated successfully")
115
+
116
+ # Extract HTML code
117
+ try:
118
+ html_code = self.extract_html_content(output)
119
+ if not html_code:
120
+ html_code = f"<!-- Generated Code -->\n{output}"
121
+ except Exception as e:
122
+ print(f"⚠️ Could not extract HTML: {e}")
123
+ html_code = self.something_happened_html
124
+
125
+ # Update history
126
+ history.append({"role": "assistant", "content": output})
127
+
128
+ yield AdditionalOutputs(history, html_code)
129
+
130
+ except Exception as e:
131
+ print(f"❌ Lỗi generate code: {e}")
132
+ history.append({"role": "assistant", "content": f"Error: {str(e)}"})
133
+ yield AdditionalOutputs(history, self.something_happened_html)