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)

1  
set flag Matches_fsi.
2  
3  
static boolean hotwire_over_bot = false;
4  
5  
static int maxAnswerLength = 1000, shortenTo = 200;
6  
static int askSelfMax = 10;
7  
8  
static L<S> botIDs = litlist("#1002317");
9  
static L<S> generalReleaseBots = litlist();
10  
static new L<Class> bots;
11  
static new L<S> activeBots;
12  
static Map<S, Class> botsByID = synchroTreeMap();
13  
14  
static new L<S> disabledBots;
15  
16  
// information for "answer" functions
17  
static new ThreadLocal<S> userName;
18  
static new ThreadLocal<S> slackTS;
19  
static new ThreadLocal<S> channelName;
20  
static new ThreadLocal<S> dialogID;
21  
static new ThreadLocal<S> actualURI;
22  
static ThreadLocal<Map<S, S>> uploadFiles = new ThreadLocal;
23  
static new ThreadLocal<Boolean> attn;
24  
static new ThreadLocal<Boolean> dedicated;
25  
static new ThreadLocal<S> originalLine;
26  
static new ThreadLocal<S> answeringBot;
27  
static ThreadLocal<Set<S>> involvedBots = new ThreadLocal; // bots involved with making the current answer
28  
static new ThreadLocal<S> postAs;
29  
static new ThreadLocal<S> botIcon;
30  
31  
static volatile S loadingBotID;
32  
static volatile Class loadingBot;
33  
static volatile boolean loaded;
34  
35  
static new L<Map> history; // stores all processed user questions (not whole chat log)
36  
37  
static volatile S lastAnswerBy;
38  
static volatile L<S> lastInvolvedBots;
39  
40  
static void coreInit() {
41  
  load("disabledBots");
42  
  reload();
43  
  readLog();
44  
  
45  
  loaded = true;
46  
}
47  
48  
static S answerImpl(S s, boolean generalRelease) {
49  
  new Matches m;
50  
  
51  
  S whoSaidThat = lastAnswerBy;
52  
  L<S> involvedBots = main.lastInvolvedBots;
53  
  
54  
  L<S> tok = javaTok(s);
55  
  if (isInteger(get(tok, 1)) && eq(get(tok, 3), ":")) {
56  
    Class bot = getBot(get(tok, 1));
57  
    if (bot == null)
58  
      ret "Bot not found: " + get(tok, 1);
59  
    s = join(subList(tok, 5));
60  
    S answer = callDehBots(litlist(bot), s);
61  
    ret empty(answer) ? "(no answer)" : answer;
62  
  }
63  
  
64  
  if "get home page bot" exceptionToUser {
65  
    if (!hasField(mc(), "homePageBotID"))
66  
      ret "Eleu was compiled without web integration";
67  
      
68  
    ret str(get(mc(), "homePageBotID"));
69  
  }
70  
  
71  
  if (master()) {
72  
    if "set home page bot *" exceptionToUser {
73  
      S id = m.fsi(0);
74  
      if (!hasField(mc(), "homePageBotID"))
75  
        ret "Eleu was compiled without web integration";
76  
        
77  
      set(mc(), "homePageBotID", id);
78  
      call(mc(), "save", "homePageBotID");
79  
      ret format("OK, home page bot ID set to *", id);
80  
    }
81  
    
82  
    if "set no home page bot *" exceptionToUser {
83  
      S id = m.fsi(0);
84  
      if (!hasField(mc(), "homePageBotID"))
85  
        ret "Eleu was compiled without web integration";
86  
        
87  
      set(mc(), "homePageBotID", null);
88  
      call(mc(), "save", "homePageBotID");
89  
      ret format("OK, home page bot ID set to null");
90  
    }
91  
    
92  
    if "disable bot *" {
93  
      setAdd(disabledBots, formatSnippetID(m.unq(0)));
94  
      save("disabledBots");
95  
      ret "OK";
96  
    }
97  
    
98  
    if "enable bot *" {
99  
      disabledBots.remove(formatSnippetID(m.unq(0)));
100  
      save("disabledBots");
101  
      ret "OK";
102  
    }
103  
  }
104  
  
105  
  if (match("reboot", s) && master()) {
106  
    int n = l(bots);
107  
    cleanUp(bots);
108  
    bots.clear();
109  
    
110  
    thread {
111  
      sleepSeconds(1);
112  
      
113  
      // take latest args from source
114  
      S vmArgs = cast loadVariableDefinition("vmArgs");
115  
      
116  
      directNohupJavax(getProgramID(), vmArgs);
117  
      System.exit(100);
118  
    }
119  
    ret n(n, "bot") + " cleaned up. Rebooting...";
120  
  }
121  
  
122  
  if (match("who said that", s))
123  
    ret (whoSaidThat == null ? "what?" : whoSaidThat) + " / " + structure(lastInvolvedBots);
124  
  
125  
  if (match("reload", s) && master()) {
126  
    time { reload(); }
127  
    ret l(bots) + "/" + l(botIDs) + " bots reloaded in "+ getLastTiming() + " ms.";
128  
  }
129  
  
130  
  if (match("reload *", s, m) && isSnippetID(m.unq(0)) && master()) {
131  
    reload(m.unq(0));
132  
    ret "Bot " + formatSnippetID(m.unq(0)) + " reloaded.";
133  
  }
134  
  
135  
  if (match("list bots", s)) {
136  
    S answer = "Active bots: " + structure(activeBots);
137  
    L<S> inactiveBots = diff(botIDs, activeBots);
138  
    if (!inactiveBots.isEmpty())
139  
      answer += ". Inactive/disabled bots: " + structure(inactiveBots);
140  
    if (!disabledBots.isEmpty())
141  
      answer += ". Disabled bots: " + structure(disabledBots);
142  
    ret answer;
143  
  }
144  
    
145  
  if (match("test", s))
146  
    ret "test me yes test me please!";
147  
    
148  
  ret callDehBots(generalRelease ? getGeneralReleaseBots() : bots, s);
149  
}
150  
151  
static S callDehBots(L<Class> bots, S s) {
152  
  answeringBot.set(null);
153  
  involvedBots.set(new TreeSet);
154  
  postAs.set(null);
155  
  botIcon.set(null);
156  
  for (Class c : bots) try {
157  
    S botID = getBotID(c);
158  
    if (disabledBots.contains(formatSnippetID(botID))) continue;
159  
    //print("Calling bot " + botID);
160  
    S answer = callStaticAnswerMethod(c, s);
161  
    if (!empty(answer)) {
162  
      S whoSaidIt = or((S) getOpt(c, "whoSaidThat"), botID);
163  
      answeringBot.set(whoSaidIt);
164  
      involvedBots.get().add(formatSnippetID(whoSaidIt));
165  
      lastAnswerBy = whoSaidIt;
166  
      lastInvolvedBots = new ArrayList(involvedBots.get());
167  
      print("Answering bot: " + whoSaidIt);
168  
      ret answer;
169  
    }
170  
  } catch (Throwable e) {
171  
    print("Error calling " + getProgramID(c) + ":\n" + getStackTrace(e));
172  
  }
173  
  ret null;
174  
}
175  
176  
static S getBotID(Class bot) {
177  
  ret reverseLookup(botsByID, bot);
178  
}
179  
180  
static int askSelfCounter;
181  
182  
static synchronized S askSelf(S s) {
183  
  if (askSelfCounter >= askSelfMax)
184  
    fail("Too much recursion asking myself (depth " + askSelfMax + ")");
185  
  ++askSelfCounter;
186  
  try {
187  
    ret answer(s);
188  
  } finally {
189  
    --askSelfCounter;
190  
  }
191  
}
192  
193  
static synchronized S answer(S s) {
194  
  ret answer(s, false);
195  
}
196  
197  
static synchronized S answer(S s, boolean generalRelease) {
198  
  long time = now();
199  
  S a = "ERREUR";
200  
  try {
201  
    a = answerImpl(s, generalRelease);
202  
  } finally {
203  
    pcall {
204  
      long x = now();
205  
      // We should record which bot answered!
206  
      Map map = litmap("startTime", time, "duration", x-time,
207  
        "question", s, "answer", a, "botID", "?");
208  
      printList(answerPriv(format("log timing *", structure(map))));
209  
    }
210  
  }
211  
  ret a;
212  
}
213  
214  
// can give multiple answers
215  
static synchronized L<S> answerPriv(S s) {
216  
  new L<S> l;
217  
  for (Class bot : bots) pcall {
218  
    S a = cast callOpt(bot, "answerPriv", s);
219  
    if (!empty(a))
220  
      l.add(a);
221  
  }
222  
  ret l;
223  
}
224  
225  
static L<Class> getGeneralReleaseBots() {
226  
  new L<Class> l;
227  
  for (S botID : generalReleaseBots) {
228  
    Class c = botsByID.get("" + parseSnippetID(botID));
229  
    if (c != null)
230  
      l.add(c);
231  
  }
232  
  ret l;
233  
}
234  
235  
static void recordFeedback(S probableQuestion, S answer, S answerTime, S feedback, int score) {
236  
  if (answer == null || probableQuestion == null) ret;
237  
238  
  Map data = litmap("realtime", now(), "question", probableQuestion, "answer", answer, "answertime", answerTime, "feedback", feedback, "score", score);
239  
  print("Recording feedback: " + data);
240  
  logQuoted(new File(programDir(), "feedback-log"), structure(data));
241  
  logQuoted(new File(programDir(), "memory-log"), structure(data));
242  
}
243  
244  
static void reloadLists() {
245  
  botIDs = or((L<S>) loadVariableDefinition("botIDs"), botIDs);
246  
  generalReleaseBots = or((L<S>) loadVariableDefinition("generalReleaseBots"), generalReleaseBots);
247  
  botIDs.addAll(generalReleaseBots);
248  
}
249  
250  
static void reload() {
251  
  reloadLists();
252  
  
253  
  cleanUp(bots);
254  
  activeBots = new ArrayList();
255  
  botsByID.clear();
256  
  for (S botID : botIDs)
257  
    pcall {
258  
      loadBot(botID);
259  
    }
260  
}
261  
262  
static void reload(S botID) {
263  
  reloadLists();
264  
  S parsedID = "" + parseSnippetID(botID);
265  
  Class bot = botsByID.get(parsedID);
266  
  if (bot != null) {
267  
    cleanUp(bot);
268  
    botsByID.remove(parsedID);
269  
    activeBots.remove(formatSnippetID(botID));
270  
    bots.remove(bot);
271  
  }
272  
  loadBot(botID);
273  
}
274  
275  
static void loadBot(S botID) {
276  
  botID = formatSnippetID(botID);
277  
  if (!botIDs.contains(botID))
278  
    fail("Bot not listed: " + botID);
279  
    
280  
  print("Loading bot: " + botID);
281  
  Class c = hotwire_over_bot ? hotwire_overBot(botID) : hotwire(botID);
282  
  setOpt(c, "mainBot", getMainClass());
283  
  loadingBotID = botID;
284  
  loadingBot = c;
285  
  try {
286  
    callMain(c);
287  
    bots.add(c);
288  
    activeBots.add(formatSnippetID(botID)); // only if loading doesn't fail
289  
    botsByID.put("" + parseSnippetID(botID), c);
290  
    print("Loaded bot: " + botID + ", bots now: " + l(activeBots));
291  
  } finally {
292  
    loadingBotID = null;
293  
    loadingBot = null;
294  
  }
295  
}
296  
297  
static void readLog() {
298  
  for (S prog : litlist("#1001915", getProgramID()))
299  
    for (S s : scanLog(prog, "memory-log")) pcall {
300  
      history.add((Map) safeUnstructure(s));
301  
    }
302  
  print(l(history) + " history entries.");
303  
}
304  
305  
// query threadlocals (called by sub-bots)
306  
307  
static S getUserName() { ret userName.get(); }
308  
static S getSlackTS() { ret slackTS.get(); }
309  
static S getChannelName() { ret channelName.get(); }
310  
static S getDialogID() { ret dialogID.get(); }
311  
static S getActualURI() { ret actualURI.get(); }
312  
static Map<S, S> getUploadFiles() { ret uploadFiles.get(); }
313  
static S getOriginalLine() { ret originalLine.get(); }
314  
static boolean isAddressed() { ret attn.get(); }
315  
static boolean dedicated() { ret dedicated.get(); }
316  
static Set getInvolvedBots() { ret involvedBots.get(); }
317  
318  
// get the sub-bot dispatcher (#1002317)
319  
static O getDispatcher() {
320  
  ret botsByID.get("" + parseSnippetID("#1002317"));
321  
}
322  
323  
static Class getBot(S botID) {
324  
  Class bot = botsByID.get("" + parseSnippetID(botID));
325  
  if (bot == null) {
326  
    O disp = getDispatcher();
327  
    if (disp != null)
328  
      ret (Class) call(disp, "getSubBot", botID);
329  
  }
330  
  ret bot;
331  
}
332  
333  
static synchronized void historyAdd(Map logEntry) {
334  
  logEntry.put("realtime", now());
335  
  logEntry.put("dialogID", getDialogID());
336  
  logEntry.put("involvedBots", toList(getInvolvedBots()));
337  
  history.add(logEntry);
338  
  logQuoted(new File(programDir(), "memory-log"), structure(logEntry));
339  
}
340  
341  
static void postAs(S name) {
342  
  postAs.set(name);
343  
}
344  
345  
static void botIcon(S url) {
346  
  botIcon.set(url);
347  
}

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: 815 / 2073
Version history: 4 change(s)
Referenced in: [show references]