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

1689
LINES

< > BotCompany Repo | #1010745 // Smart Bot (LIVE)

JavaX source code (desktop) [tags: transpile-externally use-pretranspiled] - run with: x30.jar

Download Jar. Uses 17395K of libraries. Click here for Pure Java version (44978L/280K).

1  
!7
2  
3  
set flag hotwire_here. // to honor classesToShare
4  
5  
sbool greetCookies, theoryOn;
6  
7  
sbool cloned;
8  
static long clonedSince, cloningSince;
9  
sS postStartUpMessageToChat;
10  
static new L thoughtBots;
11  
static long started, indexMakingTime, bootTime;
12  
static Class theoryModule;
13  
static Lock theoryLock = lock();
14  
static S selectedWord;
15  
static int inputNr = 1;
16  
static int myPort = 4678;
17  
static int ultimateAnswerLimit = 500000;
18  
static double speculationTimeoutForHttp = 5.0; // 5 seconds
19  
static double speculationTimeoutForNewChatLine = 30.0;
20  
static int autoComplete_timeOut = 1000; // 1 second
21  
static Set<S> speculationQueue = synchroHashSet();
22  
static double spammerSleep = 10.0;
23  
static Set<S> blockedIPs = synchroHashSet();
24  
25  
sS classesToShare = smartBot_sharedClasses();
26  
27  
static Lock aiLock = lock();
28  
static new ThreadLocal<Bool> httpAuthed;
29  
static Map<S, L<S>> lastUserLines = syncCIMap();
30  
static new ThreadLocal<L> afterAnswering;
31  
static new ThreadLocal<Bool> answering;
32  
static L<GlobalID> latestWebs = synchroList(LatestList(1000));
33  
34  
static TimedCache<Int> cachedNumberOfThreads = TimedCache(f numberOfAllThreads, 10.0);
35  
36  
static L<S> tripleAnswerFunctions = ll(
37  
  f ai_tripleAnswer_regexpMatches
38  
);
39  
40  
set flag allpublic.
41  
42  
// save space
43  
sclass E {}
44  
set flag noCLParse.
45  
46  
p {
47  
  set profilePoint_print;
48  
  print("yo");
49  
  started = sysNow();
50  
  try { setGCFrequency(10*60.0); // 10 minutes
51  
  } catch { updateJavaXAndRestart(); }
52  
  
53  
  doEvery(10*60*1000, r { blockedIPs.clear() });
54  
  
55  
  ai_useThoughtSpaces(true);
56  
  cachedNodeIndex_autoMake = false;
57  
  releaseDBLockOnTimeoutEval();
58  
  ai_prepLoadFunctions();
59  
60  
  //set postToStefansChat_printStackTrace;
61  
  db();
62  
  load('selectedWord);
63  
  load('inputNr);
64  
  //autoRestart(5);
65  
  //typicalDownload();
66  
  
67  
  O webSocketFactory = f makeWebSocket;
68  
  if (canOccupyPort80())
69  
    serveHttpWithWebsockets_multiplePorts(webSocketFactory, myPort, 80);
70  
  else
71  
    serveHttpWithWebsockets(myPort, webSocketFactory);
72  
  pcall { serveHttps_botCompany(); }
73  
  
74  
  bot("Smart Bot.", func(S s) -> S {
75  
    S x = "Input line " + (inputNr++);
76  
    print(x);
77  
    save("inputNr");
78  
    ai_postTriple(x, "is", quote(s));
79  
    //ai_speculate(x);
80  
81  
    stefansChat_onLine_fullParams.set(litmap(auth := true));
82  
    try {
83  
      ret actualAnswer(s);
84  
    } finally {
85  
      stefansChat_onLine_fullParams.set(null);
86  
    }
87  
  });
88  
  
89  
  loadPage_forcedTimeout = 70000;
90  
  thoughtBots.add(mc());
91  
92  
  indexMakingTime = sysNow();
93  
94  
  ai_fillTripleIndex();
95  
  //tripleIndex().addWeb(web_setGlobalID("abcdefghijklmnop", webFromTriple("It's", "a", "test")));
96  
97  
  indexMakingTime = sysNow()-indexMakingTime;
98  
  
99  
  // TODO ai_onNewIndexedText_do(func(S s) { speculationQueue.add(s) });
100  
  
101  
  //thoughtBots.add(memoryBot = runSubBot(#1001951));
102  
  
103  
  handleStefansChat();
104  
  handleSmartBotsChat();
105  
  
106  
  //stefansChat_post("Smart Bot Upgraded! Boot took: " + formatDouble(fromMS(sysNow()-started), 1) + " s");
107  
  
108  
  if (greetCookies) runInNewThread(#1010793); // Post on UAIP
109  
  
110  
  ai_onNewWeb(f ai_spec_moveToMiddle);
111  
  ai_onNewWeb(f addToLatestWebs);
112  
  ai_extendKnownVerbs();
113  
  
114  
  // Do the slow stuff
115  
  
116  
  addVirtualNodeIndex(hugeEnglishDictionary_virtualNodeIndex());
117  
  loadTheory();
118  
  
119  
  thread "Speculator" { speculatorLoop(); }
120  
  
121  
  doneLoading();
122  
  bootTime = sysNow()-started;
123  
  if (cloned)
124  
    postToChatNamed(postStartUpMessageToChat, infoBoxAndReturn(
125  
      "Smart Bot cloned in " + formatSeconds(bootTime, 1) + "s ("
126  
      + formatSeconds(sysNow()-clonedSince, 1) + "s full)"));
127  
  else
128  
    infoBox("Smart Bot booted in " + formatSeconds(bootTime, 1) + "s");
129  
}
130  
131  
sS actualAnswer(S s) {
132  
  ret scanMultipleBots(thoughtBots, s);
133  
}
134  
135  
svoid loadTheory {
136  
  lock theoryLock;
137  
  cleanUp(theoryModule);
138  
  theoryModule = null;
139  
  if (!theoryOn) ret;
140  
  theoryModule = run(#1010963);
141  
  setOpt(theoryModule, 'onUpdate, r { call(theoryModule, 'react) });
142  
  call(theoryModule, 'react);
143  
  print("Theory module loaded.");
144  
}
145  
146  
static int lineCount;
147  
148  
sbool authed() {
149  
  ret isTrue(mapGet(stefansChat_onLine_fullParams!, 'auth))
150  
    || webAuthed();
151  
}
152  
153  
sbool byBot() {
154  
  ret isTrue(mapGet(stefansChat_onLine_fullParams!, 'botMark));
155  
}
156  
157  
answer ctex {
158  
  if (byBot()) null;
159  
  /*temp tempSetThreadLocal(answering, true);
160  
  try {*/
161  
    selectWord(quote(s));
162  
    S a = answer_2(s);
163  
    //callAll(getAndClearThreadLocal(afterAnswering));
164  
    try answer a;
165  
  /*} on fail {
166  
    clearThreadLocal(afterAnswering);
167  
  }*/
168  
}
169  
170  
sS answer_2(S s) {
171  
  // repeat while ConcurrentModificationException
172  
  // (should not occur anymore anyway)
173  
  while licensed {
174  
    try {
175  
      ret trim(answer_go(s));
176  
    } catch print e {
177  
      S a = exceptionToStringShort(e);
178  
      if (eq(a, "ConcurrentModificationException")) {
179  
        sleep(50);
180  
        continue;
181  
      }
182  
      ret a;
183  
    }
184  
  }
185  
  null;
186  
}
187  
188  
189  
sS answer_go(S s) {
190  
  ++lineCount;
191  
  bool authed = authed();
192  
  lock dbLock();
193  
  
194  
  S std = ai_standardAnswer(s);
195  
  if (std == null) std = ai_standardAnswer_dollarVars(s); // TODO: might get slow eventually
196  
  
197  
  if (!startsWith(s, "!"))
198  
    s = ai_dropDroppableStuff(s);
199  
  
200  
  int safety = 0;
201  
  replaceloop: while (safety++ < 10) {
202  
    s = trim(s);
203  
    
204  
    try answer answer_inner(s, lineCount);
205  
    
206  
    for (WebNode node : indexedNodes(s)) {
207  
      S x = web_operandText(node, "replace with");
208  
      if (x != null && neq(s, x)) {
209  
        print("Replacing with " + x);
210  
        s = x;
211  
        continue replaceloop;
212  
      }
213  
    }
214  
    
215  
    break;
216  
  }
217  
  
218  
  //if (ai_isQuestion_1(s)) ret "No idea";
219  
  ret std;
220  
}
221  
222  
sS chatName() {
223  
  ret or2((S) mapGet(stefansChat_onLine_fullParams!, 'chatName), "Unknown Chat");
224  
}
225  
226  
sS chatLineSymbol() {
227  
  ret (S) mapGet(stefansChat_onLine_fullParams!, "Chat line symbol");
228  
}
229  
230  
sS answer_inner(S s, int lineCount) {
231  
  S chatName = chatName();
232  
  
233  
  final new Matches m;
234  
  
235  
  if (eqic(s, "!eval ps"))
236  
    ret backtick("ps");
237  
  if (swic_trim(s, "!eval ps ", m))
238  
    ret backtick("ps " + noUnixTricks(m.rest()));
239  
240  
  if (authed()) {
241  
    /*if (lineCount >= stefansChat_onLine_lookback)*/ {
242  
      if (eqic(s, "!restart")) { restart(); ret "Yo"; }
243  
      if (eqic(s, "!kill")) { cleanKillIn1Second(); ret "Yo"; }
244  
      if (eqic(s, "!soft-restart 1")) {
245  
        softRestart_level1();
246  
        ret "Hold on...";
247  
      }
248  
      
249  
      if (eqicOneOf(s, "!soft-restart", "!auto-restart")) {
250  
        softRestart_level2();
251  
        ret "Hold on...";
252  
      }
253  
      
254  
      if (eqic(s, "!theory")) ret "OK" with loadTheory();
255  
      if (swic_trim(s, "!theory ", m))
256  
        ret callAnswerFunction(theoryModule, m.rest());
257  
      if (eqic(s, "!peep")) {
258  
        runAndCleanUp(#1010980);
259  
        ret "OK, got " + fileLength(ai_chatAnalysis_peepHoleFile()) + " bytes";
260  
      }
261  
      
262  
      if (swic_trim(s, "!subst-web ", m)) {
263  
        L<S> tok = javaTokC(m.rest());
264  
        if (l(tok) == 2)
265  
          ret ai_subst_web_charBasedReplace(first(tok), selectWord(unquote(last(tok))));
266  
        else
267  
          ret ai_subst_web(m.rest());
268  
      }
269  
      
270  
      if (eqic(s, "!idle-patterns")) {
271  
        time2 {
272  
          Either<Int, Thread> e = (Either) evalWithTimeout(60.0, f ai_idle_matchPatterns);
273  
        }
274  
        ret e.isA() ? "Made " + nWebs(e.a()) + " in " + toSeconds(lastTiming(), 1) + "s" : "Timeout";
275  
      }
276  
      
277  
      if (swic_trim(s, "!experiment ", m)) {
278  
        S code = m.rest();
279  
        if (!isSnippetID(code))
280  
          code = psI(#1013002) + " " + bashQuote(code);
281  
        File outFile = directNohupJavax(code);
282  
        ret "OK, " + f2s(outFile);
283  
      }
284  
      
285  
      if (swic_trim(s, "!experiment ", m)) {
286  
        File outFile = directNohupJavax(m.rest());
287  
        ret "OK, " + f2s(outFile);
288  
      }
289  
      
290  
      if (eqic(s, "!rotate")) {
291  
        rotateSoftwareMadeWebs();
292  
        ret "OK";
293  
      }
294  
      
295  
      if (swic_trim(s, "!speculate-all ", m)) {
296  
        time2 {
297  
          Either<Int, Thread> e = (Either) evalWithTimeout(10.0, r { ai_speculate_all(m.rest()) });
298  
        }
299  
        int n = 0;
300  
        
301  
        pcall { n = e.isA() ? e.a() : websMadeInThread(e.b()); }
302  
        
303  
        ret "Made " + nWebs(n) + " in " + toSeconds(lastTiming(), 1) + "s";
304  
      }
305  
      
306  
      if (eqic(s, "!quick-transpile yourself")) ret transpileMyself('quick);
307  
308  
      if (eqic(s, "!medium-transpile yourself")) ret transpileMyself('medium);
309  
    }
310  
    
311  
    if "unlearn * *"
312  
      ret "OK, was: " + uniq(MatchLearner, pattern := $1).examples.put($2, 'rejected);
313  
      
314  
    if (swic_trim(s, "!sf ", m))
315  
      ret sfu(callAndMake_orDirect(m.rest()));
316  
317  
    if (swic_trim(s, "!specf ", m)) {
318  
      S sf = m.rest();
319  
      print("specf " + sf);
320  
      Class c = loadFunctionsWithInclude(ll(sf), #1011841);
321  
      try {
322  
        callOpt(c, 'ai_spec_init);
323  
        ret sfu(call(c, sf));
324  
      } finally {
325  
        cleanUp(c);
326  
      }
327  
    }
328  
    
329  
    if (swicOneOf_trim(s, m, "!eval ", "!j "))
330  
      ret smartBotEval(m.rest());
331  
332  
    if (swic_trim(s, "!fresh ", m)) {
333  
      dynClear();
334  
      ret smartBotEval(m.rest());
335  
    }
336  
337  
    if (eqicOneOf(s, "!fresh", "!dyn-clear")) {
338  
      dynClear();
339  
      ret "OK, refreshed";
340  
    }
341  
    
342  
    if (swic_trim(s, "!spec ", m)) {
343  
      Pair<S> p = splitAtFirstSpace(m.rest());
344  
      S f = startsWith(p.a, "ai_") ? p.a : "ai_spec_" + p.a;
345  
      ret smartBotEval("ai_callSpeculationFunction(f " + f + ", " + p.b + ");");
346  
    }
347  
      
348  
    if (swic_trim(s, "!spec-all ", m)) {
349  
      S f = m.rest();
350  
      f = startsWith(f, "ai_") ? f : "ai_spec_" + f;
351  
      fS _f = f;
352  
      ret smartBotEval("ai_callSpeculationFunctionOnAllTerms(f " + f + ");");
353  
    }
354  
    
355  
    if (swic_trim(s, "!run ", m)) {
356  
      runAndCleanUp(m.rest());
357  
      ret "OK";
358  
    }
359  
    
360  
    if (swic_trim(s, "!match ", m)) {
361  
      L<S> tok = javaTokC(m.rest());
362  
      if (l(tok) != 2) ret "need 2 parameters";
363  
      S pat = get(tok, 0), input = unquote(get(tok, 1));
364  
      Matches mm = ai_matchPattern(pat, input);
365  
      ret mm == null ? "No match" : sfu(toList(mm.m));
366  
    }
367  
    
368  
    if (eqic(s, "!compact")) {
369  
      thread "Compacting" {
370  
        startedLoading();
371  
        try {
372  
          time {
373  
            ai_compactLiveDB(true);
374  
          }
375  
          postToSmartBotsChat("Tripelized in " + toSeconds(lastTiming()) + " s");
376  
        } finally {
377  
          doneLoading();
378  
        }
379  
      }
380  
      ret "OK, compacting";
381  
    }
382  
    
383  
    if (eqic(s, "!sort-lists")) {
384  
      time {
385  
        tripleIndex().sortAllLists();
386  
      } 
387  
      ret "OK [" + lastTiming() + " ms]";
388  
    }
389  
    
390  
    if (swic_trim(s, "!var ", m))
391  
      ret sfu(get(mc(), m.rest());
392  
      
393  
    if (eqic(s, "!mtm")) {
394  
      ai_spec_moveToMiddle_all();
395  
      ret "OK";
396  
    }
397  
    
398  
    if (eqic(s, "!gc"))
399  
      ret ai_gc_scan("The most important word");
400  
      
401  
    if (eqic(s, "!num-invalid"))
402  
      ret lstr(ai_allInvalidWebs());
403  
404  
    if (swic_trim(s, "!load-subspace ", m)) {
405  
      AI_SubSpace ss = ai_swapInSubSpace($1);
406  
      ret "OK, size=" + l(ss);
407  
    }
408  
    
409  
    if (eqic(s, "!assume")) {
410  
      assumeSmartBotURL();
411  
      ret "OK";
412  
    }
413  
    
414  
    if "done making that"
415  
      ret ai_doneMakingThat(chatName);
416  
    
417  
    S c = "are making in " + chatName;
418  
    
419  
    if (flexMatchIC("let's make a *", s, m) || flexMatchIC("let's make an *", s, m)) {
420  
      S id = ai_text_verified("We", c, "$X");
421  
      if (id != null)
422  
        ret "We're still making " + id;
423  
      S aThing = a(m.rest());
424  
      id = selectWord(aGlobalID());
425  
      post("We", c, id);
426  
      post(id, "is", aThing);
427  
      
428  
      S answer = "OK, ID for new " + m.rest() + ": " + id + ".";
429  
      
430  
      pcall {
431  
        answer = appendWithSpaceIfNempty(answer, ai_makePartQuestion(chatName, id));
432  
      }
433  
      
434  
      ret answer;
435  
    }
436  
  
437  
    WebNode openQuestion = first(ai_search_dollarX_verified("Open question in " + chatName, "is", "$X"));
438  
    if (openQuestion != null) {
439  
      post(web_text(openQuestion), "is", s);
440  
      ai_invalidateWeb(openQuestion);
441  
      S answer = "OK, stored: " + web_text(openQuestion) + " is " + quoteUnlessWordsAndSpaces(s) + ".";
442  
      S id = ai_text("We", c, "$X"); // What we're making
443  
      S q = ai_makePartQuestion(chatName, id);
444  
      if (q == null) {
445  
        ai_doneMakingThat(chatName);
446  
        q = "I think we're done here. Made " + id + ", "
447  
          + ai_renderThingDescriptionWithParts(id);
448  
      }
449  
      answer = appendWithSpaceIfNempty(answer, q);
450  
      ret answer;
451  
    }
452  
    
453  
    for (S sf : ai_texts_verified("$X", "is a good function to call when user says", quote(s))) {
454  
      sf = unquote(sf);
455  
      if (endsWith(sf, "()", m))
456  
        if (isIdentifier(m.rest()))
457  
          ret sfu(makeAndCall(m.rest()));
458  
    }
459  
460  
    // end of priviledged commands
461  
  }
462  
  
463  
  if (ai_isQuestion_1(s) && !byBot()) {
464  
    selectWord(s);
465  
    ai_postTriple(s, "should be", "answered in the chat");
466  
  }
467  
  
468  
  if "Are you online?" ret "Yes";
469  
  if (eqicOneOf(s, "!question", "!gac"))
470  
    ret random_gac36k();
471  
    
472  
  if (swic_trim(s, "!word ", m)) {
473  
    selectWord(m.rest());
474  
    ret "OK " + unicode_rightPointingTriangle() + unicode_rightPointingTriangle();
475  
  }
476  
  
477  
  if (swic_trim(s, "!image ", m)) {
478  
    S x = m.rest();
479  
    print("Googling " + x); 
480  
    BufferedImage img = quickVisualize(x);
481  
    ret "[IMAGE] " + uploadJPEGToImageServer(img, x);
482  
  }
483  
  
484  
  if "memory stats|full memory stats"
485  
    ret nWeb(ai_allWebsCount()) + ". " + diskSpaceEtcBot_answer(s) + ". " + diskSpaceInfo();
486  
    
487  
  try answer diskSpaceEtcBot_answer(s);
488  
  
489  
  if (swic_trim(s, "!search ", m)) {
490  
    selectWord("[search] " + m.rest());
491  
    ret "OK " + unicode_rightPointingTriangle() + unicode_rightPointingTriangle();
492  
  }
493  
  
494  
  if (swic_trim(s, "!solve ", m)) {
495  
    S a;
496  
    time "Solve in subspace" {
497  
      a = ai_solveQuestionInSubSpace(m.rest());
498  
    }
499  
    ret "[" + lastTiming() + " ms] " + (a != null ? a : "I don't know");
500  
  }
501  
  
502  
  if (eqic(s, "!loaded-subspaces"))
503  
    ret sfu(ai_subSpaceNames());
504  
    
505  
  if (eqic(s, "!subspaces"))
506  
    ret sfu(ai_subSpaceNamesOnDisk());
507  
    
508  
  if (eqic(s, "!index-time")) ret toS(indexMakingTime, 1) + " s";
509  
  if (eqic(s, "!boot-time"))
510  
    ret toS(bootTime, 1) + " s (" + toS(bootTime+started-vmStarted(), 1) + "s full)";
511  
  
512  
  if (swic_trim(s, "!bench-search", m)) {
513  
    T3<S> t = ai_parseArrowTriple(m.rest());
514  
    time2 {
515  
      int n = l(ai_search_dollarX(t));
516  
    }
517  
    ret n(n, "result") + ", " + lastTiming() + " ms";
518  
  }
519  
  
520  
  if (swic_trim(s, "!vary ", m))
521  
    ret ifEq(ai_nlVary(m.rest()), m.rest(), "Sorry, no variation found");
522  
  
523  
  if (swic_trim(s, "!google ", m))
524  
    ret join(" - ", swapPair(first(quickGoogle($1))));
525  
    
526  
  if (swic_trim(s, "!google-texts", m))
527  
    ret lines(uniquify(map tripleC(quickGoogle2($1))));
528  
    
529  
  if (swic_trim(s, "!google-define", m))
530  
    ret lines(uniquify(map(func(T3<S> t) { t.b + " ~ " + t.c },
531  
      quickGoogle2($1))));
532  
    
533  
  if (swic_trim(s, "!google-complete ", m))
534  
    ret lines(googleAutoComplete($1));
535  
    
536  
  if (swic_trim(s, "!antonyms ", m))
537  
    ret join(", ", antonymsFromSynonymDotCom($1));
538  
    
539  
  if (swic_trim(s, "!has-triple ", m)) {
540  
    Triple<S> t = ai_parseArrowTriple(m.rest());
541  
    ret yn(ai_cache_hasTriple(t));
542  
  }
543  
    
544  
  if (swic_trim(s, "!triple ", m) || swic_trim(s, "!triples ", m)) {
545  
    L<S> elements = trimAll(splitAt(m.rest(), "->"));
546  
    if (l(elements) != 3) ret "3 parts please";
547  
    ret "[IMAGE] " + "http://ai1.space/1007546?triples=" + urlencode(lines(elements));
548  
  }
549  
  
550  
  if (swic_trim(s, "!answer ", m)) {
551  
    time2 {
552  
      S a = ai_specReturn_answerToExternalQuestion(10.0, m.rest());
553  
    }
554  
    ret "[" + lastTiming() + " ms] " + (a != null ? a : "I don't know");
555  
  }
556  
  
557  
558  
  if (swic_trim(s, "!web ", m)) {
559  
    S id = $1;
560  
    Web web = indexedWebWithGlobalID(id);
561  
    if (web == null) ret "Not found";
562  
    ret "[IMAGE] " + smartBotURL() + "/diagram?id=" + id;
563  
  }
564  
  
565  
  if (swic_trim(s, "!parse ", m))
566  
    ret ai_renderTriple(ai_tripelize(m.rest()));
567  
    
568  
  if (eqic(s, "!worst-case"))
569  
    ret sfu(getOptMC('ai_hasTriple_vary_worstCase));
570  
    
571  
  if (eqic(s, "!uptime"))
572  
    ret n(secondsSinceSysTime(started), "second");
573  
    
574  
  if (eqic(s, "!typical-set"))
575  
    ret sfu(diagramServer_typicalSet());
576  
    
577  
  if (eqic(s, "!num-unverified"))
578  
    ret lstr(ai_unverifiedWebs());
579  
    
580  
  if (eqic(s, "!num-true"))
581  
    ret lstr(ai_trueWebs());
582  
    
583  
  if (eqic(s, "!version"))
584  
    ret autoRestart_localMD5();
585  
    
586  
  if (swic_trim(s, "!blob ", m)) {
587  
    S a = postNodeFromInput(m.rest(), s);
588  
    selectWord(m.rest());
589  
    ret a;
590  
  }
591  
592  
  if (swic_trim(s, "!store ", m))
593  
    ret postTripleFromInput(ai_tripelize(m.rest()), s);
594  
595  
  if (swic_trim(s, "!store-triple ", m))
596  
    ret postTripleFromInput(ai_parseArrowTriple(m.rest()), s);
597  
598  
  if (swic(s, "!nodes ", m)) {
599  
    if (dropSuffixTrim("...", m.rest(), m))
600  
      ret lstr(indexedNodesStartingWith(m.rest()));
601  
    ret lstr(indexedNodes(m.rest()));
602  
  }
603  
  
604  
  if (eqic(s, "!webs"))
605  
    ret lstr(allIndexedWebs());
606  
    
607  
  if (swic(s, "!webs ", m))
608  
    ret joinWithSpace(collect(indexedWebs($1), 'globalID));
609  
    
610  
  if (swic(s, "!splitAtBaseFormVerb ", m))
611  
    ret sfu(splitAtBaseFormVerb($1));
612  
    
613  
  if (swic(s, "!maxRunlengthOfRepeatingChars ", m))
614  
    ret str(maxRunlengthOfRepeatingChars($1));
615  
    
616  
  if (swic(s, "!collapseWord ", m))
617  
    ret collapseWord($1);
618  
    
619  
  if (swic(s, "!gac ", m))
620  
    ret or2(first(scoredSearch(m.get(0), keys(gac36k()))), "-");
621  
    
622  
  if (eqic(s, "!vms"))
623  
    ret computerVMs_text();
624  
    
625  
  if (eqic(s, "!id")) ret aGlobalID();
626  
    
627  
  if (swic_trim(s, "!count-triple ", m)) {
628  
    T3<S> t = ai_parseArrowTriple(m.rest());
629  
    print("Searching: " + sfu(t));
630  
    Pair<Int> p = ai_countBoth_dollarX(t);
631  
    ret eq(p.a, p.b) ? str(p.a)
632  
      : p.a + " (+" + (p.b-p.a) + " unverified)";
633  
  }
634  
    
635  
  pcall { try answer ai_sfCommands(s); }
636  
  
637  
  if (swic_trim(s, "!macmillan ", m)) try {
638  
    Pair<S, L<S>> p = macmillanDefinitions3(m.rest());
639  
    ret toUpper(p.a) + "\n" + lines(prependAll("-", p.b));
640  
  } catch e {
641  
    printShortException(e);
642  
    ret "Macmillan is quiet today.";
643  
  }
644  
    
645  
  try answer ai_answerFromCache(s);
646  
  
647  
  S _s = s;
648  
  s = ai_dropLeadingAdditions(s);
649  
  
650  
  if (neq(_s, s))
651  
    try answer ai_answerFromCache(s);
652  
653  
  if "cache size"
654  
    ret n2(indexedTerms(), "different term")
655  
      //+ ", " + n(web_countNodes(allWebs_cached()), "node")
656  
      //+ ", " + n(allWebs_cached(), "web");
657  
      + ", " + nWeb(tripleIndex().numWebs());
658  
  
659  
  if "give me subtypes of ..."
660  
    ret ai_renderList(ai_subtypesOf(m.rest()));
661  
    
662  
  if "give me a third person verb"
663  
    ret random(thirdPersonVerbs());
664  
    
665  
  if (learnedFlexMatch("give me some *", s, m)) {
666  
    S query = singular($1);
667  
    ret ai_renderNodesList(concatLists(
668  
      ai_index_search_dollarX("$X", "is a", query),
669  
      ai_index_search_dollarX("$X", "is", a(query))));
670  
  }
671  
    
672  
  if "authed?"
673  
    ret authed() ? "You are authed." : "You are not authed.";
674  
    
675  
  if "what is the singular of *"
676  
    ret or2(getSingularFromWordHippo($1), singular($1));
677  
    
678  
  if (learnedFlexMatch("what is the relation between * and *", s, m)) {
679  
    L<S> l = ai_getRelation($1, $2);
680  
    //ret ai_renderList(l);
681  
    if (nempty(l)) ret $1 + " " + first(l) + " " + $2;
682  
  }
683  
    
684  
  if (containsAll(asCISet(javaTokC(s)), "list", "long"))
685  
    pcall { try answer callAnswerMethod(hotwireOnce(#1013113), s); }
686  
  
687  
  if "what unix day is it"
688  
    ret str(unixDay());
689  
    
690  
  if "show me the ..."
691  
    ret "What " + $1 + "?";
692  
    
693  
  if (learnedFlexMatch("What do * have?", s, m))
694  
    ret ai_renderNodesList(ai_index_search_dollarX($1, "have", "$X"));
695  
    
696  
  if (learnedFlexMatch("What does * do?", s, m))
697  
    ret ai_renderList(map(f web_nodePairToText, webs_search_dollarXY(webFromTriples($1, "$X", "$Y"), indexedWebs($1))));
698  
    
699  
  if (learnedFlexMatch_multi(s, m, "What is *", "Who is *", "Was ist *", "Wer ist *"))
700  
    try answer ai_renderList(ai_whatIs($1), "");
701  
    
702  
  S sf = web_text(first(ai_search_dollarX_verified("$X", "implements", quote(s))));
703  
  if (startsWith(sf, "sf ", m))
704  
    ret str(makeAndCall($1));
705  
    
706  
  if (learnedFlexMatch("* how many visitors *", s) || match("how many visitors", s))
707  
    ret str(ai1_cookiesToday_int());
708  
    
709  
  // Once more with generated webs (replacing $ vars)
710  
  
711  
  if (learnedFlexMatch("What is *", s, m)) {
712  
    L<Web> extendedWebs = indexedWebsAfterVariableSubstitution($1);
713  
    print("Have " + n(extendedWebs, "extended web") + " for " + quote($1));
714  
    try answer ai_renderNodesList(webs_search_dollarX(webFromTriples($1, "is", "$X"), extendedWebs), null);
715  
  }
716  
  
717  
  try answer ai_tryIfAndInput(s);
718  
  try answer ai_autoApplyRules(s);
719  
  
720  
  if (!ai_isQuestion_1(s)
721  
    && learnedFlexMatch_multi(s, m, "* is *", "* ist *"))
722  
    try answer postTripleFromInput(triple(m.get(0), "is", m.get(1)), s);
723  
    
724  
  try answer ai_standardAnswer(s);
725  
  try answer ai_standardAnswer_dollarVars(s); // TODO: might get slow eventually
726  
  try answer ai_standardAnswerEval(s);
727  
  
728  
  pcall {
729  
    final T3<S> t = ai_tripelize(s);
730  
    if (t != null) {
731  
      try answer evalWithTimeoutOrNull(20.0, func -> S {
732  
        for (O f : tripleAnswerFunctions)
733  
          try answer (S) pcallF(f, t);
734  
        null;
735  
      });
736  
      try answer ai_standardAnswerSF_triple_dollarVars(t);
737  
    }
738  
  }
739  
740  
  // 10 second timeout
741  
  S a = ai_specReturn_answerToExternalQuestion(10.0, s);
742  
  if (nempty(a) && !swicOneOf(a, "[", "What is ")) ret a;
743  
  
744  
  null;
745  
}
746  
747  
svoid loadBots(S... botIDs) {
748  
  for (S id : botIDs) pcall {
749  
    thoughtBots.add(runSubBot(id));
750  
  }
751  
}
752  
753  
static O html(S uri, SS params) {
754  
  profilePoint('html_1);
755  
  S ip = clientIP();
756  
  bool bad = eq(uri, "/simulate-bad-client");
757  
  Pair<Int, Bool> pair = simpleSpamClientDetect2(ip, uri);
758  
  if (pair.b) {
759  
    if (eq(ip, pcall_myFirewallIP()))
760  
      print("Not blocking myself.");
761  
    else {
762  
      print("Blocking IP " + ip);
763  
      blockedIPs.add(ip);
764  
    }
765  
  }
766  
  
767  
  if (blockedIPs.contains(ip)) {
768  
    bad = true;
769  
    post_verified(print(t3("an HTTP request from a blocked IP", "came in at", dateWithTimeGMT())));
770  
  }
771  
  
772  
  if (bad) {
773  
    NanoHTTPD.IHTTPSession httpSession = NanoHTTPD.currentSession!;
774  
    if (httpSession == null) {
775  
      print("No HTML session?");
776  
      sleepSeconds(spammerSleep);
777  
      ret "go away";
778  
    }
779  
    httpSession.badClient(true);
780  
    null;
781  
  }
782  
  
783  
  print(gmtWithSeconds() + ": Serving HTTP " + quote(uri) + " to " + ip + " (anti-spam count: " + pair.a + "/" + simpleSpamClientDetect2_spamMax + ")");
784  
  profilePoint('html_2);
785  
  
786  
  S requestID = aGlobalID();
787  
  S symbol = "HTTP request " + requestID;
788  
  if (http_isBot()) symbol = "Bot " + symbol;
789  
  //S domain = serveHttp_domainName();
790  
  {
791  
    temp temp_ai_startBuffering();
792  
    post_verified(symbol, "came in at", dateWithTimeGMT());
793  
    post_verified(symbol, "was for path", uri);
794  
    post_verified(symbol, "had user agent", serveHttp_userAgent());
795  
    post_verified(symbol, "came from IP", ip);
796  
  } 
797  
  profilePoint('html_3);
798  
  
799  
  //set serveHttp_cookieHandling_verbose;
800  
  S cookie = serveHttp_cookieHandling();
801  
  S loginUrl = "/";
802  
  S pw = params.get("pw");
803  
  Pair<S, Bool> p = standaloneWebAuth(loginUrl, cookie, pw);
804  
  print("ip=" + ip + ", cookie=" + l(cookie) + ", authed: " + p.b);
805  
  if (nempty(p.a)) ret p.a;
806  
  if (eq(uri, "/login")) ret standaloneWebAuth_showForm(loginUrl, cookie);
807  
  
808  
  httpAuthed.set(p.b);
809  
  try {
810  
    long time = sysNow();
811  
    O html = html_2(uri, params);
812  
    done2(time, "Making HTML " + uri);
813  
    ret html;
814  
  } finally {
815  
    httpAuthed.set(false);
816  
  }
817  
}
818  
819  
static O html_2(S s, SS params) {
820  
  new Matches m;
821  
  
822  
  S domain = serveHttp_domainName();
823  
  
824  
  if (ewic(domain, ".supersrv.de")) ret "Super server!";
825  
826  
  if (eqic(s, "/favicon.ico"))
827  
    ret serveFile(loadLibrary(#1013028), "image/x-icon");
828  
  
829  
  if (nempty(params.get("_pretendAuthed")) || authed())
830  
    html_pretendAuthed.set(true);
831  
    
832  
  if (eqic(s, "/number-of-threads")) ret str(cachedNumberOfThreads!);
833  
    
834  
  if (eqic(s, "/realurl"))
835  
    ret hrefresh(smartBotDirectURL());
836  
    
837  
  if (swic(domain, "pixelboys.") || eqic(domain, "www.botcompany.de"))
838  
    ret hrefresh("https://www.botcompany.de:8443/1016323/raw");
839  
    
840  
  S input = params.get("input");
841  
  if (nempty(input)) {
842  
    if (webAuthed())
843  
      ret htmlencode(callAnswerMethodVerbose(input));
844  
    else
845  
      ret "Can't send input (not authed)";
846  
  }
847  
  
848  
  if (swic(s, "/matrix/", m)) {
849  
    s = "/dyn/" + psI(#1013031);
850  
    if (nempty(m.rest()))
851  
      params.put("topic", urldecode(m.rest()));
852  
  }
853  
854  
  if (eqicOptSlash(s, "/rules"))
855  
    s = "/dyn/1013529/ai_rulesTable";
856  
    
857  
  if (eqicOptSlash(s, "/livecount"))
858  
    s = "/dyn/1013377";
859  
    
860  
  if (eqic(s, "/dyn/fresh")) {
861  
    if (!webAuthed()) ret "No";
862  
    dynClear();
863  
    ret "OK";
864  
  }
865  
  
866  
  if (swic(s, "/dyn/", m)) {
867  
    if (loading()) ret "LOADING, please try again";
868  
    S u = m.rest();
869  
    int i = smartIndexOf(u, '/');
870  
    S id = fsI(takeFirst(u, i));
871  
    if (!has_verified(id, "is", "a safe web module")) ret "Unsafe";
872  
    O mod = hotwireCached(id);
873  
    ret callHtmlMethod2(mod, or2(substring(u, i), "/"), params);
874  
  }
875  
  
876  
  if (swic(s, "/sf/", m))
877  
    ret htmlencode2(struct(callSafeSF(m.rest())));
878  
    
879  
  if "random-web"
880  
    s = str(randomIndexedTriple().globalID());
881  
882  
  try {
883  
    if "threads" {
884  
      time2 {
885  
        S text = renderRunnableThreadsWithStackTraces();
886  
      }
887  
      ret hpre(text + "\n\n" + lastTiming() + " ms");
888  
    }
889  
    
890  
    if (eqic(s, "/livecheck")) ret "Smart Bot";
891  
    
892  
    if (eqic(s, "/load")) ret formatDouble(systemLoad(), 2);
893  
    
894  
    if (eqic(s, "/1-sec-profile")) ret html_profile(1);
895  
    if (eqic(s, "/10-sec-profile")) ret html_profile(10);
896  
    
897  
    if (eqic(s, "/deadlocks")) ret htmlencode(solveDeadlocks());
898  
    
899  
    if (eqic(s, "/source-stats"))
900  
      ret h1_title("Source Stats") + multiSetToUL(ai_sourceStats());
901  
      
902  
    if "thoughts"
903  
      ret serveHTML(html_thoughts());
904  
      
905  
    if "diagram" {
906  
      S id = params.get("id");
907  
      Web web = indexedWebWithGlobalID(id);
908  
      ret serveJPEG(webToCAL(web).makeImage(600, 400));
909  
    }
910  
  
911  
    if "log"
912  
      ret serveText_direct(printLog());
913  
      
914  
    if "learners"
915  
      ret serveText_direct(renderConcepts(list(MatchLearner)));
916  
      
917  
    if "unreached"
918  
      ret h3_title("Unreached")
919  
        + ul(map html_encyclopediaTopic(ai_gc_unreachedWords()));
920  
      
921  
    // Serve Web With Global ID
922  
      
923  
    s = dropPrefix("/", s);
924  
    if (possibleGlobalID(s)) {
925  
      L<Web> webs = ai_getWebs(s);
926  
      if (nempty(webs)) {
927  
        for (Web web : webs) ai_speculateOnWeb(web);
928  
        
929  
        Web web = first(webs);
930  
        ret h2_title("Web " + s + (ai_isInvalidWeb(web) ? " [INVALID]" : "")) + loadjquery()
931  
          + pre(htmlencode(renderWeb_multiLine(web)))
932  
          + p(himg(ai_webImage_link(s), title := "Web " + s))
933  
          + (l(webs) > 1 ? p("Warning: Multiple webs") : "")
934  
          + ai_html_wordThoughts("Web " + web.globalID);
935  
      }
936  
      
937  
      /*if (theoryOn && theoryModule == null) ret serveHTML("Loading theory module");
938  
      Map<S, O> map = (Map) getOpt(theoryModule, 'theoryForLineMap);
939  
      if (map.containsKey(toLower(s)))
940  
        ret serveHTML("A line in the chat.");*/
941  
      ret serveHTML("Unknown: " + s);
942  
    }
943  
    
944  
    if (swic(s, "json/", m)) {
945  
      s = m.rest();
946  
      if (swic(s, "relations/", m)) {
947  
        new L out;
948  
        Map map = litorderedmap();
949  
        if (loading()) map.put("loading", true);
950  
        int max = 1000;
951  
        for (WebRelation r : indexedRelations(m.rest()))
952  
          if (l(out) >= max) {
953  
            map.put("more", true);
954  
            break;
955  
          } else {
956  
            L<S> l = tripleToList(web_relationToTriple(r));
957  
            l.add(r.web.globalID());
958  
            l.add(r.web.source);
959  
            if (r.web.verified()) l.add("v");
960  
            out.add(l);
961  
          }
962  
        map.put("data", out);
963  
        ret serveText(jsonEncode(map));
964  
      }
965  
      ret "unknown";
966  
    }
967  
    
968  
    if (swic(s, "e/", m)) { // serve encyclopedia topic
969  
      S topic = urldecode(m.rest());
970  
      ret html_topic(topic, eq("1", params.get("random")));
971  
    }
972  
    
973  
    if (swic(s, "autocomplete/", m)) {
974  
      int max = min(100, parseInt(or2(params.get("n"), "10")));
975  
      L<S> completed = ai_autoComplete(urldecode(m.rest()), max, autoComplete_timeOut);
976  
      new L<Map> out;
977  
      for (S c : completed) {
978  
        new HashMap map;
979  
        if (startsWith(s, c))
980  
          map.put(follow := substring(c, l(s)));
981  
        else
982  
          map.put(whole := c);
983  
        out.add(map);
984  
      }
985  
      ret serveText(jsonEncode_breakAtLevel1(out));
986  
    }
987  
988  
    if (eqic(s, "alphabetical"))
989  
      ret html_alphabetical(params);
990  
      
991  
    if (eqic(s, "latest-webs")) {
992  
      int n = toInt(params.get('n));
993  
      if (n == 0) n = 100;
994  
      ret html_latestWebs(min(1000, max(n, 10)));
995  
    }
996  
    
997  
    if (eqic(s, "the-big-number"))
998  
      ret formatWithThousandsSeparator(ai_allWebsCount());
999  
    
1000  
    if (eqic(s, "random"))
1001  
      ret hrefresh(smartBot_encyclopediaLink(ai_randomString()) + "?random=1");
1002  
1003  
    if (eqic(s, "classes")) ret html_classes();
1004  
    if (eqic(s, "standard-relations")) ret html_standardRelations();
1005  
    if (eqic(s, "active")) ret html_active();
1006  
1007  
    if (eqic(s, "all-web-ids")) {
1008  
      L<S> l = allToString(allWebIDs_cloned());
1009  
      ret serveText(
1010  
          l(l) + " ids follow.\n" + lines(l) 
1011  
        + l(l) + " ids written.");
1012  
    }
1013  
    
1014  
    if (eqic(s, "internal-files"))
1015  
      ret serveText(lines(map(func(File f) -> S {
1016  
        quote(f.getName()) + " " + fileSize(f) + " " + fileModificationTime(f)
1017  
      }, listFiles(programDir()))));
1018  
      
1019  
    if (swic(s, "internal-files/", m)) {
1020  
      S name = urldecode(m.rest());
1021  
      if (!isProperFileName(name)) ret serve404("No");
1022  
      File f = getProgramFile(name);
1023  
      ret f.isFile() ? serveFile(f) : serve404();
1024  
    }
1025  
    
1026  
    if (eqic(s, "submit-triple")) {
1027  
      S a = params.get("a"), b = params.get("b"), c = params.get("c");
1028  
      if (empty(a) || empty(b) || empty(c)) ret "Empty field(s)";
1029  
      ret htmlencode(postTripleFromInput(t3(a, b, c), null));
1030  
    }
1031  
    
1032  
    if (swic_trim(s, "texts/", m)) {
1033  
      ret serveText((loading() ? "[LOADING]\n" : "\n") + lines(map quoteBorderless2(ai_texts(ai_parseSlashTriple(urldecode(m.rest()))))));
1034  
    }
1035  
  
1036  
    T3<S> texts_big_t = null;
1037  
    
1038  
    if (swic_trim(s, "texts-big/", m))
1039  
      texts_big_t = ai_parseSlashTriple(urldecode(m.rest()));
1040  
1041  
    if (eqic(s, "texts-big")) {
1042  
      texts_big_t = t3(
1043  
        params.get("a"), params.get("b"), params.get("c"));
1044  
    }
1045  
    
1046  
    if (swic_trim(s, "rev/", m))
1047  
      texts_big_t = triple("$X", "is", urldecode(m.rest()));
1048  
1049  
    if (texts_big_t != null) {
1050  
      final bool strip = eq("1", params.get('strip));
1051  
      fS style = or2(params.get("style"), "font-size: 20px");
1052  
      T3<S> t = texts_big_t;
1053  
      //L<S> texts = ai_texts(t = ai_parseSlashTriple(urldecode(m.rest())));
1054  
      L<TripleRef<S>> refs = ai_tripleRefs(t);
1055  
      ret htitle_htmlencode(ai_renderTriple(t))
1056  
        + (loading() ? "[LOADING]\n" : "\n") +
1057  
        //joinMap(texts, func(S s) -> S { pre(htmlencode_noQuote(s), +style, title := ) });
1058  
        joinMap(refs, func(TripleRef<S> r) -> S {
1059  
          TripleWeb w = cast r.triple;
1060  
          S title = "Web " + w.globalID();
1061  
          S source = w.source();
1062  
          if (nempty(source)) title += ", source: " + source;
1063  
          S text = r!;
1064  
          if (strip) text = unquoteMultiline(text);
1065  
          ret pre(htmlencode_noQuote(text), +style, +title);
1066  
        });
1067  
    }
1068  
  
1069  
    // Search Results
1070  
    
1071  
    S q = params.get("q");
1072  
    if (nempty(q))
1073  
      ret html_searchResults(q, params.get("mode"));
1074  
  
1075  
    if (eqic(s, "popular"))
1076  
      ret html_popular(params);
1077  
    
1078  
    // Default for unknown URL  
1079  
    
1080  
    S topic = nempty(s) ? s : params.get("topic");
1081  
    if (nempty(topic))
1082  
      ret html_topic(urldecode(topic), false);
1083  
    
1084  
    // Home page
1085  
    
1086  
    ret html_home();
1087  
  } finally {
1088  
    html_pretendAuthed.set(null);
1089  
  }
1090  
}
1091  
1092  
static NanoHTTPD.Response html_topic(S topic, bool random) {
1093  
  long time;
1094  
  bool timeout = false;
1095  
  print("User agent: " + serveHttp_userAgent());
1096  
  if (http_isBot()) {
1097  
    time = -1;
1098  
    print("Bot request");
1099  
  } else {
1100  
    time2 {
1101  
      timeout = ai_speculateDeepWithActiveAndTimeout(topic, speculationTimeoutForHttp);
1102  
    }
1103  
    time = lastTiming();
1104  
  }
1105  
  L<S> words = ll(topic);
1106  
  //if (ai_getWeb(topic) != null) words.add("Web " + topic);
1107  
  ret serveHTMLNoCache(
1108  
    htitle(topic + " | Smart Bot")
1109  
    + h1(html_smallSmartBotLogo() + " " + htmlencode_noQuote("Topic: " + topic))
1110  
    + loadjquery()
1111  
    + (random ? ahref("/random", "Another random term") + " | " : "")
1112  
    + "Search: " + html_searchField(topic) + "<br><br>"
1113  
    + ai_html_wordThoughts(words)
1114  
    + ai_html_enterTripleForm(first(words))
1115  
    + p(
1116  
      (time < 0 ? "" : "Speculated for " + time + " ms" + (timeout ? " (TIMED OUT)" : "") + " ") +
1117  
      ahref(smartBot_directTopicLink(topic), "[Direct link]"))
1118  
      );
1119  
}
1120  
1121  
sS html_home() {
1122  
  temp tempProfileBlock('html_home);
1123  
  ret tag('link, "", rel := "search",
1124  
        type := "application/opensearchdescription+xml",
1125  
        title := "Smart Bot",
1126  
        href := "http://tinybrain.de:8080/getraw.php?id=1013357")
1127  
    + hcenter3(
1128  
        hsnippetimg(#1101146, width := 64, height := 64) //#1011942)
1129  
      + h1_title("Smart Bot")
1130  
      + p("by " + ahref("http://BotCompany.de/", "BotCompany.de")
1131  
      + (webAuthed() ? " Authed." : ""))
1132  
      + ahref("/popular", "Most occurring") + " | "
1133  
        + ahref("/alphabetical", "Alphabetical") + " | "
1134  
        + ahref("/latest-webs", "Latest") + " | "
1135  
        + ahref("/random", "Random term") + " | "
1136  
        + html_searchField() + "<br><br>"
1137  
      + h3("Triple Search")
1138  
      + form(
1139  
        htextfield("a") + " -> " + htextfield("b") + " -> " + htextfield("c", "$X")
1140  
        + " " + hsubmit("Search triples"),
1141  
        action := "texts-big"));
1142  
}
1143  
1144  
sS html_popular(SS params) {
1145  
  time "Popularity search" {
1146  
    //L<S> keys = multiMapKeysByPopularity(ai_mainIndex());
1147  
    L<S> keys = multiSetByPopularity(tripleIndex().wordIndex);
1148  
  }
1149  
  
1150  
  int step = 100, n = toInt(params.get("n"));
1151  
  int count = l(keys);
1152  
  L<S> l = subList(keys, n, n+step);
1153  
  
1154  
  ret hcenter3(hsnippetimg(#1011942))
1155  
    + h1_title("Smart Bot's Encyclopedia (" + n_fancy(keys, "entry") + ")")
1156  
    + "Most occurring | "
1157  
      + ahref("/alphabetical", "Alphabetical") + " | "
1158  
      + ahref("/latest-webs", "Latest") + " | "
1159  
      + html_searchField() + "<br><br>"
1160  
    + pageNav2("/", count, n, step, 'n)
1161  
    + ul(map(func(S s) -> S {
1162  
      ahref(smartBot_encyclopediaLink(s), htmlencode(or2(s, "-")))
1163  
        + " [" + ai_approximateIndexedNodesCount(s) + "]"
1164  
    }, l));
1165  
}
1166  
1167  
sS html_searchField() { ret html_searchField(""); }
1168  
sS html_searchField(S q) { ret html_searchField(q, ""); }
1169  
1170  
sS html_searchField(S q, S mode) {
1171  
  ret hform(
1172  
    htextinput("q", value := q, autofocus := 'autofocus) +
1173  
    " Mode: " + 
1174  
    hselect_list(ll("starts with", "multiple words", "ends with", "contains"), mode, name := "mode") + 
1175  
    " " + 
1176  
    hsubmit("Search"),
1177  
    style := "display: inline", action := smartBotOfficialURL());
1178  
}
1179  
1180  
static O html_profile(int seconds) {
1181  
  if (poorMansProfiling_isOn()) ret "Already on";
1182  
  poorMansProfiling(100);
1183  
  sleepSeconds(seconds);
1184  
  ret serveText(poorMansProfiling_stopAndRenderResults());
1185  
}
1186  
1187  
static S html_searchResults(S q, S mode) {
1188  
  int max = 1000; 
1189  
  time2 {
1190  
    L<S> l;
1191  
    if (eqic(mode, "multiple words"))
1192  
      l = indexedTerms_scoredSearch(q, max+1);
1193  
    else if (eqic(mode, "ends with"))
1194  
      l = asList(termsEndingWith(q));
1195  
    else if (eqic(mode, "contains"))
1196  
      l = asList(indexedTermsContaining(q));
1197  
    else
1198  
      l = asList(fullIndexedTermsStartingWith(q));
1199  
    if (possibleGlobalID(q) && !eq(first(l), q))
1200  
      l.add(0, q);
1201  
  }
1202  
  long time = lastTiming();
1203  
  bool more = l(l) > max;
1204  
  l = takeFirst(max, l);
1205  
  sortInPlaceAlternativeCI(l);
1206  
  
1207  
  S directHit = "";
1208  
  S trimmed = trim(q);
1209  
  S direct = ai_findIndexedTerm(trimmed);
1210  
  if (direct != null)
1211  
    directHit = p(unicode_blackRightArrow() + " " + b(html_encyclopediaTopic(direct)));
1212  
  else
1213  
    directHit = p("No direct hit. Create entry: " + b(html_encyclopediaTopic(trimmed)));
1214  
  
1215  
  ret h1_title("Smart Bot Search: " + htmlencode(q) + " (" + n_fancy(l, "result") + (loading() ? ", LOADING" : "") + ")")
1216  
    + "Search again: " + html_searchField(q, mode) + "<br><br>"
1217  
    + directHit
1218  
    + p(l(l) > max ? max + "+ search results" : n(l, "search result") + " [" + time + " ms]")
1219  
    + ul(map html_encyclopediaTopic(l));
1220  
}
1221  
1222  
static S html_alphabetical(SS params) {
1223  
  int step = 100, n = toInt(params.get("n"));
1224  
  Collection<S> all = indexedTerms();
1225  
  int count = l(all);
1226  
  L<S> l = subListOfCollection(all, n, n+step);
1227  
1228  
  ret h1_title("Smart Bot's Encyclopedia (Alphabetical) :)")
1229  
    + ahref("/popular", "Most occurring") + " | "
1230  
      + "Alphabetical" + " | "
1231  
      + ahref("/latest-webs", "Latest") + " | "
1232  
      + html_searchField() + "<br><br>"
1233  
    + pageNav2("/alphabetical", count, n, step, 'n)
1234  
    + ul(map(func(S s) -> S {
1235  
      ahref(smartBot_encyclopediaLink(s), htmlencode(or2(s, "-")))
1236  
    }, l));
1237  
}
1238  
1239  
sS html_classes() {
1240  
  L<S> l = sortedIC(ai_texts_verified("$X", "is", "a standard class"));
1241  
  
1242  
  ret h1_title("Smart Bot Classes")
1243  
    + ul(map(func(S s) -> S {
1244  
      ahref(smartBot_encyclopediaLink(s), htmlencode(or2(s, "-")))
1245  
        + " [" + ai_approximateIndexedNodesCount(s) + "]"
1246  
    }, l));
1247  
}
1248  
1249  
sS html_standardRelations() {
1250  
  L<S> l = sortedIC(unquoteAll(ai_texts_verified("$X", "is", "a standard relation")));
1251  
  
1252  
  ret h1_title("Smart Bot Standard Relations")
1253  
    + ul(map(func(S s) -> S {
1254  
      ahref(smartBot_encyclopediaLink(s), htmlencode(or2(s, "-")))
1255  
        + " [" + ai_approximateIndexedNodesCount(s) + "]"
1256  
    }, l));
1257  
}
1258  
1259  
sS html_active() {
1260  
  L<S> l = sortedIC(unquoteAll(ai_texts_verified("$X", "is", "an active topic")));
1261  
  L<S> lRules = sortedIC(unquoteAll(ai_texts_verified("$X", "is", "an active rule")));
1262  
  
1263  
  ret h1_title("Smart Bot's Active Topics")
1264  
    + ul(map(func(S s) -> S {
1265  
      ahref(smartBot_encyclopediaLink(s), htmlencode(or2(s, "-")))
1266  
        + " [" + ai_approximateIndexedNodesCount(s) + "]"
1267  
    }, l))
1268  
    + h2("Active Rules")
1269  
    + ul(map(func(S s) -> S {
1270  
      ahref(smartBot_encyclopediaLink(s), htmlencode(or2(s, "-")))
1271  
        + " [" + ai_approximateIndexedNodesCount(s) + "]"
1272  
    }, lRules))
1273  
    ;
1274  
}
1275  
1276  
static S html_latestWebs(int n) {
1277  
  L<GlobalID> l = takeLast(n, cloneList(latestWebs));
1278  
  S bn = formatWithThousands(ai_theBigNumber());
1279  
  ret htitle("Latest Webs (" + bn + ") | Smart Bot")
1280  
    + h1(html_smallSmartBotLogo() + " - Latest Webs from " + bn)
1281  
    + ul(mapReversed(func(GlobalID id) -> S {
1282  
      TripleWeb w = ai_getTriple(id);
1283  
      if (w == null) ret "[not found] Web " + id;
1284  
      ret ai_html_linkedWeb(id)
1285  
        + htmlencode(
1286  
            " [" + renderGMTDate(w.created()) + "] "
1287  
          + w.source() + ": ")
1288  
      + ai_html_renderTriple(w);
1289  
    }, l));
1290  
}
1291  
1292  
sS html_thoughts() {
1293  
  S html = /*hrefresh(5) +*/ hGoogleFontOswald() + loadjquery();
1294  
  S status = "";
1295  
  
1296  
  /*Pair<Int> p = evalWithTimeout_numberOfCalculations();
1297  
  if (p.a > 0) status = p(n(p.a, "calculation")
1298  
    + (p.b == 0 ? "" : ", " + p.b + " timed out"));*/
1299  
  
1300  
  Pair<Set<Thread>> p = evalWithTimeout_calculations();
1301  
  if (nempty(p.a) || nempty(p.b))
1302  
    status = ul(
1303  
      nempty(p.a) ? "In time calculations" + ul_htmlEncode(map threadName(p.a)) : null,
1304  
      nempty(p.b) ? "Timed out calculations" + ul_htmlEncode(map threadName(p.b)) : null
1305  
    );
1306  
    
1307  
  ai_html_wordThoughts_nodesMax.set(100);
1308  
  try {
1309  
    ret html + wordThoughts() + status;
1310  
  } finally {
1311  
    ai_html_wordThoughts_nodesMax.set(null);
1312  
  }
1313  
  
1314  
  /*
1315  
  if (theoryModule == null)
1316  
    ret html + "Loading theory module...";
1317  
  S thoughts = (S) call(theoryModule, 'html_thoughts);
1318  
  if (nempty(selectedWord))
1319  
    ret html + tag('table, tr(td_top(thoughts, style := "background: #CCC") + td_top(wordThoughts(), style := "padding-left: 20px")));
1320  
  ret html + thoughts;
1321  
  */
1322  
}
1323  
1324  
sS wordThoughts() {
1325  
  try {
1326  
    if (empty(selectedWord)) ret "";
1327  
    S html = ai_html_wordThoughts(selectedWord);
1328  
    html = html_addLinkToSpan(html, 'title, encyclopediaLink(selectedWord));
1329  
    ret html_addTargetBlank(html);
1330  
  } catch e {
1331  
    printStackTrace(e);
1332  
    ret "Erreur";
1333  
  }
1334  
}
1335  
1336  
sS postTripleFromInput(T3<S> triple, S input) {
1337  
  if (triple == null) null;
1338  
  if (swic(input, "OK, stored")) null;
1339  
  if (!ai_tripleAllowedToPost(triple)) null;
1340  
  
1341  
  new Matches m;
1342  
  if (!(swic(triple.a, "Web ", m) && possibleGlobalID(m.rest())))       selectWord(triple.a);
1343  
  
1344  
  if (ai_cache_hasTriple(triple))
1345  
    ret "I know";
1346  
  else {
1347  
    Web web = webFromTriple(triple);
1348  
    web.unverified = !authed();
1349  
    postSoftwareMadeWeb(web, +input);
1350  
    
1351  
    if (eqic(triple.b, "is") && eqic(triple.c, "invalid"))
1352  
      ai_invalidateWeb(triple.a);
1353  
    if (eqic(triple.b, "is") && eqic(triple.c, "wrong"))
1354  
      ai_wrongWeb(triple.a);
1355  
      
1356  
    ai_postTriple("Web " + web.globalID, "stored because of", chatLineSymbol());
1357  
    
1358  
    ret "OK, stored" + (web.unverified ? " (unverified)" : "") + ": " + ai_renderTriple(triple);
1359  
  }
1360  
}
1361  
1362  
sS postNodeFromInput(S node, S input) {
1363  
  if (!ai_nodeNameAllowedToPost(node)) null;
1364  
  if (hasIndexedNode(node))
1365  
    ret "I know";
1366  
  else {
1367  
    Web web = oneNodeWeb(node);
1368  
    web.unverified = !authed();
1369  
    postSoftwareMadeWeb(web, +input);
1370  
    ret "OK, stored" + (web.unverified ? " (unverified)" : "") + ": " + node;
1371  
  }
1372  
}
1373  
1374  
// might want to get rid of this; do it in speculation
1375  
svoid processSelectedWord {
1376  
  fS word = selectedWord;
1377  
  if (empty(word)) ret;
1378  
  ai_withMaker('processSelectedWord, r {
1379  
    //ai_speculate(word);
1380  
    pcall {
1381  
      ai_greetingRule1(word);
1382  
      //ai_greetingRule2(word);
1383  
      if (ai_hasTriple(word, "should be", "answered by me")
1384  
        && ai_postTriple(word, "was", "answered by me") != null) {
1385  
        S text = firstQuoted(web_texts(ai_search_dollarX(word, "is", "$X")));
1386  
        postToStefansChat((nempty(text) ? text + " << " : "") + "Greetings back to you!");
1387  
      }
1388  
    }
1389  
  });
1390  
}
1391  
1392  
svoid makeChatLinesUnrecent {
1393  
  new Matches m;
1394  
  for (WebNode node : ai_search_dollarX("$X", "is", "recent"))
1395  
    if (web_match("Chat line *", node, m)) pcall {
1396  
      int n = parseInt($1);
1397  
      if (n <= stefansChat_n_value-100) {
1398  
        //print("Unrecenting " + n);
1399  
        ai_invalidateWeb(node.web);
1400  
      }
1401  
    } else if (web_match("Smart Bot's Chat line *", node, m)) pcall {
1402  
      int n = parseInt($1);
1403  
      if (n <= smartBotsChat_n_value-100) {
1404  
        //print("Unrecenting " + n);
1405  
        ai_invalidateWeb(node.web);
1406  
      }
1407  
    }
1408  
}
1409  
1410  
svoid onHistoryRead {
1411  
  lock dbLock();
1412  
  print("History read.");
1413  
  processSelectedWord();
1414  
  pcall { makeChatLinesUnrecent(); }
1415  
}
1416  
1417  
sS selectWord(S word) {
1418  
  if (nempty(word)) {
1419  
    selectedWord = word;
1420  
    save('selectedWord);
1421  
    processSelectedWord();
1422  
  }
1423  
  ret word;
1424  
}
1425  
1426  
sS transpileMyself(S mode) {
1427  
  postToStefansChat("Transpiling...");
1428  
  Pair<Bool, S> p = transpileOnServer(programID(), 'medium);
1429  
  ret p.a ? "OK" : "Not OK";
1430  
}
1431  
1432  
svoid speculatorLoop {
1433  
  repeat with sleep 5 {
1434  
    ai_speculateDeepAndActive(selectedWord);
1435  
    for (L<S> words : cloneValues(lastUserLines))
1436  
      for (S word : words)
1437  
        ai_speculateDeepAndActive(word);
1438  
      
1439  
    S s;
1440  
    while ((s = first_sync(speculationQueue)) != null) {
1441  
      speculationQueue.remove(s);
1442  
      long time = sysNow();
1443  
      ai_speculateWithActive(s);
1444  
      done2_always(time, "Speculation Queue > " + s);
1445  
    }
1446  
  }
1447  
}
1448  
1449  
public static ISpec ispec = ai_defaultISpec();
1450  
1451  
// share ISpec interface with sub-modules
1452  
static JavaXClassLoader hotwire_makeClassLoader(L<File> files) {
1453  
  ClassLoader cl = myClassLoader();
1454  
  
1455  
  // Avoid class loader chaining, always reference base class loader
1456  
  if (cloned && cloningSince != 0) {
1457  
    ClassLoader parent = cast getOpt(cl, 'virtualParent);
1458  
    print("Cloned class loader. " + parent);
1459  
    if (parent != null) cl = parent;
1460  
  }
1461  
  
1462  
  ret new JavaXClassLoaderWithParent2(null, files, cl, parseClassesToShareList(classesToShare));
1463  
}
1464  
1465  
static Lock aiLock() {
1466  
  ret aiLock;
1467  
}
1468  
1469  
static bool webAuthed() {
1470  
  ret isTrue(httpAuthed!);
1471  
}
1472  
1473  
svoid handleStefansChat {
1474  
  stefansChat_n_onChange(r {
1475  
    clearTransientWebs();
1476  
    addTransientWeb(webFromTriple("Latest chat line", "is", "Chat line " + stefansChat_n_value));
1477  
  });
1478  
  
1479  
  stefansChat_onLine_lookback = 1; // 2 does double restarts etc.
1480  
  stefansChat_onLine_onHistoryRead.set(f onHistoryRead);
1481  
  stefansChat_onLine_safe(voidfunc(fS text) ctex {
1482  
    pcall {
1483  
      int nr = toInt(mapGet(stefansChat_onLine_fullParams!, "nr"));
1484  
      print("> [" + nr + "] " + text);
1485  
      if (nr != 0) {
1486  
        S x = "Chat line " + nr;
1487  
        stefansChat_onLine_fullParams->put('chatName, "Stefan's Chat");
1488  
        stefansChat_onLine_fullParams->put("Chat line symbol", x);
1489  
        post(x, "is", "a chat line");
1490  
        post(x, "is", "recent");
1491  
        postChatLineInfo(x, text);
1492  
        stefansChat_n_notify(nr);
1493  
        ai_speculateWithActiveAndTimeout(x, speculationTimeoutForNewChatLine);
1494  
        if (!byBot())
1495  
          lastUserLines.put("Stefan's Chat", ll(text, quote(text), x));
1496  
      }
1497  
    }
1498  
    
1499  
    temp tempSetThreadLocal(answering, true);
1500  
    try {
1501  
      S a = actualAnswer(text);
1502  
      a = shortenAnswerForChatAndUploadFull(text, a);
1503  
      postToStefansChat(a);
1504  
      callAll(getAndClearThreadLocal(afterAnswering));
1505  
    } on fail {
1506  
      clearThreadLocal(afterAnswering);
1507  
    }
1508  
  });
1509  
}
1510  
1511  
svoid handleSmartBotsChat {
1512  
  smartBotsChat_onLine_lookback = 1;
1513  
  smartBotsChat_onLine_onHistoryRead.set(f onHistoryRead);
1514  
  smartBotsChat_onLine_safe(voidfunc(fS text) ctex {
1515  
    pcall {
1516  
      int nr = toInt(mapGet(stefansChat_onLine_fullParams!, "nr"));
1517  
      print("> [" + nr + "] " + text);
1518  
      if (nr != 0) {
1519  
        S x = "Smart Bot's Chat line " + nr;
1520  
        stefansChat_onLine_fullParams->put('chatName, "Smart Bot's Chat");
1521  
        stefansChat_onLine_fullParams->put("Chat line symbol", x);
1522  
        post(x, "is", "a Smart Bot's chat line");
1523  
        post(x, "is", "recent");
1524  
        postChatLineInfo(x, text);
1525  
        smartBotsChat_n_notify(nr);
1526  
        ai_speculateWithActiveAndTimeout(x, speculationTimeoutForNewChatLine);
1527  
        if (!byBot())
1528  
          lastUserLines.put("Smart Bot's Chat", ll(text, quote(text), x));
1529  
      }
1530  
    }
1531  
    
1532  
    temp tempSetThreadLocal(answering, true);
1533  
    try {
1534  
      S a = actualAnswer(text);
1535  
      a = shortenAnswerForChatAndUploadFull(text, a);
1536  
      postToSmartBotsChat(a);
1537  
      callAll(getAndClearThreadLocal(afterAnswering));
1538  
    } on fail {
1539  
      clearThreadLocal(afterAnswering);
1540  
    }
1541  
  });
1542  
}
1543  
1544  
sS handleArchiveMsg(S msgSymbol) {
1545  
  S text = firstQuoted(ai_texts(msgSymbol, "is", "$X"));
1546  
  if (text == null) ret "No text found for " + msgSymbol;
1547  
  text = unquote(text);
1548  
  SS oldParams = setThreadLocal(stefansChat_onLine_fullParams, lithashmap("Chat line symbol", msgSymbol));
1549  
  try {
1550  
    ret actualAnswer(text);
1551  
  } finally {
1552  
    stefansChat_onLine_fullParams.set(oldParams);
1553  
  }
1554  
}
1555  
1556  
sS shortenAnswerForChatAndUploadFull(S text, S a) {
1557  
  a = shorten(a, ultimateAnswerLimit);
1558  
  if (l(a) > stefansChat_messageLimit()) {
1559  
    S title = "Smart Bot's answer to: " + text;
1560  
    S id = ntUpload("smart-bot-for-user", title, unSlackSnippet(a));
1561  
    a = snippetURL(id) + " | " + a;
1562  
  }
1563  
  ret a;
1564  
}
1565  
1566  
static bool ai_enabled() {
1567  
  true;
1568  
}
1569  
1570  
sbool http_isBot() {
1571  
  ret userAgentIsBot(serveHttp_userAgent());
1572  
}
1573  
1574  
// UNUSED
1575  
svoid softRestart_level1 {
1576  
  startedLoading();
1577  
  cloningSince = sysNow();
1578  
  classesToShare = "T3, TripleWeb, Symbol, GlobalID, MultiSet";
1579  
  Class c = hotwire(programID());
1580  
  set(c, ai_fillTripleIndex_useThese := asList(ai_allTriples()));
1581  
  
1582  
  softRestart_phase2(c);
1583  
}
1584  
1585  
svoid softRestart_phase2(final Class c) {
1586  
  print("Cloning phase 2");
1587  
  set(c, cloned := true);
1588  
  set(c, clonedSince := cloningSince);
1589  
  set(c, postStartUpMessageToChat := chatName());
1590  
  addAll((L) getOpt(c, 'latestWebs), latestWebs);
1591  
  
1592  
  removeFirstInjection();
1593  
    
1594  
  afterAnswering(r {
1595  
    // Create raw thread without any registering/pinging etc.
1596  
    //new Thread("Soft-Restarting") {
1597  
    //  public void run() ctex {
1598  
        //Thread.sleep(2000);
1599  
        
1600  
        print("Cloning, new thread");
1601  
        // copy JavaX translator over
1602  
        copyFields(mc(), c, 'transpileRaw_trans);
1603  
        transpileRaw_trans = null;
1604  
  
1605  
        cleanUp(mc()); // This should end all the threads & the HTTP server
1606  
        System.out.println("Cloning: Cleaned up");
1607  
        clearAllVariables();
1608  
        System.out.println("Cloning: Running main");
1609  
        runMain(c);
1610  
        System.out.println("Cloning: Done!");
1611  
    //  }
1612  
    //}.start();
1613  
  });
1614  
}
1615  
1616  
// also reuse the index
1617  
svoid softRestart_level2 {
1618  
  startedLoading();
1619  
  cloningSince = sysNow();
1620  
  classesToShare = smartBot_sharedClassesForRestart();
1621  
  Class c = hotwire(programID());
1622  
  //set(c, ai_fillTripleIndex_useThese := asList(ai_allTriples()));
1623  
  set(c, ai_fillTripleIndex_useTripleIndex := tripleIndex());
1624  
  
1625  
  softRestart_phase2(c);
1626  
}
1627  
1628  
svoid afterAnswering(O runnable) {
1629  
  if (isTrue(answering!))
1630  
    afterAnswering.set(addToOrCreateList(afterAnswering!, runnable));
1631  
  else
1632  
    callF(runnable);
1633  
}
1634  
1635  
svoid addToLatestWebs(Web web) {
1636  
  latestWebs.add(web.globalIDObj());
1637  
}
1638  
1639  
svoid dynClear {
1640  
  veryQuickJava_refresh();
1641  
  hotwireCached_clear();
1642  
  clearAllCaches();
1643  
}
1644  
1645  
svoid postChatLineInfo(S x, S text) {
1646  
  post(x, "has text", quote(text));
1647  
  post(x, "was", byBot() ? "sent by bot" : "sent by human");
1648  
  post(x, "was sent by IP", (S) lookupPossiblyIgnoreCase(stefansChat_onLine_fullParams!, "ip"));
1649  
}
1650  
1651  
static WebSocket makeWebSocket(NanoHTTPD.IHTTPSession handshake) {
1652  
  print("New WebSocket.");
1653  
  ret new WebSocket(handshake) {
1654  
    AutoCloseable streamer;
1655  
    
1656  
    @Override
1657  
    protected void onMessage(WebSocketFrame messageFrame) {
1658  
      S s = messageFrame.getTextPayload();
1659  
      print("WebSocket msg: " + s);
1660  
      if (streamer == null && eq(s, "stream-big-number")) {
1661  
        streamer = timerAsAutocloseable(doEveryStartingNow(100, new Runnable {
1662  
          S lastS = null;
1663  
          public void run() ctex {
1664  
            S s = formatWithThousands(ai_theBigNumber());
1665  
            if (neq(s, lastS)) {
1666  
              lastS = s;
1667  
              //print("Sending: " + s);
1668  
              send(s);
1669  
            }
1670  
          }
1671  
        }));
1672  
        println("Streaming!");
1673  
      }
1674  
    }
1675  
    
1676  
    protected void onClose(WebSocketFrame.CloseCode code, String reason, boolean initiatedByRemote) {
1677  
      print("WebSocket close");
1678  
      _close(streamer);
1679  
      streamer = null;
1680  
    }
1681  
  };
1682  
};
1683  
1684  
sS diskSpaceInfo() {
1685  
  ret toM(fileSize(programFile("triples.gz"))) + " MB (triples.gz) + " + toM(fileSize(programFile("webs-made.txt"))) + " MB (webs-made.txt). "
1686  
  + toM(userDir().getUsableSpace()) + " MB free disk space";
1687  
}
1688  
1689  
please include function ai_possibleRuleNames.

Author comment

Began life as a copy of #1009195

download  show line numbers  debug dex  old transpilations   

Travelled to 20 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, jmyaexzvplwz, jtubtzbbkimh, lpdgvwnxivlt, mjouhigkdmyk, mqqgnosmbjvj, onxytkatvevr, ppjhyzlbdabe, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt, ydilcnlqtmvn

No comments. add comment

Snippet ID: #1010745
Snippet name: Smart Bot (LIVE)
Eternal ID of this version: #1010745/939
Text MD5: cd0a6a4aaf387d0b2c5dd9090c9e2157
Transpilation MD5: 73477117d0a453acc4c02eb07f33d8a4
Author: stefan
Category: javax / chat
Type: JavaX source code (desktop)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2018-06-15 02:59:13
Source code size: 51838 bytes / 1689 lines
Pitched / IR pitched: No / No
Views / Downloads: 3128 / 1150567
Version history: 938 change(s)
Referenced in: [show references]