Skip to content

Custom Scopes

You can extend the scope system by creating custom scope plugins in your own modules.

Creating a custom scope plugin

  1. Create a class that extends AiContextScopeBase
  2. Place it in src/Plugin/AiContextScope/ within your module
  3. Add the #[AiContextScope] attribute with plugin metadata
  4. Implement getValues() to return available scope values

Example

namespace Drupal\my_module\Plugin\AiContextScope;

use Drupal\ai_context\Attribute\AiContextScope;
use Drupal\ai_context\Plugin\AiContextScope\AiContextScopeBase;
use Drupal\Core\StringTranslation\TranslatableMarkup;

#[AiContextScope(
  id: 'department',
  label: new TranslatableMarkup('Department'),
  description: new TranslatableMarkup('The department this context applies to.'),
  weight: 0,
)]
class AiContextScopeDepartment extends AiContextScopeBase {

  public function getValues(): array {
    return [
      'marketing' => $this->t('Marketing'),
      'engineering' => $this->t('Engineering'),
      'sales' => $this->t('Sales'),
    ];
  }

}

The plugin is automatically discovered by the AiContextScopeManager. Clear caches after adding a new plugin.

Automatic routes and settings tabs

When a scope plugin is discovered, the module automatically generates:

  • A settings route named ai_context.settings.scope.{plugin_id} at the URL path /admin/ai/context/settings/scope/{plugin-id}.
  • A local task tab under the Scope settings page, using the plugin's label as the tab title.

The tab order is determined by each plugin's weight attribute (lower weight appears first). You do not need to define routes or local tasks manually.

Plugin ID vs URL path

The plugin ID and the URL path use slightly different conventions:

  • Route name keeps the plugin ID verbatim, including underscores. For example, the target_entity scope produces the route name ai_context.settings.scope.target_entity.
  • URL path converts underscores to dashes for readability, so the same scope is served at /admin/ai/context/settings/scope/target-entity.

When linking to a scope settings page from your own code (for example, from getManageRoute()), always use the route name with underscores -- never the URL path:

public function getManageRoute(): ?array {
  return ['route_name' => 'ai_context.settings.scope.target_entity'];
}

If a scope plugin is removed (e.g., by uninstalling a module or via hook_ai_context_scope_info_alter()), its route and tab are removed automatically. The scope plugin manager invalidates the local_task cache tag whenever its definitions are cleared, so derived tabs stay in sync without a full cache rebuild.

Attribute parameters

Parameter Type Description
id string Unique plugin ID
label TranslatableMarkup Human-readable label
description TranslatableMarkup\|null Description shown on context item forms
weight int Ordering weight (lower = processed first)
deriver string\|null Optional deriver class

Optional overrides

The base class provides sensible defaults. Override these methods to customize behavior:

supportsSubscriptions()

Return FALSE to hide this scope from agent configuration forms. Useful for scopes that apply automatically (like Global or Target Entity).

public function supportsSubscriptions(): bool {
  return FALSE;
}

allowsMultiple()

Return FALSE to render radio buttons instead of checkboxes (single selection).

isDynamic()

Return TRUE if values come from an external source (database, config, API) rather than being hardcoded. Dynamic scopes may change at runtime.

getCurrentValue()

Return the currently active value for contextual detection. For example, the Language scope returns the current language, and the Site Section scope returns the matching section for the current URL.

matchesCurrentContext()

Implement custom matching logic for how this scope determines whether a context item matches the current request context.

getManageUrl() and getManageLabel()

Provide a link to an admin page where this scope's values can be managed.

buildSettingsForm(), validateSettingsForm(), submitSettingsForm()

Add custom settings beyond the default enabled checkbox.

For full API details, see the Scope API reference.

Altering scope values

Use hook_ai_context_scope_values_alter() to add, modify, or remove values from any scope plugin without writing a full plugin.

function my_module_ai_context_scope_values_alter(
  array &$values,
  string $scope_id,
): void {
  if ($scope_id === 'use_case') {
    $values['custom_workflow'] = t('Custom Workflow');
  }
}

Parameters:

  • $values -- associative array of value_id => label pairs (passed by reference)
  • $scope_id -- the plugin ID of the scope being altered (e.g., use_case, language, site_section)