Spaces:
Sleeping
Sleeping
Commit
·
56aeab4
1
Parent(s):
b6672f0
Correções no novo método de conversão dos textos para .md
Browse files
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
|
13 |
|
14 |
# Importações do LangChain
|
15 |
from langchain.prompts import PromptTemplate
|
16 |
-
from
|
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 |
-
#
|
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: 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)
|
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 =
|
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 =
|
167 |
-
resposta_grok = chain_grok.invoke({"solicitacao_usuario": solicitacao_usuario, "rag_context": rag_context})
|
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 =
|
182 |
-
resposta_sonnet = chain_sonnet.invoke({"solicitacao_usuario": solicitacao_usuario, "texto_para_analise": resposta_grok})
|
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 =
|
196 |
-
resposta_gemini = chain_gemini.invoke({"solicitacao_usuario": solicitacao_usuario, "texto_para_analise": resposta_sonnet})
|
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=
|
227 |
-
chain_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 |
-
})
|
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"
|