!7

sS regexpActivator = "."; // always

!include once #1017764 // VirtualMechLists

sS mechLibID = #1400124;
static O onOutput; // VF1<S>
static bool authorized;
sS msgGlobalID;

static L<AbstractThinkBot> bots;

abstract sclass AbstractThinkBot {
  transient VF1<? super S> postMessage;
  transient new L<Map> recentHistory;

  abstract void thinkAbout(S input);
  
  void postMessage(S s) {
    callF(postMessage, s);
  }
  
  JComponent visualize() {
    ret jpanel();
  }
}

p {
  mech_useLibrary(mechLibID);
  L<Class<? extends AbstractThinkBot>> classes = botClasses();
  print("Have think classes: " + classNames(classes));
  makeBots();
  bot();
}

static L<Class<? extends AbstractThinkBot>> botClasses() {
  ret myNonAbstractClassesImplementing(AbstractThinkBot);
}

svoid makeBots() {
  bots = map nuWithoutArguments(botClasses());
}

sbool telegram_amIAuthorized() {
  ret authorized;
}

svoid setMsgGlobalID(S globalID) {
  msgGlobalID = globalID;
}

sS answer(S s) {
  temp tempSetThreadLocal(telegram_msg_tl(), litorderedmap(globalID := msgGlobalID));
  msgGlobalID = null;
  final new L<S> output;
  for (AbstractThinkBot bot : bots) pcall {
    bot.postMessage = voidfunc(S s) {
      print(">> " + s);
      pcallF(onOutput, s);
      output.add(s);
    };
    bot.thinkAbout(s);
  }
  ret rtrim(lines(output));
}

svoid setDebug(bool b) {
  for (O bot : unnull(bots))
    setOpt(bot, debug := b);
}



please include function dm_reloadMe.

sclass TelegramFactsBot > AbstractThinkBot {
  !include #1018038
  
  visualize {
    ret withCenteredButtons(super.visualize(),
      "Checking Log", r { showText("Checking Log", lines(checkingLog)) });
  }
}