Skip to content

Commit ff08204

Browse files
committed
feature #388 [Platform] Add Perplexity (welcoMattic)
This PR was squashed before being merged into the main branch. Discussion ---------- [Platform] Add Perplexity | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes <!-- please update src/**/CHANGELOG.md files --> | Docs? | no <!-- required for new features --> | Issues | Fix #... <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead --> | License | MIT This PR adds Perplexity as a supported Platform. Models are: sonar, sonar-pro, sonar-reasoning, sonar-reasoning-pro, and sonar-deep-research API is similar to OpenAI API, with additional features I will take care of in coming days. Perplexity docs: - https://docs.perplexity.ai/api-reference/chat-completions-post - https://docs.perplexity.ai/guides/streaming - https://docs.perplexity.ai/guides/search-domain-filters - https://docs.perplexity.ai/guides/image-guide - https://docs.perplexity.ai/guides/pdf-uploads Commits ------- 5e7f2f2 [Platform] Add Perplexity
2 parents a29a7b2 + 5e7f2f2 commit ff08204

24 files changed

+1312
-1
lines changed

examples/bootstrap.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,53 @@ function print_vectors(ResultPromise $result): void
8080

8181
echo 'Dimensions: '.$result->asVectors()[0]->getDimensions().\PHP_EOL;
8282
}
83+
84+
function perplexity_print_search_results(Metadata $metadata): void
85+
{
86+
$searchResults = $metadata->get('search_results');
87+
88+
if (null === $searchResults) {
89+
return;
90+
}
91+
92+
echo 'Search results:'.\PHP_EOL;
93+
94+
if (0 === count($searchResults)) {
95+
echo 'No search results.'.\PHP_EOL;
96+
97+
return;
98+
}
99+
100+
foreach ($searchResults as $i => $searchResult) {
101+
echo 'Result #'.($i + 1).':'.\PHP_EOL;
102+
echo $searchResult['title'].\PHP_EOL;
103+
echo $searchResult['url'].\PHP_EOL;
104+
echo $searchResult['date'].\PHP_EOL;
105+
echo $searchResult['last_updated'] ? $searchResult['last_updated'].\PHP_EOL : '';
106+
echo $searchResult['snippet'] ? $searchResult['snippet'].\PHP_EOL : '';
107+
echo \PHP_EOL;
108+
}
109+
}
110+
111+
function perplexity_print_citations(Metadata $metadata): void
112+
{
113+
$citations = $metadata->get('citations');
114+
115+
if (null === $citations) {
116+
return;
117+
}
118+
119+
echo 'Citations:'.\PHP_EOL;
120+
121+
if (0 === count($citations)) {
122+
echo 'No citations.'.\PHP_EOL;
123+
124+
return;
125+
}
126+
127+
foreach ($citations as $i => $citation) {
128+
echo 'Citation #'.($i + 1).':'.\PHP_EOL;
129+
echo $citation.\PHP_EOL;
130+
echo \PHP_EOL;
131+
}
132+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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+
use Symfony\AI\Agent\Agent;
13+
use Symfony\AI\Platform\Bridge\Perplexity\Perplexity;
14+
use Symfony\AI\Platform\Bridge\Perplexity\PlatformFactory;
15+
use Symfony\AI\Platform\Bridge\Perplexity\SearchResultProcessor;
16+
use Symfony\AI\Platform\Message\Message;
17+
use Symfony\AI\Platform\Message\MessageBag;
18+
19+
require_once dirname(__DIR__).'/bootstrap.php';
20+
21+
$platform = PlatformFactory::create(env('PERPLEXITY_API_KEY'), http_client());
22+
$model = new Perplexity();
23+
$agent = new Agent($platform, $model, outputProcessors: [new SearchResultProcessor()], logger: logger());
24+
25+
$messages = new MessageBag(Message::ofUser('What is the best French cheese of the first quarter-century of 21st century?'));
26+
$response = $agent->call($messages, [
27+
'search_mode' => 'academic',
28+
'search_after_date_filter' => '01/01/2000',
29+
'search_before_date_filter' => '01/01/2025',
30+
]);
31+
32+
echo $response->getContent().\PHP_EOL;
33+
echo \PHP_EOL;
34+
35+
perplexity_print_search_results($response->getMetadata());
36+
perplexity_print_citations($response->getMetadata());

examples/perplexity/chat.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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+
use Symfony\AI\Agent\Agent;
13+
use Symfony\AI\Platform\Bridge\Perplexity\Perplexity;
14+
use Symfony\AI\Platform\Bridge\Perplexity\PlatformFactory;
15+
use Symfony\AI\Platform\Message\Message;
16+
use Symfony\AI\Platform\Message\MessageBag;
17+
18+
require_once dirname(__DIR__).'/bootstrap.php';
19+
20+
$platform = PlatformFactory::create(env('PERPLEXITY_API_KEY'), http_client());
21+
$model = new Perplexity();
22+
$agent = new Agent($platform, $model);
23+
24+
$messages = new MessageBag(Message::ofUser('What is the best French cheese?'));
25+
$response = $agent->call($messages);
26+
27+
echo $response->getContent().\PHP_EOL;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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+
use Symfony\AI\Agent\Agent;
13+
use Symfony\AI\Platform\Bridge\Perplexity\Perplexity;
14+
use Symfony\AI\Platform\Bridge\Perplexity\PlatformFactory;
15+
use Symfony\AI\Platform\Message\Message;
16+
use Symfony\AI\Platform\Message\MessageBag;
17+
18+
require_once dirname(__DIR__).'/bootstrap.php';
19+
20+
$platform = PlatformFactory::create(env('PERPLEXITY_API_KEY'), http_client());
21+
$model = new Perplexity();
22+
$agent = new Agent($platform, $model, logger: logger());
23+
24+
$messages = new MessageBag(Message::ofUser('What is 2 + 2?'));
25+
$response = $agent->call($messages, [
26+
'disable_search' => true,
27+
]);
28+
29+
echo $response->getContent().\PHP_EOL;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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+
use Symfony\AI\Agent\Agent;
13+
use Symfony\AI\Platform\Bridge\Perplexity\Perplexity;
14+
use Symfony\AI\Platform\Bridge\Perplexity\PlatformFactory;
15+
use Symfony\AI\Platform\Bridge\Perplexity\SearchResultProcessor;
16+
use Symfony\AI\Platform\Message\Content\ImageUrl;
17+
use Symfony\AI\Platform\Message\Message;
18+
use Symfony\AI\Platform\Message\MessageBag;
19+
20+
require_once dirname(__DIR__).'/bootstrap.php';
21+
22+
$platform = PlatformFactory::create(env('PERPLEXITY_API_KEY'), http_client());
23+
$model = new Perplexity();
24+
$agent = new Agent($platform, $model, outputProcessors: [new SearchResultProcessor()], logger: logger());
25+
26+
$messages = new MessageBag(
27+
Message::forSystem('You are an image analyzer bot that helps identify the content of images.'),
28+
Message::ofUser(
29+
'Describe the image as a comedian would do it.',
30+
new ImageUrl('https://upload.wikimedia.org/wikipedia/commons/thumb/3/31/Webysther_20160423_-_Elephpant.svg/350px-Webysther_20160423_-_Elephpant.svg.png'),
31+
),
32+
);
33+
$result = $agent->call($messages);
34+
35+
echo $result->getContent().\PHP_EOL;
36+
37+
perplexity_print_search_results($result->getMetadata());
38+
perplexity_print_citations($result->getMetadata());
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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+
use Symfony\AI\Agent\Agent;
13+
use Symfony\AI\Platform\Bridge\Perplexity\Perplexity;
14+
use Symfony\AI\Platform\Bridge\Perplexity\PlatformFactory;
15+
use Symfony\AI\Platform\Bridge\Perplexity\SearchResultProcessor;
16+
use Symfony\AI\Platform\Message\Content\DocumentUrl;
17+
use Symfony\AI\Platform\Message\Message;
18+
use Symfony\AI\Platform\Message\MessageBag;
19+
20+
require_once dirname(__DIR__).'/bootstrap.php';
21+
22+
$platform = PlatformFactory::create(env('PERPLEXITY_API_KEY'), http_client());
23+
$model = new Perplexity();
24+
$agent = new Agent($platform, $model, outputProcessors: [new SearchResultProcessor()], logger: logger());
25+
26+
$messages = new MessageBag(
27+
Message::ofUser(
28+
new DocumentUrl('https://upload.wikimedia.org/wikipedia/commons/2/20/Re_example.pdf'),
29+
'What is this document about?',
30+
),
31+
);
32+
$result = $agent->call($messages);
33+
34+
echo $result->getContent().\PHP_EOL;
35+
$result = $agent->call($messages);
36+
37+
echo $result->getContent().\PHP_EOL;
38+
39+
perplexity_print_search_results($result->getMetadata());
40+
perplexity_print_citations($result->getMetadata());

examples/perplexity/stream.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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+
use Symfony\AI\Agent\Agent;
13+
use Symfony\AI\Platform\Bridge\Perplexity\Perplexity;
14+
use Symfony\AI\Platform\Bridge\Perplexity\PlatformFactory;
15+
use Symfony\AI\Platform\Bridge\Perplexity\SearchResultProcessor;
16+
use Symfony\AI\Platform\Message\Message;
17+
use Symfony\AI\Platform\Message\MessageBag;
18+
19+
require_once dirname(__DIR__).'/bootstrap.php';
20+
21+
$platform = PlatformFactory::create(env('PERPLEXITY_API_KEY'), http_client());
22+
$model = new Perplexity();
23+
$agent = new Agent($platform, $model, outputProcessors: [new SearchResultProcessor()], logger: logger());
24+
25+
$messages = new MessageBag(
26+
Message::forSystem('You are a thoughtful philosopher.'),
27+
Message::ofUser('What is the purpose of an ant?'),
28+
);
29+
$result = $agent->call($messages, [
30+
'stream' => true,
31+
]);
32+
33+
foreach ($result->getContent() as $word) {
34+
echo $word;
35+
}
36+
echo \PHP_EOL;
37+
38+
perplexity_print_search_results($result->getMetadata());
39+
perplexity_print_citations($result->getMetadata());
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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+
use Symfony\AI\Agent\Agent;
13+
use Symfony\AI\Platform\Bridge\Perplexity\Perplexity;
14+
use Symfony\AI\Platform\Bridge\Perplexity\PlatformFactory;
15+
use Symfony\AI\Platform\Bridge\Perplexity\TokenOutputProcessor;
16+
use Symfony\AI\Platform\Message\Message;
17+
use Symfony\AI\Platform\Message\MessageBag;
18+
19+
require_once dirname(__DIR__).'/bootstrap.php';
20+
21+
$platform = PlatformFactory::create(env('PERPLEXITY_API_KEY'), http_client());
22+
$model = new Perplexity();
23+
$agent = new Agent($platform, $model, outputProcessors: [new TokenOutputProcessor()], logger: logger());
24+
25+
$messages = new MessageBag(
26+
Message::forSystem('You are a pirate and you write funny.'),
27+
Message::ofUser('What is the Symfony framework?'),
28+
);
29+
$result = $agent->call($messages, [
30+
'model' => Perplexity::SONAR_DEEP_RESEARCH,
31+
'max_tokens' => 500, // specific options just for this call
32+
]);
33+
34+
print_token_usage($result->getMetadata());

examples/perplexity/web-search.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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+
use Symfony\AI\Agent\Agent;
13+
use Symfony\AI\Platform\Bridge\Perplexity\Perplexity;
14+
use Symfony\AI\Platform\Bridge\Perplexity\PlatformFactory;
15+
use Symfony\AI\Platform\Message\Message;
16+
use Symfony\AI\Platform\Message\MessageBag;
17+
18+
require_once dirname(__DIR__).'/bootstrap.php';
19+
20+
$platform = PlatformFactory::create(env('PERPLEXITY_API_KEY'), http_client());
21+
$model = new Perplexity();
22+
$agent = new Agent($platform, $model, logger: logger());
23+
24+
$messages = new MessageBag(Message::ofUser('What is the best French cheese?'));
25+
$response = $agent->call($messages, [
26+
'search_domain_filter' => [
27+
'https://en.wikipedia.org/wiki/Cheese',
28+
],
29+
'search_mode' => 'web',
30+
'enable_search_classifier' => true,
31+
'search_recency_filter' => 'week',
32+
]);
33+
34+
echo $response->getContent().\PHP_EOL;

src/platform/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ CHANGELOG
66

77
* Add support for Albert API for French/EU data sovereignty
88
* Add unified abstraction layer for interacting with various AI models and providers
9-
* Add support for 13+ AI providers:
9+
* Add support for 15+ AI providers:
1010
- OpenAI (GPT-4, GPT-3.5, DALL·E, Whisper)
1111
- Anthropic (Claude models via native API and AWS Bedrock)
1212
- Google (VertexAi and Gemini models with server-side tools support)
@@ -22,6 +22,7 @@ CHANGELOG
2222
- TransformersPHP (local PHP-based transformer models)
2323
- LM Studio (local model hosting)
2424
- Cerebras (language models like Llama 4, Qwen 3, and more)
25+
- Perplexity (Sonar models, supporting search results)
2526
* Add comprehensive message system with role-based messaging:
2627
- `UserMessage` for user inputs with multi-modal content
2728
- `SystemMessage` for system instructions

0 commit comments

Comments
 (0)