MDL-82627 AI: Privacy provider

Originally implemented in MDL-82781
This commit is contained in:
Huong Nguyen 2024-08-19 17:42:49 +07:00
parent 086ac975f0
commit 67e6898853
No known key found for this signature in database
GPG Key ID: 40D88AB693A3E72A
4 changed files with 2191 additions and 20 deletions

View File

@ -16,6 +16,14 @@
namespace core_ai\privacy;
use core_privacy\local\metadata\collection;
use core_privacy\local\request\approved_contextlist;
use core_privacy\local\request\approved_userlist;
use core_privacy\local\request\contextlist;
use core_privacy\local\request\transform;
use core_privacy\local\request\userlist;
use core_privacy\local\request\writer;
/**
* Privacy Subsystem for core_ai implementing null_provider.
*
@ -24,17 +32,627 @@ namespace core_ai\privacy;
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements
\core_privacy\local\metadata\null_provider {
// TODO: Will be implemented in MDL-82781.
\core_privacy\local\metadata\provider,
\core_privacy\local\request\subsystem\provider,
\core_privacy\local\request\core_userlist_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
* Returns meta data about this system.
*
* @return string
* @param collection $collection The initialised collection to add items to.
* @return collection A listing of user data stored through this system.
*/
public static function get_reason(): string {
return 'privacy:metadata';
public static function get_metadata(collection $collection): collection {
$collection->add_database_table('ai_policy_register', [
'userid' => 'privacy:metadata:ai_policy_register:userid',
'contextid' => 'privacy:metadata:ai_policy_register:contextid',
'timeaccepted' => 'privacy:metadata:ai_policy_register:timeaccepted',
], 'privacy:metadata:ai_policy_register');
$collection->add_database_table('ai_action_register', [
'actionname' => 'privacy:metadata:ai_action_register:actionname',
'actionid' => 'privacy:metadata:ai_action_register:actionid',
'success' => 'privacy:metadata:ai_action_register:success',
'userid' => 'privacy:metadata:ai_action_register:userid',
'provider' => 'privacy:metadata:ai_action_register:provider',
'timecreated' => 'privacy:metadata:ai_action_register:timecreated',
'timecompleted' => 'privacy:metadata:ai_action_register:timecompleted',
], 'privacy:metadata:ai_action_register');
$collection->add_database_table('ai_action_generate_image', [
'prompt' => 'privacy:metadata:ai_action_generate_image:prompt',
'numberimages' => 'privacy:metadata:ai_action_generate_image:numberimages',
'quality' => 'privacy:metadata:ai_action_generate_image:quality',
'aspectratio' => 'privacy:metadata:ai_action_generate_image:aspectratio',
'style' => 'privacy:metadata:ai_action_generate_image:style',
'sourceurl' => 'privacy:metadata:ai_action_generate_image:sourceurl',
'revisedprompt' => 'privacy:metadata:ai_action_generate_image:revisedprompt',
], 'privacy:metadata:ai_action_generate_image');
$collection->add_database_table('ai_action_generate_text', [
'prompt' => 'privacy:metadata:ai_action_generate_text:prompt',
'responseid' => 'privacy:metadata:ai_action_generate_text:responseid',
'fingerprint' => 'privacy:metadata:ai_action_generate_text:fingerprint',
'generatedcontent' => 'privacy:metadata:ai_action_generate_text:generatedcontent',
'prompttokens' => 'privacy:metadata:ai_action_generate_text:prompttokens',
'completiontoken' => 'privacy:metadata:ai_action_generate_text:completiontoken',
], 'privacy:metadata:ai_action_generate_text');
$collection->add_database_table('ai_action_summarise_text', [
'prompt' => 'privacy:metadata:ai_action_summarise_text:prompt',
'responseid' => 'privacy:metadata:ai_action_summarise_text:responseid',
'fingerprint' => 'privacy:metadata:ai_action_summarise_text:fingerprint',
'generatedcontent' => 'privacy:metadata:ai_action_summarise_text:generatedcontent',
'prompttokens' => 'privacy:metadata:ai_action_summarise_text:prompttokens',
'completiontoken' => 'privacy:metadata:ai_action_summarise_text:completiontoken',
], 'privacy:metadata:ai_action_summarise_text');
return $collection;
}
/**
* Get the list of contexts that contain user information for the specified user.
*
* @param int $userid The user to search.
* @return contextlist $contextlist The contextlist containing the list of contexts used in this plugin.
*/
public static function get_contexts_for_userid(int $userid): contextlist {
$contextlist = new contextlist();
// AI policy.
$sql = 'SELECT DISTINCT ctx.id
FROM {context} ctx
JOIN {ai_policy_register} apr
ON apr.contextid = ctx.id
WHERE apr.userid = :userid';
$contextlist->add_from_sql($sql, ['userid' => $userid]);
// AI action generate text.
$sql = "SELECT DISTINCT ctx.id
FROM {context} ctx
JOIN {ai_action_register} aar
ON aar.contextid = ctx.id
JOIN {ai_action_generate_text} aagt
ON aagt.id = aar.actionid
WHERE aar.actionname = 'generate_text'
AND aar.userid = :userid";
$contextlist->add_from_sql($sql, ['userid' => $userid]);
// AI action generate image.
$sql = "SELECT DISTINCT ctx.id
FROM {context} ctx
JOIN {ai_action_register} aar
ON aar.contextid = ctx.id
JOIN {ai_action_generate_image} aagi
ON aagi.id = aar.actionid
WHERE aar.actionname = 'generate_image'
AND aar.userid = :userid";
$contextlist->add_from_sql($sql, ['userid' => $userid]);
// AI action summarise text.
$sql = "SELECT DISTINCT ctx.id
FROM {context} ctx
JOIN {ai_action_register} aar
ON aar.contextid = ctx.id
JOIN {ai_action_summarise_text} aast
ON aast.id = aar.actionid
WHERE aar.actionname = 'summarise_text'
AND aar.userid = :userid";
$contextlist->add_from_sql($sql, ['userid' => $userid]);
return $contextlist;
}
/**
* Export all user data for the specified user, in the specified contexts.
*
* @param approved_contextlist $contextlist The approved contexts to export information for.
*/
public static function export_user_data(approved_contextlist $contextlist): void {
global $DB;
// AI policy.
$userid = $contextlist->get_user()->id;
[$contextsql, $contextparams] = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);
$sql = 'SELECT apr.timeaccepted, ctx.id AS contextid
FROM {context} ctx
JOIN {ai_policy_register} apr
ON apr.contextid = ctx.id
WHERE apr.userid = :userid
AND ctx.id ' . $contextsql;
$params = [
'userid' => $userid,
];
$params += $contextparams;
$policydetails = $DB->get_recordset_sql($sql, $params);
foreach ($policydetails as $policydetail) {
$subcontexts = [
get_string('ai', 'core_ai'),
];
$name = 'policy';
$details = (object) [
'contextid' => $policydetail->contextid,
'timeaccepted' => transform::datetime($policydetail->timeaccepted),
];
$context = \context::instance_by_id($policydetail->contextid);
writer::with_context($context)->export_related_data($subcontexts, $name, $details);
}
$policydetails->close();
// AI action generate text.
$sql = "SELECT aar.actionname, aar.success, aar.provider, aar.timecreated, aar.timecompleted, aar.contextid,
aagt.prompt, aagt.responseid, aagt.fingerprint, aagt.generatedcontent,
aagt.prompttokens, aagt.completiontoken
FROM {ai_action_register} aar
JOIN {ai_action_generate_text} aagt
ON aar.actionid = aagt.id
JOIN {context} ctx
ON aar.contextid = ctx.id
WHERE aar.actionname = 'generate_text'
AND aar.userid = :userid
AND ctx.id " . $contextsql;
$params = [
'userid' => $userid,
];
$params += $contextparams;
$textgeneratedetails = $DB->get_recordset_sql($sql, $params);
foreach ($textgeneratedetails as $textgeneratedetail) {
$subcontexts = [
get_string('ai', 'core_ai'),
get_string('action_generate_text', 'core_ai'),
date('c', $textgeneratedetail->timecreated),
];
$details = (object) [
'actionname' => $textgeneratedetail->actionname,
'contextid' => $textgeneratedetail->contextid,
'prompt' => $textgeneratedetail->prompt,
'responseid' => $textgeneratedetail->responseid,
'fingerprint' => $textgeneratedetail->fingerprint,
'generatedcontent' => $textgeneratedetail->generatedcontent,
'prompttokens' => $textgeneratedetail->prompttokens,
'completiontoken' => $textgeneratedetail->completiontoken,
'success' => transform::yesno($textgeneratedetail->success),
'provider' => $textgeneratedetail->provider,
'timecreated' => transform::datetime($textgeneratedetail->timecreated),
'timecompleted' => transform::datetime($textgeneratedetail->timecompleted),
];
$name = 'action_generate_text';
$context = \context::instance_by_id($textgeneratedetail->contextid);
writer::with_context($context)->export_related_data($subcontexts, $name, $details);
}
$textgeneratedetails->close();
// AI action generate image.
$sql = "SELECT aar.actionname, aar.success, aar.provider, aar.timecreated, aar.timecompleted, aar.contextid,
aagi.prompt, aagi.numberimages, aagi.quality, aagi.aspectratio, aagi.style, aagi.sourceurl,
aagi.revisedprompt
FROM {ai_action_register} aar
JOIN {ai_action_generate_image} aagi
ON aar.actionid = aagi.id
JOIN {context} ctx
ON aar.contextid = ctx.id
WHERE aar.actionname = 'generate_image'
AND aar.userid = :userid
AND ctx.id " . $contextsql;
$params = [
'userid' => $userid,
];
$params += $contextparams;
$imagegeneratedetails = $DB->get_recordset_sql($sql, $params);
foreach ($imagegeneratedetails as $imagegeneratedetail) {
$subcontexts = [
get_string('ai', 'core_ai'),
get_string('action_generate_image', 'core_ai'),
date('c', $imagegeneratedetail->timecreated),
];
$details = (object) [
'actionname' => $imagegeneratedetail->actionname,
'contextid' => $imagegeneratedetail->contextid,
'prompt' => $imagegeneratedetail->prompt,
'numberimages' => $imagegeneratedetail->numberimages,
'quality' => $imagegeneratedetail->quality,
'aspectratio' => $imagegeneratedetail->aspectratio,
'style' => $imagegeneratedetail->style,
'sourceurl' => $imagegeneratedetail->sourceurl,
'revisedprompt' => $imagegeneratedetail->revisedprompt,
'success' => transform::yesno($imagegeneratedetail->success),
'provider' => $imagegeneratedetail->provider,
'timecreated' => transform::datetime($imagegeneratedetail->timecreated),
'timecompleted' => transform::datetime($imagegeneratedetail->timecompleted),
];
$name = 'action_generate_image';
$context = \context::instance_by_id($imagegeneratedetail->contextid);
writer::with_context($context)->export_related_data($subcontexts, $name, $details);
}
$imagegeneratedetails->close();
// AI action summarise text.
$sql = "SELECT aar.actionname, aar.success, aar.provider, aar.timecreated, aar.timecompleted, aar.contextid,
aast.prompt, aast.responseid, aast.fingerprint, aast.generatedcontent,
aast.prompttokens, aast.completiontoken
FROM {ai_action_register} aar
JOIN {ai_action_summarise_text} aast
ON aar.actionid = aast.id
JOIN {context} ctx
ON aar.contextid = ctx.id
WHERE aar.actionname = 'summarise_text'
AND aar.userid = :userid
AND ctx.id " . $contextsql;
$params = [
'userid' => $userid,
];
$params += $contextparams;
$textsummarisedetails = $DB->get_recordset_sql($sql, $params);
foreach ($textsummarisedetails as $textsummarisedetail) {
$subcontexts = [
get_string('ai', 'core_ai'),
get_string('action_summarise_text', 'core_ai'),
date('c', $textsummarisedetail->timecreated),
];
$details = (object) [
'actionname' => $textsummarisedetail->actionname,
'contextid' => $textsummarisedetail->contextid,
'prompt' => $textsummarisedetail->prompt,
'responseid' => $textsummarisedetail->responseid,
'fingerprint' => $textsummarisedetail->fingerprint,
'generatedcontent' => $textsummarisedetail->generatedcontent,
'prompttokens' => $textsummarisedetail->prompttokens,
'completiontoken' => $textsummarisedetail->completiontoken,
'success' => transform::yesno($textsummarisedetail->success),
'provider' => $textsummarisedetail->provider,
'timecreated' => transform::datetime($textsummarisedetail->timecreated),
'timecompleted' => transform::datetime($textsummarisedetail->timecompleted),
];
$name = 'action_summarise_text';
$context = \context::instance_by_id($textsummarisedetail->contextid);
writer::with_context($context)->export_related_data($subcontexts, $name, $details);
}
$textsummarisedetails->close();
}
/**
* Delete all data for all users in the specified context.
*
* @param \context $context The specific context to delete data for.
*/
public static function delete_data_for_all_users_in_context(\context $context): void {
global $DB;
// Policy.
$sql = 'SELECT DISTINCT apr.id
FROM {ai_policy_register} apr
JOIN {context} ctx
ON apr.contextid = ctx.id
WHERE ctx.id = :contextid';
$params = [
'contextid' => $context->id,
];
$policydetails = $DB->get_records_sql($sql, $params);
if ($policydetails) {
$DB->delete_records_list('ai_policy_register', 'id', array_keys($policydetails));
}
// AI action generate text.
$sql = "SELECT DISTINCT aagt.id
FROM {ai_action_register} aar
JOIN {ai_action_generate_text} aagt
ON aar.actionid = aagt.id
JOIN {context} ctx
ON aar.contextid = ctx.id
WHERE aar.actionname = 'generate_text'
AND ctx.id = :contextid";
$params = [
'contextid' => $context->id,
];
$aagtids = $DB->get_records_sql_menu($sql, $params);
if ($aagtids) {
[$aagtidsql, $aagtidparams] = $DB->get_in_or_equal(array_keys($aagtids), SQL_PARAMS_NAMED);
$sql = "UPDATE {ai_action_generate_text}
SET prompt = '',
responseid = '',
fingerprint = '',
generatedcontent = ''
WHERE id " . $aagtidsql;
$DB->execute($sql, $aagtidparams);
}
// AI action generate image.
$sql = "SELECT DISTINCT aagi.id
FROM {ai_action_register} aar
JOIN {ai_action_generate_image} aagi
ON aar.actionid = aagi.id
JOIN {context} ctx
ON aar.contextid = ctx.id
WHERE aar.actionname = 'generate_image'
AND ctx.id = :contextid";
$params = [
'contextid' => $context->id,
];
$aagiids = $DB->get_records_sql_menu($sql, $params);
if ($aagiids) {
[$aagiidsql, $aagiidparams] = $DB->get_in_or_equal(array_keys($aagiids), SQL_PARAMS_NAMED);
$sql = "UPDATE {ai_action_generate_image}
SET prompt = '',
sourceurl = '',
revisedprompt = ''
WHERE id " . $aagiidsql;
$DB->execute($sql, $aagiidparams);
}
// AI action summarise text.
$sql = "SELECT DISTINCT aast.id
FROM {ai_action_register} aar
JOIN {ai_action_summarise_text} aast
ON aar.actionid = aast.id
JOIN {context} ctx
ON aar.contextid = ctx.id
WHERE aar.actionname = 'summarise_text'
AND ctx.id = :contextid";
$params = [
'contextid' => $context->id,
];
$aastids = $DB->get_records_sql_menu($sql, $params);
if ($aastids) {
[$aastidsql, $aastidparams] = $DB->get_in_or_equal(array_keys($aastids), SQL_PARAMS_NAMED);
$sql = "UPDATE {ai_action_summarise_text}
SET prompt = '',
responseid = '',
fingerprint = '',
generatedcontent = ''
WHERE id " . $aastidsql;
$DB->execute($sql, $aastidparams);
}
}
/**
* Delete all user data for the specified user, in the specified contexts.
*
* @param approved_contextlist $contextlist The approved contexts and user information to delete information for.
*/
public static function delete_data_for_user(approved_contextlist $contextlist): void {
global $DB;
// Policy.
$userid = $contextlist->get_user()->id;
[$contextsql, $contextparams] = $DB->get_in_or_equal($contextlist->get_contextids(), SQL_PARAMS_NAMED);
$sql = "SELECT DISTINCT apr.id AS policyid
FROM {context} ctx
JOIN {ai_policy_register} apr
ON apr.contextid = ctx.id
WHERE apr.userid = :userid
AND ctx.id " . $contextsql;
$params = [
'userid' => $userid,
];
$params += $contextparams;
$policydetails = $DB->get_recordset_sql($sql, $params);
$policyids = [];
foreach ($policydetails as $policydetail) {
$policyids[] = $policydetail->policyid;
}
$policydetails->close();
$DB->delete_records_list('ai_policy_register', 'id', $policyids);
// AI action generate text.
$sql = "SELECT DISTINCT aagt.id AS textgenerateid
FROM {ai_action_register} aar
JOIN {ai_action_generate_text} aagt
ON aar.actionid = aagt.id
JOIN {context} ctx
ON aar.contextid = ctx.id
WHERE aar.actionname = 'generate_text'
AND aar.userid = :userid
AND ctx.id " . $contextsql;
$textgeneratedetails = $DB->get_recordset_sql($sql, $params);
$aagtids = [];
foreach ($textgeneratedetails as $textgeneratedetail) {
$aagtids[] = $textgeneratedetail->textgenerateid;
}
$textgeneratedetails->close();
if ($aagtids) {
[$aagtidsql, $aagtidparams] = $DB->get_in_or_equal($aagtids, SQL_PARAMS_NAMED);
$sql = "UPDATE {ai_action_generate_text}
SET prompt = '',
responseid = '',
fingerprint = '',
generatedcontent = ''
WHERE id " . $aagtidsql;
$DB->execute($sql, $aagtidparams);
}
// AI action generate image.
$sql = "SELECT DISTINCT aagi.id AS imagegenerateid
FROM {ai_action_register} aar
JOIN {ai_action_generate_image} aagi
ON aar.actionid = aagi.id
JOIN {context} ctx
ON aar.contextid = ctx.id
WHERE aar.actionname = 'generate_image'
AND aar.userid = :userid
AND ctx.id " . $contextsql;
$imagegeneratedetails = $DB->get_recordset_sql($sql, $params);
$aagiids = [];
foreach ($imagegeneratedetails as $imagegeneratedetail) {
$aagiids[] = $imagegeneratedetail->imagegenerateid;
}
$imagegeneratedetails->close();
if ($aagiids) {
[$aagiidsql, $aagiidparams] = $DB->get_in_or_equal($aagiids, SQL_PARAMS_NAMED);
$sql = "UPDATE {ai_action_generate_image}
SET prompt = '',
sourceurl = '',
revisedprompt = ''
WHERE id " . $aagiidsql;
$DB->execute($sql, $aagiidparams);
}
// AI action summarise text.
$sql = "SELECT DISTINCT aast.id AS textsummariseid
FROM {ai_action_register} aar
JOIN {ai_action_summarise_text} aast
ON aar.actionid = aast.id
JOIN {context} ctx
ON aar.contextid = ctx.id
WHERE aar.actionname = 'summarise_text'
AND aar.userid = :userid
AND ctx.id " . $contextsql;
$textsummarisedetails = $DB->get_recordset_sql($sql, $params);
$aastids = [];
foreach ($textsummarisedetails as $textsummarisedetail) {
$aastids[] = $textsummarisedetail->textsummariseid;
}
$textsummarisedetails->close();
if ($aastids) {
[$aastidsql, $aastidparams] = $DB->get_in_or_equal($aastids, SQL_PARAMS_NAMED);
$sql = "UPDATE {ai_action_summarise_text}
SET prompt = '',
responseid = '',
fingerprint = '',
generatedcontent = ''
WHERE id " . $aastidsql;
$DB->execute($sql, $aastidparams);
}
}
/**
* Get the list of users who have data within a context.
*
* @param userlist $userlist The userlist containing the list of users who have data in this context/plugin combination.
*/
public static function get_users_in_context(userlist $userlist): void {
$context = $userlist->get_context();
// AI policy.
$sql = 'SELECT DISTINCT apr.userid
FROM {context} ctx
JOIN {ai_policy_register} apr
ON apr.contextid = ctx.id
WHERE apr.contextid = :contextid';
$userlist->add_from_sql('userid', $sql, ['contextid' => $context->id]);
// AI action generate text.
$sql = "SELECT DISTINCT aar.userid
FROM {context} ctx
JOIN {ai_action_register} aar
ON aar.contextid = ctx.id
JOIN {ai_action_generate_text} aagt
ON aagt.id = aar.actionid
WHERE aar.actionname = 'generate_text'
AND aar.contextid = :contextid";
$userlist->add_from_sql('userid', $sql, ['contextid' => $context->id]);
// AI action generate image.
$sql = "SELECT DISTINCT aar.userid
FROM {context} ctx
JOIN {ai_action_register} aar
ON aar.contextid = ctx.id
JOIN {ai_action_generate_image} aagi
ON aagi.id = aar.actionid
WHERE aar.actionname = 'generate_image'
AND aar.contextid = :contextid";
$userlist->add_from_sql('userid', $sql, ['contextid' => $context->id]);
// AI action summarise text.
$sql = "SELECT DISTINCT aar.userid
FROM {context} ctx
JOIN {ai_action_register} aar
ON aar.contextid = ctx.id
JOIN {ai_action_summarise_text} aast
ON aast.id = aar.actionid
WHERE aar.actionname = 'summarise_text'
AND aar.contextid = :contextid";
$userlist->add_from_sql('userid', $sql, ['contextid' => $context->id]);
}
/**
* Delete multiple users within a single context.
*
* @param approved_userlist $userlist The approved context and user information to delete information for.
*/
public static function delete_data_for_users(approved_userlist $userlist) {
global $DB;
$context = $userlist->get_context();
$userids = $userlist->get_userids();
[$useridssql, $useridsparams] = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
$params = [
'contextid' => $context->id,
];
$params += $useridsparams;
// Policy.
$sql = "SELECT DISTINCT apr.id
FROM {ai_policy_register} apr
JOIN {context} ctx
ON apr.contextid = ctx.id
WHERE ctx.id = :contextid
AND apr.userid " . $useridssql;
$policydetails = $DB->get_records_sql($sql, $params);
if ($policydetails) {
$DB->delete_records_list('ai_policy_register', 'id', array_keys($policydetails));
}
// AI action generate text.
$sql = "SELECT DISTINCT aagt.id
FROM {ai_action_register} aar
JOIN {ai_action_generate_text} aagt
ON aar.actionid = aagt.id
JOIN {context} ctx
ON aar.contextid = ctx.id
WHERE aar.actionname = 'generate_text'
AND ctx.id = :contextid
AND aar.userid " . $useridssql;
$aagtids = $DB->get_records_sql_menu($sql, $params);
if ($aagtids) {
[$aagtidsql, $aagtidparams] = $DB->get_in_or_equal(array_keys($aagtids), SQL_PARAMS_NAMED);
$sql = "UPDATE {ai_action_generate_text}
SET prompt = '',
responseid = '',
fingerprint = '',
generatedcontent = ''
WHERE id " . $aagtidsql;
$DB->execute($sql, $aagtidparams);
}
// AI action generate image.
$sql = "SELECT DISTINCT aagi.id
FROM {ai_action_register} aar
JOIN {ai_action_generate_image} aagi
ON aar.actionid = aagi.id
JOIN {context} ctx
ON aar.contextid = ctx.id
WHERE aar.actionname = 'generate_image'
AND ctx.id = :contextid
AND aar.userid " . $useridssql;
$aagiids = $DB->get_records_sql_menu($sql, $params);
if ($aagiids) {
[$aagiidsql, $aagiidparams] = $DB->get_in_or_equal(array_keys($aagiids), SQL_PARAMS_NAMED);
$sql = "UPDATE {ai_action_generate_image}
SET prompt = '',
sourceurl = '',
revisedprompt = ''
WHERE id " . $aagiidsql;
$DB->execute($sql, $aagiidparams);
}
// AI action summarise text.
$sql = "SELECT DISTINCT aast.id
FROM {ai_action_register} aar
JOIN {ai_action_summarise_text} aast
ON aar.actionid = aast.id
JOIN {context} ctx
ON aar.contextid = ctx.id
WHERE aar.actionname = 'summarise_text'
AND ctx.id = :contextid
AND aar.userid " . $useridssql;
$aastids = $DB->get_records_sql_menu($sql, $params);
if ($aastids) {
[$aastidsql, $aastidparams] = $DB->get_in_or_equal(array_keys($aastids), SQL_PARAMS_NAMED);
$sql = "UPDATE {ai_action_summarise_text}
SET prompt = '',
responseid = '',
fingerprint = '',
generatedcontent = ''
WHERE id " . $aastidsql;
$DB->execute($sql, $aastidparams);
}
}
}

View File

@ -73,8 +73,6 @@ final class manager_test extends \advanced_testcase {
*/
public function test_get_providers_for_actions(): void {
$this->resetAfterTest();
// Invoke the plugin manager and disable the AzureAI plugin.
set_config('disabled', 1, 'aiprovider_azureai');
set_config('enabled', 1, 'aiprovider_openai');
$manager = new manager();
@ -89,13 +87,6 @@ final class manager_test extends \advanced_testcase {
// Assert that the providers array is indexed by action name.
$this->assertEquals($actions, array_keys($providers));
// Assert that there are two providers for each action.
$this->assertCount(2, $providers['core_ai\\aiactions\\generate_text']);
$this->assertCount(2, $providers['core_ai\\aiactions\\summarise_text']);
// Assert that the AzureAI provider is not included in the list of providers for the actions when only selecting active.
$providers = $manager->get_providers_for_actions($actions, true);
// Assert that there is only one provider for each action.
$this->assertCount(1, $providers['core_ai\\aiactions\\generate_text']);
$this->assertCount(1, $providers['core_ai\\aiactions\\summarise_text']);

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,7 @@
/**
* Strings for component 'ai', language 'en'
*
* @package core_ai
* @package core
* @category string
* @copyright 2024 Matt Porritt <matt.porritt@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@ -61,7 +61,40 @@ Each action can be enabled or disabled for this placement.';
$string['placementsettings'] = 'Placement specific settings';
$string['placementsettings_desc'] = 'These settings control various aspects of this AI placement.<br/>
They control how the placement connects to the AI service, and related operations';
$string['privacy:metadata'] = 'The AI subsystem currently does not store any user data.';
$string['privacy:metadata:ai_action_generate_image'] = 'A table storing the image generation requests made by users.';
$string['privacy:metadata:ai_action_generate_image:aspectratio'] = 'The aspect ratio of the generated images.';
$string['privacy:metadata:ai_action_generate_image:numberimages'] = 'The number of images generated.';
$string['privacy:metadata:ai_action_generate_image:prompt'] = 'The prompt for the image generation request.';
$string['privacy:metadata:ai_action_generate_image:quality'] = 'The quality of the generated images.';
$string['privacy:metadata:ai_action_generate_image:revisedprompt'] = 'The revised prompt of the generated images.';
$string['privacy:metadata:ai_action_generate_image:sourceurl'] = 'The source URL of the generated images.';
$string['privacy:metadata:ai_action_generate_image:style'] = 'The style of the generated images.';
$string['privacy:metadata:ai_action_generate_text'] = 'A table storing the text generation requests made by users.';
$string['privacy:metadata:ai_action_generate_text:completiontoken'] = 'The completion tokens used to generate the text.';
$string['privacy:metadata:ai_action_generate_text:fingerprint'] = 'The unique hash representing the state/version of the model and content.';
$string['privacy:metadata:ai_action_generate_text:generatedcontent'] = 'The actual text generated by the AI model based on the input prompt.';
$string['privacy:metadata:ai_action_generate_text:prompt'] = 'The prompt for the text generation request.';
$string['privacy:metadata:ai_action_generate_text:prompttokens'] = 'The prompt tokens used to generate the text.';
$string['privacy:metadata:ai_action_generate_text:responseid'] = 'The ID of the response.';
$string['privacy:metadata:ai_action_register'] = 'A table storing the action requests made by users.';
$string['privacy:metadata:ai_action_register:actionid'] = 'The ID of the action request.';
$string['privacy:metadata:ai_action_register:actionname'] = 'The action name of the request.';
$string['privacy:metadata:ai_action_register:provider'] = 'The name of the provider that handled the request.';
$string['privacy:metadata:ai_action_register:success'] = 'The state of the action request.';
$string['privacy:metadata:ai_action_register:timecreated'] = 'The created time of the request.';
$string['privacy:metadata:ai_action_register:timecompleted'] = 'The completed time of the request.';
$string['privacy:metadata:ai_action_register:userid'] = 'The ID of the user who made the request.';
$string['privacy:metadata:ai_policy_register'] = 'A table storing the status of the AI policy acceptance for each user.';
$string['privacy:metadata:ai_policy_register:userid'] = 'The ID of the user whose data was saved.';
$string['privacy:metadata:ai_policy_register:contextid'] = 'The ID of the context whose data was saved.';
$string['privacy:metadata:ai_policy_register:timeaccepted'] = 'The time the user accepted the AI policy.';
$string['privacy:metadata:ai_action_summarise_text'] = 'A table storing the summarise text requests made by users.';
$string['privacy:metadata:ai_action_summarise_text:completiontoken'] = 'The completion tokens used to summarise the text.';
$string['privacy:metadata:ai_action_summarise_text:fingerprint'] = 'The unique hash representing the state/version of the model and content.';
$string['privacy:metadata:ai_action_summarise_text:generatedcontent'] = 'The actual text generated by the AI model based on the input prompt.';
$string['privacy:metadata:ai_action_summarise_text:prompt'] = 'The prompt for the summarise text request.';
$string['privacy:metadata:ai_action_summarise_text:prompttokens'] = 'The prompt tokens used to summarise the text.';
$string['privacy:metadata:ai_action_summarise_text:responseid'] = 'The ID of the response.';
$string['provideractionsettings'] = 'Provider actions';
$string['provideractionsettings_desc'] = 'These settings are for the actions that are supported by this AI provider.<br/>
Each action can be enabled or disabled for this provider.<br/>