Skip to content

Commit aeb3acd

Browse files
caswelltomclaude
andcommitted
v3.4.4: Admin settings restructure + curl filelib fixes
Restructured admin settings into a SOLA category with 7 focused pages, replacing the single scrolling page plus the obsolete JS-based tab hack. All existing settings preserved, no DB migration, no capability changes. Pages under Site admin > Plugins > Local plugins > SOLA (AI Course Assistant): General Enabled toggle, remote config URL, version banner AI Provider & Models Provider, key, model, temp, system prompt, tokens, history Content & RAG RAG + embedding + chunk tuning + performance caps Safety & Moderation Quiz hide, off-topic, wellbeing, integrity Engagement Study plans, reminders, voice/realtime, surveys, usability, rubrics Branding & UI Institution name, display name, welcome, avatar, position Integrations FAQ/Zendesk, Redash, CDN, plugin self-update Plus 7 external pages (Starter Editor, Survey Editor, Usability Testing Editor, Rubric Editor, RAG Index, Plugin Updates, Integrity Checks) all listed under the same SOLA category. Bug fixes: - update_admin.php and rag_admin.php reindex path threw "Class curl not found" fatal errors because \curl is not auto-loaded by Moodle. Added require_once($CFG->libdir . '/filelib.php') inside every class method that creates a \curl instance: plugin_updater, reminder_manager, zendesk_client, embedding_provider\base_embedding_provider, provider\base_provider. - Removed the obsolete JS tab navigation hack and duplicated top save button script from the single settings page. Both are now redundant with the native multi-page admin category layout. QA: - All 7 new settings pages render HTTP 200 with zero errors and zero warnings over authenticated HTTP. - All 9 admin external pages (analytics, token analytics, rubric editor, survey editor, usability testing editor, RAG admin, update admin, integrity admin, starter settings) render HTTP 200 with zero errors and zero warnings. - 18 analytics methods, survey_manager, usertesting_manager, rubric_manager, and token_cost_manager all smoke tested without argument or signature errors. - All 46 lang files lint clean. Mustache template sections still balanced. CLAUDE.md updated to reflect new version. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 3c88dec commit aeb3acd

File tree

8 files changed

+322
-464
lines changed

8 files changed

+322
-464
lines changed

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
1212
SOLA (Saylor Online Learning Assistant) is a Moodle local plugin that provides an AI-powered learning coach embedded in course pages. Students interact via a floating chat widget.
1313

1414
- **Plugin component:** `local_ai_course_assistant`
15-
- **Current version:** `2026040901`, release `3.4.2`
15+
- **Current version:** `2026041101`, release `3.4.4`
1616
- **Source folder:** `~/Library/CloudStorage/Dropbox/!Saylor/aicoursetutor/ai_course_assistant/`
1717
- **Zip for upload:** `~/Library/CloudStorage/Dropbox/!Saylor/aicoursetutor/ai_course_assistant.zip`
1818
- **GitHub:** `https://github.com/saylordotorg/moodle-local_ai_course_assistant` (public)

classes/embedding_provider/base_embedding_provider.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ protected function log_embedding_cost(int $tokens): void {
150150
* @throws \moodle_exception On HTTP errors.
151151
*/
152152
protected function http_post(string $url, array $headers, string $body): string {
153+
global $CFG;
154+
require_once($CFG->libdir . '/filelib.php'); // For \curl.
153155
$curl = new \curl();
154156
$curl->setopt([
155157
'CURLOPT_HTTPHEADER' => $headers,

classes/plugin_updater.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ public static function get_current_version(): object {
4949
* or null on failure.
5050
*/
5151
public static function check_for_update(): ?object {
52+
global $CFG;
53+
require_once($CFG->libdir . '/filelib.php'); // For \curl.
5254
$token = get_config('local_ai_course_assistant', 'github_token');
5355

5456
$headers = [
@@ -116,6 +118,7 @@ public static function check_for_update(): ?object {
116118
*/
117119
public static function download_release(string $zipurl): string {
118120
global $CFG;
121+
require_once($CFG->libdir . '/filelib.php'); // For \curl.
119122

120123
// Security: only download from github.com.
121124
if (strpos($zipurl, 'https://github.com/') !== 0

classes/provider/base_provider.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ abstract protected function get_default_base_url(): string;
9494
* @throws \moodle_exception On HTTP errors.
9595
*/
9696
protected function http_post(string $url, array $headers, string $body): string {
97+
global $CFG;
98+
require_once($CFG->libdir . '/filelib.php'); // For \curl.
9799
$curl = new \curl();
98100
$curl->setopt([
99101
'CURLOPT_HTTPHEADER' => $headers,

classes/reminder_manager.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,8 @@ public static function send_email_reminder(\stdClass $reminder, string $message)
253253
* @return bool Success.
254254
*/
255255
public static function send_whatsapp_reminder(\stdClass $reminder, string $message): bool {
256-
global $DB;
256+
global $DB, $CFG;
257+
require_once($CFG->libdir . '/filelib.php'); // For \curl.
257258

258259
$apiurl = get_config('local_ai_course_assistant', 'whatsapp_api_url');
259260
$apitoken = get_config('local_ai_course_assistant', 'whatsapp_api_token');
@@ -370,6 +371,8 @@ private static function detect_whatsapp_provider(string $apiurl): string {
370371
* @return array ['success' => bool, 'httpcode' => int, 'response' => string, 'error' => string]
371372
*/
372373
private static function send_twilio_whatsapp_message(array $config, string $destination, string $body): array {
374+
global $CFG;
375+
require_once($CFG->libdir . '/filelib.php'); // For \curl.
373376
$accountsid = self::extract_twilio_account_sid($config['apiurl']);
374377
if ($accountsid === '') {
375378
return [

classes/zendesk_client.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ public static function create_ticket(
5454
string $question,
5555
string $conversationsummary
5656
): ?string {
57-
global $DB;
57+
global $DB, $CFG;
58+
require_once($CFG->libdir . '/filelib.php'); // For \curl.
5859

5960
if (!self::is_enabled()) {
6061
return null;

settings.php

Lines changed: 306 additions & 459 deletions
Large diffs are not rendered by default.

version.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
defined('MOODLE_INTERNAL') || die();
2626

2727
$plugin->component = 'local_ai_course_assistant';
28-
$plugin->version = 2026041001;
28+
$plugin->version = 2026041101;
2929
$plugin->requires = 2024100700; // Moodle 4.5+.
3030
$plugin->maturity = MATURITY_STABLE;
31-
$plugin->release = '3.4.3';
31+
$plugin->release = '3.4.4';

0 commit comments

Comments
 (0)