Skip to content

CTATLLMInput

jsewall edited this page Jul 27, 2026 · 2 revisions

CTATLLMInput and CTATLLMTextArea

These components were created to permit a student's text input string to be evaluated by an external server process. CTATLLMInput accepts a single line of text, while CTATLLMTextArea accepts multi-line input. The remote server must accept an HTTP request whose content is determined by component attributes and typically includes the student's entry on the component. 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 (SAI) 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 CTATLLMInput 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="llm_input" class="CTATLLMInput" 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 ${key} in the URL will be replaced by the value of data-ctat-llm-key, below. Any occurrences of ${input} in the URL's search parameters will be replaced by the student's input into the component.
  • data-ctat-llm-key: Optional A value for the LLM's API authentication string. See data-ctat-nlp-url, above. The key can also be defined as window.LLM_API_KEY.
  • data-ctat-nlp-method: GET or POST. Default is POST. 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. Dynamic text insertions are also available from any other CTAT component instance: an occurrence of ${_componentID_} will be replaced by the contents of a CTAT component whose id is componentID.
  • data-ctat-llm-output-instructions: general instructions for the LLM output, which should be inserted into the data-ctat-post-body prompt by the tag ${LLM_output_instructions}. The default value: "Make your response JSON with properties 'evaluation' (your assessment of student_input for this step, good or bad), 'feedback' (your response to this specific student_input) and 'advice' (an array of up to 4 hints on this individual step, most general to most specific, with the last one giving your answer). Return JSON only, no markdown."
  • data-ctat-nlp-action: A nonempty string. Default LLMevaluation. The value of 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.
  • data-ctat-parse-llm-response: Optional. The name of a function in global scope that will be called with 2 arguments: (1) the response from the LLM, normally a JSON string, and (2) an optional object; if the function is called on the response to a student's hint request, this object will include {..., type: "hint"} The function should return a string, commonly a JSON string, that will become the input value sent to the tutor's SAI matcher. If this is a hint request, the function should return a JSON string that encodes an array of hint texts.

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 CTATLLMInput 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 user presses the Tab key or clicks on another CTAT component.
  • 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.
LLMevaluation 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

.CTATLLMInput { 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);

Clone this wiki locally