MDL-82977 AI: Provider instances
Update the Azure AI provider plugin to support provider instances.
This commit is contained in:
@@ -53,14 +53,18 @@ abstract class abstract_processor extends process_base {
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function get_deployment_name(): string;
|
||||
protected function get_deployment_name(): string {
|
||||
return $this->provider->actionconfig[$this->action::class]['settings']['deployment'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the api version to use.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function get_api_version(): string;
|
||||
protected function get_api_version(): string {
|
||||
return $this->provider->actionconfig[$this->action::class]['settings']['apiversion'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the request object to send to the OpenAI API.
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace aiprovider_azureai\form;
|
||||
|
||||
use core_ai\form\action_settings_form;
|
||||
|
||||
/**
|
||||
* Generate image action provider settings form.
|
||||
*
|
||||
* @package aiprovider_azureai
|
||||
* @copyright 2024 Matt Porritt <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class action_generate_image_form extends action_settings_form {
|
||||
#[\Override]
|
||||
protected function definition() {
|
||||
$mform = $this->_form;
|
||||
$actionconfig = $this->_customdata['actionconfig']['settings'] ?? [];
|
||||
$returnurl = $this->_customdata['returnurl'] ?? null;
|
||||
$actionname = $this->_customdata['actionname'];
|
||||
$action = $this->_customdata['action'];
|
||||
$providerid = $this->_customdata['providerid'] ?? 0;
|
||||
|
||||
// Add API deployment name.
|
||||
$mform->addElement(
|
||||
'text',
|
||||
'deployment',
|
||||
get_string("action:{$actionname}:deployment", 'aiprovider_azureai'),
|
||||
'maxlength="255" size="20"',
|
||||
);
|
||||
$mform->setType('deployment', PARAM_ALPHANUMEXT);
|
||||
$mform->addRule('deployment', null, 'required', null, 'client');
|
||||
$mform->setDefault('deployment', $actionconfig['deployment'] ?? '');
|
||||
$mform->addHelpButton('deployment', "action:{$actionname}:deployment", 'aiprovider_azureai');
|
||||
|
||||
// Add API version.
|
||||
$mform->addElement(
|
||||
'text',
|
||||
'apiversion',
|
||||
get_string("action:{$actionname}:apiversion", 'aiprovider_azureai'),
|
||||
'maxlength="255" size="30"',
|
||||
);
|
||||
$mform->setType('apiversion', PARAM_ALPHANUMEXT);
|
||||
$mform->addRule('apiversion', null, 'required', null, 'client');
|
||||
$mform->setDefault('apiversion', $actionconfig['apiversion'] ?? '2024-06-01');
|
||||
|
||||
if ($returnurl) {
|
||||
$mform->addElement('hidden', 'returnurl', $returnurl);
|
||||
$mform->setType('returnurl', PARAM_LOCALURL);
|
||||
}
|
||||
|
||||
// Add the action class as a hidden field.
|
||||
$mform->addElement('hidden', 'action', $action);
|
||||
$mform->setType('action', PARAM_TEXT);
|
||||
|
||||
// Add the provider class as a hidden field.
|
||||
$mform->addElement('hidden', 'provider', 'aiprovider_azureai');
|
||||
$mform->setType('provider', PARAM_TEXT);
|
||||
|
||||
// Add the provider id as a hidden field.
|
||||
$mform->addElement('hidden', 'providerid', $providerid);
|
||||
$mform->setType('providerid', PARAM_INT);
|
||||
|
||||
$this->add_action_buttons();
|
||||
|
||||
$this->set_data($actionconfig);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace aiprovider_azureai\form;
|
||||
|
||||
use core_ai\form\action_settings_form;
|
||||
|
||||
/**
|
||||
* Generate text action provider settings form.
|
||||
*
|
||||
* @package aiprovider_azureai
|
||||
* @copyright 2024 Matt Porritt <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class action_generate_text_form extends action_settings_form {
|
||||
#[\Override]
|
||||
protected function definition() {
|
||||
$mform = $this->_form;
|
||||
$actionconfig = $this->_customdata['actionconfig']['settings'] ?? [];
|
||||
$returnurl = $this->_customdata['returnurl'] ?? null;
|
||||
$actionname = $this->_customdata['actionname'];
|
||||
$action = $this->_customdata['action'];
|
||||
$providerid = $this->_customdata['providerid'] ?? 0;
|
||||
|
||||
// Add API deployment name.
|
||||
$mform->addElement(
|
||||
'text',
|
||||
'deployment',
|
||||
get_string("action:{$actionname}:deployment", 'aiprovider_azureai'),
|
||||
'maxlength="255" size="20"',
|
||||
);
|
||||
$mform->setType('deployment', PARAM_ALPHANUMEXT);
|
||||
$mform->addRule('deployment', null, 'required', null, 'client');
|
||||
$mform->setDefault('deployment', $actionconfig['deployment'] ?? '');
|
||||
$mform->addHelpButton('deployment', "action:{$actionname}:deployment", 'aiprovider_azureai');
|
||||
|
||||
// Add API version.
|
||||
$mform->addElement(
|
||||
'text',
|
||||
'apiversion',
|
||||
get_string("action:{$actionname}:apiversion", 'aiprovider_azureai'),
|
||||
'maxlength="255" size="30"',
|
||||
);
|
||||
$mform->setType('apiversion', PARAM_ALPHANUMEXT);
|
||||
$mform->addRule('apiversion', null, 'required', null, 'client');
|
||||
$mform->setDefault('apiversion', $actionconfig['apiversion'] ?? '2024-06-01');
|
||||
|
||||
// System Instructions.
|
||||
$mform->addElement(
|
||||
'textarea',
|
||||
'systeminstruction',
|
||||
get_string("action:{$actionname}:systeminstruction", 'aiprovider_azureai'),
|
||||
'wrap="virtual" rows="5" cols="20"',
|
||||
);
|
||||
$mform->setType('systeminstruction', PARAM_TEXT);
|
||||
$mform->setDefault('systeminstruction', $actionconfig['systeminstruction'] ?? $action::get_system_instruction());
|
||||
$mform->addHelpButton('systeminstruction', "action:{$actionname}:systeminstruction", 'aiprovider_azureai');
|
||||
|
||||
if ($returnurl) {
|
||||
$mform->addElement('hidden', 'returnurl', $returnurl);
|
||||
$mform->setType('returnurl', PARAM_LOCALURL);
|
||||
}
|
||||
|
||||
// Add the action class as a hidden field.
|
||||
$mform->addElement('hidden', 'action', $action);
|
||||
$mform->setType('action', PARAM_TEXT);
|
||||
|
||||
// Add the provider class as a hidden field.
|
||||
$mform->addElement('hidden', 'provider', 'aiprovider_azureai');
|
||||
$mform->setType('provider', PARAM_TEXT);
|
||||
|
||||
// Add the provider id as a hidden field.
|
||||
$mform->addElement('hidden', 'providerid', $providerid);
|
||||
$mform->setType('providerid', PARAM_INT);
|
||||
|
||||
$this->add_action_buttons();
|
||||
|
||||
$this->set_data($actionconfig);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace aiprovider_azureai;
|
||||
|
||||
use core_ai\hook\after_ai_provider_form_hook;
|
||||
|
||||
/**
|
||||
* Hook listener for Azure AI Provider.
|
||||
*
|
||||
* @package aiprovider_azureai
|
||||
* @copyright 2024 Matt Porritt <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class hook_listener {
|
||||
|
||||
/**
|
||||
* Hook listener for the Azure AI instance setup form.
|
||||
*
|
||||
* @param after_ai_provider_form_hook $hook The hook to add to the AI instance setup.
|
||||
*/
|
||||
public static function set_form_definition_for_aiprovider_azureai(after_ai_provider_form_hook $hook): void {
|
||||
if ($hook->plugin !== 'aiprovider_azureai') {
|
||||
return;
|
||||
}
|
||||
|
||||
$mform = $hook->mform;
|
||||
|
||||
// Required setting to store azureai API key.
|
||||
$mform->addElement(
|
||||
'passwordunmask',
|
||||
'apikey',
|
||||
get_string('apikey', 'aiprovider_azureai'),
|
||||
['size' => 75],
|
||||
);
|
||||
$mform->addHelpButton('apikey', 'apikey', 'aiprovider_azureai');
|
||||
$mform->addRule('apikey', get_string('required'), 'required', null, 'client');
|
||||
|
||||
// Setting to store AzureAI endpoint URL.
|
||||
$mform->addElement(
|
||||
'text',
|
||||
'endpoint',
|
||||
get_string('endpoint', 'aiprovider_azureai'),
|
||||
['size' => 25],
|
||||
);
|
||||
$mform->setType('endpoint', PARAM_URL);
|
||||
$mform->addHelpButton('endpoint', 'endpoint', 'aiprovider_azureai');
|
||||
$mform->addRule('endpoint', get_string('required'), 'required', null, 'client');
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ class process_generate_image extends abstract_processor {
|
||||
|
||||
#[\Override]
|
||||
protected function get_endpoint(): UriInterface {
|
||||
$url = rtrim(get_config('aiprovider_azureai', 'endpoint'), '/')
|
||||
$url = rtrim($this->provider->config['endpoint'], '/')
|
||||
. '/openai/deployments/'
|
||||
. $this->get_deployment_name()
|
||||
. '/images/generations?api-version='
|
||||
@@ -46,16 +46,6 @@ class process_generate_image extends abstract_processor {
|
||||
return new Uri($url);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function get_deployment_name(): string {
|
||||
return get_config('aiprovider_azureai', 'action_generate_image_deployment');
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function get_api_version(): string {
|
||||
return get_config('aiprovider_azureai', 'action_generate_image_apiversion');
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function query_ai_api(): array {
|
||||
$response = parent::query_ai_api();
|
||||
@@ -99,6 +89,9 @@ class process_generate_image extends abstract_processor {
|
||||
return new Request(
|
||||
method: 'POST',
|
||||
uri: '',
|
||||
headers: [
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
body: json_encode((object) [
|
||||
'prompt' => $this->action->get_configuration('prompttext'),
|
||||
'n' => $this->numberimages,
|
||||
@@ -107,9 +100,6 @@ class process_generate_image extends abstract_processor {
|
||||
'style' => $this->action->get_configuration('style'),
|
||||
'user' => $userid,
|
||||
]),
|
||||
headers: [
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ use Psr\Http\Message\UriInterface;
|
||||
class process_generate_text extends abstract_processor {
|
||||
#[\Override]
|
||||
protected function get_endpoint(): UriInterface {
|
||||
$url = rtrim(get_config('aiprovider_azureai', 'endpoint'), '/')
|
||||
$url = rtrim($this->provider->config['endpoint'], '/')
|
||||
. '/openai/deployments/'
|
||||
. $this->get_deployment_name()
|
||||
. '/chat/completions?api-version='
|
||||
@@ -41,19 +41,9 @@ class process_generate_text extends abstract_processor {
|
||||
return new Uri($url);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function get_deployment_name(): string {
|
||||
return get_config('aiprovider_azureai', 'action_generate_text_deployment');
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function get_api_version(): string {
|
||||
return get_config('aiprovider_azureai', 'action_generate_text_apiversion');
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function get_system_instruction(): string {
|
||||
return get_config('aiprovider_azureai', 'action_generate_text_systeminstruction');
|
||||
return $this->provider->actionconfig[$this->action::class]['settings']['systeminstruction'];
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
@@ -81,10 +71,10 @@ class process_generate_text extends abstract_processor {
|
||||
return new Request(
|
||||
method: 'POST',
|
||||
uri: '',
|
||||
body: json_encode($requestobj),
|
||||
headers: [
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
body: json_encode($requestobj),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,18 +24,5 @@ namespace aiprovider_azureai;
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class process_summarise_text extends process_generate_text {
|
||||
#[\Override]
|
||||
protected function get_deployment_name(): string {
|
||||
return get_config('aiprovider_azureai', 'action_summarise_text_deployment');
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function get_api_version(): string {
|
||||
return get_config('aiprovider_azureai', 'action_summarise_text_apiversion');
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function get_system_instruction(): string {
|
||||
return get_config('aiprovider_azureai', 'action_summarise_text_systeminstruction');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
|
||||
namespace aiprovider_azureai;
|
||||
|
||||
use core_ai\aiactions;
|
||||
use core_ai\rate_limiter;
|
||||
use core_ai\form\action_settings_form;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
|
||||
/**
|
||||
@@ -28,46 +27,12 @@ use Psr\Http\Message\RequestInterface;
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class provider extends \core_ai\provider {
|
||||
/** @var string The Azure AI API key. */
|
||||
private string $apikey;
|
||||
|
||||
/** @var string The Azure AI API endpoint, is different for each organisation. */
|
||||
public string $apiendpoint;
|
||||
|
||||
/** @var bool Is global rate limiting for the API enabled. */
|
||||
private bool $enableglobalratelimit;
|
||||
|
||||
/** @var int The global rate limit. */
|
||||
private int $globalratelimit;
|
||||
|
||||
/** @var bool Is user rate limiting for the API enabled */
|
||||
private bool $enableuserratelimit;
|
||||
|
||||
/** @var int The user rate limit. */
|
||||
private int $userratelimit;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
// Get api key from config.
|
||||
$this->apikey = get_config('aiprovider_azureai', 'apikey');
|
||||
// Get api endpoint url id from config.
|
||||
$this->apiendpoint = get_config('aiprovider_azureai', 'endpoint');
|
||||
// Get global rate limit from config.
|
||||
$this->enableglobalratelimit = get_config('aiprovider_azureai', 'enableglobalratelimit');
|
||||
$this->globalratelimit = get_config('aiprovider_azureai', 'globalratelimit');
|
||||
// Get user rate limit from config.
|
||||
$this->enableuserratelimit = get_config('aiprovider_azureai', 'enableuserratelimit');
|
||||
$this->userratelimit = get_config('aiprovider_azureai', 'userratelimit');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of actions that this provider supports.
|
||||
*
|
||||
* @return array An array of action class names.
|
||||
*/
|
||||
public function get_action_list(): array {
|
||||
public static function get_action_list(): array {
|
||||
return [
|
||||
\core_ai\aiactions\generate_text::class,
|
||||
\core_ai\aiactions\generate_image::class,
|
||||
@@ -77,6 +42,7 @@ class provider extends \core_ai\provider {
|
||||
|
||||
/**
|
||||
* Generate a user id.
|
||||
*
|
||||
* This is a hash of the site id and user id,
|
||||
* this means we can determine who made the request
|
||||
* but don't pass any personal data to AzureAI.
|
||||
@@ -92,97 +58,47 @@ class provider extends \core_ai\provider {
|
||||
/**
|
||||
* Update a request to add any headers required by the provider.
|
||||
*
|
||||
* @param \Psr\Http\Message\RequestInterface $request
|
||||
* @return \Psr\Http\Message\RequestInterface
|
||||
* @param RequestInterface $request
|
||||
* @return RequestInterface
|
||||
*/
|
||||
public function add_authentication_headers(RequestInterface $request): RequestInterface {
|
||||
return $request
|
||||
->withAddedHeader('api-key', $this->apikey);
|
||||
->withAddedHeader('api-key', $this->config['apikey']);
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
public function is_request_allowed(aiactions\base $action): array|bool {
|
||||
$ratelimiter = \core\di::get(rate_limiter::class);
|
||||
$component = \core\component::get_component_from_classname(get_class($this));
|
||||
|
||||
// Check the user rate limit.
|
||||
if ($this->enableuserratelimit) {
|
||||
if (!$ratelimiter->check_user_rate_limit(
|
||||
component: $component,
|
||||
ratelimit: $this->userratelimit,
|
||||
userid: $action->get_configuration('userid')
|
||||
)) {
|
||||
return [
|
||||
'success' => false,
|
||||
'errorcode' => 429,
|
||||
'errormessage' => 'User rate limit exceeded',
|
||||
];
|
||||
}
|
||||
public static function get_action_settings(
|
||||
string $action,
|
||||
array $customdata = [],
|
||||
): action_settings_form|bool {
|
||||
$actionname = substr($action, (strrpos($action, '\\') + 1));
|
||||
$customdata['actionname'] = $actionname;
|
||||
$customdata['action'] = $action;
|
||||
if ($actionname === 'generate_text' || $actionname === 'summarise_text') {
|
||||
return new form\action_generate_text_form(customdata: $customdata);
|
||||
} else if ($actionname === 'generate_image') {
|
||||
return new form\action_generate_image_form(customdata: $customdata);
|
||||
}
|
||||
|
||||
// Check the global rate limit.
|
||||
if ($this->enableglobalratelimit) {
|
||||
if (!$ratelimiter->check_global_rate_limit(
|
||||
component: $component,
|
||||
ratelimit: $this->globalratelimit)) {
|
||||
return [
|
||||
'success' => false,
|
||||
'errorcode' => 429,
|
||||
'errormessage' => 'Global rate limit exceeded',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any action settings for this provider.
|
||||
*
|
||||
* @param string $action The action class name.
|
||||
* @param \admin_root $ADMIN The admin root object.
|
||||
* @param string $section The section name.
|
||||
* @param bool $hassiteconfig Whether the current user has moodle/site:config capability.
|
||||
* @return array An array of settings.
|
||||
*/
|
||||
public function get_action_settings(
|
||||
string $action,
|
||||
\admin_root $ADMIN,
|
||||
string $section,
|
||||
bool $hassiteconfig
|
||||
): array {
|
||||
#[\Override]
|
||||
public static function get_action_setting_defaults(string $action): array {
|
||||
$actionname = substr($action, (strrpos($action, '\\') + 1));
|
||||
$settings = [];
|
||||
|
||||
// Add API deployment name.
|
||||
$settings[] = new \admin_setting_configtext(
|
||||
"aiprovider_azureai/action_{$actionname}_deployment",
|
||||
new \lang_string("action_deployment", 'aiprovider_azureai'),
|
||||
new \lang_string("action_deployment_desc", 'aiprovider_azureai'),
|
||||
'',
|
||||
PARAM_ALPHANUMEXT,
|
||||
);
|
||||
// Add API version.
|
||||
$settings[] = new \admin_setting_configtext(
|
||||
"aiprovider_azureai/action_{$actionname}_apiversion",
|
||||
new \lang_string("action_apiversion", 'aiprovider_azureai'),
|
||||
'',
|
||||
'2024-06-01',
|
||||
PARAM_ALPHANUMEXT,
|
||||
);
|
||||
|
||||
$customdata = [
|
||||
'actionname' => $actionname,
|
||||
'action' => $action,
|
||||
];
|
||||
if ($actionname === 'generate_text' || $actionname === 'summarise_text') {
|
||||
// Add system instruction settings.
|
||||
$settings[] = new \admin_setting_configtextarea(
|
||||
"aiprovider_azureai/action_{$actionname}_systeminstruction",
|
||||
new \lang_string("action_systeminstruction", 'aiprovider_azureai'),
|
||||
new \lang_string("action_systeminstruction_desc", 'aiprovider_azureai'),
|
||||
$action::get_system_instruction(),
|
||||
PARAM_TEXT
|
||||
);
|
||||
$mform = new form\action_generate_text_form(customdata: $customdata);
|
||||
return $mform->get_defaults();
|
||||
} else if ($actionname === 'generate_image') {
|
||||
$mform = new form\action_generate_image_form(customdata: $customdata);
|
||||
return $mform->get_defaults();
|
||||
}
|
||||
|
||||
return $settings;
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,6 +107,6 @@ class provider extends \core_ai\provider {
|
||||
* @return bool Return true if configured.
|
||||
*/
|
||||
public function is_provider_configured(): bool {
|
||||
return !empty($this->apikey) && !empty($this->apiendpoint);
|
||||
return !empty($this->config['apikey']) && !empty($this->config['endpoint']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Hook listener callbacks for the Azure AI Provider.
|
||||
*
|
||||
* @package aiprovider_azureai
|
||||
* @copyright 2024 Matt Porritt <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$callbacks = [
|
||||
[
|
||||
'hook' => \core_ai\hook\after_ai_provider_form_hook::class,
|
||||
'callback' => \aiprovider_azureai\hook_listener::class . '::set_form_definition_for_aiprovider_azureai',
|
||||
],
|
||||
];
|
||||
@@ -22,12 +22,37 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['action:generate_image:apiversion'] = 'API version';
|
||||
$string['action:generate_image:deployment'] = 'Deployment ID';
|
||||
$string['action:generate_image:deployment_help'] = 'The deployment ID that relates to the API endpoint the provider uses for this action.';
|
||||
$string['action:generate_text:apiversion'] = 'API version';
|
||||
$string['action:generate_text:deployment'] = 'Deployment ID';
|
||||
$string['action:generate_text:deployment_help'] = 'The deployment ID that relates to the API endpoint the provider uses for this action.';
|
||||
$string['action:generate_text:systeminstruction'] = 'System Instruction';
|
||||
$string['action:generate_text:systeminstruction_help'] = 'This instruction is sent to the AI model along with the user\'s prompt. Editing this instruction is not recommended unless absolutely required.';
|
||||
$string['action:summarise_text:apiversion'] = 'API version';
|
||||
$string['action:summarise_text:deployment'] = 'Deployment ID';
|
||||
$string['action:summarise_text:deployment_help'] = 'The deployment ID that relates to the API endpoint the provider uses for this action.';
|
||||
$string['action:summarise_text:systeminstruction'] = 'System Instruction';
|
||||
$string['action:summarise_text:systeminstruction_help'] = 'This instruction is sent to the AI model along with the user\'s prompt. Editing this instruction is not recommended unless absolutely required.';
|
||||
$string['apikey'] = 'Azure AI API key';
|
||||
$string['apikey_help'] = 'Enter your Azure AI API key.';
|
||||
$string['endpoint'] = 'Azure AI API endpoint';
|
||||
$string['endpoint_help'] = 'Enter the endpoint URL for your Azure AI API in the following format: https://YOUR_RESOURCE_NAME.openai.azure.com';
|
||||
$string['pluginname'] = 'Azure AI API Provider';
|
||||
$string['privacy:metadata'] = 'The Azure Ai API provider plugin does not store any personal data.';
|
||||
$string['privacy:metadata:aiprovider_azureai:externalpurpose'] = 'This information is sent to the Azure API in order for a response to be generated. Your Azure AI account settings may change how Microsoft stores and retains this data. No user data is explicitly sent to Microsoft or stored in Moodle LMS by this plugin.';
|
||||
$string['privacy:metadata:aiprovider_azureai:model'] = 'The model used to generate the response.';
|
||||
$string['privacy:metadata:aiprovider_azureai:numberimages'] = 'When generating images the number of images used in the response.';
|
||||
$string['privacy:metadata:aiprovider_azureai:prompttext'] = 'The user entered text prompt used to generate the response.';
|
||||
$string['privacy:metadata:aiprovider_azureai:responseformat'] = 'The format of the response. When generating images.';
|
||||
|
||||
// Deprecated since Moodle 5.0.
|
||||
$string['action_apiversion'] = 'API version';
|
||||
$string['action_deployment'] = 'Deployment ID';
|
||||
$string['action_deployment_desc'] = 'The deployment ID that relates to the API endpoint the provider uses for this action.';
|
||||
$string['action_systeminstruction'] = 'System instruction';
|
||||
$string['action_systeminstruction_desc'] = 'This instruction is sent to the AI model along with the user\'s prompt. Editing this instruction is not recommended unless absolutely required.';
|
||||
$string['apikey'] = 'Azure AI API key';
|
||||
$string['apikey_desc'] = 'Enter your Azure AI API key.';
|
||||
$string['deployment'] = 'Azure AI API deployment name';
|
||||
$string['deployment_desc'] = 'Enter the deployment name for your Azure AI API.';
|
||||
@@ -35,16 +60,8 @@ $string['enableglobalratelimit'] = 'Set site-wide rate limit';
|
||||
$string['enableglobalratelimit_desc'] = 'Limit the number of requests that the Azure AI API provider can receive across the entire site every hour.';
|
||||
$string['enableuserratelimit'] = 'Set user rate limit';
|
||||
$string['enableuserratelimit_desc'] = 'Limit the number of requests each user can make to the Azure AI API provider every hour.';
|
||||
$string['endpoint'] = 'Azure AI API endpoint';
|
||||
$string['endpoint_desc'] = 'Enter the endpoint URL for your Azure AI API in the following format: https://YOUR_RESOURCE_NAME.openai.azure.com';
|
||||
$string['globalratelimit'] = 'Maximum number of site-wide requests';
|
||||
$string['globalratelimit_desc'] = 'The number of site-wide requests allowed per hour.';
|
||||
$string['pluginname'] = 'Azure AI API provider';
|
||||
$string['privacy:metadata'] = 'The Azure AI API provider plugin does not store any personal data.';
|
||||
$string['privacy:metadata:aiprovider_azureai:externalpurpose'] = 'This information is sent to the Azure API in order for a response to be generated. Your Azure AI account settings may change how Microsoft stores and retains this data. No user data is explicitly sent to Microsoft or stored in Moodle LMS by this plugin.';
|
||||
$string['privacy:metadata:aiprovider_azureai:model'] = 'The model used to generate the response.';
|
||||
$string['privacy:metadata:aiprovider_azureai:numberimages'] = 'When generating images the number of images used in the response.';
|
||||
$string['privacy:metadata:aiprovider_azureai:prompttext'] = 'The user entered text prompt used to generate the response.';
|
||||
$string['privacy:metadata:aiprovider_azureai:responseformat'] = 'When generating images the format of the response.';
|
||||
$string['userratelimit'] = 'Maximum number of requests per user';
|
||||
$string['userratelimit_desc'] = 'The number of requests allowed per hour, per user.';
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - https://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
/**
|
||||
* Plugin administration pages are defined here.
|
||||
*
|
||||
* @package aiprovider_azureai
|
||||
* @copyright 2024 Matt Porritt <[email protected]>
|
||||
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
use core_ai\admin\admin_settingspage_provider;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
if ($hassiteconfig) {
|
||||
// Provider specific settings.
|
||||
$settings = new admin_settingspage_provider(
|
||||
'aiprovider_azureai',
|
||||
new lang_string('pluginname', 'aiprovider_azureai'),
|
||||
'moodle/site:config',
|
||||
true
|
||||
);
|
||||
|
||||
$settings->add(new admin_setting_heading(
|
||||
'aiprovider_azureai/general',
|
||||
new lang_string('settings', 'core'),
|
||||
'',
|
||||
));
|
||||
|
||||
// Setting to store AzureAI API key.
|
||||
$settings->add(new admin_setting_configpasswordunmask(
|
||||
'aiprovider_azureai/apikey',
|
||||
new lang_string('apikey', 'aiprovider_azureai'),
|
||||
new lang_string('apikey_desc', 'aiprovider_azureai'),
|
||||
'',
|
||||
));
|
||||
|
||||
// Setting to store AzureAI endpoint URL.
|
||||
$settings->add(new admin_setting_configtext(
|
||||
'aiprovider_azureai/endpoint',
|
||||
new lang_string('endpoint', 'aiprovider_azureai'),
|
||||
new lang_string('endpoint_desc', 'aiprovider_azureai'),
|
||||
'',
|
||||
PARAM_URL
|
||||
));
|
||||
|
||||
// Setting to enable/disable global rate limiting.
|
||||
$settings->add(new admin_setting_configcheckbox('aiprovider_azureai/enableglobalratelimit',
|
||||
new lang_string('enableglobalratelimit', 'aiprovider_azureai'),
|
||||
new lang_string('enableglobalratelimit_desc', 'aiprovider_azureai'),
|
||||
0
|
||||
));
|
||||
|
||||
// Setting to set how many requests per hour are allowed for the global rate limit.
|
||||
// Should only be enabled when global rate limiting is enabled.
|
||||
$settings->add(new admin_setting_configtext(
|
||||
'aiprovider_azureai/globalratelimit',
|
||||
new lang_string('globalratelimit', 'aiprovider_azureai'),
|
||||
new lang_string('globalratelimit_desc', 'aiprovider_azureai'),
|
||||
100,
|
||||
PARAM_INT
|
||||
));
|
||||
$settings->hide_if('aiprovider_azureai/globalratelimit', 'aiprovider_azureai/enableglobalratelimit', 'eq', 0);
|
||||
|
||||
// Setting to enable/disable user rate limiting.
|
||||
$settings->add(new admin_setting_configcheckbox(
|
||||
'aiprovider_azureai/enableuserratelimit',
|
||||
new lang_string('enableuserratelimit', 'aiprovider_azureai'),
|
||||
new lang_string('enableuserratelimit_desc', 'aiprovider_azureai'),
|
||||
0
|
||||
));
|
||||
|
||||
// Setting to set how many requests per hour are allowed for the user rate limit.
|
||||
// Should only be enabled when user rate limiting is enabled.
|
||||
$settings->add(new admin_setting_configtext(
|
||||
'aiprovider_azureai/userratelimit',
|
||||
new lang_string('userratelimit', 'aiprovider_azureai'),
|
||||
new lang_string('userratelimit_desc', 'aiprovider_azureai'),
|
||||
10,
|
||||
PARAM_INT));
|
||||
$settings->hide_if('aiprovider_azureai/userratelimit', 'aiprovider_azureai/enableuserratelimit', 'eq', 0);
|
||||
}
|
||||
@@ -32,6 +32,9 @@ final class process_generate_image_test extends \advanced_testcase {
|
||||
/** @var string A successful response in JSON format. */
|
||||
protected string $responsebodyjson;
|
||||
|
||||
/** @var \core_ai\manager */
|
||||
private $manager;
|
||||
|
||||
/** @var provider The provider that will process the action. */
|
||||
protected provider $provider;
|
||||
|
||||
@@ -43,6 +46,7 @@ final class process_generate_image_test extends \advanced_testcase {
|
||||
*/
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
$this->resetAfterTest();
|
||||
// Load a response body from a file.
|
||||
$this->responsebodyjson = file_get_contents(self::get_fixture_path('aiprovider_azureai', 'image_request_success.json'));
|
||||
$this->create_provider();
|
||||
@@ -53,7 +57,20 @@ final class process_generate_image_test extends \advanced_testcase {
|
||||
* Create the provider object.
|
||||
*/
|
||||
private function create_provider(): void {
|
||||
$this->provider = new \aiprovider_azureai\provider();
|
||||
$this->manager = \core\di::get(\core_ai\manager::class);
|
||||
$config = [
|
||||
'apikey' => '123',
|
||||
'endpoint' => 'https://api.example.com',
|
||||
'enableuserratelimit' => true,
|
||||
'userratelimit' => 1,
|
||||
'enableglobalratelimit' => true,
|
||||
'globalratelimit' => 1,
|
||||
];
|
||||
$this->provider = $this->manager->create_provider_instance(
|
||||
classname: '\aiprovider_azureai\provider',
|
||||
name: 'dummy',
|
||||
config: $config,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -168,7 +185,6 @@ final class process_generate_image_test extends \advanced_testcase {
|
||||
* Test query_ai_api for a successful call.
|
||||
*/
|
||||
public function test_query_ai_api_success(): void {
|
||||
$this->resetAfterTest();
|
||||
// Mock the http client to return a successful response.
|
||||
['mock' => $mock] = $this->get_mocked_http_client();
|
||||
|
||||
@@ -190,17 +206,6 @@ final class process_generate_image_test extends \advanced_testcase {
|
||||
|
||||
$this->setAdminUser();
|
||||
|
||||
// Create a request object.
|
||||
$requestobj = new \stdClass();
|
||||
$requestobj->prompt = 'generate a test image';
|
||||
$requestobj->model = 'awesome-ai-3';
|
||||
$requestobj->n = '3';
|
||||
$requestobj->quality = 'hd';
|
||||
$requestobj->response_format = 'url;';
|
||||
$requestobj->size = '1024x1024';
|
||||
$requestobj->style = 'vivid';
|
||||
$requestobj->user = 't3464h89dftjltestudfaser';
|
||||
|
||||
$processor = new process_generate_image($this->provider, $this->action);
|
||||
$method = new \ReflectionMethod($processor, 'query_ai_api');
|
||||
$result = $method->invoke($processor);
|
||||
@@ -261,7 +266,6 @@ final class process_generate_image_test extends \advanced_testcase {
|
||||
* Test url_to_file.
|
||||
*/
|
||||
public function test_url_to_file(): void {
|
||||
$this->resetAfterTest();
|
||||
// Log in user.
|
||||
$this->setUser($this->getDataGenerator()->create_user());
|
||||
|
||||
@@ -281,7 +285,6 @@ final class process_generate_image_test extends \advanced_testcase {
|
||||
* Test process.
|
||||
*/
|
||||
public function test_process(): void {
|
||||
$this->resetAfterTest();
|
||||
// Log in user.
|
||||
$this->setUser($this->getDataGenerator()->create_user());
|
||||
|
||||
@@ -344,7 +347,6 @@ final class process_generate_image_test extends \advanced_testcase {
|
||||
* Test process method with error.
|
||||
*/
|
||||
public function test_process_error(): void {
|
||||
$this->resetAfterTest();
|
||||
// Log in user.
|
||||
$this->setUser($this->getDataGenerator()->create_user());
|
||||
|
||||
@@ -372,7 +374,6 @@ final class process_generate_image_test extends \advanced_testcase {
|
||||
* Test process method with user rate limiter.
|
||||
*/
|
||||
public function test_process_with_user_rate_limiter(): void {
|
||||
$this->resetAfterTest();
|
||||
// Create users.
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$user2 = $this->getDataGenerator()->create_user();
|
||||
@@ -382,15 +383,36 @@ final class process_generate_image_test extends \advanced_testcase {
|
||||
$clock = $this->mock_clock_with_frozen();
|
||||
|
||||
// Set the user rate limiter.
|
||||
set_config('enableuserratelimit', 1, 'aiprovider_azureai');
|
||||
set_config('userratelimit', 1, 'aiprovider_azureai');
|
||||
$config = [
|
||||
'apikey' => '123',
|
||||
'endpoint' => 'https://api.example.com',
|
||||
'enableuserratelimit' => true,
|
||||
'userratelimit' => 1,
|
||||
];
|
||||
$actionconfig = [
|
||||
'core_ai\\aiactions\\generate_image' => [
|
||||
'enabled' => true,
|
||||
'settings' => [
|
||||
'deployment' => 'test',
|
||||
'apiversion' => '2024-06-01',
|
||||
],
|
||||
],
|
||||
];
|
||||
$provider = $this->manager->create_provider_instance(
|
||||
classname: '\aiprovider_openai\provider',
|
||||
name: 'dummy',
|
||||
config: $config,
|
||||
);
|
||||
$provider = $this->manager->update_provider_instance(
|
||||
provider: $provider,
|
||||
actionconfig: $actionconfig,
|
||||
);
|
||||
|
||||
// Mock the http client to return a successful response.
|
||||
['mock' => $mock] = $this->get_mocked_http_client();
|
||||
$url = 'https://example.com/test.jpg';
|
||||
|
||||
// Case 1: User rate limit has not been reached.
|
||||
$this->create_provider();
|
||||
$this->create_action($user1->id);
|
||||
// The response from Azure AI.
|
||||
$mock->append(new Response(
|
||||
@@ -412,7 +434,7 @@ final class process_generate_image_test extends \advanced_testcase {
|
||||
['Content-Type' => 'image/jpeg'],
|
||||
\GuzzleHttp\Psr7\Utils::streamFor(fopen(self::get_fixture_path('aiprovider_azureai', 'test.jpg'), 'r')),
|
||||
));
|
||||
$processor = new process_generate_image($this->provider, $this->action);
|
||||
$processor = new process_generate_image($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertTrue($result->get_success());
|
||||
|
||||
@@ -438,9 +460,8 @@ final class process_generate_image_test extends \advanced_testcase {
|
||||
['Content-Type' => 'image/jpeg'],
|
||||
\GuzzleHttp\Psr7\Utils::streamFor(fopen(self::get_fixture_path('aiprovider_azureai', 'test.jpg'), 'r')),
|
||||
));
|
||||
$this->create_provider();
|
||||
$this->create_action($user1->id);
|
||||
$processor = new process_generate_image($this->provider, $this->action);
|
||||
$processor = new process_generate_image($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertEquals(429, $result->get_errorcode());
|
||||
$this->assertEquals('User rate limit exceeded', $result->get_errormessage());
|
||||
@@ -449,7 +470,6 @@ final class process_generate_image_test extends \advanced_testcase {
|
||||
// Case 3: User rate limit has not been reached for a different user.
|
||||
// Log in user2.
|
||||
$this->setUser($user2);
|
||||
$this->create_provider();
|
||||
$this->create_action($user2->id);
|
||||
// The response from Azure AI.
|
||||
$mock->append(new Response(
|
||||
@@ -471,7 +491,7 @@ final class process_generate_image_test extends \advanced_testcase {
|
||||
['Content-Type' => 'image/jpeg'],
|
||||
\GuzzleHttp\Psr7\Utils::streamFor(fopen(self::get_fixture_path('aiprovider_azureai', 'test.jpg'), 'r')),
|
||||
));
|
||||
$processor = new process_generate_image($this->provider, $this->action);
|
||||
$processor = new process_generate_image($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertTrue($result->get_success());
|
||||
|
||||
@@ -499,9 +519,8 @@ final class process_generate_image_test extends \advanced_testcase {
|
||||
['Content-Type' => 'image/jpeg'],
|
||||
\GuzzleHttp\Psr7\Utils::streamFor(fopen(self::get_fixture_path('aiprovider_azureai', 'test.jpg'), 'r')),
|
||||
));
|
||||
$this->create_provider();
|
||||
$this->create_action($user1->id);
|
||||
$processor = new process_generate_image($this->provider, $this->action);
|
||||
$processor = new process_generate_image($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertTrue($result->get_success());
|
||||
}
|
||||
@@ -510,7 +529,6 @@ final class process_generate_image_test extends \advanced_testcase {
|
||||
* Test process method with global rate limiter.
|
||||
*/
|
||||
public function test_process_with_global_rate_limiter(): void {
|
||||
$this->resetAfterTest();
|
||||
// Create users.
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$user2 = $this->getDataGenerator()->create_user();
|
||||
@@ -520,15 +538,36 @@ final class process_generate_image_test extends \advanced_testcase {
|
||||
$clock = $this->mock_clock_with_frozen();
|
||||
|
||||
// Set the global rate limiter.
|
||||
set_config('enableglobalratelimit', 1, 'aiprovider_azureai');
|
||||
set_config('globalratelimit', 1, 'aiprovider_azureai');
|
||||
$config = [
|
||||
'apikey' => '123',
|
||||
'endpoint' => 'https://api.example.com',
|
||||
'enableglobalratelimit' => true,
|
||||
'globalratelimit' => 1,
|
||||
];
|
||||
$actionconfig = [
|
||||
'core_ai\\aiactions\\generate_image' => [
|
||||
'enabled' => true,
|
||||
'settings' => [
|
||||
'deployment' => 'test',
|
||||
'apiversion' => '2024-06-01',
|
||||
],
|
||||
],
|
||||
];
|
||||
$provider = $this->manager->create_provider_instance(
|
||||
classname: '\aiprovider_openai\provider',
|
||||
name: 'dummy',
|
||||
config: $config,
|
||||
);
|
||||
$provider = $this->manager->update_provider_instance(
|
||||
provider: $provider,
|
||||
actionconfig: $actionconfig,
|
||||
);
|
||||
|
||||
// Mock the http client to return a successful response.
|
||||
['mock' => $mock] = $this->get_mocked_http_client();
|
||||
$url = 'https://example.com/test.jpg';
|
||||
|
||||
// Case 1: Global rate limit has not been reached.
|
||||
$this->create_provider();
|
||||
$this->create_action($user1->id);
|
||||
// The response from Azure AI.
|
||||
$mock->append(new Response(
|
||||
@@ -550,7 +589,7 @@ final class process_generate_image_test extends \advanced_testcase {
|
||||
['Content-Type' => 'image/jpeg'],
|
||||
\GuzzleHttp\Psr7\Utils::streamFor(fopen(self::get_fixture_path('aiprovider_azureai', 'test.jpg'), 'r')),
|
||||
));
|
||||
$processor = new process_generate_image($this->provider, $this->action);
|
||||
$processor = new process_generate_image($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertTrue($result->get_success());
|
||||
|
||||
@@ -576,9 +615,8 @@ final class process_generate_image_test extends \advanced_testcase {
|
||||
['Content-Type' => 'image/jpeg'],
|
||||
\GuzzleHttp\Psr7\Utils::streamFor(fopen(self::get_fixture_path('aiprovider_azureai', 'test.jpg'), 'r')),
|
||||
));
|
||||
$this->create_provider();
|
||||
$this->create_action($user1->id);
|
||||
$processor = new process_generate_image($this->provider, $this->action);
|
||||
$processor = new process_generate_image($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertEquals(429, $result->get_errorcode());
|
||||
$this->assertEquals('Global rate limit exceeded', $result->get_errormessage());
|
||||
@@ -587,7 +625,6 @@ final class process_generate_image_test extends \advanced_testcase {
|
||||
// Case 3: Global rate limit has been reached for a different user too.
|
||||
// Log in user2.
|
||||
$this->setUser($user2);
|
||||
$this->create_provider();
|
||||
$this->create_action($user2->id);
|
||||
// The response from Azure AI.
|
||||
$mock->append(new Response(
|
||||
@@ -609,7 +646,7 @@ final class process_generate_image_test extends \advanced_testcase {
|
||||
['Content-Type' => 'image/jpeg'],
|
||||
\GuzzleHttp\Psr7\Utils::streamFor(fopen(self::get_fixture_path('aiprovider_azureai', 'test.jpg'), 'r')),
|
||||
));
|
||||
$processor = new process_generate_image($this->provider, $this->action);
|
||||
$processor = new process_generate_image($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertFalse($result->get_success());
|
||||
|
||||
@@ -637,9 +674,8 @@ final class process_generate_image_test extends \advanced_testcase {
|
||||
['Content-Type' => 'image/jpeg'],
|
||||
\GuzzleHttp\Psr7\Utils::streamFor(fopen(self::get_fixture_path('aiprovider_azureai', 'test.jpg'), 'r')),
|
||||
));
|
||||
$this->create_provider();
|
||||
$this->create_action($user1->id);
|
||||
$processor = new process_generate_image($this->provider, $this->action);
|
||||
$processor = new process_generate_image($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertTrue($result->get_success());
|
||||
}
|
||||
|
||||
@@ -36,6 +36,9 @@ final class process_generate_text_test extends \advanced_testcase {
|
||||
/** @var string A successful response in JSON format. */
|
||||
protected string $responsebodyjson;
|
||||
|
||||
/** @var \core_ai\manager */
|
||||
private $manager;
|
||||
|
||||
/** @var provider The provider that will process the action. */
|
||||
protected provider $provider;
|
||||
|
||||
@@ -47,6 +50,7 @@ final class process_generate_text_test extends \advanced_testcase {
|
||||
*/
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
$this->resetAfterTest();
|
||||
// Load a response body from a file.
|
||||
$this->responsebodyjson = file_get_contents(self::get_fixture_path('aiprovider_azureai', 'text_request_success.json'));
|
||||
$this->create_provider();
|
||||
@@ -57,7 +61,20 @@ final class process_generate_text_test extends \advanced_testcase {
|
||||
* Create the provider object.
|
||||
*/
|
||||
private function create_provider(): void {
|
||||
$this->provider = new \aiprovider_azureai\provider();
|
||||
$this->manager = \core\di::get(\core_ai\manager::class);
|
||||
$config = [
|
||||
'apikey' => '123',
|
||||
'endpoint' => 'https://api.example.com',
|
||||
'enableuserratelimit' => true,
|
||||
'userratelimit' => 1,
|
||||
'enableglobalratelimit' => true,
|
||||
'globalratelimit' => 1,
|
||||
];
|
||||
$this->provider = $this->manager->create_provider_instance(
|
||||
classname: '\aiprovider_azureai\provider',
|
||||
name: 'dummy',
|
||||
config: $config,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -241,7 +258,6 @@ final class process_generate_text_test extends \advanced_testcase {
|
||||
* Test process method.
|
||||
*/
|
||||
public function test_process(): void {
|
||||
$this->resetAfterTest();
|
||||
// Log in user.
|
||||
$this->setUser($this->getDataGenerator()->create_user());
|
||||
|
||||
@@ -267,7 +283,6 @@ final class process_generate_text_test extends \advanced_testcase {
|
||||
* Test process method with error.
|
||||
*/
|
||||
public function test_process_error(): void {
|
||||
$this->resetAfterTest();
|
||||
// Log in user.
|
||||
$this->setUser($this->getDataGenerator()->create_user());
|
||||
|
||||
@@ -295,7 +310,6 @@ final class process_generate_text_test extends \advanced_testcase {
|
||||
* Test process method with user rate limiter.
|
||||
*/
|
||||
public function test_process_with_user_rate_limiter(): void {
|
||||
$this->resetAfterTest();
|
||||
// Create users.
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$user2 = $this->getDataGenerator()->create_user();
|
||||
@@ -305,14 +319,36 @@ final class process_generate_text_test extends \advanced_testcase {
|
||||
$clock = $this->mock_clock_with_frozen();
|
||||
|
||||
// Set the user rate limiter.
|
||||
set_config('enableuserratelimit', 1, 'aiprovider_azureai');
|
||||
set_config('userratelimit', 1, 'aiprovider_azureai');
|
||||
$config = [
|
||||
'apikey' => '123',
|
||||
'endpoint' => 'https://api.example.com',
|
||||
'enableuserratelimit' => true,
|
||||
'userratelimit' => 1,
|
||||
];
|
||||
$actionconfig = [
|
||||
'core_ai\\aiactions\\generate_text' => [
|
||||
'enabled' => true,
|
||||
'settings' => [
|
||||
'deployment' => 'test',
|
||||
'apiversion' => '2024-06-01',
|
||||
'systeminstruction' => '',
|
||||
],
|
||||
],
|
||||
];
|
||||
$provider = $this->manager->create_provider_instance(
|
||||
classname: '\aiprovider_openai\provider',
|
||||
name: 'dummy',
|
||||
config: $config,
|
||||
);
|
||||
$provider = $this->manager->update_provider_instance(
|
||||
provider: $provider,
|
||||
actionconfig: $actionconfig,
|
||||
);
|
||||
|
||||
// Mock the http client to return a successful response.
|
||||
['mock' => $mock] = $this->get_mocked_http_client();
|
||||
|
||||
// Case 1: User rate limit has not been reached.
|
||||
$this->create_provider();
|
||||
$this->create_action($user1->id);
|
||||
// The response from Azure AI.
|
||||
$mock->append(new Response(
|
||||
@@ -320,7 +356,7 @@ final class process_generate_text_test extends \advanced_testcase {
|
||||
['Content-Type' => 'application/json'],
|
||||
$this->responsebodyjson,
|
||||
));
|
||||
$processor = new process_generate_text($this->provider, $this->action);
|
||||
$processor = new process_generate_text($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertTrue($result->get_success());
|
||||
|
||||
@@ -332,9 +368,8 @@ final class process_generate_text_test extends \advanced_testcase {
|
||||
['Content-Type' => 'application/json'],
|
||||
$this->responsebodyjson,
|
||||
));
|
||||
$this->create_provider();
|
||||
$this->create_action($user1->id);
|
||||
$processor = new process_generate_text($this->provider, $this->action);
|
||||
$processor = new process_generate_text($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertEquals(429, $result->get_errorcode());
|
||||
$this->assertEquals('User rate limit exceeded', $result->get_errormessage());
|
||||
@@ -343,7 +378,6 @@ final class process_generate_text_test extends \advanced_testcase {
|
||||
// Case 3: User rate limit has not been reached for a different user.
|
||||
// Log in user2.
|
||||
$this->setUser($user2);
|
||||
$this->create_provider();
|
||||
$this->create_action($user2->id);
|
||||
// The response from Azure AI.
|
||||
$mock->append(new Response(
|
||||
@@ -351,7 +385,7 @@ final class process_generate_text_test extends \advanced_testcase {
|
||||
['Content-Type' => 'application/json'],
|
||||
$this->responsebodyjson,
|
||||
));
|
||||
$processor = new process_generate_text($this->provider, $this->action);
|
||||
$processor = new process_generate_text($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertTrue($result->get_success());
|
||||
|
||||
@@ -365,9 +399,8 @@ final class process_generate_text_test extends \advanced_testcase {
|
||||
['Content-Type' => 'application/json'],
|
||||
$this->responsebodyjson,
|
||||
));
|
||||
$this->create_provider();
|
||||
$this->create_action($user1->id);
|
||||
$processor = new process_generate_text($this->provider, $this->action);
|
||||
$processor = new process_generate_text($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertTrue($result->get_success());
|
||||
}
|
||||
@@ -376,7 +409,6 @@ final class process_generate_text_test extends \advanced_testcase {
|
||||
* Test process method with global rate limiter.
|
||||
*/
|
||||
public function test_process_with_global_rate_limiter(): void {
|
||||
$this->resetAfterTest();
|
||||
// Create users.
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$user2 = $this->getDataGenerator()->create_user();
|
||||
@@ -386,14 +418,36 @@ final class process_generate_text_test extends \advanced_testcase {
|
||||
$clock = $this->mock_clock_with_frozen();
|
||||
|
||||
// Set the global rate limiter.
|
||||
set_config('enableglobalratelimit', 1, 'aiprovider_azureai');
|
||||
set_config('globalratelimit', 1, 'aiprovider_azureai');
|
||||
$config = [
|
||||
'apikey' => '123',
|
||||
'endpoint' => 'https://api.example.com',
|
||||
'enableglobalratelimit' => true,
|
||||
'globalratelimit' => 1,
|
||||
];
|
||||
$actionconfig = [
|
||||
'core_ai\\aiactions\\generate_text' => [
|
||||
'enabled' => true,
|
||||
'settings' => [
|
||||
'deployment' => 'test',
|
||||
'apiversion' => '2024-06-01',
|
||||
'systeminstruction' => '',
|
||||
],
|
||||
],
|
||||
];
|
||||
$provider = $this->manager->create_provider_instance(
|
||||
classname: '\aiprovider_openai\provider',
|
||||
name: 'dummy',
|
||||
config: $config,
|
||||
);
|
||||
$provider = $this->manager->update_provider_instance(
|
||||
provider: $provider,
|
||||
actionconfig: $actionconfig,
|
||||
);
|
||||
|
||||
// Mock the http client to return a successful response.
|
||||
['mock' => $mock] = $this->get_mocked_http_client();
|
||||
|
||||
// Case 1: Global rate limit has not been reached.
|
||||
$this->create_provider();
|
||||
$this->create_action($user1->id);
|
||||
// The response from Azure AI.
|
||||
$mock->append(new Response(
|
||||
@@ -401,7 +455,7 @@ final class process_generate_text_test extends \advanced_testcase {
|
||||
['Content-Type' => 'application/json'],
|
||||
$this->responsebodyjson,
|
||||
));
|
||||
$processor = new process_generate_text($this->provider, $this->action);
|
||||
$processor = new process_generate_text($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertTrue($result->get_success());
|
||||
|
||||
@@ -413,9 +467,8 @@ final class process_generate_text_test extends \advanced_testcase {
|
||||
['Content-Type' => 'application/json'],
|
||||
$this->responsebodyjson,
|
||||
));
|
||||
$this->create_provider();
|
||||
$this->create_action($user1->id);
|
||||
$processor = new process_generate_text($this->provider, $this->action);
|
||||
$processor = new process_generate_text($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertEquals(429, $result->get_errorcode());
|
||||
$this->assertEquals('Global rate limit exceeded', $result->get_errormessage());
|
||||
@@ -424,7 +477,6 @@ final class process_generate_text_test extends \advanced_testcase {
|
||||
// Case 3: Global rate limit has been reached for a different user too.
|
||||
// Log in user2.
|
||||
$this->setUser($user2);
|
||||
$this->create_provider();
|
||||
$this->create_action($user2->id);
|
||||
// The response from Azure AI.
|
||||
$mock->append(new Response(
|
||||
@@ -432,7 +484,7 @@ final class process_generate_text_test extends \advanced_testcase {
|
||||
['Content-Type' => 'application/json'],
|
||||
$this->responsebodyjson,
|
||||
));
|
||||
$processor = new process_generate_text($this->provider, $this->action);
|
||||
$processor = new process_generate_text($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertFalse($result->get_success());
|
||||
|
||||
@@ -446,9 +498,8 @@ final class process_generate_text_test extends \advanced_testcase {
|
||||
['Content-Type' => 'application/json'],
|
||||
$this->responsebodyjson,
|
||||
));
|
||||
$this->create_provider();
|
||||
$this->create_action($user1->id);
|
||||
$processor = new process_generate_text($this->provider, $this->action);
|
||||
$processor = new process_generate_text($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertTrue($result->get_success());
|
||||
}
|
||||
|
||||
@@ -35,6 +35,9 @@ final class process_summarise_text_test extends \advanced_testcase {
|
||||
/** @var string A successful response in JSON format. */
|
||||
protected string $responsebodyjson;
|
||||
|
||||
/** @var \core_ai\manager */
|
||||
private $manager;
|
||||
|
||||
/** @var provider The provider that will process the action. */
|
||||
protected provider $provider;
|
||||
|
||||
@@ -46,6 +49,7 @@ final class process_summarise_text_test extends \advanced_testcase {
|
||||
*/
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
$this->resetAfterTest();
|
||||
// Load a response body from a file.
|
||||
$this->responsebodyjson = file_get_contents(self::get_fixture_path('aiprovider_azureai', 'text_request_success.json'));
|
||||
$this->create_provider();
|
||||
@@ -56,7 +60,20 @@ final class process_summarise_text_test extends \advanced_testcase {
|
||||
* Create the provider object.
|
||||
*/
|
||||
private function create_provider(): void {
|
||||
$this->provider = new \aiprovider_azureai\provider();
|
||||
$this->manager = \core\di::get(\core_ai\manager::class);
|
||||
$config = [
|
||||
'apikey' => '123',
|
||||
'endpoint' => 'https://api.example.com',
|
||||
'enableuserratelimit' => true,
|
||||
'userratelimit' => 1,
|
||||
'enableglobalratelimit' => true,
|
||||
'globalratelimit' => 1,
|
||||
];
|
||||
$this->provider = $this->manager->create_provider_instance(
|
||||
classname: '\aiprovider_azureai\provider',
|
||||
name: 'dummy',
|
||||
config: $config,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,7 +250,6 @@ final class process_summarise_text_test extends \advanced_testcase {
|
||||
* Test process method.
|
||||
*/
|
||||
public function test_process(): void {
|
||||
$this->resetAfterTest();
|
||||
// Log in user.
|
||||
$this->setUser($this->getDataGenerator()->create_user());
|
||||
|
||||
@@ -259,7 +275,6 @@ final class process_summarise_text_test extends \advanced_testcase {
|
||||
* Test process method with error.
|
||||
*/
|
||||
public function test_process_error(): void {
|
||||
$this->resetAfterTest();
|
||||
// Log in user.
|
||||
$this->setUser($this->getDataGenerator()->create_user());
|
||||
|
||||
@@ -287,7 +302,6 @@ final class process_summarise_text_test extends \advanced_testcase {
|
||||
* Test process method with user rate limiter.
|
||||
*/
|
||||
public function test_process_with_user_rate_limiter(): void {
|
||||
$this->resetAfterTest();
|
||||
// Create users.
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$user2 = $this->getDataGenerator()->create_user();
|
||||
@@ -297,14 +311,36 @@ final class process_summarise_text_test extends \advanced_testcase {
|
||||
$clock = $this->mock_clock_with_frozen();
|
||||
|
||||
// Set the user rate limiter.
|
||||
set_config('enableuserratelimit', 1, 'aiprovider_azureai');
|
||||
set_config('userratelimit', 1, 'aiprovider_azureai');
|
||||
$config = [
|
||||
'apikey' => '123',
|
||||
'endpoint' => 'https://api.example.com',
|
||||
'enableuserratelimit' => true,
|
||||
'userratelimit' => 1,
|
||||
];
|
||||
$actionconfig = [
|
||||
'core_ai\\aiactions\\summarise_text' => [
|
||||
'enabled' => true,
|
||||
'settings' => [
|
||||
'deployment' => 'test',
|
||||
'apiversion' => '2024-06-01',
|
||||
'systeminstruction' => '',
|
||||
],
|
||||
],
|
||||
];
|
||||
$provider = $this->manager->create_provider_instance(
|
||||
classname: '\aiprovider_openai\provider',
|
||||
name: 'dummy',
|
||||
config: $config,
|
||||
);
|
||||
$provider = $this->manager->update_provider_instance(
|
||||
provider: $provider,
|
||||
actionconfig: $actionconfig,
|
||||
);
|
||||
|
||||
// Mock the http client to return a successful response.
|
||||
['mock' => $mock] = $this->get_mocked_http_client();
|
||||
|
||||
// Case 1: User rate limit has not been reached.
|
||||
$this->create_provider();
|
||||
$this->create_action($user1->id);
|
||||
// The response from Azure I.
|
||||
$mock->append(new Response(
|
||||
@@ -312,7 +348,7 @@ final class process_summarise_text_test extends \advanced_testcase {
|
||||
['Content-Type' => 'application/json'],
|
||||
$this->responsebodyjson,
|
||||
));
|
||||
$processor = new process_summarise_text($this->provider, $this->action);
|
||||
$processor = new process_summarise_text($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertTrue($result->get_success());
|
||||
|
||||
@@ -324,9 +360,8 @@ final class process_summarise_text_test extends \advanced_testcase {
|
||||
['Content-Type' => 'application/json'],
|
||||
$this->responsebodyjson,
|
||||
));
|
||||
$this->create_provider();
|
||||
$this->create_action($user1->id);
|
||||
$processor = new process_summarise_text($this->provider, $this->action);
|
||||
$processor = new process_summarise_text($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertEquals(429, $result->get_errorcode());
|
||||
$this->assertEquals('User rate limit exceeded', $result->get_errormessage());
|
||||
@@ -335,7 +370,6 @@ final class process_summarise_text_test extends \advanced_testcase {
|
||||
// Case 3: User rate limit has not been reached for a different user.
|
||||
// Log in user2.
|
||||
$this->setUser($user2);
|
||||
$this->create_provider();
|
||||
$this->create_action($user2->id);
|
||||
// The response from Azure AI.
|
||||
$mock->append(new Response(
|
||||
@@ -343,7 +377,7 @@ final class process_summarise_text_test extends \advanced_testcase {
|
||||
['Content-Type' => 'application/json'],
|
||||
$this->responsebodyjson,
|
||||
));
|
||||
$processor = new process_summarise_text($this->provider, $this->action);
|
||||
$processor = new process_summarise_text($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertTrue($result->get_success());
|
||||
|
||||
@@ -357,9 +391,8 @@ final class process_summarise_text_test extends \advanced_testcase {
|
||||
['Content-Type' => 'application/json'],
|
||||
$this->responsebodyjson,
|
||||
));
|
||||
$this->create_provider();
|
||||
$this->create_action($user1->id);
|
||||
$processor = new process_summarise_text($this->provider, $this->action);
|
||||
$processor = new process_summarise_text($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertTrue($result->get_success());
|
||||
}
|
||||
@@ -378,14 +411,36 @@ final class process_summarise_text_test extends \advanced_testcase {
|
||||
$clock = $this->mock_clock_with_frozen();
|
||||
|
||||
// Set the global rate limiter.
|
||||
set_config('enableglobalratelimit', 1, 'aiprovider_azureai');
|
||||
set_config('globalratelimit', 1, 'aiprovider_azureai');
|
||||
$config = [
|
||||
'apikey' => '123',
|
||||
'endpoint' => 'https://api.example.com',
|
||||
'enableglobalratelimit' => true,
|
||||
'globalratelimit' => 1,
|
||||
];
|
||||
$actionconfig = [
|
||||
'core_ai\\aiactions\\summarise_text' => [
|
||||
'enabled' => true,
|
||||
'settings' => [
|
||||
'deployment' => 'test',
|
||||
'apiversion' => '2024-06-01',
|
||||
'systeminstruction' => '',
|
||||
],
|
||||
],
|
||||
];
|
||||
$provider = $this->manager->create_provider_instance(
|
||||
classname: '\aiprovider_openai\provider',
|
||||
name: 'dummy',
|
||||
config: $config,
|
||||
);
|
||||
$provider = $this->manager->update_provider_instance(
|
||||
provider: $provider,
|
||||
actionconfig: $actionconfig,
|
||||
);
|
||||
|
||||
// Mock the http client to return a successful response.
|
||||
['mock' => $mock] = $this->get_mocked_http_client();
|
||||
|
||||
// Case 1: Global rate limit has not been reached.
|
||||
$this->create_provider();
|
||||
$this->create_action($user1->id);
|
||||
// The response from Azure AI.
|
||||
$mock->append(new Response(
|
||||
@@ -393,7 +448,7 @@ final class process_summarise_text_test extends \advanced_testcase {
|
||||
['Content-Type' => 'application/json'],
|
||||
$this->responsebodyjson,
|
||||
));
|
||||
$processor = new process_summarise_text($this->provider, $this->action);
|
||||
$processor = new process_summarise_text($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertTrue($result->get_success());
|
||||
|
||||
@@ -405,9 +460,8 @@ final class process_summarise_text_test extends \advanced_testcase {
|
||||
['Content-Type' => 'application/json'],
|
||||
$this->responsebodyjson,
|
||||
));
|
||||
$this->create_provider();
|
||||
$this->create_action($user1->id);
|
||||
$processor = new process_summarise_text($this->provider, $this->action);
|
||||
$processor = new process_summarise_text($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertEquals(429, $result->get_errorcode());
|
||||
$this->assertEquals('Global rate limit exceeded', $result->get_errormessage());
|
||||
@@ -416,7 +470,6 @@ final class process_summarise_text_test extends \advanced_testcase {
|
||||
// Case 3: Global rate limit has been reached for a different user too.
|
||||
// Log in user2.
|
||||
$this->setUser($user2);
|
||||
$this->create_provider();
|
||||
$this->create_action($user2->id);
|
||||
// The response from Azure AI.
|
||||
$mock->append(new Response(
|
||||
@@ -424,7 +477,7 @@ final class process_summarise_text_test extends \advanced_testcase {
|
||||
['Content-Type' => 'application/json'],
|
||||
$this->responsebodyjson,
|
||||
));
|
||||
$processor = new process_summarise_text($this->provider, $this->action);
|
||||
$processor = new process_summarise_text($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertFalse($result->get_success());
|
||||
|
||||
@@ -438,9 +491,8 @@ final class process_summarise_text_test extends \advanced_testcase {
|
||||
['Content-Type' => 'application/json'],
|
||||
$this->responsebodyjson,
|
||||
));
|
||||
$this->create_provider();
|
||||
$this->create_action($user1->id);
|
||||
$processor = new process_summarise_text($this->provider, $this->action);
|
||||
$processor = new process_summarise_text($provider, $this->action);
|
||||
$result = $processor->process();
|
||||
$this->assertTrue($result->get_success());
|
||||
}
|
||||
|
||||
@@ -26,12 +26,33 @@ namespace aiprovider_azureai;
|
||||
*/
|
||||
final class provider_test extends \advanced_testcase {
|
||||
|
||||
/** @var \core_ai\manager */
|
||||
private $manager;
|
||||
|
||||
/** @var \core_ai\provider */
|
||||
private $provider;
|
||||
|
||||
/**
|
||||
* Overriding setUp() function to always reset after tests.
|
||||
*/
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Create the provider instance.
|
||||
$this->manager = \core\di::get(\core_ai\manager::class);
|
||||
$config = ['data' => 'goeshere'];
|
||||
$this->provider = $this->manager->create_provider_instance(
|
||||
classname: '\aiprovider_azureai\provider',
|
||||
name: 'dummy',
|
||||
config: $config,
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Test get_action_list
|
||||
*/
|
||||
public function test_get_action_list(): void {
|
||||
$provider = new \aiprovider_azureai\provider();
|
||||
$actionlist = $provider->get_action_list();
|
||||
$actionlist = $this->provider->get_action_list();
|
||||
$this->assertIsArray($actionlist);
|
||||
$this->assertEquals(3, count($actionlist));
|
||||
$this->assertContains(\core_ai\aiactions\generate_text::class, $actionlist);
|
||||
@@ -43,8 +64,7 @@ final class provider_test extends \advanced_testcase {
|
||||
* Test generate_userid.
|
||||
*/
|
||||
public function test_generate_userid(): void {
|
||||
$provider = new \aiprovider_azureai\provider();
|
||||
$userid = $provider->generate_userid(1);
|
||||
$userid = $this->provider->generate_userid(1);
|
||||
|
||||
// Assert that the generated userid is a string of proper length.
|
||||
$this->assertIsString($userid);
|
||||
@@ -55,13 +75,18 @@ final class provider_test extends \advanced_testcase {
|
||||
* Test is_request_allowed.
|
||||
*/
|
||||
public function test_is_request_allowed(): void {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
// Set plugin config rate limiter settings.
|
||||
set_config('enableglobalratelimit', 1, 'aiprovider_azureai');
|
||||
set_config('globalratelimit', 5, 'aiprovider_azureai');
|
||||
set_config('enableuserratelimit', 1, 'aiprovider_azureai');
|
||||
set_config('userratelimit', 3, 'aiprovider_azureai');
|
||||
// Create the provider instance.
|
||||
$config = [
|
||||
'enableuserratelimit' => true,
|
||||
'userratelimit' => 3,
|
||||
'enableglobalratelimit' => true,
|
||||
'globalratelimit' => 5,
|
||||
];
|
||||
$provider = $this->manager->create_provider_instance(
|
||||
classname: '\aiprovider_openai\provider',
|
||||
name: 'dummy',
|
||||
config: $config,
|
||||
);
|
||||
|
||||
$contextid = 1;
|
||||
$userid = 1;
|
||||
@@ -79,7 +104,6 @@ final class provider_test extends \advanced_testcase {
|
||||
numimages: $numimages,
|
||||
style: $style
|
||||
);
|
||||
$provider = new provider();
|
||||
|
||||
// Make 3 requests, all should be allowed.
|
||||
for ($i = 0; $i < 3; $i++) {
|
||||
@@ -115,22 +139,25 @@ final class provider_test extends \advanced_testcase {
|
||||
* Test is_provider_configured.
|
||||
*/
|
||||
public function test_is_provider_configured(): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
// No configured values.
|
||||
$provider = new \aiprovider_azureai\provider();
|
||||
$this->assertFalse($provider->is_provider_configured());
|
||||
$this->assertFalse($this->provider->is_provider_configured());
|
||||
|
||||
// Partially configured values.
|
||||
set_config('apikey', '123', 'aiprovider_azureai');
|
||||
set_config('endpoint', '', 'aiprovider_azureai');
|
||||
$provider = new \aiprovider_azureai\provider();
|
||||
$this->assertFalse($provider->is_provider_configured());
|
||||
$updatedprovider = $this->manager->update_provider_instance(
|
||||
provider: $this->provider,
|
||||
config: ['apikey' => '123'],
|
||||
);
|
||||
$this->assertFalse($updatedprovider->is_provider_configured());
|
||||
|
||||
// Properly configured values.
|
||||
set_config('apikey', '123', 'aiprovider_azureai');
|
||||
set_config('endpoint', 'abc', 'aiprovider_azureai');
|
||||
$provider = new \aiprovider_azureai\provider();
|
||||
$this->assertTrue($provider->is_provider_configured());
|
||||
$updatedprovider = $this->manager->update_provider_instance(
|
||||
provider: $this->provider,
|
||||
config: [
|
||||
'apikey' => '123',
|
||||
'endpoint' => 'abc',
|
||||
],
|
||||
);
|
||||
$this->assertTrue($updatedprovider->is_provider_configured());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,6 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->component = 'aiprovider_azureai';
|
||||
$plugin->version = 2024121800;
|
||||
$plugin->requires = 2024100100;
|
||||
$plugin->version = 2025010300;
|
||||
$plugin->requires = 2025010300;
|
||||
$plugin->maturity = MATURITY_STABLE;
|
||||
|
||||
Reference in New Issue
Block a user