Skip to content

Commit

Permalink
AI persistent tables added to lib/db/install.xml
Browse files Browse the repository at this point in the history
  • Loading branch information
mhughes2k committed Apr 22, 2024
1 parent 26213ee commit 9164361
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 53 deletions.
80 changes: 41 additions & 39 deletions ai/classes/aiprovider.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class AIProvider extends persistent {
// Ultimately this would extend a persistent.

const CONTEXT_ALL_MY_COURSES = -1;
const TABLE = "aiprovider";

protected static function define_properties()
{
Expand All @@ -31,13 +32,13 @@ protected static function define_properties()
'baseurl' => [
'type' => PARAM_URL
],
'embeddings' => [
'embeddingsurl' => [
'type' => PARAM_URL
],
'embeddingmodel' => [
'type' => PARAM_ALPHANUMEXT
],
'completions' => [
'completionsurl' => [
'type' => PARAM_URL
],
'completionmodel' => [
Expand Down Expand Up @@ -150,10 +151,10 @@ public function get_settings_for_user($user) {
$mycourseids = enrol_get_my_courses(array('id', 'cacherev'), 'id', 0, [], false);
$onlyenrolledcourses = $this->get('onlyenrolledcourses');
$courseids = [];
if ($this->get('context') == self::CONTEXT_ALL_MY_COURSES) {
if ($this->get('contextid') == self::CONTEXT_ALL_MY_COURSES) {
$courseids = array_keys($mycourseids);
} else {
$context = \context::instance_by_id($this->get('context'));
$context = \context::instance_by_id($this->get('contextid'));
if ($context->contextlevel == CONTEXT_COURSE) {
// Check that the specific course is also in the user's list of courses.
$courseids = array_intersect([$context->instanceid], $mycourseids);
Expand Down Expand Up @@ -187,40 +188,41 @@ public function get_settings_for_user($user) {
*/
public static function get_records($filters = [], $sort = '', $order = 'ASC', $skip = 0, $limit = 0) {
global $_ENV;

$records = [];
$fake = new static(0, (object) [
'id' => 1,
'name' => "Open AI Provider (hardcoded)",
'enabled' => true,
'allowembeddings' => true,
'allowchat' => true,
'baseurl' => 'https://api.openai.com/v1/',
'embeddings' => 'embeddings',
'embeddingmodel' => 'text-embedding-3-small',
'completions' => 'chat/completions',
'completionmodel' => 'gpt-4-turbo-preview',
'apikey'=> $_ENV['OPENAIKEY'],
'contextid' => \context_system::instance()->id,
//null, // Global AI Provider
'onlyenrolledcourses' => true
]);
array_push($records, $fake);
$fake = new static(0, (object) [
'id' => 2,
'name' => "Ollama AI Provider (hard coded)",
'enabled' => true,
'allowembeddings' => true,
'allowchat' => true,
'baseurl' => 'http://127.0.0.1:11434/api/',
'embeddings' => 'embeddings',
'embeddingmodel' => '',
'completions' => 'chat',
'completionmodel' => 'llama2',
'contextid' => null, // Global AI Provider
'onlyenrolledcourses' => true
]);
array_push($records, $fake);
$records = parent::get_records($filters, $sort, $order, $skip, $limit);
// $records = [];
// $fake = new static(0, (object) [
// 'id' => 1,
// 'name' => "Open AI Provider (hardcoded)",
// 'enabled' => true,
// 'allowembeddings' => true,
// 'allowchat' => true,
// 'baseurl' => 'https://api.openai.com/v1/',
// 'embeddings' => 'embeddings',
// 'embeddingmodel' => 'text-embedding-3-small',
// 'completions' => 'chat/completions',
// 'completionmodel' => 'gpt-4-turbo-preview',
// 'apikey'=> $_ENV['OPENAIKEY'],
// 'contextid' => \context_system::instance()->id,
// //null, // Global AI Provider
// 'onlyenrolledcourses' => true
// ]);
// array_push($records, $fake);
// $fake = new static(0, (object) [
// 'id' => 2,
// 'name' => "Ollama AI Provider (hard coded)",
// 'enabled' => true,
// 'allowembeddings' => true,
// 'allowchat' => true,
// 'baseurl' => 'http://127.0.0.1:11434/api/',
// 'embeddings' => 'embeddings',
// 'embeddingmodel' => '',
// 'completions' => 'chat',
// 'completionmodel' => 'llama2',
// 'contextid' => null, // Global AI Provider
// 'onlyenrolledcourses' => true
// ]);
// array_push($records, $fake);
/*
$fake = new static(0, (object) [
'id' => 3,
'name' => "Ollama AI Provider (hard coded) Misc Category only",
Expand All @@ -236,7 +238,7 @@ public static function get_records($filters = [], $sort = '', $order = 'ASC', $s
'onlyenrolledcourses' => true,
]);
array_push($records, $fake);

*/
$targetcontextid = $filters['contextid'] ?? null;
$targetcontext = null;
if (is_null($targetcontextid)) {
Expand Down
13 changes: 7 additions & 6 deletions ai/classes/form/openaiapiprovider.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ public function definition() {
$mform->addRule('name', null, 'required', null, 'client');
$mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'client');
$mform->addHelpButton('name', 'providername', 'ai');

$mform->addElement('advcheckbox', 'enabled', get_string('enabled', 'ai'));
$mform->addHelpButton('enabled', 'enabled', 'ai');
// Client Secret.
$mform->addElement('text','baseurl', get_string('baseurl', 'ai'));
$mform->setType('baseurl', PARAM_URL);
Expand All @@ -44,14 +45,14 @@ public function definition() {

$mform->addElement('advcheckbox', 'allowchat', get_string('allowchat', 'ai'));
$mform->addHelpButton('allowchat', 'allowchat', 'ai');
$mform->addElement('text','completions', get_string('completionspath', 'ai'));
$mform->addElement('text','completionsurl', get_string('completionspath', 'ai'));
$mform->addElement('text','completionmodel', get_string('completionmodel', 'ai'));
$mform->disabledIf('completions', 'allowchat', 'notchecked');
$mform->disabledIf('completionsurl', 'allowchat', 'notchecked');
$mform->disabledIf('completionmodel', 'allowchat', 'notchecked');

$mform->addElement('advcheckbox', 'allowembeddings', get_string('allowembeddings', 'ai'));
$mform->addHelpButton('allowembeddings', 'allowembeddings', 'ai');
$mform->addElement('text','embeddings', get_string('embeddingspath', 'ai'));
$mform->addElement('text','embeddingsurl', get_string('embeddingspath', 'ai'));
$mform->addElement('text','embeddingmodel', get_string('embeddingmodel', 'ai'));
$mform->disabledIf('embeddings', 'allowembeddings', 'notchecked');
$mform->disabledIf('embeddingmodel', 'allowembeddings', 'notchecked');
Expand Down Expand Up @@ -87,8 +88,8 @@ public function definition() {
$mform->addElement('hidden', 'onlyenrolledcourses', );
$mform->setType('onlyenrolledcourses', PARAM_RAW);

$mform->addElement('hidden', 'enabled', true);
$mform->setType('enabled', PARAM_ALPHA);
// $mform->addElement('hidden', 'enabled', true);
// $mform->setType('enabled', PARAM_ALPHA);

$mform->addElement('hidden', 'type', $this->_customdata['type']);
$mform->setType('type', PARAM_ALPHANUM);
Expand Down
2 changes: 1 addition & 1 deletion ai/classes/output/index_page.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public function providers_table($providers) {
$context = "System";
}
$completion = $provider->get('allowchat');
$embeddings = $provider->get('embeddings');
$embeddings = $provider->get('allowembeddings');
$status = $provider->get('enabled');

// Set up cells.
Expand Down
14 changes: 9 additions & 5 deletions ai/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
// We're using pid as "id" is used to specify contextids.
$providerid = optional_param('pid', '', PARAM_RAW);
$incontextid = optional_param('contextid', null, PARAM_RAW);

$context = !is_null($incontextid) ? \context::instance_by_id($incontextid) : null;
//var_dump($incontextid);
$context = !empty($incontextid) ? \context::instance_by_id($incontextid) : null;

if (empty($context)) {
$strheading = get_string(get_string('pluginname', 'ai'));
$strheading = get_string('pluginname', 'ai');
} else {
$strheading = get_string('aiprovidersin', 'ai', $context->get_context_name());
}
Expand All @@ -36,21 +36,24 @@
$mform = null;

if ($providerid) {
$provider = core\ai\api::get_provider($providerid);
$provider = api::get_provider($providerid);
if (!$provider) {
throw new moodle_exception('invaliddata');
}
}

if ($action == api::ACTION_EDIT_PROVIDER) {

if ($provider) {
// Edit
$type = "openaipi";// Should store in and read from provider.
} else {
// Create new
$type = required_param('type', PARAM_RAW);
}
$mform = new \core_ai\form\openaiapiprovider(null, [
'persistent' => $provider,
'type' => required_param('type', PARAM_RAW),
'type' => $type,
'contextid' => $incontextid
]);
}
Expand Down Expand Up @@ -81,6 +84,7 @@
$mform->display();
echo $OUTPUT->footer();
}
exit;
} else if ($action == api::ACTION_REMOVE_PROVIDER) {
// Handle remove.
} else {
Expand Down
26 changes: 25 additions & 1 deletion lib/db/install.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="lib/db" VERSION="20240129" COMMENT="XMLDB file for core Moodle tables"
<XMLDB PATH="lib/db" VERSION="20240419" COMMENT="XMLDB file for core Moodle tables"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../lib/xmldb/xmldb.xsd"
>
Expand Down Expand Up @@ -4844,5 +4844,29 @@
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
<TABLE NAME="aiprovider" COMMENT="AI Provider Persistent">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="usermodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" COMMENT="AI Provider Instance name"/>
<FIELD NAME="enabled" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="1" SEQUENCE="false"/>
<FIELD NAME="apikey" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="allowembeddings" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="1" SEQUENCE="false"/>
<FIELD NAME="allowchat" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="1" SEQUENCE="false"/>
<FIELD NAME="baseurl" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="embeddingsurl" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="completionsurl" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="embeddingmodel" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="completionmodel" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="contextid" TYPE="int" LENGTH="10" NOTNULL="false" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="onlyenrolledcourses" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="1" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="usermodified" TYPE="foreign" FIELDS="usermodified" REFTABLE="user" REFFIELDS="id"/>
</KEYS>
</TABLE>
</TABLES>
</XMLDB>
37 changes: 37 additions & 0 deletions lib/db/upgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -1129,5 +1129,42 @@ function xmldb_main_upgrade($oldversion) {
upgrade_main_savepoint(true, 2024030500.02);
}

if ($oldversion < 2024032600.01) {

// Define table aiprovider to be created.
$table = new xmldb_table('aiprovider');

// Adding fields to table aiprovider.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
$table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
$table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
$table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0');
$table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null);
$table->add_field('enabled', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '1');
$table->add_field('apikey', XMLDB_TYPE_TEXT, null, null, null, null, null);
$table->add_field('allowembeddings', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '1');
$table->add_field('allowchat', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '1');
$table->add_field('baseurl', XMLDB_TYPE_TEXT, null, null, null, null, null);
$table->add_field('embeddingsurl', XMLDB_TYPE_TEXT, null, null, null, null, null);
$table->add_field('completionsurl', XMLDB_TYPE_TEXT, null, null, null, null, null);
$table->add_field('embeddingmodel', XMLDB_TYPE_TEXT, null, null, null, null, null);
$table->add_field('completionmodel', XMLDB_TYPE_TEXT, null, null, null, null, null);
$table->add_field('contextid', XMLDB_TYPE_INTEGER, '10', null, null, null, '0');
$table->add_field('onlyenrolledcourses', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '1');

// Adding keys to table aiprovider.
$table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
$table->add_key('usermodified', XMLDB_KEY_FOREIGN, ['usermodified'], 'user', ['id']);

// Conditionally launch create table for aiprovider.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}

// Main savepoint reached.
upgrade_main_savepoint(true, 2024032600.02);
}


return true;
}
3 changes: 2 additions & 1 deletion mod/xaichat/view.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
require_once(__DIR__.'/lib.php');

use core_ai\api;
use core_ai\aiclient;
use mod_xaichat\aichatform;

// Course module id.
Expand Down Expand Up @@ -83,7 +84,7 @@
}
$stepnow = 0;
$totalsteps = 4;
$aiclient = new \core\ai\AIClient($aiprovider);
$aiclient = new AIClient($aiprovider);

$progress = new \progress_bar();
$progress->create();
Expand Down

0 comments on commit 9164361

Please sign in to comment.