diff --git a/src/components/ChatHeader.tsx b/src/components/ChatHeader.tsx index 9c346b3..e17a750 100644 --- a/src/components/ChatHeader.tsx +++ b/src/components/ChatHeader.tsx @@ -1,4 +1,4 @@ -import { ChevronDown, UserCog } from "lucide-react"; +import { ChevronDown, UserCog, Loader2 } from "lucide-react"; import { Button } from "@/components/ui/button"; import { DropdownMenu, @@ -15,7 +15,11 @@ import { DialogTrigger, } from "@/components/ui/dialog"; import { Textarea } from "@/components/ui/textarea"; -import { useState } from "react"; +import { useState, useEffect } from "react"; +import { fetchModelsFromDatabase, ModelConfig } from "@/config/models"; + +// Texto padrão da personalidade (mesmo valor usado em ChatView) +const DEFAULT_SYSTEM_PROMPT = "Você é um assistente útil e prestativo."; interface ChatHeaderProps { showModelSelector?: boolean; @@ -29,25 +33,30 @@ export const ChatHeader = ({ showModelSelector = false, selectedModel = "GPT-4o", onModelChange, - systemPrompt = "Você é um assistente útil e prestativo.", + systemPrompt = DEFAULT_SYSTEM_PROMPT, onSystemPromptChange }: ChatHeaderProps) => { const [isPersonalityOpen, setIsPersonalityOpen] = useState(false); const [tempSystemPrompt, setTempSystemPrompt] = useState(systemPrompt); + const [models, setModels] = useState([]); + const [isLoadingModels, setIsLoadingModels] = useState(true); - const models = [ - "GPT-4.1", - "GPT-4o", - "GPT-5 Mini", - "Gemini 2.0 Flash", - "Claude Sonnet 4.5", - "DeepSeek V3.2 Chat", - "DeepSeek V3.2 Reasoner", - "Gemini 2.5 Flash", - "Gemini 2.5 Flash-Lite", - "Claude Haiku 4.5", - "GPT-4o Mini", - ]; + // Carrega modelos da API ao montar o componente + useEffect(() => { + const loadModels = async () => { + setIsLoadingModels(true); + try { + const modelsFromAPI = await fetchModelsFromDatabase(); + setModels(modelsFromAPI); + } catch (error) { + console.error('Erro ao carregar modelos:', error); + } finally { + setIsLoadingModels(false); + } + }; + + loadModels(); + }, []); const handleSavePersonality = () => { if (onSystemPromptChange) { @@ -67,19 +76,37 @@ export const ChatHeader = ({ {showModelSelector && onModelChange && ( - {models.map((model) => ( - onModelChange(model)} + onClick={() => onModelChange(model.name)} > - {model} +
+ {model.name} + {model.description && ( + {model.description} + )} +
))}
diff --git a/src/components/chat/ChatView.tsx b/src/components/chat/ChatView.tsx index cd973d5..9c0ac7a 100644 --- a/src/components/chat/ChatView.tsx +++ b/src/components/chat/ChatView.tsx @@ -8,6 +8,9 @@ import { chatService, ChatRecord, MessageRecord } from "@/services/chat"; import { useToast } from "@/hooks/use-toast"; import { getModelId } from "@/config/models"; +// Texto padrão da personalidade (usado para novos chats) +const DEFAULT_SYSTEM_PROMPT = "Você é um assistente útil e prestativo."; + interface Message { id: string; role: "user" | "assistant"; @@ -26,7 +29,8 @@ export const ChatView = () => { const [selectedModel, setSelectedModel] = useState("GPT-4o"); // Inicia com "0" - será atualizado com o chat_id real após primeira resposta da API const [currentChatId, setCurrentChatId] = useState("0"); - const [systemPrompt, setSystemPrompt] = useState("Você é um assistente útil e prestativo."); + // Inicia com texto padrão - será atualizado ao carregar chat existente + const [systemPrompt, setSystemPrompt] = useState(DEFAULT_SYSTEM_PROMPT); const [messages, setMessages] = useState([ { id: "1", @@ -74,6 +78,10 @@ export const ChatView = () => { const handleNewChat = () => { // Reseta para "0" - novo chat sempre começa com chat_id "0" setCurrentChatId("0"); + + // Reseta a personalidade para o texto padrão + setSystemPrompt(DEFAULT_SYSTEM_PROMPT); + setMessages([ { id: "1", @@ -91,6 +99,10 @@ export const ChatView = () => { // Carrega um chat existente do banco de dados setCurrentChatId(chat.id); + // Atualiza a personalidade com o valor do banco de dados + // Se não tiver personalidade salva, usa o texto padrão + setSystemPrompt(chat.personalidade || DEFAULT_SYSTEM_PROMPT); + // Limpa mensagens enquanto carrega setMessages([]); setIsLoading(true); @@ -99,14 +111,12 @@ export const ChatView = () => { // Busca mensagens do chat na API const messagesFromAPI = await chatService.getChatMessages(chat.id); - console.log('Mensagens carregadas da API:', messagesFromAPI); - // Converte MessageRecord para Message const loadedMessages: Message[] = messagesFromAPI.map((msg: MessageRecord) => ({ id: msg.id, role: msg.role, content: msg.content, - model: undefined, // model_id vem como número, não temos mapeamento reverso + model: msg.model_name, // Nome do modelo retornado pela API attachments: msg.has_attachments ? [] : undefined, // Não temos detalhes dos anexos no GET })); @@ -236,7 +246,7 @@ export const ChatView = () => { {/* Main Chat Area */}
- { - * const response = await apiService.get('/api/models'); - * return response.data.map((model: any) => ({ - * name: model.name, - * id: model.id.toString(), - * description: model.description || '', - * })); - * } - * - * Nos componentes, usar: - * - useEffect para carregar modelos na montagem - * - useState para armazenar lista de modelos - * - Loading state durante o fetch + * @returns Promise com array de modelos ativos */ +export async function fetchModelsFromDatabase(): Promise { + try { + // Importa dinamicamente para evitar circular dependency + const { apiService } = await import('@/services/api'); + + const response = await apiService.get('/webhook/codex/get_models_ia'); + + console.log('Modelos carregados da API:', response.data); + + // Filtra apenas modelos ativos e converte para ModelConfig + return response.data + .filter(model => model.is_active === 1) + .map((model: ModelIA) => ({ + name: model.name, + id: model.id.toString(), + description: `${model.model_identifier}`, + })); + } catch (error) { + console.error('Erro ao buscar modelos da API:', error); + + // Fallback para modelos hardcoded em caso de erro + console.warn('Usando modelos hardcoded como fallback'); + return AVAILABLE_MODELS; + } +} diff --git a/src/services/chat.ts b/src/services/chat.ts index d3bd50e..5d91e81 100644 --- a/src/services/chat.ts +++ b/src/services/chat.ts @@ -79,6 +79,7 @@ export interface ChatRecord { folder_id: string | null; created_at: string; updated_at: string; + personalidade: string; // Personalidade/prompt do sistema salvo no banco estabelecimento_id: number; } @@ -99,6 +100,7 @@ export interface MessageRecord { role: 'user' | 'assistant'; content: string; model_id: number; + model_name?: string; // Nome do modelo retornado pela API has_attachments: number; input_tokens: number; output_tokens: number;