File size: 6,275 Bytes
b9516fa
a5bb34c
d3813dd
cac680e
 
 
d3813dd
cac680e
 
 
 
d3813dd
 
 
cac680e
 
 
 
 
 
 
 
d3813dd
 
cac680e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d3813dd
cac680e
 
d3813dd
cac680e
 
 
 
 
 
 
 
 
 
 
 
b9516fa
cac680e
d3813dd
 
cac680e
d3813dd
 
 
 
cac680e
b9516fa
 
cac680e
d3813dd
cac680e
 
b9516fa
 
cac680e
 
 
 
 
 
 
 
 
d3813dd
cac680e
b9516fa
 
 
cac680e
d3813dd
b9516fa
d3813dd
cac680e
b9516fa
 
 
 
 
 
cac680e
b9516fa
cac680e
d3813dd
 
 
cac680e
 
 
 
b9516fa
cac680e
 
b9516fa
 
 
 
 
cac680e
 
d3813dd
 
 
 
cac680e
 
 
 
 
 
 
b9516fa
 
cac680e
 
 
 
 
b9516fa
 
 
 
 
 
 
 
 
d3813dd
cac680e
 
b9516fa
d3813dd
cac680e
 
b9516fa
cac680e
b9516fa
 
cac680e
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# Gradio 6.0.2 compatible chatbot application
import gradio as gr
import openai
import os
import json
from threading import Lock
import pkg_resources

# --- Configuração Inicial e Gerenciamento de Memória ---

CHATBOT_MEMORY_FILE = "memory_chatbot.json"
API_MEMORY_FILE = "memory_api.json"
MODEL_NAME = "openai/gpt-oss-120b"
TOGETHER_API_BASE = "https://api.together.xyz/v1"

file_lock = Lock()

def initialize_memory_files():
    with file_lock:
        if not os.path.exists(CHATBOT_MEMORY_FILE):
            with open(CHATBOT_MEMORY_FILE, 'w') as f:
                json.dump([], f)
        if not os.path.exists(API_MEMORY_FILE):
            with open(API_MEMORY_FILE, 'w') as f:
                json.dump([], f)

def load_json(filepath):
    with file_lock:
        try:
            with open(filepath, 'r', encoding='utf-8') as f:
                return json.load(f)
        except (FileNotFoundError, json.JSONDecodeError):
            return []

def save_json(filepath, data):
    with file_lock:
        with open(filepath, 'w', encoding='utf-8') as f:
            json.dump(data, f, indent=4, ensure_ascii=False)

# --- Funções da Aba de Ajuda ---

def get_library_versions():
    """Retorna as versões das bibliotecas principais."""
    try:
        gradio_version = pkg_resources.get_distribution("gradio").version
        openai_version = pkg_resources.get_distribution("openai").version
        return f"""
- **Gradio:** `{gradio_version}`
- **OpenAI:** `{openai_version}`
        """
    except pkg_resources.DistributionNotFound:
        return "Não foi possível obter as versões das bibliotecas."

def load_help_content():
    """Carrega o conteúdo do arquivo help.md."""
    try:
        with open('help.md', 'r', encoding='utf-8') as f:
            return f.read()
    except FileNotFoundError:
        return "Arquivo help.md não encontrado."

# --- Função Principal do Chatbot ---

def get_model_response(user_message, chat_history):
    """Obtém uma resposta da API e gerencia a memória."""
    try:
        client = openai.OpenAI(
            api_key=os.getenv("TOGETHER_API_KEY"),
            base_url=TOGETHER_API_BASE,
        )
    except Exception as e:
        chat_history.append((user_message, f"ERRO: A chave da API não foi encontrada. Verifique o segredo 'TOGETHER_API_KEY' no seu Space. Detalhes: {e}"))
        return chat_history

    messages = [{"role": "system", "content": "Você é um assistente prestativo e detalhista."}]
    for user_msg, assistant_msg in chat_history:
        messages.append({"role": "user", "content": user_msg})
        if assistant_msg: # Evita adicionar respostas nulas
             messages.append({"role": "assistant", "content": assistant_msg})
    messages.append({"role": "user", "content": user_message})

    try:
        chat_completion = client.chat.completions.create(
            messages=messages,
            model=MODEL_NAME,
        )
        assistant_response = chat_completion.choices[0].message.content
    except Exception as e:
        assistant_response = f"Ocorreu um erro ao contatar a API: {e}"

    chat_history.append((user_message, assistant_response))

    save_json(CHATBOT_MEMORY_FILE, chat_history) # A memória do chatbot agora é o próprio histórico
    
    api_memory = load_json(API_MEMORY_FILE)
    api_memory.append({ "request": messages, "response": assistant_response })
    save_json(API_MEMORY_FILE, api_memory)

    return chat_history

# Função wrapper para a interface do chatbot que lida com o estado
def add_text(history, text):
    history = history + [(text, None)]
    return history, ""

# --- Construção da Interface Gradio (Compatível com v6.0.2) ---

with gr.Blocks(title=f"Assistente com {MODEL_NAME}") as demo:
    gr.Markdown(f"# 🤖 Assistente de Chat com {MODEL_NAME}")
    gr.Markdown("Faça uma pergunta e receba uma resposta do modelo hospedado na Together.ai.")

    with gr.Tabs():
        with gr.TabItem("Chatbot"):
            initial_history = load_json(CHATBOT_MEMORY_FILE)
            chatbot_ui = gr.Chatbot(value=initial_history, label="Conversa").style(height=600)
            
            with gr.Row():
                msg_input = gr.Textbox(
                    scale=4,
                    show_label=False,
                    placeholder="Digite sua mensagem e pressione Enter",
                )
                btn_submit = gr.Button("Enviar", variant="primary")

        with gr.TabItem("JSON API Log"):
            gr.Markdown("Exibe o log completo de requisições e respostas para a API.")
            btn_update_api_log = gr.Button("Atualizar")
            json_api_view = gr.JSON(label="Memória da API")

        with gr.TabItem("JSON Chatbot"):
            gr.Markdown("Exibe o histórico de mensagens formatado para a interface do chatbot.")
            btn_update_chatbot = gr.Button("Atualizar")
            json_chatbot_view = gr.JSON(label="Memória do Chatbot")
            
        with gr.TabItem("Help"):
            # Usar um Textbox para exibir o conteúdo do Markdown é mais robusto em versões antigas
            help_display = gr.Markdown(load_help_content())
            gr.Markdown("### Versões das Bibliotecas")
            gr.Markdown(get_library_versions())

    # --- Lógica de Eventos da UI ---
    
    # Ações do Chatbot
    msg_input.submit(add_text, [chatbot_ui, msg_input], [chatbot_ui, msg_input]).then(
        get_model_response, chatbot_ui, chatbot_ui
    )
    btn_submit.click(add_text, [chatbot_ui, msg_input], [chatbot_ui, msg_input]).then(
        get_model_response, chatbot_ui, chatbot_ui
    )

    # Ações dos botões de atualização para as abas JSON
    btn_update_api_log.click(fn=lambda: load_json(API_MEMORY_FILE), inputs=None, outputs=[json_api_view])
    btn_update_chatbot.click(fn=lambda: load_json(CHATBOT_MEMORY_FILE), inputs=None, outputs=[json_chatbot_view])
    
    # Carrega os JSONs quando o aplicativo é iniciado
    demo.load(fn=lambda: load_json(API_MEMORY_FILE), inputs=None, outputs=[json_api_view])
    demo.load(fn=lambda: load_json(CHATBOT_MEMORY_FILE), inputs=None, outputs=[json_chatbot_view])

# Inicializa os arquivos de memória antes de iniciar o app
initialize_memory_files()

# Lança a aplicação
demo.launch()