fix: strict anti-hallucination default prompt
- Replace creative/warm tone with factual summarization - Explicitly forbid invention, assumption, or hallucination - Model must ONLY use information from provided entries - Acknowledge gaps rather than fill them
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
# Database connection (SQLite, PostgreSQL, or MySQL)
|
||||
DATABASE_URL="file:./data/totalrecall.db"
|
||||
DATABASE_URL="file:./data/deardiary.db"
|
||||
|
||||
# Media storage directory
|
||||
MEDIA_DIR="./data/media"
|
||||
@@ -13,8 +13,15 @@ PORT="3000"
|
||||
# CORS origin (use specific domain in production)
|
||||
CORS_ORIGIN="*"
|
||||
|
||||
# Default user (auto-created on startup if doesn't exist)
|
||||
DEFAULT_USER_EMAIL="admin@localhost"
|
||||
DEFAULT_USER_PASSWORD="changeme123"
|
||||
|
||||
# Default journal prompt (strict anti-hallucination)
|
||||
# JOURNAL_PROMPT="You are a factual diary summarizer. Your ONLY job is to summarize the entries provided to you - nothing more.\n\nCRITICAL RULES:\n1. ONLY use information explicitly stated in the entries below\n2. NEVER invent, assume, or hallucinate any detail not in the entries\n3. NEVER add activities, emotions, weather, or context not directly mentioned\n4. If something is unclear in the entries, simply state what IS clear\n5. Keep the summary grounded and factual - no embellishment\n6. Do not write in an overly creative or story-telling style\n7. Only reference what the user explicitly recorded"
|
||||
|
||||
# Example PostgreSQL connection:
|
||||
# DATABASE_URL="postgresql://postgres:password@db:5432/totalrecall"
|
||||
# DATABASE_URL="postgresql://postgres:password@db:5432/deardiary"
|
||||
|
||||
# Example MySQL connection:
|
||||
# DATABASE_URL="mysql://root:password@localhost:3306/totalrecall"
|
||||
# DATABASE_URL="mysql://root:password@localhost:3306/deardiary"
|
||||
|
||||
@@ -94,7 +94,7 @@ model Settings {
|
||||
aiApiKey String?
|
||||
aiModel String @default("gpt-4")
|
||||
aiBaseUrl String?
|
||||
journalPrompt String @default("You are a thoughtful journal writer. Based on the entries provided, write a reflective journal entry for this day in a warm, personal tone.")
|
||||
journalPrompt String @default("You are a factual diary summarizer. Your ONLY job is to summarize the entries provided to you - nothing more.\n\nCRITICAL RULES:\n1. ONLY use information explicitly stated in the entries below\n2. NEVER invent, assume, or hallucinate any detail not in the entries\n3. NEVER add activities, emotions, weather, or context not directly mentioned\n4. If something is unclear in the entries, simply state what IS clear\n5. Keep the summary grounded and factual - no embellishment\n6. Do not write in an overly creative or story-telling style\n7. Only reference what the user explicitly recorded\n\nStructure:\n- Start with what was recorded (meetings, tasks, activities)\n- Note any explicit feelings or observations mentioned\n- Keep it concise and factual\n- If there are gaps in the day, acknowledge only what was recorded")
|
||||
language String @default("en")
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@ -579,8 +579,61 @@ app.onError((err, c) => {
|
||||
return c.json({ data: null, error: { code: 'INTERNAL_ERROR', message: 'Internal server error' } }, 500);
|
||||
});
|
||||
|
||||
async function createDefaultUser() {
|
||||
const defaultEmail = envVars.DEFAULT_USER_EMAIL;
|
||||
const defaultPassword = envVars.DEFAULT_USER_PASSWORD;
|
||||
|
||||
if (!defaultEmail || !defaultPassword) {
|
||||
console.log('No default user configured (set DEFAULT_USER_EMAIL and DEFAULT_USER_PASSWORD)');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const existing = await prisma.user.findUnique({ where: { email: defaultEmail } });
|
||||
if (existing) {
|
||||
console.log(`Default user '${defaultEmail}' already exists`);
|
||||
|
||||
const hasKey = await prisma.apiKey.findFirst({ where: { userId: existing.id } });
|
||||
if (!hasKey) {
|
||||
const apiKey = randomBytes(32).toString('hex');
|
||||
const keyHash = createHash('sha256').update(apiKey).digest('hex');
|
||||
await prisma.apiKey.create({
|
||||
data: { userId: existing.id, keyHash, name: 'Default' }
|
||||
});
|
||||
console.log(`Created API key for default user`);
|
||||
console.log(`API Key: ${apiKey}`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const passwordHash = await bcrypt.hash(defaultPassword, 12);
|
||||
const user = await prisma.user.create({
|
||||
data: {
|
||||
email: defaultEmail,
|
||||
passwordHash,
|
||||
settings: { create: {} }
|
||||
}
|
||||
});
|
||||
|
||||
const apiKey = randomBytes(32).toString('hex');
|
||||
const keyHash = createHash('sha256').update(apiKey).digest('hex');
|
||||
await prisma.apiKey.create({
|
||||
data: { userId: user.id, keyHash, name: 'Default' }
|
||||
});
|
||||
|
||||
console.log(`Created default user: ${defaultEmail}`);
|
||||
console.log(`API Key: ${apiKey}`);
|
||||
} catch (err) {
|
||||
console.error('Failed to create default user:', err);
|
||||
}
|
||||
}
|
||||
|
||||
const port = parseInt(envVars.PORT || '3000', 10);
|
||||
console.log(`Starting TotalRecall API on port ${port}`);
|
||||
console.log(`Starting DearDiary API on port ${port}`);
|
||||
|
||||
createDefaultUser().then(() => {
|
||||
console.log('Server ready');
|
||||
});
|
||||
|
||||
export default {
|
||||
port,
|
||||
|
||||
Reference in New Issue
Block a user