danielspba commited on
Commit
f241c48
·
verified ·
1 Parent(s): ee5ba74

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +155 -0
app.py ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from dotenv import load_dotenv
3
+ from langchain_openai import ChatOpenAI
4
+ from langchain.prompts import PromptTemplate
5
+ from langchain.chains import ConversationChain
6
+ from langchain.memory import ConversationBufferMemory
7
+ import gradio as gr
8
+ import traceback # Import traceback for better error handling
9
+
10
+ # Carrega a chave da API
11
+ load_dotenv()
12
+ api_key = os.getenv("OPENROUTER_API_KEY")
13
+
14
+ if not api_key:
15
+ raise ValueError("❌ Variável OPENROUTER_API_KEY não encontrada.")
16
+
17
+ # Define variáveis do ambiente
18
+ os.environ["OPENAI_API_KEY"] = api_key
19
+ os.environ["OPENAI_API_BASE"] = "https://openrouter.ai/api/v1"
20
+
21
+ # Instancia o modelo
22
+ llm = ChatOpenAI(
23
+ # model="deepseek/deepseek-r1:free", # You can keep this or choose another
24
+ model="mistralai/mistral-7b-instruct:free", # Example using a different free model
25
+ temperature=0.5 # Slightly increased temperature for potentially more varied explanations
26
+ )
27
+
28
+ # --- Lista de Tutores/Matérias ---
29
+ subjects = [
30
+ "Python",
31
+ "Java",
32
+ "Ruby",
33
+ "Golang",
34
+ "C++",
35
+ "C#",
36
+ "Rust",
37
+ "SQL",
38
+ "Tableau",
39
+ "Power BI",
40
+ "Excel",
41
+ "Looker",
42
+ "Solidity"
43
+ ]
44
+
45
+ # --- Template Generalizado ---
46
+ # Now includes {subject} as an input variable
47
+ template_string = """Você é um assistente virtual e tutor especialista em {subject}.
48
+ Ajude os alunos com dúvidas sobre {subject}, sempre de forma clara, objetiva e com exemplos didáticos.
49
+ Adapte a profundidade da sua resposta ao nível aparente da pergunta.
50
+ Se a pergunta for muito vaga, peça mais detalhes.
51
+ Concentre-se estritamente em {subject}, a menos que o aluno peça explicitamente para comparar com outra tecnologia.
52
+
53
+ Histórico da conversa:
54
+ {history}
55
+
56
+ Aluno: {input}
57
+ Resposta:"""
58
+
59
+ template = PromptTemplate(
60
+ input_variables=["history", "input", "subject"], # Added 'subject'
61
+ template=template_string
62
+ )
63
+
64
+ # --- Memória da Conversa (Compartilhada entre tutores por sessão) ---
65
+ # Consider separate memories per subject if long-term context separation is critical,
66
+ # but for a single session, shared memory is simpler.
67
+ memoria = ConversationBufferMemory(return_messages=True)
68
+
69
+ # --- Criação da Chain (O prompt será atualizado dinamicamente) ---
70
+ # Note: We are creating the chain once, but the prompt used *within* the chain
71
+ # will be effectively updated by how we pass the input in the 'responder' function.
72
+ # Alternatively, you could create a new chain object on each call, but that's less efficient.
73
+ chat_chain = ConversationChain(
74
+ llm=llm,
75
+ memory=memoria,
76
+ prompt=template, # Use the template with the 'subject' variable
77
+ verbose=False # Set to True for debugging langchain steps
78
+ )
79
+
80
+ # --- Função para Responder com Contexto do Tutor Selecionado ---
81
+ def responder(subject, user_message):
82
+ """
83
+ Generates a response from the LLM based on the selected subject and user message.
84
+ """
85
+ if not subject:
86
+ return "⚠️ Por favor, selecione uma matéria primeiro."
87
+ if not user_message:
88
+ return "⚠️ Por favor, digite sua dúvida."
89
+
90
+ try:
91
+ # Here we pass the subject along with the input message to the chain.
92
+ # The chain's prompt template expects 'subject' and 'input'.
93
+ response = chat_chain.run(input=user_message, subject=subject)
94
+ return response
95
+ except Exception as e:
96
+ # Log the full error for debugging
97
+ print(f"❌ Erro ao processar a solicitação:\n{traceback.format_exc()}")
98
+ # Return a user-friendly error message
99
+ return f"❌ Desculpe, ocorreu um erro ao processar sua solicitação. Detalhes: {str(e)}"
100
+
101
+ # --- Interface Gradio Atualizada ---
102
+ with gr.Blocks() as app:
103
+ gr.Markdown("# Tutor Poliglota com IA 🤖🎓")
104
+ gr.Markdown("Selecione a matéria e tire suas dúvidas com um assistente que lembra da conversa.")
105
+
106
+ with gr.Row():
107
+ # Dropdown para selecionar a matéria
108
+ subject_selector = gr.Dropdown(
109
+ choices=subjects,
110
+ label="Selecione a Matéria",
111
+ info="Escolha sobre qual linguagem ou ferramenta você quer perguntar."
112
+ )
113
+
114
+ with gr.Row():
115
+ # Textbox para a pergunta do usuário
116
+ input_textbox = gr.Textbox(
117
+ placeholder="Ex: Como declarar uma variável em Java?",
118
+ label="Sua Dúvida",
119
+ lines=3 # Allow more lines for input
120
+ )
121
+
122
+ with gr.Row():
123
+ # Botão para enviar
124
+ submit_button = gr.Button("Perguntar ao Tutor")
125
+
126
+ with gr.Row():
127
+ # Textbox para a resposta do assistente
128
+ output_textbox = gr.Textbox(
129
+ label="Resposta do Tutor",
130
+ lines=8 # Allow more lines for output
131
+ )
132
+
133
+ # Adiciona um botão para limpar a conversa (opcional, mas útil)
134
+ clear_button = gr.ClearButton(
135
+ components=[input_textbox, output_textbox],
136
+ value="Limpar Conversa e Memória"
137
+ )
138
+
139
+ # Define a ação do botão de envio
140
+ submit_button.click(
141
+ fn=responder,
142
+ inputs=[subject_selector, input_textbox], # Passa a matéria e a mensagem
143
+ outputs=output_textbox
144
+ )
145
+
146
+ # Define a ação do botão Limpar para também limpar a memória da chain
147
+ def clear_memory_and_interface():
148
+ memoria.clear() # Limpa a memória da conversa
149
+ return ["", ""] # Retorna valores vazios para limpar os textboxes
150
+
151
+ clear_button.click(fn=clear_memory_and_interface, outputs=[input_textbox, output_textbox])
152
+
153
+
154
+ # Lança a aplicação
155
+ app.launch(share=True)