Skip to content

Commit d0014e4

Browse files
committed
Decouple Platform Token Usage handling from Agent by introducing new interface
1 parent b9a7258 commit d0014e4

File tree

68 files changed

+494
-303
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+494
-303
lines changed

examples/anthropic/token-metadata.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@
1111

1212
use Symfony\AI\Agent\Agent;
1313
use Symfony\AI\Platform\Bridge\Anthropic\PlatformFactory;
14-
use Symfony\AI\Platform\Bridge\Anthropic\TokenOutputProcessor;
1514
use Symfony\AI\Platform\Message\Message;
1615
use Symfony\AI\Platform\Message\MessageBag;
1716

1817
require_once dirname(__DIR__).'/bootstrap.php';
1918

2019
$platform = PlatformFactory::create(env('ANTHROPIC_API_KEY'), http_client());
2120

22-
$agent = new Agent($platform, 'claude-sonnet-4-5-20250929', outputProcessors: [new TokenOutputProcessor()]);
21+
$agent = new Agent($platform, 'claude-sonnet-4-5-20250929');
2322
$messages = new MessageBag(
2423
Message::forSystem('You are a pirate and you write funny.'),
2524
Message::ofUser('What is the Symfony framework?'),

examples/bootstrap.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
use Symfony\AI\Agent\Exception\ExceptionInterface as AgentException;
1515
use Symfony\AI\Platform\Exception\ExceptionInterface as PlatformException;
1616
use Symfony\AI\Platform\Metadata\Metadata;
17-
use Symfony\AI\Platform\Metadata\TokenUsage;
1817
use Symfony\AI\Platform\Result\DeferredResult;
18+
use Symfony\AI\Platform\TokenUsage\TokenUsage;
1919
use Symfony\AI\Store\Exception\ExceptionInterface as StoreException;
2020
use Symfony\Component\Console\Helper\Table;
2121
use Symfony\Component\Console\Logger\ConsoleLogger;

examples/deepseek/token-metadata.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@
1111

1212
use Symfony\AI\Agent\Agent;
1313
use Symfony\AI\Platform\Bridge\DeepSeek\PlatformFactory;
14-
use Symfony\AI\Platform\Bridge\DeepSeek\TokenOutputProcessor;
1514
use Symfony\AI\Platform\Message\Message;
1615
use Symfony\AI\Platform\Message\MessageBag;
1716

1817
require_once dirname(__DIR__).'/bootstrap.php';
1918

2019
$platform = PlatformFactory::create(env('DEEPSEEK_API_KEY'), http_client());
2120

22-
$agent = new Agent($platform, 'deepseek-chat', outputProcessors: [new TokenOutputProcessor()]);
21+
$agent = new Agent($platform, 'deepseek-chat');
2322
$messages = new MessageBag(
2423
Message::forSystem('You are a pirate and you write funny.'),
2524
Message::ofUser('What is the Symfony framework?'),

examples/gemini/token-metadata.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@
1111

1212
use Symfony\AI\Agent\Agent;
1313
use Symfony\AI\Platform\Bridge\Gemini\PlatformFactory;
14-
use Symfony\AI\Platform\Bridge\Gemini\TokenOutputProcessor;
1514
use Symfony\AI\Platform\Message\Message;
1615
use Symfony\AI\Platform\Message\MessageBag;
1716

1817
require_once dirname(__DIR__).'/bootstrap.php';
1918

2019
$platform = PlatformFactory::create(env('GEMINI_API_KEY'), http_client());
2120

22-
$agent = new Agent($platform, 'gemini-2.0-flash', outputProcessors: [new TokenOutputProcessor()]);
21+
$agent = new Agent($platform, 'gemini-2.0-flash');
2322
$messages = new MessageBag(
2423
Message::forSystem('You are a pirate and you write funny.'),
2524
Message::ofUser('What is the Symfony framework?'),

examples/mistral/token-metadata.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@
1111

1212
use Symfony\AI\Agent\Agent;
1313
use Symfony\AI\Platform\Bridge\Mistral\PlatformFactory;
14-
use Symfony\AI\Platform\Bridge\Mistral\TokenOutputProcessor;
1514
use Symfony\AI\Platform\Message\Message;
1615
use Symfony\AI\Platform\Message\MessageBag;
1716

1817
require_once dirname(__DIR__).'/bootstrap.php';
1918

2019
$platform = PlatformFactory::create(env('MISTRAL_API_KEY'), http_client());
2120

22-
$agent = new Agent($platform, 'mistral-large-latest', outputProcessors: [new TokenOutputProcessor()]);
21+
$agent = new Agent($platform, 'mistral-large-latest');
2322

2423
$messages = new MessageBag(
2524
Message::forSystem('You are a pirate and you write funny.'),

examples/openai/token-metadata.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@
1111

1212
use Symfony\AI\Agent\Agent;
1313
use Symfony\AI\Platform\Bridge\OpenAi\PlatformFactory;
14-
use Symfony\AI\Platform\Bridge\OpenAi\TokenOutputProcessor;
1514
use Symfony\AI\Platform\Message\Message;
1615
use Symfony\AI\Platform\Message\MessageBag;
1716

1817
require_once dirname(__DIR__).'/bootstrap.php';
1918

2019
$platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client());
2120

22-
$agent = new Agent($platform, 'gpt-4o-mini', outputProcessors: [new TokenOutputProcessor()]);
21+
$agent = new Agent($platform, 'gpt-4o-mini');
2322
$messages = new MessageBag(
2423
Message::forSystem('You are a pirate and you write funny.'),
2524
Message::ofUser('What is the Symfony framework?'),

examples/perplexity/token-metadata.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,13 @@
1111

1212
use Symfony\AI\Agent\Agent;
1313
use Symfony\AI\Platform\Bridge\Perplexity\PlatformFactory;
14-
use Symfony\AI\Platform\Bridge\Perplexity\TokenOutputProcessor;
1514
use Symfony\AI\Platform\Message\Message;
1615
use Symfony\AI\Platform\Message\MessageBag;
1716

1817
require_once dirname(__DIR__).'/bootstrap.php';
1918

2019
$platform = PlatformFactory::create(env('PERPLEXITY_API_KEY'), http_client());
21-
$agent = new Agent($platform, 'sonar', outputProcessors: [new TokenOutputProcessor()]);
20+
$agent = new Agent($platform, 'sonar');
2221

2322
$messages = new MessageBag(
2423
Message::forSystem('You are a pirate and you write funny.'),

examples/vertexai/token-metadata.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@
1111

1212
use Symfony\AI\Agent\Agent;
1313
use Symfony\AI\Platform\Bridge\VertexAi\PlatformFactory;
14-
use Symfony\AI\Platform\Bridge\VertexAi\TokenOutputProcessor;
1514
use Symfony\AI\Platform\Message\Message;
1615
use Symfony\AI\Platform\Message\MessageBag;
1716

1817
require_once __DIR__.'/bootstrap.php';
1918

2019
$platform = PlatformFactory::create(env('GOOGLE_CLOUD_LOCATION'), env('GOOGLE_CLOUD_PROJECT'), adc_aware_http_client());
2120

22-
$agent = new Agent($platform, 'gemini-2.0-flash-lite', outputProcessors: [new TokenOutputProcessor()]);
21+
$agent = new Agent($platform, 'gemini-2.0-flash-lite');
2322
$messages = new MessageBag(
2423
Message::forSystem('You are an expert assistant in animal study.'),
2524
Message::ofUser('What does a cat usually eat?'),

src/ai-bundle/config/services.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
use Symfony\AI\Platform\Bridge\Albert\ModelCatalog as AlbertModelCatalog;
2929
use Symfony\AI\Platform\Bridge\Anthropic\Contract\AnthropicContract;
3030
use Symfony\AI\Platform\Bridge\Anthropic\ModelCatalog as AnthropicModelCatalog;
31-
use Symfony\AI\Platform\Bridge\Anthropic\TokenOutputProcessor as AnthropicTokenOutputProcessor;
31+
use Symfony\AI\Platform\Bridge\Anthropic\TokenUsageExtractor as AnthropicTokenOutputProcessor;
3232
use Symfony\AI\Platform\Bridge\Azure\OpenAi\ModelCatalog as AzureOpenAiModelCatalog;
3333
use Symfony\AI\Platform\Bridge\Cartesia\ModelCatalog as CartesiaModelCatalog;
3434
use Symfony\AI\Platform\Bridge\Cerebras\ModelCatalog as CerebrasModelCatalog;
@@ -37,29 +37,29 @@
3737
use Symfony\AI\Platform\Bridge\DockerModelRunner\ModelCatalog as DockerModelRunnerModelCatalog;
3838
use Symfony\AI\Platform\Bridge\ElevenLabs\ModelCatalog as ElevenLabsModelCatalog;
3939
use Symfony\AI\Platform\Bridge\Gemini\Contract\GeminiContract;
40+
use Symfony\AI\Platform\Bridge\Gemini\Gemini\TokenUsageExtractor as GeminiTokenOutputProcessor;
4041
use Symfony\AI\Platform\Bridge\Gemini\ModelCatalog as GeminiModelCatalog;
41-
use Symfony\AI\Platform\Bridge\Gemini\TokenOutputProcessor as GeminiTokenOutputProcessor;
4242
use Symfony\AI\Platform\Bridge\HuggingFace\Contract\HuggingFaceContract;
4343
use Symfony\AI\Platform\Bridge\HuggingFace\ModelCatalog as HuggingFaceModelCatalog;
4444
use Symfony\AI\Platform\Bridge\LmStudio\ModelCatalog as LmStudioModelCatalog;
4545
use Symfony\AI\Platform\Bridge\Meta\ModelCatalog as MetaModelCatalog;
46+
use Symfony\AI\Platform\Bridge\Mistral\Llm\TokenUsageExtractor as MistralTokenOutputProcessor;
4647
use Symfony\AI\Platform\Bridge\Mistral\ModelCatalog as MistralModelCatalog;
47-
use Symfony\AI\Platform\Bridge\Mistral\TokenOutputProcessor as MistralTokenOutputProcessor;
4848
use Symfony\AI\Platform\Bridge\Ollama\Contract\OllamaContract;
4949
use Symfony\AI\Platform\Bridge\Ollama\ModelCatalog as OllamaModelCatalog;
5050
use Symfony\AI\Platform\Bridge\OpenAi\Contract\OpenAiContract;
51+
use Symfony\AI\Platform\Bridge\OpenAi\Gpt\TokenUsageExtractor as OpenAiTokenOutputProcessor;
5152
use Symfony\AI\Platform\Bridge\OpenAi\ModelCatalog as OpenAiModelCatalog;
52-
use Symfony\AI\Platform\Bridge\OpenAi\TokenOutputProcessor as OpenAiTokenOutputProcessor;
5353
use Symfony\AI\Platform\Bridge\OpenRouter\ModelCatalog as OpenRouterModelCatalog;
5454
use Symfony\AI\Platform\Bridge\Perplexity\Contract\PerplexityContract;
5555
use Symfony\AI\Platform\Bridge\Perplexity\ModelCatalog as PerplexityModelCatalog;
5656
use Symfony\AI\Platform\Bridge\Perplexity\SearchResultProcessor as PerplexitySearchResultProcessor;
57-
use Symfony\AI\Platform\Bridge\Perplexity\TokenOutputProcessor as PerplexityTokenOutputProcessor;
57+
use Symfony\AI\Platform\Bridge\Perplexity\TokenUsageExtractor as PerplexityTokenOutputProcessor;
5858
use Symfony\AI\Platform\Bridge\Replicate\ModelCatalog as ReplicateModelCatalog;
5959
use Symfony\AI\Platform\Bridge\Scaleway\ModelCatalog as ScalewayModelCatalog;
6060
use Symfony\AI\Platform\Bridge\VertexAi\Contract\GeminiContract as VertexAiGeminiContract;
61+
use Symfony\AI\Platform\Bridge\VertexAi\Gemini\TokenOutputProcessor as VertexAiTokenOutputProcessor;
6162
use Symfony\AI\Platform\Bridge\VertexAi\ModelCatalog as VertexAiModelCatalog;
62-
use Symfony\AI\Platform\Bridge\VertexAi\TokenOutputProcessor as VertexAiTokenOutputProcessor;
6363
use Symfony\AI\Platform\Bridge\Voyage\ModelCatalog as VoyageModelCatalog;
6464
use Symfony\AI\Platform\Contract;
6565
use Symfony\AI\Platform\Contract\JsonSchema\DescriptionParser;

src/platform/src/Bridge/Anthropic/ResultConverter.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ public function convert(RawHttpResult|RawResultInterface $result, array $options
7777
return new TextResult($data['content'][0]['text']);
7878
}
7979

80+
public function getTokenUsageExtractor(): TokenUsageExtractor
81+
{
82+
return new TokenUsageExtractor();
83+
}
84+
8085
private function convertStream(RawResultInterface $result): \Generator
8186
{
8287
foreach ($result->getDataStream() as $data) {

0 commit comments

Comments
 (0)