elevenlabs_field-1.0.0-beta7/modules/ai_interpolator_elevenlabs_field/src/Plugin/AiInterpolatorFieldRules/ElevenLabsDialogue.php
modules/ai_interpolator_elevenlabs_field/src/Plugin/AiInterpolatorFieldRules/ElevenLabsDialogue.php
<?php namespace Drupal\ai_interpolator_elevenlabs_field\Plugin\AiInterPolatorFieldRules; use Drupal\ai_interpolator\PluginInterfaces\AiInterpolatorFieldRuleInterface; use Drupal\ai_interpolator_openai\OpenAiBase; use Drupal\ai_interpolator_openai\OpenAiRequester; use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\elevenlabs_field\ElevenLabsApiService; use Drupal\elevenlabs_field\ElevenLabsGenerateService; use Symfony\Component\DependencyInjection\ContainerInterface; /** * The rules for a ElevenLabs Field. * * @AiInterpolatorFieldRule( * id = "ai_interpolator_elevenlabs_dialogue", * title = @Translation("ElevenLabs Dialogue Creator"), * field_rule = "elevenlabs", * target = "file", * ) */ class ElevenLabsDialogue extends OpenAiBase implements AiInterpolatorFieldRuleInterface, ContainerFactoryPluginInterface { /** * {@inheritDoc} */ public $title = 'ElevenLabs Dialogue Creator'; /** * The elevenLabs requester. */ public ElevenLabsApiService $elevenLabs; /** * The Open AI requester. */ public OpenAiRequester $openAi; /** * The elevenlabs generator. */ public ElevenLabsGenerateService $generator; /** * Construct an image field. * * @param array $configuration * Inherited configuration. * @param string $plugin_id * Inherited plugin id. * @param mixed $plugin_definition * Inherited plugin definition. * @param \Drupal\elevenlabs_field\ElevenLabsApiService $elevenLabs * The elevenlabs requester. * @param \Drupal\ai_interpolator_openai\OpenAiRequester $openAi * The OpenAI requester. * @param \Drupal\elevenlabs_field\ElevenLabsGenerateService $generator * The elevenlabs generator. */ public function __construct( array $configuration, $plugin_id, $plugin_definition, ElevenLabsApiService $elevenLabs, OpenAiRequester $openAi, ElevenLabsGenerateService $generator ) { parent::__construct($configuration, $plugin_id, $plugin_definition, $openAi); $this->elevenLabs = $elevenLabs; $this->openAi = $openAi; $this->generator = $generator; } /** * {@inheritDoc} */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { return new static( $configuration, $plugin_id, $plugin_definition, $container->get('elevenlabs_field.api_service'), $container->get('ai_interpolator_openai.request'), $container->get('elevenlabs_field.generator_service') ); } /** * {@inheritDoc} */ public function needsPrompt() { return TRUE; } /** * {@inheritDoc} */ public function advancedMode() { return TRUE; } /** * {@inheritDoc} */ public function placeholderText() { return "Based on the context text create a dialogue between podcast interviewer Richard Ayoade who is a fun loving character and Julia Stipes who is a serious guest expert on the topic and answering the questions. Start with an introduction and created 10 dialogues back and forth and then end with a thank you to the guest. The elevenlabs voices to use are: Richard Ayoade = {{ clyde }} Julia Stipes = {{ rachel }} Context: {{ context }}"; } /** * {@inheritDoc} */ public function tokens() { $voices = $this->elevenLabs->getVoices(); $tokens = [ 'context' => 'The cleaned text from the base field.', 'raw_context' => 'The raw text from the base field. Can include HTML', 'max_amount' => 'The max amount of entries to set. If unlimited this value will be empty.', ]; foreach ($voices['voices'] as $voices) { $tokens[strtolower($voices['name'])] = $this->t('Voice of %name', ['%name' => $voices['name']]); } return $tokens; } /** * {@inheritDoc} */ public function extraAdvancedFormFields(ContentEntityInterface $entity, FieldDefinitionInterface $fieldDefinition) { $form['interpolator_openai_model'] = [ '#type' => 'select', '#title' => 'OpenAI Model', '#description' => $this->t('Choose the model you want to use here.'), '#options' => $this->openAi->getModels(), '#default_value' => $fieldDefinition->getConfig($entity->bundle())->getThirdPartySetting('ai_interpolator', 'interpolator_openai_model', 'gpt-3.5-turbo-0613'), '#weight' => 24, ]; $form['interpolator_openai_role'] = [ '#type' => 'textarea', '#title' => 'OpenAI Role', '#description' => $this->t('If the AI should have some specific role, write it here.'), '#attributes' => [ 'placeholder' => $this->t('You are an OSK assistant helping with coming up with company party ideas.'), ], '#default_value' => $fieldDefinition->getConfig($entity->bundle())->getThirdPartySetting('ai_interpolator', 'interpolator_openai_role', ''), '#weight' => 25, ]; return $form; } /** * {@inheritDoc} */ public function generateTokens(ContentEntityInterface $entity, FieldDefinitionInterface $fieldDefinition, array $interpolatorConfig, $delta = 0) { $tokens = parent::generateTokens($entity, $fieldDefinition, $interpolatorConfig); $voices = $this->elevenLabs->getVoices(); foreach ($voices['voices'] as $voices) { $tokens[strtolower($voices['name'])] = $voices['voice_id']; } return $tokens; } /** * {@inheritDoc} */ public function generate(ContentEntityInterface $entity, FieldDefinitionInterface $fieldDefinition, array $interpolatorConfig) { $prompts = parent::generate($entity, $fieldDefinition, $interpolatorConfig); // Add to get functional output. $total = []; // Add to get functional output. foreach ($prompts as $prompt) { $prompt .= "\n\nDo not include any explanations, only provide a RFC8259 compliant JSON response following this format without deviation. [ {\"value\": {\"speaker\": \"The name of the speaker\",\"speaker_id\": \"The id of the speaker\",\"text\": \"The dialogue\"}}, {\"value\": {\"speaker\": \"The name of the speaker\",\"speaker_id\": \"The id of the speaker\",\"text\": \"The dialogue\"}} ] An example of a 3 dialogue output would be: [ {\"value\": {\"speaker\": \"Jonas Nilsson\",\"speaker_id\": \"ThT5KcBeYPX3keUQqHPh\",\"text\": \"Hello and welcome to the show Jenny!\"}}, {\"value\": {\"speaker\": \"Jenny Moore\",\"speaker_id\": \"flq6f7yk4E4fJM5XTYuZ\",\"text\": \"Thank you Jonas, it's nice to be here.\"}}, {\"value\": {\"speaker\": \"Jonas Nilsson\",\"speaker_id\": \"ThT5KcBeYPX3keUQqHPh\",\"text\": \"I would like to start with asking you about tomorrows weather?\"}} ]"; try { $values = $this->openAi->generateResponse($prompt, $fieldDefinition, $interpolatorConfig); $total = array_merge_recursive($total, $values); } catch (\Exception $e) { } } return $total; } /** * {@inheritDoc} */ public function verifyValue(ContentEntityInterface $entity, $value, FieldDefinitionInterface $fieldDefinition) { // Validate. if (empty($value['speaker']) && empty($value['speaker_id']) && empty($value['text'])) { return FALSE; } // Otherwise it is ok. return TRUE; } /** * {@inheritDoc} */ public function storeValues(ContentEntityInterface $entity, array $values, FieldDefinitionInterface $fieldDefinition) { // Transform string to stripped. foreach ($values as $key => $value) { // We need to generate right away, since presave does not always invoke. $data = $this->generator->generateFile($value['text'], $value['speaker_id'], $fieldDefinition, 'eleven_multilingual_v2', [ 'stability' => 1, 'similarity_boost' => 0.75, 'style_exaggeration' => 0, ]); if (!empty($data['file'])) { $values[$key] = [ 'target_id' => $data['file']->id(), 'history_item_id' => $data['history_item_id'], 'text' => $value['text'], 'speaker' => $value['speaker_id'], 'start_time' => 0, 'similarity_boost' => 0.75, 'style_exaggeration' => 0, 'stability' => 1, ]; } } // Then set the value. $entity->set($fieldDefinition->getName(), $values); } }