PluginProbe
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 3.7.6
AI Engine – The Chatbot, AI Framework & MCP for WordPress v3.7.6
3.7.6 3.7.5 3.7.4 3.7.3 3.7.2 3.7.1 3.7.0 3.6.9 3.6.8 3.6.7 3.6.6 3.6.4 3.6.5 3.6.3 3.6.2 3.6.1 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 All 526 releases
ai-engine / classes / query / text.php
text.php
222 lines 7.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class Meow_MWAI_Query_Text extends Meow_MWAI_Query_Base implements JsonSerializable {
4 // Core Content
5 public ?Meow_MWAI_Query_DroppedFile $attachedFile = null;
6 public ?array $attachedFiles = null; // Multiple files support
7
8 // Parameters
9 public ?float $temperature = null;
10 public ?int $maxTokens = null;
11 public ?string $stop = null;
12 public ?string $responseFormat = null;
13 public ?string $reasoning = null; // GPT-5 reasoning effort
14 public ?string $verbosity = null; // GPT-5 verbosity level
15
16 #region Constructors, Serialization
17
18 public function __construct( ?string $message = '', ?int $maxTokens = null, ?string $model = null ) {
19 parent::__construct( $message );
20 if ( !empty( $model ) ) {
21 $this->set_model( $model );
22 }
23 if ( !empty( $maxTokens ) ) {
24 $this->set_max_tokens( $maxTokens );
25 }
26 }
27
28 #[\ReturnTypeWillChange]
29 public function jsonSerialize(): array {
30 $json = [
31 'message' => $this->message,
32 'instructions' => $this->instructions,
33
34 'ai' => [
35 'model' => $this->model,
36 'feature' => $this->feature,
37 'maxTokens' => $this->maxTokens,
38 'temperature' => $this->temperature,
39 ],
40
41 'system' => [
42 'class' => get_class( $this ),
43 'envId' => $this->envId,
44 'scope' => $this->scope,
45 'session' => $this->session,
46 'customId' => $this->customId,
47 'maxMessages' => $this->maxMessages,
48 ]
49 ];
50
51 if ( !empty( $this->context ) ) {
52 $json['context']['content'] = $this->context;
53 }
54
55 if ( !empty( $this->attachedFile ) ) {
56 $json['context']['hasFile'] = true;
57 if ( $this->attachedFile->get_type() === 'url' ) {
58 $json['context']['fileUrl'] = $this->attachedFile->get_url();
59 }
60 }
61
62 if ( !empty( $this->attachedFiles ) ) {
63 $json['context']['hasFiles'] = true;
64 $json['context']['fileCount'] = count( $this->attachedFiles );
65 }
66
67 return $json;
68 }
69
70 #endregion
71
72 #region File Handling
73
74 /**
75 * Get all attached files as a normalized array.
76 * This method provides backward compatibility by merging both attachedFile (legacy)
77 * and attachedFiles (current) into a single array.
78 *
79 * @return Meow_MWAI_Query_DroppedFile[] Array of attached files
80 */
81 public function getAttachments(): array {
82 $files = $this->attachedFiles ?? [];
83
84 // Backward compatibility: include legacy attachedFile if it exists and isn't already in the array
85 if ( $this->attachedFile && !in_array( $this->attachedFile, $files, true ) ) {
86 // Prepend the single file so it appears first (maintains legacy behavior)
87 array_unshift( $files, $this->attachedFile );
88 }
89
90 return $files;
91 }
92
93 /**
94 * Add a file to the attachedFiles array.
95 * This is the unified method for both single and multi-file uploads.
96 */
97 public function add_file( Meow_MWAI_Query_DroppedFile $file ): void {
98 if ( $this->attachedFiles === null ) {
99 $this->attachedFiles = [];
100 }
101 $this->attachedFiles[] = $file;
102 }
103
104 public function set_files( array $files ): void {
105 $this->attachedFiles = $files;
106 }
107
108 public function get_files(): ?array {
109 return $this->attachedFiles;
110 }
111
112 #endregion
113
114 #region Parameters
115
116 /**
117 * The type of return expected from the API. It can be either null or "json".
118 * @param int $maxResults The maximum number of completions.
119 */
120 public function set_response_format( $responseFormat ) {
121 if ( !empty( $responseFormat ) && $responseFormat !== 'json' ) {
122 throw new Exception( 'AI Engine: The response format can only be null or json.' );
123 }
124 $this->responseFormat = $responseFormat;
125 }
126
127 /**
128 * The maximum number of tokens to generate in the completion.
129 * The token count of your prompt plus max_tokens cannot exceed the model's context length.
130 * Most models have a context length of 2048 tokens (except for the newest models, which support 4096).
131 * @param float $maxTokens The maximum number of tokens.
132 */
133 public function set_max_tokens( int $maxTokens ): void {
134 $this->maxTokens = $maxTokens;
135 }
136
137 /**
138 * Set the sampling temperature to use. Higher values means the model will take more risks.
139 * Try 0.9 for more creative applications, and 0 for ones with a well-defined reply.
140 * @param float $temperature The temperature.
141 */
142 public function set_temperature( float $temperature ): void {
143 $temperature = floatval( $temperature );
144 if ( $temperature > 1 ) {
145 $temperature = 1;
146 }
147 if ( $temperature < 0 ) {
148 $temperature = 0;
149 }
150 $this->temperature = round( $temperature, 2 );
151 }
152
153 public function set_stop( string $stop ): void {
154 $this->stop = $stop;
155 }
156
157 /**
158 * Set the reasoning effort for GPT-5 models.
159 * @param string $reasoning The reasoning effort level (none, minimal, low, medium, high, xhigh, max).
160 */
161 public function set_reasoning( string $reasoning ): void {
162 // OpenAI keeps extending this range: 'xhigh' arrived with GPT-5.6, 'max' with GPT-6.
163 // Which levels a given model accepts is declared in its 'params' entry in models.php.
164 $valid = ['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'];
165 if ( !in_array( $reasoning, $valid ) ) {
166 throw new Exception( 'AI Engine: Invalid reasoning level. Must be one of: ' . implode( ', ', $valid ) . '.' );
167 }
168 $this->reasoning = $reasoning;
169 }
170
171 /**
172 * Set the verbosity level for GPT-5 models.
173 * @param string $verbosity The verbosity level (low, medium, high).
174 */
175 public function set_verbosity( string $verbosity ): void {
176 $valid = ['low', 'medium', 'high'];
177 if ( !in_array( $verbosity, $valid ) ) {
178 throw new Exception( 'AI Engine: Invalid verbosity level. Must be one of: low, medium, high.' );
179 }
180 $this->verbosity = $verbosity;
181 }
182
183 #endregion
184
185 #region Inject Params
186
187 // Based on the params of the query, update the attributes
188 public function inject_params( array $params ): void {
189 parent::inject_params( $params );
190 $params = $this->convert_keys( $params );
191
192 if ( !empty( $params['maxTokens'] ) && $this->to_int( $params['maxTokens'] ) > 0 ) {
193 $this->set_max_tokens( $this->to_int( $params['maxTokens'] ) );
194 }
195 if ( isset( $params['temperature'] ) && $params['temperature'] !== '' ) {
196 $this->set_temperature( $params['temperature'] );
197 }
198 if ( !empty( $params['stop'] ) ) {
199 $this->set_stop( $params['stop'] );
200 }
201 if ( !empty( $params['responseFormat'] ) ) {
202 $this->set_response_format( $params['responseFormat'] );
203 }
204 // Accept both 'reasoning' and 'reasoningEffort' (UI uses reasoningEffort)
205 if ( !empty( $params['reasoning'] ) ) {
206 $this->set_reasoning( $params['reasoning'] );
207 }
208 if ( !empty( $params['reasoningEffort'] ) ) {
209 $this->set_reasoning( $params['reasoningEffort'] );
210 }
211 if ( !empty( $params['verbosity'] ) ) {
212 $this->set_verbosity( $params['verbosity'] );
213 }
214 // Store prompt-related params as extra params
215 if ( !empty( $params['promptId'] ) ) {
216 $this->setExtraParam( 'promptId', $params['promptId'] );
217 }
218 }
219
220 #endregion
221 }
222