Pass AI token usage data to the events
>>> [!note] Migrated issue
<!-- Drupal.org comment -->
<!-- Migrated from issue #3541284. -->
Reported by: [murz](https://www.drupal.org/user/157092)
Related to !828
>>>
<h3 id="summary-problem-motivation">Problem/Motivation</h3>
<p>In the issue <span class="drupalorg-gitlab-issue-link project-issue-status-info project-issue-status-7"><a href="https://www.drupal.org/project/ai/issues/3517618" title="Status: Closed (fixed)">#3517618: Abstract token usage</a></span>, we implemented getters and setters for the token usage:</p>
<div class="codeblock">
<pre><span style="color: #000000"><span style="color: #0000BB"><?php<br> </span><span style="color: #007700">public function </span><span style="color: #0000BB">getTotalTokenUsage</span><span style="color: #007700">(): ?</span><span style="color: #0000BB">int</span><span style="color: #007700">;<br> public function </span><span style="color: #0000BB">getInputTokenUsage</span><span style="color: #007700">(): ?</span><span style="color: #0000BB">int</span><span style="color: #007700">;<br> public function </span><span style="color: #0000BB">getOutputTokenUsage</span><span style="color: #007700">(): ?</span><span style="color: #0000BB">int</span><span style="color: #007700">;<br> public function </span><span style="color: #0000BB">getCachedTokenUsage</span><span style="color: #007700">(): ?</span><span style="color: #0000BB">int</span><span style="color: #007700">;<br></span><span style="color: #0000BB">?></span></span></pre></div>
<p>But added them only to the class <code>ChatOutput</code> and that's it.</p>
<p>And after receiving this information in the plugin <code>ProviderProxy</code> - it just disappears!</p>
<p>So, we need to pass the token usage data from the provider to the events, at least, to the PostGenerateResponseEvent and PostStreamingResponseEvent.</p>
<h3 id="summary-proposed-resolution">Proposed resolution</h3>
<p>The easiest way is to just pass each value as a parameter to the <code>PostGenerateResponseEvent</code>, something like this:</p>
<div class="codeblock">
<pre><span style="color: #000000"><span style="color: #0000BB"><?php<br> </span><span style="color: #FF8000">// Invoke the post generate response event.<br> </span><span style="color: #0000BB">$post_generate_event </span><span style="color: #007700">= new </span><span style="color: #0000BB">PostGenerateResponseEvent</span><span style="color: #007700">(<br> </span><span style="color: #0000BB">$event_id</span><span style="color: #007700">,<br> </span><span style="color: #0000BB">$this</span><span style="color: #007700">-></span><span style="color: #0000BB">plugin</span><span style="color: #007700">-></span><span style="color: #0000BB">getPluginId</span><span style="color: #007700">(),<br> </span><span style="color: #0000BB">$operation_type</span><span style="color: #007700">,<br> </span><span style="color: #0000BB">$this</span><span style="color: #007700">-></span><span style="color: #0000BB">plugin</span><span style="color: #007700">-></span><span style="color: #0000BB">configuration</span><span style="color: #007700">,<br> </span><span style="color: #0000BB">$arguments</span><span style="color: #007700">[</span><span style="color: #0000BB">0</span><span style="color: #007700">],<br> </span><span style="color: #0000BB">$arguments</span><span style="color: #007700">[</span><span style="color: #0000BB">1</span><span style="color: #007700">],<br> </span><span style="color: #0000BB">$response</span><span style="color: #007700">,<br> </span><span style="color: #0000BB">$this</span><span style="color: #007700">-></span><span style="color: #0000BB">plugin</span><span style="color: #007700">-></span><span style="color: #0000BB">getTags</span><span style="color: #007700">(),<br> </span><span style="color: #0000BB">$this</span><span style="color: #007700">-></span><span style="color: #0000BB">plugin</span><span style="color: #007700">-></span><span style="color: #0000BB">getDebugData</span><span style="color: #007700">(),<br> </span><span style="color: #0000BB">$pre_generate_event</span><span style="color: #007700">-></span><span style="color: #0000BB">getAllMetadata</span><span style="color: #007700">(),<br><br> </span><span style="color: #FF8000">// Pass the token usage data.<br> </span><span style="color: #0000BB">$this</span><span style="color: #007700">-></span><span style="color: #0000BB">plugin</span><span style="color: #007700">-></span><span style="color: #0000BB">getTotalTokenUsage</span><span style="color: #007700">(),<br> </span><span style="color: #0000BB">$this</span><span style="color: #007700">-></span><span style="color: #0000BB">plugin</span><span style="color: #007700">-></span><span style="color: #0000BB">getInputTokenUsage</span><span style="color: #007700">(),<br> </span><span style="color: #0000BB">$this</span><span style="color: #007700">-></span><span style="color: #0000BB">plugin</span><span style="color: #007700">-></span><span style="color: #0000BB">getOutputTokenUsage</span><span style="color: #007700">(),<br> </span><span style="color: #0000BB">$this</span><span style="color: #007700">-></span><span style="color: #0000BB">plugin</span><span style="color: #007700">-></span><span style="color: #0000BB">getReasoningTokenUsage</span><span style="color: #007700">(),<br> </span><span style="color: #0000BB">$this</span><span style="color: #007700">-></span><span style="color: #0000BB">plugin</span><span style="color: #007700">-></span><span style="color: #0000BB">getCachedTokenUsage</span><span style="color: #007700">(),<br> );<br></span><span style="color: #0000BB">?></span></span></pre></div>
<p>But the number of the constructor parameters is already huge! So adding more parameters, especially one more separate parameter for just an integer, is not so good, from my point of view.</p>
<p>Because all the token usage numbers usually come simultaneously, I think it'll be a good idea to introduce a DTO class handling all this, and pass it as an argument. </p>
<p>What do you think about this way of moving forward?</p>
<h3 id="summary-remaining-tasks">Remaining tasks</h3>
issue