File size: 5,080 Bytes
d368963
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
137
138
139
140
141
import streamlit as st
import requests
from PIL import Image
import base64

import streamlit as st
import streamlit_authenticator as stauth

import yaml
from yaml.loader import SafeLoader


class ChatbotApp:
    def __init__(self):
        # URL do backend (Flask)
        self.backend_url = "http://localhost:5001/chat"
        self.title = "Chatbot Carômetro"
        self.description = "Este assistente virtual pode te ajudar com informações sobre carômetros da Sicoob."

    def stream_chat(self, user_input):
        """
        Faz a comunicação com o backend e retorna a resposta como streaming de tokens.
        """
        try:
            response = requests.post(
                self.backend_url,
                json={"message": user_input},
                stream=True  # Ativa o streaming
            )
            response.raise_for_status()

            # Gera os tokens conforme chegam no streaming
            for chunk in response.iter_content(chunk_size=512):
                if chunk:
                    yield chunk.decode("utf-8")
        except Exception as e:
            yield f"Erro ao conectar ao servidor: {e}"

    def render_sidebar(self):
        """
        Exibe opções na barra lateral e renderiza a logo do Sicoob.
        """
        st.sidebar.title("Configuração de LLM")
        sidebar_option = st.sidebar.radio("Selecione o LLM", ["gpt-3.5-turbo"])
        if sidebar_option != "gpt-3.5-turbo":
            raise Exception("Opção de LLM inválida!")

        # Exibe a logo do Sicoob na barra lateral
        with open("sicoob-logo.png", "rb") as f:
            data = base64.b64encode(f.read()).decode("utf-8")
            st.sidebar.markdown(
                f"""
                <div style="display:table;margin-top:-80%;margin-left:0%;">
                    <img src="data:image/png;base64,{data}" width="250" height="70">
                </div>
                """,
                unsafe_allow_html=True,
            )

    def render(self):
        """
        Renderiza a interface do chatbot.
        """
        # Configura título, ícone e layout da página
        im = Image.open("pngegg.png")
        st.set_page_config(page_title="Chatbot Carômetro", page_icon=im, layout="wide")

        with open('./config.yaml') as file:
            config = yaml.load(file, Loader=SafeLoader)

        # Pre-hashing all plain text passwords once
        # stauth.Hasher.hash_passwords(config['credentials'])

        authenticator = stauth.Authenticate(
            config['credentials'],
            config['cookie']['name'],
            config['cookie']['key'],
            config['cookie']['expiry_days']
        )

        #try:
        #    authenticator.login()
        #except Exception as e:
        #    st.error(e)
            
        with open('./config.yaml', 'w', encoding='utf-8') as file:
            yaml.dump(config, file, default_flow_style=False)


        authentication_status = authenticator.login()

        if st.session_state["authentication_status"]:
            authenticator.logout('Logout', 'main')

            # Renderiza a barra lateral
            self.render_sidebar()

            # Título e descrição
            st.title(self.title)
            st.write(self.description)

            # Inicializa o histórico na sessão
            if "chat_history" not in st.session_state:
                st.session_state.chat_history = []

            # Renderiza as mensagens do histórico
            for message in st.session_state.chat_history:
                role, text = message.split(":", 1)
                with st.chat_message(role.strip().lower()):
                    st.write(text.strip())

            # Captura o input do usuário
            user_input = st.chat_input("Digite sua pergunta")
            if user_input:
                # Exibe a mensagem do usuário
                with st.chat_message("user"):
                    st.write(user_input)
                st.session_state.chat_history.append(f"user: {user_input}")

                # Placeholder para a resposta do assistente
                with st.chat_message("assistant"):
                    message_placeholder = st.empty()
                    assistant_message = ""

                    # Executa o streaming de tokens enquanto o backend responde
                    for token in self.stream_chat(user_input):
                        assistant_message += token
                        message_placeholder.markdown(assistant_message + "▌")

                    # Atualiza o placeholder com a mensagem final
                    message_placeholder.markdown(assistant_message)
                    st.session_state.chat_history.append(f"assistant: {assistant_message}")
        elif st.session_state["authentication_status"] == False:
            st.error('Username/password is incorrect')
        elif st.session_state["authentication_status"] == None:
            st.warning('Please enter your username and password')

if __name__ == "__main__":
    chatbot_app = ChatbotApp()
    chatbot_app.render()