KB-Infinity-Tech commited on
Commit
73513b6
ยท
verified ยท
1 Parent(s): c62b2eb

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +222 -43
src/streamlit_app.py CHANGED
@@ -1,52 +1,231 @@
 
 
 
 
 
1
  import streamlit as st
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  import os
3
  from huggingface_hub import InferenceClient
4
 
5
- # -----------------------------
6
- # PAGE SETUP
7
- # -----------------------------
8
- st.set_page_config(page_title="Text to Image AI", layout="centered")
9
- st.title("๐ŸŽจ Text โ†’ Image Generator (Pro)")
10
 
11
- # -----------------------------
12
- # LOAD TOKEN
13
- # -----------------------------
14
- HF_TOKEN = os.getenv("HF_TOKEN") or st.secrets.get("HF_TOKEN")
 
 
 
 
 
15
 
16
- if not HF_TOKEN:
17
- st.error("โŒ HF_TOKEN is missing. Add it in Secrets.")
18
- st.stop()
19
 
20
- # -----------------------------
21
- # HUGGING FACE CLIENT
22
- # -----------------------------
23
- client = InferenceClient(
24
- provider="nscale",
25
- api_key=HF_TOKEN,
 
 
 
 
 
 
26
  )
27
 
28
- # -----------------------------
29
- # UI INPUT
30
- # -----------------------------
31
- prompt = st.text_input("Enter your prompt (e.g. astronaut riding a horse)")
32
-
33
- # -----------------------------
34
- # GENERATE IMAGE
35
- # -----------------------------
36
- if st.button("Generate Image"):
37
- if not prompt:
38
- st.warning("Please enter a prompt")
39
- else:
40
- with st.spinner("Generating image... โณ"):
41
- try:
42
- image = client.text_to_image(
43
- prompt,
44
- model="stabilityai/stable-diffusion-xl-base-1.0",
45
- )
46
-
47
- st.image(image, caption=prompt)
48
- st.success("Done ๐ŸŽ‰")
49
-
50
- except Exception as e:
51
- st.error("Error generating image:")
52
- st.write(str(e))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Streamlit demo for the Math Tutor with multilingual & voice support.
3
+ Run: streamlit run demo.py
4
+ """
5
+
6
  import streamlit as st
7
+ import io
8
+ import wave
9
+
10
+ from gtts import gTTS
11
+ import tempfile
12
+ from tutor.core import (
13
+ CurriculumLoader,
14
+ ChildASRAdapter,
15
+ ResponseScorer,
16
+ LearnerState,
17
+ FeedbackGenerator,
18
+ LocalProgressStore,
19
+ )
20
  import os
21
  from huggingface_hub import InferenceClient
22
 
23
+ client = InferenceClient(
24
+ provider="nscale",
25
+ api_key=os.environ["HF_TOKEN"],
26
+ )
 
27
 
28
+ # =========================
29
+ # ๐Ÿ”Š VOICE ENGINE (NEW)
30
+ # =========================
31
+ def speak(text, lang="en"):
32
+ lang_map = {
33
+ "en": "en",
34
+ "fr": "fr",
35
+ "kin": "en" # fallback safe
36
+ }
37
 
38
+ tts = gTTS(text=text, lang=lang_map.get(lang, "en"))
 
 
39
 
40
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as f:
41
+ tts.save(f.name)
42
+ return f.name
43
+
44
+
45
+ # =========================
46
+ # PAGE CONFIG
47
+ # =========================
48
+ st.set_page_config(
49
+ page_title="Math Tutor",
50
+ page_icon="๐Ÿงฎ",
51
+ layout="centered"
52
  )
53
 
54
+ # =========================
55
+ # SESSION STATE
56
+ # =========================
57
+ if 'curriculum' not in st.session_state:
58
+ st.session_state.curriculum = CurriculumLoader()
59
+ if 'learner_state' not in st.session_state:
60
+ st.session_state.learner_state = LearnerState('demo_learner')
61
+ if 'item_index' not in st.session_state:
62
+ st.session_state.item_index = 0
63
+ if 'store' not in st.session_state:
64
+ st.session_state.store = LocalProgressStore()
65
+ st.session_state.store.add_learner('demo_learner', 'Demo Child', 'en')
66
+ if 'asr' not in st.session_state:
67
+ st.session_state.asr = ChildASRAdapter()
68
+ if 'scorer' not in st.session_state:
69
+ st.session_state.scorer = ResponseScorer()
70
+ if 'language' not in st.session_state:
71
+ st.session_state.language = 'en'
72
+
73
+ # =========================
74
+ # MAIN UI
75
+ # =========================
76
+ st.title("๐Ÿงฎ AI Math Tutor for Early Learners")
77
+
78
+ curriculum = st.session_state.curriculum
79
+ learner_state = st.session_state.learner_state
80
+ store = st.session_state.store
81
+ asr = st.session_state.asr
82
+ scorer = st.session_state.scorer
83
+
84
+ # =========================
85
+ # SIDEBAR
86
+ # =========================
87
+ with st.sidebar:
88
+ st.markdown("### โš™๏ธ Settings")
89
+
90
+ language_map = {
91
+ 'English ๐Ÿ‡ฌ๐Ÿ‡ง': 'en',
92
+ 'Franรงais ๐Ÿ‡ซ๐Ÿ‡ท': 'fr',
93
+ 'Kinyarwanda ๐Ÿ‡ท๐Ÿ‡ผ': 'kin'
94
+ }
95
+
96
+ lang_display = st.radio(
97
+ "Language:",
98
+ list(language_map.keys())
99
+ )
100
+
101
+ st.session_state.language = language_map[lang_display]
102
+
103
+ # =========================
104
+ # GET CURRENT ITEM
105
+ # =========================
106
+ if st.session_state.item_index < len(curriculum.items):
107
+
108
+ current_item = curriculum.items[st.session_state.item_index]
109
+
110
+ st.markdown("### ๐Ÿ‘‚ Listen and Answer")
111
+
112
+ lang_key = f"stem_{st.session_state.language}"
113
+ question = current_item.get(lang_key, current_item.get('stem_en'))
114
+
115
+ st.markdown(f"**Question:** {question}")
116
+
117
+ # =========================
118
+ # ๐Ÿ”Š SPEAK QUESTION (NEW)
119
+ # =========================
120
+ if st.button("๐Ÿ”Š Listen Question"):
121
+ audio_q = speak(question, st.session_state.language)
122
+ st.audio(audio_q)
123
+
124
+ # =========================
125
+ # VISUAL GROUNDING (IMPROVED)
126
+ # =========================
127
+ visual = current_item.get('visual')
128
+
129
+ if visual:
130
+ parts = visual.split('_')
131
+ name = parts[0]
132
+
133
+ nums = [int(s) for s in parts if s.isdigit()]
134
+ count = nums[0] if nums else None
135
+
136
+ emoji_map = {
137
+ 'apples': '๐ŸŽ',
138
+ 'goats': '๏ฟฝ๏ฟฝ๏ฟฝ',
139
+ 'beads': '๐Ÿ”ต',
140
+ 'default': '๐Ÿ”ข'
141
+ }
142
+
143
+ symbol = emoji_map.get(name.lower(), '๐Ÿ”ข')
144
+
145
+ if count:
146
+ st.markdown("### ๐Ÿง  Visual Learning")
147
+ st.markdown(symbol * min(count, 20))
148
+
149
+ # =========================
150
+ # INPUT
151
+ # =========================
152
+ transcript = st.text_input(
153
+ "Your Answer:"
154
+ )
155
+
156
+ # =========================
157
+ # SUBMIT
158
+ # =========================
159
+ if st.button("Submit Answer", type="primary"):
160
+
161
+ if transcript.strip():
162
+
163
+ # Score
164
+ correct = scorer.score_response(
165
+ current_item.get('answer_int', 0),
166
+ transcript,
167
+ current_item
168
+ )
169
+
170
+ # Detect language (code-switch awareness)
171
+ detected_lang = asr.detect_language(transcript)
172
+
173
+ # Save
174
+ store.add_response(
175
+ 'demo_learner',
176
+ current_item.get('skill'),
177
+ current_item.get('id'),
178
+ correct,
179
+ transcript
180
+ )
181
+
182
+ learner_state.record_response(
183
+ current_item.get('skill'),
184
+ correct
185
+ )
186
+
187
+ # =========================
188
+ # FEEDBACK ENGINE
189
+ # =========================
190
+ feedback = FeedbackGenerator.generate_feedback(
191
+ correct,
192
+ st.session_state.language,
193
+ current_item.get('answer_int')
194
+ )
195
+
196
+ # =========================
197
+ # CODE-SWITCH HANDLING (NEW)
198
+ # =========================
199
+ if detected_lang != st.session_state.language:
200
+ feedback += " (I noticed mixed language input ๐Ÿ‘)"
201
+
202
+ # =========================
203
+ # SHOW RESULT
204
+ # =========================
205
+ if correct:
206
+ st.success(f"โœ… {feedback}")
207
+ else:
208
+ st.error(f"โŒ {feedback}")
209
+
210
+ # =========================
211
+ # ๐Ÿ”Š VOICE RESPONSE (NEW)
212
+ # =========================
213
+ audio = speak(feedback, st.session_state.language)
214
+ st.audio(audio, autoplay=True)
215
+
216
+ # NEXT QUESTION
217
+ st.session_state.item_index += 1
218
+ st.rerun()
219
+
220
+ else:
221
+ st.warning("Please enter an answer")
222
+
223
+ # =========================
224
+ # END SCREEN
225
+ # =========================
226
+ else:
227
+ st.success("๐ŸŽ‰ Great job! You finished!")
228
+
229
+ if st.button("Restart"):
230
+ st.session_state.item_index = 0
231
+ st.rerun()