PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 2.9.1
AI Engine – The Chatbot, AI Framework & MCP for WordPress v2.9.1
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 / services / message-builder.php
ai-engine / classes / services Last commit date
image.php 1 year ago message-builder.php 1 year ago model-environment.php 11 months ago response-id-manager.php 1 year ago session.php 11 months ago usage-stats.php 11 months ago
message-builder.php
300 lines
1 <?php
2
3 /**
4 * Service for building and transforming messages for different AI APIs.
5 *
6 * Simplifies the complex message building logic by breaking it down
7 * into smaller, focused methods.
8 */
9 class Meow_MWAI_Services_MessageBuilder {
10 private Meow_MWAI_Core $core;
11
12 public function __construct( Meow_MWAI_Core $core ) {
13 $this->core = $core;
14 }
15
16 /**
17 * Build messages array for Responses API format
18 */
19 public function build_responses_api_messages( Meow_MWAI_Query_Base $query ): array {
20 $messages = [];
21
22 // Handle different query types
23 if ( $query instanceof Meow_MWAI_Query_Feedback ) {
24 $messages = $this->build_feedback_messages( $query );
25 }
26 else {
27 $messages = $this->convert_messages_to_responses_format( $query->messages );
28 }
29
30 // Add user message with attachments if needed
31 if ( !( $query instanceof Meow_MWAI_Query_Feedback ) ) {
32 $messages = $this->add_user_message_with_attachments( $messages, $query );
33 }
34
35 return $messages;
36 }
37
38 /**
39 * Build messages for feedback queries
40 */
41 private function build_feedback_messages( Meow_MWAI_Query_Feedback $query ): array {
42 $messages = [];
43
44 // Convert existing messages
45 $messages = $this->convert_messages_to_responses_format( $query->messages );
46
47 // Process feedback blocks
48 if ( !empty( $query->blocks ) ) {
49 $messages = $this->add_feedback_results( $messages, $query->blocks );
50 }
51
52 return $messages;
53 }
54
55 /**
56 * Convert role-based messages to Responses API format
57 */
58 private function convert_messages_to_responses_format( array $messages ): array {
59 $converted = [];
60
61 foreach ( $messages as $message ) {
62 if ( !isset( $message['role'] ) ) {
63 // Already in Responses API format
64 $converted[] = $message;
65 continue;
66 }
67
68 // Handle assistant messages with tool calls
69 if ( $message['role'] === 'assistant' && isset( $message['tool_calls'] ) ) {
70 $converted = array_merge(
71 $converted,
72 $this->convert_assistant_with_tools( $message )
73 );
74 }
75 else {
76 // Regular messages stay as-is
77 $converted[] = $message;
78 }
79 }
80
81 return $converted;
82 }
83
84 /**
85 * Convert assistant message with tool calls to separate messages
86 */
87 private function convert_assistant_with_tools( array $message ): array {
88 $messages = [];
89
90 // Add assistant text if present
91 if ( !empty( $message['content'] ) ) {
92 $messages[] = [
93 'role' => 'assistant',
94 'content' => $message['content']
95 ];
96 }
97
98 // Convert each tool call to function_call message
99 if ( isset( $message['tool_calls'] ) ) {
100 foreach ( $message['tool_calls'] as $toolCall ) {
101 $functionCall = Meow_MWAI_Data_FunctionCall::from_tool_call( $toolCall, $message );
102 $messages[] = [
103 'type' => 'function_call',
104 'call_id' => $functionCall->id,
105 'name' => $functionCall->name,
106 'arguments' => $functionCall->get_arguments_json()
107 ];
108 }
109 }
110
111 return $messages;
112 }
113
114 /**
115 * Add feedback results to messages
116 */
117 private function add_feedback_results( array $messages, array $blocks ): array {
118 $functionResults = [];
119 $processedCallIds = [];
120
121 foreach ( $blocks as $block ) {
122 if ( !isset( $block['feedbacks'] ) ) {
123 continue;
124 }
125
126 foreach ( $block['feedbacks'] as $feedback ) {
127 $toolId = $feedback['request']['toolId'] ?? null;
128
129 // Skip duplicates
130 if ( !$toolId || in_array( $toolId, $processedCallIds ) ) {
131 continue;
132 }
133
134 // Create function result object
135 $result = Meow_MWAI_Data_FunctionResult::success(
136 $toolId,
137 $feedback['reply']['value'] ?? null
138 );
139
140 $functionResults[] = $result->to_responses_api_format();
141 $processedCallIds[] = $toolId;
142 }
143 }
144
145 // Add function results at the end
146 return array_merge( $messages, $functionResults );
147 }
148
149 /**
150 * Add user message with attachments
151 */
152 private function add_user_message_with_attachments( array $messages, Meow_MWAI_Query_Base $query ): array {
153 if ( !$query->attachedFile ) {
154 // Simple text message
155 $messages[] = [
156 'role' => 'user',
157 'content' => [
158 [
159 'type' => 'input_text',
160 'text' => $query->get_message()
161 ]
162 ]
163 ];
164 }
165 else {
166 // Message with image attachment
167 $content = [
168 [
169 'type' => 'input_text',
170 'text' => $query->get_message()
171 ]
172 ];
173
174 // Add image
175 $imageUrl = $query->image_remote_upload === 'url'
176 ? $query->attachedFile->get_url()
177 : $query->attachedFile->get_inline_base64_url();
178
179 $content[] = [
180 'type' => 'input_image',
181 'image_url' => $imageUrl
182 ];
183
184 $messages[] = [
185 'role' => 'user',
186 'content' => $content
187 ];
188 }
189
190 return $messages;
191 }
192
193 /**
194 * Build feedback-only messages for Responses API with previous_response_id
195 */
196 public function build_feedback_only_messages( Meow_MWAI_Query_Feedback $query ): array {
197 $messages = [];
198
199 if ( empty( $query->blocks ) ) {
200 return $messages;
201 }
202
203 $processedCallIds = [];
204
205 foreach ( $query->blocks as $block ) {
206 if ( !isset( $block['feedbacks'] ) ) {
207 continue;
208 }
209
210 foreach ( $block['feedbacks'] as $feedback ) {
211 $toolId = $feedback['request']['toolId'] ?? null;
212
213 if ( !$toolId || in_array( $toolId, $processedCallIds ) ) {
214 continue;
215 }
216
217 // First: Echo the function_call from the model
218 if ( isset( $feedback['request']['rawMessage']['tool_calls'] ) ) {
219 foreach ( $feedback['request']['rawMessage']['tool_calls'] as $toolCall ) {
220 if ( $toolCall['id'] === $toolId ) {
221 $functionCall = Meow_MWAI_Data_FunctionCall::from_tool_call( $toolCall );
222 $messages[] = [
223 'type' => 'function_call',
224 'call_id' => $functionCall->id,
225 'name' => $functionCall->name,
226 'arguments' => $functionCall->get_arguments_json()
227 ];
228 break;
229 }
230 }
231 }
232
233 // Second: Add the function result
234 $result = Meow_MWAI_Data_FunctionResult::success( $toolId, $feedback['reply']['value'] ?? '' );
235 $messages[] = $result->to_responses_api_format();
236
237 $processedCallIds[] = $toolId;
238 }
239 }
240
241 return $messages;
242 }
243
244 /**
245 * Build messages for Chat Completions API
246 */
247 public function build_chat_completions_messages( Meow_MWAI_Query_Base $query ): array {
248 $messages = [];
249
250 // Add system message if present
251 if ( !empty( $query->instructions ) ) {
252 $messages[] = [
253 'role' => 'system',
254 'content' => $query->instructions
255 ];
256 }
257
258 // Add conversation messages
259 if ( !empty( $query->messages ) ) {
260 $messages = array_merge( $messages, $query->messages );
261 }
262
263 // Add current user message
264 if ( !( $query instanceof Meow_MWAI_Query_Feedback ) ) {
265 $messages[] = [
266 'role' => 'user',
267 'content' => $query->get_message()
268 ];
269 }
270
271 return $messages;
272 }
273
274 /**
275 * Validate message order for Responses API
276 */
277 public function validate_message_order( array $messages ): bool {
278 // Responses API is flexible with message order
279 // but certain patterns should be maintained
280
281 // Check for function_call followed by function_call_output
282 for ( $i = 0; $i < count( $messages ) - 1; $i++ ) {
283 $current = $messages[$i];
284 $next = $messages[$i + 1];
285
286 // If we have a function_call, the next related message should be function_call_output
287 if ( isset( $current['type'] ) && $current['type'] === 'function_call' ) {
288 if ( isset( $next['type'] ) && $next['type'] === 'function_call_output' ) {
289 // Validate matching call_ids
290 if ( $current['call_id'] !== $next['call_id'] ) {
291 return false;
292 }
293 }
294 }
295 }
296
297 return true;
298 }
299 }
300