PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 2.2.53
AI Engine – The Chatbot, AI Framework & MCP for WordPress v2.2.53
3.5.8 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 / openrouter.php
ai-engine / classes / engines Last commit date
anthropic.php 2 years ago core.php 2 years ago factory.php 2 years ago google.php 2 years ago huggingface.php 2 years ago openai.php 2 years ago openrouter.php 2 years ago
openrouter.php
166 lines
1 <?php
2
3 class Meow_MWAI_Engines_OpenRouter extends Meow_MWAI_Engines_OpenAI
4 {
5
6 public function __construct( $core, $env )
7 {
8 parent::__construct( $core, $env );
9 }
10
11 protected function set_environment() {
12 $env = $this->env;
13 $this->apiKey = $env['apikey'];
14 }
15
16 protected function build_url( $query, $endpoint = null ) {
17 $endpoint = apply_filters( 'mwai_openrouter_endpoint', 'https://openrouter.ai/api/v1', $this->env );
18 $url = parent::build_url( $query, $endpoint );
19 return $url;
20 }
21
22 protected function build_headers( $query ) {
23 parent::build_headers( $query );
24 $site_url = apply_filters( 'mwai_openrouter_site_url', get_site_url(), $query );
25 $site_name = apply_filters( 'mwai_openrouter_site_name', get_bloginfo( 'name' ), $query );
26 $headers = array(
27 'Content-Type' => 'application/json',
28 'Authorization' => 'Bearer ' . $this->apiKey,
29 'HTTP-Referer' => $site_url,
30 'X-Title' => $site_name,
31 'User-Agent' => 'AI Engine',
32 );
33 return $headers;
34 }
35
36 private function truncate_float( $number, $precision = 4 ) {
37 $factor = pow( 10, $precision );
38 return floor( $number * $factor ) / $factor;
39 }
40
41 protected function get_service_name() {
42 return "OpenRouter";
43 }
44
45 public function get_models() {
46 return $this->core->get_option( 'openrouter_models' );
47 }
48
49 public function handle_tokens_usage( $reply, $query, $returned_model, $returned_in_tokens, $returned_out_tokens ) {
50 $returned_in_tokens = !is_null( $returned_in_tokens ) ? $returned_in_tokens : $reply->get_in_tokens( $query );
51 $returned_out_tokens = !is_null( $returned_out_tokens ) ? $returned_out_tokens : $reply->get_out_tokens();
52
53 // This is how to retrieve the exact number of tokens used with OpenRouter.
54 // However, it doesn't work with streaming and it slows the request.
55
56 if ( !empty( $reply->id ) ) {
57 $url = 'https://openrouter.ai/api/v1/generation?id=' . $reply->id;
58 try {
59
60 // This is the CURL way
61 // $ch = curl_init();
62 // curl_setopt( $ch, CURLOPT_URL, $url );
63 // curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
64 // curl_setopt( $ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer ' . $this->apiKey ] );
65 // curl_setopt( $ch, CURLOPT_USERAGENT, 'AI Engine' );
66 // $res = curl_exec( $ch );
67 // curl_close( $ch );
68 // $res = json_decode( $res, true );
69
70 // This is the WordPress way
71 // It currently doesn't work with OpenRouter (for mysterious reasons)
72 // $res = wp_remote_get( $url, array(
73 // 'headers' => array(
74 // 'Authorization' => 'Bearer ' . $this->apiKey,
75 // 'User-Agent' => 'AI Engine',
76 // 'Accept' => 'application/json',
77 // ),
78 // 'sslverify' => false,
79 // 'user-agent' => 'AI Engine',
80 // 'timeout' => 30,
81 // 'blocking' => false,
82 // ) );
83
84 if ( isset( $res['data'] ) ) {
85 $data = $res['data'];
86 $returned_model = $data['model'];
87 $returned_in_tokens = $data['tokens_prompt'];
88 $returned_out_tokens = $data['tokens_completion'];
89 $price = $res['usage'];
90 $usage = $this->core->record_tokens_usage( $returned_model, $returned_in_tokens, $returned_out_tokens );
91 $reply->set_usage( $usage );
92 return;
93 }
94 }
95 catch ( Exception $e ) {
96 error_log( $e->getMessage() );
97 }
98 }
99
100 $usage = $this->core->record_tokens_usage( $returned_model, $returned_in_tokens, $returned_out_tokens );
101 $reply->set_usage( $usage );
102 }
103
104 public function get_price( Meow_MWAI_Query_Base $query, Meow_MWAI_Reply $reply ) {
105 return parent::get_price( $query, $reply );
106 }
107
108 public function retrieve_models() {
109 $url = 'https://openrouter.ai/api/v1/models';
110 $response = wp_remote_get( $url );
111 if ( is_wp_error( $response ) ) {
112 throw new Exception( 'AI Engine: ' . $response->get_error_message() );
113 }
114 $body = json_decode( $response['body'], true );
115 $models = array();
116 foreach ( $body['data'] as $model ) {
117 $family = "n/a";
118 $maxCompletionTokens = 4096;
119 $maxContextualTokens = 8096;
120 $priceIn = 0;
121 $priceOut = 0;
122 $family = explode( '/', $model['id'] )[0];
123 if ( isset( $model['top_provider']['max_completion_tokens'] ) ) {
124 $maxCompletionTokens = (int)$model['top_provider']['max_completion_tokens'];
125 }
126 if ( isset( $model['context_length'] ) ) {
127 $maxContextualTokens = (int)$model['context_length'];
128 }
129 if ( isset( $model['pricing']['prompt'] ) && $model['pricing']['prompt'] > 0 ) {
130 $priceIn = floatval( $model['pricing']['prompt'] ) * 1000;
131 $priceIn = $this->truncate_float( $priceIn );
132 }
133 if ( isset( $model['pricing']['completion'] ) && $model['pricing']['completion'] > 0 ) {
134 $priceOut = floatval( $model['pricing']['completion'] ) * 1000;
135 $priceOut = $this->truncate_float( $priceOut );
136 }
137
138 $tags = [ 'core', 'chat' ];
139 // If the name contains (beta), (alpha) or (preview), add 'preview' tag and remove from name
140 if ( preg_match( '/\((beta|alpha|preview)\)/i', $model['name'], $matches ) ) {
141 $tags[] = 'preview';
142 $model['name'] = preg_replace( '/\((beta|alpha|preview)\)/i', '', $model['name'] );
143 }
144 // If the name includes 'Vision', add 'vision' tag
145 if ( preg_match( '/vision/i', $model['name'], $matches ) ) {
146 $tags[] = 'vision';
147 }
148 $models[] = array(
149 'model' => $model['id'],
150 'name' => trim( $model['name'] ),
151 'family' => $family,
152 'mode' => 'chat',
153 'price' => array(
154 'in' => $priceIn,
155 'out' => $priceOut,
156 ),
157 'type' => 'token',
158 'unit' => 1 / 1000,
159 'maxCompletionTokens' => $maxCompletionTokens,
160 'maxContextualTokens' => $maxContextualTokens,
161 'tags' => $tags
162 );
163 }
164 return $models;
165 }
166 }