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 ofProviderProxy::$pluginis replaced with the publicgetPlugin()accessor (available since drupal/ai 1.4.2).- The manual
logUsage()call on the degraded fallback path now reads real token counts from theTokenUsageDtothe provider populates insidechat(), 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/airaised from^1.0to^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
- Configure a low per-user budget and
quota.fallback_provider: ollama,quota.fallback_model: llama3.2:3b. - As that user, run a translate_text operation large enough to exceed the budget.
- Check the usage log: the fallback row (
operation: translate_text_fallback, providerollama) shows the tokenizer counts reported by Ollama, notceil(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