PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 3.5.8
AI Engine – The Chatbot, AI Framework & MCP for WordPress v3.5.8
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 / services / response-id-manager.php
ai-engine / classes / services Last commit date
image.php 2 days ago message-builder.php 3 weeks ago model-environment.php 7 months ago response-id-manager.php 2 days ago session.php 11 months ago usage-stats.php 1 month ago
response-id-manager.php
214 lines
1 <?php
2
3 /**
4 * Centralized manager for AI response IDs.
5 *
6 * Handles storage, retrieval, and validation of response IDs
7 * used for stateful conversations with various AI APIs.
8 */
9 class Meow_MWAI_Services_ResponseIdManager {
10 private Meow_MWAI_Core $core;
11 private array $cache = [];
12
13 // Response ID patterns for different providers
14 public const OPENAI_RESPONSES_PATTERN = '/^resp_/';
15 public const OPENAI_CHAT_PATTERN = '/^chatcmpl-/';
16 public const ANTHROPIC_PATTERN = '/^msg_/';
17 public const GOOGLE_INTERACTIONS_PATTERN = '/^v1_/';
18
19 // Expiry time (30 days as per OpenAI's policy)
20 public const EXPIRY_DAYS = 30;
21
22 public function __construct( Meow_MWAI_Core $core ) {
23 $this->core = $core;
24 }
25
26 /**
27 * Store a response ID with metadata
28 */
29 public function store( string $discussionId, string $responseId, array $metadata = [] ): void {
30 $data = [
31 'responseId' => $responseId,
32 'responseDate' => gmdate( 'Y-m-d H:i:s' ),
33 'provider' => $this->detect_provider( $responseId ),
34 'apiType' => $this->detect_api_type( $responseId )
35 ];
36
37 // Merge additional metadata
38 $data = array_merge( $data, $metadata );
39
40 // Cache for current request
41 $this->cache[$discussionId] = $data;
42
43 // Let the discussion system handle persistence
44 // This is called by the chatbot module when storing discussions
45 }
46
47 /**
48 * Retrieve a response ID if valid
49 */
50 public function retrieve( string $discussionId, array $extra = [] ): ?string {
51 // Check cache first
52 if ( isset( $this->cache[$discussionId] ) ) {
53 $data = $this->cache[$discussionId];
54 return $this->is_valid_data( $data ) ? $data['responseId'] : null;
55 }
56
57 // Check provided extra data (from discussion storage)
58 if ( !empty( $extra['responseId'] ) ) {
59 $responseDate = $extra['responseDate'] ?? null;
60
61 if ( $this->is_valid_date( $responseDate ) ) {
62 // Cache for future use in this request
63 $this->cache[$discussionId] = $extra;
64 return $extra['responseId'];
65 }
66 }
67
68 return null;
69 }
70
71 /**
72 * Validate a response ID for a specific API type
73 */
74 public function validate( string $responseId, string $apiType ): bool {
75 switch ( $apiType ) {
76 case 'openai_responses':
77 return $this->is_responses_api_id( $responseId );
78
79 case 'openai_chat':
80 return $this->is_chat_completions_id( $responseId );
81
82 case 'anthropic':
83 return $this->is_anthropic_id( $responseId );
84
85 default:
86 return true; // Allow unknown types
87 }
88 }
89
90 /**
91 * Check if ID is from OpenAI Responses API
92 */
93 public function is_responses_api_id( string $responseId ): bool {
94 return preg_match( self::OPENAI_RESPONSES_PATTERN, $responseId ) === 1;
95 }
96
97 /**
98 * Check if ID is from Google's Interactions API (stateful, server-side history)
99 */
100 public function is_interactions_api_id( string $responseId ): bool {
101 return preg_match( self::GOOGLE_INTERACTIONS_PATTERN, $responseId ) === 1;
102 }
103
104 /**
105 * Whether the ID refers to a stateful, server-side conversation that must be
106 * kept consistent (OpenAI Responses or Google Interactions). Used to avoid
107 * skipping the function-result round-trip on all-static turns, which would
108 * leave the server-side conversation half-answered.
109 */
110 public function is_stateful_conversation_id( string $responseId ): bool {
111 return $this->is_responses_api_id( $responseId )
112 || $this->is_interactions_api_id( $responseId );
113 }
114
115 /**
116 * Check if ID is from OpenAI Chat Completions API
117 */
118 public function is_chat_completions_id( string $responseId ): bool {
119 return preg_match( self::OPENAI_CHAT_PATTERN, $responseId ) === 1;
120 }
121
122 /**
123 * Check if ID is from Anthropic
124 */
125 public function is_anthropic_id( string $responseId ): bool {
126 return preg_match( self::ANTHROPIC_PATTERN, $responseId ) === 1;
127 }
128
129 /**
130 * Detect provider from response ID format
131 */
132 private function detect_provider( string $responseId ): string {
133 if ( $this->is_responses_api_id( $responseId ) ) {
134 return 'openai';
135 }
136 if ( $this->is_chat_completions_id( $responseId ) ) {
137 return 'openai';
138 }
139 if ( $this->is_anthropic_id( $responseId ) ) {
140 return 'anthropic';
141 }
142 return 'unknown';
143 }
144
145 /**
146 * Detect API type from response ID format
147 */
148 private function detect_api_type( string $responseId ): string {
149 if ( $this->is_responses_api_id( $responseId ) ) {
150 return 'responses_api';
151 }
152 if ( $this->is_chat_completions_id( $responseId ) ) {
153 return 'chat_completions';
154 }
155 if ( $this->is_anthropic_id( $responseId ) ) {
156 return 'messages_api';
157 }
158 return 'unknown';
159 }
160
161 /**
162 * Check if stored data is still valid
163 */
164 private function is_valid_data( array $data ): bool {
165 if ( empty( $data['responseId'] ) ) {
166 return false;
167 }
168
169 $responseDate = $data['responseDate'] ?? null;
170 return $this->is_valid_date( $responseDate );
171 }
172
173 /**
174 * Check if a response date is within validity period
175 */
176 private function is_valid_date( ?string $responseDate ): bool {
177 if ( empty( $responseDate ) ) {
178 return false;
179 }
180
181 $date = strtotime( $responseDate );
182 if ( $date === false ) {
183 return false;
184 }
185
186 $expiryTime = time() - ( self::EXPIRY_DAYS * 24 * 60 * 60 );
187 return $date > $expiryTime;
188 }
189
190 /**
191 * Clean up expired response IDs (for maintenance)
192 */
193 public function cleanup_expired(): int {
194 // This would be called by a scheduled task
195 // Implementation depends on how discussions are stored
196 // Return count of cleaned items
197 return 0;
198 }
199
200 /**
201 * Get debug information about a response ID
202 */
203 public function get_debug_info( string $responseId ): array {
204 return [
205 'id' => $responseId,
206 'provider' => $this->detect_provider( $responseId ),
207 'api_type' => $this->detect_api_type( $responseId ),
208 'is_valid_responses_api' => $this->is_responses_api_id( $responseId ),
209 'is_valid_chat_completions' => $this->is_chat_completions_id( $responseId ),
210 'is_valid_anthropic' => $this->is_anthropic_id( $responseId )
211 ];
212 }
213 }
214