Skip to content

Events System

When to Use

Use events when you need to intercept AI requests or responses across all operations without modifying providers. Use Guardrails when you need content filtering. Use events for logging, caching, authentication override, or telemetry.

Decision

Situation Choose Why
Modify input before call PreGenerateResponseEvent Can rewrite input, change auth, force output
Cache/return early PreGenerateResponseEvent + setForcedOutputObject() Short-circuits the provider call
Log or audit responses PostGenerateResponseEvent Fires after non-streamed response
Audit streamed responses PostStreamingResponseEvent Read-only; fires after stream completes

Pattern

use Drupal\ai\Event\PreGenerateResponseEvent;
use Drupal\ai\Event\PostGenerateResponseEvent;

class MyEventSubscriber implements EventSubscriberInterface {

  public static function getSubscribedEvents(): array {
    return [
      PreGenerateResponseEvent::EVENT_NAME => ['onPreGenerate', 0],
      PostGenerateResponseEvent::EVENT_NAME => ['onPostGenerate', 0],
    ];
  }

  public function onPreGenerate(PreGenerateResponseEvent $event): void {
    $tags = $event->getTags();
    $input = $event->getInput();
    // Modify input or check cache.
    $event->setInput($modifiedInput);
  }

  public function onPostGenerate(PostGenerateResponseEvent $event): void {
    $output = $event->getOutput();
    $tokenUsage = $event->getTokenUsage();
    // Log, cache, or audit.
  }
}

Event Types

Event Constant When Can Modify
PreGenerateResponseEvent ai.pre_generate_response Before provider call Input, config, auth, tags; can force output
PostGenerateResponseEvent ai.post_generate_response After non-streamed response Output
PostStreamingResponseEvent ai.post_streaming_response After streamed response completes Read-only

Event Properties

Method Pre Post PostStreaming
getInput() / setInput() R/W R R
getOutput() -- R/W R
getOperationType() R R R
getProviderId() R R R
getTags() / setTags() R/W R R
getRequestThreadId() R R R
getMetadata($key) / setMetadata($key, $val) R/W R/W R
setAuthentication($auth) R/W -- --
setForcedOutputObject($output) R/W -- --

Tagging Convention

$provider->chat($input, $model, [
  'my_module',                     // Module tag
  'my_module:feature:summarize',   // Feature tag
  'my_module:entity_type:node',    // Entity type
  'my_module:bundle:article',      // Bundle
]);

Tags enable: logging filters, guardrail targeting, event subscriber filtering, cost attribution.

Common Mistakes

  • Wrong: Not using getRequestThreadId() to correlate pre/post events → Right: UUID links pre and post events; use it for correlated logging
  • Wrong: Modifying output in PostStreamingResponseEventRight: This event is read-only — use PostGenerateResponseEvent for modification

See Also