mirror of
https://github.com/moodle/moodle.git
synced 2025-04-13 12:32:08 +02:00
MDL-82609 AI: Provider - Action settings
Allow each each Provider plugin to be able to specify settings for the actions that they support. Adds admin setting support for these settings.
This commit is contained in:
parent
09e56f2d1a
commit
2ae9b25ad4
@ -89,8 +89,8 @@ abstract class base {
|
||||
*
|
||||
* @return string The system instruction for the action.
|
||||
*/
|
||||
public function get_system_instruction(): string {
|
||||
$stringid = 'action_' . $this->get_basename() . '_instruction';
|
||||
public static function get_system_instruction(): string {
|
||||
$stringid = 'action_' . self::get_basename() . '_instruction';
|
||||
|
||||
// If the string doesn't exist, return an empty string.
|
||||
if (!get_string_manager()->string_exists($stringid, 'core_ai')) {
|
||||
|
@ -54,4 +54,21 @@ abstract class provider {
|
||||
return get_string('pluginname', $component);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
@ -175,7 +175,14 @@ class aiprovider_action_management_table extends flexible_table implements dynam
|
||||
* @return string
|
||||
*/
|
||||
protected function col_settings(stdClass $row): string {
|
||||
// TODO: MDL-82609 - Add settings link.
|
||||
global $CFG;
|
||||
require_once($CFG->libdir . '/adminlib.php'); // Needed for the AJAX calls.
|
||||
$tree = \admin_get_root();
|
||||
$sectionname = $this->pluginname . '_' . $row->action::get_basename();
|
||||
$section = $tree->locate($sectionname);
|
||||
if ($section) {
|
||||
return \html_writer::link($section->get_settings_page_url(), get_string('settings'));
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,15 @@ abstract class abstract_processor extends process_base {
|
||||
*/
|
||||
abstract protected function get_model(): string;
|
||||
|
||||
/**
|
||||
* Get the system instructions.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_system_instruction(): string {
|
||||
return $this->action::get_system_instruction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the request object to send to the OpenAI API.
|
||||
*
|
||||
|
@ -22,6 +22,7 @@ use GuzzleHttp\Psr7\Request;
|
||||
use GuzzleHttp\Psr7\Uri;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
|
||||
/**
|
||||
* Class process image generation.
|
||||
@ -38,13 +39,13 @@ class process_generate_image extends abstract_processor {
|
||||
private string $responseformat = 'url';
|
||||
|
||||
#[\Override]
|
||||
protected function get_endpoint(): \Psr\Http\Message\UriInterface {
|
||||
return new Uri('https://api.openai.com/v1/images/generations');
|
||||
protected function get_endpoint(): UriInterface {
|
||||
return new Uri(get_config('aiprovider_openai', 'action_generate_image_endpoint'));
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function get_model(): string {
|
||||
return 'dall-e-3';
|
||||
return get_config('aiprovider_openai', 'action_generate_image_model');
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
|
@ -32,12 +32,17 @@ use Psr\Http\Message\UriInterface;
|
||||
class process_generate_text extends abstract_processor {
|
||||
#[\Override]
|
||||
protected function get_endpoint(): UriInterface {
|
||||
return new Uri('https://api.openai.com/v1/chat/completions');
|
||||
return new Uri(get_config('aiprovider_openai', 'action_generate_text_endpoint'));
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function get_model(): string {
|
||||
return 'gpt-4o';
|
||||
return get_config('aiprovider_openai', 'action_generate_text_model');
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function get_system_instruction(): string {
|
||||
return get_config('aiprovider_openai', 'action_generate_text_systeminstruction');
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
@ -53,7 +58,7 @@ class process_generate_text extends abstract_processor {
|
||||
$requestobj->user = $userid;
|
||||
|
||||
// If there is a system string available, use it.
|
||||
$systeminstruction = $this->action->get_system_instruction();
|
||||
$systeminstruction = $this->get_system_instruction();
|
||||
if (!empty($systeminstruction)) {
|
||||
$systemobj = new \stdClass();
|
||||
$systemobj->role = 'system';
|
||||
|
@ -16,6 +16,9 @@
|
||||
|
||||
namespace aiprovider_openai;
|
||||
|
||||
use GuzzleHttp\Psr7\Uri;
|
||||
use Psr\Http\Message\UriInterface;
|
||||
|
||||
/**
|
||||
* Class process text summarisation.
|
||||
*
|
||||
@ -24,4 +27,18 @@ namespace aiprovider_openai;
|
||||
* @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_endpoint(): UriInterface {
|
||||
return new Uri(get_config('aiprovider_openai', 'action_summarise_text_endpoint'));
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function get_model(): string {
|
||||
return get_config('aiprovider_openai', 'action_summarise_text_model');
|
||||
}
|
||||
|
||||
#[\Override]
|
||||
protected function get_system_instruction(): string {
|
||||
return get_config('aiprovider_openai', 'action_summarise_text_systeminstruction');
|
||||
}
|
||||
}
|
||||
|
@ -143,4 +143,68 @@ class provider extends \core_ai\provider {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
$actionname = substr($action, (strrpos($action, '\\') + 1));
|
||||
$settings = [];
|
||||
if ($actionname === 'generate_text' || $actionname === 'summarise_text') {
|
||||
// Add the model setting.
|
||||
$settings[] = new \admin_setting_configtext(
|
||||
"aiprovider_openai/action_{$actionname}_model",
|
||||
new \lang_string("action:{$actionname}:model", 'aiprovider_openai'),
|
||||
new \lang_string("action:{$actionname}:model_desc", 'aiprovider_openai'),
|
||||
'gpt-4o',
|
||||
PARAM_TEXT,
|
||||
);
|
||||
// Add API endpoint.
|
||||
$settings[] = new \admin_setting_configtext(
|
||||
"aiprovider_openai/action_{$actionname}_endpoint",
|
||||
new \lang_string("action:{$actionname}:endpoint", 'aiprovider_openai'),
|
||||
new \lang_string("action:{$actionname}:endpoint_desc", 'aiprovider_openai'),
|
||||
'https://api.openai.com/v1/chat/completions',
|
||||
PARAM_URL,
|
||||
);
|
||||
// Add system instruction settings.
|
||||
$settings[] = new \admin_setting_configtextarea(
|
||||
"aiprovider_openai/action_{$actionname}_systeminstruction",
|
||||
new \lang_string("action:{$actionname}:systeminstruction", 'aiprovider_openai'),
|
||||
new \lang_string("action:{$actionname}:systeminstruction_desc", 'aiprovider_openai'),
|
||||
$action::get_system_instruction(),
|
||||
PARAM_TEXT
|
||||
);
|
||||
} else if ($actionname === 'generate_image') {
|
||||
// Add the model setting.
|
||||
$settings[] = new \admin_setting_configtext(
|
||||
"aiprovider_openai/action_{$actionname}_model",
|
||||
new \lang_string("action:{$actionname}:model", 'aiprovider_openai'),
|
||||
new \lang_string("action:{$actionname}:model_desc", 'aiprovider_openai'),
|
||||
'dall-e-3',
|
||||
PARAM_TEXT,
|
||||
);
|
||||
// Add API endpoint.
|
||||
$settings[] = new \admin_setting_configtext(
|
||||
"aiprovider_openai/action_{$actionname}_endpoint",
|
||||
new \lang_string("action:{$actionname}:endpoint", 'aiprovider_openai'),
|
||||
new \lang_string("action:{$actionname}:endpoint_desc", 'aiprovider_openai'),
|
||||
'https://api.openai.com/v1/images/generations',
|
||||
PARAM_URL,
|
||||
);
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,22 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
$string['action:generate_image:endpoint'] = 'API endpoint';
|
||||
$string['action:generate_image:endpoint_desc'] = 'The API endpoint the provider uses for this action.';
|
||||
$string['action:generate_image:model'] = 'Image generation model';
|
||||
$string['action:generate_image:model_desc'] = 'The model used to generate images from user prompts.';
|
||||
$string['action:generate_text:endpoint'] = 'API endpoint';
|
||||
$string['action:generate_text:endpoint_desc'] = 'The API endpoint for the provider uses for this action.';
|
||||
$string['action:generate_text:model'] = 'Text generation model';
|
||||
$string['action:generate_text:model_desc'] = 'The model used to generate the text response.';
|
||||
$string['action:generate_text:systeminstruction'] = 'System instruction';
|
||||
$string['action:generate_text:systeminstruction_desc'] = 'This instruction is provided together with the user prompt for this action. It provides information to the AI model on how to generate the response.';
|
||||
$string['action:summarise_text:endpoint'] = 'API endpoint';
|
||||
$string['action:summarise_text:endpoint_desc'] = 'The API endpoint the provider uses for this action.';
|
||||
$string['action:summarise_text:model'] = 'Text summarisation model';
|
||||
$string['action:summarise_text:model_desc'] = 'The model used to summarise the provided text.';
|
||||
$string['action:summarise_text:systeminstruction'] = 'System instruction';
|
||||
$string['action:summarise_text:systeminstruction_desc'] = 'This instruction is provided together with the user prompt for this action. It provides information to the AI model on how to generate the response.';
|
||||
$string['apikey'] = 'OpenAI API key';
|
||||
$string['apikey_desc'] = 'Enter your OpenAI API key. You can get one from <a href="https://platform.openai.com/account/api-keys" target="_blank">here</a>';
|
||||
$string['enableglobalratelimit'] = 'Enable global rate limiting';
|
||||
|
@ -83,8 +83,8 @@ final class process_generate_text_test extends \advanced_testcase {
|
||||
|
||||
$body = (object) json_decode($request->getBody()->getContents());
|
||||
|
||||
$this->assertEquals('This is a test prompt', $body->messages[0]->content);
|
||||
$this->assertEquals('user', $body->messages[0]->role);
|
||||
$this->assertEquals('This is a test prompt', $body->messages[1]->content);
|
||||
$this->assertEquals('user', $body->messages[1]->role);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -25,6 +25,6 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->component = 'aiprovider_openai';
|
||||
$plugin->version = 2024060900;
|
||||
$plugin->version = 2024091300;
|
||||
$plugin->requires = 2024041600;
|
||||
$plugin->maturity = MATURITY_STABLE;
|
||||
|
@ -27,6 +27,9 @@ $string['action_generate_image'] = 'Generate image';
|
||||
$string['action_generate_image_desc'] = 'Generates an image based on a text prompt.';
|
||||
$string['action_generate_text'] = 'Generate text';
|
||||
$string['action_generate_text_desc'] = 'Generates text based on a text prompt.';
|
||||
$string['action_generate_text_instruction'] = 'You will receive a text input from the user. Your task is to generate text based on their request. Follow these important instructions:
|
||||
1. Return the summary in plain text only.
|
||||
2. Do not include any markdown formatting, greetings, or platitudes.';
|
||||
$string['action_summarise_text'] = 'Summarise text';
|
||||
$string['action_summarise_text_desc'] = 'Summarises text based on provided input text.';
|
||||
$string['action_summarise_text_instruction'] = 'You will receive a text input from the user. Your task is to summarize the provided text. Follow these guidelines:
|
||||
@ -41,6 +44,9 @@ Important Instructions:
|
||||
Ensure the summary is easy to read and effectively conveys the main points of the original text.';
|
||||
$string['action_translate_text'] = 'Translate text';
|
||||
$string['action_translate_text_desc'] = 'Translate provided text from one language to another.';
|
||||
$string['actionsettingprovider'] = '{$a} action settings';
|
||||
$string['actionsettingprovider_desc'] = 'These settings are specifc to this action for this provider.<br/>
|
||||
They are used to control how the action is processed by the provider.';
|
||||
$string['ai'] = 'AI';
|
||||
$string['aiplacementsettings'] = 'Manage settings for AI placements';
|
||||
$string['aiprovidersettings'] = 'Manage settings for AI providers';
|
||||
|
@ -18,7 +18,6 @@ namespace core\plugininfo;
|
||||
|
||||
use core_plugin_manager;
|
||||
use moodle_url;
|
||||
use core\lang_string;
|
||||
|
||||
/**
|
||||
* AI placement plugin info class.
|
||||
@ -103,18 +102,36 @@ class aiprovider extends base {
|
||||
} else {
|
||||
// Provider action settings heading.
|
||||
$settings->add(new \admin_setting_heading("{$section}/generals",
|
||||
new lang_string('provideractionsettings', 'core_ai'),
|
||||
new lang_string('provideractionsettings_desc', 'core_ai')));
|
||||
new \lang_string('provideractionsettings', 'core_ai'),
|
||||
new \lang_string('provideractionsettings_desc', 'core_ai')));
|
||||
// Load the setting table of actions that this provider supports.
|
||||
$settings->add(new \core_ai\admin\admin_setting_action_manager(
|
||||
$section,
|
||||
\core_ai\table\aiprovider_action_management_table::class,
|
||||
'manageaiproviders',
|
||||
new lang_string('manageaiproviders', 'core_ai'),
|
||||
new \lang_string('manageaiproviders', 'core_ai'),
|
||||
));
|
||||
}
|
||||
|
||||
$ADMIN->add($parentnodename, $settings);
|
||||
// Load any action settings for this provider.
|
||||
$providerclass = "\\{$section}\\provider";
|
||||
$provider = new $providerclass();
|
||||
$actionlist = $provider->get_action_list();
|
||||
foreach ($actionlist as $action) {
|
||||
$actionsettings = $provider->get_action_settings($action, $ADMIN, $section, $hassiteconfig);
|
||||
if (!empty($actionsettings)) {
|
||||
$actionname = substr($action, (strrpos($action, '\\') + 1));
|
||||
$settings = new \admin_settingpage($section . '_' . $actionname, $action::get_name(), 'moodle/site:config', true);
|
||||
$setting = new \admin_setting_heading("{$section}_actions/heading",
|
||||
new \lang_string('actionsettingprovider', 'core_ai', $provider->get_name()),
|
||||
new \lang_string('actionsettingprovider_desc', 'core_ai'));
|
||||
$settings->add($setting);
|
||||
foreach ($actionsettings as $setting) {
|
||||
$settings->add($setting);
|
||||
}
|
||||
$ADMIN->add('root', $settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user