shukdevdatta123 commited on
Commit
7d42197
Β·
verified Β·
1 Parent(s): 9cfd091

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +278 -0
app.py ADDED
@@ -0,0 +1,278 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import openai
3
+ import json
4
+ import os
5
+ from datetime import datetime
6
+
7
+ # Default configurations
8
+ SUPPORTED_LANGUAGES = {
9
+ "English": "en",
10
+ "Spanish": "es",
11
+ "French": "fr",
12
+ "German": "de",
13
+ "Chinese": "zh",
14
+ "Japanese": "ja",
15
+ "Italian": "it",
16
+ "Portuguese": "pt",
17
+ "Russian": "ru",
18
+ "Arabic": "ar"
19
+ }
20
+
21
+ PROFICIENCY_LEVELS = ["Beginner", "Intermediate", "Advanced"]
22
+
23
+ # Tracks conversation history and user stats
24
+ class LearningSession:
25
+ def __init__(self):
26
+ self.conversation_history = []
27
+ self.vocabulary = set()
28
+ self.session_start = datetime.now()
29
+ self.api_key = None
30
+ self.language = "Spanish"
31
+ self.language_code = "es"
32
+ self.proficiency = "Beginner"
33
+ self.thinking_mode = False
34
+
35
+ def add_message(self, role, content):
36
+ self.conversation_history.append({"role": role, "content": content})
37
+ if role == "assistant":
38
+ # Extract vocabulary from assistant responses
39
+ words = content.lower().replace('.', ' ').replace(',', ' ').replace('!', ' ').replace('?', ' ').split()
40
+ self.vocabulary.update(words)
41
+
42
+ def get_messages(self):
43
+ # Format for display
44
+ formatted = []
45
+ for msg in self.conversation_history:
46
+ if msg["role"] == "system":
47
+ continue
48
+ speaker = "πŸ‘€ You:" if msg["role"] == "user" else f"πŸ€– {self.language} Tutor:"
49
+ formatted.append(f"{speaker} {msg['content']}")
50
+ return "\n\n".join(formatted)
51
+
52
+ def get_openai_messages(self):
53
+ # Add system message for context
54
+ system_prompt = self._generate_system_prompt()
55
+ messages = [{"role": "system", "content": system_prompt}]
56
+
57
+ # Add conversation history (limit to last 10 messages to save tokens)
58
+ messages.extend(self.conversation_history[-10:])
59
+ return messages
60
+
61
+ def _generate_system_prompt(self):
62
+ if self.thinking_mode:
63
+ mode_instruction = (
64
+ "Use a thinking/reasoning mode where you carefully analyze the user's language, "
65
+ "provide corrections, and explain grammar concepts in detail."
66
+ )
67
+ else:
68
+ mode_instruction = (
69
+ "Maintain a natural conversational flow. Only correct critical errors that "
70
+ "would impede understanding, and do so gently within the conversation."
71
+ )
72
+
73
+ language_level_map = {
74
+ "Beginner": "Use simple vocabulary and short sentences. Frequently introduce basic vocabulary and simple grammar constructions.",
75
+ "Intermediate": "Use moderate vocabulary and varied sentence structures. Introduce idioms occasionally and more complex grammar patterns.",
76
+ "Advanced": "Use rich vocabulary, complex sentences, idioms, and cultural references. Challenge the learner with sophisticated language constructs."
77
+ }
78
+
79
+ level_instruction = language_level_map[self.proficiency]
80
+
81
+ return f"""You are a friendly and patient {self.language} language tutor.
82
+
83
+ IMPORTANT: You must respond ONLY in {self.language} except when explaining grammar concepts in thinking mode.
84
+
85
+ {mode_instruction}
86
+
87
+ {level_instruction}
88
+
89
+ Keep conversations engaging, diverse, and natural. Ask questions about the learner's interests, daily life, or opinions.
90
+ Occasionally introduce culturally relevant topics about countries where {self.language} is spoken.
91
+
92
+ Remember that you are helping someone learn {self.language}, so maintain an encouraging tone.
93
+ """
94
+
95
+ # Initialize session
96
+ session = LearningSession()
97
+
98
+ def set_api_key(api_key):
99
+ """Validate and set the OpenRouter API key."""
100
+ if not api_key.strip():
101
+ return "❌ Please enter your OpenRouter API key"
102
+
103
+ # Store API key in session
104
+ session.api_key = api_key
105
+
106
+ # Simple validation (just checking if it looks like a valid key format)
107
+ if len(api_key) < 20:
108
+ return "❌ API key looks too short. Please check it and try again."
109
+
110
+ return "βœ… API key set! You can now start your language learning session."
111
+
112
+ def update_settings(language, proficiency, thinking_mode):
113
+ """Update session settings."""
114
+ session.language = language
115
+ session.language_code = SUPPORTED_LANGUAGES[language]
116
+ session.proficiency = proficiency
117
+ session.thinking_mode = thinking_mode
118
+
119
+ return f"Settings updated: Learning {language} at {proficiency} level. Thinking mode: {'On' if thinking_mode else 'Off'}"
120
+
121
+ def get_ai_response(user_message):
122
+ """Get response from Qwen3 0.6B via OpenRouter API."""
123
+ if not session.api_key:
124
+ return "Please set your OpenRouter API key first."
125
+
126
+ if not user_message.strip():
127
+ return "Please enter a message."
128
+
129
+ try:
130
+ # Add user message to history
131
+ session.add_message("user", user_message)
132
+
133
+ # Create OpenAI client with OpenRouter base URL
134
+ client = openai.OpenAI(
135
+ base_url="https://openrouter.ai/api/v1",
136
+ api_key=session.api_key
137
+ )
138
+
139
+ # Get conversation history formatted for API
140
+ messages = session.get_openai_messages()
141
+
142
+ # Make API request
143
+ completion = client.chat.completions.create(
144
+ extra_headers={
145
+ "HTTP-Referer": "Language Learning Companion App",
146
+ "X-Title": "Language Learning App with Qwen3"
147
+ },
148
+ model="qwen/qwen3-0.6b-04-28:free",
149
+ messages=messages
150
+ )
151
+
152
+ # Extract response
153
+ ai_response = completion.choices[0].message.content
154
+
155
+ # Add to history
156
+ session.add_message("assistant", ai_response)
157
+
158
+ # Return full conversation history
159
+ return session.get_messages()
160
+
161
+ except Exception as e:
162
+ return f"Error: {str(e)}"
163
+
164
+ def reset_conversation():
165
+ """Reset the conversation history."""
166
+ session.conversation_history = []
167
+ return "Conversation has been reset."
168
+
169
+ def get_vocabulary_list():
170
+ """Get the current vocabulary list."""
171
+ if not session.vocabulary:
172
+ return "No vocabulary collected yet."
173
+
174
+ vocab_list = sorted(list(session.vocabulary))
175
+ return ", ".join(vocab_list)
176
+
177
+ def get_session_stats():
178
+ """Get statistics about the current session."""
179
+ duration = datetime.now() - session.session_start
180
+ hours, remainder = divmod(duration.seconds, 3600)
181
+ minutes, seconds = divmod(remainder, 60)
182
+
183
+ stats = {
184
+ "Language": session.language,
185
+ "Proficiency Level": session.proficiency,
186
+ "Session Duration": f"{hours}h {minutes}m {seconds}s",
187
+ "Messages Exchanged": len(session.conversation_history),
188
+ "Vocabulary Words": len(session.vocabulary)
189
+ }
190
+
191
+ return json.dumps(stats, indent=2)
192
+
193
+ # Create Gradio interface
194
+ with gr.Blocks(title="Language Learning Companion") as app:
195
+ gr.Markdown("# 🌍 Language Learning Companion")
196
+ gr.Markdown("Learn languages through natural conversation with AI powered by Qwen3 0.6B")
197
+
198
+ with gr.Accordion("Setup", open=True):
199
+ api_key_input = gr.Textbox(
200
+ label="OpenRouter API Key",
201
+ placeholder="Enter your OpenRouter API key...",
202
+ type="password"
203
+ )
204
+ api_submit = gr.Button("Set API Key")
205
+ api_status = gr.Textbox(label="API Status", interactive=False)
206
+
207
+ api_submit.click(set_api_key, inputs=api_key_input, outputs=api_status)
208
+
209
+ with gr.Accordion("Learning Settings", open=True):
210
+ with gr.Row():
211
+ language_dropdown = gr.Dropdown(
212
+ choices=list(SUPPORTED_LANGUAGES.keys()),
213
+ value="Spanish",
214
+ label="Language to Learn"
215
+ )
216
+ proficiency_dropdown = gr.Dropdown(
217
+ choices=PROFICIENCY_LEVELS,
218
+ value="Beginner",
219
+ label="Proficiency Level"
220
+ )
221
+ thinking_checkbox = gr.Checkbox(
222
+ label="Enable Thinking Mode (Grammar Explanations)",
223
+ value=False
224
+ )
225
+
226
+ settings_submit = gr.Button("Update Settings")
227
+ settings_status = gr.Textbox(label="Settings Status", interactive=False)
228
+
229
+ settings_submit.click(
230
+ update_settings,
231
+ inputs=[language_dropdown, proficiency_dropdown, thinking_checkbox],
232
+ outputs=settings_status
233
+ )
234
+
235
+ with gr.Row():
236
+ with gr.Column(scale=2):
237
+ chat_output = gr.Textbox(
238
+ label="Conversation",
239
+ placeholder="Your conversation will appear here...",
240
+ lines=15,
241
+ interactive=False
242
+ )
243
+
244
+ user_input = gr.Textbox(
245
+ label="Your message",
246
+ placeholder=f"Type your message in any language...",
247
+ lines=2
248
+ )
249
+
250
+ with gr.Row():
251
+ submit_btn = gr.Button("Send", variant="primary")
252
+ reset_btn = gr.Button("Reset Conversation")
253
+
254
+ with gr.Column(scale=1):
255
+ with gr.Accordion("Vocabulary", open=True):
256
+ vocab_output = gr.Textbox(
257
+ label="Words Encountered",
258
+ lines=10,
259
+ interactive=False
260
+ )
261
+ vocab_btn = gr.Button("Show Vocabulary")
262
+
263
+ with gr.Accordion("Session Stats", open=True):
264
+ stats_output = gr.JSON(label="Learning Statistics")
265
+ stats_btn = gr.Button("Update Stats")
266
+
267
+ # Set up button actions
268
+ submit_btn.click(get_ai_response, inputs=user_input, outputs=chat_output)
269
+ reset_btn.click(reset_conversation, outputs=chat_output)
270
+ vocab_btn.click(get_vocabulary_list, outputs=vocab_output)
271
+ stats_btn.click(get_session_stats, outputs=stats_output)
272
+
273
+ # Allow pressing Enter to submit
274
+ user_input.submit(get_ai_response, inputs=user_input, outputs=chat_output)
275
+
276
+ # Launch the app
277
+ if __name__ == "__main__":
278
+ app.launch()