Refactor: Renomeacao e modernizacao completa para Pedagog / PedagogIA

This commit is contained in:
2026-08-31 10:34:33 +00:00
parent 00341ebf64
commit f3350b0969
16 changed files with 225 additions and 176 deletions
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
})
+46
View File
@@ -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
View File
@@ -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`;
+65 -42
View File
@@ -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({
+4 -4
View File
@@ -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"