Issue #3604247: Replace ReflectionProperty reroute with public ProviderProxy::getPlugin(), log real fallback token counts

Closes https://www.drupal.org/project/ai_metering/issues/3604247

What changed

  • AiPreGenerateSubscriber::rerouteTranslationViaChat(): the ReflectionProperty read of ProviderProxy::$plugin is replaced with the public getPlugin() accessor (available since drupal/ai 1.4.2).
  • The manual logUsage() call on the degraded fallback path now reads real token counts from the TokenUsageDto the provider populates inside chat(), and only falls back to the character estimate when the provider returns no usage data. The real cached-token count is passed instead of a hardcoded 0.
  • composer.json: drupal/ai raised from ^1.0 to ^1.4.2; info.yml: ai:ai (>=1.4.2).
  • New unit tests cover both behaviors (real counts pass through unchanged; estimation only on empty usage).

Why not an event

drupal/ai 1.4.x has no pre-call provider-selection event. AiExceptionEvent fires after a failed call, so it cannot serve a preventive reroute. The existing PreGenerateResponseEvent + setForcedOutputObject() mechanism stays; getPlugin() removes the only unsanctioned coupling. Details in the issue summary.

Testing steps

  1. Configure a low per-user budget and quota.fallback_provider: ollama, quota.fallback_model: llama3.2:3b.
  2. As that user, run a translate_text operation large enough to exceed the budget.
  3. Check the usage log: the fallback row (operation: translate_text_fallback, provider ollama) shows the tokenizer counts reported by Ollama, not ceil(chars / 4).

Verified end to end on Drupal 11.3.12 / drupal/ai 1.4.3 / PHP 8.4.17: logged 382 input / 364 output real tokens where the estimate would have been ~522. Full module suite green (129 tests, 496 assertions), PHPCS and PHPStan clean.

AI assistance

Investigation, patch and tests produced with AI assistance, then verified end to end on a live site as described above.

Edited by Jérôme Tchania

Merge request reports

Loading