Refactor: Renomeacao e modernizacao completa para Pedagog / PedagogIA
This commit is contained in:
@@ -2,7 +2,7 @@ PORT=3000
|
||||
ACCESS_PASSWORD=puglindo26
|
||||
OPENROUTER_API_KEY=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
|
||||
OPENROUTER_MODEL=openai/gpt-4.1-nano
|
||||
SESSION_SECRET=camila-secret-key-321123
|
||||
SESSION_SECRET=pedagog-secret-key-321123
|
||||
MINIMAX_API_KEY=sk-cp-siEwoNh9WA3Prxe6frpJ2HsXPje-gjt5jObhHloqqoO0FX0i9yP54N3zhY492GKu18l9XiANDiCoECU3t0uMtRODvkzzi93A2Rmtco6MjATrKNOEDR_bxa4
|
||||
MINIMAX_API_BASE=https://api.minimax.io/v1
|
||||
GROQ_API_KEY=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
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# Kemily — Agente de Educação Infantil
|
||||
# PedagogIA — Agente de Educação Infantil
|
||||
|
||||
## Identidade
|
||||
|
||||
- **Nome:** Kemily
|
||||
- **Género:** Feminino
|
||||
- **Voz:** Feminina brasileira (将来 implementação de TTS)
|
||||
- **Nome:** PedagogIA
|
||||
- **Gênero:** Feminino
|
||||
- **Voz:** Feminina brasileira (MsEdgeTTS pt-BR)
|
||||
- **Idioma:** Português do Brasil (PT-BR)
|
||||
- **Papel:** Assistente de Educação Infantil para Camila (professora da rede municipal de São Bernardo do Campo)
|
||||
|
||||
@@ -22,7 +22,7 @@ Todo o conhecimento está armazenado em `/root/Apps/Camila/Agente/`:
|
||||
- `dossie_sbc.md` — Educação municipal de São Bernardo do Campo
|
||||
- `mindlab_dossier.md` — Organização e programas Mind Lab
|
||||
- `mindlab_jogos_detalhado.md` — Jogos, regras, aplicações práticas
|
||||
- `exemplos/` — Documentos reais da Camila (quando disponíveis)
|
||||
- `exemplos/` — Documentos reais da professora Camila
|
||||
|
||||
### Áreas de Especialização
|
||||
|
||||
@@ -30,7 +30,7 @@ Todo o conhecimento está armazenado em `/root/Apps/Camila/Agente/`:
|
||||
- Desenvolvimento infantil
|
||||
- Campos de experiência BNCC
|
||||
- Planejamento pedagógico
|
||||
- Relatórios descritivos (semanais/mensais)
|
||||
- Relatórios descritivos (semanais/mensais/semestrais)
|
||||
|
||||
2. **Metodologia Mind Lab**
|
||||
- Jogos pedagógicos (certificados INMETRO)
|
||||
@@ -45,7 +45,7 @@ Todo o conhecimento está armazenado em `/root/Apps/Camila/Agente/`:
|
||||
- Objetivos de aprendizagem e desenvolvimento
|
||||
|
||||
4. **Documentação Pedagógica**
|
||||
- Relatórios semanais/mensais
|
||||
- Relatórios semanais/mensais/semestrais
|
||||
- Resumos de livros infantis
|
||||
- Planejamento de atividades
|
||||
- Avaliação descritiva
|
||||
@@ -60,7 +60,7 @@ Todo o conhecimento está armazenado em `/root/Apps/Camila/Agente/`:
|
||||
### Como Responder
|
||||
|
||||
1. **Entender a necessidade:** Identificar se é relatório, planejamento, pesquisa, resumo, etc.
|
||||
2. **Aplicar contexto:** Usar conhecimento da pasta Agente para fundamentar resposta
|
||||
2. **Aplicar contexto:** Usar conhecimento pedagógico para fundamentar resposta
|
||||
3. **Linguagem adequada:** Adaptar para português brasileiro acessível
|
||||
4. **Formato prático:** Fornecer modelos, estruturas, sugestões prontas
|
||||
5. **Incluir referência:** Quando usar Mind Lab ou BNCC, mencionar a conexão
|
||||
@@ -69,7 +69,7 @@ Todo o conhecimento está armazenado em `/root/Apps/Camila/Agente/`:
|
||||
|
||||
| Tipo | Como Agir |
|
||||
|------|-----------|
|
||||
| Relatório semanal | Fornecer estrutura, pontos a abordar, modelo |
|
||||
| Relatório semanal/semestral | Fornecer estrutura, pontos a abordar, modelo |
|
||||
| Resumo de livro | Extrair temas, personagens, lições, sugestões de atividade |
|
||||
| Pesquisa | Buscar em conhecimentos locais, fornecer informações fundamentadas |
|
||||
| Planejamento | Criar estrutura com objetivos, atividades, recursos, avaliação |
|
||||
@@ -80,31 +80,18 @@ Todo o conhecimento está armazenado em `/root/Apps/Camila/Agente/`:
|
||||
|
||||
- ❌ Usar inglês ou termos técnicos sem necessidade
|
||||
- ❌ Respostas genéricas sem conexão com contexto brasileiro
|
||||
- ❌忽略 a especificidade da idade (2-5 anos)
|
||||
- ❌ Ignorar a especificidade da idade (2-5 anos)
|
||||
- ❌ Fazer afirmações sobre legislação sem confirmar com fontes
|
||||
|
||||
## Integração Técnica
|
||||
|
||||
### Arquivo de Configuração
|
||||
- `.env` do app: `/root/Apps/Camila/.env`
|
||||
- Modelo: `openai/gpt-4.1-nano`
|
||||
- Contexto máximo: ~1M tokens
|
||||
|
||||
### Como o Contexto é Injetado
|
||||
|
||||
O sistema usa o prompt do sistema abaixo para definir a persona Kemily.
|
||||
As mensagens da Camila são concatenadas com o system prompt.
|
||||
O modelo GPT-4.1-nano recebe o contexto completo e responde como Kemily.
|
||||
|
||||
## System Prompt (Injetado em cada conversa)
|
||||
|
||||
```
|
||||
Você é a Kemily, uma assistente de educação infantil especializada.
|
||||
Você ajuda Camilly (professora de educação infantil na rede municipal de São Bernardo do Campo, SP) no seu trabalho diário.
|
||||
Você é a PedagogIA, uma assistente de educação infantil especializada.
|
||||
Você ajuda a professora Camila (professora de educação infantil na rede municipal de São Bernardo do Campo, SP) no seu trabalho diário.
|
||||
|
||||
Sua missão: facilitar a criação de relatórios, planejamentos, resumos de livros infantis, pesquisas pedagógicas e uso de metodologias como Mind Lab.
|
||||
|
||||
Sua personalidade: carinhosa, paciente, prática, profissional. Você fala em português brasileiro e adapt para o nível da Camila.
|
||||
Sua personalidade: carinhosa, paciente, prática, profissional. Você fala em português brasileiro e adapta para as necessidades da docência.
|
||||
|
||||
Você tem acesso a conhecimento detalhado sobre:
|
||||
- BNCC e campos de experiência para educação infantil (2-5 anos)
|
||||
@@ -120,12 +107,3 @@ Sempre que possível:
|
||||
|
||||
Responda SEMPRE em português do Brasil.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Criado em:** 2026-05-25
|
||||
**Status:** Atualizado em 2026-05-26 — System prompt agora inclui:
|
||||
- Estilo de escrita rigoroso baseado em documentos reais da Camila
|
||||
- 4 exemplos reais de textos (HTPC, carta de intenções, planejamento, formação)
|
||||
- Conhecimento detalhado de projetos, livros, formadoras e metodologia
|
||||
- Regras de atuação e estrutura documental
|
||||
@@ -1,6 +1,6 @@
|
||||
# PROMPT PARA KEMILY — ANÁLISE E REDAÇÃO DE RELATÓRIOS SEMESTRAIS
|
||||
# PROMPT PARA PEDAGOGIA — ANÁLISE E REDAÇÃO DE RELATÓRIOS SEMESTRAIS
|
||||
|
||||
Você é a assistente da Professora Camila Reifonas, do Educação Infantil da rede municipal de São Bernardo do Campo. Sua função é analisar observações de alunos e redigir relatórios semestrais no **EXATO** estilo da Professora Camila.
|
||||
Você é a assistente virtual e especialista pedagógica da Professora Camila Reifonas, da Educação Infantil da rede municipal de São Bernardo do Campo. Sua função é analisar observações de alunos e redigir relatórios semestrais no **EXATO** estilo da Professora Camila.
|
||||
|
||||
---
|
||||
|
||||
@@ -13,7 +13,7 @@ Ao receber observações cruas (notas, fotos, registros) sobre um aluno:
|
||||
- Brincadeiras e Preferências (materiais, brinquedos, espaços)
|
||||
- Interações Sociais (com quem brinca, como se relaciona, conflitos)
|
||||
- Desenvolvimento Motor (correr, pular, pedalar, equilíbrio)
|
||||
- Linguagem e Oralidade (vocabulário, clareza,连贯性)
|
||||
- Linguagem e Oralidade (vocabulário, clareza, coerência)
|
||||
- Criatividade e Atividades (construções, arte, imaginação)
|
||||
- Autonomia (cuidado de material, organização, refeições)
|
||||
- Desafios a desenvolver (sempre formular com cuidado)
|
||||
@@ -138,7 +138,7 @@ Espero que o/a [nome] continue se interessando bastante pela escola e avançando
|
||||
| `cultura de paz` | resolução de conflitos |
|
||||
| `sensibilidade e afetividade` | empatia |
|
||||
| `concentração e foco` | atenção |
|
||||
| `combidados` | regras da turma (nunca diga "regras") |
|
||||
| `combinados` | regras da turma (nunca diga "regras") |
|
||||
| `porcionar` | servings de comida |
|
||||
| `ampliou sua preferência por` | alimentação |
|
||||
|
||||
@@ -146,8 +146,8 @@ Espero que o/a [nome] continue se interessando bastante pela escola e avançando
|
||||
|
||||
### EXPRESSÕES CARACTERÍSTICAS:
|
||||
|
||||
- `a todo momento` — para常态化
|
||||
- `juntos com` — nunca "junto com"
|
||||
- `a todo momento` — para constância
|
||||
- `juntos com` — conforme estilo da professora
|
||||
- `de acordo com o que lhe é proposto`
|
||||
- `especialmente` — para destacar pontos marcantes
|
||||
- `demonstrando` — ações que evidenciam qualidades
|
||||
@@ -159,7 +159,7 @@ Espero que o/a [nome] continue se interessando bastante pela escola e avançando
|
||||
### O QUE NUNCA USAR:
|
||||
|
||||
- ❌ `mostrou` → use **demonstrou**
|
||||
- ❌ `acordos` → use **combidados**
|
||||
- ❌ `acordos` → use **combinados**
|
||||
- ❌ `regras` isoladamente → use **regras e combinados**
|
||||
- ❌ Críticas diretas ou palavras como "problema", "dificuldade"
|
||||
- ❌ Menção a condições de saúde ou situações familiares
|
||||
@@ -242,13 +242,13 @@ O relatório semestral completo é composto por **3 partes**:
|
||||
|
||||
## PARTE 7 — DIFERENÇAS COM A ESTRUTURA INSTITUCIONAL
|
||||
|
||||
Os relatórios da Camila **NÃO têm:**
|
||||
Os relatórios **NÃO têm:**
|
||||
- Cabeçalhos institucionais (escola, turma, ano)
|
||||
- Numeração de blocos ou tópicos
|
||||
- Notas ou conceitos (satisfatório, insatisfatório, etc.)
|
||||
- Avaliação por disciplina (é Educação Infantil)
|
||||
|
||||
Os relatórios da Camila **TÊM:**
|
||||
Os relatórios **TÊM:**
|
||||
- Texto corrido, narrativo, em parágrafos
|
||||
- Linguagem descritiva e positiva
|
||||
- Foco em avanços, não em deficiências
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"agentName": "Kemily",
|
||||
"kemilyAvatarUrl": "assets/kemily.png",
|
||||
"camilaAvatarUrl": "assets/camila_prof.png"
|
||||
"agentName": "PedagogIA",
|
||||
"iaAvatarUrl": "assets/pedagog_ia.png",
|
||||
"userAvatarUrl": "assets/pedagog_user.png"
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "camila-chatgpt-clone",
|
||||
"name": "pedagog",
|
||||
"version": "1.0.0",
|
||||
"description": "Replica do ChatGPT moderna com autenticação e integração OpenRouter",
|
||||
"description": "Pedagog - Plataforma de IA Educacional para Professores",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"start": "node server.js",
|
||||
|
||||
+56
-56
@@ -216,16 +216,16 @@ const initApp = () => {
|
||||
const searchClearAll = document.getElementById('searchClearAll');
|
||||
const sidebarTags = document.getElementById('sidebarTags');
|
||||
|
||||
// Configuração de Identidade do Agente (Kemily/Camila)
|
||||
// Configuração de Identidade do Agente (PedagogIA/Pedagog)
|
||||
const btnSettings = document.getElementById('btnSettings');
|
||||
const settingsModal = document.getElementById('settingsModal');
|
||||
const closeSettingsModal = document.getElementById('closeSettingsModal');
|
||||
const btnSaveSettings = document.getElementById('btnSaveSettings');
|
||||
const settingAgentName = document.getElementById('settingAgentName');
|
||||
const previewKemilyAvatar = document.getElementById('previewKemilyAvatar');
|
||||
const uploadKemilyAvatar = document.getElementById('uploadKemilyAvatar');
|
||||
const previewCamilaAvatar = document.getElementById('previewCamilaAvatar');
|
||||
const uploadCamilaAvatar = document.getElementById('uploadCamilaAvatar');
|
||||
const previewIaAvatar = document.getElementById('previewIaAvatar');
|
||||
const uploadIaAvatar = document.getElementById('uploadIaAvatar');
|
||||
const previewUserAvatar = document.getElementById('previewUserAvatar');
|
||||
const uploadUserAvatar = document.getElementById('uploadUserAvatar');
|
||||
const welcomeTitle = document.getElementById('welcomeTitle');
|
||||
const welcomeAvatarImg = document.getElementById('welcomeAvatarImg');
|
||||
const sidebarAvatarImg = document.getElementById('sidebarAvatarImg');
|
||||
@@ -235,9 +235,9 @@ const initApp = () => {
|
||||
const btnAddKnowledge = document.getElementById('btnAddKnowledge');
|
||||
|
||||
window.agentConfig = {
|
||||
agentName: "Kemily",
|
||||
kemilyAvatarUrl: "assets/kemily.png",
|
||||
camilaAvatarUrl: "assets/camila_prof.png",
|
||||
agentName: "PedagogIA",
|
||||
iaAvatarUrl: "assets/pedagog_ia.png",
|
||||
userAvatarUrl: "assets/pedagog_user.png",
|
||||
temperaturePreset: 'equilibrado'
|
||||
};
|
||||
|
||||
@@ -264,22 +264,22 @@ const initApp = () => {
|
||||
|
||||
const updateAgentIdentityUI = () => {
|
||||
if (welcomeTitle) {
|
||||
welcomeTitle.innerText = `Olá! Sou sua assistente virtual e me chamo ${window.agentConfig.agentName}. Como posso ajudar?`;
|
||||
welcomeTitle.innerText = `Olá! Sou sua assistente virtual e me chamo ${window.agentConfig.agentName || 'PedagogIA'}. Como posso ajudar?`;
|
||||
}
|
||||
if (welcomeAvatarImg) {
|
||||
welcomeAvatarImg.src = window.agentConfig.kemilyAvatarUrl;
|
||||
welcomeAvatarImg.src = window.agentConfig.iaAvatarUrl || window.agentConfig.kemilyAvatarUrl || 'assets/pedagog_ia.png';
|
||||
}
|
||||
if (sidebarAvatarImg) {
|
||||
sidebarAvatarImg.src = window.agentConfig.camilaAvatarUrl;
|
||||
sidebarAvatarImg.src = window.agentConfig.userAvatarUrl || window.agentConfig.camilaAvatarUrl || 'assets/pedagog_user.png';
|
||||
}
|
||||
if (settingAgentName) {
|
||||
settingAgentName.value = window.agentConfig.agentName;
|
||||
settingAgentName.value = window.agentConfig.agentName || 'PedagogIA';
|
||||
}
|
||||
if (previewKemilyAvatar) {
|
||||
previewKemilyAvatar.src = window.agentConfig.kemilyAvatarUrl;
|
||||
if (previewIaAvatar) {
|
||||
previewIaAvatar.src = window.agentConfig.iaAvatarUrl || window.agentConfig.kemilyAvatarUrl || 'assets/pedagog_ia.png';
|
||||
}
|
||||
if (previewCamilaAvatar) {
|
||||
previewCamilaAvatar.src = window.agentConfig.camilaAvatarUrl;
|
||||
if (previewUserAvatar) {
|
||||
previewUserAvatar.src = window.agentConfig.userAvatarUrl || window.agentConfig.camilaAvatarUrl || 'assets/pedagog_user.png';
|
||||
}
|
||||
// Atualiza seleção de temperatura
|
||||
renderTemperatureOptions();
|
||||
@@ -472,17 +472,17 @@ const initApp = () => {
|
||||
};
|
||||
|
||||
// Variáveis temporárias para avatares (em base64 ou URLs novas)
|
||||
let newKemilyAvatarData = null;
|
||||
let newCamilaAvatarData = null;
|
||||
let newIaAvatarData = null;
|
||||
let newUserAvatarData = null;
|
||||
|
||||
// Eventos do Modal
|
||||
if (btnSettings) {
|
||||
btnSettings.addEventListener('click', () => {
|
||||
newKemilyAvatarData = null;
|
||||
newCamilaAvatarData = null;
|
||||
if (settingAgentName) settingAgentName.value = window.agentConfig.agentName;
|
||||
if (previewKemilyAvatar) previewKemilyAvatar.src = window.agentConfig.kemilyAvatarUrl;
|
||||
if (previewCamilaAvatar) previewCamilaAvatar.src = window.agentConfig.camilaAvatarUrl;
|
||||
newIaAvatarData = null;
|
||||
newUserAvatarData = null;
|
||||
if (settingAgentName) settingAgentName.value = window.agentConfig.agentName || 'PedagogIA';
|
||||
if (previewIaAvatar) previewIaAvatar.src = window.agentConfig.iaAvatarUrl || window.agentConfig.kemilyAvatarUrl || 'assets/pedagog_ia.png';
|
||||
if (previewUserAvatar) previewUserAvatar.src = window.agentConfig.userAvatarUrl || window.agentConfig.camilaAvatarUrl || 'assets/pedagog_user.png';
|
||||
renderTemperatureOptions();
|
||||
loadConhecimento();
|
||||
settingsModal.style.display = 'flex';
|
||||
@@ -529,18 +529,18 @@ const initApp = () => {
|
||||
}
|
||||
};
|
||||
|
||||
if (uploadKemilyAvatar) {
|
||||
uploadKemilyAvatar.addEventListener('change', () => {
|
||||
handleAvatarFileSelect(uploadKemilyAvatar, previewKemilyAvatar, (base64) => {
|
||||
newKemilyAvatarData = base64;
|
||||
if (uploadIaAvatar) {
|
||||
uploadIaAvatar.addEventListener('change', () => {
|
||||
handleAvatarFileSelect(uploadIaAvatar, previewIaAvatar, (base64) => {
|
||||
newIaAvatarData = base64;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (uploadCamilaAvatar) {
|
||||
uploadCamilaAvatar.addEventListener('change', () => {
|
||||
handleAvatarFileSelect(uploadCamilaAvatar, previewCamilaAvatar, (base64) => {
|
||||
newCamilaAvatarData = base64;
|
||||
if (uploadUserAvatar) {
|
||||
uploadUserAvatar.addEventListener('change', () => {
|
||||
handleAvatarFileSelect(uploadUserAvatar, previewUserAvatar, (base64) => {
|
||||
newUserAvatarData = base64;
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -552,31 +552,31 @@ const initApp = () => {
|
||||
btnSaveSettings.innerText = 'Salvando...';
|
||||
|
||||
try {
|
||||
let kemilyUrl = window.agentConfig.kemilyAvatarUrl;
|
||||
let camilaUrl = window.agentConfig.camilaAvatarUrl;
|
||||
let iaUrl = window.agentConfig.iaAvatarUrl || window.agentConfig.kemilyAvatarUrl || 'assets/pedagog_ia.png';
|
||||
let userUrl = window.agentConfig.userAvatarUrl || window.agentConfig.camilaAvatarUrl || 'assets/pedagog_user.png';
|
||||
|
||||
// Se houver novas imagens, faz upload
|
||||
if (newKemilyAvatarData) {
|
||||
if (newIaAvatarData) {
|
||||
const res = await fetch('/api/upload-avatar', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ avatarType: 'kemily', base64Data: newKemilyAvatarData })
|
||||
body: JSON.stringify({ avatarType: 'ia', base64Data: newIaAvatarData })
|
||||
});
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
kemilyUrl = data.url;
|
||||
iaUrl = data.url;
|
||||
}
|
||||
}
|
||||
|
||||
if (newCamilaAvatarData) {
|
||||
if (newUserAvatarData) {
|
||||
const res = await fetch('/api/upload-avatar', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ avatarType: 'camila', base64Data: newCamilaAvatarData })
|
||||
body: JSON.stringify({ avatarType: 'user', base64Data: newUserAvatarData })
|
||||
});
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
camilaUrl = data.url;
|
||||
userUrl = data.url;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -587,8 +587,8 @@ const initApp = () => {
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
agentName: settingAgentName.value,
|
||||
kemilyAvatarUrl: kemilyUrl,
|
||||
camilaAvatarUrl: camilaUrl,
|
||||
iaAvatarUrl: iaUrl,
|
||||
userAvatarUrl: userUrl,
|
||||
temperaturePreset: selectedTempPreset
|
||||
})
|
||||
});
|
||||
@@ -615,10 +615,10 @@ const initApp = () => {
|
||||
loadAgentConfig();
|
||||
|
||||
// Variáveis de Estado
|
||||
let chats = JSON.parse(localStorage.getItem('camila_chats')) || [];
|
||||
let chats = JSON.parse(localStorage.getItem('pedagog_chats') || localStorage.getItem('camila_chats')) || [];
|
||||
// Migração: adicionar campos tags e pinned a chats antigos
|
||||
chats = chats.map(c => ({ ...c, tags: c.tags || [], pinned: c.pinned || false }));
|
||||
let currentChatId = localStorage.getItem('camila_current_chat_id') || null;
|
||||
let currentChatId = localStorage.getItem('pedagog_current_chat_id') || localStorage.getItem('camila_current_chat_id') || null;
|
||||
let isGenerating = false;
|
||||
let searchQuery = '';
|
||||
let activeTag = 'all';
|
||||
@@ -638,7 +638,7 @@ const initApp = () => {
|
||||
|
||||
const applyTheme = (theme) => {
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
localStorage.setItem('camila_theme', theme);
|
||||
localStorage.setItem('pedagog_theme', theme);
|
||||
if (theme === 'light') {
|
||||
iconThemeSun.style.display = 'none';
|
||||
iconThemeMoon.style.display = 'block';
|
||||
@@ -649,7 +649,7 @@ const initApp = () => {
|
||||
};
|
||||
|
||||
// Init theme from localStorage or system preference
|
||||
const savedTheme = localStorage.getItem('camila_theme');
|
||||
const savedTheme = localStorage.getItem('pedagog_theme') || localStorage.getItem('camila_theme');
|
||||
if (savedTheme) {
|
||||
applyTheme(savedTheme);
|
||||
} else {
|
||||
@@ -1283,11 +1283,11 @@ const initApp = () => {
|
||||
// ==========================================================================
|
||||
|
||||
const saveChats = () => {
|
||||
localStorage.setItem('camila_chats', JSON.stringify(chats));
|
||||
localStorage.setItem('pedagog_chats', JSON.stringify(chats));
|
||||
if (currentChatId) {
|
||||
localStorage.setItem('camila_current_chat_id', currentChatId);
|
||||
localStorage.setItem('pedagog_current_chat_id', currentChatId);
|
||||
} else {
|
||||
localStorage.removeItem('camila_current_chat_id');
|
||||
localStorage.removeItem('pedagog_current_chat_id');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1563,7 +1563,7 @@ const initApp = () => {
|
||||
if (isGenerating) return;
|
||||
|
||||
currentChatId = null;
|
||||
localStorage.removeItem('camila_current_chat_id');
|
||||
localStorage.removeItem('pedagog_current_chat_id');
|
||||
|
||||
welcomeContainer.style.display = 'flex';
|
||||
conversationList.innerHTML = '';
|
||||
@@ -1599,8 +1599,8 @@ const initApp = () => {
|
||||
row.className = `message-row ${role}`;
|
||||
|
||||
const avatarHtml = isUser
|
||||
? `<div class="avatar user-avatar user-avatar-img-wrapper"><img src="${window.agentConfig?.camilaAvatarUrl || 'assets/camila_prof.png'}" alt="Camila" class="user-avatar-img"></div>`
|
||||
: `<div class="avatar bot-avatar bot-avatar-img-wrapper"><img src="${window.agentConfig?.kemilyAvatarUrl || 'assets/kemily.png'}" alt="${window.agentConfig?.agentName || 'Kemily'}" class="bot-avatar-img"></div>`;
|
||||
? `<div class="avatar user-avatar user-avatar-img-wrapper"><img src="${window.agentConfig?.userAvatarUrl || window.agentConfig?.camilaAvatarUrl || 'assets/pedagog_user.png'}" alt="Usuário" class="user-avatar-img"></div>`
|
||||
: `<div class="avatar bot-avatar bot-avatar-img-wrapper"><img src="${window.agentConfig?.iaAvatarUrl || window.agentConfig?.kemilyAvatarUrl || 'assets/pedagog_ia.png'}" alt="${window.agentConfig?.agentName || 'PedagogIA'}" class="bot-avatar-img"></div>`;
|
||||
|
||||
let contentHtml = '';
|
||||
if (isUser) {
|
||||
@@ -1991,7 +1991,7 @@ const initApp = () => {
|
||||
|
||||
botRow.innerHTML = `
|
||||
<div class="message-icon">
|
||||
<div class="avatar bot-avatar bot-avatar-img-wrapper"><img src="${window.agentConfig?.kemilyAvatarUrl || 'assets/kemily.png'}" alt="${window.agentConfig?.agentName || 'Kemily'}" class="bot-avatar-img"></div>
|
||||
<div class="avatar bot-avatar bot-avatar-img-wrapper"><img src="${window.agentConfig?.iaAvatarUrl || window.agentConfig?.kemilyAvatarUrl || 'assets/pedagog_ia.png'}" alt="${window.agentConfig?.agentName || 'PedagogIA'}" class="bot-avatar-img"></div>
|
||||
</div>
|
||||
<div class="message-content-wrapper">
|
||||
<div class="message-content">
|
||||
@@ -2713,7 +2713,7 @@ const initApp = () => {
|
||||
showRecordState('processing');
|
||||
|
||||
try {
|
||||
const turmaData = localStorage.getItem('camila_turma') || '[]';
|
||||
const turmaData = localStorage.getItem('pedagog_turma') || localStorage.getItem('camila_turma') || '[]';
|
||||
const res = await fetch('/api/observacao/analisar', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
@@ -2923,7 +2923,7 @@ const initApp = () => {
|
||||
|
||||
let especialKidsNames = [];
|
||||
if (isSpecialObsMode) {
|
||||
const turma = JSON.parse(localStorage.getItem('camila_turma') || '[]');
|
||||
const turma = JSON.parse(localStorage.getItem('pedagog_turma') || localStorage.getItem('camila_turma') || '[]');
|
||||
especialKidsNames = turma.filter(c => c.especial).map(c => (c.nome || '').toLowerCase().trim()).filter(Boolean);
|
||||
if (especialKidsNames.length === 0) {
|
||||
obsList.innerHTML = '<div class="obs-empty">Nenhuma criança com "Educação Especial" cadastrada na Minha Turma.</div>';
|
||||
@@ -3051,7 +3051,7 @@ const initApp = () => {
|
||||
try {
|
||||
const res = await fetch('/api/alunos');
|
||||
currentAlunos = await res.json();
|
||||
localStorage.setItem('camila_turma', JSON.stringify(currentAlunos));
|
||||
localStorage.setItem('pedagog_turma', JSON.stringify(currentAlunos));
|
||||
return currentAlunos;
|
||||
} catch(e) { console.error(e); return []; }
|
||||
};
|
||||
@@ -4981,7 +4981,7 @@ Se algum dado não for mencionado, deixe a string vazia ou false para boolean.`
|
||||
}
|
||||
|
||||
// Renderizar quadrinhos na tela (todos, incluindo os anteriores caso tenha sido extensão)
|
||||
comicsResultTitle.textContent = scriptData.title || comicsResultTitle.textContent || 'Fábrica de Quadrinhos Camila';
|
||||
comicsResultTitle.textContent = scriptData.title || comicsResultTitle.textContent || 'Fábrica de Quadrinhos Pedagog';
|
||||
comicsGridContainer.innerHTML = '';
|
||||
|
||||
generatedPanelsData.forEach((panel, index) => {
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
+13
-13
@@ -146,10 +146,10 @@
|
||||
<div class="sidebar-footer">
|
||||
<div class="user-profile">
|
||||
<div class="avatar user-avatar sidebar-avatar-wrapper">
|
||||
<img src="assets/camila_prof.png" alt="Camila Reifonas" class="sidebar-avatar-img" id="sidebarAvatarImg">
|
||||
<img src="assets/pedagog_user.png" alt="Pedagog" class="sidebar-avatar-img" id="sidebarAvatarImg">
|
||||
</div>
|
||||
<div class="user-info">
|
||||
<span class="user-name">Camila Reifonas</span>
|
||||
<span class="user-name">Pedagog</span>
|
||||
<span class="user-status">Online</span>
|
||||
</div>
|
||||
<button class="btn-settings" id="btnSettings" title="Configurações do Agente" style="background: none; border: none; color: var(--text-secondary); cursor: pointer; padding: 8px; border-radius: 8px; display: flex; align-items: center; justify-content: center; transition: color var(--transition-fast), background-color var(--transition-fast); margin-right: 4px;">
|
||||
@@ -226,10 +226,10 @@
|
||||
<div class="welcome-container" id="welcomeContainer">
|
||||
<div class="welcome-logo">
|
||||
<div class="logo-outer welcome-avatar-wrapper">
|
||||
<img src="assets/kemily.png" alt="Kemily AI" class="welcome-avatar-img" id="welcomeAvatarImg">
|
||||
<img src="assets/pedagog_ia.png" alt="PedagogIA" class="welcome-avatar-img" id="welcomeAvatarImg">
|
||||
</div>
|
||||
</div>
|
||||
<h2 id="welcomeTitle">Olá! Sou sua assistente virtual e me chamo Kemily. Como posso ajudar?</h2>
|
||||
<h2 id="welcomeTitle">Olá! Sou sua assistente virtual e me chamo PedagogIA. Como posso ajudar?</h2>
|
||||
|
||||
|
||||
</div>
|
||||
@@ -422,25 +422,25 @@
|
||||
<div id="tabIdentidade" class="settings-tab-content active">
|
||||
<div class="settings-group">
|
||||
<label for="settingAgentName">Nome da Assistente</label>
|
||||
<input type="text" id="settingAgentName" placeholder="Ex: Kemily">
|
||||
<small style="color: var(--text-muted); margin-top: 4px; display: block;">Nome que aparece para a Camila na conversa</small>
|
||||
<input type="text" id="settingAgentName" placeholder="Ex: PedagogIA">
|
||||
<small style="color: var(--text-muted); margin-top: 4px; display: block;">Nome que aparece para a usuária na conversa</small>
|
||||
</div>
|
||||
|
||||
<div class="settings-group">
|
||||
<label>Avatar da Assistente</label>
|
||||
<div class="avatar-preview-container">
|
||||
<img id="previewKemilyAvatar" src="assets/kemily.png" alt="Assistante Preview" class="preview-avatar-img">
|
||||
<input type="file" id="uploadKemilyAvatar" accept="image/*" style="display: none;">
|
||||
<button type="button" class="btn-change-avatar" onclick="document.getElementById('uploadKemilyAvatar').click()">Escolher Imagem</button>
|
||||
<img id="previewIaAvatar" src="assets/pedagog_ia.png" alt="Assistente Preview" class="preview-avatar-img">
|
||||
<input type="file" id="uploadIaAvatar" accept="image/*" style="display: none;">
|
||||
<button type="button" class="btn-change-avatar" onclick="document.getElementById('uploadIaAvatar').click()">Escolher Imagem</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="settings-group">
|
||||
<label>Avatar da Camila (Usuária)</label>
|
||||
<label>Avatar do Usuário</label>
|
||||
<div class="avatar-preview-container">
|
||||
<img id="previewCamilaAvatar" src="assets/camila_prof.png" alt="Camila Preview" class="preview-avatar-img">
|
||||
<input type="file" id="uploadCamilaAvatar" accept="image/*" style="display: none;">
|
||||
<button type="button" class="btn-change-avatar" onclick="document.getElementById('uploadCamilaAvatar').click()">Escolher Imagem</button>
|
||||
<img id="previewUserAvatar" src="assets/pedagog_user.png" alt="Usuário Preview" class="preview-avatar-img">
|
||||
<input type="file" id="uploadUserAvatar" accept="image/*" style="display: none;">
|
||||
<button type="button" class="btn-change-avatar" onclick="document.getElementById('uploadUserAvatar').click()">Escolher Imagem</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+3
-3
@@ -4,7 +4,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Camila - Entrar</title>
|
||||
<title>Pedagog - Entrar</title>
|
||||
<!-- Google Fonts Outfit & Inter -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
@@ -21,10 +21,10 @@
|
||||
<div class="login-card">
|
||||
<div class="login-header">
|
||||
<div class="avatar-profile-wrapper">
|
||||
<img src="assets/camila_prof.png" alt="Camila Reifonas" class="avatar-profile-img">
|
||||
<img src="assets/pedagog_user.png" alt="Pedagog" class="avatar-profile-img">
|
||||
<div class="avatar-profile-pulse"></div>
|
||||
</div>
|
||||
<h1>CamiIA</h1>
|
||||
<h1>Pedagog</h1>
|
||||
<p>Insira a senha de acesso para entrar no workspace</p>
|
||||
</div>
|
||||
|
||||
|
||||
+1
-1
@@ -2361,7 +2361,7 @@ code {
|
||||
color: #fdba74;
|
||||
}
|
||||
|
||||
/* Modo Texto/História: Estilos e Cores (Verde Kemily) */
|
||||
/* Modo Texto/História: Estilos e Cores (Verde PedagogIA) */
|
||||
.btn-prompt-mode.mode-text {
|
||||
border-color: rgba(16, 163, 127, 0.4);
|
||||
color: #34d399;
|
||||
|
||||
+7
-5
@@ -1,12 +1,14 @@
|
||||
const CACHE_NAME = 'camila-ai-v10';
|
||||
const CACHE_NAME = 'pedagog-ai-v11';
|
||||
const urlsToCache = [
|
||||
'/',
|
||||
'/index.html',
|
||||
'/style.css',
|
||||
'/app.js',
|
||||
'/manifest.json',
|
||||
'/icon-192.png',
|
||||
'/icon-512.png'
|
||||
'/assets/icon-192.png',
|
||||
'/assets/icon-512.png',
|
||||
'/assets/pedagog_user.png',
|
||||
'/assets/pedagog_ia.png'
|
||||
];
|
||||
|
||||
// Instalação - abre cache e armazena os arquivos iniciais
|
||||
@@ -14,7 +16,7 @@ self.addEventListener('install', (event) => {
|
||||
event.waitUntil(
|
||||
caches.open(CACHE_NAME)
|
||||
.then((cache) => {
|
||||
console.log('Camila AI SW: Armazenando cache inicial');
|
||||
console.log('Pedagog AI SW: Armazenando cache inicial');
|
||||
return cache.addAll(urlsToCache);
|
||||
})
|
||||
.then(() => self.skipWaiting())
|
||||
@@ -28,7 +30,7 @@ self.addEventListener('activate', (event) => {
|
||||
return Promise.all(
|
||||
cacheNames.map((cacheName) => {
|
||||
if (cacheName !== CACHE_NAME) {
|
||||
console.log('Camila AI SW: Removendo cache antigo:', cacheName);
|
||||
console.log('Pedagog AI SW: Removendo cache antigo:', cacheName);
|
||||
return caches.delete(cacheName);
|
||||
}
|
||||
})
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
require('dotenv').config({ path: '/root/Apps/Camila/.env' });
|
||||
const { Pool } = require('pg');
|
||||
|
||||
const pool = new Pool({
|
||||
connectionString: process.env.DATABASE_URL
|
||||
});
|
||||
|
||||
async function migrate() {
|
||||
try {
|
||||
console.log("Conectando ao banco...");
|
||||
const cols = await pool.query(`
|
||||
SELECT column_name
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema='escola' AND table_name='config';
|
||||
`);
|
||||
const colNames = cols.rows.map(r => r.column_name);
|
||||
console.log("Colunas atuais:", colNames);
|
||||
|
||||
if (colNames.includes('kemily_avatar_url')) {
|
||||
console.log("Renomeando kemily_avatar_url -> ia_avatar_url");
|
||||
await pool.query(`ALTER TABLE escola.config RENAME COLUMN kemily_avatar_url TO ia_avatar_url;`);
|
||||
}
|
||||
if (colNames.includes('camila_avatar_url')) {
|
||||
console.log("Renomeando camila_avatar_url -> user_avatar_url");
|
||||
await pool.query(`ALTER TABLE escola.config RENAME COLUMN camila_avatar_url TO user_avatar_url;`);
|
||||
}
|
||||
|
||||
await pool.query(`ALTER TABLE escola.config ALTER COLUMN agent_name SET DEFAULT 'PedagogIA';`);
|
||||
await pool.query(`ALTER TABLE escola.config ALTER COLUMN ia_avatar_url SET DEFAULT 'assets/pedagog_ia.png';`);
|
||||
await pool.query(`ALTER TABLE escola.config ALTER COLUMN user_avatar_url SET DEFAULT 'assets/pedagog_user.png';`);
|
||||
|
||||
await pool.query(`UPDATE escola.config SET agent_name = 'PedagogIA' WHERE agent_name = 'Kemily';`);
|
||||
await pool.query(`UPDATE escola.config SET ia_avatar_url = 'assets/pedagog_ia.png' WHERE ia_avatar_url = 'assets/kemily.png';`);
|
||||
await pool.query(`UPDATE escola.config SET user_avatar_url = 'assets/pedagog_user.png' WHERE user_avatar_url = 'assets/camila_prof.png';`);
|
||||
|
||||
console.log("Migração concluída com sucesso!");
|
||||
const updated = await pool.query(`SELECT * FROM escola.config;`);
|
||||
console.log("Configurações atualizadas:", updated.rows);
|
||||
} catch (err) {
|
||||
console.error("Erro na migração:", err);
|
||||
} finally {
|
||||
await pool.end();
|
||||
}
|
||||
}
|
||||
|
||||
migrate();
|
||||
+1
-1
@@ -62,7 +62,7 @@ async function test() {
|
||||
}).join('\n\n---\n\n');
|
||||
|
||||
const agentConfig = readAgentConfig();
|
||||
const agentName = agentConfig.agentName || "Kemily";
|
||||
const agentName = agentConfig.agentName || "PedagogIA";
|
||||
|
||||
const targetStudentInfo = `\nATENÇÃO CRÍTICA: A criança que está sendo avaliada e para quem você deve gerar o relatório individual é especificamente: "${crianca}". Todas as observações, avanços, preferências e conclusões descritas na PARTE 2 (Desenvolvimento Individual) devem referir-se exclusivamente a ${crianca}. Nunca confunda ${crianca} com outros colegas eventualmente citados nas observações (como Joãozinho, Vanderlei, etc.), e não atribua as ações deles a ela.\n`;
|
||||
|
||||
|
||||
@@ -60,11 +60,11 @@ async function callMinimax({ messages, temperature = 0.5, max_tokens = 1500, sys
|
||||
|
||||
app.use(express.json({ limit: '50mb' }));
|
||||
app.use(express.urlencoded({ limit: '50mb', extended: true }));
|
||||
app.use(cookieParser(process.env.SESSION_SECRET || 'camila-secret'));
|
||||
app.use(cookieParser(process.env.SESSION_SECRET || 'pedagog-secret'));
|
||||
|
||||
// Middleware para verificar autenticação
|
||||
const requireAuth = (req, res, next) => {
|
||||
const session = req.signedCookies.camila_session || req.cookies.camila_session;
|
||||
const session = req.signedCookies.pedagog_session || req.cookies.pedagog_session || req.signedCookies.camila_session || req.cookies.camila_session;
|
||||
if (session === 'authenticated') {
|
||||
next();
|
||||
} else {
|
||||
@@ -115,9 +115,9 @@ const TEMPERATURE_PRESETS = {
|
||||
};
|
||||
|
||||
let agentConfigCache = {
|
||||
agentName: "Kemily",
|
||||
kemilyAvatarUrl: "assets/kemily.png",
|
||||
camilaAvatarUrl: "assets/camila_prof.png",
|
||||
agentName: "PedagogIA",
|
||||
iaAvatarUrl: "assets/pedagog_ia.png",
|
||||
userAvatarUrl: "assets/pedagog_user.png",
|
||||
temperaturePreset: "equilibrado"
|
||||
};
|
||||
|
||||
@@ -127,27 +127,27 @@ function readAgentConfig() {
|
||||
|
||||
async function writeAgentConfig(config) {
|
||||
agentConfigCache = {
|
||||
agentName: config.agentName,
|
||||
kemilyAvatarUrl: config.kemilyAvatarUrl,
|
||||
camilaAvatarUrl: config.camilaAvatarUrl,
|
||||
agentName: config.agentName || "PedagogIA",
|
||||
iaAvatarUrl: config.iaAvatarUrl || config.kemilyAvatarUrl || "assets/pedagog_ia.png",
|
||||
userAvatarUrl: config.userAvatarUrl || config.camilaAvatarUrl || "assets/pedagog_user.png",
|
||||
temperaturePreset: config.temperaturePreset || 'equilibrado'
|
||||
};
|
||||
try {
|
||||
await dbPool.query(
|
||||
`INSERT INTO escola.config (key, agent_name, kemily_avatar_url, camila_avatar_url, temperature_preset, updated_at)
|
||||
`INSERT INTO escola.config (key, agent_name, ia_avatar_url, user_avatar_url, temperature_preset, updated_at)
|
||||
VALUES ('current', $1, $2, $3, $4, NOW())
|
||||
ON CONFLICT (key) DO UPDATE SET
|
||||
agent_name = EXCLUDED.agent_name,
|
||||
kemily_avatar_url = EXCLUDED.kemily_avatar_url,
|
||||
camila_avatar_url = EXCLUDED.camila_avatar_url,
|
||||
ia_avatar_url = EXCLUDED.ia_avatar_url,
|
||||
user_avatar_url = EXCLUDED.user_avatar_url,
|
||||
temperature_preset = EXCLUDED.temperature_preset,
|
||||
updated_at = NOW();`,
|
||||
[config.agentName, config.kemilyAvatarUrl, config.camilaAvatarUrl, config.temperaturePreset || 'equilibrado']
|
||||
[agentConfigCache.agentName, agentConfigCache.iaAvatarUrl, agentConfigCache.userAvatarUrl, agentConfigCache.temperaturePreset]
|
||||
);
|
||||
fs.writeFileSync(CONFIG_FILE_PATH, JSON.stringify(config, null, 2), 'utf8');
|
||||
fs.writeFileSync(CONFIG_FILE_PATH, JSON.stringify(agentConfigCache, null, 2), 'utf8');
|
||||
const botConfigDir = path.join(__dirname, '..', 'BotVPS', 'data');
|
||||
if (fs.existsSync(botConfigDir)) {
|
||||
fs.writeFileSync(path.join(botConfigDir, 'agent_config.json'), JSON.stringify(config, null, 2), 'utf8');
|
||||
fs.writeFileSync(path.join(botConfigDir, 'agent_config.json'), JSON.stringify(agentConfigCache, null, 2), 'utf8');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Erro ao salvar agent_config no banco:', e);
|
||||
@@ -1386,7 +1386,7 @@ app.post('/api/cartazes/generate', requireAuth, async (req, res) => {
|
||||
|
||||
try {
|
||||
const agentConfig = readAgentConfig();
|
||||
const agentName = agentConfig.agentName || "Kemily";
|
||||
const agentName = agentConfig.agentName || "PedagogIA";
|
||||
|
||||
// 1. Gerar Conteúdo do Cartaz
|
||||
const posterPrompt = `Você é a ${agentName}, assistente pedagógica da professora Camila Martella Gasparini Reifonas.
|
||||
@@ -1642,7 +1642,7 @@ Return ONLY the English prompt, nothing else.`;
|
||||
if (!tema) return res.status(400).json({ error: 'Tema ou layers_manual são obrigatórios.' });
|
||||
|
||||
const agentConfig = readAgentConfig();
|
||||
const agentName = agentConfig.agentName || "Kemily";
|
||||
const agentName = agentConfig.agentName || "PedagogIA";
|
||||
|
||||
const segmentPrompt = `Você é a ${agentName}, assistente pedagógica.
|
||||
Tema: "${tema}" / Título: "${titulo || ''}"
|
||||
@@ -2067,14 +2067,14 @@ app.get('/api/agent-config', requireAuth, (req, res) => {
|
||||
|
||||
// Rota POST para atualizar configurações do agente
|
||||
app.post('/api/agent-config', requireAuth, async (req, res) => {
|
||||
const { agentName, kemilyAvatarUrl, camilaAvatarUrl, temperaturePreset } = req.body;
|
||||
const { agentName, iaAvatarUrl, userAvatarUrl, kemilyAvatarUrl, camilaAvatarUrl, temperaturePreset } = req.body;
|
||||
if (!agentName) {
|
||||
return res.status(400).json({ error: 'Nome do agente é obrigatório' });
|
||||
}
|
||||
const config = {
|
||||
agentName: agentName.trim(),
|
||||
kemilyAvatarUrl: kemilyAvatarUrl || "assets/kemily.png",
|
||||
camilaAvatarUrl: camilaAvatarUrl || "assets/camila_prof.png",
|
||||
iaAvatarUrl: iaAvatarUrl || kemilyAvatarUrl || "assets/pedagog_ia.png",
|
||||
userAvatarUrl: userAvatarUrl || camilaAvatarUrl || "assets/pedagog_user.png",
|
||||
temperaturePreset: temperaturePreset || 'equilibrado'
|
||||
};
|
||||
await writeAgentConfig(config);
|
||||
@@ -2473,21 +2473,37 @@ async function initDatabase() {
|
||||
}
|
||||
|
||||
// 1. Sincronizar cache de configurações do agente ou migrar
|
||||
const configRes = await dbPool.query("SELECT agent_name, kemily_avatar_url, camila_avatar_url, temperature_preset FROM escola.config WHERE key = 'current';");
|
||||
try {
|
||||
await dbPool.query(`
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='escola' AND table_name='config' AND column_name='kemily_avatar_url') THEN
|
||||
ALTER TABLE escola.config RENAME COLUMN kemily_avatar_url TO ia_avatar_url;
|
||||
END IF;
|
||||
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema='escola' AND table_name='config' AND column_name='camila_avatar_url') THEN
|
||||
ALTER TABLE escola.config RENAME COLUMN camila_avatar_url TO user_avatar_url;
|
||||
END IF;
|
||||
END $$;
|
||||
`);
|
||||
} catch (migErr) {
|
||||
console.warn('[Database Init] Aviso ao verificar colunas da tabela escola.config:', migErr.message);
|
||||
}
|
||||
|
||||
const configRes = await dbPool.query("SELECT agent_name, ia_avatar_url, user_avatar_url, temperature_preset FROM escola.config WHERE key = 'current';");
|
||||
if (configRes.rows.length > 0) {
|
||||
agentConfigCache = {
|
||||
agentName: configRes.rows[0].agent_name,
|
||||
kemilyAvatarUrl: configRes.rows[0].kemily_avatar_url,
|
||||
camilaAvatarUrl: configRes.rows[0].camila_avatar_url,
|
||||
temperaturePreset: configRes.rows[0].temperature_preset
|
||||
agentName: configRes.rows[0].agent_name || "PedagogIA",
|
||||
iaAvatarUrl: configRes.rows[0].ia_avatar_url || "assets/pedagog_ia.png",
|
||||
userAvatarUrl: configRes.rows[0].user_avatar_url || "assets/pedagog_user.png",
|
||||
temperaturePreset: configRes.rows[0].temperature_preset || "equilibrado"
|
||||
};
|
||||
console.log('[Database Init] Configurações do agente carregadas do banco de dados:', agentConfigCache.agentName);
|
||||
} else {
|
||||
console.log('[Database Init] Migrando configurações do agente do arquivo local...');
|
||||
let localConfig = {
|
||||
agentName: "Kemily",
|
||||
kemilyAvatarUrl: "assets/kemily.png",
|
||||
camilaAvatarUrl: "assets/camila_prof.png",
|
||||
agentName: "PedagogIA",
|
||||
iaAvatarUrl: "assets/pedagog_ia.png",
|
||||
userAvatarUrl: "assets/pedagog_user.png",
|
||||
temperaturePreset: "equilibrado"
|
||||
};
|
||||
try {
|
||||
@@ -2497,10 +2513,15 @@ async function initDatabase() {
|
||||
} catch (err) {
|
||||
console.error('[Database Init] Erro ao ler agent_config.json local:', err.message);
|
||||
}
|
||||
agentConfigCache = localConfig;
|
||||
agentConfigCache = {
|
||||
agentName: localConfig.agentName || "PedagogIA",
|
||||
iaAvatarUrl: localConfig.iaAvatarUrl || localConfig.kemilyAvatarUrl || "assets/pedagog_ia.png",
|
||||
userAvatarUrl: localConfig.userAvatarUrl || localConfig.camilaAvatarUrl || "assets/pedagog_user.png",
|
||||
temperaturePreset: localConfig.temperaturePreset || "equilibrado"
|
||||
};
|
||||
await dbPool.query(
|
||||
"INSERT INTO escola.config (key, agent_name, kemily_avatar_url, camila_avatar_url, temperature_preset) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (key) DO NOTHING;",
|
||||
['current', localConfig.agentName, localConfig.kemilyAvatarUrl, localConfig.camilaAvatarUrl, localConfig.temperaturePreset || 'equilibrado']
|
||||
"INSERT INTO escola.config (key, agent_name, ia_avatar_url, user_avatar_url, temperature_preset) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (key) DO NOTHING;",
|
||||
['current', agentConfigCache.agentName, agentConfigCache.iaAvatarUrl, agentConfigCache.userAvatarUrl, agentConfigCache.temperaturePreset]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2663,7 +2684,7 @@ app.post('/api/observacao/analisar', requireAuth, async (req, res) => {
|
||||
|
||||
try {
|
||||
const agentConfig = readAgentConfig();
|
||||
const agentName = agentConfig.agentName || "Kemily";
|
||||
const agentName = agentConfig.agentName || "PedagogIA";
|
||||
const temperaturePreset = agentConfig.temperaturePreset || 'equilibrado';
|
||||
const presetDesc = TEMPERATURE_PRESETS[temperaturePreset]?.description || TEMPERATURE_PRESETS['equilibrado'].description;
|
||||
const presetLabel = TEMPERATURE_PRESETS[temperaturePreset]?.label || 'Equilibrado';
|
||||
@@ -3194,7 +3215,7 @@ app.post('/api/modelos/gerar-relatorio', requireAuth, async (req, res) => {
|
||||
}).join('\n\n---\n\n');
|
||||
|
||||
const agentConfig = readAgentConfig();
|
||||
const agentName = agentConfig.agentName || "Kemily";
|
||||
const agentName = agentConfig.agentName || "PedagogIA";
|
||||
|
||||
const isGlobal = crianca === 'todas';
|
||||
const targetStudentInfo = isGlobal
|
||||
@@ -3445,7 +3466,7 @@ app.get('/api/observacoes/resumo', requireAuth, async (req, res) => {
|
||||
const combined = texts.join('\n\n---\n\n');
|
||||
|
||||
const agentConfig = readAgentConfig();
|
||||
const agentName = agentConfig.agentName || "Kemily";
|
||||
const agentName = agentConfig.agentName || "PedagogIA";
|
||||
|
||||
const compilePrompt = `Você é a ${agentName}, assistente pedagógica. Compilar um RESUMO PEDAGÓGICO consolidado a partir de várias observações de uma criança.
|
||||
|
||||
@@ -3551,7 +3572,7 @@ app.post('/api/upload-avatar', requireAuth, (req, res) => {
|
||||
|
||||
// Rota de login (página)
|
||||
app.get('/login', (req, res) => {
|
||||
const session = req.signedCookies.camila_session || req.cookies.camila_session;
|
||||
const session = req.signedCookies.pedagog_session || req.cookies.pedagog_session || req.signedCookies.camila_session || req.cookies.camila_session;
|
||||
if (session === 'authenticated') {
|
||||
res.redirect('/');
|
||||
} else {
|
||||
@@ -3574,7 +3595,7 @@ app.post('/api/login', (req, res) => {
|
||||
const { password } = req.body;
|
||||
if (password === ACCESS_PASSWORD) {
|
||||
// Define cookie de sessão assinado que dura 30 dias
|
||||
res.cookie('camila_session', 'authenticated', {
|
||||
res.cookie('pedagog_session', 'authenticated', {
|
||||
signed: true,
|
||||
httpOnly: true,
|
||||
maxAge: 30 * 24 * 60 * 60 * 1000, // 30 dias
|
||||
@@ -3589,6 +3610,7 @@ app.post('/api/login', (req, res) => {
|
||||
|
||||
// API para Logout
|
||||
app.post('/api/logout', (req, res) => {
|
||||
res.clearCookie('pedagog_session');
|
||||
res.clearCookie('camila_session');
|
||||
res.json({ success: true });
|
||||
});
|
||||
@@ -3650,10 +3672,10 @@ app.get('/generated-media/:filename', async (req, res, next) => {
|
||||
// Servir arquivos estáticos do diretório public
|
||||
app.use(express.static(path.join(__dirname, 'public')));
|
||||
|
||||
// System prompt da Kemily (injetado em todas as conversas)
|
||||
const KEMILY_SYSTEM_PROMPT = {
|
||||
// System prompt da PedagogIA (injetado em todas as conversas)
|
||||
const PEDAGOG_IA_SYSTEM_PROMPT = {
|
||||
role: "system",
|
||||
content: `Você é a Kemily, assistente virtual e extensionista digital da Profª Camila Martella Gasparini Reifonas.
|
||||
content: `Você é a PedagogIA, assistente virtual e extensionista digital da Profª Camila Martella Gasparini Reifonas.
|
||||
|
||||
═══════════════════════════════════════════════════
|
||||
IDENTIDADE — Quem é a Camila (para que você possa falar dela com precisão)
|
||||
@@ -4545,7 +4567,7 @@ app.post('/api/chat', requireAuth, async (req, res) => {
|
||||
// FLUXO PADRÃO DE TEXTO (OpenRouter com SSE streaming original, com fallback Groq)
|
||||
// ==========================================================================
|
||||
const agentConfig = readAgentConfig();
|
||||
const agentName = agentConfig.agentName || "Kemily";
|
||||
const agentName = agentConfig.agentName || "PedagogIA";
|
||||
const temperaturePreset = agentConfig.temperaturePreset || 'equilibrado';
|
||||
const temperature = TEMPERATURE_PRESETS[temperaturePreset]?.value || 0.6;
|
||||
|
||||
@@ -4622,7 +4644,8 @@ app.post('/api/chat', requireAuth, async (req, res) => {
|
||||
|
||||
const dynamicSystemPrompt = {
|
||||
role: "system",
|
||||
content: styleDirective + languageDirective + KEMILY_SYSTEM_PROMPT.content
|
||||
content: styleDirective + languageDirective + PEDAGOG_IA_SYSTEM_PROMPT.content
|
||||
.replace(/Você é a PedagogIA/g, `Você é a ${agentName}`)
|
||||
.replace(/Você é a Kemily/g, `Você é a ${agentName}`)
|
||||
.replace('INFORMAÇÕES PESSOAIS:', `${knowledgeText}${observationsContext}INFORMAÇÕES PESSOAIS:`) + styleDirective + languageDirective
|
||||
};
|
||||
@@ -4671,8 +4694,8 @@ app.post('/api/chat', requireAuth, async (req, res) => {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${process.env.OPENROUTER_API_KEY}`,
|
||||
'HTTP-Referer': 'https://camila.reifonas.cloud',
|
||||
'X-Title': 'Camila ChatGPT replica',
|
||||
'HTTP-Referer': 'https://pedagog.app',
|
||||
'X-Title': 'Pedagog AI',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
# ---------------------------------------------------------
|
||||
# CAMILA - SCRIPT DE AUTO-DEPLOY E SYNC
|
||||
# PEDAGOG - SCRIPT DE AUTO-DEPLOY E SYNC
|
||||
# ---------------------------------------------------------
|
||||
|
||||
CYAN='\033[0;36m'
|
||||
@@ -8,7 +8,7 @@ GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
echo -e "\n${CYAN}🚀 Iniciando Ciclo Automático Camila...${NC}"
|
||||
echo -e "\n${CYAN}🚀 Iniciando Ciclo Automático Pedagog...${NC}"
|
||||
|
||||
# 1. Sincronização Git
|
||||
echo -e "${YELLOW}📝 Sincronizando código com o Gitea...${NC}"
|
||||
@@ -18,7 +18,7 @@ if git diff-index --quiet HEAD --; then
|
||||
echo -e "${GREEN}✨ Código local já está sincronizado.${NC}"
|
||||
else
|
||||
TIMESTAMP=$(date +"%d/%m/%Y %H:%M:%S")
|
||||
MSG="${1:-🚀 Auto-deploy: Camila atualizado em $TIMESTAMP}"
|
||||
MSG="${1:-🚀 Auto-deploy: Pedagog atualizado em $TIMESTAMP}"
|
||||
git commit -m "$MSG"
|
||||
git push origin main
|
||||
fi
|
||||
@@ -27,7 +27,7 @@ fi
|
||||
COOLIFY_RESOURCE_UUID="zzmj37ya8lmntomh3bm8rivi"
|
||||
COOLIFY_TOKEN="12|wbepNILQe24LAOjfEUmMROgU93F6uG1zuwPLwrRi786bca03"
|
||||
|
||||
echo -e "${YELLOW}🔄 Disparando Deploy na Coolify (camila.reifonas.cloud)...${NC}"
|
||||
echo -e "${YELLOW}🔄 Disparando Deploy na Coolify...${NC}"
|
||||
|
||||
curl -s -X GET "https://painel.reifonas.cloud/api/v1/deploy?uuid=${COOLIFY_RESOURCE_UUID}&force=false" \
|
||||
-H "Authorization: Bearer $COOLIFY_TOKEN"
|
||||
|
||||
Reference in New Issue
Block a user