Add Google and Groq AI providers, enhance provider manager, and implement conversation and logging services
- Introduced `Groq_AI_Provider_Google` and `Groq_AI_Provider_Groq` classes for handling AI interactions with Google and Groq respectively. - Enhanced `Groq_AI_Provider_Manager` to register and manage multiple AI providers. - Implemented `Groq_AI_Conversation_Manager` for managing conversation IDs and context hashes. - Added `Groq_AI_Generation_Logger` for logging AI generation events and managing log tables. - Developed `Groq_AI_Prompt_Builder` for constructing prompts and processing AI responses. - Established `Groq_AI_Settings_Manager` for managing plugin settings, including context fields and module configurations.
This commit is contained in:
141
includes/Providers/class-groq-ai-abstract-openai-provider.php
Normal file
141
includes/Providers/class-groq-ai-abstract-openai-provider.php
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
abstract class Groq_AI_Abstract_OpenAI_Provider implements Groq_AI_Provider_Interface {
|
||||
public function get_available_models() {
|
||||
return [];
|
||||
}
|
||||
|
||||
public function supports_response_format() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function supports_live_models() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function fetch_live_models( $api_key ) {
|
||||
$endpoint = $this->get_models_endpoint();
|
||||
if ( empty( $endpoint ) ) {
|
||||
return new WP_Error( 'groq_ai_models_endpoint_missing', __( 'Geen model-endpoint beschikbaar voor deze aanbieder.', 'groq-ai-product-text' ) );
|
||||
}
|
||||
|
||||
$response = wp_remote_get(
|
||||
$endpoint,
|
||||
[
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $api_key,
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
'timeout' => 20,
|
||||
]
|
||||
);
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$body = json_decode( wp_remote_retrieve_body( $response ), true );
|
||||
|
||||
if ( isset( $body['error']['message'] ) ) {
|
||||
return new WP_Error( 'groq_ai_provider_error', (string) $body['error']['message'] );
|
||||
}
|
||||
|
||||
if ( empty( $body['data'] ) || ! is_array( $body['data'] ) ) {
|
||||
return new WP_Error( 'groq_ai_empty_response', __( 'Geen modeldata ontvangen.', 'groq-ai-product-text' ) );
|
||||
}
|
||||
|
||||
$models = [];
|
||||
foreach ( $body['data'] as $model ) {
|
||||
if ( ! empty( $model['id'] ) ) {
|
||||
$models[] = sanitize_text_field( $model['id'] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $models ) ) {
|
||||
return new WP_Error( 'groq_ai_empty_response', __( 'Geen modeldata ontvangen.', 'groq-ai-product-text' ) );
|
||||
}
|
||||
|
||||
return $models;
|
||||
}
|
||||
|
||||
public function generate_content( array $args ) {
|
||||
$settings = isset( $args['settings'] ) ? (array) $args['settings'] : [];
|
||||
$prompt = isset( $args['prompt'] ) ? $args['prompt'] : '';
|
||||
$system_prompt = isset( $args['system_prompt'] ) ? $args['system_prompt'] : '';
|
||||
$model = ! empty( $args['model'] ) ? $args['model'] : $this->get_default_model();
|
||||
$api_key = $this->get_api_key( $settings );
|
||||
|
||||
if ( empty( $api_key ) ) {
|
||||
return new WP_Error( 'groq_ai_missing_api_key', sprintf( __( 'Stel eerst de API-sleutel voor %s in.', 'groq-ai-product-text' ), $this->get_label() ) );
|
||||
}
|
||||
|
||||
$messages = [
|
||||
[
|
||||
'role' => 'system',
|
||||
'content' => $system_prompt,
|
||||
],
|
||||
[
|
||||
'role' => 'user',
|
||||
'content' => $prompt,
|
||||
],
|
||||
];
|
||||
|
||||
$request_body = [
|
||||
'model' => $model,
|
||||
'messages' => $messages,
|
||||
'temperature' => isset( $args['temperature'] ) ? (float) $args['temperature'] : 0.7,
|
||||
'max_tokens' => 1024,
|
||||
];
|
||||
|
||||
if ( ! empty( $args['response_format'] ) ) {
|
||||
$request_body['response_format'] = $args['response_format'];
|
||||
}
|
||||
|
||||
$response = wp_remote_post(
|
||||
$this->get_endpoint(),
|
||||
[
|
||||
'headers' => [
|
||||
'Authorization' => 'Bearer ' . $api_key,
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
'body' => wp_json_encode( $request_body ),
|
||||
'timeout' => isset( $args['timeout'] ) ? (int) $args['timeout'] : 60,
|
||||
]
|
||||
);
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$body = json_decode( wp_remote_retrieve_body( $response ), true );
|
||||
|
||||
if ( isset( $body['error']['message'] ) ) {
|
||||
return new WP_Error( 'groq_ai_provider_error', (string) $body['error']['message'] );
|
||||
}
|
||||
|
||||
if ( empty( $body['choices'][0]['message']['content'] ) ) {
|
||||
return new WP_Error(
|
||||
'groq_ai_empty_response',
|
||||
sprintf( __( 'Geen antwoord ontvangen van %s.', 'groq-ai-product-text' ), $this->get_label() )
|
||||
);
|
||||
}
|
||||
|
||||
$content = trim( $body['choices'][0]['message']['content'] );
|
||||
$usage = isset( $body['usage'] ) && is_array( $body['usage'] ) ? $body['usage'] : [];
|
||||
|
||||
return [
|
||||
'content' => $content,
|
||||
'usage' => $usage,
|
||||
'raw_response' => $body,
|
||||
];
|
||||
}
|
||||
|
||||
abstract protected function get_endpoint();
|
||||
|
||||
abstract protected function get_models_endpoint();
|
||||
|
||||
protected function get_api_key( $settings ) {
|
||||
$field = $this->get_option_key();
|
||||
return isset( $settings[ $field ] ) ? $settings[ $field ] : '';
|
||||
}
|
||||
}
|
||||
158
includes/Providers/class-groq-ai-provider-google.php
Normal file
158
includes/Providers/class-groq-ai-provider-google.php
Normal file
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
|
||||
class Groq_AI_Provider_Google implements Groq_AI_Provider_Interface {
|
||||
public function get_key() {
|
||||
return 'google';
|
||||
}
|
||||
|
||||
public function get_label() {
|
||||
return __( 'Google AI (Gemini)', 'groq-ai-product-text' );
|
||||
}
|
||||
|
||||
public function get_default_model() {
|
||||
return 'gemini-1.5-flash';
|
||||
}
|
||||
|
||||
public function get_available_models() {
|
||||
return [
|
||||
'gemini-1.5-flash',
|
||||
'gemini-1.5-pro',
|
||||
'gemini-pro',
|
||||
];
|
||||
}
|
||||
|
||||
public function get_option_key() {
|
||||
return 'google_api_key';
|
||||
}
|
||||
|
||||
public function supports_live_models() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function supports_response_format() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function fetch_live_models( $api_key ) {
|
||||
$endpoint = add_query_arg(
|
||||
[ 'key' => $api_key, 'pageSize' => 100 ],
|
||||
'https://generativelanguage.googleapis.com/v1beta/models'
|
||||
);
|
||||
|
||||
$response = wp_remote_get(
|
||||
$endpoint,
|
||||
[
|
||||
'timeout' => 20,
|
||||
]
|
||||
);
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$body = json_decode( wp_remote_retrieve_body( $response ), true );
|
||||
|
||||
if ( isset( $body['error']['message'] ) ) {
|
||||
return new WP_Error( 'groq_ai_provider_error', (string) $body['error']['message'] );
|
||||
}
|
||||
|
||||
if ( empty( $body['models'] ) || ! is_array( $body['models'] ) ) {
|
||||
return new WP_Error( 'groq_ai_empty_response', __( 'Geen modeldata ontvangen.', 'groq-ai-product-text' ) );
|
||||
}
|
||||
|
||||
$models = [];
|
||||
foreach ( $body['models'] as $model ) {
|
||||
if ( ! empty( $model['name'] ) ) {
|
||||
$parts = explode( '/', $model['name'] );
|
||||
$models[] = sanitize_text_field( end( $parts ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $models ) ) {
|
||||
return new WP_Error( 'groq_ai_empty_response', __( 'Geen modeldata ontvangen.', 'groq-ai-product-text' ) );
|
||||
}
|
||||
|
||||
return $models;
|
||||
}
|
||||
|
||||
public function generate_content( array $args ) {
|
||||
$settings = isset( $args['settings'] ) ? (array) $args['settings'] : [];
|
||||
$prompt = isset( $args['prompt'] ) ? $args['prompt'] : '';
|
||||
$system_prompt = isset( $args['system_prompt'] ) ? $args['system_prompt'] : '';
|
||||
$model = ! empty( $args['model'] ) ? $args['model'] : $this->get_default_model();
|
||||
$api_key = isset( $settings[ $this->get_option_key() ] ) ? $settings[ $this->get_option_key() ] : '';
|
||||
|
||||
if ( empty( $api_key ) ) {
|
||||
return new WP_Error( 'groq_ai_missing_api_key', sprintf( __( 'Stel eerst de API-sleutel voor %s in.', 'groq-ai-product-text' ), $this->get_label() ) );
|
||||
}
|
||||
|
||||
$endpoint = add_query_arg(
|
||||
'key',
|
||||
$api_key,
|
||||
sprintf( 'https://generativelanguage.googleapis.com/v1beta/models/%s:generateContent', rawurlencode( $model ) )
|
||||
);
|
||||
|
||||
$payload = [
|
||||
'contents' => [
|
||||
[
|
||||
'role' => 'user',
|
||||
'parts' => [
|
||||
[
|
||||
'text' => $system_prompt . "\n\n" . $prompt,
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
'generationConfig' => [
|
||||
'temperature' => isset( $args['temperature'] ) ? (float) $args['temperature'] : 0.7,
|
||||
'maxOutputTokens' => 1024,
|
||||
],
|
||||
];
|
||||
|
||||
$response = wp_remote_post(
|
||||
$endpoint,
|
||||
[
|
||||
'headers' => [
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
'body' => wp_json_encode( $payload ),
|
||||
'timeout' => isset( $args['timeout'] ) ? (int) $args['timeout'] : 60,
|
||||
]
|
||||
);
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$body = json_decode( wp_remote_retrieve_body( $response ), true );
|
||||
|
||||
if ( isset( $body['error']['message'] ) ) {
|
||||
return new WP_Error( 'groq_ai_provider_error', (string) $body['error']['message'] );
|
||||
}
|
||||
|
||||
if ( empty( $body['candidates'][0]['content']['parts'] ) ) {
|
||||
return new WP_Error(
|
||||
'groq_ai_empty_response',
|
||||
sprintf( __( 'Geen antwoord ontvangen van %s.', 'groq-ai-product-text' ), $this->get_label() )
|
||||
);
|
||||
}
|
||||
|
||||
$parts = $body['candidates'][0]['content']['parts'];
|
||||
$texts = [];
|
||||
|
||||
foreach ( $parts as $part ) {
|
||||
if ( isset( $part['text'] ) ) {
|
||||
$texts[] = $part['text'];
|
||||
}
|
||||
}
|
||||
|
||||
$content = trim( implode( "\n\n", array_filter( $texts ) ) );
|
||||
$usage = isset( $body['usageMetadata'] ) && is_array( $body['usageMetadata'] ) ? $body['usageMetadata'] : [];
|
||||
|
||||
return [
|
||||
'content' => $content,
|
||||
'usage' => $usage,
|
||||
'raw_response' => $body,
|
||||
];
|
||||
}
|
||||
}
|
||||
36
includes/Providers/class-groq-ai-provider-groq.php
Normal file
36
includes/Providers/class-groq-ai-provider-groq.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
class Groq_AI_Provider_Groq extends Groq_AI_Abstract_OpenAI_Provider {
|
||||
public function get_key() {
|
||||
return 'groq';
|
||||
}
|
||||
|
||||
public function get_label() {
|
||||
return __( 'Groq', 'groq-ai-product-text' );
|
||||
}
|
||||
|
||||
public function get_default_model() {
|
||||
return 'llama3-70b-8192';
|
||||
}
|
||||
|
||||
public function get_available_models() {
|
||||
return [
|
||||
'llama3-70b-8192',
|
||||
'llama3-8b-8192',
|
||||
'mixtral-8x7b-32768',
|
||||
'gemma-7b-it',
|
||||
];
|
||||
}
|
||||
|
||||
public function get_option_key() {
|
||||
return 'groq_api_key';
|
||||
}
|
||||
|
||||
protected function get_endpoint() {
|
||||
return 'https://api.groq.com/openai/v1/chat/completions';
|
||||
}
|
||||
|
||||
protected function get_models_endpoint() {
|
||||
return 'https://api.groq.com/openai/v1/models';
|
||||
}
|
||||
}
|
||||
24
includes/Providers/class-groq-ai-provider-manager.php
Normal file
24
includes/Providers/class-groq-ai-provider-manager.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
class Groq_AI_Provider_Manager {
|
||||
/** @var Groq_AI_Provider_Interface[] */
|
||||
private $providers = [];
|
||||
|
||||
public function __construct() {
|
||||
$this->register_provider( new Groq_AI_Provider_Groq() );
|
||||
$this->register_provider( new Groq_AI_Provider_OpenAI() );
|
||||
$this->register_provider( new Groq_AI_Provider_Google() );
|
||||
}
|
||||
|
||||
public function register_provider( Groq_AI_Provider_Interface $provider ) {
|
||||
$this->providers[ $provider->get_key() ] = $provider;
|
||||
}
|
||||
|
||||
public function get_providers() {
|
||||
return $this->providers;
|
||||
}
|
||||
|
||||
public function get_provider( $key ) {
|
||||
return isset( $this->providers[ $key ] ) ? $this->providers[ $key ] : null;
|
||||
}
|
||||
}
|
||||
36
includes/Providers/class-groq-ai-provider-openai.php
Normal file
36
includes/Providers/class-groq-ai-provider-openai.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
class Groq_AI_Provider_OpenAI extends Groq_AI_Abstract_OpenAI_Provider {
|
||||
public function get_key() {
|
||||
return 'openai';
|
||||
}
|
||||
|
||||
public function get_label() {
|
||||
return __( 'OpenAI', 'groq-ai-product-text' );
|
||||
}
|
||||
|
||||
public function get_default_model() {
|
||||
return 'gpt-4o-mini';
|
||||
}
|
||||
|
||||
public function get_available_models() {
|
||||
return [
|
||||
'gpt-4o',
|
||||
'gpt-4o-mini',
|
||||
'gpt-4.1-mini',
|
||||
'gpt-3.5-turbo',
|
||||
];
|
||||
}
|
||||
|
||||
public function get_option_key() {
|
||||
return 'openai_api_key';
|
||||
}
|
||||
|
||||
protected function get_endpoint() {
|
||||
return 'https://api.openai.com/v1/chat/completions';
|
||||
}
|
||||
|
||||
protected function get_models_endpoint() {
|
||||
return 'https://api.openai.com/v1/models';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user