PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 0.9.85
AI Engine – The Chatbot, AI Framework & MCP for WordPress v0.9.85
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 / ai.php
ai-engine / classes Last commit date
modules 3 years ago admin.php 3 years ago ai.php 3 years ago answer.php 3 years ago core.php 3 years ago init.php 3 years ago openai.php 3 years ago query.php 3 years ago queryimage.php 3 years ago querytext.php 3 years ago rest.php 3 years ago ui.php 3 years ago
ai.php
215 lines
1 <?php
2
3 class Meow_MWAI_AI {
4 private $core = null;
5 private $localApiKey = null;
6
7 public function __construct( $core ) {
8 $this->core = $core;
9 $this->localApiKey = $this->core->get_option( 'openai_apikey' );
10 }
11
12 // Record usage of the API on a monthly basis
13 public function record_usage( $model, $prompt_tokens, $completion_tokens = 0 ) {
14 if ( !is_numeric( $prompt_tokens ) ) {
15 throw new Exception( 'Record usage: prompt_tokens is not a number.' );
16 }
17 if ( !is_numeric( $completion_tokens ) ) {
18 $completion_tokens = 0;
19 }
20 if ( !$model ) {
21 throw new Exception( 'Record usage: model is missing.' );
22 }
23 $usage = $this->core->get_option( 'openai_usage' );
24 $month = date( 'Y-m' );
25 if ( !isset( $usage[$month] ) ) {
26 $usage[$month] = array();
27 }
28 if ( !isset( $usage[$month][$model] ) ) {
29 $usage[$month][$model] = array(
30 'prompt_tokens' => 0,
31 'completion_tokens' => 0,
32 'total_tokens' => 0
33 );
34 }
35 $usage[$month][$model]['prompt_tokens'] += $prompt_tokens;
36 $usage[$month][$model]['completion_tokens'] += $completion_tokens;
37 $usage[$month][$model]['total_tokens'] += $prompt_tokens + $completion_tokens;
38 $this->core->update_option( 'openai_usage', $usage );
39 return [
40 'prompt_tokens' => $prompt_tokens,
41 'completion_tokens' => $completion_tokens,
42 'total_tokens' => $prompt_tokens + $completion_tokens
43 ];
44 }
45
46 public function record_image_usage( $model, $resolution, $images ) {
47 if ( !$model || !$resolution || !$images ) {
48 throw new Exception( 'Missing parameters for record_dalle_usage.' );
49 }
50 $usage = $this->core->get_option( 'openai_usage' );
51 $month = date( 'Y-m' );
52 if ( !isset( $usage[$month] ) ) {
53 $usage[$month] = array();
54 }
55 if ( !isset( $usage[$month][$model] ) ) {
56 $usage[$month][$model] = array(
57 'resolution' => array(),
58 'images' => 0
59 );
60 }
61 if ( !isset( $usage[$month][$model]['resolution'][$resolution] ) ) {
62 $usage[$month][$model]['resolution'][$resolution] = 0;
63 }
64 $usage[$month][$model]['resolution'][$resolution] += $images;
65 $usage[$month][$model]['images'] += $images;
66 $this->core->update_option( 'openai_usage', $usage );
67 return [
68 'resolution' => $resolution,
69 'images' => $images
70 ];
71 }
72
73 public function runTextQuery( $query ) {
74 if ( empty( $query->apiKey ) ) {
75 $query->apiKey = $this->localApiKey;
76 }
77 $url = 'https://api.openai.com/v1/completions';
78 $options = array(
79 "headers" => "Content-Type: application/json\r\n" . "Authorization: Bearer " . $query->apiKey . "\r\n",
80 "method" => "POST",
81 "timeout" => 120,
82 "body" => json_encode( array(
83 "model" => $query->model,
84 "prompt" => $query->prompt,
85 "stop" => $query->stop,
86 "n" => $query->maxResults,
87 "max_tokens" => $query->maxTokens,
88 "temperature" => $query->temperature,
89 ) ),
90 "sslverify" => false
91 );
92
93 try {
94 $response = wp_remote_get( $url, $options );
95 if ( is_wp_error( $response ) ) {
96 throw new Exception( $response->get_error_message() );
97 }
98 $response = wp_remote_retrieve_body( $response );
99 $data = json_decode( $response, true );
100
101 // Error handling
102 if ( isset( $data['error'] ) ) {
103 $message = $data['error']['message'];
104 // If the message contains "Incorrect API key provided: THE_KEY.", replace the key by "----".
105 if ( preg_match( '/API key provided(: .*)\./', $message, $matches ) ) {
106 $message = str_replace( $matches[1], '', $message );
107 }
108 throw new Exception( $message );
109 }
110 if ( !$data['model'] ) {
111 error_log( print_r( $data, 1 ) );
112 throw new Exception( "Got an unexpected response from OpenAI. Check your PHP Error Logs." );
113 }
114 $answer = new Meow_MWAI_Answer( $query );
115 $usage = $this->record_usage( $data['model'], $data['usage']['prompt_tokens'],
116 $data['usage']['completion_tokens'] );
117 $answer->setUsage( $usage );
118 $answer->setChoices( $data['choices'] );
119 return $answer;
120 }
121 catch ( Exception $e ) {
122 error_log( $e->getMessage() );
123 throw new Exception( 'Error while calling OpenAI: ' . $e->getMessage() );
124 }
125 }
126
127 // Request to DALL-E API
128 public function runImageQuery( $query ) {
129 if ( empty( $query->apiKey ) ) {
130 $query->apiKey = $this->localApiKey;
131 }
132 $url = 'https://api.openai.com/v1/images/generations';
133 $options = array(
134 "headers" => "Content-Type: application/json\r\n" . "Authorization: Bearer " . $query->apiKey . "\r\n",
135 "method" => "POST",
136 "timeout" => 120,
137 "body" => json_encode( array(
138 "prompt" => $query->prompt,
139 "n" => $query->maxResults,
140 "size" => '1024x1024',
141 ) ),
142 "sslverify" => false
143 );
144
145 try {
146 $response = wp_remote_get( $url, $options );
147 if ( is_wp_error( $response ) ) {
148 throw new Exception( $response->get_error_message() );
149 }
150 $response = wp_remote_retrieve_body( $response );
151 $data = json_decode( $response, true );
152
153 // Error handling
154 if ( isset( $data['error'] ) ) {
155 $message = $data['error']['message'];
156 // If the message contains "Incorrect API key provided: THE_KEY.", replace the key by "----".
157 if ( preg_match( '/API key provided(: .*)\./', $message, $matches ) ) {
158 $message = str_replace( $matches[1], '', $message );
159 }
160 throw new Exception( $message );
161 }
162
163 $answer = new Meow_MWAI_Answer( $query );
164 $usage = $this->record_image_usage( "dall-e", "1024x1024", $query->maxResults );
165 $answer->setUsage( $usage );
166 $answer->setChoices( $data['data'] );
167 return $answer;
168 }
169 catch ( Exception $e ) {
170 error_log( $e->getMessage() );
171 throw new Exception( 'Error while calling OpenAI: ' . $e->getMessage() );
172 }
173 }
174
175 public function throwException( $message ) {
176 $message = apply_filters( 'mwai_ai_exception', $message );
177 throw new Exception( $message );
178 }
179
180 public function run( $query ) {
181
182 // Check if the query is allowed
183 $limits = $this->core->get_option( 'limits' );
184 $ok = apply_filters( 'mwai_ai_allowed', true, $query, $limits );
185 if ( $ok !== true ) {
186 $message = is_string( $ok ) ? $ok : 'Unauthorized query.';
187 $this->throwException( $message );
188 }
189
190 // Allow to modify the query
191 $query = apply_filters( 'mwai_ai_query', $query );
192
193 // Run the query
194 $answer = null;
195 try {
196 if ( $query instanceof Meow_MWAI_QueryText ) {
197 $answer = $this->runTextQuery( $query );
198 }
199 else if ( $query instanceof Meow_MWAI_QueryImage ) {
200 $answer = $this->runImageQuery( $query );
201 }
202 else {
203 $this->throwException( 'Invalid query.' );
204 }
205 }
206 catch ( Exception $e ) {
207 $this->throwException( $e->getMessage() );
208 }
209
210 // Let's allow some modififications of the answer
211 $answer = apply_filters( 'mwai_ai_reply', $answer, $query );
212 return $answer;
213 }
214 }
215