gutenberg_ai_tools-1.0.x-dev/src/Plugin/rest/resource/GutenbergAIEndpoint.php
src/Plugin/rest/resource/GutenbergAIEndpoint.php
<?php
namespace Drupal\gutenberg_ai_tools\Plugin\rest\resource;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\ai\AiProviderPluginManager;
use Drupal\ai\OperationType\Chat\ChatInput;
use Drupal\ai\OperationType\Chat\ChatMessage;
use Psr\Log\LoggerInterface;
/**
* Provides a Save Events User Endpoint.
*
* @RestResource(
* id = "gutenberg_ai_tools_ai_endpoint",
* label = @Translation("Gutenberg AI Tools AI REST"),
* serialization_class = "",
* uri_paths = {
* "create" = "/gutenberg-ai-tools/ai-rest"
* }
* )
*/
class GutenbergAIEndpoint extends ResourceBase {
/**
* The available serialization formats.
*
* @var array
*/
protected $serializerFormats = [];
/**
* A current user instance.
*
* @var \Drupal\Core\Session\AccountProxyInterface
*/
protected $currentUser;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The configuration factory.
*
* @var \Drupal\Core\Config\ConfigFactory
*/
protected $configFactory;
/**
* The AI provider plugin manager.
*
* @var \Drupal\ai\AiProviderPluginManager
*/
protected $aiProvider;
/**
* Logger.
*
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/**
* Constructs a Drupal\rest\Plugin\ResourceBase object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param array $serializer_formats
* The available serialization formats.
* @param \Drupal\Core\Session\AccountProxyInterface $current_user
* A current user instance.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory.
* @param \Drupal\ai\AiProviderPluginManager $ai_provider
* The AI provider plugin manager.
* @param \Psr\Log\LoggerInterface $logger
* A logger instance.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, array $serializer_formats, AccountProxyInterface $current_user, EntityTypeManagerInterface $entity_type_manager, ConfigFactoryInterface $config_factory, AiProviderPluginManager $ai_provider, LoggerInterface $logger) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger);
$this->currentUser = $current_user;
$this->entityTypeManager = $entity_type_manager;
$this->configFactory = $config_factory;
$this->aiProvider = $ai_provider;
$this->logger = $logger;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->getParameter('serializer.formats'),
$container->get('current_user'),
$container->get('entity_type.manager'),
$container->get('config.factory'),
$container->get('ai.provider'),
$container->get('logger.channel.gutenberg_ai_tools'),
);
}
/**
* Responds to POST requests.
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
* Throws exception expected.
*/
public function post($data) {
// Use current user after pass authentication to validate access.
if (!$this->currentUser->isAuthenticated()) {
// Display the default access denied page.
throw new AccessDeniedHttpException('Access Denied.');
}
// Check if we have enough data to work with.
if (empty($data['ai_prompt'])) {
// If an exception was thrown at this stage, there was a problem
// decoding the data. Throw a 400 http exception.
throw new BadRequestHttpException($this->t('Bad data format. Please make sure you have all data set in the request.'));
}
/* Get the AI settings for the desired response */
$ai_settings = $this->configFactory->get('gutenberg_ai_tools.settings');
$text = $data['ai_prompt'];
$provider_model = $ai_settings->get('provider_model');
$ai_provider = $ai_settings->get('ai_provider');
if (!$ai_provider) {
$error = $this->t("You need to select an AI Provider.");
$this->logger->error($error);
$response = new ResourceResponse($error);
return $response;
}
if (!$provider_model) {
$error = $this->t('You need to select a Provider Model: /admin/config/ai/gutenberg-ai-settings.');
$this->logger->error($error);
$response = new ResourceResponse($error);
return $response;
}
try {
$provider = $this->aiProvider->loadProviderFromSimpleOption($provider_model);
}
catch (\Exception $e) {
$error = $this->t('You need to select a Model.');
$this->logger->error($error);
$response = new ResourceResponse($error);
return $response;
}
$model = $this->aiProvider->getModelNameFromSimpleOption($provider_model);
try {
$messages = new ChatInput([
new ChatMessage('user', $data['ai_prompt']),
]);
}
catch (\Exception $e) {
$error = $this->t('Error when creating an instance of ChatInput to create an AI Chat session, please check the logs for more information.');
$this->logger->error($error);
$response = new ResourceResponse("Error when creating an instance of ChatInput to create an AI Chat session, please check the logs for more information.");
return $response;
}
try {
$message = $provider->chat($messages, $model)->getNormalized();
}
catch (\Exception $e) {
$error = $this->t('Error when making a call to chat() to the AI Provider, please check the logs for more information.');
$this->logger->error($error);
$response = new ResourceResponse($error);
return $response;
}
$response = new ResourceResponse($message->getText());
return $response;
}
}
