PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 2.8.5
AI Engine – The Chatbot, AI Framework & MCP for WordPress v2.8.5
3.5.7 3.5.6 3.5.5 3.5.4 3.5.3 3.5.2 3.5.1 3.5.0 3.4.9 3.4.8 3.4.7 0.2.1 1.6.91 0.2.2 1.6.92 0.2.3 1.6.93 0.2.4 1.6.94 0.2.5 1.6.95 0.2.6 1.6.96 0.2.7 1.6.97 0.2.8 1.6.98 0.2.9 1.6.99 0.3.0 1.7.0 0.3.1 1.7.1 0.3.2 1.7.2 0.3.3 1.7.3 0.3.4 1.7.4 0.3.5 1.7.5 0.3.6 1.7.6 0.4.0 1.7.7 0.4.1 1.7.8 0.4.2 1.7.9 0.4.3 1.8.0 0.4.4 1.8.1 0.4.5 1.8.2 0.4.6 1.8.3 0.4.7 1.8.4 0.4.8 1.8.5 0.4.9 1.8.6 0.5.0 1.8.7 0.5.1 1.8.8 0.5.2 1.8.9 0.5.3 1.9.0 0.5.4 1.9.1 0.5.5 1.9.2 0.5.6 1.9.3 0.5.7 1.9.4 0.5.8 1.9.5 0.5.9 1.9.6 0.6.0 1.9.7 0.6.1 1.9.8 0.6.2 1.9.81 0.6.3 1.9.82 0.6.4 1.9.83 0.6.5 1.9.84 0.6.6 1.9.85 0.6.7 1.9.86 0.6.8 1.9.87 0.6.9 1.9.88 0.7.0 1.9.89 0.7.1 1.9.90 0.7.2 1.9.91 0.7.3 1.9.92 0.7.4 1.9.93 0.7.5 1.9.94 0.7.6 1.9.95 0.7.7 1.9.96 0.7.8 1.9.97 0.7.9 1.9.98 0.8.0 1.9.99 0.8.1 2.0.0 0.8.2 2.0.1 0.8.3 2.0.2 0.8.4 2.0.3 0.8.5 2.0.4 0.8.6 2.0.5 0.8.7 2.0.6 0.8.8 2.0.7 0.8.9 2.0.8 0.9.0 2.0.9 0.9.2 2.1.0 0.9.3 2.1.1 0.9.4 2.1.2 0.9.5 2.1.3 0.9.6 2.1.4 0.9.7 2.1.5 0.9.8 2.1.6 0.9.81 2.1.7 0.9.82 2.1.8 0.9.83 2.1.9 0.9.84 2.2.0 0.9.85 2.2.1 0.9.86 2.2.2 0.9.87 2.2.3 0.9.88 2.2.4 0.9.89 2.2.5 0.9.9 2.2.51 0.9.91 2.2.52 0.9.92 2.2.53 0.9.93 2.2.54 0.9.94 2.2.56 0.9.95 2.2.57 0.9.96 2.2.6 0.9.97 2.2.60 0.9.98 2.2.61 0.9.99 2.2.62 1.0.0 2.2.63 1.0.01 2.2.70 1.0.1 2.2.80 1.0.2 2.2.81 1.0.3 2.2.90 1.0.4 2.2.91 1.0.5 2.2.92 1.0.6 2.2.93 1.0.7 2.2.94 1.0.8 2.2.95 1.0.9 2.3.0 1.1.0 2.3.1 1.1.1 2.3.2 1.1.2 2.3.3 1.1.3 2.3.4 1.1.4 2.3.5 1.1.5 2.3.6 1.1.6 2.3.7 1.1.7 2.3.8 1.1.8 2.3.9 1.1.9 2.4.0 1.2.0 2.4.1 1.2.1 2.4.2 1.2.2 2.4.3 1.2.21 2.4.4 1.2.3 2.4.5 1.2.30 2.4.6 1.3.0 2.4.7 1.3.1 2.4.8 1.3.2 2.4.9 1.3.3 2.5.0 1.3.31 2.5.1 1.3.32 2.5.2 1.3.33 2.5.3 1.3.34 2.5.4 1.3.35 2.5.5 1.3.36 2.5.6 1.3.37 2.5.7 1.3.38 2.5.8 1.3.39 2.5.9 1.3.40 2.6.0 1.3.41 2.6.1 1.3.42 2.6.2 1.3.43 2.6.3 1.3.44 2.6.5 1.3.45 2.6.6 1.3.46 2.6.7 1.3.47 2.6.8 1.3.48 2.6.9 1.3.49 2.7.0 1.3.50 2.7.1 1.3.51 2.7.2 1.3.52 2.7.3 1.3.53 2.7.4 1.3.54 2.7.5 1.3.56 2.7.6 1.3.57 2.7.7 1.3.58 2.7.8 1.3.59 2.7.9 1.3.60 2.8.0 1.3.61 2.8.1 1.3.62 2.8.2 1.3.63 2.8.3 1.3.64 2.8.4 1.3.65 2.8.5 1.3.66 2.8.6 1.3.67 2.8.7 1.3.68 2.8.8 1.3.69 2.8.9 1.3.70 2.9.0 1.3.71 2.9.1 1.3.72 2.9.2 1.3.73 2.9.3 1.3.74 2.9.4 1.3.75 2.9.5 1.3.76 2.9.6 1.3.77 2.9.7 1.3.78 2.9.8 1.3.79 2.9.9 1.3.80 3.0.0 1.3.81 3.0.1 1.3.82 3.0.2 1.3.83 3.0.3 1.3.84 3.0.4 1.3.85 3.0.5 1.3.86 3.0.6 1.3.87 3.0.7 1.3.88 3.0.8 1.3.89 3.0.9 1.3.90 3.1.0 1.3.91 3.1.1 1.3.92 3.1.2 1.3.93 3.1.3 1.3.94 3.1.4 1.3.95 3.1.5 1.3.96 3.1.6 1.3.97 3.1.7 1.3.98 3.1.8 1.3.99 3.1.9 1.4.0 3.2.0 1.4.1 3.2.1 1.4.2 3.2.2 1.4.3 3.2.3 1.4.4 3.2.4 1.4.5 3.2.5 1.4.6 3.2.6 1.4.7 3.2.7 1.4.8 3.2.8 1.4.9 3.2.9 1.5.0 3.3.0 1.5.1 3.3.1 1.5.2 3.3.2 1.5.3 3.3.3 1.5.4 3.3.4 1.5.5 3.3.5 1.5.6 3.3.6 1.5.7 3.3.7 1.5.8 3.3.8 1.5.9 3.3.9 1.6.0 3.4.0 1.6.1 3.4.1 1.6.2 3.4.2 1.6.3 3.4.3 1.6.5 3.4.4 1.6.51 3.4.5 1.6.52 3.4.6 1.6.53 1.6.54 1.6.55 1.6.56 1.6.57 1.6.58 1.6.59 1.6.60 1.6.61 1.6.62 1.6.63 1.6.64 1.6.65 1.6.66 1.6.67 1.6.68 trunk 1.6.69 0.0.1 1.6.70 0.0.2 1.6.71 0.0.3 1.6.72 0.0.4 1.6.73 0.0.5 1.6.74 0.0.6 1.6.75 0.0.7 1.6.76 0.0.8 1.6.77 0.0.9 1.6.78 0.1.0 1.6.79 0.1.1 1.6.81 0.1.2 1.6.82 0.1.3 1.6.83 0.1.4 1.6.84 0.1.5 1.6.85 0.1.6 1.6.86 0.1.7 1.6.87 0.1.8 1.6.88 0.1.9 1.6.89 0.2.0 1.6.90
ai-engine / classes / engines / perplexity.php
ai-engine / classes / engines Last commit date
traits 1 year ago anthropic.php 1 year ago chatml.php 1 year ago core.php 1 year ago factory.php 1 year ago google.php 1 year ago hugging-face.php 1 year ago open-router.php 1 year ago openai.php 1 year ago perplexity.php 1 year ago replicate.php 1 year ago
perplexity.php
135 lines
1 <?php
2
3 class Meow_MWAI_Engines_Perplexity extends Meow_MWAI_Engines_ChatML {
4 // Streaming
5 protected $streamInTokens = null;
6 protected $streamOutTokens = null;
7 protected $streamContent = null;
8 protected $streamBuffer = null;
9 protected $inCitations = null;
10
11 public function __construct( $core, $env ) {
12 parent::__construct( $core, $env );
13 }
14
15 protected function set_environment() {
16 $env = $this->env;
17 $this->apiKey = $env['apikey'] ?? null;
18 }
19
20 protected function get_service_name() {
21 return 'Perplexity';
22 }
23
24 public function get_models() {
25 return apply_filters( 'mwai_perplexity_models', MWAI_PERPLEXITY_MODELS );
26 }
27
28 public static function get_models_static() {
29 return MWAI_PERPLEXITY_MODELS;
30 }
31
32 protected function build_url( $query, $endpoint = null ) {
33 $endpoint = apply_filters( 'mwai_perplexity_endpoint', 'https://api.perplexity.ai', $this->env );
34 return rtrim( $endpoint, '/' ) . '/chat/completions';
35 }
36
37 protected function build_messages( $query ) {
38 $messages = parent::build_messages( $query );
39 $filtered = [];
40 $haveSeenUser = false;
41 foreach ( $messages as $message ) {
42 if ( !$haveSeenUser ) {
43 if ( $message['role'] === 'assistant' ) {
44 continue;
45 }
46 if ( $message['role'] === 'user' ) {
47 $haveSeenUser = true;
48 }
49 $filtered[] = $message;
50 }
51 else {
52 $filtered[] = $message;
53 }
54 }
55
56 return $filtered;
57 }
58
59 protected function build_headers( $query ) {
60 if ( $query->apiKey ) {
61 $this->apiKey = $query->apiKey;
62 }
63 if ( empty( $this->apiKey ) ) {
64 throw new Exception( 'No Perplexity API Key provided. Check your settings.' );
65 }
66 return [
67 'Content-Type' => 'application/json',
68 'Authorization' => 'Bearer ' . $this->apiKey,
69 'User-Agent' => 'AI Engine',
70 ];
71 }
72
73 protected function build_body( $query, $streamCallback = null, $extra = null ) {
74 $body = parent::build_body( $query, $streamCallback, $extra );
75 return $body;
76 }
77
78 public function reset_stream() {
79 $this->inCitations = null;
80 return parent::reset_stream();
81 }
82
83 // Let's override the stream handler only to capture the citations
84 protected function stream_data_handler( $json ) {
85 if ( isset( $json['citations'] ) ) {
86 $this->inCitations = $json['citations'];
87 }
88 return parent::stream_data_handler( $json );
89 }
90
91 /**
92 * In Perplexity, we intercept the final choices and insert citations
93 * as ([domain1](https://...), [domain2](https://...))
94 * based on [1][2][3] references in the text.
95 */
96 protected function finalize_choices( $choices, $responseData, $query ) {
97 $citations = isset( $responseData['citations'] ) ? $responseData['citations'] : null;
98 if ( empty( $citations ) && !empty( $this->inCitations ) ) {
99 $citations = $this->inCitations;
100 }
101 if ( empty( $citations ) ) {
102 return parent::finalize_choices( $choices, $responseData, $query );
103 }
104
105 foreach ( $choices as &$choice ) {
106 if ( isset( $choice['message']['content'] ) && is_string( $choice['message']['content'] ) ) {
107 $content = $choice['message']['content'];
108 $content = preg_replace_callback( '/\[(\d+)\](?:\s*\[(\d+)\])*/', function ( $matches ) use ( $citations ) {
109 preg_match_all( '/\[(\d+)\]/', $matches[0], $refs );
110 $links = [];
111 foreach ( $refs[1] as $refNumber ) {
112 $index = (int) $refNumber - 1;
113 if ( isset( $citations[$index] ) ) {
114 $url = $citations[$index];
115 $domain = parse_url( $url, PHP_URL_HOST );
116 if ( !empty( $domain ) ) {
117 $domain = str_replace( 'www.', '', $domain );
118 }
119 $links[] = '[' . $domain . '](' . $url . ')';
120 }
121 }
122 // If we gathered at least one link, return them all in a parenthetical group
123 // e.g. " ([google.com](https://google.com), [othersite.io](https://othersite.io))"
124 // Otherwise, just return the original matches (fallback).
125 return !empty( $links ) ? ' (' . implode( ', ', $links ) . ')' : $matches[0];
126 }, $content );
127 $choice['message']['content'] = $content;
128 }
129 }
130
131 return $choices;
132 }
133
134 }
135