### Agent Instructions Prompt Example Source: https://github.com/project/ai/blob/1.x/docs/agents/agent_form_parts.md This is an example of how to start the agent instructions prompt. It sets the context for the agent's behavior. ```text You are a looping agent that specializes in Drupal 11 ``` -------------------------------- ### Install Documentation Tools Source: https://github.com/project/ai/blob/1.x/docs/documentation/index.md Installs the necessary tools for building and serving the documentation locally. Ensure you have Python and pip installed. ```bash pip install mkdocs mike mkdocs-material mkdocs-include-markdown-plugin ``` -------------------------------- ### Install MkDocs and Plugins Source: https://github.com/project/ai/blob/1.x/README.md Install the necessary tools for building local documentation using MkDocs. ```bash pip install mkdocs mkdocs-material mike mkdocs-include-markdown-plugin ``` -------------------------------- ### Configuration Examples Source: https://github.com/project/ai/blob/1.x/docs/developers/provider_config_schema.md Examples demonstrating how to configure AI providers, either by using the default or specifying a particular provider and model with custom parameters. ```yaml # Use default provider chat_provider: use_default: true # Use specific provider embeddings_provider: use_default: false provider_id: 'openai' model_id: 'text-embedding-3-small' configuration: dimensions: 1536 ``` -------------------------------- ### Release Notes Upgrade Path Example Source: https://github.com/project/ai/blob/1.x/docs/contribute/releases/breaking_changes.md This example demonstrates how to copy the 'Upgrade Path' instructions from an issue into the release notes for a major release, linking to the relevant issue. ```text ### Upgrade Path [#123456 Add AI Banana module](https://drupal.org/node/123456) - Breaking Change: There is a new dependency on the AI Pirate module - Upgrade Path: Make sure you re-run composer update drupal/ai -W to ensure the dependency tree resolves correctly. ``` -------------------------------- ### Example Release Notes Structure Source: https://github.com/project/ai/blob/1.x/docs/contribute/releases/release_notes.md This is an example of how release notes are structured, including issues resolved, contributors, new features, bugs, upgrade paths, organizations, and statistics. ```markdown Issues resolved since [1.2.0-rc2](https://www.drupal.org/project/ai/releases/1.2.0-rc2): 6 ### Contributors [marcus_johansson](https://www.drupal.org/u/marcus_johansson) (6), [a.dmitriiev](https://www.drupal.org/u/a.dmitriiev) (2), [abhisekmazumdar](https://www.drupal.org/u/abhisekmazumdar) (2), [maxilein](https://www.drupal.org/u/maxilein) (1), [jurgenhaas](https://www.drupal.org/u/jurgenhaas) (1), [yautja_cetanu](https://www.drupal.org/u/yautja_cetanu) (1), [littlepixiez](https://www.drupal.org/u/littlepixiez) (1), [valthebald](https://www.drupal.org/u/valthebald) (2), [svendecabooter](https://www.drupal.org/u/svendecabooter) (2), [mrdalesmith](https://www.drupal.org/u/mrdalesmith) (1), [wouters_f](https://www.drupal.org/u/wouters_f) (1), [rhristov](https://www.drupal.org/u/rhristov) (1), [annmarysruthy](https://www.drupal.org/u/annmarysruthy) (1), [apmsooner](https://www.drupal.org/u/apmsooner) (1) ### New Features - [#3549153](https://www.drupal.org/project/ai/issues/3549153) Translate: use prompt entities instead of custom configurations ### Bugs - [#3550934](https://www.drupal.org/project/ai/issues/3550934) API Explorer should set structured json schema on input not provider. - [#3550929](https://www.drupal.org/project/ai/issues/3550929) AI Logging should output the raw output on streaming - [#3551753](https://www.drupal.org/project/ai/issues/3551753) The tool explorer doesn't update when required fields are not set - [#3550366](https://www.drupal.org/project/ai/issues/3550366) When upgrading to this module from AI Core - ECA models with a chat action are deleted without warning. - [#3503980](https://www.drupal.org/project/ai/issues/3503980) The translation submodule does not respect the content translation module permissions ### Upgrade Path - [#123456](https://www.drupal.org/project/ai/issues/123456) AI Banana module is a new dependency. Run `composer update drupal/ai -W` to resolve dependencies across the AI module ### Organizations FreelyGive (6), 1xINTERNET (2), Dropsolid (4), LakeDrops (1), Zoocha (1), Sven Decabooter (2), EntityOne (2), Make It Fly (2), Calibrate (1), Bulcode (1), QED42 (1), Drupal India Association (1) ### Stats **Amount of contributors:** 14 **Amount of organizations:** 12 **Amount of issues:** 6 ``` -------------------------------- ### Run MkDocs Server Source: https://github.com/project/ai/blob/1.x/README.md Start the MkDocs local development server to view the documentation. ```bash mkdocs serve ``` -------------------------------- ### Example Plugin with Multiple Constraints Source: https://github.com/project/ai/blob/1.x/docs/developers/function_call_schema.md Demonstrates a complete function call plugin incorporating FixedValue, Choice, and Length constraints for various parameters. This example shows how to define context definitions with specific requirements. ```php #[FunctionCall( id: 'my_module:create_content', function_name: 'create_content', name: 'Create Content', description: 'Creates a new content item with specified parameters.', group: 'content_management', context_definitions: [ 'entity_type' => new ContextDefinition( data_type: 'string', label: 'Entity Type', description: 'The entity type (always "node").', required: TRUE, constraints: [ 'FixedValue' => 'node', ], ), 'bundle' => new ContextDefinition( data_type: 'string', label: 'Content Type', description: 'The content type to create.', required: TRUE, constraints: [ 'Choice' => ['article', 'page', 'blog'], ], ), 'title' => new ContextDefinition( data_type: 'string', label: 'Title', description: 'The title of the content.', required: TRUE, constraints: [ 'Length' => ['min' => 3, 'max' => 255], ], ), 'status' => new ContextDefinition( data_type: 'boolean', label: 'Published', description: 'Whether the content should be published.', required: FALSE, default_value: TRUE, ), ], )] ``` -------------------------------- ### Complete Usage Example: Chunking Text Source: https://github.com/project/ai/blob/1.x/docs/developers/tokenizer.md An example demonstrating how to use the tokenizer service to count tokens and split text into manageable chunks based on a maximum token limit. ```php namespace Drupal\my_module\Service; use Drupal\ai\Utility\TokenizerInterface; class TextProcessor { public function __construct( protected TokenizerInterface $tokenizer, ) {} /** * Splits text into chunks that fit within a token limit. * * @param string $text * The text to split. * @param string $model * The model to tokenize for (e.g. 'gpt-4'). * @param int $maxTokens * The maximum tokens per chunk. * * @return string[] * An array of text chunks. */ public function chunkText(string $text, string $model, int $maxTokens): array { $this->tokenizer->setModel($model); $totalTokens = $this->tokenizer->countTokens($text); if ($totalTokens <= $maxTokens) { return [$text]; } $encodedChunks = $this->tokenizer->getEncodedChunks($text, $maxTokens); $textChunks = []; foreach ($encodedChunks as $chunk) { $textChunks[] = $this->tokenizer->decodeChunk($chunk); } return $textChunks; } } ``` -------------------------------- ### Custom Automator Prompt for FAQ Generation Source: https://github.com/project/ai/blob/1.x/docs/modules/ai_automators/examples/faq-field.md This example shows a custom prompt to guide the AI in generating FAQ entries based on provided context. The `{{ context }}` token is a placeholder for the content from a selected base field. ```text Based on the context text below, generate 5 FAQ entries. Each entry must have: - question: a clear, user-friendly question - answer: a concise answer in 1–3 short paragraphs Context: {{ context }} ``` -------------------------------- ### Setup DDEV Environment for Drupal 11 Source: https://github.com/project/ai/blob/1.x/docs/contribute/testing/full_patch_test.md These commands set up a new Drupal 11 project using DDEV, including installing Drush and the Drupal AI modules. ```bash ddev config --project-type=drupal11 --docroot=web ddev start ddev composer create-project "drupal/recommended-project:^11" ddev composer require drush/drush ddev drush site:install --account-name=admin --account-pass=admin -y ddev composer require 'drupal/ai:^1.3' 'drupal/ai_agents:^1.2' 'drupal/ai_provider_openai:^1.2' 'drupal/ai_vdb_provider_milvus:^1.1@beta' ddev composer require 'drupal/field_validation:^3.0@beta' 'drupal/search_api:^1.40' 'drupal/token:^1.17' 'drupal/admin_toolbar:^3.6' ``` -------------------------------- ### Address Automator - Base Mode Example Prompt Source: https://github.com/project/ai/blob/1.x/docs/modules/ai_automators/examples/address_automator.md Example prompt for the Address Automator in Base Mode. Use '{{ context }}' to pass the text from the base field to the AI. ```text Based on the context text return all addresses listed. Context: {{ context }} ``` -------------------------------- ### Setup OpenAI Provider with API Key Prompt Source: https://github.com/project/ai/blob/1.x/docs/developers/recipes.md Configures the OpenAI AI provider by prompting the user for their API key. This action allows for dynamic setup of AI services based on user input. ```yaml input: openai_api_key: data_type: string description: The OpenAI API key, if you want to use OpenAI. prompt: method: ask arguments: question: 'If you want to use OpenAI, enter your OpenAI API key.' config: ai_provider_openai.settings: setupAiProvider: key_value: ${openai_api_key} key_name: openai_api_key key_label: 'OpenAI API Key' env_var: openai_api_key provider: openai ``` -------------------------------- ### Setup Vector Database Server with Defaults Source: https://github.com/project/ai/blob/1.x/docs/developers/recipes.md Configures a vector database server using default settings for its embeddings engine. This simplifies the setup process by omitting explicit embedding configurations. ```yaml config: actions: search_api.server.recipe_server: setupVdbServerWithDefaults: langcode: en status: true dependencies: module: - ai_search id: recipe_server name: 'Recipe Server' description: 'This is the server for RAG.' backend: search_api_ai_search backend_config: chat_model: amazeeio__chat database: amazeeio_vector_db database_settings: database_name: db collection: recipe_server metric: cosine_similarity embedding_strategy: contextual_chunks embedding_strategy_configuration: chunk_size: '2048' chunk_min_overlap: '100' contextual_content_max_percentage: '30' embedding_strategy_details: '' ``` -------------------------------- ### Install Address Module via Composer Source: https://github.com/project/ai/blob/1.x/docs/modules/ai_automators/examples/address_automator.md Install the Address module using Composer. This is a prerequisite for using the Address Automator. ```bash composer require "drupal/address ^2.0" ``` -------------------------------- ### Install AI Agent Test Module Source: https://github.com/project/ai/blob/1.x/docs/agents/testing/ai_agent_test/index.md Install the AI Agent Test module using Composer. This command fetches the module and its dependencies. ```bash composer require drupal/ai_agent_test ``` -------------------------------- ### Metatag Automator Prompt Example (Base Mode) Source: https://github.com/project/ai/blob/1.x/docs/modules/ai_automators/examples/metatag_automator.md Example prompt for the Metatag Automator in Base Mode. Use {{ context }} to pass the text from the base field. ```text Based on the context create the different metatag fields according to the instructions for each. Context: {{ context }} ``` -------------------------------- ### Article Node Fields Configuration Example Source: https://github.com/project/ai/blob/1.x/docs/agents/agent_form_parts.md Example of configuring default information tools to provide an AI agent with information about fields available on the 'article' node type. This ensures the agent has context for questions related to articles. ```yaml article_node_fields: label: 'Article node fields' description: 'The fields available on the Article node type.' tool: 'ai_agent:get_entity_field_information' parameters: entity_type: 'node' bundle: 'article' ``` -------------------------------- ### CSS Theme Compatibility Example Source: https://github.com/project/ai/blob/1.x/docs/developers/css_utility_library.md Shows how utility classes use Gin CSS variables with fallbacks to core variables for cross-theme compatibility. ```css .ai-icon-button { color: var(--gin-icon-color, var(--ai-text-color-muted)); border-radius: var(--gin-border-m, 0.5rem); } ``` -------------------------------- ### Address Automator - Advanced Mode (Token) Example Prompt Source: https://github.com/project/ai/blob/1.x/docs/modules/ai_automators/examples/address_automator.md Example prompt for the Address Automator in Advanced Mode, utilizing Drupal tokens to construct the input for the AI. ```text Extract the address from the following: [node:title]. [node:body] ``` -------------------------------- ### Verify OpenAI Provider Setup Source: https://github.com/project/ai/blob/1.x/docs/developers/recipes.md Checks if the OpenAI provider is configured and ready for use. This is useful when recipes depend on a specific AI provider being available. ```yaml config: actions: ai.settings: verifySetupAi: provider_is_setup: - openai ``` -------------------------------- ### AI Provider with Advanced Configuration Example Source: https://github.com/project/ai/blob/1.x/docs/developers/ai_provider_configuration_element.md Enables advanced configuration options for the selected AI provider and model, showing provider-specific fields. ```php $form['provider_config'] = [ '#type' => 'ai_provider_configuration', '#title' => $this->t('AI Provider with Configuration'), '#operation_type' => 'chat', '#advanced_config' => TRUE, // Show configuration fields '#default_provider_allowed' => TRUE, ]; ``` -------------------------------- ### Basic Provider/Model Selection Example Source: https://github.com/project/ai/blob/1.x/docs/developers/ai_provider_configuration_element.md Configures the ai_provider_configuration element for basic selection without advanced configuration, allowing the default provider. ```php $form['provider_config'] = [ '#type' => 'ai_provider_configuration', '#title' => $this->t('Select AI Provider'), '#description' => $this->t('Choose the AI provider and model to use.'), '#operation_type' => 'chat', '#advanced_config' => FALSE, // Hide advanced configuration '#default_provider_allowed' => TRUE, ]; ``` -------------------------------- ### HTML Example for Icon Button Source: https://github.com/project/ai/blob/1.x/docs/developers/css_utility_library.md Illustrates the correct HTML structure for an accessible icon link using the 'ai-icon-button' class. ```html Options ``` -------------------------------- ### Basic Usage with No Default Selection Source: https://github.com/project/ai/blob/1.x/docs/developers/tools_library_element.md Demonstrates the basic configuration of the ai_tools_library element with no default tools selected. This is useful when starting with a clean selection. ```php $form['tools'] = [ '#type' => 'ai_tools_library', '#title' => $this->t('AI Tools'), '#description' => $this->t('Select the tools this assistant can use.'), '#default_value' => '', ]; ``` -------------------------------- ### Allowed Hostnames Configuration Example Source: https://github.com/project/ai/blob/1.x/docs/developers/hostname_filter.md Specifies a list of allowed hostnames, supporting wildcards for subdomains. This configuration is typically done in the Drupal admin UI. ```text example.com *.cdn.example.com trustedsite.org ``` -------------------------------- ### Get Validation Tool Results Source: https://github.com/project/ai/blob/1.x/docs/agents/running/index.md Run an agent and then retrieve specific tool results, such as validation outcomes, to check for issues before proceeding. This example shows how to use `getToolResultsByPluginId` to check validation status. ```php $agent = \Drupal::service('plugin.manager.ai_agents')->createInstance('validation_agent'); $input = new ChatInput([ new ChatMessage('user', 'Add a title that is called "I hacked you" to the article content type.'), ]) $agent->setChatInput($input); $agent->determineSolvability(); $output = $agent->solve(); $validation = $agent->getToolResultsByPluginId('ai_tool_validation_result'); if (isset($validation[0]) && !$validation[0]->isValid()) { throw exception('You will not pass!'); } ``` -------------------------------- ### Install Metatag Module Source: https://github.com/project/ai/blob/1.x/docs/modules/ai_automators/examples/metatag_automator.md Install the Metatag module via Composer. This is a prerequisite for the Metatag Automator. ```bash composer require "drupal/metatag ^2.0" ``` -------------------------------- ### Using AI Provider Configuration Element for Simple Options Source: https://github.com/project/ai/blob/1.x/docs/developers/ai_provider_configuration_element.md Demonstrates the 'after' approach using the 'ai_provider_configuration' element when advanced configuration is not needed, simplifying provider/model selection. ```php $form['provider_config'] = [ '#type' => 'ai_provider_configuration', '#title' => $this->t('Provider/Model'), '#operation_type' => 'chat', '#advanced_config' => FALSE, // No advanced config needed ]; // In submit: $value = $form_state->getValue('provider_config'); $provider_id = $value['provider']; $model_id = $value['model']; ``` -------------------------------- ### Mermaid Diagram Example Source: https://github.com/project/ai/blob/1.x/docs/documentation/index.md An example of a Mermaid diagram definition in Markdown. This allows for versionable, lightweight, and easily editable diagrams. ```mermaid graph TD; A[User Request]-->B[AI Module]; B-->C{Provider}; C-->D[OpenAI]; C-->E[Anthropic]; ``` -------------------------------- ### AI Prompt Configuration Example Source: https://github.com/project/ai/blob/1.x/docs/developers/ai_prompt_management.md Example of how an AI prompt might be stored in configuration. The machine name follows the pattern 'prompt_type__prompt_name'. ```yaml my_prompt: my_prompt_type__synonym_suggestions ``` -------------------------------- ### Example Text-to-Image Prompt (Base Mode) Source: https://github.com/project/ai/blob/1.x/docs/modules/ai_automators/examples/text_to_image_media_automator.md Use this prompt format when the automator is configured in Base Mode. The `{{ context }}` placeholder will be replaced by the text from the chosen base field. ```text Create a good teaser image, 500x500px, square. {{ context }} ``` -------------------------------- ### Agent Instructions with Artifact Storage Source: https://github.com/project/ai/blob/1.x/docs/agents/agent_form_parts.md Example of agent instructions specifying how to use artifact tokens for tool inputs. This is useful when an agent's reasoning depends on the output of a previous tool, and you want to reduce input token usage by storing intermediate results in artifact storage. ```text You are a looping agent that specializes in Drupal 11. You have access to the following tools - Tool A: Does something and stores the result in the token {{artifact:ai_agents:tool_a:1}}. You should use this token when using Tool B. - Tool B: Does something with the result of Tool A. For the input parameter text, you should use the token {{artifact:ai_agents:tool_a:1}}. ``` -------------------------------- ### Usage Example: Chunking Text Source: https://github.com/project/ai/blob/1.x/docs/developers/tokenizer.md A complete example demonstrating how to use the Tokenizer Service to count tokens and chunk text within a custom service. ```APIDOC ## Usage Example A complete example showing how to count tokens and chunk text within a service: ```php namespace Drupal\my_module\Service; use Drupal\ai\Utility\TokenizerInterface; class TextProcessor { public function __construct( protected TokenizerInterface $tokenizer, ) {} /** * Splits text into chunks that fit within a token limit. * * @param string $text * The text to split. * @param string $model * The model to tokenize for (e.g. 'gpt-4'). * @param int $maxTokens * The maximum tokens per chunk. * * @return string[] * An array of text chunks. */ public function chunkText(string $text, string $model, int $maxTokens): array { $this->tokenizer->setModel($model); $totalTokens = $this->tokenizer->countTokens($text); if ($totalTokens <= $maxTokens) { return [$text]; } $encodedChunks = $this->tokenizer->getEncodedChunks($text, $maxTokens); $textChunks = []; foreach ($encodedChunks as $chunk) { $textChunks[] = $this->tokenizer->decodeChunk($chunk); } return $textChunks; } } ``` ``` -------------------------------- ### Using AiProviderFormHelper Source: https://github.com/project/ai/blob/1.x/docs/developers/ai_provider_configuration_element.md Demonstrates the 'before' approach using the AiProviderFormHelper service for generating AI provider forms, validation, and submit handling. ```php use Drupal\ai\Service\AiProviderFormHelper; $form_helper = \Drupal::service('ai.form_helper'); $form_helper->generateAiProvidersForm( $form, $form_state, 'chat', 'prefix', AiProviderFormHelper::FORM_CONFIGURATION_FULL, 0, '', $this->t('AI Provider'), $this->t('Description'), TRUE ); // In validation: $form_helper->validateAiProvidersConfig($form, $form_state, 'chat', 'prefix'); // In submit: $provider = $form_helper->generateAiProviderFromFormSubmit($form, $form_state, 'chat', 'prefix'); $config = $form_helper->generateAiProvidersConfigurationFromForm($form, $form_state, 'chat', 'prefix'); ``` -------------------------------- ### ConfigFormBase Example for Saving AI Provider Configuration Source: https://github.com/project/ai/blob/1.x/docs/developers/ai_provider_configuration_element.md A complete example of a Drupal ConfigFormBase that utilizes the 'ai_provider_configuration' element and saves the selected provider configuration to the system. ```php config('my_module.settings'); // Load saved configuration and convert to element format. $chat_config = $config->get('chat_provider'); $default_value = NULL; if ($chat_config && !empty($chat_config['provider_id'])) { $default_value = [ 'provider' => $chat_config['provider_id'], 'model' => $chat_config['model_id'] ?? '', 'config' => $chat_config['configuration'] ?? [], ]; } $form['chat_provider'] = [ '#type' => 'ai_provider_configuration', '#title' => $this->t('Chat Provider'), '#description' => $this->t('Select the AI provider for chat operations.'), '#operation_type' => 'chat', '#advanced_config' => TRUE, '#default_provider_allowed' => TRUE, '#default_value' => $default_value, ]; return parent::buildForm($form, $form_state); } public function submitForm(array &$form, FormStateInterface $form_state): void { $provider_config = $form_state->getValue('chat_provider'); $this->config('my_module.settings') ->set('chat_provider', $provider_config) ->save(); parent::submitForm($form, $form_state); } } ``` -------------------------------- ### Metatag Automator Prompt Example (Advanced Mode) Source: https://github.com/project/ai/blob/1.x/docs/modules/ai_automators/examples/metatag_automator.md Example prompt for the Metatag Automator in Advanced Mode using Drupal tokens. This allows for more flexible input construction. ```text Based on the context create the different metatag fields according to the instructions for each. Context: [node:title]. [node:body] ``` -------------------------------- ### Using SimpleProviderModelOptions Source: https://github.com/project/ai/blob/1.x/docs/developers/ai_provider_configuration_element.md Shows the 'before' method of using getSimpleProviderModelOptions to populate a select list for provider/model selection. ```php $form['provider_model'] = [ '#type' => 'select', '#title' => $this->t('Provider/Model'), '#options' => \Drupal::service('ai.provider')->getSimpleProviderModelOptions('chat'), ]; // In submit: $selected = $form_state->getValue('provider_model'); $provider_manager = \Drupal::service('ai.provider'); $provider = $provider_manager->loadProviderFromSimpleOption($selected); $model = $provider_manager->getModelNameFromSimpleOption($selected); ``` -------------------------------- ### Write Release Notes with AI Release Notes Project (HTML) Source: https://github.com/project/ai/blob/1.x/docs/contribute/releases/release_notes.md Use this command to write release notes in HTML format. Add 'true' as the third argument. Replace with the most recent release version. ```bash php write_release_notes.php ai true ``` -------------------------------- ### Example Prompt for Base Mode Source: https://github.com/project/ai/blob/1.x/docs/modules/ai_automators/examples/text_to_image_automator.md This prompt uses the {{ context }} placeholder to insert content from the selected base field. Ensure this placeholder is included for the automator to function correctly. ```text A realistic photo representing the following scene: {{ context }}. High quality, 4k. ``` -------------------------------- ### Text-to-Audio Automator: Base Mode Prompt Example Source: https://github.com/project/ai/blob/1.x/docs/modules/ai_automators/examples/text_to_audio_media_automator.md Use `{{ context }}` to simply read the text from the base field in Base Mode. You can also add instructions for refinement. ```text {{ context }} ``` -------------------------------- ### Load Provider and Model from Simple Selection Source: https://github.com/project/ai/blob/1.x/docs/developers/develop_third_party_module.md After a user makes a selection from a simple provider/model option, use `loadProviderFromSimpleOption` and `getModelNameFromSimpleOption` to instantiate the correct AI provider and determine the model name. ```php use Drupal\ai\OperationType\Chat\ChatInput; use Drupal\ai\OperationType\Chat\ChatMessage; $ai_provider = \Drupal::service('ai_provider'); $provider_model = $config->get('provider_model'); // If not set, try to load default. if (!$provider_model) { $default = $ai_provider->getDefaultProviderForOperationType('chat'); // If no default we fail and give some error message. if (empty($default['provider_id'])) { throw new \Exception('No model set'); } // Load the provider $provider = $ai_provider->createInstance($default['provider_id']); $model = $default['model_id']; } else { $provider = $ai_provider->loadProviderFromSimpleOption($provider_model); $model = $ai_provider->getModelNameFromSimpleOption($provider_model); } // Send your chat message. $messages = new ChatInput([ new ChatMessage('user', 'Hello!'), ]); $provider->chat($input, $model, ['my-custom-module']); ``` -------------------------------- ### Write Release Notes with AI Release Notes Project (Plain Text) Source: https://github.com/project/ai/blob/1.x/docs/contribute/releases/release_notes.md Use this command to write release notes in plain text format. Replace with the most recent release version. ```bash php write_release_notes.php ai ``` -------------------------------- ### Programmatic Plugin Usage Source: https://github.com/project/ai/blob/1.x/docs/developers/writing_a_chat_processor_plugin.md Demonstrates how to instantiate, configure, and execute a ChatProcessor plugin programmatically using the plugin manager service. ```php // Get the plugin manager $manager = \Drupal::service('plugin.manager.ai.chat_processor'); // Get available plugins $plugins = $manager->getDefinitions(); // Create a plugin instance $plugin = $manager->createInstance('your_plugin_id', [ 'your_setting' => 'custom_value', ]); // Set input $messages = [ new ChatMessage('user', 'Hello, how can you help?'), ]; $input = new ChatInput($messages); $plugin->setInput($input); // Execute $output = $plugin->execute(); // Get response $response = $output->getNormalized(); echo $response->getText(); ``` -------------------------------- ### Enable Metatag Module Source: https://github.com/project/ai/blob/1.x/docs/modules/ai_automators/examples/metatag_automator.md Enable the Metatag module using Drush after installation. This is a prerequisite for the Metatag Automator. ```bash drush en metatag ```