CTATNLPInput - CMUCTAT/CTAT GitHub Wiki

CTATNLPInput

This component was created to permit a student's text input string to be evaluated by an external server process. The server must accept an HTTP request whose content is determined by component attributes and typically includes the student's text. The return text from the server, which typically includes an evaluation or other characterization of the student's text, will become the input element of the selection-action-input tuple submitted to the CTAT tutor (example-tracing or rule-based) for evaluation. That is, the component sends the request to the external processor and waits for the response before submitting the response for CTAT evaluation. However, an untutored action is recorded at the time of the student's entry, before submitting to the server.

In order to use CTATNLPInput instances, one has to have a server to process the components' HTTP requests and return responses as described above. See Nodejs echo server below for the code for a server that runs under Nodejs and simply echoes the request.

Code

<div id="nlp_input" class="CTATNLPInput" data-ctat-nlp-url="http://localhost:3001/echo" ></div>

Running Example

(live example will be up soon; note that an HTTP server is required)

CTATTextInput Example

Attributes and Settings

Attributes and settings specific to this component

  • data-ctat-nlp-url: Required. The web address (a URL) of the server that will process the request and return the result. Any occurrences of ${input} in the URL's search parameters will be replaced by the student's input into the component.
  • data-ctat-nlp-method: GET or POST. Default is GET. The HTTP request method.
  • data-ctat-post-body: Required if method is POST unless data-ctat-preprocess is used. The data to be submitted with the request to the remote processor. Any occurrences of ${input} will be replaced by the student's entry in this component.
  • data-ctat-nlp-action: A nonempty string. Default NLPclassification. The action element of the selection-action-input to be evaluated by the CTAT tutor.
  • data-ctat-nlp-headers: Optional HTTP request headers, as a JSON-encoded object. E.g. data-ctat-nlp-headers="{&quot;Accept&quot;: &quot;text/json&quot;}"
  • data-ctat-preprocess: Optional, used with method POST. The name of a function in global scope that will be called with a single argument, the student's input string, and should return the contents of the POST body to be sent with the request to the remote processor.

Attributes and settings common to other components

  • id: Required. The name of the component, must be a valid html id name.
  • class: Required. The class list, must include CTATNLPInput and no other CTAT<component> classes.
  • data-ctat-enabled: true or false. Default is true. Controls if the component will accept student interaction.
  • data-ctat-tutor: true or false. Default is true. Controls if direct actions on the component trigger grading.
  • data-ctat-show-feedback: true or false. Default is true unless data-ctat-tutor="false". Determines if grading feedback is shown on the component.
  • data-ctat-show-hint-highlight: true or false. Default is true. Determines if hint highlighting is shown on the component.
  • data-ctat-disable-on-correct: true or false. Default is true. Determines if the component becomes locked when it is graded as correct.
  • data-ctat-submit-on-blur: true or false. Default is true. CTATv4.5 and later If false the component will not submit the content for grading when the cursor focus exits.
  • data-ctat-submit-on-enter: true or false. Default is true. CTATv4.5 and later If false the component will not submit the content for grading when the user presses the Enter key.

Action-Input

In addition to the common Actions listed in Often Used TPAs this component supports the following actions:

Action Input Notes
UpdateTextField a string Modifies the value.
NLPclassification a string This is the default action in the selection-action-input given to the CTAT tutor for evaluation against a behavior graph or rule set.

Styling

.CTATNLPInput { width: 100px; display: inline-block; background-color: white; border-style:solid;}

.katex {
    font: 400 1.21em KaTeX_Main,Times New Roman,serif;
    line-height: 1.2;
    white-space: nowrap;
    text-indent: 0;
    text-rendering: auto
}

Nodejs echo server

To use, save this code to a file echo.js and invoke with node echo.js [port], where port is an optional HTTP port number (default 3001).

var http = require("http");
var url = require("url");

const port=(process.argv[2] ? Number(process.argv[2]) : 3001);  // default url: http://localhost:3001/echo

//Echoes received data back to client
function echo(response, data, request) {
    console.log("/echo: data\n", data);
    response.write(
        /HEAD|GET/i.test(request.method) ?
        new URL(request.url, "http://localhost:"+server.port).search :
        data
    );
    response.end();
}

function onRequest(request, response) {
  var queryData = "";

  response.setHeader("Access-Control-Allow-Origin", "*");
  response.setHeader("Access-Control-Allow-Headers", "ctatsession, Content-Type, Accept, Tutorshop-Path");
  response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS");
  response.setHeader("Access-Control-Max-Age", "1728000");

  var pathname = decodeURIComponent(url.parse(request.url).pathname);
  console.log("Request from", request.socket.remoteAddress, "for", pathname, "content-type", request.headers["content-type"]);
  request.setEncoding("utf-8");        // data assumed to be string, not FormData

  request.on("data", function(data) {
    queryData += data;
  });

  request.on("end", function() {
    try {
      switch(pathname) {
        case "/echo":
          echo(response, queryData, request);
          break;
        default:
          response.writeHead(404, {"Content-Type": "text/plain"});
          response.write("404 File or Directory Not Found : \n" + pathname);
          response.write("\nError "+err.code+" "+err.message);
          response.end();
      }
    } catch(e) {
      console.log("Error from router", e);
      request.destroy(e);
    }
  });
}

http.createServer(onRequest).listen(port);
console.log("Server listening on port",port,"argv",process.argv);
⚠️ **GitHub.com Fallback** ⚠️