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 | 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 | 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 | 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 promptPool = [];
|
||||||
let geminiErrors = 0;
|
let geminiErrors = 0;
|
||||||
@@ -195,6 +280,13 @@ function spawnBot(index) {
|
|||||||
bot.on('login', () => {
|
bot.on('login', () => {
|
||||||
connected++;
|
connected++;
|
||||||
console.log(`[${ts()}] [${name}] Connected (${connected}/${count})`);
|
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));
|
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) => {
|
bot.on('error', (err) => {
|
||||||
console.error(`[${ts()}] [${name}] Error: ${err.message}`);
|
console.error(`[${ts()}] [${name}] Error: ${err.message}`);
|
||||||
});
|
});
|
||||||
@@ -227,6 +353,7 @@ function interactionLoop(bot) {
|
|||||||
if (!bot.entity) return;
|
if (!bot.entity) return;
|
||||||
|
|
||||||
bot._msgCount++;
|
bot._msgCount++;
|
||||||
|
totalChats++;
|
||||||
|
|
||||||
let message;
|
let message;
|
||||||
const roll = Math.random();
|
const roll = Math.random();
|
||||||
@@ -234,6 +361,10 @@ function interactionLoop(bot) {
|
|||||||
if (roll < 0.10 && bot._noResponseCount >= 2) {
|
if (roll < 0.10 && bot._noResponseCount >= 2) {
|
||||||
// File bug report if we haven't gotten responses
|
// File bug report if we haven't gotten responses
|
||||||
message = BUG_REPORTS[Math.floor(Math.random() * BUG_REPORTS.length)];
|
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 {
|
} else {
|
||||||
message = getNextPrompt();
|
message = getNextPrompt();
|
||||||
bot._noResponseCount++;
|
bot._noResponseCount++;
|
||||||
@@ -247,19 +378,24 @@ function interactionLoop(bot) {
|
|||||||
setTimeout(() => interactionLoop(bot), delay);
|
setTimeout(() => interactionLoop(bot), delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pre-fill the pool before bots connect
|
// Pre-fill both pools before bots connect
|
||||||
refillPool();
|
refillPool();
|
||||||
|
refillDolphinPool();
|
||||||
|
|
||||||
// Spawn bots staggered (10s apart to avoid throttle)
|
// Spawn bots staggered (10s apart to avoid throttle)
|
||||||
for (let i = 0; i < count; i++) {
|
for (let i = 0; i < count; i++) {
|
||||||
setTimeout(() => spawnBot(i), i * 10000);
|
setTimeout(() => spawnBot(i), i * 10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Periodically refill from Gemini
|
// Periodically refill from Gemini and Dolphin
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
if (promptPool.length < 10) refillPool();
|
if (promptPool.length < 10) refillPool();
|
||||||
}, 60000);
|
}, 60000);
|
||||||
|
|
||||||
|
setInterval(() => {
|
||||||
|
if (dolphinPool.length < 5) refillDolphinPool();
|
||||||
|
}, 120000);
|
||||||
|
|
||||||
// Graceful shutdown
|
// Graceful shutdown
|
||||||
process.on('SIGINT', () => {
|
process.on('SIGINT', () => {
|
||||||
console.log(`\n[${ts()}] Shutting down ${bots.length} bots...`);
|
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()}] Spawning ${count} prayer bots on ${host}:${port}`);
|
||||||
console.log(`[${ts()}] Using Gemini ${GEMINI_MODEL} for prompt generation`);
|
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()}] Interaction interval: 15-45s per bot`);
|
||||||
console.log(`[${ts()}] Press Ctrl+C to stop`);
|
console.log(`[${ts()}] Press Ctrl+C to stop`);
|
||||||
|
|||||||
Reference in New Issue
Block a user