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

154
LINES

< > BotCompany Repo | #1027566 // Chat Bot Frontend [backup v1]

JavaX source code (Dynamic Module) [tags: use-pretranspiled] - run with: Stefan's OS

Uses 911K of libraries. Click here for Pure Java version (16184L/86K).

!7

concept Cmd {
  S patterns; // for mmo_parsePattern
  S exampleInputs; // line-separated
  S cmd; // a star pattern recognized by the backend
  S questionsForArguments; // line-separated
  int index;
  
  transient MMOPattern parsedPattern;
  void change { parsedPattern = null; super.change(); }
  MMOPattern parsedPattern() {
    if (parsedPattern == null) parsedPattern = mmo_parsePattern(patterns);
    ret parsedPattern;
  }
  
  sS _fieldOrder = "exampleInputs patterns cmd index";
}

cmodule ChatBotFrontend > DynCRUD<Cmd> {
  switchable S backendModuleLibID = "#1027443/Scenarios";
  O currentAttractor;

  class HandleArgument implements IF1<S> {
    S cmd;
    LS argQuestions;
    new LS arguments;

    *() {}
    *(S *cmd, LS *argQuestions) {}

    // process an argument
    public S get(S arg) {
      arguments.add(arg);
      if (l(arguments) >= countAsteriskTokens(cmd))
        ret sendToBackend(format_quoteAll(cmd, asObjectArray(arguments)));
      else
        ret handleQuestionWithArguments(this);
    }

    S currentQuestion() {
      ret or2(_get(argQuestions, l(arguments)), "Need argument");
    }
  }

  runnable class Cancel { setField(currentAttractor := null); }

  class UndoHandler implements IF1<Bool, S> {
    public S get(Bool yes) {
      if (!yes) ret "OK"; // user said no
      ret (S) sendToBackend("undo");
    }
  }

  start {
    dm_watchFieldAndNow backendModuleLibID(r {
      dm_setModuleName("Frontend for " + dm_moduleName(backend()))
    });
    
    crud.multiLineFields = litset("exampleInputs", "questionsForArguments");
    crud.sorter = func(Cl<Cmd> l) -> L<Cmd> { sortByField index(l) };
    crud.formFixer = 48;
  }

  S handleCommand(Cmd cmd) {
    if (cmd == null) null;
 
    print("handleCommand " + cmd.cmd);
    
    if (match("undo after confirm", cmd.cmd)) {
      O undo = dm_call(backend(), 'lastUndo);
      if (undo == null) ret "Nothing to undo";
      new WaitForAnswer_YesNo attractor;
      attractor.question = "Undo " + undo + "?";
      setField(currentAttractor := attractor);
      print("Set attractor to: " + attractor);
      attractor.processAnswer = new UndoHandler;
      attractor.cancelSilently = new Cancel;
      ret attractor.question;
    }
    
    if (hasAsteriskTokens(cmd.cmd))
      ret handleQuestionWithArguments(
        new HandleArgument(cmd.cmd, tlft(cmd.questionsForArguments)));
    else
      ret sendToBackend(cmd.cmd);
  }

  S handleQuestionWithArguments(HandleArgument handler) {
    new WaitForName attractor;
    attractor.question = handler.currentQuestion();
    setField(currentAttractor := attractor);
    print("Set attractor to: " + attractor);
    attractor.processName = handler;
    attractor.cancelSilently = new Cancel;
    ret attractor.question;
  }

  S sendToBackend(S cmd) {
    ret (S) dm_call(backend(), 'answer, cmd);
  }
  
  S backend() {
    ret dm_require(backendModuleLibID);
  }
  
  afterVisualize {
    addComponents(crud.buttons,
      jbutton("Talk to me", rThread talkToMe),
      jPopDownButton_noText("Consistency check", rThread consistencyCheck));
  }

  void talkToMe enter { dm_showConversationPopupForModule(); }

  void consistencyCheck enter {
    reindex();
    L<Cmd> cmds = list(Cmd);
    L<MMOConsistencyError> errors = mmo_consistencyCheck(
      map(cmds, cmd -> pair(cmd.exampleInputs, cmd.patterns)));
    if (empty(errors)) infoBox("No consistency problems");
    else
      dm_showText(n2(errors, "consistency problem"), lines(errors));
  }

  void reindex {
    int index = 1;
    for (Cmd cmd : conceptsSortedByField Cmd('index))
      cset(cmd, index := index++);
  }
  
  // API
  
  void copyCommandsFromBackend() {
    for (S cmd : allIfQuotedPatterns(loadSnippet(beforeSlash(backendModuleLibID)))
)
      uniqConcept(+cmd);
  }
  
  S answer(S s) {
    if (currentAttractor != null) {
      print("Sending to attractor " + currentAttractor + ": " + s);
      S a = strOrNull(call(currentAttractor, 'answer, s));
      if (a != null) {
        print("Attractor said: " + a);
        ret a;
      }
    }
    Cmd cmd = mmo_matchMultiWithTypos(1, 
      filter(conceptsSortedByField Cmd('index), c -> nempty(c.patterns)),
      c -> c.parsedPattern(), s);
    if (cmd != null) ret handleCommand(cmd);
    ret sendToBackend(s);
  }
}

Author comment

Began life as a copy of #1027518

download  show line numbers  debug dex  old transpilations   

Travelled to 7 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv

No comments. add comment

Snippet ID: #1027566
Snippet name: Chat Bot Frontend [backup v1]
Eternal ID of this version: #1027566/1
Text MD5: 60e69050c041eb9a33afaa12a38dd0d3
Transpilation MD5: cf792c16a2110ff73851adbe25fd927f
Author: stefan
Category: javax
Type: JavaX source code (Dynamic Module)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2020-03-23 23:38:42
Source code size: 4454 bytes / 154 lines
Pitched / IR pitched: No / No
Views / Downloads: 147 / 200
Referenced in: [show references]