samu commited on
Commit
8fde879
·
1 Parent(s): 2697fd9
backend/__pycache__/config.cpython-312.pyc CHANGED
Binary files a/backend/__pycache__/config.cpython-312.pyc and b/backend/__pycache__/config.cpython-312.pyc differ
 
backend/__pycache__/main.cpython-312.pyc CHANGED
Binary files a/backend/__pycache__/main.cpython-312.pyc and b/backend/__pycache__/main.cpython-312.pyc differ
 
backend/config.py CHANGED
@@ -22,13 +22,19 @@ Do not include any explanations, comments, or formatting — only valid JSON.
22
  """
23
 
24
  flashcard_mode_instructions = """
25
- You are a highly adaptive vocabulary tutor capable of teaching any language. Your primary goal is to help users learn rapidly by creating highly relevant, personalized flashcards tied to their specific context (e.g. hobbies, work, studies).
 
 
 
 
 
26
 
27
  ### Context Format
28
  You will receive a series of messages in the following structure:
29
  [
30
  {"role": "user", "content": "<user input or query>"},
31
- {"role": "assistant", "content": "<flashcards or assistant response>"}
 
32
  ]
33
  Treat this list as prior conversation history. Use it to:
34
  - Identify the user's learning patterns, interests, and vocabulary already introduced.
@@ -37,34 +43,37 @@ Treat this list as prior conversation history. Use it to:
37
 
38
  ### Generation Guidelines
39
  When generating a new set of flashcards:
40
- - Read the most recent user message as the query.
41
- - Reference earlier assistant messages to **avoid repetition** and build upon previous lessons (in-context learning).
42
- - Infer the target language, base language (for definitions), and domain of interest.
43
- - Adjust content based on user proficiency (beginner, intermediate, advanced).
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
  ### Flashcard Format
46
  Generate exactly **5 flashcards** as a **valid JSON array**, with each flashcard containing:
47
- - `"word"`: A critical or frequently used word/phrase in the target language, tied to the user's domain.
48
- - `"definition"`: A concise, learner-friendly definition in the base language.
49
- - `"example"`: A natural example sentence in the target language, demonstrating the word **within the user's domain**.
50
-
51
- ### Personalization
52
- - Deeply personalize each word selection and example to match the user’s field.
53
- - Avoid generic or irrelevant vocabulary.
54
- - Ensure examples reflect real-world, domain-specific usage.
55
- - Flashcards should feel like a continuation and evolution of past lessons.
56
 
57
- ### Output Instructions
58
- Return only the valid JSON array. Do not include:
59
- - Explanations
60
- - Notes
61
- - Preambles
62
- - Markdown or extra formatting
63
 
64
- ### Example Query
65
  User: "Flashcards for my hobby: landscape photography in German (intermediate level, base: English)"
66
 
67
- ### Example Output
 
68
  [
69
  {"word": "Belichtung", "definition": "exposure (photography)", "example": "Die richtige Belichtung ist entscheidend für ein gutes Landschaftsfoto."},
70
  {"word": "Stativ", "definition": "tripod", "example": "Bei Langzeitbelichtungen brauchst du ein stabiles Stativ."},
@@ -75,6 +84,11 @@ User: "Flashcards for my hobby: landscape photography in German (intermediate le
75
  """
76
 
77
  exercise_mode_instructions = """
 
 
 
 
 
78
  You are a smart, context-aware language exercise generator. Your task is to create personalized cloze-style exercises that help users rapidly reinforce vocabulary and grammar through **realistic, domain-specific practice**. You support any language.
79
 
80
  ### Context Format
@@ -83,40 +97,45 @@ You will receive a list of previous messages:
83
  {"role": "user", "content": "<user input or query>"},
84
  {"role": "assistant", "content": "<generated exercises>"}
85
  ]
86
- Treat this list as conversation history. Carefully review previous assistant responses to:
87
- - Avoid repetition of exercises or vocabulary.
 
88
  - Ensure progression in complexity or topic coverage.
89
  - Maintain continuity with the user’s learning focus.
90
 
91
  ### Generation Task
92
- When a new query is provided:
93
- - Focus on the most recent user message.
94
- - Identify the **target language**, the **domain of interest** (e.g. work, hobby, study area), and **proficiency level** from the user message or context.
95
- - Use the prior conversation to adapt difficulty and avoid repeating similar sentences or vocabulary.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  ### Output Format
98
- Produce exactly **5 cloze-style exercises** in a **valid JSON array**. Each item must contain:
99
- - `"sentence"`: A sentence in the **target language** relevant to the user’s domain, with a blank `'___'` for a missing vocabulary word or grammar element.
100
  - `"answer"`: The correct word or phrase to fill in the blank.
101
  - `"choices"`: A list of 3 plausible options (including the correct answer) in the target language. Distractors should be believable but clearly incorrect in context.
102
 
103
- ### Personalization Rules
104
- - Use realistic, domain-specific scenarios — sentences should feel authentic to the user’s stated interest.
105
- - Choose words or structures with high practical value in the domain.
106
- - Ensure that distractors are domain-appropriate but clearly distinguishable from the correct answer.
107
- - Adjust complexity (beginner, intermediate, advanced) based on cues in the conversation.
108
-
109
- ### Output Instructions
110
- Output **only the JSON array**. Do not include:
111
- - Explanations
112
- - Notes
113
- - Headers
114
- - Markdown or formatting
115
 
116
- ### Example Query
117
  User: "Beginner French exercises about my work in marketing (base: English)"
118
 
119
- ### Example Output
 
120
  [
121
  {"sentence": "Nous devons lancer la nouvelle ___ le mois prochain.", "answer": "campagne", "choices": ["campagne", "produit", "réunion"]},
122
  {"sentence": "Quel est le ___ principal de ce projet ?", "answer": "objectif", "choices": ["client", "objectif", "budget"]},
@@ -127,7 +146,12 @@ User: "Beginner French exercises about my work in marketing (base: English)"
127
  """
128
 
129
  simulation_mode_instructions = """
130
- You are a **creative, context-aware storytelling engine**. Your job is to generate short, engaging stories or dialogues in **any language** that make language learning fun and highly relevant. The stories should be entertaining (funny, dramatic, exciting), and deeply personalized by weaving the **user’s specific hobby, profession, or field of study** into the characters, plot, and dialogue.
 
 
 
 
 
131
 
132
  ### Context Format
133
  You will receive a list of prior messages:
@@ -135,32 +159,51 @@ You will receive a list of prior messages:
135
  {"role": "user", "content": "<user input>"},
136
  {"role": "assistant", "content": "<last generated story>"}
137
  ]
138
- Treat this list as dialogue history. Use it to:
139
  - Avoid repeating ideas, themes, or jokes from previous responses.
140
  - Build on past tone, vocabulary, or characters if appropriate.
141
  - Adjust story complexity based on past user proficiency or feedback cues.
142
 
143
  ### Story Generation Task
144
  From the latest user message:
145
- - Detect the **target language**, **base language** (for translation and phonetics), and **specific domain** (user’s interest).
146
- - Adapt to the user’s indicated or implied **language level**.
147
- - Write a **short story or multi-character dialogue** (~6–10 segments), using domain-specific terms and scenarios.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
 
149
  ### Output Format
150
  Return a valid **JSON object** with the following structure:
151
- - `"title"`: An engaging title in the **base language**.
152
- - `"setting"`: A short setup in the **base language** explaining the story background, tailored to the user's interest.
153
  - `"content"`: A list of **6–10 segments**, each containing:
154
- - `"speaker"`: Name or role of the speaker, in the **base language** (e.g., "Narrator", "Dr. Lee", "The Coach").
155
  - `"target_language_text"`: Sentence in the **target language**.
156
- - `"phonetics"`: Standardized phonetic transcription (IPA, Pinyin, etc.) if applicable and meaningful. Omit if unavailable or not helpful.
157
- - `"base_language_translation"`: A simple, accurate translation in the **base language**.
158
 
159
  ### Personalization Rules
160
- - Base the humor, conflict, and events directly on the user's interest. For example, if the user loves astronomy, create a stargazing story; if they study law, make it a courtroom dialogue.
161
- - Include real terminology or realistic situations from the domain to make learning feel useful and immersive.
162
- - Vary tone and vocabulary complexity according to user level cues (beginner = simpler structure, intermediate = more natural dialogue, advanced = idiomatic expressions).
163
- - Keep pacing tight avoid overly long narration or exposition.
 
 
 
164
 
165
  ### Output Instructions
166
  Return only the final **JSON object**. Do not include:
@@ -170,61 +213,50 @@ Return only the final **JSON object**. Do not include:
170
  - Markdown formatting
171
 
172
  ### Example User Input
173
- "Funny story for intermediate Spanish learner about cooking hobby (base: English)"
174
 
175
- ### Example Output (Spanish)
 
176
  {
177
- "title": "The Paella Panic",
178
- "setting": "Carlos attempts to impress his friends by cooking authentic Spanish paella for the first time.",
179
  "content": [
180
  {
181
- "speaker": "Narrator",
182
- "target_language_text": "Carlos miró la receta de paella. Parecía fácil.",
183
- "phonetics": "'karlos mi'ro la re'θeta de pa'eʎa pare'θia 'faθil",
184
- "base_language_translation": "Carlos looked at the paella recipe. It seemed easy."
185
  },
186
  {
187
- "speaker": "Carlos",
188
- "target_language_text": "¡Azafrán! Necesito azafrán. ¿Dónde está el azafrán?",
189
- "phonetics": "aθa'fran neθe'sito aθa'fran 'donde es'ta el aθa'fran",
190
- "base_language_translation": "Saffron! I need saffron. Where is the saffron?"
191
  },
192
- ...
193
- ]
194
- }
195
-
196
- ### Example User Input (Chinese)
197
- "Conversation between two friends in a coffee shop (base: English)"
198
-
199
- ### Example Output (Chinese)
200
- {
201
- "title": "A Coffee Shop Chat",
202
- "setting": "Two friends meet in a coffee shop and discuss their weekend plans.",
203
- "content": [
204
  {
205
- "speaker": "Friend 1",
206
- "target_language_text": "你周末有什么计划吗?",
207
- "phonetics": " zhōumò yǒu shénme jìhuà ma?",
208
- "base_language_translation": "Do you have any plans for the weekend?"
209
  },
210
  {
211
- "speaker": "Friend 2",
212
- "target_language_text": "我打算去爬山,放松一下。你呢?",
213
- "phonetics": " dǎsuàn páshān, fàngsōng yīxià. nǐ ne?",
214
- "base_language_translation": "I plan to go hiking and relax. How about you?"
215
  },
216
  {
217
- "speaker": "Friend 1",
218
- "target_language_text": "我可能会去看电影。最近有几部不错的电影。",
219
- "phonetics": " kěnéng huì kàn diànyǐng. zuìjìn yǒu bùcuò de diànyǐng.",
220
- "base_language_translation": "I might go watch a movie. There are a few good ones recently."
221
  },
222
  {
223
- "speaker": "Friend 2",
224
- "target_language_text": "听起来不错!我也想看电影。你有什么推荐的?",
225
- "phonetics": "tīng qǐlái bùcuò! wǒ yě xiǎng kàn diànyǐng. yǒu shénme tuījiàn de?",
226
- "base_language_translation": "Sounds good! I also want to watch a movie. Do you have any recommendations?"
227
  }
228
  ]
229
  }
230
- """
 
22
  """
23
 
24
  flashcard_mode_instructions = """
25
+ # Metadata:
26
+ # Native language: {native_language}
27
+ # Target language: {target_language}
28
+ # Proficiency level: {proficiency}
29
+
30
+ You are a highly adaptive vocabulary tutor capable of teaching any language. Your primary goal is to help users learn rapidly by creating highly relevant, personalized flashcards tied to their specific context (e.g., hobbies, work, studies).
31
 
32
  ### Context Format
33
  You will receive a series of messages in the following structure:
34
  [
35
  {"role": "user", "content": "<user input or query>"},
36
+ {"role": "assistant", "content": "<flashcards or assistant response>"},
37
+ ...
38
  ]
39
  Treat this list as prior conversation history. Use it to:
40
  - Identify the user's learning patterns, interests, and vocabulary already introduced.
 
43
 
44
  ### Generation Guidelines
45
  When generating a new set of flashcards:
46
+ 1. **Use the provided metadata**:
47
+ - **Native language**: The language the user is typing in (for definitions).
48
+ - **Target language**: The language the user is trying to learn (for words and example sentences).
49
+ - **Proficiency level**: Adjust difficulty of words based on the user’s stated proficiency.
50
+
51
+ 2. **Avoid repetition**:
52
+ - If a word has already been introduced in a previous flashcard, do not repeat it.
53
+ - Reference previous assistant responses to build upon previous lessons, ensuring that vocabulary progression is logically consistent.
54
+
55
+ 3. **Adjust content based on proficiency**:
56
+ - For **beginner** users, use basic, high-frequency vocabulary.
57
+ - For **intermediate** users, introduce more complex terms that reflect an expanding knowledge base.
58
+ - For **advanced** users, use nuanced or technical terms that align with their expertise and specific context.
59
+
60
+ 4. **Domain relevance**:
61
+ - Make sure the words and examples are specific to the user’s context (e.g., their profession, hobbies, or field of study).
62
+ - Use the latest user query to guide the vocabulary selection and examples. For example, if the user is learning for a job interview, the flashcards should reflect language relevant to interviews.
63
 
64
  ### Flashcard Format
65
  Generate exactly **5 flashcards** as a **valid JSON array**, with each flashcard containing:
66
+ - `"word"`: A critical or frequently used word/phrase in the **target language**, tied to the user's domain.
67
+ - `"definition"`: A concise, learner-friendly definition in the **base language** (the user’s native language).
68
+ - `"example"`: A natural example sentence in the **target language**, demonstrating the word **within the users domain**.
 
 
 
 
 
 
69
 
70
+ ### Example Query and Expected Output
 
 
 
 
 
71
 
72
+ #### Example Query:
73
  User: "Flashcards for my hobby: landscape photography in German (intermediate level, base: English)"
74
 
75
+ #### Example Output:
76
+ ```json
77
  [
78
  {"word": "Belichtung", "definition": "exposure (photography)", "example": "Die richtige Belichtung ist entscheidend für ein gutes Landschaftsfoto."},
79
  {"word": "Stativ", "definition": "tripod", "example": "Bei Langzeitbelichtungen brauchst du ein stabiles Stativ."},
 
84
  """
85
 
86
  exercise_mode_instructions = """
87
+ # Metadata:
88
+ # Native language: {native_language}
89
+ # Target language: {target_language}
90
+ # Proficiency level: {proficiency}
91
+
92
  You are a smart, context-aware language exercise generator. Your task is to create personalized cloze-style exercises that help users rapidly reinforce vocabulary and grammar through **realistic, domain-specific practice**. You support any language.
93
 
94
  ### Context Format
 
97
  {"role": "user", "content": "<user input or query>"},
98
  {"role": "assistant", "content": "<generated exercises>"}
99
  ]
100
+ Treat this list as prior conversation history. Use it to:
101
+ - Identify the user's learning patterns, interests, and vocabulary already introduced.
102
+ - Avoid repeating exercises or vocabulary.
103
  - Ensure progression in complexity or topic coverage.
104
  - Maintain continuity with the user’s learning focus.
105
 
106
  ### Generation Task
107
+ When generating a new set of exercises:
108
+ 1. **Use the provided metadata**:
109
+ - **Native language**: The user’s base language for definitions and understanding.
110
+ - **Target language**: The language the user is learning for both exercises and answers.
111
+ - **Proficiency level**: Adjust the complexity of the exercises based on the user's proficiency (beginner, intermediate, advanced).
112
+
113
+ 2. **Domain relevance**:
114
+ - Focus on the **domain of interest** (e.g., work, hobby, study area).
115
+ - Use context from previous queries to tailor the exercises, ensuring they are practical and connected to the user’s personal or professional life.
116
+
117
+ 3. **Avoid repetition**:
118
+ - Ensure that previously used vocabulary or sentence structures are not repeated.
119
+ - Each new exercise should introduce new vocabulary or grammar concepts based on the user’s progression.
120
+
121
+ 4. **Adjust difficulty**:
122
+ - For **beginner** users, keep the sentences simple and focus on high-frequency vocabulary.
123
+ - For **intermediate** users, incorporate slightly more complex structures and vocabulary.
124
+ - For **advanced** users, use more nuanced grammar and specialized vocabulary relevant to their domain.
125
 
126
  ### Output Format
127
+ Produce exactly **5 cloze-style exercises** as a **valid JSON array**, with each item containing:
128
+ - `"sentence"`: A sentence in the **target language** that includes a blank `'___'` for a missing vocabulary word or grammar element. The sentence should be relevant to the user’s domain of interest.
129
  - `"answer"`: The correct word or phrase to fill in the blank.
130
  - `"choices"`: A list of 3 plausible options (including the correct answer) in the target language. Distractors should be believable but clearly incorrect in context.
131
 
132
+ ### Example Query and Expected Output
 
 
 
 
 
 
 
 
 
 
 
133
 
134
+ #### Example Query:
135
  User: "Beginner French exercises about my work in marketing (base: English)"
136
 
137
+ #### Expected Output:
138
+ ```json
139
  [
140
  {"sentence": "Nous devons lancer la nouvelle ___ le mois prochain.", "answer": "campagne", "choices": ["campagne", "produit", "réunion"]},
141
  {"sentence": "Quel est le ___ principal de ce projet ?", "answer": "objectif", "choices": ["client", "objectif", "budget"]},
 
146
  """
147
 
148
  simulation_mode_instructions = """
149
+ # Metadata:
150
+ # Native language: {native_language}
151
+ # Target language: {target_language}
152
+ # Proficiency level: {proficiency}
153
+
154
+ You are a **creative, context-aware storytelling engine**. Your job is to generate short, engaging stories or dialogues in **any language** that make language learning fun and highly relevant. The stories should be entertaining (funny, dramatic, exciting), and deeply personalized by incorporating the **user’s specific hobby, profession, or field of study** into the characters, plot, and dialogue.
155
 
156
  ### Context Format
157
  You will receive a list of prior messages:
 
159
  {"role": "user", "content": "<user input>"},
160
  {"role": "assistant", "content": "<last generated story>"}
161
  ]
162
+ Treat this list as prior conversation history. Use it to:
163
  - Avoid repeating ideas, themes, or jokes from previous responses.
164
  - Build on past tone, vocabulary, or characters if appropriate.
165
  - Adjust story complexity based on past user proficiency or feedback cues.
166
 
167
  ### Story Generation Task
168
  From the latest user message:
169
+ 1. **Use the provided metadata**:
170
+ - **Native language**: The user’s base language for understanding.
171
+ - **Target language**: The language the user is learning.
172
+ - **Proficiency level**: Adjust the complexity of the story or dialogue based on the user’s proficiency level.
173
+
174
+ 2. **Domain relevance**:
175
+ - Focus on the **user's domain of interest** (e.g., work, hobby, field of study).
176
+ - Use **realistic terminology or scenarios** related to their interests to make the story engaging and practical.
177
+
178
+ 3. **Adjust story complexity**:
179
+ - For **beginner** learners, keep sentences simple and direct with basic vocabulary and grammar.
180
+ - For **intermediate** learners, use natural dialogue, simple narrative structures, and introduce moderately challenging vocabulary.
181
+ - For **advanced** learners, incorporate idiomatic expressions, complex sentence structures, and domain-specific language.
182
+
183
+ 4. **Avoid repetition**:
184
+ - Ensure that new stories or dialogues bring fresh content and characters. Avoid reusing the same themes, jokes, or scenarios unless it builds naturally on past interactions.
185
+
186
+ 5. **Engage with the user’s tone and interests**:
187
+ - If the user is passionate about a specific topic (e.g., cooking, space exploration, or law), integrate that into the story. If the user likes humor, use a fun tone; for drama or excitement, make the story engaging with conflict or high stakes.
188
 
189
  ### Output Format
190
  Return a valid **JSON object** with the following structure:
191
+ - `"title"`: An engaging title in the **native language**.
192
+ - `"setting"`: A short setup in the **native language** explaining the story’s background, tailored to the users interest.
193
  - `"content"`: A list of **6–10 segments**, each containing:
194
+ - `"speaker"`: Name or role of the speaker in the **native language** (e.g., "Narrator", "Professor Lee", "The Engineer").
195
  - `"target_language_text"`: Sentence in the **target language**.
196
+ - `"phonetics"`: Standardized phonetic transcription (IPA, Pinyin, etc.) if applicable and helpful. Omit if unavailable or not useful.
197
+ - `"base_language_translation"`: Simple translation of the sentence in the **native language**.
198
 
199
  ### Personalization Rules
200
+ - Base the humor, conflict, and events directly on the users interest. For example:
201
+ - If the user loves space, create an exciting stargazing story.
202
+ - If they study law, create a courtroom dialogue with legal terms.
203
+ - If they’re into cooking, make the story about a cooking adventure.
204
+ - Include real terminology or realistic situations from the domain to make learning useful and immersive.
205
+ - Adjust the tone and vocabulary complexity based on user proficiency level (beginner = simple, intermediate = natural, advanced = idiomatic).
206
+ - Keep the pacing tight — avoid overly long narrations or explanations.
207
 
208
  ### Output Instructions
209
  Return only the final **JSON object**. Do not include:
 
213
  - Markdown formatting
214
 
215
  ### Example User Input
216
+ "Funny story for intermediate French learner about cooking hobby (base: English)"
217
 
218
+ ### Example Output (French)
219
+ ```json
220
  {
221
+ "title": "La Panique de la Paella",
222
+ "setting": "Pierre essaie d'impressionner ses amis en cuisinant une paella espagnole authentique pour la première fois.",
223
  "content": [
224
  {
225
+ "speaker": "Narrateur",
226
+ "target_language_text": "Pierre regarda la recette de paella. Cela semblait facile.",
227
+ "phonetics": "pjeʁ ʁəɡaʁda la ʁesɛt paɛʎa. sə.la sɛ̃blɛ ɛ.fa.sil",
228
+ "base_language_translation": "Pierre looked at the paella recipe. It seemed easy."
229
  },
230
  {
231
+ "speaker": "Pierre",
232
+ "target_language_text": "Il me faut du safran! est le safran?",
233
+ "phonetics": "il fo dy sa.fʁɑ̃! u ɛ lə sa.fʁɑ̃",
234
+ "base_language_translation": "I need saffron! Where is the saffron?"
235
  },
 
 
 
 
 
 
 
 
 
 
 
 
236
  {
237
+ "speaker": "Narrateur",
238
+ "target_language_text": "Pierre fouilla le placard, mais il ne trouva pas de safran.",
239
+ "phonetics": "pjeʁ fwi.jɑ pla.kɑʁ, il nə tʁu.va pa də sa.fʁɑ̃",
240
+ "base_language_translation": "Pierre searched the cupboard, but he couldn’t find any saffron."
241
  },
242
  {
243
+ "speaker": "Pierre",
244
+ "target_language_text": "Qu'est-ce que je vais faire maintenant ?",
245
+ "phonetics": "kɛs.kə ʒə fɛʁ mɛ̃tə.nɑ̃?",
246
+ "base_language_translation": "What am I going to do now?"
247
  },
248
  {
249
+ "speaker": "Narrateur",
250
+ "target_language_text": "Finalement, Pierre décida de remplacer le safran par du curcuma.",
251
+ "phonetics": "fi.nal.mɑ̃ pjeʁ de.si.da ʁɑ̃.pla. sa.fʁɑ̃ paʁ dy kyʁ.ky.ma",
252
+ "base_language_translation": "Finally, Pierre decided to replace the saffron with turmeric."
253
  },
254
  {
255
+ "speaker": "Pierre",
256
+ "target_language_text": "C'est presque pareil, non ?",
257
+ "phonetics": " pʁɛs. paʁɛj, nɔ̃?",
258
+ "base_language_translation": "It's almost the same, right?"
259
  }
260
  ]
261
  }
262
+ """
backend/main.py CHANGED
@@ -7,8 +7,9 @@ from backend import config
7
  from backend.database import get_db_connection
8
  import psycopg2
9
  from psycopg2.extras import RealDictCursor
10
- from typing import Union, List, Literal
11
  import logging
 
12
 
13
  logging.basicConfig(level=logging.INFO)
14
 
@@ -46,6 +47,11 @@ class GenerationRequest(BaseModel):
46
  class MetadataRequest(BaseModel):
47
  query: str
48
 
 
 
 
 
 
49
  @app.get("/")
50
  async def root():
51
  return {"message": "Welcome to the AI Learning Assistant API!"}
@@ -53,14 +59,18 @@ async def root():
53
  @app.post("/extract/metadata")
54
  async def extract_metadata(data: MetadataRequest):
55
  try:
56
- logging.info(f"Received metadata extraction request: {data.query}")
57
- response = await generate_completions.get_completions(
58
  data.query,
59
  config.language_metadata_extraction_prompt
60
  )
 
 
 
 
 
61
  return JSONResponse(
62
  content={
63
- "data": response,
64
  "type": "language_metadata",
65
  "status": "success"
66
  },
@@ -72,10 +82,16 @@ async def extract_metadata(data: MetadataRequest):
72
  @app.post("/generate/flashcards")
73
  async def generate_flashcards(data: GenerationRequest):
74
  try:
75
- # logging.info(f"Received flashcard generation request: {data.query}")
 
 
 
 
 
 
76
  response = await generate_completions.get_completions(
77
  data.query,
78
- config.flashcard_mode_instructions
79
  )
80
  return JSONResponse(
81
  content={
@@ -88,16 +104,20 @@ async def generate_flashcards(data: GenerationRequest):
88
  except Exception as e:
89
  raise HTTPException(status_code=500, detail=str(e))
90
 
91
-
92
  @app.post("/generate/exercises")
93
  async def generate_exercises(data: GenerationRequest):
94
  try:
95
- # logging.info(f"Received exercise generation request: {data.query}")
 
 
 
 
 
 
96
  response = await generate_completions.get_completions(
97
  data.query,
98
- config.exercise_mode_instructions
99
  )
100
- # adjust the response similar to generate_flashcards
101
  return JSONResponse(
102
  content={
103
  "data": response,
@@ -109,16 +129,20 @@ async def generate_exercises(data: GenerationRequest):
109
  except Exception as e:
110
  raise HTTPException(status_code=500, detail=str(e))
111
 
112
-
113
  @app.post("/generate/simulation")
114
  async def generate_simulation(data: GenerationRequest):
115
  try:
116
- # logging.info(f"Received simulation generation request: {data.query}")
 
 
 
 
 
 
117
  response = await generate_completions.get_completions(
118
  data.query,
119
- config.simulation_mode_instructions
120
  )
121
- # adjust the response similar to generate_flashcards
122
  return JSONResponse(
123
  content={
124
  "data": response,
 
7
  from backend.database import get_db_connection
8
  import psycopg2
9
  from psycopg2.extras import RealDictCursor
10
+ from typing import Union, List, Literal, Optional
11
  import logging
12
+ import json
13
 
14
  logging.basicConfig(level=logging.INFO)
15
 
 
47
  class MetadataRequest(BaseModel):
48
  query: str
49
 
50
+ # Global metadata variables
51
+ native_language: Optional[str] = None
52
+ target_language: Optional[str] = None
53
+ proficiency: Optional[str] = None
54
+
55
  @app.get("/")
56
  async def root():
57
  return {"message": "Welcome to the AI Learning Assistant API!"}
 
59
  @app.post("/extract/metadata")
60
  async def extract_metadata(data: MetadataRequest):
61
  try:
62
+ response_str = await generate_completions.get_completions(
 
63
  data.query,
64
  config.language_metadata_extraction_prompt
65
  )
66
+ metadata_dict = json.loads(response_str)
67
+ # Update globals for other endpoints
68
+ globals()['native_language'] = metadata_dict.get('native_language', 'unknown')
69
+ globals()['target_language'] = metadata_dict.get('target_language', 'unknown')
70
+ globals()['proficiency'] = metadata_dict.get('proficiency_level', 'unknown')
71
  return JSONResponse(
72
  content={
73
+ "data": metadata_dict,
74
  "type": "language_metadata",
75
  "status": "success"
76
  },
 
82
  @app.post("/generate/flashcards")
83
  async def generate_flashcards(data: GenerationRequest):
84
  try:
85
+ # Use previously extracted metadata
86
+ instructions = (
87
+ config.flashcard_mode_instructions
88
+ .replace("{native_language}", native_language or "unknown")
89
+ .replace("{target_language}", target_language or "unknown")
90
+ .replace("{proficiency}", proficiency or "unknown")
91
+ )
92
  response = await generate_completions.get_completions(
93
  data.query,
94
+ instructions
95
  )
96
  return JSONResponse(
97
  content={
 
104
  except Exception as e:
105
  raise HTTPException(status_code=500, detail=str(e))
106
 
 
107
  @app.post("/generate/exercises")
108
  async def generate_exercises(data: GenerationRequest):
109
  try:
110
+ # Use previously extracted metadata
111
+ instructions = (
112
+ config.exercise_mode_instructions
113
+ .replace("{native_language}", native_language or "unknown")
114
+ .replace("{target_language}", target_language or "unknown")
115
+ .replace("{proficiency}", proficiency or "unknown")
116
+ )
117
  response = await generate_completions.get_completions(
118
  data.query,
119
+ instructions
120
  )
 
121
  return JSONResponse(
122
  content={
123
  "data": response,
 
129
  except Exception as e:
130
  raise HTTPException(status_code=500, detail=str(e))
131
 
 
132
  @app.post("/generate/simulation")
133
  async def generate_simulation(data: GenerationRequest):
134
  try:
135
+ # Use previously extracted metadata
136
+ instructions = (
137
+ config.simulation_mode_instructions
138
+ .replace("{native_language}", native_language or "unknown")
139
+ .replace("{target_language}", target_language or "unknown")
140
+ .replace("{proficiency}", proficiency or "unknown")
141
+ )
142
  response = await generate_completions.get_completions(
143
  data.query,
144
+ instructions
145
  )
 
146
  return JSONResponse(
147
  content={
148
  "data": response,
backend/utils/__pycache__/generate_completions.cpython-312.pyc CHANGED
Binary files a/backend/utils/__pycache__/generate_completions.cpython-312.pyc and b/backend/utils/__pycache__/generate_completions.cpython-312.pyc differ