amauricunha commited on
Commit
48381a8
·
verified ·
1 Parent(s): bc329fa

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +17 -12
app.py CHANGED
@@ -9,6 +9,7 @@ from flask import Flask, request, jsonify, send_file
9
  from gtts import gTTS
10
  from groq import Groq
11
  import google.generativeai as genai
 
12
 
13
  # --- CONFIGURAÇÃO INICIAL ---
14
  app = Flask(__name__)
@@ -45,7 +46,6 @@ except Exception as e:
45
  @app.route('/list-models')
46
  def list_models():
47
  available_models = []
48
- # Lista de modelos Groq para geração de texto foi atualizada.
49
  groq_text_models = [
50
  "llama-3.1-8b-instant",
51
  "llama-3.3-70b-versatile",
@@ -63,7 +63,6 @@ def list_models():
63
  "value": f"gemini:{model_name}",
64
  "name": m.display_name
65
  })
66
-
67
  if groq_client:
68
  for model_id in groq_text_models:
69
  display_name = model_id.split('/')[-1].replace('-instant', '').replace('-versatile', '')
@@ -71,14 +70,12 @@ def list_models():
71
  "value": f"groq:{model_id}",
72
  "name": f"Groq: {display_name}"
73
  })
74
-
75
  except Exception as e:
76
  print(f"Erro ao listar modelos: {e}")
77
  return jsonify([
78
  {"value": "gemini:gemini-2.5-flash-latest", "name": "Gemini 2.5 Flash (Fallback)"},
79
  {"value": "groq:llama-3.1-8b-instant", "name": "Llama 3.1 8B (Fallback)"}
80
  ])
81
-
82
  return jsonify(available_models)
83
 
84
 
@@ -123,13 +120,12 @@ def explain_proxy():
123
  schema = {"type": "object", "properties": {"term": {"type": "string"}, "translation": {"type": "string"}, "context_sentence": {"type": "string"}, "gapped_sentence": {"type": "string"}, "definition": {"type": "string"}}, "required": ["term", "translation", "context_sentence", "gapped_sentence", "definition"]}
124
  prompt = f"Analyze '{word}' in context: '{context}'. Generate a JSON for a flashcard. The 'gapped_sentence' must replace '{word}' with '______________'."
125
  return jsonify(get_ai_text_response(model_provider, model_name, system_instruction_base, prompt, json_schema=schema))
126
-
127
  else:
128
  prompt = f"Analyze '{word}' in context: '{context}'. Provide a one-sentence English explanation, then '---', then the Portuguese translation."
129
  parts = get_ai_text_response(model_provider, model_name, system_instruction_base, prompt).split('---', 1)
130
  return jsonify({"explanation": parts[0].strip(), "translation": parts[1].strip() if len(parts) > 1 else 'N/A'})
131
-
132
  except Exception as e:
 
133
  return jsonify({"error": f"AI analysis failed: {e}"}), 500
134
 
135
  @app.route('/activity-feedback', methods=['POST'])
@@ -141,7 +137,6 @@ def activity_feedback():
141
  user_response = data.get('user_response', '')
142
 
143
  if not original_prompt or not user_response: return jsonify({"error": "Original prompt and user response are required."}), 400
144
-
145
  if (model_provider == 'gemini' and not genai_client) or (model_provider == 'groq' and not groq_client):
146
  return jsonify({"error": f"{model_provider.upper()}_API_KEY not configured."}), 503
147
 
@@ -155,7 +150,6 @@ def activity_feedback():
155
  "Structure your feedback with markdown for clarity (e.g., using ### Corrected Version)."
156
  )
157
  user_prompt = f"The original task was: \"{original_prompt}\"\n\nHere is the user's response:\n---\n{user_response}\n---\nPlease provide your feedback."
158
-
159
  try:
160
  feedback_text = get_ai_text_response(model_provider, model_name, system_instruction, user_prompt)
161
  return jsonify({"feedback": feedback_text})
@@ -179,13 +173,18 @@ def analyze_image():
179
  model = genai_client.GenerativeModel(model_name)
180
  schema = { "type": "object", "properties": { "vocabulary": { "type": "array", "items": { "type": "object", "properties": { "term": {"type": "string"}, "definition": {"type": "string"} }, "required": ["term", "definition"] } } }, "required": ["vocabulary"] }
181
  prompt = [ "Act as an English teacher. Identify 5-7 key objects/concepts in this image. For each, provide its English name and a simple definition. Return a single JSON object conforming to the schema.", image ]
182
- response = model.generate_content(prompt, generation_config={"response_mime_type": "application/json", "response_schema": schema})
 
 
 
 
183
  return jsonify(json.loads(response.text)['vocabulary'])
184
  except Exception as e:
185
  return jsonify({"error": f"Image analysis failed: {e}"}), 500
186
 
187
  @app.route('/chat-with-ai', methods=['POST'])
188
  def chat_with_ai():
 
189
  if not groq_client: return jsonify({"error": "GROQ_API_KEY not configured."}), 503
190
  data = request.get_json()
191
  history, user_message = data.get('history', []), data.get('message', '')
@@ -200,6 +199,7 @@ def chat_with_ai():
200
 
201
  @app.route('/pronunciation-feedback', methods=['POST'])
202
  def pronunciation_feedback():
 
203
  if not groq_client: return jsonify({"error": "GROQ_API_KEY not configured."}), 503
204
  data = request.get_json()
205
  target_text, user_text = data.get('target_text'), data.get('user_text')
@@ -215,6 +215,7 @@ def pronunciation_feedback():
215
 
216
  @app.route('/generate-image', methods=['POST'])
217
  def generate_image():
 
218
  if not genai_client: return jsonify({"error": "GEMINI_API_KEY not configured."}), 503
219
  data = request.get_json()
220
  prompt = data.get('prompt')
@@ -231,9 +232,12 @@ def generate_image():
231
  def get_ai_text_response(provider, model_name, system_instruction, user_prompt, json_schema=None):
232
  if provider == 'gemini':
233
  model = genai_client.GenerativeModel(model_name, system_instruction=system_instruction)
234
- config = {}
 
 
235
  if json_schema:
236
- config = {"response_mime_type": "application/json", "response_schema": json_schema}
 
237
  response = model.generate_content(user_prompt, generation_config=config)
238
 
239
  parsed_json = json.loads(response.text)
@@ -241,9 +245,10 @@ def get_ai_text_response(provider, model_name, system_instruction, user_prompt,
241
  required_keys = json_schema.get("required", [])
242
  if not all(key in parsed_json and parsed_json[key] for key in required_keys):
243
  raise ValueError(f"AI response missing required keys. Required: {required_keys}, Got: {list(parsed_json.keys())}")
244
- return parsed_json
245
 
246
  elif provider == 'groq':
 
247
  final_user_prompt = user_prompt
248
  if json_schema:
249
  final_user_prompt += f"\n\nYou MUST respond with a single JSON object that strictly follows this schema. Do not add any other text before or after the JSON object:\n{json.dumps(json_schema)}"
 
9
  from gtts import gTTS
10
  from groq import Groq
11
  import google.generativeai as genai
12
+ from google.generativeai.types import GenerationConfig
13
 
14
  # --- CONFIGURAÇÃO INICIAL ---
15
  app = Flask(__name__)
 
46
  @app.route('/list-models')
47
  def list_models():
48
  available_models = []
 
49
  groq_text_models = [
50
  "llama-3.1-8b-instant",
51
  "llama-3.3-70b-versatile",
 
63
  "value": f"gemini:{model_name}",
64
  "name": m.display_name
65
  })
 
66
  if groq_client:
67
  for model_id in groq_text_models:
68
  display_name = model_id.split('/')[-1].replace('-instant', '').replace('-versatile', '')
 
70
  "value": f"groq:{model_id}",
71
  "name": f"Groq: {display_name}"
72
  })
 
73
  except Exception as e:
74
  print(f"Erro ao listar modelos: {e}")
75
  return jsonify([
76
  {"value": "gemini:gemini-2.5-flash-latest", "name": "Gemini 2.5 Flash (Fallback)"},
77
  {"value": "groq:llama-3.1-8b-instant", "name": "Llama 3.1 8B (Fallback)"}
78
  ])
 
79
  return jsonify(available_models)
80
 
81
 
 
120
  schema = {"type": "object", "properties": {"term": {"type": "string"}, "translation": {"type": "string"}, "context_sentence": {"type": "string"}, "gapped_sentence": {"type": "string"}, "definition": {"type": "string"}}, "required": ["term", "translation", "context_sentence", "gapped_sentence", "definition"]}
121
  prompt = f"Analyze '{word}' in context: '{context}'. Generate a JSON for a flashcard. The 'gapped_sentence' must replace '{word}' with '______________'."
122
  return jsonify(get_ai_text_response(model_provider, model_name, system_instruction_base, prompt, json_schema=schema))
 
123
  else:
124
  prompt = f"Analyze '{word}' in context: '{context}'. Provide a one-sentence English explanation, then '---', then the Portuguese translation."
125
  parts = get_ai_text_response(model_provider, model_name, system_instruction_base, prompt).split('---', 1)
126
  return jsonify({"explanation": parts[0].strip(), "translation": parts[1].strip() if len(parts) > 1 else 'N/A'})
 
127
  except Exception as e:
128
+ print(f"AI ANALYSIS ERROR in /explain-proxy: {e}")
129
  return jsonify({"error": f"AI analysis failed: {e}"}), 500
130
 
131
  @app.route('/activity-feedback', methods=['POST'])
 
137
  user_response = data.get('user_response', '')
138
 
139
  if not original_prompt or not user_response: return jsonify({"error": "Original prompt and user response are required."}), 400
 
140
  if (model_provider == 'gemini' and not genai_client) or (model_provider == 'groq' and not groq_client):
141
  return jsonify({"error": f"{model_provider.upper()}_API_KEY not configured."}), 503
142
 
 
150
  "Structure your feedback with markdown for clarity (e.g., using ### Corrected Version)."
151
  )
152
  user_prompt = f"The original task was: \"{original_prompt}\"\n\nHere is the user's response:\n---\n{user_response}\n---\nPlease provide your feedback."
 
153
  try:
154
  feedback_text = get_ai_text_response(model_provider, model_name, system_instruction, user_prompt)
155
  return jsonify({"feedback": feedback_text})
 
173
  model = genai_client.GenerativeModel(model_name)
174
  schema = { "type": "object", "properties": { "vocabulary": { "type": "array", "items": { "type": "object", "properties": { "term": {"type": "string"}, "definition": {"type": "string"} }, "required": ["term", "definition"] } } }, "required": ["vocabulary"] }
175
  prompt = [ "Act as an English teacher. Identify 5-7 key objects/concepts in this image. For each, provide its English name and a simple definition. Return a single JSON object conforming to the schema.", image ]
176
+
177
+ # CORREÇÃO: Usa o objeto GenerationConfig
178
+ config = GenerationConfig(response_mime_type="application/json", response_schema=schema)
179
+ response = model.generate_content(prompt, generation_config=config)
180
+
181
  return jsonify(json.loads(response.text)['vocabulary'])
182
  except Exception as e:
183
  return jsonify({"error": f"Image analysis failed: {e}"}), 500
184
 
185
  @app.route('/chat-with-ai', methods=['POST'])
186
  def chat_with_ai():
187
+ # ... (código existente sem alterações) ...
188
  if not groq_client: return jsonify({"error": "GROQ_API_KEY not configured."}), 503
189
  data = request.get_json()
190
  history, user_message = data.get('history', []), data.get('message', '')
 
199
 
200
  @app.route('/pronunciation-feedback', methods=['POST'])
201
  def pronunciation_feedback():
202
+ # ... (código existente sem alterações) ...
203
  if not groq_client: return jsonify({"error": "GROQ_API_KEY not configured."}), 503
204
  data = request.get_json()
205
  target_text, user_text = data.get('target_text'), data.get('user_text')
 
215
 
216
  @app.route('/generate-image', methods=['POST'])
217
  def generate_image():
218
+ # ... (código existente sem alterações) ...
219
  if not genai_client: return jsonify({"error": "GEMINI_API_KEY not configured."}), 503
220
  data = request.get_json()
221
  prompt = data.get('prompt')
 
232
  def get_ai_text_response(provider, model_name, system_instruction, user_prompt, json_schema=None):
233
  if provider == 'gemini':
234
  model = genai_client.GenerativeModel(model_name, system_instruction=system_instruction)
235
+
236
+ # CORREÇÃO: Cria o objeto GenerationConfig a partir do dicionário.
237
+ config = None
238
  if json_schema:
239
+ config = GenerationConfig(response_mime_type="application/json", response_schema=json_schema)
240
+
241
  response = model.generate_content(user_prompt, generation_config=config)
242
 
243
  parsed_json = json.loads(response.text)
 
245
  required_keys = json_schema.get("required", [])
246
  if not all(key in parsed_json and parsed_json[key] for key in required_keys):
247
  raise ValueError(f"AI response missing required keys. Required: {required_keys}, Got: {list(parsed_json.keys())}")
248
+ return parsed_json if json_schema else response.text.strip()
249
 
250
  elif provider == 'groq':
251
+ # ... (código existente sem alterações) ...
252
  final_user_prompt = user_prompt
253
  if json_schema:
254
  final_user_prompt += f"\n\nYou MUST respond with a single JSON object that strictly follows this schema. Do not add any other text before or after the JSON object:\n{json.dumps(json_schema)}"