Hooks
The AI Context module implements several hooks and provides two alter hooks for third-party modules.
Alter hooks
hook_ai_context_scope_info_alter()
Allows modules to add, modify, or remove scope plugin definitions before
they are used for discovery, settings tabs, and matching. Called from
AiContextScopeManager via alterInfo('ai_context_scope_info').
Use this to hide or replace scope plugins based on site configuration or optional module availability.
function hook_ai_context_scope_info_alter(array &$definitions): void {
if (!\Drupal::moduleHandler()->moduleExists('my_optional_module')) {
unset($definitions['my_scope']);
}
$definitions['department']['icon_class'] = 'ai-icon--scope-department';
}
Parameters:
$definitions-- scope plugin definitions keyed by plugin ID (by reference)
API group: @ingroup ai_context_scope_api
hook_ai_context_scope_values_alter()
Allows modules to add, modify, or remove values from any scope plugin.
Called when scope values are retrieved for display in forms, labels,
filters, and other display paths via
AiContextScopeInterface::getAlteredValues(). Matching uses stored value
IDs directly and does not invoke this hook.
function hook_ai_context_scope_values_alter(
array &$values,
string $scope_id,
?\Drupal\Core\Cache\CacheableMetadata $cache = NULL,
): void {
if ($scope_id === 'use_case') {
$values['custom_workflow'] = t('Custom Workflow');
}
if ($scope_id === 'language') {
unset($values['und']);
}
if ($cache) {
$cache->addCacheTags(['config:my_module.settings']);
}
}
Parameters:
$values-- associative array ofvalue_id => labelpairs (by reference)$scope_id-- plugin ID of the scope (e.g.,use_case,language)$cache-- optionalCacheableMetadatawhen labels are collected for a cached display. Add tags or contexts for sources the altered labels depend on. Existing two-argument implementations remain valid.
API group: @ingroup ai_context_scope_api
No consumer-type definition alter
There is no hook_ai_context_consumer_type_info_alter(). Consumer
type discovery is not alterable. Use the enabled key on
ai_context.consumer_type_settings.{type} to turn automatic push
off for every instance of that type. A disabled type still appears
in listings; pull-based tools keep working. See
Consumer type API.
Implemented hooks
hook_ENTITY_TYPE_insert() for ai_context_item
When a context item is inserted, adds its scope values to the denormalized
scope index table via ai_context.scope_index.
Implemented in ai_context_ai_context_item_insert() in ai_context.module.
hook_ENTITY_TYPE_update() for ai_context_item
When a context item is updated, refreshes its scope index rows. If the item is a parent and its scope values changed, reindexes inheriting children so their indexed scope mirrors the parent.
Implemented in ai_context_ai_context_item_update() in ai_context.module.
hook_ENTITY_TYPE_delete() for ai_context_item
When a parent context item is deleted, clears the parent and
subcontext_type fields from all children to prevent orphaned references.
Also removes the item's rows from the scope index.
Implemented in ai_context_ai_context_item_delete() in ai_context.module.
hook_entity_delete()
When a non-context-item entity is deleted, asks opted-in scope plugins
whether to scrub stored values
(AiContextScopeStoredValueInterface::shouldScrubAfterEntityDelete()),
then clears entity item references from context items that pointed at
the deleted entity. Deleting a host entity also removes its matching
row from ai_context.consumers when a consumer type maps that
entity (Agent: ai_agent → agent:{id}, Automator:
ai_automator → automator:{id}). Disabled and unavailable
types are still asked. A type that fails to instantiate or map
is skipped and logged so one broken plugin cannot abort the
delete.
The consumer row is kept when the module that provided the deleted
entity's type is being uninstalled. Those deletes are the type going
away, not an admin removing one consumer, so the saved override
survives and the consumers listing shows it as Off (type
unavailable). Availability cannot decide this: core clears
core.extension only after the config entities are gone, so the type
still reports as installed while the deletes run. See
hook_module_preuninstall().
Implemented in ai_context_entity_delete() in ai_context.module.
hook_module_preuninstall()
Records the module core is about to uninstall so
ai_context_entity_delete() can tell a module teardown apart from a
single host-entity delete. Core fires this before it deletes the
module's configuration, which is when the host entities disappear.
Config sync is not special-cased: the host entities are deleted the
same way, so their overrides must survive either path.
Implemented in ai_context_module_preuninstall() in
ai_context.module.
hook_entity_bundle_delete()
When a bundle is deleted, asks opted-in scope plugins whether to scrub
stored values
(AiContextScopeStoredValueInterface::shouldScrubAfterBundleDelete()).
Entity Types keeps a type-level All value (type:_all), because All
still means every current and future bundle of that type.
Implemented in ai_context_entity_bundle_delete() in ai_context.module.
hook_modules_uninstalled()
Uninstalling a module that provided entity types, vocabularies, or
languages does not fire the per-option delete hooks for leftover
stored values. This hook asks every opted-in plugin to drop what is
now stale. It does nothing when ai_context itself is being
uninstalled, or during config synchronization: sync processes
extension changes before config values, so a scrub then would compare
stored values to a half-imported environment.
Implemented in ai_context_modules_uninstalled() in ai_context.module.
hook_entity_type_build()
Registers the AiContextItemIntegrity constraint on ai_context_item so
subcontext integrity rules are enforced through entity validation and storage
pre-save checks.
hook_cron()
Purges old usage records based on configured limits (usage_max_records
and usage_max_age). Runs during each cron execution.
hook_theme()
Registers theme hooks:
ai_context_overview-- the overview dashboard pageai_context_pill_list-- renders a list of labels as pill-style tags. By default the first two labels stay visible and the rest collapse into a+Npill (max_visible, default 2).max_visible0 puts every label in+N. Long labels use an ellipsis (truncate, default TRUE). PasstruncateFALSE to keep the full label, as the consumer listing does for count pills.AiContextThemeHooks::preprocessAiContextPillList()encodes tooltip values soPrice <10stays readable and markup cannot execute afterai/ai_global.jsassignsdata-ai-tooltiptoinnerHTML. A LegacyHook bridge covers Drupal 10.ai_context_item-- entity theme hook; full view usesai-context-item--full.html.twig, default view usesai-context-item.html.twig. Template suggestions are added inhook_theme_suggestions_ai_context_item(). Initial preprocess is registered inAiContextThemeHooks::theme()and implemented byAiContextThemeHooks::preprocessAiContextItem(), which delegates toAiContextItemViewBuilder. The hook class is autowired inai_context.services.ymlvia theAiContextItemViewBuilderclass alias.
hook_local_tasks_alter()
Conditionally shows or hides the Overview tab based on the
show_overview_page setting.
hook_menu_local_tasks_alter()
Hides the derived per-type and per-scope tab group (including its "All"
tab) on the Consumer Types and Scope overview routes, where it would
otherwise merge into the Settings trail. Implemented in
AiContextLocalTaskHooks, registered in ai_context.services.yml with
a LegacyHook bridge for Drupal 10.
hook_module_implements_alter()
Ensures the module's hook_form_alter() runs after Scheduler's, so it can
modify Scheduler form elements.
hook_form_alter()
Applies to AI Context Item entity forms and the AI Agent edit form:
- Moves Scheduler fields to the sidebar
- Groups moderation state with revision information
- Hides
entity_itemsfield when no entity types are allowed - Adds a "Context Control Center" section to the agent form with a link to consumer context settings
hook_field_widget_single_element_form_alter()
Restricts the dynamic entity reference widget on entity_items to only
show allowed entity types and enforces one entity per field row.
hook_page_attachments_alter()
Attaches the ai_context/ai_context library globally.
hook_gin_content_form_routes()
Registers context item add/edit form routes with the Gin admin theme for content-form styling.
hook_ENTITY_TYPE_view() for ai_context_item
Attaches the ai_context_item CSS/JS library on the full view mode.
Canonical and revision routes render with the full view mode; layout and
sidebar variables are built by AiContextItemViewBuilder via
AiContextThemeHooks::preprocessAiContextItem().
hook_block_access()
Forbids page_title_block on the canonical context item route so the
template H1 is the only title. Revision view keeps the route revision title
from page_title_block.
hook_preprocess_html()
Adds a page-ai-context-item-view body class on canonical and revision
context item view routes.
hook_entity_type_alter()
Delegates to DiffHooks for Diff module integration (adding diff field
builders to entity type definitions).
hook_modules_installed()
Delegates to DiffHooks to register diff field builders when the Diff
module is installed.