Summary

Add a scope plugin that includes a context item when the AI request carries one of the tags the item is scoped to. Tags here are the strings the ai module records on a provider call — set via AiProviderInterface::setTag() / the $tags argument to chat(), and surfaced on the provider request events as AiProviderRequestBaseEvent::getTags() (e.g. an operation type, ai_ckeditor, or a caller-defined tag like ai_empathy_scenario:5).

Problem / motivation

ai_context today has a tag scope, but it keys on taxonomy term IDs (ai_context_tags vocabulary) matched via agent subscriptions. There is no way to scope a context item to the runtime AI request tags the ai module already tracks. Consumers that are not agents (ai_ckeditor, custom callers, ai_empathy evaluations) tag their provider calls but cannot use those tags to select context.

Related: #3581955 (inject context into ai_ckeditor requests) matches on entity type/ID; request-tag matching is a complementary mechanism that would let CKEditor (and any consumer) also target context by the operation/tags on the call.

The one design constraint

Context is injected into the prompt before the provider request is sent, so a scope cannot wait for ai.pre_generate_response to learn the tags — by then the input (with context) is already built. The request's tags must be made available to context selection up front. This is the only genuinely new integration required; the rest is a standard scope plugin.

Proposed approach

  1. New request_tag scope plugin:
    • Selectable tags are an admin-defined list on the scope's settings form (mirrors the entity_bundle scope), rendered as checkboxes on each context item. Values are plain tag strings, not taxonomy term IDs.
    • supportsSubscriptions() stays TRUE, so items are matched by intersecting the request's tags with the item's selected tags through the existing resolver scoring; doGetCurrentValue() returns NULL (no ambient page value).
  2. A supported way for callers to declare the request's tags — pick one:
    • (a) Recommended: add a requestTags field to AiContextRequest (and a param on AiContextRequestFactory::fromParameters() / getRenderedContext()) that callers populate. Simple and explicit; reuses the existing scopeSubscriptions machinery; no changes to the ai module.
    • (b) Alternative: a request-scoped "current AI request tags" collector, populated where callers call $provider->setTag() and, where the flow allows, from ai.pre_generate_response. More automatic but heavier.

Working prototype

A functioning implementation already exists in the ai_empathy_ccc submodule of the ai_empathy project and can be lifted into ai_context:

  • AiContextScopeRequestTag — the scope plugin (admin-defined tag list + checkboxes; subscription matching; ai_context.scope_settings.request_tag config).
  • The empathy evaluator surfaces its request tags (ai_empathy, ai_empathy_scenario:<id>, ai_empathy_run:<n>) on its prompt-alter event, and the subscriber passes them via getRenderedContext(scopes: ['request_tag' => $tags]).
  • A kernel test proves that with SELECTION_MODE_MATCH_ALL (as getRenderedContext() uses), a request_tag subscription restricts inclusion to matching items (plus globals) — it does not merely reorder — confirming the resolver already supports this end-to-end.

Moving it upstream mainly requires deciding mechanism (a) vs (b) so any consumer — agents, ai_ckeditor — can declare request tags, not just ai_empathy.

Proposed resolution

  • Add AiContextScopeRequestTag plugin + settings form + config/schema.
  • Decide (a) vs (b) and expose request tags to selection.
  • Kernel test for tag-restricted inclusion; update docs (custom scopes).

Related issues

Issue fork ai_empathy-3610965

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

joshua1234511 created an issue. See original summary.

joshua1234511’s picture

Issue summary: View changes
joshua1234511’s picture

Issue summary: View changes
joshua1234511’s picture

Assigned: joshua1234511 » Unassigned
Status: Active » Needs review
joshua1234511’s picture

Issue summary: View changes

  • joshua1234511 committed 4655c7a2 on 1.1.x
    Issue #3610965: Add request_tag scope to attach context by AI request...
joshua1234511’s picture

Status: Needs review » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

joshua1234511’s picture

Status: Fixed » Closed (fixed)
nitinkumar_7’s picture

I was checking this issue and writing this comment but not able to submit on time :)

I think this is a clean solution to the problem of making request tags available during context resolution, and the implementation fits well with the existing scope system.

I only have one concern and suggestion before this is marked RTBC. It would be good to add a kernel test covering the case where no request tags are provided. Specifically, verify that a context item scoped only with request_tag is excluded when the request tag list is empty. The current tests cover matching tags and global context, but this boundary case would help ensure the resolver behaves as expected.

Other than that, the implementation look good to me.

joshua1234511’s picture

Thanks again, @nitinkumar_7. I've opened a follow-up to add the empty request-tag-list boundary test: #3612824.

Since 1.2.0 is already released, I'd like to keep this issue as fixed and handle the additional coverage there. Marking fixed.

Since you spotted the gap, feel free to pick it up if you'd like — I've written up the proposed test method in the summary to make it an easy start. Happy to review a patch/MR whenever it suits you. Otherwise I'll get to it in due course.