PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 3.6.0
AI Engine – The Chatbot, AI Framework & MCP for WordPress v3.6.0
3.6.0 3.5.9 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 / labs / wpai-gateway-directory.php
ai-engine / labs Last commit date
mcp-core.php 14 hours ago mcp-oauth.php 1 month ago mcp-rest.php 3 weeks ago mcp.conf 1 year ago mcp.js 8 months ago mcp.md 8 months ago mcp.php 1 week ago wpai-connectors.php 2 months ago wpai-gateway-availability.php 2 months ago wpai-gateway-directory.php 2 months ago wpai-gateway-image-model.php 2 months ago wpai-gateway-model.php 2 months ago wpai-gateway-providers.php 2 months ago wpai-gateway.php 2 months ago
wpai-gateway-directory.php
167 lines
1 <?php
2 /**
3 * Exposes AI Engine's models to the WP AI framework.
4 *
5 * The directory can be scoped to a single engine type (e.g. only the
6 * OpenAI-engine models), or list every model AI Engine knows when no scope
7 * is given. Source of truth is `options.ai_engines[].models`.
8 */
9
10 use WordPress\AiClient\Messages\Enums\ModalityEnum;
11 use WordPress\AiClient\Providers\Contracts\ModelMetadataDirectoryInterface;
12 use WordPress\AiClient\Providers\Models\DTO\ModelMetadata;
13 use WordPress\AiClient\Providers\Models\DTO\SupportedOption;
14 use WordPress\AiClient\Providers\Models\Enums\CapabilityEnum;
15 use WordPress\AiClient\Providers\Models\Enums\OptionEnum;
16
17 class Meow_MWAI_Labs_WPAI_Gateway_Directory implements ModelMetadataDirectoryInterface {
18
19 private ?string $engine_type;
20
21 public function __construct( ?string $engine_type = null ) {
22 $this->engine_type = $engine_type;
23 }
24
25 public function listModelMetadata(): array {
26 $models = [];
27 foreach ( $this->iterate_models() as $id => $model ) {
28 $models[] = $this->make_metadata( $id, $model );
29 }
30 return $models;
31 }
32
33 public function hasModelMetadata( string $modelId ): bool {
34 foreach ( $this->iterate_models() as $id => $_m ) {
35 if ( $id === $modelId ) {
36 return true;
37 }
38 }
39 return false;
40 }
41
42 public function getModelMetadata( string $modelId ): ModelMetadata {
43 foreach ( $this->iterate_models() as $id => $model ) {
44 if ( $id === $modelId ) {
45 return $this->make_metadata( $id, $model );
46 }
47 }
48 throw new \WordPress\AiClient\Common\Exception\InvalidArgumentException(
49 sprintf( 'Unknown AI Engine model: %s', $modelId )
50 );
51 }
52
53 private function iterate_models(): iterable {
54 $core = Meow_MWAI_Labs_WPAI_Gateway::$core;
55 if ( ! $core ) {
56 return;
57 }
58 $options = $core->get_all_options();
59 $engines = $options['ai_engines'] ?? [];
60 foreach ( $engines as $engine ) {
61 $engine_type = $engine['type'] ?? '';
62 if ( $this->engine_type !== null && $engine_type !== $this->engine_type ) {
63 continue;
64 }
65 if ( empty( $engine['models'] ) || ! is_array( $engine['models'] ) ) {
66 continue;
67 }
68 foreach ( $engine['models'] as $m ) {
69 if ( empty( $m['model'] ) ) {
70 continue;
71 }
72 $id = $m['model'];
73 $m['_engine_type'] = $engine_type;
74 yield $id => $m;
75 }
76 }
77 }
78
79 private function make_metadata( string $id, array $model ): ModelMetadata {
80 // Phase 3 TODO — gate `webSearch` on a future 'web_search' tag. Low
81 // priority; native plugins do this by model-id regex today.
82
83 $capabilities = [];
84 $tags = $model['tags'] ?? [];
85 $is_image = in_array( 'image', $tags, true ) || in_array( 'image-generation', $tags, true );
86 $is_chat = in_array( 'chat', $tags, true ) || in_array( 'completion', $tags, true );
87 $has_functions = in_array( 'functions', $tags, true );
88 $has_json = in_array( 'json', $tags, true );
89 $has_vision = in_array( 'vision', $tags, true );
90 $has_files = in_array( 'files', $tags, true );
91 $has_audio = in_array( 'audio', $tags, true );
92
93 if ( $is_image ) {
94 $capabilities[] = CapabilityEnum::imageGeneration();
95 }
96 if ( $is_chat ) {
97 $capabilities[] = CapabilityEnum::textGeneration();
98 $capabilities[] = CapabilityEnum::chatHistory();
99 }
100 if ( empty( $capabilities ) ) {
101 // Unknown tag shape: assume text generation as the safest default.
102 $capabilities[] = CapabilityEnum::textGeneration();
103 $capabilities[] = CapabilityEnum::chatHistory();
104 }
105
106 // Option support. Base options every chat model accepts; plus a tag-gated
107 // set for features that engines actually enforce at dispatch time
108 // (classes/engines/*.php). If we declared these without the tag, the
109 // WP AI Client would think we support them and the call would fail deep
110 // in the engine with an opaque message.
111 $option_methods = [
112 'outputModalities', 'outputMimeType', 'outputSchema',
113 'systemInstruction', 'maxTokens', 'temperature', 'topP', 'topK',
114 'candidateCount', 'stopSequences', 'frequencyPenalty', 'presencePenalty',
115 'logprobs', 'topLogprobs', 'webSearch',
116 'outputFileType', 'outputMediaAspectRatio', 'outputMediaOrientation',
117 'outputSpeechVoice', 'customOptions',
118 ];
119 // AI Engine's 'json' tag is narrow (OpenAI only today), but every chat
120 // engine handles structured output — via native JSON mode, tool use, or
121 // "reply in JSON" prompting. Declaring outputSchema permissively matches
122 // reality; gating by tag would falsely advertise Claude/Google as
123 // incapable of JSON responses.
124 //
125 // functionDeclarations IS tag-gated because dispatch-time checks in
126 // classes/engines/*.php actively skip tool payloads for non-`functions`
127 // models; declaring here would claim support the engine refuses.
128 if ( $has_functions ) {
129 $option_methods[] = 'functionDeclarations';
130 }
131 unset( $has_json ); // reserved for future finer-grained JSON-mode gating
132 $supportedOptions = [];
133 foreach ( $option_methods as $m ) {
134 // OptionEnum uses __callStatic, so method_exists is blind. Try/catch
135 // lets options not in this WP build degrade quietly.
136 try {
137 $supportedOptions[] = new SupportedOption( OptionEnum::$m() );
138 }
139 catch ( \Throwable $e ) {
140 // Skip options not present in this WP build.
141 }
142 }
143
144 // inputModalities is declared with the exact combinations we'll accept.
145 // Anthropic's reference adapter does the same — see
146 // AnthropicModelMetadataDirectory.php:95-104. Declaring `null` (any)
147 // would silently let image-only prompts reach a text-only model.
148 $input_combos = [ [ ModalityEnum::text() ] ];
149 if ( $has_vision ) {
150 $input_combos[] = [ ModalityEnum::text(), ModalityEnum::image() ];
151 }
152 if ( $has_files ) {
153 $input_combos[] = [ ModalityEnum::text(), ModalityEnum::document() ];
154 if ( $has_vision ) {
155 $input_combos[] = [ ModalityEnum::text(), ModalityEnum::image(), ModalityEnum::document() ];
156 }
157 }
158 if ( $has_audio ) {
159 $input_combos[] = [ ModalityEnum::text(), ModalityEnum::audio() ];
160 }
161 $supportedOptions[] = new SupportedOption( OptionEnum::inputModalities(), $input_combos );
162
163 $name = $model['rawName'] ?? $model['name'] ?? $id;
164 return new ModelMetadata( $id, is_string( $name ) ? $name : $id, array_values( array_unique( $capabilities, SORT_REGULAR ) ), $supportedOptions );
165 }
166 }
167