File size: 4,789 Bytes
abf48e1
a2661aa
bf993a9
 
2f11e7a
bf993a9
a2661aa
 
 
 
 
bf993a9
 
a2661aa
 
 
 
 
675a523
a2661aa
 
 
675a523
a2661aa
675a523
 
a2661aa
 
 
 
 
 
102b0ec
a2661aa
2f11e7a
5fc0bd7
675a523
 
 
eb22a4b
5fc0bd7
 
 
eb22a4b
 
 
2f11e7a
a2661aa
102b0ec
a2661aa
 
 
102b0ec
 
675a523
102b0ec
 
 
 
 
675a523
102b0ec
abf48e1
a2661aa
 
 
102b0ec
abf48e1
a2661aa
 
102b0ec
abf48e1
cff2509
bf993a9
 
a2661aa
 
 
 
675a523
a2661aa
 
 
 
bf993a9
 
 
102b0ec
 
 
 
 
 
 
 
bf993a9
 
a2661aa
bf993a9
102b0ec
abf48e1
102b0ec
 
bf993a9
 
 
102b0ec
 
 
 
 
 
 
 
 
 
 
 
 
bf993a9
 
102b0ec
 
 
 
 
 
 
bf993a9
 
102b0ec
abf48e1
102b0ec
 
abf48e1
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#--- START OF FILE app.py ---

import chainlit as cl
import httpx
import os 

API_URL = "http://localhost:8000"
UPLOAD_URL = f"{API_URL}/upload-document"
CHAT_URL = f"{API_URL}/chat"

RAG_INITIALIZED = False

@cl.on_chat_start
async def start():
    global RAG_INITIALIZED
    RAG_INITIALIZED = False

    await cl.Message(
        content="👋 **Bem-vindo ao RAG Multi-Formato!**\n\nPara começar, faça o upload de um arquivo. Suporto: **PDF, TXT, Markdown (.md) e Python (.py)**.",
        author="Sistema"
    ).send()

    # MUDANÇA: Lista de extensões aceitas atualizada
    files = await cl.AskFileMessage(
        content="📂 Por favor, envie seu arquivo:",
        accept=[".pdf", ".txt", ".md", ".py"],
        max_size_mb=20,
        timeout=180,
    ).send()

    if files:
        file = files[0]
        msg = cl.Message(content=f"⏳ Processando '{file.name}'...", author="Sistema")
        await msg.send()
        
        try:
            # Pega o MIME type ou define genericamente como octet-stream se falhar, 
            # o backend agora confia mais na extensão do arquivo.
            mime_type = getattr(file, 'type', 'application/octet-stream')
            
            with open(file.path, "rb") as f:
                file_content = f.read()

            files_payload = {
                "file": (file.name, file_content, mime_type)
            }

            async with httpx.AsyncClient(timeout=300) as client:
                response = await client.post(UPLOAD_URL, files=files_payload)
                
                if response.status_code == 200:
                    RAG_INITIALIZED = True
                    data = response.json()
                    chunks = data.get("total_chunks", "?")
                    # Removemos 'total_pages' do destaque principal pois txt/py não tem página
                    
                    msg.content = (
                        f"✅ **Processamento Concluído!**\n\n"
                        f"📄 Arquivo: `{file.name}`\n"
                        f"✂️ Segmentos gerados (Chunks): {chunks}\n\n"
                        f"Base de conhecimento atualizada! Pode perguntar."
                    )
                    await msg.update()
                else:
                    RAG_INITIALIZED = False
                    error_detail = response.json().get('detail', 'Erro desconhecido')
                    msg.content = f"❌ Erro ao processar. Código: {response.status_code}. Detalhe: {error_detail}"
                    await msg.update()

        except Exception as e:
            msg.content = f"❌ Ocorreu um erro crítico: {e}"
            await msg.update()
        
@cl.on_message
async def main(message: cl.Message):
    global RAG_INITIALIZED
    
    if not RAG_INITIALIZED:
        await cl.Message(
            content="⚠️ Nenhum documento carregado. Por favor, recarregue a página para enviar um arquivo.",
            author="Sistema"
        ).send()
        return

    msg = cl.Message(content="")
    await msg.send()

    audit_step = cl.Step(name="🔎 Processando & Auditoria", type="process")
    audit_step.input = message.content
    await audit_step.send()

    debug_separator = "###__DEBUG__###"
    is_debug_mode = False
    debug_content = ""

    try:
        async with httpx.AsyncClient(timeout=60) as client:
            async with client.stream("POST", CHAT_URL, json={"content": message.content}) as response:
                if response.status_code != 200:
                    msg.content = f"❌ Erro na IA: {response.status_code}"
                    await msg.update()
                    audit_step.status = "failed"
                    await audit_step.update()
                    return

                async for chunk in response.aiter_text():
                    if is_debug_mode:
                        debug_content += chunk
                        continue

                    if debug_separator in chunk:
                        parts = chunk.split(debug_separator)
                        if parts[0]:
                            await msg.stream_token(parts[0])
                        is_debug_mode = True
                        if len(parts) > 1:
                            debug_content += parts[1]
                    else:
                        await msg.stream_token(chunk)
        
        await msg.update()
        
        if debug_content:
            audit_step.output = debug_content
        else:
            audit_step.output = "Nenhum contexto adicional retornado."
            
        await audit_step.update()

    except Exception as e:
        msg.content = f"❌ Erro de conexão: {e}"
        await msg.update()
        audit_step.status = "failed"
        await audit_step.update()

#--- END OF FILE app.py ---