diff --git a/amd/build/editformhelper.min.js b/amd/build/editformhelper.min.js
index b50e111..d6dc172 100644
--- a/amd/build/editformhelper.min.js
+++ b/amd/build/editformhelper.min.js
@@ -5,6 +5,6 @@ define("qtype_aitext/editformhelper",["exports","core/str","core/ajax","core/log
    * @module     qtype_aitext/editformhelper
    * @copyright  2024 Justin Hunt <justin@poodll.com>
    * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
-   */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_ajax=_interopRequireDefault(_ajax),_log=_interopRequireDefault(_log),_notification=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(_notification);const Selectors_fields={sampleanswer:"#id_sampleanswer",sampleanswerbtn:"#id_sampleanswerbtn",sampleanswereval:"#id_sampleanswereval",aiprompt:"#id_aiprompt",markscheme:"#id_markscheme",defaultmark:"#id_defaultmark"};_exports.init=()=>{var strings={};(0,_str.get_strings)([{key:"prompttester",component:"qtype_aitext"},{key:"sampleanswerempty",component:"qtype_aitext"}]).done((function(s){var i=0;strings.prompttester=s[i++],strings.sampleanswerempty=s[i++]})),document.querySelector(Selectors_fields.sampleanswerbtn).addEventListener("click",(e=>{const form=e.target.closest("form"),sampleanswer=form.querySelector(Selectors_fields.sampleanswer),sampleanswereval=form.querySelector(Selectors_fields.sampleanswereval),aiprompt=form.querySelector(Selectors_fields.aiprompt),marksscheme=form.querySelector(Selectors_fields.markscheme),defaultmark=form.querySelector(Selectors_fields.defaultmark);""!==sampleanswer.value&&""!==aiprompt.value?(sampleanswereval.innerHTML='<i class="icon fa fa-spinner fa-spin fa-2x"></i>',_ajax.default.call([{methodname:"qtype_aitext_fetch_ai_grade",args:{response:sampleanswer.value,defaultmark:defaultmark.value,prompt:aiprompt.value,marksscheme:marksscheme.value},async:!1}])[0].then((function(airesponse){_log.default.debug(airesponse),airesponse.feedback&&(sampleanswereval.textContent=airesponse.feedback+" (GRADE: "+airesponse.marks+"/"+defaultmark.value+")")})).fail((error=>{(0,_notification.exception)(error),sampleanswereval.innerHTML=""}))):_notification.default.alert(strings.prompttester,strings.sampleanswerempty)}))}}));
+   */Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.init=void 0,_ajax=_interopRequireDefault(_ajax),_log=_interopRequireDefault(_log),_notification=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}(_notification);const Selectors_fields={sampleanswer:"#id_sampleanswer",sampleanswerbtn:"#id_sampleanswerbtn",sampleanswereval:"#id_sampleanswereval",aiprompt:"#id_aiprompt",markscheme:"#id_markscheme",defaultmark:"#id_defaultmark"};_exports.init=contextid=>{var strings={};(0,_str.get_strings)([{key:"prompttester",component:"qtype_aitext"},{key:"sampleanswerempty",component:"qtype_aitext"}]).done((function(s){var i=0;strings.prompttester=s[i++],strings.sampleanswerempty=s[i++]})),document.querySelector(Selectors_fields.sampleanswerbtn).addEventListener("click",(e=>{const form=e.target.closest("form"),sampleanswer=form.querySelector(Selectors_fields.sampleanswer),sampleanswereval=form.querySelector(Selectors_fields.sampleanswereval),aiprompt=form.querySelector(Selectors_fields.aiprompt),marksscheme=form.querySelector(Selectors_fields.markscheme),defaultmark=form.querySelector(Selectors_fields.defaultmark);""!==sampleanswer.value&&""!==aiprompt.value?(sampleanswereval.innerHTML='<i class="icon fa fa-spinner fa-spin fa-2x"></i>',_ajax.default.call([{methodname:"qtype_aitext_fetch_ai_grade",args:{response:sampleanswer.value,defaultmark:defaultmark.value,prompt:aiprompt.value,marksscheme:marksscheme.value,contextid:contextid},async:!1}])[0].then((function(airesponse){_log.default.debug(airesponse),airesponse.feedback&&(sampleanswereval.textContent=airesponse.feedback+" (GRADE: "+airesponse.marks+"/"+defaultmark.value+")")})).fail((error=>{(0,_notification.exception)(error),sampleanswereval.innerHTML=""}))):_notification.default.alert(strings.prompttester,strings.sampleanswerempty)}))}}));
 
 //# sourceMappingURL=editformhelper.min.js.map
\ No newline at end of file
diff --git a/amd/build/editformhelper.min.js.map b/amd/build/editformhelper.min.js.map
index 8397b91..b36c471 100644
--- a/amd/build/editformhelper.min.js.map
+++ b/amd/build/editformhelper.min.js.map
@@ -1 +1 @@
-{"version":3,"file":"editformhelper.min.js","sources":["../src/editformhelper.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/ //\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n\nimport {get_strings} from 'core/str';\nimport Ajax from 'core/ajax';\nimport Log from 'core/log';\nimport Notify from 'core/notification';\nimport {exception as displayException} from 'core/notification';\n\n/**\n * Question AI Text Edit Form Helper\n *\n * @module     qtype_aitext/editformhelper\n * @copyright  2024 Justin Hunt <justin@poodll.com>\n * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nconst Selectors = {\n    fields: {\n        sampleanswer: '#id_sampleanswer',\n        sampleanswerbtn: '#id_sampleanswerbtn',\n        sampleanswereval: '#id_sampleanswereval',\n        aiprompt: '#id_aiprompt',\n        markscheme: '#id_markscheme',\n        defaultmark: '#id_defaultmark',\n    },\n};\n\n/**\n * Initialise the format chooser.\n */\nexport const init = () => {\n\n    // Set up strings\n    var strings={};\n    get_strings([\n        { \"key\": \"prompttester\", \"component\": 'qtype_aitext'},\n        { \"key\": \"sampleanswerempty\", \"component\": 'qtype_aitext'},\n\n    ]).done(function (s) {\n        var i = 0;\n        strings.prompttester = s[i++];\n        strings.sampleanswerempty = s[i++];\n    });\n\n    document.querySelector(Selectors.fields.sampleanswerbtn).addEventListener('click', e => {\n\n        const form = e.target.closest('form');\n        const sampleanswer = form.querySelector(Selectors.fields.sampleanswer);\n        const sampleanswereval = form.querySelector(Selectors.fields.sampleanswereval);\n        const aiprompt = form.querySelector(Selectors.fields.aiprompt);\n        const marksscheme = form.querySelector(Selectors.fields.markscheme);\n        const defaultmark = form.querySelector(Selectors.fields.defaultmark);\n\n        if(sampleanswer.value===\"\" || aiprompt.value===\"\"){\n            Notify.alert(strings.prompttester, strings.sampleanswerempty);\n            return;\n        }\n\n        //put  spinner in place\n        sampleanswereval.innerHTML='<i class=\"icon fa fa-spinner fa-spin fa-2x\"></i>';\n\n        Ajax.call([{\n            methodname: 'qtype_aitext_fetch_ai_grade',\n            args: {\n                response: sampleanswer.value,\n                defaultmark: defaultmark.value,\n                prompt: aiprompt.value,\n                marksscheme: marksscheme.value\n            },\n            async: false\n        }])[0].then(function(airesponse) {\n            Log.debug(airesponse);\n            if (airesponse.feedback) {\n                sampleanswereval.textContent = airesponse.feedback + ' (GRADE: ' + airesponse.marks + '/' + defaultmark.value + ')';\n            }\n        }).fail(error => {\n            displayException(error);\n            sampleanswereval.innerHTML = '';\n        });\n    });//end of click\n};\n"],"names":["Selectors","sampleanswer","sampleanswerbtn","sampleanswereval","aiprompt","markscheme","defaultmark","strings","done","s","i","prompttester","sampleanswerempty","document","querySelector","addEventListener","e","form","target","closest","marksscheme","value","innerHTML","call","methodname","args","response","prompt","async","then","airesponse","debug","feedback","textContent","marks","fail","error","alert"],"mappings":";;;;;;;w0BA4BMA,iBACM,CACJC,aAAc,mBACdC,gBAAiB,sBACjBC,iBAAkB,uBAClBC,SAAU,eACVC,WAAY,iBACZC,YAAa,iCAOD,SAGZC,QAAQ,wBACA,CACR,KAAS,yBAA6B,gBACtC,KAAS,8BAAkC,kBAE5CC,MAAK,SAAUC,OACVC,EAAI,EACRH,QAAQI,aAAeF,EAAEC,KACzBH,QAAQK,kBAAoBH,EAAEC,QAGlCG,SAASC,cAAcd,iBAAiBE,iBAAiBa,iBAAiB,SAASC,UAEzEC,KAAOD,EAAEE,OAAOC,QAAQ,QACxBlB,aAAegB,KAAKH,cAAcd,iBAAiBC,cACnDE,iBAAmBc,KAAKH,cAAcd,iBAAiBG,kBACvDC,SAAWa,KAAKH,cAAcd,iBAAiBI,UAC/CgB,YAAcH,KAAKH,cAAcd,iBAAiBK,YAClDC,YAAcW,KAAKH,cAAcd,iBAAiBM,aAEhC,KAArBL,aAAaoB,OAA+B,KAAjBjB,SAASiB,OAMvClB,iBAAiBmB,UAAU,iEAEtBC,KAAK,CAAC,CACPC,WAAY,8BACZC,KAAM,CACFC,SAAUzB,aAAaoB,MACvBf,YAAaA,YAAYe,MACzBM,OAAQvB,SAASiB,MACjBD,YAAaA,YAAYC,OAE7BO,OAAO,KACP,GAAGC,MAAK,SAASC,yBACbC,MAAMD,YACNA,WAAWE,WACX7B,iBAAiB8B,YAAcH,WAAWE,SAAW,YAAcF,WAAWI,MAAQ,IAAM5B,YAAYe,MAAQ,QAErHc,MAAKC,oCACaA,OACjBjC,iBAAiBmB,UAAY,6BAvBtBe,MAAM9B,QAAQI,aAAcJ,QAAQK"}
\ No newline at end of file
+{"version":3,"file":"editformhelper.min.js","sources":["../src/editformhelper.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/ //\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.\n\nimport {get_strings} from 'core/str';\nimport Ajax from 'core/ajax';\nimport Log from 'core/log';\nimport Notify from 'core/notification';\nimport {exception as displayException} from 'core/notification';\n\n/**\n * Question AI Text Edit Form Helper\n *\n * @module     qtype_aitext/editformhelper\n * @copyright  2024 Justin Hunt <justin@poodll.com>\n * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nconst Selectors = {\n    fields: {\n        sampleanswer: '#id_sampleanswer',\n        sampleanswerbtn: '#id_sampleanswerbtn',\n        sampleanswereval: '#id_sampleanswereval',\n        aiprompt: '#id_aiprompt',\n        markscheme: '#id_markscheme',\n        defaultmark: '#id_defaultmark',\n    },\n};\n\n/**\n * Initialise the format chooser.\n */\nexport const init = (contextid) => {\n\n    // Set up strings\n    var strings={};\n    get_strings([\n        { \"key\": \"prompttester\", \"component\": 'qtype_aitext'},\n        { \"key\": \"sampleanswerempty\", \"component\": 'qtype_aitext'},\n\n    ]).done(function (s) {\n        var i = 0;\n        strings.prompttester = s[i++];\n        strings.sampleanswerempty = s[i++];\n    });\n\n    document.querySelector(Selectors.fields.sampleanswerbtn).addEventListener('click', e => {\n\n        const form = e.target.closest('form');\n        const sampleanswer = form.querySelector(Selectors.fields.sampleanswer);\n        const sampleanswereval = form.querySelector(Selectors.fields.sampleanswereval);\n        const aiprompt = form.querySelector(Selectors.fields.aiprompt);\n        const marksscheme = form.querySelector(Selectors.fields.markscheme);\n        const defaultmark = form.querySelector(Selectors.fields.defaultmark);\n\n        if(sampleanswer.value===\"\" || aiprompt.value===\"\"){\n            Notify.alert(strings.prompttester, strings.sampleanswerempty);\n            return;\n        }\n\n        //put  spinner in place\n        sampleanswereval.innerHTML='<i class=\"icon fa fa-spinner fa-spin fa-2x\"></i>';\n\n        Ajax.call([{\n            methodname: 'qtype_aitext_fetch_ai_grade',\n            args: {\n                response: sampleanswer.value,\n                defaultmark: defaultmark.value,\n                prompt: aiprompt.value,\n                marksscheme: marksscheme.value,\n                contextid: contextid\n            },\n            async: false\n        }])[0].then(function(airesponse) {\n            Log.debug(airesponse);\n            if (airesponse.feedback) {\n                sampleanswereval.textContent = airesponse.feedback + ' (GRADE: ' + airesponse.marks + '/' + defaultmark.value + ')';\n            }\n        }).fail(error => {\n            displayException(error);\n            sampleanswereval.innerHTML = '';\n        });\n    });//end of click\n};\n"],"names":["Selectors","sampleanswer","sampleanswerbtn","sampleanswereval","aiprompt","markscheme","defaultmark","contextid","strings","done","s","i","prompttester","sampleanswerempty","document","querySelector","addEventListener","e","form","target","closest","marksscheme","value","innerHTML","call","methodname","args","response","prompt","async","then","airesponse","debug","feedback","textContent","marks","fail","error","alert"],"mappings":";;;;;;;w0BA4BMA,iBACM,CACJC,aAAc,mBACdC,gBAAiB,sBACjBC,iBAAkB,uBAClBC,SAAU,eACVC,WAAY,iBACZC,YAAa,iCAOAC,gBAGbC,QAAQ,wBACA,CACR,KAAS,yBAA6B,gBACtC,KAAS,8BAAkC,kBAE5CC,MAAK,SAAUC,OACVC,EAAI,EACRH,QAAQI,aAAeF,EAAEC,KACzBH,QAAQK,kBAAoBH,EAAEC,QAGlCG,SAASC,cAAcf,iBAAiBE,iBAAiBc,iBAAiB,SAASC,UAEzEC,KAAOD,EAAEE,OAAOC,QAAQ,QACxBnB,aAAeiB,KAAKH,cAAcf,iBAAiBC,cACnDE,iBAAmBe,KAAKH,cAAcf,iBAAiBG,kBACvDC,SAAWc,KAAKH,cAAcf,iBAAiBI,UAC/CiB,YAAcH,KAAKH,cAAcf,iBAAiBK,YAClDC,YAAcY,KAAKH,cAAcf,iBAAiBM,aAEhC,KAArBL,aAAaqB,OAA+B,KAAjBlB,SAASkB,OAMvCnB,iBAAiBoB,UAAU,iEAEtBC,KAAK,CAAC,CACPC,WAAY,8BACZC,KAAM,CACFC,SAAU1B,aAAaqB,MACvBhB,YAAaA,YAAYgB,MACzBM,OAAQxB,SAASkB,MACjBD,YAAaA,YAAYC,MACzBf,UAAWA,WAEfsB,OAAO,KACP,GAAGC,MAAK,SAASC,yBACbC,MAAMD,YACNA,WAAWE,WACX9B,iBAAiB+B,YAAcH,WAAWE,SAAW,YAAcF,WAAWI,MAAQ,IAAM7B,YAAYgB,MAAQ,QAErHc,MAAKC,oCACaA,OACjBlC,iBAAiBoB,UAAY,6BAxBtBe,MAAM9B,QAAQI,aAAcJ,QAAQK"}
\ No newline at end of file
diff --git a/amd/src/editformhelper.js b/amd/src/editformhelper.js
index 11d6b33..5c67abd 100644
--- a/amd/src/editformhelper.js
+++ b/amd/src/editformhelper.js
@@ -40,7 +40,7 @@ const Selectors = {
 /**
  * Initialise the format chooser.
  */
-export const init = () => {
+export const init = (contextid) => {
 
     // Set up strings
     var strings={};
@@ -77,7 +77,8 @@ export const init = () => {
                 response: sampleanswer.value,
                 defaultmark: defaultmark.value,
                 prompt: aiprompt.value,
-                marksscheme: marksscheme.value
+                marksscheme: marksscheme.value,
+                contextid: contextid
             },
             async: false
         }])[0].then(function(airesponse) {
diff --git a/classes/external.php b/classes/external.php
index a405e14..ad4a7f6 100644
--- a/classes/external.php
+++ b/classes/external.php
@@ -47,6 +47,7 @@ public static function fetch_ai_grade_parameters(): external_function_parameters
                 'defaultmark' => new external_value(PARAM_INT, 'The total possible score'),
                 'prompt' => new external_value(PARAM_TEXT, 'The AI Prompt'),
                 'marksscheme' => new external_value(PARAM_TEXT, 'The marks scheme'),
+                'contextid' => new external_value(PARAM_INT, 'The context id'),
             ]
         );
 
@@ -55,18 +56,40 @@ public static function fetch_ai_grade_parameters(): external_function_parameters
     /**
      * Similar to clicking the submit button.
      *
-     * @param array $response
+     * @param string $response
      * @param integer $defaultmark
      * @param string $prompt
      * @param string $marksscheme
+     * @param int $contextid the context id
      * @return array the response array
      */
-    public static function fetch_ai_grade($response, $defaultmark, $prompt, $marksscheme): stdClass {
+    public static function fetch_ai_grade(string $response, int $defaultmark, string $prompt, string $marksscheme, int $contextid): stdClass {
+        [
+                'response' => $response,
+                'defaultmark' => $defaultmark,
+                'prompt' => $prompt,
+                'marksscheme' => $marksscheme,
+                'contextid' => $contextid,
+        ] = self::validate_parameters(self::fetch_ai_grade_parameters(),
+                [
+                        'response' => $response,
+                        'defaultmark' => $defaultmark,
+                        'prompt' => $prompt,
+                        'marksscheme' => $marksscheme,
+                        'contextid' => $contextid,
+                ]
+        );
+        $context = $contextid === 0 ? context_system::instance() : context::instance_by_id($contextid);
+        self::validate_context($context);
+
+        // TODO Eventually move this to a own capability which by default is assigned to a teacher in a course.
+        require_capability('mod/quiz:grade', $context);
+
         // Build an aitext question instance so we can call the same code that the question type uses when it grades.
         $type = 'aitext';
         \question_bank::load_question_definition_classes($type);
         $aiquestion = new qtype_aitext_question();
-        $aiquestion->contextid = 0;
+        $aiquestion->contextid = $contextid;
         $aiquestion->qtype = \question_bank::get_qtype('aitext');
         // Make sure we have the right data for AI to work with.
         if (!empty($response) && !empty($prompt) && $defaultmark > 0) {
diff --git a/edit_aitext_form.php b/edit_aitext_form.php
index 470305f..1767306 100755
--- a/edit_aitext_form.php
+++ b/edit_aitext_form.php
@@ -135,7 +135,7 @@ protected function definition_inner($mform) {
                 ['rows' => 10], $this->editoroptions);
 
         // Load any JS that we need to make things happen, specifically the prompt tester.
-        $PAGE->requires->js_call_amd('qtype_aitext/editformhelper', 'init', []);
+        $PAGE->requires->js_call_amd('qtype_aitext/editformhelper', 'init', [$this->context->id]);
     }
 
     /**
diff --git a/question.php b/question.php
index 01cc092..e3708e8 100755
--- a/question.php
+++ b/question.php
@@ -154,8 +154,7 @@ public function perform_request(string $prompt, string $purpose = 'feedback'): s
         $backend = get_config('qtype_aitext', 'backend');
         if ($backend == 'local_ai_manager') {
             $manager = new local_ai_manager\manager($purpose);
-            $llmresponse = (object) $manager->perform_request($prompt,  ['component' => 'qtype_aitext',
-             'contextid' => $this->contextid]);
+            $llmresponse = (object) $manager->perform_request($prompt, 'qtype_aitext', $this->contextid);
             if ($llmresponse->get_code() !== 200) {
                 throw new moodle_exception(
                 'err_retrievingfeedback',
diff --git a/renderer.php b/renderer.php
index 2902cc6..d438ab7 100755
--- a/renderer.php
+++ b/renderer.php
@@ -23,8 +23,6 @@
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-use qtype_aitext\form\edit_spellcheck;
-
 defined('MOODLE_INTERNAL') || die();
 /**
  * Generates the output for aitext questions.