victorafarias commited on
Commit
56aeab4
·
1 Parent(s): b6672f0

Correções no novo método de conversão dos textos para .md

Browse files
Files changed (1) hide show
  1. app.py +18 -18
app.py CHANGED
@@ -7,13 +7,13 @@ import os
7
  import uuid
8
  import threading
9
  import concurrent.futures
10
- from html import escape
11
  import re
12
- from markdown_it import MarkdownIt # ✅ NOVA IMPORTAÇÃO
13
 
14
  # Importações do LangChain
15
  from langchain.prompts import PromptTemplate
16
- from langchain.chains import LLMChain
17
 
18
  # Importa os LLMs
19
  from llms import claude_llm, grok_llm, gemini_llm
@@ -32,7 +32,7 @@ if not os.path.exists('uploads'):
32
 
33
  app.config['MAX_CONTENT_LENGTH'] = 100 * 1024 * 1024
34
 
35
- # Instancia o novo conversor de Markdown
36
  md = MarkdownIt()
37
 
38
  def is_html_empty(html: str) -> bool:
@@ -42,11 +42,8 @@ def is_html_empty(html: str) -> bool:
42
  """
43
  if not html:
44
  return True
45
- # 1. Remove todas as tags do HTML
46
  text_only = re.sub('<[^<]+?>', '', html)
47
- # 2. Decodifica entidades HTML (ex: &nbsp; para ' ')
48
  decoded_text = unescape(text_only)
49
- # 3. Verifica se o texto restante está de fato vazio
50
  return not decoded_text.strip()
51
 
52
  @app.route('/')
@@ -91,6 +88,8 @@ def process():
91
  yield f"data: {json.dumps({'progress': 0, 'message': 'Processando arquivos e extraindo contexto...'})}\n\n"
92
  rag_context = get_relevant_context(file_paths, solicitacao_usuario)
93
 
 
 
94
  if processing_mode == 'atomic':
95
  # --- LÓGICA ATÔMICA (PARALELA) ---
96
  results = {}
@@ -98,7 +97,7 @@ def process():
98
 
99
  def run_chain_with_timeout(chain, inputs, key, timeout=300):
100
  def task():
101
- return chain.invoke(inputs)['text']
102
 
103
  with concurrent.futures.ThreadPoolExecutor() as executor:
104
  future = executor.submit(task)
@@ -120,7 +119,7 @@ def process():
120
  yield f"data: {json.dumps({'progress': 15, 'message': 'Iniciando processamento paralelo...'})}\n\n"
121
 
122
  for name, llm in models.items():
123
- chain = LLMChain(llm=llm, prompt=prompt)
124
  thread = threading.Thread(target=run_chain_with_timeout, args=(chain, {"solicitacao_usuario": solicitacao_usuario, "rag_context": rag_context}, name))
125
  threads.append(thread)
126
  thread.start()
@@ -163,8 +162,8 @@ def process():
163
  # --- LÓGICA HIERÁRQUICA (SEQUENCIAL) ---
164
  yield f"data: {json.dumps({'progress': 15, 'message': 'O GROK está processando sua solicitação...'})}\n\n"
165
  prompt_grok = PromptTemplate(template=PROMPT_HIERARQUICO_GROK, input_variables=["solicitacao_usuario", "rag_context"])
166
- chain_grok = LLMChain(llm=grok_llm, prompt=prompt_grok)
167
- resposta_grok = chain_grok.invoke({"solicitacao_usuario": solicitacao_usuario, "rag_context": rag_context})['text']
168
 
169
  if not resposta_grok or not resposta_grok.strip():
170
  yield f"data: {json.dumps({'error': 'Falha no serviço GROK: Sem resposta.'})}\n\n"
@@ -178,8 +177,8 @@ def process():
178
 
179
  prompt_sonnet = PromptTemplate(template=PROMPT_HIERARQUICO_SONNET, input_variables=["solicitacao_usuario", "texto_para_analise"])
180
  claude_with_max_tokens = claude_llm.bind(max_tokens=20000)
181
- chain_sonnet = LLMChain(llm=claude_with_max_tokens, prompt=prompt_sonnet)
182
- resposta_sonnet = chain_sonnet.invoke({"solicitacao_usuario": solicitacao_usuario, "texto_para_analise": resposta_grok})['text']
183
 
184
  if not resposta_sonnet or not resposta_sonnet.strip():
185
  yield f"data: {json.dumps({'error': 'Falha no serviço Claude Sonnet: Sem resposta.'})}\n\n"
@@ -192,8 +191,8 @@ def process():
192
  yield f"data: {json.dumps({'progress': 66, 'message': 'Gemini está processando...', 'partial_result': {'id': 'sonnet-output', 'content': sonnet_html}})}\n\n"
193
 
194
  prompt_gemini = PromptTemplate(template=PROMPT_HIERARQUICO_GEMINI, input_variables=["solicitacao_usuario", "texto_para_analise"])
195
- chain_gemini = LLMChain(llm=gemini_llm, prompt=prompt_gemini)
196
- resposta_gemini = chain_gemini.invoke({"solicitacao_usuario": solicitacao_usuario, "texto_para_analise": resposta_sonnet})['text']
197
 
198
  if not resposta_gemini or not resposta_gemini.strip():
199
  yield f"data: {json.dumps({'error': 'Falha no serviço Gemini: Sem resposta.'})}\n\n"
@@ -221,10 +220,11 @@ def merge():
221
  try:
222
  yield f"data: {json.dumps({'progress': 0, 'message': 'Iniciando o processo de merge...'})}\n\n"
223
 
 
224
  prompt_merge = PromptTemplate(template=PROMPT_ATOMICO_MERGE, input_variables=["solicitacao_usuario", "texto_para_analise_grok", "texto_para_analise_sonnet", "texto_para_analise_gemini"])
225
 
226
- grok_with_max_tokens = grok_llm.bind(max_tokens=100000)
227
- chain_merge = LLMChain(llm=grok_with_max_tokens, prompt=prompt_merge)
228
 
229
  yield f"data: {json.dumps({'progress': 50, 'message': 'Enviando textos para o GROK para consolidação...'})}\n\n"
230
 
@@ -233,7 +233,7 @@ def merge():
233
  "texto_para_analise_grok": data.get('grok_text'),
234
  "texto_para_analise_sonnet": data.get('sonnet_text'),
235
  "texto_para_analise_gemini": data.get('gemini_text')
236
- })['text']
237
 
238
  if not resposta_merge or not resposta_merge.strip():
239
  yield f"data: {json.dumps({'error': 'Falha no serviço de Merge (GROK): Sem resposta.'})}\n\n"
 
7
  import uuid
8
  import threading
9
  import concurrent.futures
10
+ from html import escape, unescape
11
  import re
12
+ from markdown_it import MarkdownIt
13
 
14
  # Importações do LangChain
15
  from langchain.prompts import PromptTemplate
16
+ from langchain_core.output_parsers import StrOutputParser
17
 
18
  # Importa os LLMs
19
  from llms import claude_llm, grok_llm, gemini_llm
 
32
 
33
  app.config['MAX_CONTENT_LENGTH'] = 100 * 1024 * 1024
34
 
35
+ # Instancia o conversor de Markdown
36
  md = MarkdownIt()
37
 
38
  def is_html_empty(html: str) -> bool:
 
42
  """
43
  if not html:
44
  return True
 
45
  text_only = re.sub('<[^<]+?>', '', html)
 
46
  decoded_text = unescape(text_only)
 
47
  return not decoded_text.strip()
48
 
49
  @app.route('/')
 
88
  yield f"data: {json.dumps({'progress': 0, 'message': 'Processando arquivos e extraindo contexto...'})}\n\n"
89
  rag_context = get_relevant_context(file_paths, solicitacao_usuario)
90
 
91
+ output_parser = StrOutputParser()
92
+
93
  if processing_mode == 'atomic':
94
  # --- LÓGICA ATÔMICA (PARALELA) ---
95
  results = {}
 
97
 
98
  def run_chain_with_timeout(chain, inputs, key, timeout=300):
99
  def task():
100
+ return chain.invoke(inputs)
101
 
102
  with concurrent.futures.ThreadPoolExecutor() as executor:
103
  future = executor.submit(task)
 
119
  yield f"data: {json.dumps({'progress': 15, 'message': 'Iniciando processamento paralelo...'})}\n\n"
120
 
121
  for name, llm in models.items():
122
+ chain = prompt | llm | output_parser
123
  thread = threading.Thread(target=run_chain_with_timeout, args=(chain, {"solicitacao_usuario": solicitacao_usuario, "rag_context": rag_context}, name))
124
  threads.append(thread)
125
  thread.start()
 
162
  # --- LÓGICA HIERÁRQUICA (SEQUENCIAL) ---
163
  yield f"data: {json.dumps({'progress': 15, 'message': 'O GROK está processando sua solicitação...'})}\n\n"
164
  prompt_grok = PromptTemplate(template=PROMPT_HIERARQUICO_GROK, input_variables=["solicitacao_usuario", "rag_context"])
165
+ chain_grok = prompt_grok | grok_llm | output_parser
166
+ resposta_grok = chain_grok.invoke({"solicitacao_usuario": solicitacao_usuario, "rag_context": rag_context})
167
 
168
  if not resposta_grok or not resposta_grok.strip():
169
  yield f"data: {json.dumps({'error': 'Falha no serviço GROK: Sem resposta.'})}\n\n"
 
177
 
178
  prompt_sonnet = PromptTemplate(template=PROMPT_HIERARQUICO_SONNET, input_variables=["solicitacao_usuario", "texto_para_analise"])
179
  claude_with_max_tokens = claude_llm.bind(max_tokens=20000)
180
+ chain_sonnet = prompt_sonnet | claude_with_max_tokens | output_parser
181
+ resposta_sonnet = chain_sonnet.invoke({"solicitacao_usuario": solicitacao_usuario, "texto_para_analise": resposta_grok})
182
 
183
  if not resposta_sonnet or not resposta_sonnet.strip():
184
  yield f"data: {json.dumps({'error': 'Falha no serviço Claude Sonnet: Sem resposta.'})}\n\n"
 
191
  yield f"data: {json.dumps({'progress': 66, 'message': 'Gemini está processando...', 'partial_result': {'id': 'sonnet-output', 'content': sonnet_html}})}\n\n"
192
 
193
  prompt_gemini = PromptTemplate(template=PROMPT_HIERARQUICO_GEMINI, input_variables=["solicitacao_usuario", "texto_para_analise"])
194
+ chain_gemini = prompt_gemini | gemini_llm | output_parser
195
+ resposta_gemini = chain_gemini.invoke({"solicitacao_usuario": solicitacao_usuario, "texto_para_analise": resposta_sonnet})
196
 
197
  if not resposta_gemini or not resposta_gemini.strip():
198
  yield f"data: {json.dumps({'error': 'Falha no serviço Gemini: Sem resposta.'})}\n\n"
 
220
  try:
221
  yield f"data: {json.dumps({'progress': 0, 'message': 'Iniciando o processo de merge...'})}\n\n"
222
 
223
+ output_parser = StrOutputParser()
224
  prompt_merge = PromptTemplate(template=PROMPT_ATOMICO_MERGE, input_variables=["solicitacao_usuario", "texto_para_analise_grok", "texto_para_analise_sonnet", "texto_para_analise_gemini"])
225
 
226
+ grok_with_max_tokens = grok_llm.bind(max_tokens=20000)
227
+ chain_merge = prompt_merge | grok_with_max_tokens | output_parser
228
 
229
  yield f"data: {json.dumps({'progress': 50, 'message': 'Enviando textos para o GROK para consolidação...'})}\n\n"
230
 
 
233
  "texto_para_analise_grok": data.get('grok_text'),
234
  "texto_para_analise_sonnet": data.get('sonnet_text'),
235
  "texto_para_analise_gemini": data.get('gemini_text')
236
+ })
237
 
238
  if not resposta_merge or not resposta_merge.strip():
239
  yield f"data: {json.dumps({'error': 'Falha no serviço de Merge (GROK): Sem resposta.'})}\n\n"