Skip to content

Commit 9b73ba6

Browse files
Revert "feat(platform): Standardize token usage"
This reverts commit 1f1e6be.
1 parent 1f1e6be commit 9b73ba6

18 files changed

+196
-502
lines changed

examples/mistral/token-metadata.php

Lines changed: 0 additions & 48 deletions
This file was deleted.

examples/openai/token-metadata.php

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,9 @@
1212
use Symfony\AI\Agent\Agent;
1313
use Symfony\AI\Platform\Bridge\OpenAi\Gpt;
1414
use Symfony\AI\Platform\Bridge\OpenAi\PlatformFactory;
15-
use Symfony\AI\Platform\Bridge\OpenAi\TokenUsageExtractor;
15+
use Symfony\AI\Platform\Bridge\OpenAi\TokenOutputProcessor;
1616
use Symfony\AI\Platform\Message\Message;
1717
use Symfony\AI\Platform\Message\MessageBag;
18-
use Symfony\AI\Platform\Result\TokenUsage\TokenUsageOutputProcessor;
1918

2019
require_once dirname(__DIR__).'/bootstrap.php';
2120

@@ -24,26 +23,18 @@
2423
'temperature' => 0.5, // default options for the model
2524
]);
2625

27-
$agent = new Agent(
28-
$platform,
29-
$model,
30-
outputProcessors: [new TokenUsageOutputProcessor(new TokenUsageExtractor())],
31-
logger: logger()
32-
);
26+
$agent = new Agent($platform, $model, outputProcessors: [new TokenOutputProcessor()], logger: logger());
3327
$messages = new MessageBag(
3428
Message::forSystem('You are a pirate and you write funny.'),
3529
Message::ofUser('What is the Symfony framework?'),
3630
);
37-
3831
$result = $agent->call($messages, [
3932
'max_tokens' => 500, // specific options just for this call
4033
]);
4134

42-
if (null === $tokenUsage = $result->getTokenUsage()) {
43-
throw new RuntimeException('Token usage is not available.');
44-
}
35+
$metadata = $result->getMetadata();
4536

46-
echo 'Utilized Tokens: '.$tokenUsage->total.\PHP_EOL;
47-
echo '-- Prompt Tokens: '.$tokenUsage->prompt.\PHP_EOL;
48-
echo '-- Completion Tokens: '.$tokenUsage->completion.\PHP_EOL;
49-
echo 'Remaining Tokens: '.$tokenUsage->remaining.\PHP_EOL;
37+
echo 'Utilized Tokens: '.$metadata['total_tokens'].\PHP_EOL;
38+
echo '-- Prompt Tokens: '.$metadata['prompt_tokens'].\PHP_EOL;
39+
echo '-- Completion Tokens: '.$metadata['completion_tokens'].\PHP_EOL;
40+
echo 'Remaining Tokens: '.$metadata['remaining_tokens'].\PHP_EOL;

src/ai-bundle/config/options.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@
103103
->info('Include tool definitions at the end of the system prompt')
104104
->defaultFalse()
105105
->end()
106-
->booleanNode('token_usage')->defaultFalse()->end()
107106
->arrayNode('tools')
108107
->addDefaultsIfNotSet()
109108
->treatFalseLike(['enabled' => false])

src/ai-bundle/src/AiBundle.php

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
use Symfony\AI\Agent\Toolbox\Tool\Agent as AgentTool;
2222
use Symfony\AI\Agent\Toolbox\ToolFactory\ChainFactory;
2323
use Symfony\AI\Agent\Toolbox\ToolFactory\MemoryToolFactory;
24-
use Symfony\AI\AiBundle\DependencyInjection\Compiler\RegisterTokenUsageExtractorPass;
2524
use Symfony\AI\AiBundle\Exception\InvalidArgumentException;
2625
use Symfony\AI\AiBundle\Profiler\TraceablePlatform;
2726
use Symfony\AI\AiBundle\Profiler\TraceableToolbox;
@@ -39,8 +38,6 @@
3938
use Symfony\AI\Platform\ModelClientInterface;
4039
use Symfony\AI\Platform\Platform;
4140
use Symfony\AI\Platform\PlatformInterface;
42-
use Symfony\AI\Platform\Result\TokenUsage\TokenUsageExtractorInterface;
43-
use Symfony\AI\Platform\Result\TokenUsage\TokenUsageOutputProcessor;
4441
use Symfony\AI\Platform\ResultConverterInterface;
4542
use Symfony\AI\Store\Bridge\Azure\SearchStore as AzureSearchStore;
4643
use Symfony\AI\Store\Bridge\ChromaDb\Store as ChromaDbStore;
@@ -142,8 +139,6 @@ public function loadExtension(array $config, ContainerConfigurator $container, C
142139
->addTag('ai.platform.model_client');
143140
$builder->registerForAutoconfiguration(ResultConverterInterface::class)
144141
->addTag('ai.platform.result_converter');
145-
$builder->registerForAutoconfiguration(TokenUsageExtractorInterface::class)
146-
->addTag('ai.platform.token_usage_extractor');
147142

148143
if (!ContainerBuilder::willBeAvailable('symfony/security-core', AuthorizationCheckerInterface::class, ['symfony/ai-bundle'])) {
149144
$builder->removeDefinition('ai.security.is_granted_attribute_listener');
@@ -159,13 +154,6 @@ public function loadExtension(array $config, ContainerConfigurator $container, C
159154
}
160155
}
161156

162-
public function build(ContainerBuilder $container): void
163-
{
164-
parent::build($container);
165-
166-
$container->addCompilerPass(new RegisterTokenUsageExtractorPass());
167-
}
168-
169157
/**
170158
* @param array<string, mixed> $platform
171159
*/
@@ -394,7 +382,7 @@ private function processAgentConfig(string $name, array $config, ContainerBuilde
394382
$tool['service'] = \sprintf('ai.agent.%s', $tool['agent']);
395383
}
396384
$reference = new Reference($tool['service']);
397-
// We use the memory factory in case, method, description and name are set
385+
// We use the memory factory in case method, description and name are set
398386
if (isset($tool['name'], $tool['description'])) {
399387
if (isset($tool['agent'])) {
400388
$agentWrapperDefinition = new Definition(AgentTool::class, [$reference]);
@@ -444,24 +432,6 @@ private function processAgentConfig(string $name, array $config, ContainerBuilde
444432
}
445433
}
446434

447-
// TOKEN USAGE
448-
if ($config['token_usage'] ?? false) {
449-
$platformServiceId = $config['platform'];
450-
$platformName = str_replace('ai.platform.', '', $platformServiceId);
451-
$extractorAlias = \sprintf('ai.platform.token_usage_extractor.%s', $platformName);
452-
453-
if (!$container->hasAlias($extractorAlias)) {
454-
throw new InvalidArgumentException(\sprintf('Token usage is enabled for agent "%s", but no token usage extractor is registered for platform "%s".', $name, $platformName));
455-
}
456-
457-
$processorId = \sprintf('ai.token_usage_output_processor.%s', $name);
458-
$processorDefinition = (new Definition(TokenUsageOutputProcessor::class))
459-
->addArgument(new Reference($extractorAlias));
460-
461-
$container->setDefinition($processorId, $processorDefinition);
462-
$outputProcessors[] = new Reference($processorId);
463-
}
464-
465435
// STRUCTURED OUTPUT
466436
if ($config['structured_output']) {
467437
$inputProcessors[] = new Reference('ai.agent.structured_output_processor');

src/ai-bundle/src/DependencyInjection/Compiler/RegisterTokenUsageExtractorPass.php

Lines changed: 0 additions & 48 deletions
This file was deleted.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\AI\Platform\Bridge\Mistral;
13+
14+
use Symfony\AI\Agent\Output;
15+
use Symfony\AI\Agent\OutputProcessorInterface;
16+
use Symfony\AI\Platform\Result\StreamResult;
17+
use Symfony\Contracts\HttpClient\ResponseInterface;
18+
19+
/**
20+
* @author Quentin Fahrner <[email protected]>
21+
*/
22+
final class TokenOutputProcessor implements OutputProcessorInterface
23+
{
24+
public function processOutput(Output $output): void
25+
{
26+
if ($output->result instanceof StreamResult) {
27+
// Streams have to be handled manually as the tokens are part of the streamed chunks
28+
return;
29+
}
30+
31+
$rawResponse = $output->result->getRawResult()?->getObject();
32+
if (!$rawResponse instanceof ResponseInterface) {
33+
return;
34+
}
35+
36+
$metadata = $output->result->getMetadata();
37+
38+
$metadata->add(
39+
'remaining_tokens_minute',
40+
(int) $rawResponse->getHeaders(false)['x-ratelimit-limit-tokens-minute'][0],
41+
);
42+
43+
$metadata->add(
44+
'remaining_tokens_month',
45+
(int) $rawResponse->getHeaders(false)['x-ratelimit-limit-tokens-month'][0],
46+
);
47+
48+
$content = $rawResponse->toArray(false);
49+
50+
if (!\array_key_exists('usage', $content)) {
51+
return;
52+
}
53+
54+
$metadata->add('prompt_tokens', $content['usage']['prompt_tokens'] ?? null);
55+
$metadata->add('completion_tokens', $content['usage']['completion_tokens'] ?? null);
56+
$metadata->add('total_tokens', $content['usage']['total_tokens'] ?? null);
57+
}
58+
}

src/platform/src/Bridge/Mistral/TokenUsageExtractor.php

Lines changed: 0 additions & 60 deletions
This file was deleted.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\AI\Platform\Bridge\OpenAi;
13+
14+
use Symfony\AI\Agent\Output;
15+
use Symfony\AI\Agent\OutputProcessorInterface;
16+
use Symfony\AI\Platform\Result\StreamResult;
17+
use Symfony\Contracts\HttpClient\ResponseInterface;
18+
19+
/**
20+
* @author Denis Zunke <[email protected]>
21+
*/
22+
final class TokenOutputProcessor implements OutputProcessorInterface
23+
{
24+
public function processOutput(Output $output): void
25+
{
26+
if ($output->result instanceof StreamResult) {
27+
// Streams have to be handled manually as the tokens are part of the streamed chunks
28+
return;
29+
}
30+
31+
$rawResponse = $output->result->getRawResult()?->getObject();
32+
if (!$rawResponse instanceof ResponseInterface) {
33+
return;
34+
}
35+
36+
$metadata = $output->result->getMetadata();
37+
38+
$metadata->add(
39+
'remaining_tokens',
40+
(int) $rawResponse->getHeaders(false)['x-ratelimit-remaining-tokens'][0],
41+
);
42+
43+
$content = $rawResponse->toArray(false);
44+
45+
if (!\array_key_exists('usage', $content)) {
46+
return;
47+
}
48+
49+
$metadata->add('prompt_tokens', $content['usage']['prompt_tokens'] ?? null);
50+
$metadata->add('completion_tokens', $content['usage']['completion_tokens'] ?? null);
51+
$metadata->add('total_tokens', $content['usage']['total_tokens'] ?? null);
52+
}
53+
}

0 commit comments

Comments
 (0)