API stability
This page defines which parts of AI Context are public (safe to depend on) and which are internal (implementation details that may change without a deprecation period). It exists so contrib developers and site builders can answer one question without reading selector internals: what am I allowed to depend on?
The default rule
If an API is not listed as public on this page, treat it as internal.
- Public APIs follow Drupal's deprecation policy: behavior changes are announced and a deprecation path is provided across minor releases.
- Internal APIs may change, move, or be removed in any release without notice. Depending on them couples your code to implementation details that are expected to evolve.
While the module is in beta, public APIs may still change between releases without a full deprecation cycle — check release notes when upgrading. Once the module reaches a stable release, the boundaries on this page describe the supported surface. See also Upgrade and compatibility policy.
Deprecated APIs
CCC 1.0.x does not currently ship @deprecated public APIs. When a
supported entry point is deprecated, it will be listed here with its
replacement and the release that removes it.
If you depend on classes or services marked @internal in code, migrate to
the public surfaces on this page — those internals are not deprecated; they
were never part of the supported API.
Beta upgrade: entity scope terminology
The entity scope APIs were renamed before the 1.0.0 stable release. There are
no backward-compatibility wrappers for the old names. Deploy the new code and
run drush updatedb in the same release window, then update custom code and
configuration that uses the old identifiers.
| Old | New |
|---|---|
Scope plugin entity_bundle / AiContextScopeEntityBundle |
entity_type / AiContextScopeEntityType |
Scope plugin target_entity / AiContextScopeTargetEntity |
entity_item / AiContextScopeEntityItem |
Cache context ai_context.target_entity |
ai_context.entity_item |
Base field target_entities |
entity_items |
Usage fields target_entity_type / target_entity_id |
entity_item_type / entity_item_id |
Views field ai_context_target_entity_link |
ai_context_entity_item_link |
Service ai_context.entity_target_resolver / AiContextEntityTargetResolver |
ai_context.current_entity_resolver / AiContextCurrentEntityResolver |
Request factory parameter targetEntity |
currentEntity |
The AiContextItem methods were renamed or replaced as follows:
| Old | New |
|---|---|
getTargetEntities() |
getEntityItems() |
hasTargetEntities() |
hasEntityItems() |
getTargetEntityData() |
getEntityItemData() |
buildTargetEntityRenderArray() |
buildEntityItemRenderArray() |
getTargetEntityMarkup() |
buildEntityItemRenderArray() (render array, not markup string) |
matchesTargetEntity() |
matchesEntityItem() |
The AiContextUsage getters and setters now use EntityItem instead of
TargetEntity, for example getEntityItemType() and setEntityItemId().
Updates 10015 through 10019 migrate stored scope values and revisions,
scope configuration, usage storage and Views configuration, and the optional
Dynamic Entity Reference field storage. Update hooks cannot rewrite custom PHP
or render arrays, so custom cache-context tokens, plugin IDs, class names, and
method calls must be changed during the deployment.
Beta upgrade: max_items removal
The Max context items to inject limit was removed before the 1.0.0
stable release. The token budget (max_tokens) is now the only
user-facing limit on overall injected context; max_global_items still
caps the Global group. There are no backward-compatibility wrappers.
| Removed | Replacement |
|---|---|
max_items in ai_context.settings and per-agent overrides |
None; use max_tokens |
maxItems parameter on AiContextRequest and AiContextRequestParamsData |
None |
AiContextSelectionItemsSelectedEvent::getMaxItems() (constructor no longer takes a max-items argument) |
None |
max_items parameter on the get_relevant_ai_context_items function call |
None |
AiContextLimitsConstraint and its validator |
None; the cross-limit validation is obsolete |
Update 10020 removes the obsolete max_items keys from active
configuration, and legacy configuration exports are sanitized during
import. Custom code that passes maxItems or calls getMaxItems()
must be updated in the same release window.
Update 10023 installs the token_count base field on ai_context_item and
backfills stored estimates. See
Configuration: Upgrading.
Public API
Request factory service
Service ID ai_context.request_factory
(Drupal\ai_context\Service\AiContextRequestFactory) is the supported entry
point for running context selection from your own code.
| API | Purpose |
|---|---|
getRenderedContext() |
One-liner returning the rendered context string for non-agent consumers |
getResult() |
Full AiContextResult with cache metadata, selected IDs, and token usage |
fromAgent() |
Build an AiContextRequest from a saved agent config entry |
fromParameters() |
Build an AiContextRequest from typed parameters |
findAgentConfig() |
Canonical reader for per-agent context config |
isLoopAware() |
Whether an agent has loop-aware injection enabled |
See Services for full signatures and examples.
Scope subscription form builder
Service ID ai_context.scope_subscription_form
(Drupal\ai_context\Service\AiContextScopeSubscriptionFormBuilderInterface)
is the supported way to build and process scope subscription widgets on
non-agent forms.
| API | Purpose |
|---|---|
hasSubscribableScopes() |
Whether any enabled scope supports subscriptions |
getNonSubscribableScopeLabels() |
Labels for scopes that cannot be subscribed to |
buildWidgets() |
Per-scope subscription form elements (same UI as agent form) |
extractValues() |
Normalize submitted widgets into a scope map |
buildSummary() |
Render-array summary of selected subscriptions |
Do not depend on plugin.manager.ai_context_scope for subscription UI; use
this service instead. See
Services.
Request and result value objects
Drupal\ai_context\Model\AiContextRequestParamsData— validated parameter DTO forfromParameters(). Build instances withfromArray()when passing raw input from forms, plugins, or other loosely typed sources.Drupal\ai_context\Model\AiContextRequest— the immutable request passed into selection.Drupal\ai_context\Model\AiContextResult— the immutable result returned from selection (rendered text, selected item IDs, token usage, cache metadata).
The supported way to run a request is through ai_context.request_factory,
which builds these objects and invokes selection for you. The params DTO
getters, request fields, and result accessors — such as getRenderedText(),
getSelectedItemIds(), and getCacheableMetadata() — are public.
Selector pipeline events
The ai_context.selection.* events are the supported way to inspect or alter
selection without coupling to selector internals:
ai_context.selection.items_selected(AiContextSelectionItemsSelectedEvent)ai_context.selection.text_rendered(AiContextSelectionTextRenderedEvent)
Event name constants live on Drupal\ai_context\Event\AiContextSelectionEvents.
See the Supported extension model in
Events for the full contract, subscriber constraints, and examples.
Scope plugins, hooks, and alters
AiContextScopeplugins are a public extension point. Create your own scope plugins as described in Custom scopes and the Scope API.- The documented hooks and alter hooks are public. See Hooks.
- 1.0 custom scope storage: supported custom scopes store values in the
context item scope map field (
scope[plugin_id] => string[]). Custom entity-field storage, cleanup, and form lifecycle integration are internal module concerns in 1.0; map-backed scopes are indexed automatically. - Entity scope helpers on
AiContextItemare public for reading scope state. Resolve effective scope throughgetScopeItem()first; use stored accessors (getScope(),getScopeValues(),isStoredGlobal(),getStoredEntityItemScopeValues()) only when you need values saved on this item. See Scope API.
Do not inject plugin.manager.ai_context_scope from contrib modules; prefer
the subscription form builder service for subscription widgets. The manager
may gain orchestration methods in a future release without a deprecation
period while marked @internal.
Function call plugins
The context_tools function call plugin IDs
(ai_context:list_ai_context_items,
ai_context:load_ai_context_item_by_id,
ai_context:get_relevant_ai_context_items) are stable identifiers for agent
configuration. See Function calls.
Internal implementation
The following are internal. They may change without deprecation; do not depend on them, decorate them, or replace them.
Selector and its pipeline
ai_context.selector (Drupal\ai_context\Service\AiContextSelector) and
AiContextSelectorInterface — and the candidate pipeline (loading, scoring,
priority merge, and subcontext resolution) — are internal. Extend selection
through the selector pipeline events, not
by depending on or replacing the selector.
Supporting services
These services support the selector and are not part of the public surface:
ai_context.scope_resolver— scope scoring and hard context filtersai_context.scope_index— denormalized scope index used for prefilteringai_context.subcontext_resolver— child item resolutionai_context.renderer,ai_context.token_estimator, andai_context.subscription_budget— rendering, token budgeting, and agent settings budget summary internalsai_context.current_entity_resolver,ai_context.scope_cleanup,ai_context.children,ai_context.item_validator, and the remaining services in Services
Event subscribers, route subscribers, access checks, cache contexts, and the
scope plugin manager (plugin.manager.ai_context_scope) are likewise internal
infrastructure. All entries under Support services
in the services reference are internal — they are not labeled individually.
Use the public extension points above instead.
Service decoration and replacement
Decorating, extending, or replacing internal services (for example
ai_context.selector) in a services.yml file is not supported. The
internal pipeline may change shape, argument order, or service graph between
releases. Use the selector pipeline events
and the request factory for supported customization.
See also
- Events — Supported extension model
- Services — per-service public/internal status labels
- Access boundaries — permissions versus entity access
- Upgrade and compatibility policy
- Scope API and Custom scopes
- Hooks