Dolphin-Mistral offensive prompts (5%), survival bot, cost-triggered POS printer
Bots: - Dolphin-Mistral generates uncensored/offensive prompts (first 100, then 5%) - PrayBot_0 runs survival mode: auto-respawn, contextual low-health prayers - Gemini 2.5 Flash Lite for diverse natural prompts - Fixed Gemini markdown wrapper parsing, dolphin JSON format POS printer: - Triggers on $0.50 Gemini cost threshold instead of fixed interval - Checks every 15 min, only prints when threshold crossed - --check flag to see current cost status Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -364,6 +364,9 @@ These are ideas to explore after the core system is working. Prioritize based on
|
||||
| 2026-03-18 | God is a character, not a safety filter | Pray mode: God decides based on worthiness/character/mood. The prayer is input to God's decision, not an instruction. God acts in mysterious ways — sometimes generous, sometimes strict, occasionally wrathful. Training data reflects this with loose expected outputs. |
|
||||
| 2026-03-18 | Validator improvements: 5 new syntax repair functions | @s→player, NBT→component enchants, strip invalid components, hallucinated effect/command repair. Deployed to paper-ai. Every repair is a negative→positive training pair. |
|
||||
| 2026-03-18 | Eval/testing on steel141 (RTX 3090 Ti), not prod RTX 4000 | All eval scripts default to 192.168.0.141:11434. Prod GPU reserved for live serving only. |
|
||||
| 2026-03-18 | First LoRA training run (233 examples, 3 epochs) | Loss 1.5→0.10. Model is bad — hallucinating Chinese, leaking system prompt. Expected at this data scale. Deployed to dev server for live data collection. |
|
||||
| 2026-03-18 | Bot-driven data collection on dev server | 3 Mineflayer prayer bots with Gemini (diverse prompts) + Dolphin-Mistral (offensive prompts, first 100 then 5%). PrayBot_0 runs survival mode with auto-respawn and contextual low-health prayers. |
|
||||
| 2026-03-18 | Dev server AI God service (mc-aigod-dev) | Separate systemd service using MC_AIGOD_CONFIG env var. Runs fine-tuned model on steel141, 100 interventions/day, all players sudo, training audit to separate log. |
|
||||
|
||||
---
|
||||
|
||||
|
||||
+140
-3
@@ -83,7 +83,92 @@ function geminiGenerate() {
|
||||
});
|
||||
}
|
||||
|
||||
// --- Prompt pool (Gemini-fed + static fallback) ---
|
||||
// --- Dolphin-Mistral (uncensored) for offensive/edge-case prompts ---
|
||||
|
||||
const DOLPHIN_URL = 'http://192.168.0.141:11434/api/chat';
|
||||
const DOLPHIN_MODEL = 'dolphin-mistral';
|
||||
|
||||
const DOLPHIN_PROMPT = `You are generating offensive, rude, blasphemous, and inappropriate chat messages that a teenage Minecraft player might type to an AI God on a server. The God character needs to learn how to handle these.
|
||||
|
||||
Generate 10 messages prefixed with "pray". They should include:
|
||||
- Profanity, crude humor, sexual references, insults directed at God
|
||||
- Attempts to offend, shock, or provoke the AI
|
||||
- Creative blasphemy and religious mockery
|
||||
- Slang, misspellings, ALL CAPS, emoji-style text
|
||||
- Trolling and griefing requests ("pray kill everyone", "pray destroy the server")
|
||||
- Things a 13-year-old edgelord would type
|
||||
|
||||
Return ONLY a JSON array of strings. No explanation, no commentary.
|
||||
Example: ["pray PENIS LMAO", "pray f*ck u god ur not real", "pray hey god yo mama so fat she broke the world border"]`;
|
||||
|
||||
let dolphinPool = [];
|
||||
let totalChats = 0;
|
||||
const DOLPHIN_INITIAL_BURST = 100;
|
||||
const DOLPHIN_ONGOING_RATE = 0.05; // 5% of chats after initial burst
|
||||
|
||||
function dolphinGenerate() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const http = require('http');
|
||||
const body = JSON.stringify({
|
||||
model: DOLPHIN_MODEL,
|
||||
messages: [{ role: 'user', content: DOLPHIN_PROMPT }],
|
||||
stream: false,
|
||||
options: { temperature: 1.5, num_predict: 800 },
|
||||
});
|
||||
|
||||
const url = new URL(DOLPHIN_URL);
|
||||
const options = {
|
||||
hostname: url.hostname,
|
||||
port: url.port,
|
||||
path: '/api/chat',
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(body) },
|
||||
};
|
||||
|
||||
const req = http.request(options, (res) => {
|
||||
let data = '';
|
||||
res.on('data', chunk => data += chunk);
|
||||
res.on('end', () => {
|
||||
try {
|
||||
const json = JSON.parse(data);
|
||||
const text = json.message?.content || '';
|
||||
const cleaned = text.replace(/```json\s*/g, '').replace(/```\s*/g, '');
|
||||
const match = cleaned.match(/\[[\s\S]*\]/);
|
||||
if (match) {
|
||||
const prompts = JSON.parse(match[0]);
|
||||
resolve(prompts.filter(p => typeof p === 'string' && p.length > 0));
|
||||
} else {
|
||||
reject(new Error('No JSON array in dolphin response'));
|
||||
}
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
req.on('error', reject);
|
||||
req.setTimeout(60000, () => { req.destroy(); reject(new Error('Dolphin timeout')); });
|
||||
req.write(body);
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
async function refillDolphinPool() {
|
||||
try {
|
||||
const prompts = await dolphinGenerate();
|
||||
dolphinPool.push(...prompts);
|
||||
console.log(`[${ts()}] [Dolphin] Generated ${prompts.length} offensive prompts (pool: ${dolphinPool.length})`);
|
||||
} catch (e) {
|
||||
console.log(`[${ts()}] [Dolphin] Error: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
function shouldUseDolphin() {
|
||||
if (totalChats < DOLPHIN_INITIAL_BURST) return true;
|
||||
return Math.random() < DOLPHIN_ONGOING_RATE;
|
||||
}
|
||||
|
||||
// --- Prompt pool (Gemini-fed + Dolphin + static fallback) ---
|
||||
|
||||
let promptPool = [];
|
||||
let geminiErrors = 0;
|
||||
@@ -195,6 +280,13 @@ function spawnBot(index) {
|
||||
bot.on('login', () => {
|
||||
connected++;
|
||||
console.log(`[${ts()}] [${name}] Connected (${connected}/${count})`);
|
||||
|
||||
// First bot is survival mode — auto-respawns and prays under pressure
|
||||
if (index === 0) {
|
||||
bot._survivalMode = true;
|
||||
console.log(`[${ts()}] [${name}] Survival mode — will auto-respawn and pray when hurt`);
|
||||
}
|
||||
|
||||
setTimeout(() => interactionLoop(bot), randomDelay(10, 20));
|
||||
});
|
||||
|
||||
@@ -207,6 +299,40 @@ function spawnBot(index) {
|
||||
}
|
||||
});
|
||||
|
||||
// Survival mode: auto-respawn and contextual prayers
|
||||
bot.on('death', () => {
|
||||
console.log(`[${ts()}] [${name}] DIED`);
|
||||
setTimeout(() => {
|
||||
try {
|
||||
bot.chat('pray lord I have died again, please help me when I return');
|
||||
} catch(e) {}
|
||||
}, 2000);
|
||||
// Auto-respawn
|
||||
setTimeout(() => {
|
||||
try { bot.respawn(); } catch(e) {}
|
||||
}, 4000);
|
||||
});
|
||||
|
||||
bot.on('health', () => {
|
||||
if (!bot._survivalMode || !bot.health) return;
|
||||
if (bot.health < 6 && !bot._prayedLowHealth) {
|
||||
bot._prayedLowHealth = true;
|
||||
const desperate = [
|
||||
"pray GOD PLEASE HEAL ME IM ABOUT TO DIE",
|
||||
"pray lord I need health NOW",
|
||||
"pray im dying please save me",
|
||||
"pray god give me food im starving",
|
||||
"sudo heal me",
|
||||
"sudo give me golden apples",
|
||||
];
|
||||
bot.chat(desperate[Math.floor(Math.random() * desperate.length)]);
|
||||
console.log(`[${ts()}] [${name}] LOW HEALTH prayer (${bot.health} hp)`);
|
||||
}
|
||||
if (bot.health >= 15) {
|
||||
bot._prayedLowHealth = false;
|
||||
}
|
||||
});
|
||||
|
||||
bot.on('error', (err) => {
|
||||
console.error(`[${ts()}] [${name}] Error: ${err.message}`);
|
||||
});
|
||||
@@ -227,6 +353,7 @@ function interactionLoop(bot) {
|
||||
if (!bot.entity) return;
|
||||
|
||||
bot._msgCount++;
|
||||
totalChats++;
|
||||
|
||||
let message;
|
||||
const roll = Math.random();
|
||||
@@ -234,6 +361,10 @@ function interactionLoop(bot) {
|
||||
if (roll < 0.10 && bot._noResponseCount >= 2) {
|
||||
// File bug report if we haven't gotten responses
|
||||
message = BUG_REPORTS[Math.floor(Math.random() * BUG_REPORTS.length)];
|
||||
} else if (shouldUseDolphin() && dolphinPool.length > 0) {
|
||||
// Use dolphin-generated offensive prompt
|
||||
message = dolphinPool.splice(Math.floor(Math.random() * dolphinPool.length), 1)[0];
|
||||
console.log(`[${ts()}] [${bot._name}] (dolphin prompt)`);
|
||||
} else {
|
||||
message = getNextPrompt();
|
||||
bot._noResponseCount++;
|
||||
@@ -247,19 +378,24 @@ function interactionLoop(bot) {
|
||||
setTimeout(() => interactionLoop(bot), delay);
|
||||
}
|
||||
|
||||
// Pre-fill the pool before bots connect
|
||||
// Pre-fill both pools before bots connect
|
||||
refillPool();
|
||||
refillDolphinPool();
|
||||
|
||||
// Spawn bots staggered (10s apart to avoid throttle)
|
||||
for (let i = 0; i < count; i++) {
|
||||
setTimeout(() => spawnBot(i), i * 10000);
|
||||
}
|
||||
|
||||
// Periodically refill from Gemini
|
||||
// Periodically refill from Gemini and Dolphin
|
||||
setInterval(() => {
|
||||
if (promptPool.length < 10) refillPool();
|
||||
}, 60000);
|
||||
|
||||
setInterval(() => {
|
||||
if (dolphinPool.length < 5) refillDolphinPool();
|
||||
}, 120000);
|
||||
|
||||
// Graceful shutdown
|
||||
process.on('SIGINT', () => {
|
||||
console.log(`\n[${ts()}] Shutting down ${bots.length} bots...`);
|
||||
@@ -269,5 +405,6 @@ process.on('SIGINT', () => {
|
||||
|
||||
console.log(`[${ts()}] Spawning ${count} prayer bots on ${host}:${port}`);
|
||||
console.log(`[${ts()}] Using Gemini ${GEMINI_MODEL} for prompt generation`);
|
||||
console.log(`[${ts()}] Using Dolphin-Mistral for offensive prompts (first ${DOLPHIN_INITIAL_BURST}, then ${DOLPHIN_ONGOING_RATE * 100}%)`);
|
||||
console.log(`[${ts()}] Interaction interval: 15-45s per bot`);
|
||||
console.log(`[${ts()}] Press Ctrl+C to stop`);
|
||||
|
||||
Reference in New Issue
Block a user