Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

347
LINES

< > BotCompany Repo | #1002578 // Eleu Core (Include)

JavaX fragment (include)

set flag Matches_fsi.

static boolean hotwire_over_bot = false;

static int maxAnswerLength = 1000, shortenTo = 200;
static int askSelfMax = 10;

static L<S> botIDs = litlist("#1002317");
static L<S> generalReleaseBots = litlist();
static new L<Class> bots;
static new L<S> activeBots;
static Map<S, Class> botsByID = synchroTreeMap();

static new L<S> disabledBots;

// information for "answer" functions
static new ThreadLocal<S> userName;
static new ThreadLocal<S> slackTS;
static new ThreadLocal<S> channelName;
static new ThreadLocal<S> dialogID;
static new ThreadLocal<S> actualURI;
static ThreadLocal<Map<S, S>> uploadFiles = new ThreadLocal;
static new ThreadLocal<Boolean> attn;
static new ThreadLocal<Boolean> dedicated;
static new ThreadLocal<S> originalLine;
static new ThreadLocal<S> answeringBot;
static ThreadLocal<Set<S>> involvedBots = new ThreadLocal; // bots involved with making the current answer
static new ThreadLocal<S> postAs;
static new ThreadLocal<S> botIcon;

static volatile S loadingBotID;
static volatile Class loadingBot;
static volatile boolean loaded;

static new L<Map> history; // stores all processed user questions (not whole chat log)

static volatile S lastAnswerBy;
static volatile L<S> lastInvolvedBots;

static void coreInit() {
  load("disabledBots");
  reload();
  readLog();
  
  loaded = true;
}

static S answerImpl(S s, boolean generalRelease) {
  new Matches m;
  
  S whoSaidThat = lastAnswerBy;
  L<S> involvedBots = main.lastInvolvedBots;
  
  L<S> tok = javaTok(s);
  if (isInteger(get(tok, 1)) && eq(get(tok, 3), ":")) {
    Class bot = getBot(get(tok, 1));
    if (bot == null)
      ret "Bot not found: " + get(tok, 1);
    s = join(subList(tok, 5));
    S answer = callDehBots(litlist(bot), s);
    ret empty(answer) ? "(no answer)" : answer;
  }
  
  if "get home page bot" exceptionToUser {
    if (!hasField(mc(), "homePageBotID"))
      ret "Eleu was compiled without web integration";
      
    ret str(get(mc(), "homePageBotID"));
  }
  
  if (master()) {
    if "set home page bot *" exceptionToUser {
      S id = m.fsi(0);
      if (!hasField(mc(), "homePageBotID"))
        ret "Eleu was compiled without web integration";
        
      set(mc(), "homePageBotID", id);
      call(mc(), "save", "homePageBotID");
      ret format("OK, home page bot ID set to *", id);
    }
    
    if "set no home page bot *" exceptionToUser {
      S id = m.fsi(0);
      if (!hasField(mc(), "homePageBotID"))
        ret "Eleu was compiled without web integration";
        
      set(mc(), "homePageBotID", null);
      call(mc(), "save", "homePageBotID");
      ret format("OK, home page bot ID set to null");
    }
    
    if "disable bot *" {
      setAdd(disabledBots, formatSnippetID(m.unq(0)));
      save("disabledBots");
      ret "OK";
    }
    
    if "enable bot *" {
      disabledBots.remove(formatSnippetID(m.unq(0)));
      save("disabledBots");
      ret "OK";
    }
  }
  
  if (match("reboot", s) && master()) {
    int n = l(bots);
    cleanUp(bots);
    bots.clear();
    
    thread {
      sleepSeconds(1);
      
      // take latest args from source
      S vmArgs = cast loadVariableDefinition("vmArgs");
      
      directNohupJavax(getProgramID(), vmArgs);
      System.exit(100);
    }
    ret n(n, "bot") + " cleaned up. Rebooting...";
  }
  
  if (match("who said that", s))
    ret (whoSaidThat == null ? "what?" : whoSaidThat) + " / " + structure(lastInvolvedBots);
  
  if (match("reload", s) && master()) {
    time { reload(); }
    ret l(bots) + "/" + l(botIDs) + " bots reloaded in "+ getLastTiming() + " ms.";
  }
  
  if (match("reload *", s, m) && isSnippetID(m.unq(0)) && master()) {
    reload(m.unq(0));
    ret "Bot " + formatSnippetID(m.unq(0)) + " reloaded.";
  }
  
  if (match("list bots", s)) {
    S answer = "Active bots: " + structure(activeBots);
    L<S> inactiveBots = diff(botIDs, activeBots);
    if (!inactiveBots.isEmpty())
      answer += ". Inactive/disabled bots: " + structure(inactiveBots);
    if (!disabledBots.isEmpty())
      answer += ". Disabled bots: " + structure(disabledBots);
    ret answer;
  }
    
  if (match("test", s))
    ret "test me yes test me please!";
    
  ret callDehBots(generalRelease ? getGeneralReleaseBots() : bots, s);
}

static S callDehBots(L<Class> bots, S s) {
  answeringBot.set(null);
  involvedBots.set(new TreeSet);
  postAs.set(null);
  botIcon.set(null);
  for (Class c : bots) try {
    S botID = getBotID(c);
    if (disabledBots.contains(formatSnippetID(botID))) continue;
    //print("Calling bot " + botID);
    S answer = callStaticAnswerMethod(c, s);
    if (!empty(answer)) {
      S whoSaidIt = or((S) getOpt(c, "whoSaidThat"), botID);
      answeringBot.set(whoSaidIt);
      involvedBots.get().add(formatSnippetID(whoSaidIt));
      lastAnswerBy = whoSaidIt;
      lastInvolvedBots = new ArrayList(involvedBots.get());
      print("Answering bot: " + whoSaidIt);
      ret answer;
    }
  } catch (Throwable e) {
    print("Error calling " + getProgramID(c) + ":\n" + getStackTrace(e));
  }
  ret null;
}

static S getBotID(Class bot) {
  ret reverseLookup(botsByID, bot);
}

static int askSelfCounter;

static synchronized S askSelf(S s) {
  if (askSelfCounter >= askSelfMax)
    fail("Too much recursion asking myself (depth " + askSelfMax + ")");
  ++askSelfCounter;
  try {
    ret answer(s);
  } finally {
    --askSelfCounter;
  }
}

static synchronized S answer(S s) {
  ret answer(s, false);
}

static synchronized S answer(S s, boolean generalRelease) {
  long time = now();
  S a = "ERREUR";
  try {
    a = answerImpl(s, generalRelease);
  } finally {
    pcall {
      long x = now();
      // We should record which bot answered!
      Map map = litmap("startTime", time, "duration", x-time,
        "question", s, "answer", a, "botID", "?");
      printList(answerPriv(format("log timing *", structure(map))));
    }
  }
  ret a;
}

// can give multiple answers
static synchronized L<S> answerPriv(S s) {
  new L<S> l;
  for (Class bot : bots) pcall {
    S a = cast callOpt(bot, "answerPriv", s);
    if (!empty(a))
      l.add(a);
  }
  ret l;
}

static L<Class> getGeneralReleaseBots() {
  new L<Class> l;
  for (S botID : generalReleaseBots) {
    Class c = botsByID.get("" + parseSnippetID(botID));
    if (c != null)
      l.add(c);
  }
  ret l;
}

static void recordFeedback(S probableQuestion, S answer, S answerTime, S feedback, int score) {
  if (answer == null || probableQuestion == null) ret;

  Map data = litmap("realtime", now(), "question", probableQuestion, "answer", answer, "answertime", answerTime, "feedback", feedback, "score", score);
  print("Recording feedback: " + data);
  logQuoted(new File(programDir(), "feedback-log"), structure(data));
  logQuoted(new File(programDir(), "memory-log"), structure(data));
}

static void reloadLists() {
  botIDs = or((L<S>) loadVariableDefinition("botIDs"), botIDs);
  generalReleaseBots = or((L<S>) loadVariableDefinition("generalReleaseBots"), generalReleaseBots);
  botIDs.addAll(generalReleaseBots);
}

static void reload() {
  reloadLists();
  
  cleanUp(bots);
  activeBots = new ArrayList();
  botsByID.clear();
  for (S botID : botIDs)
    pcall {
      loadBot(botID);
    }
}

static void reload(S botID) {
  reloadLists();
  S parsedID = "" + parseSnippetID(botID);
  Class bot = botsByID.get(parsedID);
  if (bot != null) {
    cleanUp(bot);
    botsByID.remove(parsedID);
    activeBots.remove(formatSnippetID(botID));
    bots.remove(bot);
  }
  loadBot(botID);
}

static void loadBot(S botID) {
  botID = formatSnippetID(botID);
  if (!botIDs.contains(botID))
    fail("Bot not listed: " + botID);
    
  print("Loading bot: " + botID);
  Class c = hotwire_over_bot ? hotwire_overBot(botID) : hotwire(botID);
  setOpt(c, "mainBot", getMainClass());
  loadingBotID = botID;
  loadingBot = c;
  try {
    callMain(c);
    bots.add(c);
    activeBots.add(formatSnippetID(botID)); // only if loading doesn't fail
    botsByID.put("" + parseSnippetID(botID), c);
    print("Loaded bot: " + botID + ", bots now: " + l(activeBots));
  } finally {
    loadingBotID = null;
    loadingBot = null;
  }
}

static void readLog() {
  for (S prog : litlist("#1001915", getProgramID()))
    for (S s : scanLog(prog, "memory-log")) pcall {
      history.add((Map) safeUnstructure(s));
    }
  print(l(history) + " history entries.");
}

// query threadlocals (called by sub-bots)

static S getUserName() { ret userName.get(); }
static S getSlackTS() { ret slackTS.get(); }
static S getChannelName() { ret channelName.get(); }
static S getDialogID() { ret dialogID.get(); }
static S getActualURI() { ret actualURI.get(); }
static Map<S, S> getUploadFiles() { ret uploadFiles.get(); }
static S getOriginalLine() { ret originalLine.get(); }
static boolean isAddressed() { ret attn.get(); }
static boolean dedicated() { ret dedicated.get(); }
static Set getInvolvedBots() { ret involvedBots.get(); }

// get the sub-bot dispatcher (#1002317)
static O getDispatcher() {
  ret botsByID.get("" + parseSnippetID("#1002317"));
}

static Class getBot(S botID) {
  Class bot = botsByID.get("" + parseSnippetID(botID));
  if (bot == null) {
    O disp = getDispatcher();
    if (disp != null)
      ret (Class) call(disp, "getSubBot", botID);
  }
  ret bot;
}

static synchronized void historyAdd(Map logEntry) {
  logEntry.put("realtime", now());
  logEntry.put("dialogID", getDialogID());
  logEntry.put("involvedBots", toList(getInvolvedBots()));
  history.add(logEntry);
  logQuoted(new File(programDir(), "memory-log"), structure(logEntry));
}

static void postAs(S name) {
  postAs.set(name);
}

static void botIcon(S url) {
  botIcon.set(url);
}

download  show line numbers  debug dex  old transpilations   

Travelled to 15 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv

No comments. add comment

Snippet ID: #1002578
Snippet name: Eleu Core (Include)
Eternal ID of this version: #1002578/5
Text MD5: e37561bfb18cfed771b75f0feea0df4b
Author: stefan
Category: eleu
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2020-07-02 11:52:28
Source code size: 10041 bytes / 347 lines
Pitched / IR pitched: No / No
Views / Downloads: 814 / 2072
Version history: 4 change(s)
Referenced in: #1002017 - Eleutheria Main, including Slack Bot (LIVE)
#1002591 - Eleu Sister Main for tinybrain.de
#1002767 - Eleu 4 Desktop
#1002891 - Eleu Sock Puppet Test
#1013896 - Eleutheria Main for butter.botcompany.de + Stefan's OS (LIVE)
#1022823 - Eleutheria Main for butter.botcompany.de as Dyn Module [dev.]
#1023951 - agi.blue Standalone with GUI [OK]
#1024026 - Eleutheria Main for butter.botcompany.de (backup without Stefan's OS)
#3000202 - Answer for stefanreich (>> T conversion bot)
#3000238 - Answer for stefanreich (>> t power bot)
#3000382 - Answer for ferdie (>> t = 1, f = 0)
#3000383 - Answer for funkoverflow (>> t=1, f=0 okay)