abstract sclass AbstractTelegramThinkBot > DynPrintLog {
  abstract void thinkAbout(S input);
  
  transient int lookback = 3; // old lines to grab
  transient Set<S> toSend;
  transient LatestList<Map> recentHistory;

  // only called when not in test mode
  start {
    loadFunctions_preferCached();
    dm_useLocallyCopiedMechLists();

    recentHistory = new LatestList(lookback);
    recentHistory.addAll(map_pcall unstructureUnquote(dropLast(lastNLines(lookback, telegramLogFile()))));
    watchStructureLog_plusLastLine(500, telegramLogFile(), voidfunc(final Map map) {
      temp tempAfterwards(r { recentHistory.add(map) });
      if (!eqGet(map, 'type, 'heard)) ret;
      printStruct(map);

      try {
        setThreadLocal((ThreadLocal) getOptMC('makeAndCall_initChild), voidfunc(Class c) { copyFields(mc(), c, 'telegram_msg_tl) });
        temp tempSetThreadLocal(telegram_msg_tl(), map);
        
        S s = getString(map, 'text);
        toSend = new LinkedHashSet;
        thinkAbout(s);
        for (PairS out : takeFirst(3, getAndClearList(toSend))) {
          recentHistory.add(litmap(text := out.a));
          telegram_postToSendLog(out, (Long) get(map, 'where));
        }
      } catch e {
        printStackTrace(e);
        postMessage(exceptionToStringShort(e));
      }
    });
  }
  
  void postMessage(S s) {
    print("Sending: " + s);
    toSend.add(s);
  }
}