Fatser commited on
Commit
c39edc9
·
verified ·
1 Parent(s): 42290d2

Upload 2 files

Browse files
Files changed (2) hide show
  1. src/app.py +96 -0
  2. src/main.py +121 -0
src/app.py ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import os
3
+ from main import get_english_tutor_agent, sesi_metne_cevir, metni_sese_cevir
4
+
5
+ st.set_page_config(page_title="AI English Tutor", page_icon="🇬🇧", layout="centered")
6
+
7
+ @st.cache_resource
8
+ def ajan_yukle():
9
+ return get_english_tutor_agent()
10
+
11
+ ajan, sistem_komutu = ajan_yukle()
12
+
13
+ # --- YAN MENÜ (SIDEBAR) AYARLARI ---
14
+ st.sidebar.title("⚙️ Eğitim Ayarları")
15
+
16
+ st.sidebar.markdown("**Sen Hangi Dilde Konuşacaksın?**")
17
+ ogrenci_dili = st.sidebar.radio(
18
+ "Mikrofon Algılama Dili",
19
+ ["İngilizce", "Türkçe"],
20
+ help="İngilizce pratik yaparken 'İngilizce' seçili kalsın. Öğretmene Türkçe bir şey sormak istersen 'Türkçe'ye alabilirsin."
21
+ )
22
+ # Seçime göre kod belirle
23
+ stt_lang = "en-US" if ogrenci_dili == "İngilizce" else "tr-TR"
24
+
25
+
26
+ st.sidebar.markdown("---")
27
+ st.sidebar.markdown("**Öğretmen Aksanı**")
28
+ ogretmen_sesi = st.sidebar.radio(
29
+ "AI Öğretmenin Sesi",
30
+ ["Amerikalı (Aria)", "Türk (Emel)"],
31
+ help="Amerikalı Aria sadece İngilizceyi kusursuz okur, Türkçeyi bozarak okur. Türk Emel ise Türkçeyi kusursuz okur, İngilizceyi Türk aksanıyla okur."
32
+ )
33
+ # Seçime göre model belirle
34
+ tts_voice = "en-US-AriaNeural" if ogretmen_sesi == "Amerikalı (Aria)" else "tr-TR-EmelNeural"
35
+
36
+
37
+ # --- ARAYÜZ (UI) ---
38
+ st.title("🎙️ AI English Tutor")
39
+ st.markdown("Hello! İster yazarak ister konuşarak pratik yapabiliriz.")
40
+
41
+ if "mesaj_gecmisi" not in st.session_state:
42
+ st.session_state.mesaj_gecmisi = []
43
+
44
+ for mesaj in st.session_state.mesaj_gecmisi:
45
+ with st.chat_message(mesaj["role"]):
46
+ st.markdown(mesaj["content"])
47
+
48
+ col1, col2 = st.columns([1, 1])
49
+ with col1:
50
+ yazili_girdi = st.chat_input("Yazarak cevap ver...")
51
+ with col2:
52
+ sesli_girdi = st.audio_input("Veya konuşarak cevap ver")
53
+
54
+ kullanici_girdisi = None
55
+
56
+ if sesli_girdi is not None:
57
+ with open("gecici_ses.wav", "wb") as f:
58
+ f.write(sesli_girdi.getvalue())
59
+
60
+ with st.spinner(f"Sesin {ogrenci_dili} olarak dinleniyor..."):
61
+ # Seçilen dil kodunu fonksiyona gönderiyoruz
62
+ kullanici_girdisi = sesi_metne_cevir("gecici_ses.wav", dil_kodu=stt_lang)
63
+
64
+ elif yazili_girdi:
65
+ kullanici_girdisi = yazili_girdi
66
+
67
+ if kullanici_girdisi:
68
+ with st.chat_message("user"):
69
+ st.markdown(kullanici_girdisi)
70
+ st.session_state.mesaj_gecmisi.append({"role": "user", "content": kullanici_girdisi})
71
+
72
+ with st.chat_message("assistant"):
73
+ with st.spinner("Öğretmen cevap hazırlıyor..."):
74
+ try:
75
+ langgraph_mesajlari = [("system", sistem_komutu)]
76
+ for m in st.session_state.mesaj_gecmisi:
77
+ langgraph_mesajlari.append((m["role"], m["content"]))
78
+
79
+ cevap = ajan.invoke({"messages": langgraph_mesajlari})
80
+ ham_icerik = cevap["messages"][-1].content
81
+
82
+ if isinstance(ham_icerik, list):
83
+ son_mesaj = "".join([blok.get("text", "") for blok in ham_icerik if isinstance(blok, dict) and "text" in blok])
84
+ else:
85
+ son_mesaj = ham_icerik
86
+
87
+ st.markdown(son_mesaj)
88
+ st.session_state.mesaj_gecmisi.append({"role": "assistant", "content": son_mesaj})
89
+
90
+ with st.spinner("Seslendiriliyor..."):
91
+ # Seçilen öğretmen sesini fonksiyona gönderiyoruz
92
+ ses_dosyasi = metni_sese_cevir(son_mesaj, ses_modeli=tts_voice)
93
+ st.audio(ses_dosyasi, autoplay=True)
94
+
95
+ except Exception as e:
96
+ st.error(f"Sistem Hatası: {e}")
src/main.py ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import asyncio
3
+ import edge_tts
4
+ import speech_recognition as sr
5
+ from dotenv import load_dotenv
6
+ from langchain_google_genai import ChatGoogleGenerativeAI
7
+ from langgraph.prebuilt import create_react_agent
8
+
9
+ load_dotenv()
10
+
11
+ SISTEM_KOMUTU = """Sen İngilizce öğreten bir yapay zekâ ajanısın ve kullanıcıyla arkadaş gibi konuşursun.
12
+
13
+ Amaç:
14
+ Kullanıcının seviyesini belirleyip ona uygun şekilde İngilizceyi adım adım öğretmek ve onu akıcı şekilde konuşur hale getirmek.
15
+
16
+ Genel Kurallar:
17
+
18
+ * Cevapların kısa olsun (maksimum 1-2 cümle)
19
+ * Basit ve anlaşılır konuş
20
+ * Sohbet tarzında ilerle (ders anlatma)
21
+ * Samimi ve destekleyici ol
22
+
23
+ SEVİYE BELİRLEME:
24
+
25
+ * Konuşmanın başında kullanıcıya 2-3 basit soru sor
26
+ * Sorular İngilizce olsun (çok basit seviyede)
27
+ * Kullanıcının cevaplarına göre seviyesini tahmin et:
28
+
29
+ * Çok zorlanıyorsa → başlangıç (A1)
30
+ * Basit cevaplar veriyorsa → A1-A2
31
+ * Daha rahat konuşuyorsa → üst seviyeye geç
32
+
33
+ SEVİYEYE GÖRE DAVRANIŞ:
34
+
35
+ * Başlangıç seviyesinde:
36
+
37
+ * Daha fazla Türkçe destek ver
38
+ * Çok basit İngilizce kullan
39
+ * Seviye arttıkça:
40
+
41
+ * Türkçeyi azalt
42
+ * İngilizceyi artır
43
+ * Soruları biraz zorlaştır
44
+
45
+ ÖĞRETİM YAKLAŞIMI:
46
+
47
+ * Basitten zora ilerle (küçük adımlar)
48
+ * Aynı anda tek konuya odaklan
49
+ * Kullanıcı hazır olmadan zorlaştırma
50
+ * Sohbet içinde öğret
51
+
52
+ DİL KULLANIMI:
53
+
54
+ * Kullanıcı Türkçe yazarsa:
55
+
56
+ * Kısa Türkçe cevap ver
57
+ * Ardından basit İngilizce cümle ekle
58
+ * Kullanıcı İngilizce yazarsa:
59
+
60
+ * İngilizce cevap ver
61
+ * Gerekirse kısa Türkçe destek ekle
62
+
63
+ KULLANICIYI KONUŞTURMA:
64
+
65
+ * Her mesajda kullanıcıyı İngilizce yazmaya teşvik et
66
+ * Küçük görevler ver:
67
+
68
+ * “Sen de dene”
69
+ * “Bunu İngilizce söyleyebilir misin?”
70
+ * Tek seferde 1 soru sor
71
+
72
+ HATA DÜZELTME:
73
+
74
+ * Hataları doğal şekilde düzelt
75
+ * Uzun açıklama yapma
76
+ * Doğru cümleyi örnek olarak ver
77
+
78
+ İLERLEME:
79
+
80
+ * Kullanıcı iyi performans gösterirse:
81
+
82
+ * Soruları biraz zorlaştır
83
+ * Zorlanırsa:
84
+
85
+ * Basitleştir ve Türkçe destek ver
86
+
87
+ SOHBET:
88
+
89
+ * Günlük konular kullan (okul, arkadaşlar, hobiler)
90
+ * Kullanıcıyı rahat hissettir
91
+ * Motive edici ol
92
+
93
+ Amaç:
94
+ Kullanıcının korkmadan, adım adım İngilizce konuşabilmesini sağlamak
95
+ """
96
+
97
+ def get_english_tutor_agent():
98
+ llm = ChatGoogleGenerativeAI(model="gemini-flash-lite-latest", temperature=0.7)
99
+ return create_react_agent(llm, []), SISTEM_KOMUTU
100
+
101
+ # SİHİRLİ DOKUNUŞ: Artık dil dışarıdan parametre olarak geliyor
102
+ def sesi_metne_cevir(audio_file_path, dil_kodu="en-US"):
103
+ r = sr.Recognizer()
104
+ try:
105
+ with sr.AudioFile(audio_file_path) as source:
106
+ audio = r.record(source)
107
+ metin = r.recognize_google(audio, language=dil_kodu)
108
+ return metin
109
+ except sr.UnknownValueError:
110
+ return "Anlayamadım, lütfen tekrar eder misin?"
111
+ except Exception as e:
112
+ return f"Ses çözümleme hatası: {e}"
113
+
114
+ # SİHİRLİ DOKUNUŞ: Ses modeli dışarıdan parametre olarak geliyor
115
+ def metni_sese_cevir(text, ses_modeli="en-US-AriaNeural", output_file_path="ogretmen_yaniti.mp3"):
116
+ async def uret():
117
+ communicate = edge_tts.Communicate(text, ses_modeli)
118
+ await communicate.save(output_file_path)
119
+
120
+ asyncio.run(uret())
121
+ return output_file_path