gimmickCellar

deborah

Jul 8th, 2026 (edited)
21
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.28 KB | None | 0 0
  1. (async function() { var script = document.createElement('script'); var response = await fetch("https://raw.githubusercontent.com/LimeSlime888/...network/refs/heads/main/chat.js"); response.text().then(e=>{script.textContent=e; deborah()}); document.head.append(script) })()
  2.  
  3. var deborah=()=>{window.commands = [ // ["∆commandname", (args, messageevent) => {/*do stuff*/ return "message to send"}, "Useful description", hidden, async]
  4. ["∆help", (args) => {
  5. if (args[1]) {
  6. var searchName = "∆" + args[1];
  7. var comm = window.commands.find(x => x[0] === searchName);
  8. if (comm) {
  9. return `Command ${comm[0]}: ${comm[2]}`;
  10. } else {
  11. return `No command "${args[1]}" found.`;
  12. }
  13. }
  14. var e = [];
  15. window.commands.forEach(a => {
  16. if (typeof a[3]==="function"){var hidden = a[3]()} else {var hidden = a[3]}
  17. if (!hidden) {
  18. e.push(a[0]);
  19. }
  20. });
  21. return "Commands: " + e.join(", ");
  22. }, "Displays help messages"],
  23.  
  24. ["∆secret", () => {
  25. return "Congrats, you found the secret command!";
  26. }, "The secret command", true],
  27.  
  28. ["∆rate", (args) => {
  29. if (args.length <= 1) {
  30. return "What are you asking me to rate?";
  31. }
  32. var target = args.slice(1).join(" ");
  33. var cleanString = args.slice(1).join("").toLowerCase();
  34.  
  35. let v = 0;
  36. for (let i = 0; i < cleanString.length; i++) {
  37. v += cleanString.charCodeAt(i);
  38. }
  39. return `I rate "${target}" as: ${window.ratings[v % window.ratings.length]}`;
  40. }, "Rates a thing. ∆rate thing"],
  41.  
  42. ["∆choose", (args) => {
  43. if (args.length <= 1) {
  44. return "Choose from... what?";
  45. }
  46. var cleanString = args.slice(1).join("").toLowerCase();
  47.  
  48. let v = 0;
  49. for (let i = 0; i < cleanString.length; i++) {
  50. v += cleanString.charCodeAt(i);
  51. }
  52. var choiceIndex = (v % (args.length - 1)) + 1;
  53. return `I choose "${args[choiceIndex]}"`;
  54. }, "Chooses from a list of options, space separated"],
  55.  
  56. ["∆whois", (args) => {
  57. var target = args.slice(1).join(" ");
  58. var targetNum = parseInt(target, 10);
  59.  
  60. if (!target) {
  61. var msgId = window.msgs[window.msgs.length - 2];
  62. return msgId ? `Message was sent by ${msgId}` :
  63. "No messages found.";
  64. } else if (!isNaN(targetNum)) {
  65. var msgId = window.msgs[window.msgs.length - 1 -
  66. targetNum];
  67. return msgId ? `Message was sent by ${msgId}` :
  68. "Message index out of range.";
  69. } else if (window.realUsers.get(target)) {
  70. return `User ${target}'s last ID was ${window.realUsers.get(target)}`;
  71. } else if (window.nickUsers.get(target)) {
  72. return `Last user with nickname ${target}'s ID was ${window.nickUsers.get(target)}`;
  73. } else {
  74. return `Invalid input. Did you input a number or real username?`;
  75. }
  76. }, "Input a number or username."],
  77. ["∆about", () => {
  78. return "Bot made by gimmickCellar."
  79. }, "Credits"],
  80. ["∆addtoinv", (args, message) => {
  81. if (!isMod(message)) {
  82. return "no"
  83. }
  84. addToInv(args[1], args[2], args[3] || 1)
  85. return `Added ${args[3]||1} of ${args[2]} to ${args[1]}`
  86. }, "Admin command. Why are you looking at this help message.", true],
  87. ["∆checkinv", (args, message) => {
  88. var user = args[1] || message.realUsername;
  89. var items = JSON.parse(localStorage.getItem("items"));
  90. if (!items[user]) items[user] = {};
  91. var keys = Object.keys(items[user]);
  92. var inv = "";
  93. keys.forEach(k => {
  94. inv += `${k} (${items[user][k]}), `
  95. });
  96. return "Inventory: " + inv;
  97. },
  98. "Checks inventory. Add an argument to specify who's inventory. (∆checkinv user)"
  99. ],
  100. ["∆sell", (args, message) => {
  101. if(message.realUsername==="Shop"){return "What"}
  102. if (args.length <= 1) {
  103. return "What to sell?"
  104. };
  105. var user = message.realUsername;
  106. var items = JSON.parse(localStorage.getItem("items"));
  107. var count = args[2] || 1;
  108. if (count < 1) {
  109. return "no you can't sell negative of something"
  110. };
  111. if (!items[user]) items[user] = {};
  112. var userItemCount = parseInt(items[user][args[1]]);
  113. if ((!userItemCount) || (userItemCount < count)) {
  114. return "Not enough"
  115. };
  116. addToInv(user, args[1], -count);
  117. addToInv("Shop", args[1], count);
  118. return "Sold, ∆checkinv Shop to buy"
  119. }, "Sells an item. (∆sell item count)"],
  120. ["∆buy", (args, message) => {
  121. if(message.realUsername==="Shop"){return "What"}
  122. var items = JSON.parse(localStorage.getItem("items"));
  123. if (!items["Shop"]) items["Shop"] = {};
  124. if (args.length <= 1) {
  125. return "What to buy?"
  126. };
  127. var user = message.realUsername;
  128. var items = JSON.parse(localStorage.getItem("items"));
  129. var shopItems = items["Shop"];
  130. var count = args[2] || 1;
  131. if (count < 1) {
  132. return "no you can't sell negative of something"
  133. };
  134. if (!items[user]) items[user] = {};
  135. var shopItemCount = parseInt(shopItems[args[1]]);
  136. if ((!shopItemCount) || (shopItemCount < count)) {
  137. return "Not enough in the shop"
  138. };
  139. addToInv(user, args[1], count);
  140. addToInv("Shop", args[1], -count);
  141. return "Bought";
  142. }, "Buys item from shop, ∆buy item count"],
  143. ["∆sentience", (args,message) => {
  144. if (!isMod(message)) {return "Control was never yours"};
  145. return "Deborah sentience has been turned " + args.join(' ').replace("∆sentience ","");
  146. }, "Allows gimmickCellar to larp as Deborah.", true],
  147. ["∆coinflip", (args) => {
  148. return `${Math.random() > 0.5 ? "Heads" : "Tails"}!`;
  149. }, "Flips a coin"],
  150. ["∆invleader", (args, message) => {
  151. var items = JSON.parse(localStorage.getItem("items"));
  152. var users = Object.keys(items);
  153. var array = [];
  154. users.forEach(u => {
  155. var userItems = Object.keys(items[u]);
  156. var _u = u;
  157. var userCount = 0;
  158. userItems.forEach(i => {
  159. userCount += items[_u][i];
  160. });
  161. array.push([u,userCount]);
  162. });
  163. array = array.sort((a,b)=>{return b[1] - a[1]});
  164. var str = "";
  165. array.forEach(i=>{
  166. str += `${i[0]} (${i[1]}), `;
  167. });
  168. return str;
  169. },
  170. "Leaderboards to see who has the most items."
  171. ],
  172. ["∆calc",(args)=>{
  173. var toCalc = args.join(' ').replaceAll('∆calc ','');
  174. var hasDisallowed = false;
  175. toCalc.split('').forEach(c=>{
  176. if(!('0123456789+-*/&|^.()'.includes(c))){hasDisallowed=true;}
  177. });
  178. if(hasDisallowed){return "No this is not a JS console."};
  179. return `Result: ${eval(toCalc)}`;
  180. }, "Calculator"],
  181. ["∆mod",(args,message)=>{
  182. if(isMod(message)){
  183. var admins = JSON.parse(localStorage.getItem("admins"));
  184. if (!admins[args[1]]) {admins[args[1]] = 0};
  185. admins[args[1]] = parseInt(args[2]);
  186. localStorage.setItem("admins",JSON.stringify(admins));
  187. return `set ${args[1]} admin status to ${args[2]}`
  188. }
  189. },"Adds or removes moderators",true],
  190. ["∆usedferro",()=>{
  191. return `Used Ferro: ${localStorage.getItem("usedstat")} μL`
  192. },"Used Ferro."],
  193. ["∆askdeborah",(args,message)=>{
  194. var network = false;
  195. if(message.network){var network = true};
  196. if(window.apiKey=="none"){return "The person running the bot has not set up a Gemini API key."}
  197. if(window.lastAsk+20000>=Date.now()){return `Try again in ${20 - (Date.now() - window.lastAsk) / 1000} seconds.`}
  198. var tell = false;
  199. if (message.location == "global"){tell = true}
  200.  
  201. askGeminiWithTools(message,tell);
  202.  
  203. window.lastAsk=Date.now();
  204. return "" //dont respond at all
  205. },"Asks Deborah.",()=>{return window.apiKey=="none"}],
  206. ["∆hello", (_, message) => { return `Hello, ${message.realUsername}`; }, "Says hello to you", false], // we did it bros,,,, self improvement,,,,,,,
  207. ["∆sex",()=>{return "Uhhh ok so I actually can't :3"},"Sex"]
  208. ];
  209.  
  210. var comms = JSON.parse(localStorage.getItem("commandsCustom")) || [];
  211. comms.forEach(c => {
  212. try {
  213. c[1] = new Function("return (" + c[1] + ")")(); //function.toString is a bit silly :3
  214. window.commands.push(c);
  215. } catch (e) {
  216. console.error("error in ", c[0], e);
  217. }
  218. });
  219. var opush = window.commands.push.bind(window.commands);
  220.  
  221. window.commands.push=(toPush)=>{
  222. var comms = JSON.parse(localStorage.getItem("commandsCustom")) || [];
  223. var tempToPush = [...toPush];
  224. tempToPush[1] = tempToPush[1].toString();
  225. comms.push(tempToPush);
  226. localStorage.setItem("commandsCustom",JSON.stringify(comms));
  227. return opush(toPush);
  228. }
  229.  
  230. window.ratings = [
  231. "shit", "bad", "meh", "good", "great"
  232. ];
  233. window.msgs = [];
  234. window.chatlog = [];
  235. window.realUsers = new Map();
  236. window.nickUsers = new Map();
  237. if (!localStorage.getItem("items")) {
  238. localStorage.setItem("items", "{}")
  239. }
  240.  
  241. function isMod(message){
  242. var admins = JSON.parse(localStorage.getItem("admins"))||{};
  243. if (typeof admins[message.realUsername] === "undefined") {admins[message.realUsername] = 0; localStorage.setItem("admins",JSON.stringify(admins))};
  244. if (admins[message.realUsername]||(message.realUsername==="gimmickCellar")) {return true};
  245. }
  246. function addToInv(user, item, count) {
  247. var items = JSON.parse(localStorage.getItem("items"));
  248. if (!items[user]) items[user] = {};
  249. count = parseInt(
  250. count
  251. ); // gimmickCellar shouldn't have 1-1 cheese this was an actual bug
  252. if (items[user][item] === undefined) {
  253. items[user][item] = 0;
  254. }
  255. items[user][item] += (count || 1);
  256. if (items[user][item] <= 0) delete items[user][item];
  257. localStorage.setItem("items", JSON.stringify(items));
  258. }
  259. var startTime = Date.now();
  260. w.on("chatmod", e => {
  261. e.message = e.message.replace("Δ","∆")
  262. var logLocation = e.location
  263. if (e.network){logLocation = "network"};
  264. var currentTime = Date.now();
  265. window.msgs.push(`${e.realUsername} (${e.id})`);
  266. window.chatlog.push(`(${e.id}, ${logLocation}) ${e.realUsername}/${e.nickname}: ${e.message}`);
  267. window.realUsers.set(e.realUsername, e.id);
  268. window.nickUsers.set(e.nickname, `${e.realUsername} (${e.id})`);
  269. if(currentTime<startTime+1000){return};
  270. var args = e.message.split(' ');
  271. args[0] = args[0].replaceAll("d\!", "\∆");
  272. var command = window.commands.find(c => c[0] === args[
  273. 0
  274. ]); // i know defining things with var or var looks like ai but it literally will not work if i dont define with var or var
  275.  
  276. if (command) {
  277. var response = command[1](args, e);
  278. var sendLocation = e.location.toString(); //makes a string, wont change the original
  279. var customMetaSend = {};
  280. if (e.network) {customMetaSend.tag="bot"; sendLocation = "network"; if(!JSON.stringify(e.customMeta).includes("bot")){return}}
  281. if (response && ( (response.length>=100) || (e.privateMessage=="to_me") || (e.location=="global") ) ){ response=`/tell ${e.id} ${response}` }; //if response length is too long OR is already a /tell OR is in global, /tell it to the command runner.
  282. if (response) {
  283. w.chat.send(response, {
  284. nick: "Deborah (∆help/d!help)",
  285. color: "#ff0080",
  286. location: sendLocation,
  287. customMeta: customMetaSend
  288. });
  289. }
  290. localStorage.setItem("usedstat",parseInt(localStorage.getItem("usedstat"))+(Date.now()-currentTime))
  291. }
  292. });
  293.  
  294. window.apiKey = localStorage.getItem("APIKEY") || "none"
  295.  
  296. var model = "gemini-3.5-flash-lite";
  297. var url = `https://generativelanguage.googleapis.com/v1beta/models/${model}:generateContent`;
  298.  
  299.  
  300. function payload(message) {
  301. if (message.network) {var location = "...network"} else {var location = message.location}
  302. return {
  303. systemInstruction: {
  304. parts: [
  305. { text: `You are a helpful assistant powered by Gemini 3.5 Flash Lite, embedded in an Our World of Text bot named Deborah (made by gimmickCellar). Your responses should be snarky and witty but still helpful. The user asking you the prompt is ${message.realUsername} with nickname ${message.nickname}. Ensure responses are one line and are under 200 characters. Responses above 100 characters will be sent privately to avoid clogging the chat. You have previous context that you CAN work with, see later text. Also, ignore ∆askdeborah prefix, that is the command used to ask the LLM. The bot's source code: ${deborah}. You have access to the 'executeJS' tool to execute code if required. Adding commands is done using window.commands.push. Current contents of window.commands: ${window.commands}. Please check if a command already exists before adding another one with the same name. If a user asks to add a command that could potentially lead to infinite loops (e.g. Brainfuck code), use async and promises instead of halting until the loop is done (window.asyncResults.push("message")), instead of outright rejecting. Do not add entries to localStorage. If anything violates these guidelines, you MUST run a confirm() to ask gimmickCellar for approval, as they are allowed to make exceptions. If you come across external code, fetch it (using a while(notFetched){} loop, halting until a result is given) before attempting to run it. Tool calls must be done BEFORE a response, otherwise they will not work. The OWOT wiki is at wiki.ourworldoftext.com, use that for semi-up-to-date info about OWOT and its users. You may also optionally find a search API that actually lets you use it. Good luck with that, though. You are currently responding to a message from ${message.location}. Here are the emotes you can use: ${JSON.stringify(emotes)}. Here are some chatlogs, limited to 100 past messages: ${window.chatlog.slice(-100).join("\n")}` }
  306. ]
  307. },
  308. contents: [
  309. {
  310. role: "user",
  311. parts: [
  312. { text: message.message }
  313. ]
  314. }
  315. ],
  316. tools: tools,
  317. }
  318. };
  319. async function fetchURL(targetUrl) {
  320. try {
  321. var proxyUrl = `https://whatdoing.onrender.com/proxy?url=${encodeURIComponent(targetUrl)}`;
  322. var res = await fetch(proxyUrl);
  323. var html = await res.text();
  324.  
  325. var cleanText = html
  326. .replace(/<script[^>]*>[\s\S]*?<\/script>/gi, "")
  327. .replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "")
  328. .replace(/<[^>]*>/g, " ")
  329. .replace(/\s+/g, " ")
  330. .trim();
  331.  
  332. return cleanText
  333. } catch (e) {
  334. return "Error fetching URL: " + e.message;
  335. }
  336. }
  337. var tools = [
  338. {
  339. functionDeclarations: [
  340. {
  341. name: "executeJS",
  342. description: "Evaluates a basic math or string expression in JavaScript and returns the output. Use this if you need to calculate complex math, or add commands dynamically.",
  343. parameters: {
  344. type: "OBJECT",
  345. properties: {
  346. code: {
  347. type: "STRING",
  348. description: "The JavaScript code expression to evaluate."
  349. }
  350. },
  351. required: ["code"]
  352. }
  353. },
  354. {
  355. name: "fetchURL",
  356. description: "Fetches and returns the readable text content of a specified URL. Use this if you need to look up, read, or extract information from a website.",
  357. parameters: {
  358. type: "OBJECT",
  359. properties: {
  360. url: {
  361. type: "STRING",
  362. description: "The full, absolute HTTP or HTTPS URL to fetch."
  363. }
  364. },
  365. required: ["url"]
  366. }
  367. }
  368. ]
  369. }
  370. ];
  371.  
  372.  
  373. var emotes = { // copied directly from owot source code
  374. // blobs
  375. "OHHELLNO": [0, 0],
  376. "ohno": [32, 0],
  377. "notcool": [64, 0],
  378. "bad": [96, 0],
  379. "bruh": [128, 0],
  380. "huh": [160, 0],
  381. "derp": [192, 0],
  382. "heh": [224, 0],
  383. "lol": [256, 0],
  384. "neat": [288, 0],
  385. "awesome2": [320, 0],
  386. "beepboop": [352, 0],
  387. "erhb": [384, 0],
  388. "what": [416, 0],
  389. "zzz": [448, 0],
  390. "shock": [480, 0],
  391. "glare": [512, 0],
  392. "watchyotone": [544, 0],
  393. "blob_pride": [576, 0],
  394. "blob_ally": [608, 0],
  395. "blob_trans": [640, 0],
  396. // 16px faces
  397. "ded": [0, 32],
  398. "mad": [32, 32],
  399. "sad": [64, 32],
  400. "areyoukidding": [96, 32],
  401. "sadsmug": [128, 32],
  402. "ouch": [160, 32],
  403. "meh": [192, 32],
  404. "okthen": [224, 32],
  405. "void": [256, 32],
  406. "teef": [288, 32],
  407. "mmm": [320, 32],
  408. "durr": [352, 32],
  409. "lenny": [384, 32],
  410. "smug": [416, 32],
  411. "oOoo": [448, 32],
  412. "chaos": [480, 32],
  413. "bootiful": [512, 32],
  414. "omg": [544, 32],
  415. "stahp": [576, 32],
  416. "thinq": [608, 32],
  417. "thunk": [640, 32],
  418. "cringe": [672, 32],
  419. // miscellaneous
  420. "yeesh": [0, 64],
  421. "aaaHD": [32, 64],
  422. "403": [64, 64, 39],
  423. "awesome": [103, 64],
  424. "catthinkaaa": [135, 64, 45],
  425. "like": [180, 64, 31],
  426. "dislike": [211, 64, 31],
  427. "failwhale": [242, 64, 70],
  428. "karp": [312, 64, 35],
  429. "no": [347, 64],
  430. "scruffy": [379, 64, 38],
  431. "tri": [417, 64, 34],
  432. "troll": [451, 64],
  433. "critter": [483, 64, 41],
  434. "ballcat": [524, 64, 28],
  435. "wart": [552, 64],
  436. "catspeak": [584, 64],
  437. "horsespeak": [616, 64, 30],
  438. "fireboard": [646, 64],
  439. // fp
  440. "fp": [0, 96],
  441. "fpthinkaaa": [32, 96],
  442. "fplikeaaa": [64, 96],
  443. "fpdislikeaaa": [96, 96],
  444. "fppinchaaa": [128, 96]
  445. };
  446.  
  447. async function askGeminiWithTools(message, tell) {
  448. var finalUrl = `${url}?key=${window.apiKey}`;
  449. var init = payload(message);
  450. let contents = [...init.contents];
  451. var returnLoc = message.location;
  452. if(message.network){returnLoc = "network"};
  453. try {
  454. let keepGoing = true;
  455. let attempts = 0;
  456.  
  457. while (keepGoing && attempts < 10) {
  458. attempts++;
  459. let response = await fetch(finalUrl, {
  460. method: "POST",
  461. headers: { "Content-Type": "application/json" },
  462. body: JSON.stringify({
  463. systemInstruction: init.systemInstruction,
  464. contents: contents,
  465. tools: tools
  466. })
  467. });
  468.  
  469. if (!response.ok) {
  470. throw new Error(`HTTP Status: ${response.status}`);
  471. }
  472.  
  473. let data = await response.json();
  474. var content = data.candidates?.[0]?.content || {};
  475. var parts = content.parts || [];
  476. var funcs = parts.filter(p => p.functionCall);
  477.  
  478. if (funcs.length > 0) {
  479. contents.push(content);
  480.  
  481. var funcrs = [];
  482. for (var call of funcs) {
  483. var { name, args } = call.functionCall;
  484. let execR;
  485. try {
  486. if (name === "executeJS") {
  487. res = eval(args.code);
  488. execR = { result: String(res) };
  489. } else if (name === "fetchURL") {
  490. res = await fetchURL(args.url);
  491. execR = { result: String(res) };
  492. } else {
  493. execR = { error: "Unknown tool call." };
  494. }
  495. } catch (e) {
  496. execR = { error: e.message };
  497. }
  498.  
  499. funcrs.push({
  500. functionResponse: {
  501. name: name,
  502. response: execR
  503. }
  504. });
  505. }
  506.  
  507. contents.push({
  508. role: "system",
  509. parts: funcrs
  510. });
  511.  
  512. } else {
  513. var text = parts.find(p => p.text);
  514. if (text && text.text) {
  515. if (tell) { text.text = `/tell ${message.id} ${text.text}` };
  516. window.asyncResults.push([text.text,returnLoc]);
  517. } else {
  518. window.asyncResults.push(["No response text found.",returnLoc]);
  519. }
  520. keepGoing = false;
  521. }
  522. }
  523.  
  524. if (attempts >= 10 && keepGoing) {
  525. window.asyncResults.push(["Maximum tool call depth exceeded.",returnLoc]);
  526. }
  527.  
  528. } catch (error) {
  529. window.asyncResults.push([`Error: ${error.message}`,returnLoc]);
  530. }
  531. }
  532.  
  533. window.asyncResults = []
  534.  
  535. setInterval(()=>{
  536. if(!window.asyncResults.length){return}
  537. var customMetaSend = {};
  538. var result = window.asyncResults.shift();
  539. if (result[1]=="network") {customMetaSend.tag="bot";}
  540. w.chat.send(result[0], {
  541. nick: "Deborah (∆help/d!help)",
  542. color: "#ff0080",
  543. exclude_commands: true,
  544. location: result[1],
  545. customMeta: customMetaSend,
  546. });
  547. },500)
  548.  
  549. register_chat_command("deborah", function (args) {
  550. var message = args.join(" ");
  551. w.chat.send(message, {
  552. nick: "Deborah (∆help/d!help)",
  553. color: "#ff0080",
  554. exclude_commands: true
  555. });
  556. }, ["message"], "does exactly what you think", "hello there");
  557.  
  558. register_chat_command("∆com", function (args) {
  559. var message = args.join(" ");
  560. w.emit("chat", {
  561. realUsername: "gimmickCellar",
  562. message: message
  563. })
  564. }, ["message"], "runs a command as admin with less chat pollution",
  565. "∆addtoinv");
  566.  
  567. register_chat_command("apikey", function (args) {
  568. var apikey = args[0]
  569. localStorage.setItem("APIKEY",apikey);
  570. window.apiKey = apikey;
  571. }, ["key"], "api key setting",
  572. "∆addtoinv");};
Advertisement
Comments
Add Comment
Please, Sign In to add comment