'application/json', 'api-key' => 'Bearer ' . $token, 'OpenAI-Beta' => 'assistants=v2' ]; if (isset($aimogen_Main_Settings['openai_organization']) && $aimogen_Main_Settings['openai_organization'] != '') { $headers['OpenAI-Organization'] = $aimogen_Main_Settings['openai_organization']; } if (isset($aimogen_Main_Settings['azure_api_selector_assistants']) && $aimogen_Main_Settings['azure_api_selector_assistants'] != '' && $aimogen_Main_Settings['azure_api_selector_assistants'] != 'default') { $api_ver = '?api-version=' . $aimogen_Main_Settings['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($aimogen_Main_Settings['azure_endpoint'])) . 'openai/assistants' . $api_ver; $localAzureDeployments = array(); $depl_arr = aimogen_get_deployments($token); if(is_array($depl_arr)) { foreach($depl_arr as $dar) { if(empty($dar)) { continue; } if(is_string($dar)) { $localAzureDeployments[trim($dar)] = trim($dar); } else { $localAzureDeployments[trim($dar->model)] = trim($dar->id); } } } $azureDeployment = ''; foreach ( $localAzureDeployments as $dmodel => $dname ) { if ( $dmodel === str_replace('.', '', $model) || $dmodel === $model ) { $azureDeployment = $dname; break; } } if ( $azureDeployment == '' ) { $new_dep = aimogen_update_deployments_azure($token); if($new_dep !== false) { $localAzureDeployments = array(); foreach($new_dep as $dar) { if(empty($dar)) { continue; } if(is_string($dar)) { $localAzureDeployments[trim($dar)] = trim($dar); } else { $localAzureDeployments[trim($dar->model)] = trim($dar->id); } } foreach ( $localAzureDeployments as $dmodel => $dname ) { if ( $dmodel === str_replace('.', '', $model) || $dmodel === $model ) { $azureDeployment = $dname; break; } } } if ( $azureDeployment == '' ) { throw new Exception('No added Azure deployment found for chat model: ' . esc_html($model) . ' - you need to add this model in your Azure Portal as a Deployment'); } } $model = $azureDeployment; } else { $headers = [ 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $token, 'OpenAI-Beta' => 'assistants=v2' ]; if (isset($aimogen_Main_Settings['openai_organization']) && $aimogen_Main_Settings['openai_organization'] != '') { $headers['OpenAI-Organization'] = $aimogen_Main_Settings['openai_organization']; } if (isset($aimogen_Main_Settings['api_selector']) && trim($aimogen_Main_Settings['api_selector']) == 'custom' && isset($aimogen_Main_Settings['custom_endpoint']) && trim($aimogen_Main_Settings['custom_endpoint'], ' /') != '') { $api_endpoint = trim($aimogen_Main_Settings['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . '/v1/assistants'; } if(empty($name)) { throw new Exception('Name cannot be empty'); } if(empty($model)) { throw new Exception('Model cannot be empty'); } $code_interpreter_found = false; foreach($tools as $xthist) { if($xthist['type'] == 'code_interpreter') { $code_interpreter_found = true; break; } } if(is_array($file_ids) && $code_interpreter_found === true && count($file_ids) > 20) { $file_ids = array_slice($file_ids, 0, 20); } $tools_resource = new stdClass(); foreach($tools as $thist) { if($thist['type'] == 'code_interpreter') { $tools_resource->code_interpreter = new stdClass(); $tools_resource->code_interpreter->file_ids = $file_ids; } elseif($thist['type'] == 'file_search') { if(count($file_ids) > 0) { $tools_resource->file_search = new stdClass(); $tools_resource->file_search->vector_stores = array(); $vs = array(); $vs['file_ids'] = $file_ids; $tools_resource->file_search->vector_stores[] = $vs; } } } $postData = [ 'model' => $model, 'name' => $name, 'description' => $description, 'instructions' => $instructions, 'tools' => $tools, 'tool_resources' => $tools_resource, 'metadata' => $metadata ]; if(!empty($temperature)) { $postData['temperature'] = floatval($temperature); } if(!empty($topp)) { $postData['top_p'] = floatval($topp); } $args = array( 'method' => 'POST', 'headers' => $headers, 'body' => wp_json_encode($postData), 'timeout' => isset($aimogen_Main_Settings['max_timeout']) && $aimogen_Main_Settings['max_timeout'] !== '' ? intval($aimogen_Main_Settings['max_timeout']) : 300, 'sslverify' => false, ); if ( isset($aimogen_Main_Settings['proxy_ai']) && $aimogen_Main_Settings['proxy_ai'] === 'on' && !empty($aimogen_Main_Settings['proxy_url']) && $aimogen_Main_Settings['proxy_url'] !== 'disable' && $aimogen_Main_Settings['proxy_url'] !== 'disabled' ) { $prx = array_map('trim', explode(',', $aimogen_Main_Settings['proxy_url'])); $randomness = array_rand($prx); $args['proxy'] = $prx[$randomness]; if (!empty($aimogen_Main_Settings['proxy_auth'])) { $prx_auth = array_map('trim', explode(',', $aimogen_Main_Settings['proxy_auth'])); if (!empty($prx_auth[$randomness])) { $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($prx_auth[$randomness]); } } } $response = wp_remote_post($url, $args); if (is_wp_error($response)) { throw new Exception(esc_html($response->get_error_message())); } $httpCode = wp_remote_retrieve_response_code( $response ); $response = wp_remote_retrieve_body($response); if ($response === '' || $response === null) { throw new Exception('Empty response from remote API.'); } $jsdec = json_decode($response, true); if ($httpCode != 200) { $err_mess = isset($jsdec['error']['code']) ? ', error: ' . $jsdec['error']['code'] : ''; if(isset($jsdec['error']['message'])) { $err_mess = ', error: ' . $jsdec['error']['message']; } throw new Exception("Response with Status Code: " . esc_html($httpCode) . esc_html($err_mess)); } if(isset($jsdec['tool_resources']['file_search']['vector_store_ids'][0])) { $vector_store_id = $jsdec['tool_resources']['file_search']['vector_store_ids'][0]; } return $jsdec; } function aimogen_openai_modify_assistant($token, $assistant_id, $model = null, $name = null, $description = null, $instructions = null, $temperature = '', $topp = '', $tools = [], $file_ids = [], $metadata = null, &$vector_store_id = '', $address_post_id = '') { if (empty($metadata)) { $metadata = new stdClass(); } if (empty($assistant_id)) { throw new Exception('Assistant ID cannot be empty'); } $aimogen_Main_Settings = get_option('aimogen_Main_Settings', false); if(aimogen_check_if_azure($aimogen_Main_Settings)) { $headers = [ 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $token, 'OpenAI-Beta' => 'assistants=v2' ]; if (isset($aimogen_Main_Settings['azure_api_selector_assistants']) && $aimogen_Main_Settings['azure_api_selector_assistants'] != '' && $aimogen_Main_Settings['azure_api_selector_assistants'] != 'default') { $api_ver = '?api-version=' . $aimogen_Main_Settings['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($aimogen_Main_Settings['azure_endpoint'])) . 'openai/assistants/' . $assistant_id . $api_ver; $localAzureDeployments = array(); $depl_arr = aimogen_get_deployments($token); if(is_array($depl_arr)) { foreach($depl_arr as $dar) { if(empty($dar)) { continue; } if(is_string($dar)) { $localAzureDeployments[trim($dar)] = trim($dar); } else { $localAzureDeployments[trim($dar->model)] = trim($dar->id); } } } $azureDeployment = ''; foreach ( $localAzureDeployments as $dmodel => $dname ) { if ( $dmodel === str_replace('.', '', $model) || $dmodel === $model ) { $azureDeployment = $dname; break; } } if ( $azureDeployment == '' ) { $new_dep = aimogen_update_deployments_azure($token); if($new_dep !== false) { $localAzureDeployments = array(); foreach($new_dep as $dar) { if(empty($dar)) { continue; } if(is_string($dar)) { $localAzureDeployments[trim($dar)] = trim($dar); } else { $localAzureDeployments[trim($dar->model)] = trim($dar->id); } } foreach ( $localAzureDeployments as $dmodel => $dname ) { if ( $dmodel === str_replace('.', '', $model) || $dmodel === $model ) { $azureDeployment = $dname; break; } } } if ( $azureDeployment == '' ) { throw new Exception('No added Azure deployment found for chat model: ' . esc_html($model) . ' - you need to add this model in your Azure Portal as a Deployment'); } } $model = $azureDeployment; } else { $headers = [ 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $token, 'OpenAI-Beta' => 'assistants=v2' ]; if (isset($aimogen_Main_Settings['openai_organization']) && $aimogen_Main_Settings['openai_organization'] != '') { $headers['OpenAI-Organization'] = $aimogen_Main_Settings['openai_organization']; } if (isset($aimogen_Main_Settings['api_selector']) && trim($aimogen_Main_Settings['api_selector']) == 'custom' && isset($aimogen_Main_Settings['custom_endpoint']) && trim($aimogen_Main_Settings['custom_endpoint'], ' /') != '') { $api_endpoint = trim($aimogen_Main_Settings['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . "/v1/assistants/" . $assistant_id; } $tools_resource = new stdClass(); foreach($tools as $thist) { if($thist['type'] == 'code_interpreter') { $tools_resource->code_interpreter = new stdClass(); $tools_resource->code_interpreter->file_ids = $file_ids; } elseif($thist['type'] == 'file_search') { if(count($file_ids) > 0) { if(!empty($vector_store_id)) { $solved = false; $ls_fid = []; try { $list_stores = aimogen_openai_list_vector_store_files($token, $vector_store_id); } catch(Exception $e) { if(strstr($e->getMessage(), 'No vector store found with id') !== false) { $vs = aimogen_openai_create_vector_store($token, 'New Vector Store', $file_ids); if(isset($vs['id'])) { $tools_resource->file_search = new stdClass(); $tools_resource->file_search->vector_store_ids = array($vs['id']); $vector_store_id = $vs['id']; if(!empty($address_post_id)) { update_post_meta($address_post_id, '_assistant_vector_store_id', $address_post_id); $solved = true; } } } else { throw $e; } } if(!$solved) { foreach($list_stores as $ls) { $ls_fid[] = $ls['id']; } foreach($file_ids as $fid) { if(!in_array($fid, $ls_fid)) { aimogen_openai_create_vector_store_file($token, $vector_store_id, $fid); } } foreach($ls_fid as $fid) { if(!in_array($fid, $file_ids)) { aimogen_openai_delete_vector_store_file($token, $vector_store_id, $fid); } } $tools_resource->file_search = new stdClass(); $tools_resource->file_search->vector_store_ids = array($vector_store_id); } } else { if($vector_store_id !== null) { $vs = aimogen_openai_create_vector_store($token, 'New Vector Store', $file_ids); if(isset($vs['id'])) { $tools_resource->file_search = new stdClass(); $tools_resource->file_search->vector_store_ids = array($vs['id']); $vector_store_id = $vs['id']; if(!empty($address_post_id)) { update_post_meta($address_post_id, '_assistant_vector_store_id', $address_post_id); } } } } } else { $tools_resource->file_search = new stdClass(); $tools_resource->file_search->vector_store_ids = array(); } } } $postData = array_filter([ 'model' => $model, 'name' => $name, 'description' => $description, 'instructions' => $instructions, 'tools' => $tools, 'tool_resources' => $tools_resource, 'metadata' => $metadata ], function($value) { return !is_null($value); }); if (!empty($temperature)) { $postData['temperature'] = (float) $temperature; } if (!empty($topp)) { $postData['top_p'] = (float) $topp; } $wp_headers = []; foreach ($headers as $h) { if (strpos($h, ':') !== false) { list($k, $v) = explode(':', $h, 2); $wp_headers[trim($k)] = trim($v); } } $args = array( 'method' => 'POST', 'headers' => $wp_headers, 'body' => wp_json_encode($postData), 'timeout' => !empty($aimogen_Main_Settings['max_timeout']) ? (int) $aimogen_Main_Settings['max_timeout'] : 300, 'sslverify' => false ); if ( !empty($aimogen_Main_Settings['proxy_ai']) && $aimogen_Main_Settings['proxy_ai'] === 'on' && !empty($aimogen_Main_Settings['proxy_url']) && !in_array($aimogen_Main_Settings['proxy_url'], ['disable','disabled'], true) ) { $prx = array_map('trim', explode(',', $aimogen_Main_Settings['proxy_url'])); $idx = array_rand($prx); $args['proxy'] = $prx[$idx]; if (!empty($aimogen_Main_Settings['proxy_auth'])) { $authList = array_map('trim', explode(',', $aimogen_Main_Settings['proxy_auth'])); if (!empty($authList[$idx])) { $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($authList[$idx]); } } } $response = wp_remote_post($url, $args); if (is_wp_error($response)) { throw new Exception(esc_html($response->get_error_message())); } $httpCode = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); if ($body === '' || $body === null) { throw new Exception('Empty response from remote API.'); } $decoded = json_decode($body, true); if ($httpCode !== 200) { $err = ''; if (!empty($decoded['error']['message'])) { $err = ', error: ' . esc_html($decoded['error']['message']); } throw new Exception( 'HTTP modify assistant request failed with status code ' . esc_html(esc_html(intval($httpCode) . sanitize_text_field($err))) ); } return $decoded; } function aimogen_openai_duplicate_assistant($token, $assistant_id, &$vector_store_id = '') { $existingAssistant = aimogen_openai_retrieve_assistant($token, $assistant_id); if (empty($existingAssistant) || $existingAssistant['id'] != $assistant_id) { throw new Exception('Failed to retrieve the assistant to duplicate'); } $name = $existingAssistant['name'] . ' (Copy)'; $description = $existingAssistant['description']; $model = $existingAssistant['model']; $instructions = $existingAssistant['instructions']; $tools = $existingAssistant['tools']; $temperature = $existingAssistant['temperature']; $topp = $existingAssistant['top_p']; if(isset($existingAssistant['tool_resources']['code_interpreter']['file_ids'])) { $file_ids = $existingAssistant['tool_resources']['code_interpreter']['file_ids']; } else { $file_ids = array(); } if(!is_object($existingAssistant['metadata'])) { $existingAssistant['metadata'] = new stdClass(); } $metadata = $existingAssistant['metadata']; $newAssistant = aimogen_openai_save_assistant($token, $model, $name, $description, $temperature, $topp, $instructions, $tools, $file_ids, $metadata, $vector_store_id); return $newAssistant; } function aimogen_openai_delete_assistant($token, $assistant_id) { if (empty($assistant_id)) { throw new Exception('Assistant ID cannot be empty'); } $settings = get_option('aimogen_Main_Settings', false); if (aimogen_check_if_azure($settings)) { // Azure headers $headers = array( 'Content-Type' => 'application/json', 'api-key' => $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['azure_api_selector_assistants']) && $settings['azure_api_selector_assistants'] !== 'default') { $api_ver = '?api-version=' . $settings['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($settings['azure_endpoint'])) . 'openai/assistants/' . $assistant_id . $api_ver; } else { // OpenAI headers $headers = array( 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['openai_organization'])) { $headers['OpenAI-Organization'] = $settings['openai_organization']; } if ( isset($settings['api_selector']) && trim($settings['api_selector']) === 'custom' && !empty(trim($settings['custom_endpoint'], ' /')) ) { $api_endpoint = trim($settings['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . '/v1/assistants/' . $assistant_id; } // Build request $args = array( 'method' => 'DELETE', 'headers' => $headers, 'timeout' => !empty($settings['max_timeout']) ? intval($settings['max_timeout']) : 300, 'sslverify' => false ); // Proxy support if ( !empty($settings['proxy_ai']) && $settings['proxy_ai'] === 'on' && !empty($settings['proxy_url']) && !in_array($settings['proxy_url'], array('disable','disabled'), true) ) { $proxies = array_map('trim', explode(',', $settings['proxy_url'])); $idx = array_rand($proxies); $args['proxy'] = $proxies[$idx]; if (!empty($settings['proxy_auth'])) { $auths = array_map('trim', explode(',', $settings['proxy_auth'])); if (!empty($auths[$idx])) { $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($auths[$idx]); } } } // Execute request $response = wp_remote_request($url, $args); if (is_wp_error($response)) { throw new Exception(esc_html($response->get_error_message())); } $code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); if ($body === '' || $body === null) { throw new Exception('Empty response from remote API.'); } $decoded = json_decode($body, true); if ($code !== 200) { $msg = ''; if (!empty($decoded['error']['message'])) { $msg = ', error: ' . esc_html($decoded['error']['message']); } throw new Exception( 'Response with Status Code: ' . intval($code) . esc_html(sanitize_text_field($msg)) ); } return $decoded; } function aimogen_openai_list_assistants($token, $limit = 100, $order = 'desc') { $assistants = array(); $has_more = true; $after = null; $settings = get_option('aimogen_Main_Settings', false); while ($has_more) { // Build headers if (aimogen_check_if_azure($settings)) { $headers = array( 'Content-Type' => 'application/json', 'api-key' => $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['azure_api_selector_assistants']) && $settings['azure_api_selector_assistants'] !== 'default') { $api_ver = '?api-version=' . $settings['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($settings['azure_endpoint'])) . 'openai/assistants?limit=' . $limit . '&order=' . $order . str_replace('?', '&', $api_ver); } else { $headers = array( 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['openai_organization'])) { $headers['OpenAI-Organization'] = $settings['openai_organization']; } if ( isset($settings['api_selector']) && trim($settings['api_selector']) === 'custom' && !empty(trim($settings['custom_endpoint'], ' /')) ) { $api_endpoint = trim($settings['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . '/v1/assistants?limit=' . $limit . '&order=' . $order; } if ($after) { $url .= '&after=' . urlencode($after); } // Build WP request args $args = array( 'method' => 'GET', 'headers' => $headers, 'timeout' => !empty($settings['max_timeout']) ? intval($settings['max_timeout']) : 300, 'sslverify' => false ); // Proxy support if ( !empty($settings['proxy_ai']) && $settings['proxy_ai'] === 'on' && !empty($settings['proxy_url']) && !in_array($settings['proxy_url'], array('disable', 'disabled'), true) ) { $proxies = array_map('trim', explode(',', $settings['proxy_url'])); $idx = array_rand($proxies); $args['proxy'] = $proxies[$idx]; if (!empty($settings['proxy_auth'])) { $auth = array_map('trim', explode(',', $settings['proxy_auth'])); if (!empty($auth[$idx])) { $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($auth[$idx]); } } } // Execute request $response = wp_remote_get($url, $args); if (is_wp_error($response)) { throw new Exception(esc_html($response->get_error_message())); } $status_code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); if ($body === '' || $body === null) { throw new Exception('Empty response from remote API.'); } $decoded = json_decode($body, true); if ($status_code !== 200) { $msg = ''; if (!empty($decoded['error']['message'])) { $msg = ', error: ' . esc_html($decoded['error']['message']); } throw new Exception( 'Response with Status Code: ' . intval($status_code) . esc_html(sanitize_text_field($msg)) ); } // Merge assistants if (!empty($decoded['data'])) { $assistants = array_merge($assistants, $decoded['data']); } // Pagination $has_more = !empty($decoded['has_more']); if ($has_more && !empty($decoded['data'])) { $last = end($decoded['data']); $after = isset($last['id']) ? $last['id'] : null; if (!$after) { $has_more = false; } } else { $has_more = false; } } return $assistants; } function aimogen_openai_list_vector_store_files($token, $vector_store_id, $limit = 100, $order = 'desc') { $assistants = array(); $has_more = true; $after = null; $settings = get_option('aimogen_Main_Settings', false); while ($has_more) { if (aimogen_check_if_azure($settings)) { $headers = array( 'Content-Type' => 'application/json', 'api-key' => $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['azure_api_selector_assistants']) && $settings['azure_api_selector_assistants'] !== 'default') { $api_ver = '?api-version=' . $settings['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($settings['azure_endpoint'])) . 'openai/vector_stores/' . $vector_store_id . '/files?limit=' . $limit . '&order=' . $order . str_replace('?', '&', $api_ver); } else { $headers = array( 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['openai_organization'])) { $headers['OpenAI-Organization'] = $settings['openai_organization']; } if ( isset($settings['api_selector']) && trim($settings['api_selector']) === 'custom' && !empty(trim($settings['custom_endpoint'], ' /')) ) { $api_endpoint = trim($settings['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . '/v1/vector_stores/' . $vector_store_id . '/files?limit=' . $limit . '&order=' . $order; } if ($after) { $url .= '&after=' . urlencode($after); } $args = array( 'method' => 'GET', 'headers' => $headers, 'timeout' => !empty($settings['max_timeout']) ? intval($settings['max_timeout']) : 300, 'sslverify' => false ); if ( !empty($settings['proxy_ai']) && $settings['proxy_ai'] === 'on' && !empty($settings['proxy_url']) && !in_array($settings['proxy_url'], array('disable','disabled'), true) ) { $proxies = array_map('trim', explode(',', $settings['proxy_url'])); $idx = array_rand($proxies); $args['proxy'] = $proxies[$idx]; if (!empty($settings['proxy_auth'])) { $auths = array_map('trim', explode(',', $settings['proxy_auth'])); if (!empty($auths[$idx])) { $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($auths[$idx]); } } } $response = wp_remote_get($url, $args); if (is_wp_error($response)) { throw new Exception(esc_html($response->get_error_message())); } $status_code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); if ($body === '' || $body === null) { throw new Exception('Empty response from remote API.'); } $decoded = json_decode($body, true); if ($status_code !== 200) { $msg = ''; if (!empty($decoded['error']['message'])) { $msg = ', error: ' . esc_html($decoded['error']['message']); } throw new Exception( 'Response with Status Code: ' . intval($status_code) . esc_html(sanitize_text_field($msg)) ); } if (!empty($decoded['data'])) { $assistants = array_merge($assistants, $decoded['data']); } $has_more = !empty($decoded['has_more']); if ($has_more && !empty($decoded['data'])) { $last = end($decoded['data']); $after = isset($last['id']) ? $last['id'] : null; if (!$after) { $has_more = false; } } else { $has_more = false; } } return $assistants; } function aimogen_openai_retrieve_assistant($token, $assistant_id) { if (empty($assistant_id)) { throw new Exception('Assistant ID cannot be empty'); } $settings = get_option('aimogen_Main_Settings', false); if (aimogen_check_if_azure($settings)) { $headers = array( 'Content-Type' => 'application/json', 'api-key' => $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['azure_api_selector_assistants']) && $settings['azure_api_selector_assistants'] !== 'default') { $api_ver = '?api-version=' . $settings['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($settings['azure_endpoint'])) . 'openai/assistants/' . $assistant_id . $api_ver; } else { $headers = array( 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['openai_organization'])) { $headers['OpenAI-Organization'] = $settings['openai_organization']; } if ( isset($settings['api_selector']) && trim($settings['api_selector']) === 'custom' && !empty(trim($settings['custom_endpoint'], ' /')) ) { $api_endpoint = trim($settings['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . '/v1/assistants/' . $assistant_id; } $args = array( 'method' => 'GET', 'headers' => $headers, 'timeout' => !empty($settings['max_timeout']) ? intval($settings['max_timeout']) : 300, 'sslverify' => false ); if ( !empty($settings['proxy_ai']) && $settings['proxy_ai'] === 'on' && !empty($settings['proxy_url']) && !in_array($settings['proxy_url'], array('disable','disabled'), true) ) { $proxies = array_map('trim', explode(',', $settings['proxy_url'])); $idx = array_rand($proxies); $args['proxy'] = $proxies[$idx]; if (!empty($settings['proxy_auth'])) { $auths = array_map('trim', explode(',', $settings['proxy_auth'])); if (!empty($auths[$idx])) { $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($auths[$idx]); } } } $response = wp_remote_get($url, $args); if (is_wp_error($response)) { throw new Exception(esc_html($response->get_error_message())); } $code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); if ($body === '' || $body === null) { throw new Exception('Empty response from remote API.'); } $decoded = json_decode($body, true); if ($code !== 200) { $msg = ''; if (!empty($decoded['error']['message'])) { $msg = ', error: ' . esc_html($decoded['error']['message']); } throw new Exception( 'HTTP request failed with code (assistant id: ' . esc_html($assistant_id) . ') ' . intval($code) . esc_html(sanitize_text_field($msg)) ); } if (json_last_error() !== JSON_ERROR_NONE) { throw new Exception('Failed to decode JSON response'); } return $decoded; } function aimogen_openai_create_vector_store($token, $name, $files = []) { $settings = get_option('aimogen_Main_Settings', false); if (aimogen_check_if_azure($settings)) { $headers = array( 'Content-Type' => 'application/json', 'api-key' => $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['azure_api_selector_assistants']) && $settings['azure_api_selector_assistants'] !== 'default') { $api_ver = '?api-version=' . $settings['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($settings['azure_endpoint'])) . 'openai/vector_stores' . $api_ver; } else { $headers = array( 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['openai_organization'])) { $headers['OpenAI-Organization'] = $settings['openai_organization']; } if ( isset($settings['api_selector']) && trim($settings['api_selector']) === 'custom' && !empty(trim($settings['custom_endpoint'], ' /')) ) { $api_endpoint = trim($settings['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . "/v1/vector_stores"; } $postData = array( 'name' => $name, 'file_ids' => $files ); $args = array( 'method' => 'POST', 'headers' => $headers, 'body' => wp_json_encode($postData), 'timeout' => !empty($settings['max_timeout']) ? intval($settings['max_timeout']) : 300, 'sslverify' => false ); if ( !empty($settings['proxy_ai']) && $settings['proxy_ai'] === 'on' && !empty($settings['proxy_url']) && !in_array($settings['proxy_url'], array('disable', 'disabled'), true) ) { $proxies = array_map('trim', explode(',', $settings['proxy_url'])); $idx = array_rand($proxies); $args['proxy'] = $proxies[$idx]; if (!empty($settings['proxy_auth'])) { $auths = array_map('trim', explode(',', $settings['proxy_auth'])); if (!empty($auths[$idx])) { $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($auths[$idx]); } } } $response = wp_remote_post($url, $args); if (is_wp_error($response)) { throw new Exception(esc_html($response->get_error_message())); } $code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); if ($body === '' || $body === null) { throw new Exception('Empty response from remote API.'); } $decoded = json_decode($body, true); if ($code !== 200) { $msg = ''; if (!empty($decoded['error']['message'])) { $msg = ', error: ' . esc_html($decoded['error']['message']); } throw new Exception( 'HTTP create thread request failed with status code ' . intval($code) . esc_html(sanitize_text_field($msg)) ); } return $decoded; } function aimogen_openai_list_vector_stores($token, $limit = 100, $order = 'desc') { $stores = array(); $has_more = true; $after = null; $settings = get_option('aimogen_Main_Settings', false); while ($has_more) { if (aimogen_check_if_azure($settings)) { $headers = array( 'Content-Type' => 'application/json', 'api-key' => $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['azure_api_selector_assistants']) && $settings['azure_api_selector_assistants'] !== 'default') { $api_ver = '?api-version=' . $settings['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($settings['azure_endpoint'])) . 'openai/vector_stores?limit=' . $limit . '&order=' . $order . str_replace('?', '&', $api_ver); } else { $headers = array( 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['openai_organization'])) { $headers['OpenAI-Organization'] = $settings['openai_organization']; } if ( isset($settings['api_selector']) && trim($settings['api_selector']) === 'custom' && !empty(trim($settings['custom_endpoint'], ' /')) ) { $api_endpoint = trim($settings['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . '/v1/vector_stores?limit=' . $limit . '&order=' . $order; } if ($after) { $url .= '&after=' . urlencode($after); } $args = array( 'method' => 'GET', 'headers' => $headers, 'timeout' => !empty($settings['max_timeout']) ? intval($settings['max_timeout']) : 300, 'sslverify' => false ); if ( !empty($settings['proxy_ai']) && $settings['proxy_ai'] === 'on' && !empty($settings['proxy_url']) && !in_array($settings['proxy_url'], array('disable', 'disabled'), true) ) { $proxies = array_map('trim', explode(',', $settings['proxy_url'])); $idx = array_rand($proxies); $args['proxy'] = $proxies[$idx]; if (!empty($settings['proxy_auth'])) { $auths = array_map('trim', explode(',', $settings['proxy_auth'])); if (!empty($auths[$idx])) { $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($auths[$idx]); } } } $response = wp_remote_get($url, $args); if (is_wp_error($response)) { throw new Exception(esc_html($response->get_error_message())); } $status_code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); if ($body === '' || $body === null) { throw new Exception('Empty response from remote API.'); } $decoded = json_decode($body, true); if ($status_code !== 200) { $msg = ''; if (!empty($decoded['error']['message'])) { $msg = ', error: ' . esc_html($decoded['error']['message']); } throw new Exception( 'Response with Status Code: ' . intval($status_code) . esc_html(sanitize_text_field($msg)) ); } if (!empty($decoded['data'])) { $stores = array_merge($stores, $decoded['data']); } $has_more = !empty($decoded['has_more']); if ($has_more && !empty($decoded['data'])) { $last = end($decoded['data']); $after = isset($last['id']) ? $last['id'] : null; if (!$after) { $has_more = false; } } else { $has_more = false; } } return $stores; } function aimogen_openai_modify_vector_store($token, $vector_store_id, $name) { if (empty($vector_store_id)) { throw new Exception('Vectore store ID cannot be empty'); } $settings = get_option('aimogen_Main_Settings', false); if (aimogen_check_if_azure($settings)) { $headers = array( 'Content-Type' => 'application/json', 'api-key' => $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['azure_api_selector_assistants']) && $settings['azure_api_selector_assistants'] !== 'default') { $api_ver = '?api-version=' . $settings['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($settings['azure_endpoint'])) . 'openai/vector_stores/' . $vector_store_id . $api_ver; } else { $headers = array( 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['openai_organization'])) { $headers['OpenAI-Organization'] = $settings['openai_organization']; } if ( isset($settings['api_selector']) && trim($settings['api_selector']) === 'custom' && !empty(trim($settings['custom_endpoint'], ' /')) ) { $api_endpoint = trim($settings['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . "/v1/vector_stores/" . $vector_store_id; } $postData = array( 'name' => $name ); $args = array( 'method' => 'POST', 'headers' => $headers, 'body' => wp_json_encode($postData), 'timeout' => !empty($settings['max_timeout']) ? intval($settings['max_timeout']) : 300, 'sslverify' => false ); if ( !empty($settings['proxy_ai']) && $settings['proxy_ai'] === 'on' && !empty($settings['proxy_url']) && !in_array($settings['proxy_url'], array('disable', 'disabled'), true) ) { $proxies = array_map('trim', explode(',', $settings['proxy_url'])); $idx = array_rand($proxies); $args['proxy'] = $proxies[$idx]; if (!empty($settings['proxy_auth'])) { $auths = array_map('trim', explode(',', $settings['proxy_auth'])); if (!empty($auths[$idx])) { $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($auths[$idx]); } } } $response = wp_remote_post($url, $args); if (is_wp_error($response)) { throw new Exception(esc_html($response->get_error_message())); } $code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); if ($body === '' || $body === null) { throw new Exception('Empty response from remote API.'); } $decoded = json_decode($body, true); if ($code !== 200) { $msg = ''; if (!empty($decoded['error']['message'])) { $msg = ', error: ' . esc_html($decoded['error']['message']); } throw new Exception( 'HTTP modify vector store request failed with status code ' . intval($code) . esc_html(sanitize_text_field($msg)) ); } return $decoded; } function aimogen_openai_delete_vector_store($token, $vector_store_id) { if (empty($vector_store_id)) { throw new Exception('Vector store ID cannot be empty'); } $settings = get_option('aimogen_Main_Settings', false); if (aimogen_check_if_azure($settings)) { $headers = array( 'Content-Type' => 'application/json', 'api-key' => $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['azure_api_selector_assistants']) && $settings['azure_api_selector_assistants'] !== 'default') { $api_ver = '?api-version=' . $settings['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($settings['azure_endpoint'])) . 'openai/vector_stores/' . $vector_store_id . $api_ver; } else { $headers = array( 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['openai_organization'])) { $headers['OpenAI-Organization'] = $settings['openai_organization']; } if ( isset($settings['api_selector']) && trim($settings['api_selector']) === 'custom' && !empty(trim($settings['custom_endpoint'], ' /')) ) { $api_endpoint = trim($settings['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . '/v1/vector_stores/' . $vector_store_id; } $args = array( 'method' => 'DELETE', 'headers' => $headers, 'timeout' => !empty($settings['max_timeout']) ? intval($settings['max_timeout']) : 300, 'sslverify' => false ); if ( !empty($settings['proxy_ai']) && $settings['proxy_ai'] === 'on' && !empty($settings['proxy_url']) && !in_array($settings['proxy_url'], array('disable', 'disabled'), true) ) { $proxies = array_map('trim', explode(',', $settings['proxy_url'])); $idx = array_rand($proxies); $args['proxy'] = $proxies[$idx]; if (!empty($settings['proxy_auth'])) { $auths = array_map('trim', explode(',', $settings['proxy_auth'])); if (!empty($auths[$idx])) { $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($auths[$idx]); } } } $response = wp_remote_request($url, $args); if (is_wp_error($response)) { throw new Exception(esc_html($response->get_error_message())); } $code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); if ($body === '' || $body === null) { throw new Exception('Empty response from remote API.'); } $decoded = json_decode($body, true); if ($code !== 200) { $msg = ''; if (!empty($decoded['error']['message'])) { $msg = ', error: ' . esc_html($decoded['error']['message']); } throw new Exception( 'Response with Status Code: ' . intval($code) . esc_html(sanitize_text_field($msg)) ); } return $decoded; } function aimogen_openai_delete_vector_store_file($token, $vector_store_id, $file_id) { if (empty($vector_store_id)) { throw new Exception('Vectore store ID cannot be empty'); } if (empty($file_id)) { throw new Exception('File ID cannot be empty'); } $settings = get_option('aimogen_Main_Settings', false); if (aimogen_check_if_azure($settings)) { $headers = array( 'Content-Type' => 'application/json', 'api-key' => $token, 'OpenAI-Beta' => 'assistants=v2' ); if ( !empty($settings['azure_api_selector_assistants']) && $settings['azure_api_selector_assistants'] !== 'default' ) { $api_ver = '?api-version=' . $settings['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($settings['azure_endpoint'])) . 'openai/vector_stores/' . $vector_store_id . '/files/' . $file_id . $api_ver; } else { $headers = array( 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['openai_organization'])) { $headers['OpenAI-Organization'] = $settings['openai_organization']; } if ( isset($settings['api_selector']) && trim($settings['api_selector']) === 'custom' && !empty(trim($settings['custom_endpoint'], ' /')) ) { $api_endpoint = trim($settings['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . '/v1/vector_stores/' . $vector_store_id . '/files/' . $file_id; } $args = array( 'method' => 'DELETE', 'headers' => $headers, 'timeout' => !empty($settings['max_timeout']) ? intval($settings['max_timeout']) : 300, 'sslverify' => false ); if ( !empty($settings['proxy_ai']) && $settings['proxy_ai'] === 'on' && !empty($settings['proxy_url']) && !in_array($settings['proxy_url'], array('disable', 'disabled'), true) ) { $proxies = array_map('trim', explode(',', $settings['proxy_url'])); $idx = array_rand($proxies); $args['proxy'] = $proxies[$idx]; if (!empty($settings['proxy_auth'])) { $auths = array_map('trim', explode(',', $settings['proxy_auth'])); if (!empty($auths[$idx])) { $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($auths[$idx]); } } } $response = wp_remote_request($url, $args); if (is_wp_error($response)) { throw new Exception(esc_html($response->get_error_message())); } $code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); if ($body === '' || $body === null) { throw new Exception('Empty response from remote API.'); } $decoded = json_decode($body, true); if ($code !== 200) { $msg = ''; if (!empty($decoded['error']['message'])) { $msg = ', error: ' . esc_html($decoded['error']['message']); } throw new Exception( 'Response with Status Code: ' . intval($code) . esc_html(sanitize_text_field($msg)) ); } return $decoded; } function aimogen_openai_create_vector_store_file($token, $vector_store_id, $file_id) { if (empty($vector_store_id)) { throw new Exception('Vector store ID cannot be empty'); } if (empty($file_id)) { throw new Exception('File ID cannot be empty'); } $settings = get_option('aimogen_Main_Settings', false); if (aimogen_check_if_azure($settings)) { $headers = array( 'Content-Type' => 'application/json', 'api-key' => $token, 'OpenAI-Beta' => 'assistants=v2' ); if ( !empty($settings['azure_api_selector_assistants']) && $settings['azure_api_selector_assistants'] !== 'default' ) { $api_ver = '?api-version=' . $settings['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($settings['azure_endpoint'])) . 'openai/vector_stores/' . $vector_store_id . '/files' . $api_ver; } else { $headers = array( 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['openai_organization'])) { $headers['OpenAI-Organization'] = $settings['openai_organization']; } if ( isset($settings['api_selector']) && trim($settings['api_selector']) === 'custom' && !empty(trim($settings['custom_endpoint'], ' /')) ) { $api_endpoint = trim($settings['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . '/v1/vector_stores/' . $vector_store_id . '/files'; } $postData = array( 'file_id' => $file_id ); $args = array( 'method' => 'POST', 'headers' => $headers, 'body' => wp_json_encode($postData), 'timeout' => !empty($settings['max_timeout']) ? intval($settings['max_timeout']) : 300, 'sslverify' => false ); if ( !empty($settings['proxy_ai']) && $settings['proxy_ai'] === 'on' && !empty($settings['proxy_url']) && !in_array($settings['proxy_url'], array('disable', 'disabled'), true) ) { $proxies = array_map('trim', explode(',', $settings['proxy_url'])); $idx = array_rand($proxies); $args['proxy'] = $proxies[$idx]; if (!empty($settings['proxy_auth'])) { $auths = array_map('trim', explode(',', $settings['proxy_auth'])); if (!empty($auths[$idx])) { $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($auths[$idx]); } } } $response = wp_remote_post($url, $args); if (is_wp_error($response)) { throw new Exception(esc_html($response->get_error_message())); } $code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); if ($body === '' || $body === null) { throw new Exception('Empty response from remote API.'); } $decoded = json_decode($body, true); if ($code !== 200) { $msg = ''; if (!empty($decoded['error']['message'])) { $msg = ', error: ' . esc_html($decoded['error']['message']); } throw new Exception( 'HTTP create assistant request failed with status code ' . intval($code) . esc_html(sanitize_text_field($msg)) ); } return $decoded; } function aimogen_openai_create_assistant_file($token, $assistant_id, $file_id) { if (empty($assistant_id)) { throw new Exception('Assistant ID cannot be empty'); } if (empty($file_id)) { throw new Exception('File ID cannot be empty'); } $settings = get_option('aimogen_Main_Settings', false); if (aimogen_check_if_azure($settings)) { $headers = array( 'Content-Type' => 'application/json', 'api-key' => $token, 'OpenAI-Beta' => 'assistants=v2' ); if ( !empty($settings['azure_api_selector_assistants']) && $settings['azure_api_selector_assistants'] !== 'default' ) { $api_ver = '?api-version=' . $settings['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($settings['azure_endpoint'])) . 'openai/' . $assistant_id . '/files' . $api_ver; } else { $headers = array( 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['openai_organization'])) { $headers['OpenAI-Organization'] = $settings['openai_organization']; } if ( isset($settings['api_selector']) && trim($settings['api_selector']) === 'custom' && !empty(trim($settings['custom_endpoint'], ' /')) ) { $api_endpoint = trim($settings['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . '/v1/assistants/' . $assistant_id . '/files'; } $postData = array( 'file_id' => $file_id ); $args = array( 'method' => 'POST', 'headers' => $headers, 'body' => wp_json_encode($postData), 'timeout' => !empty($settings['max_timeout']) ? intval($settings['max_timeout']) : 300, 'sslverify' => false ); if ( !empty($settings['proxy_ai']) && $settings['proxy_ai'] === 'on' && !empty($settings['proxy_url']) && !in_array($settings['proxy_url'], array('disable', 'disabled'), true) ) { $proxies = array_map('trim', explode(',', $settings['proxy_url'])); $idx = array_rand($proxies); $args['proxy'] = $proxies[$idx]; if (!empty($settings['proxy_auth'])) { $auths = array_map('trim', explode(',', $settings['proxy_auth'])); if (!empty($auths[$idx])) { $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($auths[$idx]); } } } $response = wp_remote_post($url, $args); if (is_wp_error($response)) { throw new Exception(esc_html($response->get_error_message())); } $code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); if ($body === '' || $body === null) { throw new Exception('Empty response from remote API.'); } $decoded = json_decode($body, true); if ($code !== 200) { $msg = ''; if (!empty($decoded['error']['message'])) { $msg = ', error: ' . esc_html($decoded['error']['message']); } throw new Exception( 'HTTP create assistant request failed with status code ' . intval($code) . esc_html(sanitize_text_field($msg)) ); } return $decoded; } function aimogen_openai_modify_thread($token, $thread_id, $vector_store_id = '') { $settings = get_option('aimogen_Main_Settings', false); if (aimogen_check_if_azure($settings)) { $headers = array( 'Content-Type' => 'application/json', 'api-key' => $token, 'OpenAI-Beta' => 'assistants=v2' ); if ( !empty($settings['azure_api_selector_assistants']) && $settings['azure_api_selector_assistants'] !== 'default' ) { $api_ver = '?api-version=' . $settings['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($settings['azure_endpoint'])) . 'openai/threads/' . $thread_id . $api_ver; } else { $headers = array( 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['openai_organization'])) { $headers['OpenAI-Organization'] = $settings['openai_organization']; } if ( isset($settings['api_selector']) && trim($settings['api_selector']) === 'custom' && !empty(trim($settings['custom_endpoint'], ' /')) ) { $api_endpoint = trim($settings['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . '/v1/threads/' . $thread_id; } $postData = array(); if ($vector_store_id !== '') { $postData['tool_resources'] = array( 'file_search' => array( 'vector_store_ids' => array($vector_store_id) ) ); } $args = array( 'method' => 'POST', 'headers' => $headers, 'body' => wp_json_encode($postData), 'timeout' => !empty($settings['max_timeout']) ? intval($settings['max_timeout']) : 300, 'sslverify' => false ); if ( !empty($settings['proxy_ai']) && $settings['proxy_ai'] === 'on' && !empty($settings['proxy_url']) && !in_array($settings['proxy_url'], array('disable', 'disabled'), true) ) { $proxies = array_map('trim', explode(',', $settings['proxy_url'])); $idx = array_rand($proxies); $args['proxy'] = $proxies[$idx]; if (!empty($settings['proxy_auth'])) { $auths = array_map('trim', explode(',', $settings['proxy_auth'])); if (!empty($auths[$idx])) { $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($auths[$idx]); } } } $response = wp_remote_post($url, $args); if (is_wp_error($response)) { throw new Exception(esc_html($response->get_error_message())); } $code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); if ($body === '' || $body === null) { throw new Exception('Empty response from remote API.'); } $decoded = json_decode($body, true); if ($code !== 200) { $msg = ''; if (!empty($decoded['error']['message'])) { $msg = ', error: ' . esc_html($decoded['error']['message']); } throw new Exception( 'HTTP create thread request failed with status code ' . intval($code) . esc_html(sanitize_text_field($msg)) ); } return $decoded; } function aimogen_openai_create_thread($token, $messages = array(), $vector_store_id = '') { $settings = get_option('aimogen_Main_Settings', false); if (aimogen_check_if_azure($settings)) { $headers = array( 'Content-Type' => 'application/json', 'api-key' => $token, 'OpenAI-Beta' => 'assistants=v2' ); if ( !empty($settings['azure_api_selector_assistants']) && $settings['azure_api_selector_assistants'] !== 'default' ) { $api_ver = '?api-version=' . $settings['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($settings['azure_endpoint'])) . 'openai/threads' . $api_ver; } else { $headers = array( 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['openai_organization'])) { $headers['OpenAI-Organization'] = $settings['openai_organization']; } if ( isset($settings['api_selector']) && trim($settings['api_selector']) === 'custom' && !empty(trim($settings['custom_endpoint'], ' /')) ) { $api_endpoint = trim($settings['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . '/v1/threads'; } $postData = array('messages' => $messages); if ($vector_store_id !== '') { $postData['tool_resources'] = array( 'file_search' => array( 'vector_store_ids' => array($vector_store_id) ) ); } $args = array( 'method' => 'POST', 'headers' => $headers, 'body' => wp_json_encode($postData), 'timeout' => !empty($settings['max_timeout']) ? intval($settings['max_timeout']) : 300, 'sslverify' => false ); if ( !empty($settings['proxy_ai']) && $settings['proxy_ai'] === 'on' && !empty($settings['proxy_url']) && !in_array($settings['proxy_url'], array('disable', 'disabled'), true) ) { $proxies = array_map('trim', explode(',', $settings['proxy_url'])); $idx = array_rand($proxies); $args['proxy'] = $proxies[$idx]; if (!empty($settings['proxy_auth'])) { $auths = array_map('trim', explode(',', $settings['proxy_auth'])); if (!empty($auths[$idx])) { $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($auths[$idx]); } } } $response = wp_remote_post($url, $args); if (is_wp_error($response)) { throw new Exception(esc_html($response->get_error_message())); } $code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); if ($body === '' || $body === null) { throw new Exception('Empty response from remote API.'); } $decoded = json_decode($body, true); if ($code !== 200) { $msg = ''; if (!empty($decoded['error']['message'])) { $msg = ', error: ' . esc_html($decoded['error']['message']); } throw new Exception( 'HTTP create thread request failed with status code ' . intval($code) . esc_html(sanitize_text_field($msg)) ); } return $decoded; } function aimogen_openai_create_thread_and_run($token, $assistant_id, $thread = null, $model = null, $instructions = null, $tools = array(), $metadata = null, $file_data = '') { if (empty($metadata)) { $metadata = new stdClass(); } if (empty($assistant_id)) { throw new Exception('Assistant ID cannot be empty'); } $settings = get_option('aimogen_Main_Settings', false); if (aimogen_check_if_azure($settings)) { $headers = array( 'Content-Type' => 'application/json', 'api-key' => $token, 'OpenAI-Beta' => 'assistants=v2' ); if ( !empty($settings['azure_api_selector_assistants']) && $settings['azure_api_selector_assistants'] !== 'default' ) { $api_ver = '?api-version=' . $settings['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($settings['azure_endpoint'])) . 'openai/threads/runs' . $api_ver; $local = array(); $dep = aimogen_get_deployments($token); if (is_array($dep)) { foreach ($dep as $d) { if (empty($d)) { continue; } if (is_string($d)) { $local[trim($d)] = trim($d); } else { $local[trim($d->model)] = trim($d->id); } } } $az = ''; foreach ($local as $m => $id) { if ($m === str_replace('.', '', $model) || $m === $model) { $az = $id; break; } } if ($az === '') { $new = aimogen_update_deployments_azure($token); if ($new !== false) { $local = array(); foreach ($new as $d) { if (empty($d)) { continue; } if (is_string($d)) { $local[trim($d)] = trim($d); } else { $local[trim($d->model)] = trim($d->id); } } foreach ($local as $m => $id) { if ($m === str_replace('.', '', $model) || $m === $model) { $az = $id; break; } } } if ($az === '') { throw new Exception( 'No added Azure deployment found for chat model: ' . esc_html($model) ); } } $model = $az; } else { $headers = array( 'Authorization' => 'Bearer ' . $token, 'Content-Type' => 'application/json', 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['openai_organization'])) { $headers['OpenAI-Organization'] = $settings['openai_organization']; } if ( isset($settings['api_selector']) && trim($settings['api_selector']) === 'custom' && !empty(trim($settings['custom_endpoint'], ' /')) ) { $api_endpoint = trim($settings['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . '/v1/threads/runs'; } $post = array( 'assistant_id' => $assistant_id ); if ($file_data !== '') { $post['tool_resources'] = array( 'file_search' => array( 'vector_store_ids' => array($file_data) ) ); } if (!empty($thread)) { $post['thread'] = $thread; } if ($model !== null) { $post['model'] = $model; } if ($instructions !== null) { $post['instructions'] = $instructions; } if (!empty($tools)) { $post['tools'] = $tools; } if (!empty($metadata)) { $post['metadata'] = $metadata; } if (!empty($settings['assist_max_prompt_token'])) { $post['max_prompt_tokens'] = intval($settings['assist_max_prompt_token']); } if (!empty($settings['assist_max_completion_token'])) { $post['max_completion_tokens'] = intval($settings['assist_max_completion_token']); } $args = array( 'method' => 'POST', 'headers' => $headers, 'body' => wp_json_encode($post), 'timeout' => !empty($settings['max_timeout']) ? intval($settings['max_timeout']) : 300, 'sslverify' => false ); if ( !empty($settings['proxy_ai']) && $settings['proxy_ai'] === 'on' && !empty($settings['proxy_url']) && !in_array($settings['proxy_url'], array('disable', 'disabled'), true) ) { $proxies = array_map('trim', explode(',', $settings['proxy_url'])); $idx = array_rand($proxies); $args['proxy'] = $proxies[$idx]; if (!empty($settings['proxy_auth'])) { $auth = array_map('trim', explode(',', $settings['proxy_auth'])); if (!empty($auth[$idx])) { $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($auth[$idx]); } } } $response = wp_remote_post($url, $args); if (is_wp_error($response)) { throw new Exception( esc_html($response->get_error_message()) ); } $code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); if ($body === '' || $body === null) { throw new Exception('Empty response from remote API.'); } $decoded = json_decode($body, true); if ($code !== 200) { $msg = ''; if (!empty($decoded['error']['message'])) { $msg = ', error: ' . esc_html($decoded['error']['message']); } throw new Exception( 'HTTP create thread rund request failed with status code ' . intval($code) . esc_html(sanitize_text_field($msg)) ); } return $decoded; } function aimogen_openai_create_message($token, $thread_id, $role, $content, $metadata = null, $vision_file = '') { if (empty($metadata)) { $metadata = new stdClass(); } if (empty($thread_id)) { throw new Exception('Thread ID cannot be empty'); } if (empty($role)) { throw new Exception('Role cannot be empty'); } if (empty($content)) { throw new Exception('Content cannot be empty'); } $settings = get_option('aimogen_Main_Settings', false); if (aimogen_check_if_azure($settings)) { $headers = array( 'Content-Type' => 'application/json', 'api-key' => $token, 'OpenAI-Beta' => 'assistants=v2' ); if ( !empty($settings['azure_api_selector_assistants']) && $settings['azure_api_selector_assistants'] !== 'default' ) { $api_ver = '?api-version=' . $settings['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($settings['azure_endpoint'])) . 'openai/threads/' . $thread_id . '/messages' . $api_ver; } else { $headers = array( 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['openai_organization'])) { $headers['OpenAI-Organization'] = $settings['openai_organization']; } if ( isset($settings['api_selector']) && trim($settings['api_selector']) === 'custom' && !empty(trim($settings['custom_endpoint'], ' /')) ) { $api_endpoint = trim($settings['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . '/v1/threads/' . $thread_id . '/messages'; } if ($vision_file !== '' && $role === 'user') { $xacontent = array( array('type' => 'text', 'text' => $content), array( 'type' => 'image_url', 'image_url' => array( 'url' => $vision_file, 'detail' => 'low' ) ) ); $content = $xacontent; } $post = array( 'role' => $role, 'content' => $content, 'metadata' => $metadata ); $args = array( 'method' => 'POST', 'headers' => $headers, 'body' => wp_json_encode($post), 'timeout' => !empty($settings['max_timeout']) ? intval($settings['max_timeout']) : 300, 'sslverify' => false ); if ( !empty($settings['proxy_ai']) && $settings['proxy_ai'] === 'on' && !empty($settings['proxy_url']) && !in_array($settings['proxy_url'], array('disable', 'disabled'), true) ) { $proxies = array_map('trim', explode(',', $settings['proxy_url'])); $idx = array_rand($proxies); $args['proxy'] = $proxies[$idx]; if (!empty($settings['proxy_auth'])) { $auth = array_map('trim', explode(',', $settings['proxy_auth'])); if (!empty($auth[$idx])) { $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($auth[$idx]); } } } $response = wp_remote_post($url, $args); if (is_wp_error($response)) { throw new Exception( esc_html($response->get_error_message()) ); } $code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); if ($body === '' || $body === null) { throw new Exception('Empty response from remote API.'); } $decoded = json_decode($body, true); if ($code !== 200) { $msg = ''; if (!empty($decoded['error']['message'])) { $msg = ', error: ' . esc_html($decoded['error']['message']); } throw new Exception( 'HTTP create message request failed with status code ' . intval($code) . esc_html(sanitize_text_field($msg)) ); } return $decoded; } function aimogen_openai_submit_tool_outputs_to_run($token, $thread_id, $run_id, $tool_outputs) { if (empty($thread_id)) { throw new Exception('Thread ID cannot be empty'); } if (empty($run_id)) { throw new Exception('Run ID cannot be empty'); } if (empty($tool_outputs)) { throw new Exception('Tool outputs cannot be empty'); } $settings = get_option('aimogen_Main_Settings', false); if (aimogen_check_if_azure($settings)) { $headers = array( 'Content-Type' => 'application/json', 'api-key' => $token, 'OpenAI-Beta' => 'assistants=v2' ); if ( !empty($settings['azure_api_selector_assistants']) && $settings['azure_api_selector_assistants'] !== 'default' ) { $api_ver = '?api-version=' . $settings['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($settings['azure_endpoint'])) . 'openai/threads/' . $thread_id . '/runs/' . $run_id . '/submit_tool_outputs' . $api_ver; } else { $headers = array( 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $token, 'OpenAI-Beta' => 'assistants=v2' ); if (!empty($settings['openai_organization'])) { $headers['OpenAI-Organization'] = $settings['openai_organization']; } if ( isset($settings['api_selector']) && trim($settings['api_selector']) === 'custom' && !empty(trim($settings['custom_endpoint'], ' /')) ) { $api_endpoint = trim($settings['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . '/v1/threads/' . $thread_id . '/runs/' . $run_id . '/submit_tool_outputs'; } $payload = array('tool_outputs' => $tool_outputs); $args = array( 'method' => 'POST', 'headers' => $headers, 'body' => wp_json_encode($payload), 'timeout' => !empty($settings['max_timeout']) ? intval($settings['max_timeout']) : 300, 'sslverify' => false ); if ( !empty($settings['proxy_ai']) && $settings['proxy_ai'] === 'on' && !empty($settings['proxy_url']) && !in_array($settings['proxy_url'], array('disable', 'disabled'), true) ) { $proxies = array_map('trim', explode(',', $settings['proxy_url'])); $idx = array_rand($proxies); $args['proxy'] = $proxies[$idx]; if (!empty($settings['proxy_auth'])) { $auth = array_map('trim', explode(',', $settings['proxy_auth'])); if (!empty($auth[$idx])) { $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($auth[$idx]); } } } $response = wp_remote_post($url, $args); if (is_wp_error($response)) { throw new Exception( esc_html($response->get_error_message()) ); } $code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); $decoded = json_decode($body, true); if ($code !== 200) { $msg = ''; if (!empty($decoded['error']['message'])) { $msg = ', error: ' . esc_html($decoded['error']['message']); } throw new Exception( 'HTTP submit tool output request failed with status code ' . intval($code) . esc_html(sanitize_text_field($msg)) ); } return $decoded; } function aimogen_openai_submit_tool_outputs_to_stream_run($token, $thread_id, $run_id, $tool_outputs) { if (empty($thread_id)) { throw new Exception('Thread ID cannot be empty'); } if (empty($run_id)) { throw new Exception('Run ID cannot be empty'); } if (empty($tool_outputs)) { throw new Exception('Tool outputs cannot be empty'); } $aimogen_Main_Settings = get_option('aimogen_Main_Settings', false); if(aimogen_check_if_azure($aimogen_Main_Settings)) { $headers = [ 'Content-Type: application/json', 'api-key:' . $token, 'OpenAI-Beta: assistants=v2' ]; if (isset($aimogen_Main_Settings['azure_api_selector_assistants']) && $aimogen_Main_Settings['azure_api_selector_assistants'] != '' && $aimogen_Main_Settings['azure_api_selector_assistants'] != 'default') { $api_ver = '?api-version=' . $aimogen_Main_Settings['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($aimogen_Main_Settings['azure_endpoint'])) . 'openai/threads/' . $thread_id . "/runs/" . $run_id . "/submit_tool_outputs" . $api_ver; } else { $headers = [ 'Content-Type: application/json', 'Authorization: Bearer ' . $token, 'OpenAI-Beta: assistants=v2' ]; if (isset($aimogen_Main_Settings['openai_organization']) && $aimogen_Main_Settings['openai_organization'] != '') { $headers['OpenAI-Organization'] = $aimogen_Main_Settings['openai_organization']; } if (isset($aimogen_Main_Settings['api_selector']) && trim($aimogen_Main_Settings['api_selector']) == 'custom' && isset($aimogen_Main_Settings['custom_endpoint']) && trim($aimogen_Main_Settings['custom_endpoint'], ' /') != '') { $api_endpoint = trim($aimogen_Main_Settings['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . "/v1/threads/" . $thread_id . "/runs/" . $run_id . "/submit_tool_outputs"; } $postData = [ 'tool_outputs' => $tool_outputs, 'stream' => true ]; // Streaming request payload - must be done with cURL, not wp_remote_post, as WP does not support streaming responses $ch = curl_init($url);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_init if ($ch === false) { throw new Exception('Failed to initialize cURL session'); } if (isset($aimogen_Main_Settings['proxy_ai']) && $aimogen_Main_Settings['proxy_ai'] == 'on' && isset($aimogen_Main_Settings['proxy_url']) && $aimogen_Main_Settings['proxy_url'] != '' && $aimogen_Main_Settings['proxy_url'] != 'disable' && $aimogen_Main_Settings['proxy_url'] != 'disabled') { $prx = explode(',', $aimogen_Main_Settings['proxy_url']); $randomness = array_rand($prx); curl_setopt($ch, CURLOPT_PROXY , trim($prx[$randomness]));// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt if (isset($aimogen_Main_Settings['proxy_auth']) && $aimogen_Main_Settings['proxy_auth'] != '') { $prx_auth = explode(',', $aimogen_Main_Settings['proxy_auth']); if(isset($prx_auth[$randomness]) && trim($prx_auth[$randomness]) != '') { curl_setopt($ch, CURLOPT_PROXYUSERPWD , trim($prx_auth[$randomness]));// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt } } } curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt curl_setopt($ch, CURLOPT_POST, true);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData));// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt if (isset($aimogen_Main_Settings['max_timeout']) && $aimogen_Main_Settings['max_timeout'] != '') { $ztime = intval($aimogen_Main_Settings['max_timeout']); } else { $ztime = 300; } curl_setopt($ch, CURLOPT_TIMEOUT, $ztime);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($curl_info, $data) // phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt { $my_copy_data = trim($data); $prefix = 'data: '; if (substr($my_copy_data, 0, strlen($prefix)) == $prefix) { $my_copy_data = substr($my_copy_data, strlen($prefix)); } $suffix = 'data: [DONE]'; $needle_length = strlen($suffix); if (substr($my_copy_data, -$needle_length) === $suffix) { $my_copy_data = substr($my_copy_data, 0, -$needle_length); } $my_copy_data = trim($my_copy_data); $response = json_decode($my_copy_data, true); if (isset($response['error']) && !empty($response['error'])) { $message = isset($response['error']['message']) && !empty($response['error']['message']) ? $response['error']['message'] : ''; if (empty($message) && isset($response['error']['code']) && $response['error']['code'] == 'invalid_api_key') { $message = "Incorrect API key provided. You can find your API key at https://platform.openai.com/account/api-keys."; } echo "event: message\n"; echo 'data: {"error":[{"message":"' . esc_js($message) . '"}]}'; echo "\n\n"; $l1 = ob_get_length(); if($l1 === false) { $l1 = 0; } if (ob_get_length()) { ob_end_flush(); } flush(); echo 'data: {"choices":[{"finish_reason":"stop"}]}'; echo "\n\n"; $l2 = ob_get_length(); if($l2 === false) { $l2 = 0; } if (ob_get_length()) { ob_end_flush(); } flush(); return $l1 + $l2; } else { //not escaped because of streaming // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped // added wp_strip_all_tags now! echo esc_html(wp_strip_all_tags( $data )); if (ob_get_length()) { ob_flush(); } flush(); return strlen($data); } }); // Streaming request payload - must be done with cURL, not wp_remote_post, as WP does not support streaming responses $response = curl_exec($ch);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_exec if ($response === false) { $error = curl_error($ch);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_error curl_close($ch);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_close throw new Exception('cURL error: ' . esc_html($error)); } $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_getinfo if ($httpCode != 200) { $error = curl_error($ch);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_error curl_close($ch);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_close $jsdec = json_decode($response, true); throw new Exception("HTTP streamed tool output submit request failed with status code " . esc_html($httpCode) . (isset($jsdec['error']['message']) ? ', error: ' . esc_html($jsdec['error']['message']) : '')); } curl_close($ch);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_close return json_decode($response, true); } function aimogen_openai_retrieve_run($token, $thread_id, $run_id) { if (empty($thread_id)) { throw new Exception('Thread ID cannot be empty'); } if (empty($run_id)) { throw new Exception('Run ID cannot be empty'); } $s = get_option('aimogen_Main_Settings', false); if (aimogen_check_if_azure($s)) { $headers = [ 'Content-Type' => 'application/json', 'api-key' => $token, 'OpenAI-Beta' => 'assistants=v2' ]; if (!empty($s['azure_api_selector_assistants']) && $s['azure_api_selector_assistants'] !== 'default') { $api_ver = '?api-version=' . $s['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($s['azure_endpoint'])) . 'openai/threads/' . $thread_id . '/runs/' . $run_id . $api_ver; } else { $headers = [ 'Authorization' => 'Bearer ' . $token, 'OpenAI-Beta' => 'assistants=v2' ]; if (!empty($s['openai_organization'])) { $headers['OpenAI-Organization'] = $s['openai_organization']; } if (!empty($s['api_selector']) && trim($s['api_selector']) === 'custom' && !empty(trim($s['custom_endpoint'], ' /'))) { $api_endpoint = trim($s['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . '/v1/threads/' . $thread_id . '/runs/' . $run_id; } $timeout = !empty($s['max_timeout']) ? intval($s['max_timeout']) : 300; $args = [ 'method' => 'GET', 'headers' => $headers, 'timeout' => $timeout, 'sslverify' => false ]; if (!empty($s['proxy_ai']) && $s['proxy_ai'] === 'on' && !empty($s['proxy_url']) && !in_array($s['proxy_url'], ['disable','disabled'], true)) { $proxies = array_map('trim', explode(',', $s['proxy_url'])); $selected = $proxies[array_rand($proxies)]; $args['proxy'] = $selected; if (!empty($s['proxy_auth'])) { $auths = array_map('trim', explode(',', $s['proxy_auth'])); $auth = $auths[array_rand($auths)] ?? ''; if (!empty($auth)) { $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($auth); } } } $response = wp_remote_get($url, $args); if (is_wp_error($response)) { throw new Exception('HTTP error: ' . esc_html($response->get_error_message())); } $code = wp_remote_retrieve_response_code($response); $body = wp_remote_retrieve_body($response); if ($code != 200) { $decoded = json_decode($body, true); throw new Exception( "HTTP retrieve run request failed with status code " . esc_html($code) . (isset($decoded['error']['message']) ? ', error: ' . esc_html($decoded['error']['message']) : '') ); } return json_decode($body, true); } function aimogen_openai_create_run($token, $thread_id, $assistant_id, $model = null, $instructions = null, $tools = [], $metadata = null) { if (empty($metadata)) { $metadata = new stdClass(); } if (empty($thread_id)) { throw new Exception('Thread ID cannot be empty'); } if (empty($assistant_id)) { throw new Exception('Assistant ID cannot be empty'); } $s = get_option('aimogen_Main_Settings', false); if (aimogen_check_if_azure($s)) { $headers = [ 'Content-Type' => 'application/json', 'api-key' => $token, 'OpenAI-Beta' => 'assistants=v2' ]; if (!empty($s['azure_api_selector_assistants']) && $s['azure_api_selector_assistants'] !== 'default') { $api_ver = '?api-version=' . $s['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($s['azure_endpoint'])) . 'openai/threads/' . $thread_id . '/runs' . $api_ver; $localAzureDeployments = []; $depl_arr = aimogen_get_deployments($token); if (is_array($depl_arr)) { foreach ($depl_arr as $dar) { if (empty($dar)) { continue; } if (is_string($dar)) { $localAzureDeployments[trim($dar)] = trim($dar); } else { $localAzureDeployments[trim($dar->model)] = trim($dar->id); } } } $resolved = ''; foreach ($localAzureDeployments as $dmodel => $dname) { if ($dmodel === str_replace('.', '', $model) || $dmodel === $model) { $resolved = $dname; break; } } if ($resolved === '') { $new = aimogen_update_deployments_azure($token); if ($new !== false) { $localAzureDeployments = []; foreach ($new as $dar) { if (empty($dar)) { continue; } if (is_string($dar)) { $localAzureDeployments[trim($dar)] = trim($dar); } else { $localAzureDeployments[trim($dar->model)] = trim($dar->id); } } foreach ($localAzureDeployments as $dmodel => $dname) { if ($dmodel === str_replace('.', '', $model) || $dmodel === $model) { $resolved = $dname; break; } } } if ($resolved === '') { throw new Exception( 'No added Azure deployment found for chat model: ' . esc_html($model) ); } } $model = $resolved; } else { $headers = [ 'Authorization' => 'Bearer ' . $token, 'Content-Type' => 'application/json', 'OpenAI-Beta' => 'assistants=v2' ]; if (!empty($s['openai_organization'])) { $headers['OpenAI-Organization'] = $s['openai_organization']; } if (!empty($s['api_selector']) && trim($s['api_selector']) === 'custom' && !empty(trim($s['custom_endpoint'], ' /'))) { $api_endpoint = trim($s['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . '/v1/threads/' . $thread_id . '/runs'; } $post = [ 'assistant_id' => $assistant_id ]; if ($model !== null) { $post['model'] = $model; } if ($instructions !== null) { $post['instructions'] = $instructions; } if (!empty($tools)) { $post['tools'] = $tools; } if (!empty($metadata)) { $post['metadata'] = $metadata; } if (!empty($s['assist_max_prompt_token'])) { $post['max_prompt_tokens'] = intval($s['assist_max_prompt_token']); } if (!empty($s['assist_max_completion_token'])) { $post['max_completion_tokens'] = intval($s['assist_max_completion_token']); } $timeout = !empty($s['max_timeout']) ? intval($s['max_timeout']) : 300; $args = [ 'method' => 'POST', 'headers' => $headers, 'body' => wp_json_encode($post), 'timeout' => $timeout, 'sslverify' => false ]; if (!empty($s['proxy_ai']) && $s['proxy_ai'] === 'on' && !empty($s['proxy_url']) && !in_array($s['proxy_url'], ['disable','disabled'], true)) { $proxies = array_map('trim', explode(',', $s['proxy_url'])); $selected = $proxies[array_rand($proxies)]; $args['proxy'] = $selected; if (!empty($s['proxy_auth'])) { $auths = array_map('trim', explode(',', $s['proxy_auth'])); $chosen = $auths[array_rand($auths)] ?? ''; if (!empty($chosen)) { $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($chosen); } } } $resp = wp_remote_post($url, $args); if (is_wp_error($resp)) { throw new Exception('HTTP error: ' . esc_html($resp->get_error_message())); } $code = wp_remote_retrieve_response_code($resp); $body = wp_remote_retrieve_body($resp); if ($code != 200) { $decoded = json_decode($body, true); throw new Exception( "HTTP create run request failed with status code " . esc_html($code) . (isset($decoded['error']['message']) ? ', error: ' . esc_html($decoded['error']['message']) : '') ); } return json_decode($body, true); } function aimogen_openai_create_stream_run($token, $thread_id, $assistant_id, $model = null, $instructions = null, $tools = [], $metadata = null) { if (empty($metadata)) { $metadata = new stdClass(); } if (empty($thread_id)) { throw new Exception('Thread ID cannot be empty'); } if (empty($assistant_id)) { throw new Exception('Assistant ID cannot be empty'); } $aimogen_Main_Settings = get_option('aimogen_Main_Settings', false); if(aimogen_check_if_azure($aimogen_Main_Settings)) { $headers = [ 'Content-Type: application/json', 'api-key:' . $token, 'OpenAI-Beta: assistants=v2' ]; if (isset($aimogen_Main_Settings['azure_api_selector_assistants']) && $aimogen_Main_Settings['azure_api_selector_assistants'] != '' && $aimogen_Main_Settings['azure_api_selector_assistants'] != 'default') { $api_ver = '?api-version=' . $aimogen_Main_Settings['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($aimogen_Main_Settings['azure_endpoint'])) . 'openai/threads/' . $thread_id . "/runs" . $api_ver; $localAzureDeployments = array(); $depl_arr = aimogen_get_deployments($token); if(is_array($depl_arr)) { foreach($depl_arr as $dar) { if(empty($dar)) { continue; } if(is_string($dar)) { $localAzureDeployments[trim($dar)] = trim($dar); } else { $localAzureDeployments[trim($dar->model)] = trim($dar->id); } } } $azureDeployment = ''; foreach ( $localAzureDeployments as $dmodel => $dname ) { if ( $dmodel === str_replace('.', '', $model) || $dmodel === $model ) { $azureDeployment = $dname; break; } } if ( $azureDeployment == '' ) { $new_dep = aimogen_update_deployments_azure($token); if($new_dep !== false) { $localAzureDeployments = array(); foreach($new_dep as $dar) { if(empty($dar)) { continue; } if(is_string($dar)) { $localAzureDeployments[trim($dar)] = trim($dar); } else { $localAzureDeployments[trim($dar->model)] = trim($dar->id); } } foreach ( $localAzureDeployments as $dmodel => $dname ) { if ( $dmodel === str_replace('.', '', $model) || $dmodel === $model ) { $azureDeployment = $dname; break; } } } if ( $azureDeployment == '' ) { throw new Exception('No added Azure deployment found for chat model: ' . esc_html($model) . ' - you need to add this model in your Azure Portal as a Deployment'); } } $model = $azureDeployment; } else { $headers = [ 'Authorization: Bearer ' . $token, 'Content-Type: application/json', 'OpenAI-Beta: assistants=v2' ]; if (isset($aimogen_Main_Settings['openai_organization']) && $aimogen_Main_Settings['openai_organization'] != '') { $headers['OpenAI-Organization'] = $aimogen_Main_Settings['openai_organization']; } if (isset($aimogen_Main_Settings['api_selector']) && trim($aimogen_Main_Settings['api_selector']) == 'custom' && isset($aimogen_Main_Settings['custom_endpoint']) && trim($aimogen_Main_Settings['custom_endpoint'], ' /') != '') { $api_endpoint = trim($aimogen_Main_Settings['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . "/v1/threads/" . $thread_id . "/runs"; } $postData = [ 'assistant_id' => $assistant_id ]; if ($model !== null) { $postData['model'] = $model; } if ($instructions !== null) { $postData['instructions'] = $instructions; } if (!empty($tools)) { $postData['tools'] = $tools; } if (!empty($metadata)) { $postData['metadata'] = $metadata; } if(isset($aimogen_Main_Settings['assist_max_prompt_token']) && $aimogen_Main_Settings['assist_max_prompt_token'] != '') { $postData['max_prompt_tokens'] = intval($aimogen_Main_Settings['assist_max_prompt_token']); } if(isset($aimogen_Main_Settings['assist_max_completion_token']) && $aimogen_Main_Settings['assist_max_completion_token'] != '') { $postData['max_completion_tokens'] = intval($aimogen_Main_Settings['assist_max_completion_token']); } $postData['stream'] = true; // Streaming request payload - must be done with cURL, not wp_remote_post, as WP does not support streaming responses $ch = curl_init($url);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_init if ($ch === false) { throw new Exception('Failed to initialize cURL session'); } if (isset($aimogen_Main_Settings['proxy_ai']) && $aimogen_Main_Settings['proxy_ai'] == 'on' && isset($aimogen_Main_Settings['proxy_url']) && $aimogen_Main_Settings['proxy_url'] != '' && $aimogen_Main_Settings['proxy_url'] != 'disable' && $aimogen_Main_Settings['proxy_url'] != 'disabled') { $prx = explode(',', $aimogen_Main_Settings['proxy_url']); $randomness = array_rand($prx); curl_setopt($ch, CURLOPT_PROXY , trim($prx[$randomness]));// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt if (isset($aimogen_Main_Settings['proxy_auth']) && $aimogen_Main_Settings['proxy_auth'] != '') { $prx_auth = explode(',', $aimogen_Main_Settings['proxy_auth']); if(isset($prx_auth[$randomness]) && trim($prx_auth[$randomness]) != '') { curl_setopt($ch, CURLOPT_PROXYUSERPWD , trim($prx_auth[$randomness]));// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt } } } curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt curl_setopt($ch, CURLOPT_POST, true);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData));// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt if (isset($aimogen_Main_Settings['max_timeout']) && $aimogen_Main_Settings['max_timeout'] != '') { $ztime = intval($aimogen_Main_Settings['max_timeout']); } else { $ztime = 300; } curl_setopt($ch, CURLOPT_TIMEOUT, $ztime);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($curl_info, $data)// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt { $my_copy_data = trim($data); $prefix = 'data: '; if (substr($my_copy_data, 0, strlen($prefix)) == $prefix) { $my_copy_data = substr($my_copy_data, strlen($prefix)); } $suffix = 'data: [DONE]'; $needle_length = strlen($suffix); if (substr($my_copy_data, -$needle_length) === $suffix) { $my_copy_data = substr($my_copy_data, 0, -$needle_length); } $my_copy_data = trim($my_copy_data); $response = json_decode($my_copy_data, true); if (isset($response['error']) && !empty($response['error'])) { $message = isset($response['error']['message']) && !empty($response['error']['message']) ? $response['error']['message'] : ''; if (empty($message) && isset($response['error']['code']) && $response['error']['code'] == 'invalid_api_key') { $message = "Incorrect API key provided. You can find your API key at https://platform.openai.com/account/api-keys."; } echo "event: message\n"; echo 'data: {"error":[{"message":"' . esc_js($message) . '"}]}'; echo "\n\n"; $l1 = ob_get_length(); if($l1 === false) { $l1 = 0; } if (ob_get_length()) { ob_end_flush(); } flush(); echo 'data: {"choices":[{"finish_reason":"stop"}]}'; echo "\n\n"; $l2 = ob_get_length(); if($l2 === false) { $l2 = 0; } if (ob_get_length()) { ob_end_flush(); } flush(); return $l1 + $l2; } else { //not escaped because of streaming // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped // added wp_strip_all_tags now! echo esc_html(wp_strip_all_tags( $data )); if (ob_get_length()) { ob_flush(); } flush(); return strlen($data); } }); // Streaming request payload - must be done with cURL, not wp_remote_post, as WP does not support streaming responses $response = curl_exec($ch);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_exec if ($response === false) { $error = curl_error($ch);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_error curl_close($ch);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_close throw new Exception('cURL error: ' . esc_html($error)); } $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_getinfo if ($httpCode != 200) { $error = curl_error($ch);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_error curl_close($ch);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_close $jsdec = json_decode($response, true); throw new Exception("HTTP create stream run request failed with status code " . esc_html($httpCode) . (isset($jsdec['error']['message']) ? ', error: ' . esc_html($jsdec['error']['message']) : '')); } curl_close($ch);// phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_close return json_decode($response, true); }function aimogen_openai_retrieve_run_step($token, $thread_id, $run_id, $step_id) { if (empty($thread_id)) { throw new Exception('Thread ID cannot be empty'); } if (empty($run_id)) { throw new Exception('Run ID cannot be empty'); } if (empty($step_id)) { throw new Exception('Step ID cannot be empty'); } $s = get_option('aimogen_Main_Settings', false); if (aimogen_check_if_azure($s)) { $headers = [ 'Content-Type' => 'application/json', 'api-key' => $token, 'OpenAI-Beta' => 'assistants=v2' ]; if (!empty($s['azure_api_selector_assistants']) && $s['azure_api_selector_assistants'] !== 'default') { $api_ver = '?api-version=' . $s['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($s['azure_endpoint'])) . 'openai/threads/' . $thread_id . '/runs/' . $run_id . '/steps/' . $step_id . $api_ver; } else { $headers = [ 'Authorization' => 'Bearer ' . $token, 'Content-Type' => 'application/json', 'OpenAI-Beta' => 'assistants=v2' ]; if (!empty($s['openai_organization'])) { $headers['OpenAI-Organization'] = $s['openai_organization']; } if (!empty($s['api_selector']) && trim($s['api_selector']) === 'custom' && !empty(trim($s['custom_endpoint'], ' /'))) { $api_endpoint = trim($s['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . '/v1/threads/' . $thread_id . '/runs/' . $run_id . '/steps/' . $step_id; } $args = [ 'method' => 'GET', 'headers' => $headers, 'timeout' => 300, 'sslverify' => false ]; if (!empty($s['proxy_ai']) && $s['proxy_ai'] === 'on' && !empty($s['proxy_url']) && !in_array($s['proxy_url'], ['disable','disabled'], true)) { $proxies = array_map('trim', explode(',', $s['proxy_url'])); $selected = $proxies[array_rand($proxies)]; $args['proxy'] = $selected; if (!empty($s['proxy_auth'])) { $auths = array_map('trim', explode(',', $s['proxy_auth'])); $chosen = $auths[array_rand($auths)] ?? ''; if (!empty($chosen)) { $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($chosen); } } } $resp = wp_remote_get($url, $args); if (is_wp_error($resp)) { throw new Exception('HTTP error: ' . esc_html($resp->get_error_message())); } $code = wp_remote_retrieve_response_code($resp); $body = wp_remote_retrieve_body($resp); if ($code != 200) { $decoded = json_decode($body, true); throw new Exception( 'HTTP retrieve run step request failed with status code ' . esc_html($code) . (isset($decoded['error']['message']) ? ', error: ' . esc_html($decoded['error']['message']) : '') ); } return json_decode($body, true); } function aimogen_openai_retrieve_message($token, $thread_id, $message_id) { if (empty($thread_id)) { throw new Exception('Thread ID cannot be empty'); } if (empty($message_id)) { throw new Exception('Message ID cannot be empty'); } $s = get_option('aimogen_Main_Settings', false); if (aimogen_check_if_azure($s)) { $headers = [ 'Content-Type' => 'application/json', 'api-key' => $token, 'OpenAI-Beta' => 'assistants=v2' ]; if (!empty($s['azure_api_selector_assistants']) && $s['azure_api_selector_assistants'] !== 'default') { $api_ver = '?api-version=' . $s['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($s['azure_endpoint'])) . 'openai/threads/' . $thread_id . '/messages/' . $message_id . $api_ver; } else { $headers = [ 'Authorization' => 'Bearer ' . $token, 'Content-Type' => 'application/json', 'OpenAI-Beta' => 'assistants=v2' ]; if (!empty($s['openai_organization'])) { $headers['OpenAI-Organization'] = $s['openai_organization']; } if (!empty($s['api_selector']) && trim($s['api_selector']) === 'custom' && !empty(trim($s['custom_endpoint'], ' /'))) { $api_endpoint = trim($s['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . '/v1/threads/' . $thread_id . '/messages/' . $message_id; } $args = [ 'method' => 'GET', 'headers' => $headers, 'timeout' => 300, 'sslverify' => false ]; if (!empty($s['proxy_ai']) && $s['proxy_ai'] === 'on' && !empty($s['proxy_url']) && !in_array($s['proxy_url'], ['disable','disabled'], true)) { $proxies = array_map('trim', explode(',', $s['proxy_url'])); $chosen = $proxies[array_rand($proxies)]; $args['proxy'] = $chosen; if (!empty($s['proxy_auth'])) { $auths = array_map('trim', explode(',', $s['proxy_auth'])); $auth = $auths[array_rand($auths)] ?? ''; if (!empty($auth)) { $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($auth); } } } $resp = wp_remote_get($url, $args); if (is_wp_error($resp)) { throw new Exception('HTTP error: ' . esc_html($resp->get_error_message())); } $code = wp_remote_retrieve_response_code($resp); $body = wp_remote_retrieve_body($resp); if ($code != 200) { $dump = json_decode($body, true); throw new Exception( 'HTTP retrieve message request failed with status code ' . esc_html($code) . (isset($dump['error']['message']) ? ', error: ' . esc_html($dump['error']['message']) : '') ); } return json_decode($body, true); } function aimogen_openai_list_messages($token, $thread_id, $limit = 20, $order = 'desc', $after = null, $before = null) { if (empty($thread_id)) { throw new Exception('Thread ID is required'); } $queryParams = http_build_query([ 'limit' => $limit, 'order' => $order, 'after' => $after, 'before' => $before ]); $s = get_option('aimogen_Main_Settings', false); if (aimogen_check_if_azure($s)) { $headers = [ 'Content-Type' => 'application/json', 'api-key' => $token, 'OpenAI-Beta' => 'assistants=v2' ]; if (!empty($s['azure_api_selector_assistants']) && $s['azure_api_selector_assistants'] !== 'default') { $api_ver = '?api-version=' . $s['azure_api_selector_assistants']; } else { $api_ver = AIMOGEN_AZURE_ASSISTANTS_API_VERSION; } $url = trailingslashit(trim($s['azure_endpoint'])) . 'openai/threads/' . $thread_id . '/messages?' . $queryParams . str_replace('?', '&', $api_ver); } else { $headers = [ 'Content-Type' => 'application/json', 'Authorization'=> 'Bearer ' . $token, 'OpenAI-Beta' => 'assistants=v2' ]; if (!empty($s['openai_organization'])) { $headers['OpenAI-Organization'] = $s['openai_organization']; } if (!empty($s['api_selector']) && trim($s['api_selector']) === 'custom' && !empty(trim($s['custom_endpoint'], ' /'))) { $api_endpoint = trim($s['custom_endpoint'], ' /'); } else { $api_endpoint = 'https://api.openai.com'; } $url = $api_endpoint . '/v1/threads/' . $thread_id . '/messages?' . $queryParams; } $args = [ 'method' => 'GET', 'headers' => $headers, 'timeout' => 300, 'sslverify' => false ]; if (!empty($s['proxy_ai']) && $s['proxy_ai'] === 'on' && !empty($s['proxy_url']) && !in_array($s['proxy_url'], ['disable', 'disabled'], true)) { $proxies = array_map('trim', explode(',', $s['proxy_url'])); $chosen = $proxies[array_rand($proxies)]; $args['proxy'] = $chosen; if (!empty($s['proxy_auth'])) { $auth_list = array_map('trim', explode(',', $s['proxy_auth'])); $chosen_auth = $auth_list[array_rand($auth_list)] ?? ''; if (!empty($chosen_auth)) { // WP-style proxy authentication $args['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($chosen_auth); } } } $resp = wp_remote_get($url, $args); if (is_wp_error($resp)) { throw new Exception('HTTP error: ' . esc_html($resp->get_error_message())); } $code = wp_remote_retrieve_response_code($resp); $body = wp_remote_retrieve_body($resp); if ($code != 200) { $decoded = json_decode($body, true); throw new Exception( 'HTTP request for messages failed with code ' . esc_html($code) . (isset($decoded['error']['message']) ? ', error: ' . esc_html($decoded['error']['message']) : '') ); } $decoded = json_decode($body, true); if (json_last_error() !== JSON_ERROR_NONE) { throw new Exception('Failed to decode JSON response'); } return $decoded; } ?>