caarleexx commited on
Commit
102b0ec
·
verified ·
1 Parent(s): 7702d81

Update frontend/app.py

Browse files
Files changed (1) hide show
  1. frontend/app.py +64 -44
frontend/app.py CHANGED
@@ -4,15 +4,10 @@ import chainlit as cl
4
  import httpx
5
  import os
6
 
7
- # URL do nosso backend FastAPI
8
- # Se estiver rodando no Docker, localhost geralmente funciona se usar network host,
9
- # mas em bridge pode precisar do nome do serviço.
10
- # Mantendo localhost conforme seu log de sucesso anterior (200 OK).
11
  API_URL = "http://localhost:8000"
12
  UPLOAD_URL = f"{API_URL}/upload-document"
13
  CHAT_URL = f"{API_URL}/chat"
14
 
15
- # Flag para saber se o RAG está inicializado
16
  RAG_INITIALIZED = False
17
 
18
  @cl.on_chat_start
@@ -20,15 +15,13 @@ async def start():
20
  global RAG_INITIALIZED
21
  RAG_INITIALIZED = False
22
 
23
- # Mensagem de instrução inicial
24
  await cl.Message(
25
- content="Olá! Para começar, por favor, **faça o upload de um arquivo PDF** para eu usar como contexto. Após o upload, poderemos conversar sobre o conteúdo do documento.",
26
  author="Sistema"
27
  ).send()
28
 
29
- # Pede o upload do arquivo
30
  files = await cl.AskFileMessage(
31
- content="Faça o upload do PDF:",
32
  accept=["application/pdf"],
33
  max_size_mb=20,
34
  timeout=180,
@@ -36,47 +29,44 @@ async def start():
36
 
37
  if files:
38
  file = files[0]
39
- # Inicia a mensagem de "Processando"
40
- msg = cl.Message(content=f"Recebido: {file.name}. Processando...", author="Sistema")
41
  await msg.send()
42
 
43
  try:
44
- # 1. Obtendo o MIME Type de forma robusta
45
  mime_type = getattr(file, 'type', 'application/pdf') or 'application/pdf'
46
 
47
- # 2. Lendo o conteúdo do arquivo
48
  with open(file.path, "rb") as f:
49
  file_content = f.read()
50
 
51
- # 3. Criando o payload
52
  files_payload = {
53
  "file": (file.name, file_content, mime_type)
54
  }
55
 
56
- # 4. Envia o arquivo para o backend
57
  async with httpx.AsyncClient(timeout=300) as client:
58
- response = await client.post(
59
- UPLOAD_URL,
60
- files=files_payload
61
- )
62
 
63
- # CORREÇÃO AQUI: Atualiza o atributo content e depois chama update() sem argumentos
64
  if response.status_code == 200:
65
  RAG_INITIALIZED = True
66
- msg.content = f"✅ Documento '{file.name}' processado com sucesso! Agora você pode fazer perguntas sobre o conteúdo do documento."
 
 
 
 
 
 
 
 
 
 
67
  await msg.update()
68
  else:
69
  RAG_INITIALIZED = False
70
  error_detail = response.json().get('detail', 'Erro desconhecido')
71
- msg.content = f"❌ Erro ao processar o arquivo. Código: {response.status_code}. Detalhe: {error_detail}"
72
  await msg.update()
73
 
74
- except httpx.ConnectError:
75
- msg.content = "Erro de conexão: Não foi possível se conectar ao backend. Verifique se ele está rodando."
76
- await msg.update()
77
-
78
  except Exception as e:
79
- msg.content = f"Ocorreu um erro: {e}"
80
  await msg.update()
81
 
82
  @cl.on_message
@@ -85,42 +75,72 @@ async def main(message: cl.Message):
85
 
86
  if not RAG_INITIALIZED:
87
  await cl.Message(
88
- content="Por favor, aguarde o processamento do arquivo ou recarregue a página para um novo upload. Nenhum documento foi processado ainda.",
89
  author="Sistema"
90
  ).send()
91
  return
92
 
93
- # Cria uma mensagem de resposta vazia para preencher com o stream
94
  msg = cl.Message(content="")
95
  await msg.send()
96
 
 
 
 
 
 
 
 
 
 
 
97
  try:
98
  async with httpx.AsyncClient(timeout=60) as client:
99
  async with client.stream("POST", CHAT_URL, json={"content": message.content}) as response:
100
  if response.status_code != 200:
101
- try:
102
- error_text = await response.aread()
103
- error_detail = error_text.decode('utf-8')
104
- except Exception:
105
- error_detail = f"Status Code: {response.status_code}"
106
-
107
- # CORREÇÃO AQUI TAMBÉM
108
- msg.content = f"❌ Erro na comunicação com o serviço de IA. Detalhe: {error_detail}"
109
  await msg.update()
 
 
110
  return
111
 
112
- # Streaming
113
  async for chunk in response.aiter_text():
114
- await msg.stream_token(chunk)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
 
116
- # Finaliza a mensagem (stream_token atualiza automaticamente, update final garante persistência)
117
  await msg.update()
 
 
 
 
 
 
 
 
118
 
119
- except httpx.ConnectError:
120
- msg.content = "Erro de conexão: Não foi possível se conectar ao backend. Verifique se ele está rodando."
121
- await msg.update()
122
  except Exception as e:
123
- msg.content = f"Ocorreu um erro: {e}"
124
  await msg.update()
 
 
125
 
126
  #--- END OF FILE app.py ---
 
4
  import httpx
5
  import os
6
 
 
 
 
 
7
  API_URL = "http://localhost:8000"
8
  UPLOAD_URL = f"{API_URL}/upload-document"
9
  CHAT_URL = f"{API_URL}/chat"
10
 
 
11
  RAG_INITIALIZED = False
12
 
13
  @cl.on_chat_start
 
15
  global RAG_INITIALIZED
16
  RAG_INITIALIZED = False
17
 
 
18
  await cl.Message(
19
+ content="👋 **Bem-vindo ao RAG Llama 3.3!**\n\nPara começar, faça o upload de um PDF. Vou ler o conteúdo e criar uma base de conhecimento para responder suas perguntas.",
20
  author="Sistema"
21
  ).send()
22
 
 
23
  files = await cl.AskFileMessage(
24
+ content="📂 Por favor, envie seu arquivo PDF:",
25
  accept=["application/pdf"],
26
  max_size_mb=20,
27
  timeout=180,
 
29
 
30
  if files:
31
  file = files[0]
32
+ msg = cl.Message(content=f"⏳ Processando '{file.name}'...", author="Sistema")
 
33
  await msg.send()
34
 
35
  try:
 
36
  mime_type = getattr(file, 'type', 'application/pdf') or 'application/pdf'
37
 
 
38
  with open(file.path, "rb") as f:
39
  file_content = f.read()
40
 
 
41
  files_payload = {
42
  "file": (file.name, file_content, mime_type)
43
  }
44
 
 
45
  async with httpx.AsyncClient(timeout=300) as client:
46
+ response = await client.post(UPLOAD_URL, files=files_payload)
 
 
 
47
 
 
48
  if response.status_code == 200:
49
  RAG_INITIALIZED = True
50
+ data = response.json()
51
+ chunks = data.get("total_chunks", "?")
52
+ pages = data.get("total_pages", "?")
53
+
54
+ msg.content = (
55
+ f"✅ **Processamento Concluído!**\n\n"
56
+ f"📄 Arquivo: `{file.name}`\n"
57
+ f"📑 Páginas lidas: {pages}\n"
58
+ f"✂️ Segmentos gerados (Chunks): {chunks}\n\n"
59
+ f"Agora você pode perguntar qualquer coisa sobre o documento!"
60
+ )
61
  await msg.update()
62
  else:
63
  RAG_INITIALIZED = False
64
  error_detail = response.json().get('detail', 'Erro desconhecido')
65
+ msg.content = f"❌ Erro ao processar. Código: {response.status_code}. Detalhe: {error_detail}"
66
  await msg.update()
67
 
 
 
 
 
68
  except Exception as e:
69
+ msg.content = f"Ocorreu um erro crítico: {e}"
70
  await msg.update()
71
 
72
  @cl.on_message
 
75
 
76
  if not RAG_INITIALIZED:
77
  await cl.Message(
78
+ content="⚠️ Nenhum documento carregado. Por favor, recarregue a página para enviar um PDF.",
79
  author="Sistema"
80
  ).send()
81
  return
82
 
83
+ # 1. Cria a mensagem principal
84
  msg = cl.Message(content="")
85
  await msg.send()
86
 
87
+ # 2. Cria o Step de Auditoria (inicialmente rodando)
88
+ audit_step = cl.Step(name="🔎 Processando & Auditoria", type="process")
89
+ audit_step.input = message.content
90
+ await audit_step.send()
91
+
92
+ # Buffer para detectar o separador de debug
93
+ debug_separator = "###__DEBUG__###"
94
+ is_debug_mode = False
95
+ debug_content = ""
96
+
97
  try:
98
  async with httpx.AsyncClient(timeout=60) as client:
99
  async with client.stream("POST", CHAT_URL, json={"content": message.content}) as response:
100
  if response.status_code != 200:
101
+ msg.content = f"❌ Erro na IA: {response.status_code}"
 
 
 
 
 
 
 
102
  await msg.update()
103
+ audit_step.status = "failed"
104
+ await audit_step.update()
105
  return
106
 
 
107
  async for chunk in response.aiter_text():
108
+ # Se já estamos no modo debug, acumulamos apenas no Step
109
+ if is_debug_mode:
110
+ debug_content += chunk
111
+ continue
112
+
113
+ # Verifica se o chunk contém o início do separador
114
+ if debug_separator in chunk:
115
+ parts = chunk.split(debug_separator)
116
+
117
+ # Parte 1: Final da resposta normal
118
+ if parts[0]:
119
+ await msg.stream_token(parts[0])
120
+
121
+ # Ativa modo debug e guarda o resto
122
+ is_debug_mode = True
123
+ if len(parts) > 1:
124
+ debug_content += parts[1]
125
+ else:
126
+ # Fluxo normal de texto para o usuário
127
+ await msg.stream_token(chunk)
128
 
129
+ # Finalização
130
  await msg.update()
131
+
132
+ # Atualiza o Step com o conteúdo de auditoria (Contexto recuperado)
133
+ if debug_content:
134
+ audit_step.output = debug_content
135
+ else:
136
+ audit_step.output = "Nenhum contexto adicional retornado."
137
+
138
+ await audit_step.update()
139
 
 
 
 
140
  except Exception as e:
141
+ msg.content = f" Erro de conexão: {e}"
142
  await msg.update()
143
+ audit_step.status = "failed"
144
+ await audit_step.update()
145
 
146
  #--- END OF FILE app.py ---