maestro-3.0.1-rc2/modules/maestro_ai_task/src/MaestroAiTaskAPI/MaestroAiTaskAPI.php

modules/maestro_ai_task/src/MaestroAiTaskAPI/MaestroAiTaskAPI.php
<?php

namespace Drupal\maestro_ai_task\MaestroAiTaskAPI;

use Drupal\maestro\Engine\MaestroEngine;
use Drupal\maestro_ai_task\Entity\MaestroAIStorage;

/**
 * MaestroAiTaskAPI API class.
 *
 * Provides the Maestro AI Task API.
 */
class MaestroAiTaskAPI {
  
  /**
   * getAiStorageEntityDefinitionsInTemplate  
   *   Provide a template machine name and this method will look for all AI tasks in that template and return to you  
   *   an array of defined Maestro AI Task Storage entities in use.  
   *   This method will omit the Maestro AI Task's reserved "maestro_ai_task_history" for potential future use.
   *
   * @param  string $templateMachineName  
   *   The template machine name.
   * @param  bool $return_as_options_array  
   *   Default is TRUE -- will return an options array keyed by the name of the variable with value of the variable.  
   *   FALSE will return a simple value array.
   * @return array  
   *   Empty array on failure or absence of storage entities.  Success will be an array with count > 0.  
   */
  public static function getAiStorageEntityDefinitionsInTemplate($templateMachineName, $return_as_options_array = TRUE) {
    $definitions = [];
    $template = MaestroEngine::getTemplate($templateMachineName);
    foreach ($template->tasks as $templateTask) {
      $tasktype = $templateTask['tasktype'] ?? NULL;
      if ($tasktype == 'MaestroAITask') {
        // See if there's any other entities already set.
        $ai_var = $templateTask['ai_return_into_ai_variable'] ?? NULL;
        if ($ai_var && $ai_var != 'maestro_ai_task_history') {
          if($return_as_options_array) {
            $definitions[strval($ai_var)] = $ai_var;
          }
          else {
            $definitions[] = $ai_var;
          }
          
        }
      }
    }
    return $definitions;
  }


  /**
   * createMaestroAiTaskCapabilityPlugin  
   *   Creates and instance of a Maestro AI Task Capability Plugin.  
   *
   * @param  string $selected_ai_provider  
   *   The provider we're trying to instantiate for.  
   * @param  array $config  
   *   Array of config options.  The currently supported options are  
   *    [  
   *      'task' => ..                  // A Maestro Task configuration array  
   *      'templateMachineName' => ...  // The template machine name  
   *      'queueID' => ...              // A queue ID if we're executing  
   *      'processID' => ...            // A process ID if we're executing  
   *      'prompt' => ...               // The AI prompt  
   *      'form_state' => ...           // FormState if required or even available  
   *      'form' => ...                 // The Form array if required or even available  
   *    ]  
   *   
   *   Any config option can be blank/NULL, but that may affect how the capability plugin works.  
   * @return NULL|MaestroAiTaskCapabilitiesInterface  
   *   Returns NULL on failure.  An instance of the Maestro AI Task Capability plugin on success.  
   */
  public static function createMaestroAiTaskCapabilityPlugin($selected_ai_provider, array $config) {
    $maestro_capability = NULL;
    $ai_task_plugin_manager = \Drupal::service('plugin.manager.maestro_ai_task_capabilities');
    $implemented_maestro_ai_task_capabilities = $ai_task_plugin_manager->getDefinitions(); // Array of available Capability plugins we offer.
    $chosen_capability = $implemented_maestro_ai_task_capabilities[$selected_ai_provider] ?? NULL;
    if($chosen_capability) {
      $maestro_capability = $ai_task_plugin_manager->createInstance(
        $selected_ai_provider, 
        $config
      );
    }
    return $maestro_capability;
  }

  /**
   * Get the AI Storage Entity.
   *
   *   Fetches the Maestro AI Task storage entity defined in AI tasks.
   *   This requires the entity's unique_id (machine name) to be provided
   *   to this method as defined in the AI Task.
   *
   * @param string $unique_id
   *   The unique ID/machine_name given to the AI Storage entity in the AI task.
   * @param int $process_id
   *   The process ID this entity lives in.
   *
   * @return Drupal\maestro_ai_task\Entity\MaestroAIStorage[]|null
   *   On success, you'll get an array of MaestroAIStorage entity(ies) fully
   *   loaded. NULL on failure.
   */
  public static function getAiStorageEntityByUniqueId($unique_id, $process_id) {
    $entity = NULL;
    $storage_query = \Drupal::entityTypeManager()->getStorage('maestro_ai_storage')->getQuery()
      ->condition('machine_name', $unique_id)
      ->condition('process_id', $process_id)
      ->accessCheck(FALSE);
    $ai_storage_result = $storage_query->execute();
    if ($ai_storage_result) {
      $entity = MaestroAIStorage::loadMultiple($ai_storage_result);
    }

    return $entity;
  }

  /**
   * Get the Ai Storage Value By UniqueID.
   *
   *   Provide the process ID and the unique machine name for the AI Task's
   *   storage entity and this method will Return to you the value stored.
   *   PLEASE NOTE:  This method will ONLY return values when there is a
   *   singular entity tagged with the machine name provided.
   *   You will get a NULL return when multiple AI Storage entities exist
   *   in the same process with the same machine name.
   *
   * @param mixed $unique_id
   *   The unique ID/machine_name given to the AI Storage entity in the AI task.
   * @param int $process_id
   *   The process ID this entity lives in.
   * @param string $data_array_key
   *   Optional.  The data arary key that holds the output you're after.  By default, Maestro AI Task saves
   *   The data in a 'response' key.  Unless you specify otherwise, this is the key that is returned.  
   * 
   * @return string|null
   *   On success, this will return the value stored by the AI storage entity.
   *   Else, NULL.
   */
  public static function getAiStorageValueByUniqueId($unique_id, $process_id, $data_array_key = 'response') {
    $return_value = NULL;
    $ai_storage_entities = self::getAiStorageEntityByUniqueId($unique_id, $process_id);
    if (count($ai_storage_entities) == 1) {
      /** @var \Drupal\maestro_ai_task\Entity\MaestroAIStorage $aiEntity */
      $aiEntity = current($ai_storage_entities);
      $saved_value = $aiEntity->ai_storage->getValue() ?? NULL;
      if ($saved_value) {
         if(array_key_exists($data_array_key, $saved_value[0])) {
          $return_value = $saved_value[0][$data_array_key];
        }
        else { // Otherwise, return the whole array/blob
          $return_value = $saved_value[0];
        }
      }
    }
    return $return_value;
  }

  /**
   * Convert a base64 AI Storage entity to an Image file.
   *
   *   If you have an image stored in the Maestro AI Storage entity as base64, 
   *   use this method to extract it to a physical file and place it on the disk.
   *
   *   Default filename created will be:
   *   sites/default/files/private/ai_image-[UNIQUE_ID]-[PROCESS_ID].[extension]
   *   Where
   *     [UNIQUE_ID] is the unique ID for the Maestro AI Entity you configured
   *     in your Maestro AI task.
   *     [PROCESS_ID] is the process ID the image was associated with.
   *     [extension] is automatically generated from the base_64 decoded
   *     stored data.
   *
   * @param string $unique_id
   *   The unique ID/machine_name given to the AI Storage entity in the AI task.
   * @param mixed $process_id
   *   The process ID this entity lives in.
   * @param string $file_path_base
   *   [optional] Where you'd like to store the file. Defaults to the PRIVATE
   *   files folder with a filename of
   *   ai_image-[UNIQUEID]-[PROCESSID].[IMAGEEXTENSION]
   *   Please note, if the image extension cannot be determined, the extension will be "unknown".
   *
   * @return array
   *   Returns an empty array on failure.
   *   Returns an array with 2 keys on success:
   *   file => the file path, mime_type => the mime type of the image
   */
  public static function convertBase64AiStorageImageToFile($unique_id, $process_id, $file_path_base = NULL) {
    $return_array = [];
    // Default extension is unknown.
    $extension = 'unknown';
    // Default mime type is unknown.
    $mime_type = 'unknown';
    $image_string = self::getAiStorageValueByUniqueID($unique_id, $process_id);
    if ($image_string) {
      $return_array = self::saveBase64ImageToFile($image_string, $file_path_base, $unique_id, $process_id);
    }

    return $return_array;
  }
  
  /**
   * saveBase64ImageToFile  
   * 
   *   This method will take a base64 encoded image string and save it to a file.  
   *   This method differs from the convertBase64AiStorageImageToFile method in that
   *   as this method requires the image string to be passed in directly.
   * 
   *   If you do not provide a file_path_base, the unique ID and process ID are used to create 
   *   the filename.  The file is saved to the private files directory.
   *
   * @param  mixed $image_string  
   *   The base64 encoded image string to be saved.
   * @param  mixed $file_path_base  
   *   The base path to save the file to.  If not provided, the private files directory
   *   will be used, using the unique ID and process ID to create the filename.  
   * @param  mixed $unique_id  
   *   The unique ID/machine_name given to the AI Storage entity in the AI task.  
   * @param  mixed $process_id  
   *   The process ID this entity lives in.  
   * @return array  
   *   Returns an empty array on failure.  Otherwise an array with 2 keys:
   *   file => the file path, mime_type => the mime type of the image
   */
  public static function saveBase64ImageToFile($image_string, $file_path_base = NULL, $unique_id = NULL, $process_id = NULL) {
    $return_array = [];
    // Get the extension and remove the preamble (if it exists)
    if (preg_match('/^data:image\/(\w+);base64,/', $image_string, $matches)) {
      // Extract format (e.g., png, jpeg, webp)
      $extension = $matches[1];
      $mime_type = 'image/' . $extension;
      $image_string = substr($image_string, strpos($image_string, ',') + 1);
    }
    $image_data = base64_decode($image_string);
    if (!$file_path_base) {
      // We use a predefined private files path.
      // If this fails, good chance that the private files path doesn't exist.
      if(empty($unique_id)) {
        $unique_id = 'no-unique-id';
      }
      if(empty($process_id)) {
        $process_id = 'no-process-id';
      }
      $file_path = 'private://ai-image-' . $unique_id . '-' . $process_id . '.' . $extension;
      $file_path = \Drupal::service('file_system')->realpath($file_path);
    }
    else {
      $file_path = $file_path_base;
    }

    // Suppress the file_put_contents warning when the file location
    // can't be found.
    // We handle this as a blank array return and avoids warnings showing.
    if (@file_put_contents($file_path, $image_data)) {
      $return_array = [
        'file' => $file_path,
        'mime_type' => $mime_type,
      ];
    }
    else {
      // Likely due to the private files folder (or the folder passed in)
      // doesn't exist or hasn't been configured.
      \Drupal::logger('Maestro AI API')->error(t('Unable to save file to the location specified. :file', [':file' => $file_path]));
    }

    return $return_array;
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc