Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MBS-9385: Add custom error handling for content filtering #26

Merged
merged 1 commit into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 31 additions & 14 deletions classes/base_connector.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

namespace local_ai_manager;

use aitool_chatgpt\instance;
use core\http_client;
use core_plugin_manager;
use local_ai_manager\local\prompt_response;
Expand Down Expand Up @@ -199,7 +198,7 @@ final public static function get_all_connectors(): array {
* @param ClientExceptionInterface $exception the exception which has been thrown
* @return request_response a request_response object containing the necessary information in a standardized way
*/
protected function create_error_response_from_exception(ClientExceptionInterface $exception): request_response {
final protected function create_error_response_from_exception(ClientExceptionInterface $exception): request_response {
$message = '';
// This is actually pretty bad, but it does not seem possible to get to these kind of errors through some kind of
// Guzzle API functions, so we have to hope the cURL error messages are kinda stable.
PhMemmel marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -210,18 +209,22 @@ protected function create_error_response_from_exception(ClientExceptionInterface
$message = get_string('exception_curl', 'local_ai_manager');
}
} else {
switch ($exception->getCode()) {
case 401:
$message = get_string('exception_http401', 'local_ai_manager');
break;
case 429:
$message = get_string('exception_http429', 'local_ai_manager');
break;
case 500:
$message = get_string('exception_http500', 'local_ai_manager');
break;
default:
$message = get_string('exception_default', 'local_ai_manager');
$message = $this->get_custom_error_message($exception->getCode(), $exception);
if (empty($message)) {
// If the tool specific connector does not provide a customized error message, we use our defaults.
switch ($exception->getCode()) {
case 401:
$message = get_string('exception_http401', 'local_ai_manager');
break;
case 429:
$message = get_string('exception_http429', 'local_ai_manager');
break;
case 500:
$message = get_string('exception_http500', 'local_ai_manager');
break;
default:
$message = get_string('exception_default', 'local_ai_manager');
}
}
}
$debuginfo = $exception->getMessage() . '\n' . $exception->getTraceAsString() . '\n';
Expand Down Expand Up @@ -253,4 +256,18 @@ protected function get_headers(): array {
public function allowed_mimetypes(): array {
return [];
}

/**
* Provides a custom error message for a given error code.
*
* This method is intended to be overwritten by subclasses to provide customized error information.
*
* @param int $code the error code from the request of the external AI tool
* @param ?ClientExceptionInterface $exception the exception (if there is any) to extract additional information from,
* can be null if no exception had been thrown
* @return string the localized error message string
*/
protected function get_custom_error_message(int $code, ?ClientExceptionInterface $exception = null): string {
return '';
}
}
18 changes: 18 additions & 0 deletions tools/chatgpt/classes/connector.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use local_ai_manager\local\prompt_response;
use local_ai_manager\local\unit;
use local_ai_manager\local\usage;
use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Message\StreamInterface;

/**
Expand Down Expand Up @@ -150,4 +151,21 @@ protected function get_headers(): array {
public function allowed_mimetypes(): array {
return ['image/png', 'image/jpeg', 'image/webp', 'image/gif'];
}

#[\Override]
protected function get_custom_error_message(int $code, ?ClientExceptionInterface $exception = null): string {
$message = '';
switch ($code) {
case 400:
if (method_exists($exception, 'getResponse') && !empty($exception->getResponse())) {
$responsebody = json_decode($exception->getResponse()->getBody()->getContents());
if (property_exists($responsebody, 'error') && property_exists($responsebody->error, 'code')
&& $responsebody->error->code === 'content_filter') {
$message = get_string('err_contentfilter', 'aitool_chatgpt');
}
}
break;
}
return $message;
}
}
1 change: 1 addition & 0 deletions tools/chatgpt/lang/de/aitool_chatgpt.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@
*/

$string['adddescription'] = 'ChatGPT ist ein vielseitiges KI-Modell, das für natürliche Sprachinteraktionen wie Kundensupport, virtuelle Assistenzen, Content-Erstellung und mehr eingesetzt wird.';
$string['err_contentfilter'] = 'Ihre Anfrage wurde vom Inhaltsfilter des KI-Tools zurückgewiesen. Ihr Prompt enthält vermutlich eine Anweisung, die nicht erlaubt ist.';
$string['pluginname'] = 'ChatGPT';
$string['privacy:metadata'] = 'Das Subplugin des ai_manager Plugins "ChatGPT" speichert keine personenbezogenen Daten.';
1 change: 1 addition & 0 deletions tools/chatgpt/lang/en/aitool_chatgpt.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@
*/

$string['adddescription'] = 'ChatGPT is a versatile AI model used for natural language interactions such as customer support, virtual assistants, content creation and more.';
$string['err_contentfilter'] = 'Your request was rejected as a result of the content filter of the external tool. Your prompt probably requests something that is not allowed.';
$string['pluginname'] = 'ChatGPT';
$string['privacy:metadata'] = 'The local ai_manager tool subplugin "ChatGPT" does not store any personal data.';
18 changes: 18 additions & 0 deletions tools/dalle/classes/connector.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use local_ai_manager\local\prompt_response;
use local_ai_manager\local\unit;
use local_ai_manager\local\usage;
use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Message\StreamInterface;

/**
Expand Down Expand Up @@ -123,4 +124,21 @@ public function get_available_options(): array {
}
return $options;
}

#[\Override]
protected function get_custom_error_message(int $code, ?ClientExceptionInterface $exception = null): string {
$message = '';
switch ($code) {
case 400:
if (method_exists($exception, 'getResponse') && !empty($exception->getResponse())) {
$responsebody = json_decode($exception->getResponse()->getBody()->getContents());
if (property_exists($responsebody, 'error') && property_exists($responsebody->error, 'code')
&& $responsebody->error->code === 'content_policy_violation') {
$message = get_string('err_contentpolicyviolation', 'aitool_dalle');
}
}
break;
}
return $message;
}
}
1 change: 1 addition & 0 deletions tools/dalle/lang/de/aitool_dalle.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@
*/

$string['adddescription'] = 'Dall-E ist ein KI-Modell von OpenAI, das darauf spezialisiert ist, aus Textbeschreibungen Bilder zu generieren.';
$string['err_contentpolicyviolation'] = 'Ihre Anfrage wurde vom Sicherheitssystem des KI-Tools zurückgewiesen. Ihr Prompt enthält vermutlich eine Anweisung, die nicht erlaubt ist.';
$string['pluginname'] = 'Dall-E';
$string['privacy:metadata'] = 'Das Subplugin des ai_manager Plugins "Dall-E" speichert keine personenbezogenen Daten.';
1 change: 1 addition & 0 deletions tools/dalle/lang/en/aitool_dalle.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@
*/

$string['adddescription'] = 'Dall-E is an AI model from OpenAI that specializes in generating images from text descriptions.';
$string['err_contentpolicyviolation'] = 'Your request was rejected as a result of our safety system. Your prompt probably requests something that is not allowed.';
$string['pluginname'] = 'Dall-E';
$string['privacy:metadata'] = 'The local ai_manager tool subplugin "Dall-E" does not store any personal data.';