feat: Add Google safety settings and enhance logging for AI generation events

This commit is contained in:
2026-01-31 14:00:59 +00:00
parent 5ddd3f8104
commit 051db0febc
8 changed files with 516 additions and 55 deletions

View File

@@ -217,6 +217,9 @@ class Groq_AI_Product_Text_Settings_Page {
$google_connected_email = isset( $settings['google_oauth_connected_email'] ) ? (string) $settings['google_oauth_connected_email'] : '';
$google_connected_at = isset( $settings['google_oauth_connected_at'] ) ? absint( $settings['google_oauth_connected_at'] ) : 0;
$oauth_redirect = add_query_arg( 'action', 'groq_ai_google_oauth_callback', admin_url( 'admin-post.php' ) );
$google_safety_settings = $this->plugin->get_google_safety_settings( $settings );
$google_safety_categories = $this->plugin->get_google_safety_categories();
$google_safety_thresholds = $this->plugin->get_google_safety_thresholds();
?>
<div class="wrap">
@@ -281,6 +284,30 @@ class Groq_AI_Product_Text_Settings_Page {
<td>
<input type="password" id="groq-ai-api-<?php echo esc_attr( $provider_key ); ?>" class="regular-text" name="<?php echo esc_attr( $option_key ); ?>[<?php echo esc_attr( $option_field ); ?>]" value="<?php echo esc_attr( $value ); ?>" autocomplete="off" />
<p class="description"><?php printf( esc_html__( 'Voer de API-sleutel in voor %s.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), esc_html( $provider->get_label() ) ); ?></p>
<?php if ( 'google' === $provider_key && ! empty( $google_safety_categories ) ) : ?>
<div class="groq-ai-google-safety-settings" style="margin-top:16px; padding:16px; border:1px solid #dcdcde; background:#f6f7f7;">
<strong><?php esc_html_e( 'Gemini safety filters', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></strong>
<p class="description" style="margin-top:4px;"><?php esc_html_e( 'Kies optioneel welke beleidscategorieën je zelf instelt. Laat op "Google standaard" om geen safetySettings mee te sturen.', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></p>
<?php foreach ( $google_safety_categories as $category_key => $info ) :
$category_label = isset( $info['label'] ) ? $info['label'] : $category_key;
$category_description = isset( $info['description'] ) ? $info['description'] : '';
$selected_threshold = isset( $google_safety_settings[ $category_key ] ) ? $google_safety_settings[ $category_key ] : '';
$field_id = 'groq-ai-google-safety-' . sanitize_html_class( $category_key );
?>
<label for="<?php echo esc_attr( $field_id ); ?>" style="display:block; margin:12px 0 4px;">
<span style="display:block; margin-bottom:4px;"><strong><?php echo esc_html( $category_label ); ?></strong></span>
<select id="<?php echo esc_attr( $field_id ); ?>" name="<?php echo esc_attr( $option_key ); ?>[google_safety_settings][<?php echo esc_attr( $category_key ); ?>]" style="max-width:280px;">
<?php foreach ( $google_safety_thresholds as $threshold_key => $threshold_label ) : ?>
<option value="<?php echo esc_attr( $threshold_key ); ?>" <?php selected( $selected_threshold, $threshold_key ); ?>><?php echo esc_html( $threshold_label ); ?></option>
<?php endforeach; ?>
</select>
<?php if ( '' !== $category_description ) : ?>
<p class="description" style="margin:4px 0 0;"><?php echo esc_html( $category_description ); ?></p>
<?php endif; ?>
</label>
<?php endforeach; ?>
</div>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
@@ -892,6 +919,34 @@ class Groq_AI_Product_Text_Settings_Page {
<h2><?php esc_html_e( 'AI-respons', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></h2>
<pre style="background:#f9f9f9;border:1px solid #dcdcde;padding:12px;white-space:pre-wrap;"><?php echo esc_html( $log['response'] ); ?></pre>
<?php
$request_params = [];
if ( ! empty( $log['request_json'] ) ) {
$request_params = json_decode( $log['request_json'], true );
$request_params = is_array( $request_params ) ? $request_params : [];
}
if ( ! empty( $request_params ) ) :
$request_pretty = wp_json_encode( $request_params, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES );
$request_pretty = $request_pretty ? $request_pretty : wp_json_encode( $request_params );
?>
<h2><?php esc_html_e( 'Request parameters', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></h2>
<pre style="background:#fff;border:1px solid #dcdcde;padding:12px;white-space:pre-wrap;"><?php echo esc_html( $request_pretty ); ?></pre>
<?php endif; ?>
<?php
$usage_meta = [];
if ( ! empty( $log['usage_json'] ) ) {
$usage_meta = json_decode( $log['usage_json'], true );
$usage_meta = is_array( $usage_meta ) ? $usage_meta : [];
}
if ( ! empty( $usage_meta ) ) :
$usage_pretty = wp_json_encode( $usage_meta, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES );
$usage_pretty = $usage_pretty ? $usage_pretty : wp_json_encode( $usage_meta );
?>
<h2><?php esc_html_e( 'Usage metadata', GROQ_AI_PRODUCT_TEXT_DOMAIN ); ?></h2>
<pre style="background:#f6f7f7;border:1px solid #dcdcde;padding:12px;white-space:pre-wrap;"><?php echo esc_html( $usage_pretty ); ?></pre>
<?php endif; ?>
<?php endif; ?>
</div>
<?php

View File

@@ -198,7 +198,26 @@ class Groq_AI_Ajax_Controller {
$final_prompt = $prompt_builder->append_response_instructions( $prompt_with_context, $settings );
}
$request_parameters = $this->build_request_parameters_snapshot(
$settings,
[
'provider' => $provider_key,
'conversation_id' => $conversation_id,
'temperature' => 0.7,
'response_format_mode' => $use_response_format ? 'structured' : 'prompt',
'response_format_definition' => $response_format,
'term_context' => [
'term_id' => $term_id,
'taxonomy' => $taxonomy,
],
'term_options' => $usage_meta['term_options'],
'origin' => $origin,
'google_safety_settings' => isset( $settings['google_safety_settings'] ) ? $settings['google_safety_settings'] : [],
]
);
$model = $this->plugin->get_selected_model( $provider, $settings );
$request_parameters['model'] = $model;
$result = $provider->generate_content(
[
'prompt' => $final_prompt,
@@ -212,20 +231,21 @@ class Groq_AI_Ajax_Controller {
);
if ( is_wp_error( $result ) ) {
if ( $logger ) {
$logger->log_generation_event(
[
'provider' => $provider_key,
'model' => $model,
'prompt' => $final_prompt,
'response' => '',
'usage' => $usage_meta,
'status' => 'error',
'error_message' => $result->get_error_message(),
'post_id' => 0,
]
);
}
if ( $logger ) {
$logger->log_generation_event(
[
'provider' => $provider_key,
'model' => $model,
'prompt' => $final_prompt,
'response' => '',
'usage' => $usage_meta,
'status' => 'error',
'error_message' => $result->get_error_message(),
'post_id' => 0,
'parameters' => $request_parameters,
]
);
}
return $result;
}
@@ -241,20 +261,21 @@ class Groq_AI_Ajax_Controller {
$parsed = $prompt_builder->parse_term_structured_response( $response_text, $settings );
}
if ( is_wp_error( $parsed ) ) {
if ( $logger ) {
$logger->log_generation_event(
[
'provider' => $provider_key,
'model' => $model,
'prompt' => $final_prompt,
'response' => $response_text,
'usage' => $response_usage,
'status' => 'error',
'error_message' => $parsed->get_error_message(),
'post_id' => 0,
]
);
}
if ( $logger ) {
$logger->log_generation_event(
[
'provider' => $provider_key,
'model' => $model,
'prompt' => $final_prompt,
'response' => $response_text,
'usage' => $response_usage,
'status' => 'error',
'error_message' => $parsed->get_error_message(),
'post_id' => 0,
'parameters' => $request_parameters,
]
);
}
return $parsed;
}
if ( ! is_array( $parsed ) ) {
@@ -263,19 +284,20 @@ class Groq_AI_Ajax_Controller {
];
}
if ( $logger ) {
$logger->log_generation_event(
[
'provider' => $provider_key,
'model' => $model,
'prompt' => $final_prompt,
'response' => $response_text,
'usage' => $response_usage,
'status' => 'success',
'post_id' => 0,
]
);
}
if ( $logger ) {
$logger->log_generation_event(
[
'provider' => $provider_key,
'model' => $model,
'prompt' => $final_prompt,
'response' => $response_text,
'usage' => $response_usage,
'status' => 'success',
'post_id' => 0,
'parameters' => $request_parameters,
]
);
}
return [
'top_description' => isset( $parsed['top_description'] ) ? $parsed['top_description'] : ( isset( $parsed['description'] ) ? $parsed['description'] : '' ),
@@ -492,6 +514,23 @@ class Groq_AI_Ajax_Controller {
$final_prompt = $prompt_builder->append_response_instructions( $prompt_with_context, $settings );
}
$request_parameters = $this->build_request_parameters_snapshot(
$settings,
[
'provider' => $provider_key,
'model' => $model,
'post_id' => $post_id,
'conversation_id' => $conversation_id,
'temperature' => 0.7,
'response_format_mode' => $use_response_format ? 'structured' : 'prompt',
'response_format_definition' => $response_format,
'context_fields' => $context_fields,
'attribute_includes' => isset( $settings['product_attribute_includes'] ) ? $settings['product_attribute_includes'] : [],
'image_context' => $image_context_meta,
'google_safety_settings' => isset( $settings['google_safety_settings'] ) ? $settings['google_safety_settings'] : [],
]
);
$result = $provider->generate_content(
[
'prompt' => $final_prompt,
@@ -518,6 +557,7 @@ class Groq_AI_Ajax_Controller {
'post_id' => $post_id,
'status' => 'error',
'error_message' => $result->get_error_message(),
'parameters' => $request_parameters,
]
);
wp_send_json_error( [ 'message' => $result->get_error_message() ], 500 );
@@ -543,6 +583,7 @@ class Groq_AI_Ajax_Controller {
'post_id' => $post_id,
'status' => 'error',
'error_message' => $response->get_error_message(),
'parameters' => $request_parameters,
]
);
wp_send_json_error( [ 'message' => $response->get_error_message() ], 500 );
@@ -557,6 +598,7 @@ class Groq_AI_Ajax_Controller {
'usage' => $response_usage,
'post_id' => $post_id,
'status' => 'success',
'parameters' => $request_parameters,
]
);
@@ -607,4 +649,16 @@ class Groq_AI_Ajax_Controller {
return (string) $result;
}
private function build_request_parameters_snapshot( $settings, array $additional = [] ) {
$snapshot = [
'settings' => $this->plugin->get_loggable_settings_snapshot( $settings ),
];
foreach ( $additional as $key => $value ) {
$snapshot[ $key ] = $value;
}
return $snapshot;
}
}

View File

@@ -30,7 +30,7 @@ class Groq_AI_Provider_Google implements Groq_AI_Provider_Interface {
}
public function supports_response_format() {
return false;
return true;
}
public function supports_image_context() {
@@ -153,6 +153,18 @@ class Groq_AI_Provider_Google implements Groq_AI_Provider_Interface {
}
$max_tokens = max( 128, min( 8192, $max_tokens ) );
$generation_config = [
'temperature' => isset( $args['temperature'] ) ? (float) $args['temperature'] : 0.7,
'maxOutputTokens' => $max_tokens,
];
$response_format = isset( $args['response_format'] ) ? $args['response_format'] : null;
$schema_payload = $this->prepare_response_schema_payload( $response_format );
if ( ! empty( $schema_payload ) ) {
$generation_config['responseMimeType'] = 'application/json';
$generation_config['responseJsonSchema'] = $schema_payload;
}
$payload = [
'contents' => [
[
@@ -160,12 +172,17 @@ class Groq_AI_Provider_Google implements Groq_AI_Provider_Interface {
'parts' => $parts,
],
],
'generationConfig' => [
'temperature' => isset( $args['temperature'] ) ? (float) $args['temperature'] : 0.7,
'maxOutputTokens' => $max_tokens,
],
'generationConfig' => $generation_config,
];
$safety_settings_payload = $this->build_safety_settings_payload(
isset( $settings['google_safety_settings'] ) ? $settings['google_safety_settings'] : []
);
if ( ! empty( $safety_settings_payload ) ) {
$payload['safetySettings'] = $safety_settings_payload;
}
$response = wp_remote_post(
$endpoint,
[
@@ -204,7 +221,11 @@ class Groq_AI_Provider_Google implements Groq_AI_Provider_Interface {
}
$content = trim( implode( "\n\n", array_filter( $texts ) ) );
$usage = isset( $body['usageMetadata'] ) && is_array( $body['usageMetadata'] ) ? $body['usageMetadata'] : [];
$usage_metadata = isset( $body['usageMetadata'] ) && is_array( $body['usageMetadata'] ) ? $body['usageMetadata'] : [];
$usage = $usage_metadata;
if ( ! empty( $usage_metadata ) ) {
$usage = array_merge( $usage, $this->map_usage_metadata_counts( $usage_metadata ) );
}
$finish_reason = isset( $body['candidates'][0]['finishReason'] ) ? sanitize_text_field( (string) $body['candidates'][0]['finishReason'] ) : '';
if ( '' !== $finish_reason ) {
$usage['finish_reason'] = $finish_reason;
@@ -216,4 +237,112 @@ class Groq_AI_Provider_Google implements Groq_AI_Provider_Interface {
'raw_response' => $body,
];
}
private function build_safety_settings_payload( $settings ) {
if ( empty( $settings ) || ! is_array( $settings ) ) {
return [];
}
$categories = class_exists( 'Groq_AI_Settings_Manager' ) ? array_keys( Groq_AI_Settings_Manager::get_google_safety_categories_list() ) : [];
$thresholds = class_exists( 'Groq_AI_Settings_Manager' ) ? array_keys( Groq_AI_Settings_Manager::get_google_safety_thresholds_list() ) : [];
if ( empty( $categories ) || empty( $thresholds ) ) {
return [];
}
$payload = [];
foreach ( $settings as $category => $threshold ) {
$category = sanitize_text_field( (string) $category );
$threshold = sanitize_text_field( (string) $threshold );
if ( ! in_array( $category, $categories, true ) || ! in_array( $threshold, $thresholds, true ) ) {
continue;
}
$payload[] = [
'category' => $category,
'threshold' => $threshold,
];
}
return $payload;
}
private function prepare_response_schema_payload( $response_format ) {
if ( empty( $response_format ) || ! is_array( $response_format ) ) {
return [];
}
if ( isset( $response_format['type'] ) && 'json_schema' === $response_format['type'] ) {
if ( isset( $response_format['json_schema']['schema'] ) && is_array( $response_format['json_schema']['schema'] ) ) {
return $this->sanitize_schema_definition( $response_format['json_schema']['schema'] );
}
if ( isset( $response_format['schema'] ) && is_array( $response_format['schema'] ) ) {
return $this->sanitize_schema_definition( $response_format['schema'] );
}
}
return [];
}
private function sanitize_schema_definition( $schema ) {
if ( ! is_array( $schema ) ) {
return [];
}
$encoded = wp_json_encode( $schema );
if ( ! $encoded ) {
return [];
}
$decoded = json_decode( $encoded, true );
if ( ! is_array( $decoded ) ) {
return [];
}
$this->remove_disallowed_schema_keys( $decoded );
return $decoded;
}
private function remove_disallowed_schema_keys( array &$schema ) {
$disallowed = [ 'additionalProperties' ];
foreach ( $schema as $key => &$value ) {
if ( in_array( $key, $disallowed, true ) ) {
unset( $schema[ $key ] );
continue;
}
if ( is_array( $value ) ) {
$this->remove_disallowed_schema_keys( $value );
}
}
unset( $value );
}
private function map_usage_metadata_counts( $metadata ) {
if ( ! is_array( $metadata ) ) {
return [];
}
$mapped = [];
if ( isset( $metadata['promptTokenCount'] ) ) {
$mapped['prompt_tokens'] = absint( $metadata['promptTokenCount'] );
}
if ( isset( $metadata['candidatesTokenCount'] ) ) {
$mapped['completion_tokens'] = absint( $metadata['candidatesTokenCount'] );
}
if ( isset( $metadata['totalTokenCount'] ) ) {
$mapped['total_tokens'] = absint( $metadata['totalTokenCount'] );
}
return $mapped;
}
}

View File

@@ -26,9 +26,32 @@ class Groq_AI_Generation_Logger {
$table = $this->get_logs_table_name();
$usage = isset( $args['usage'] ) && is_array( $args['usage'] ) ? $args['usage'] : [];
$prompt_tokens = isset( $usage['prompt_tokens'] ) ? absint( $usage['prompt_tokens'] ) : null;
$completion_tokens = isset( $usage['completion_tokens'] ) ? absint( $usage['completion_tokens'] ) : null;
$total_tokens = isset( $usage['total_tokens'] ) ? absint( $usage['total_tokens'] ) : null;
$parameters = isset( $args['parameters'] ) && is_array( $args['parameters'] ) ? $args['parameters'] : [];
$prompt_tokens = $this->extract_usage_token_value(
$usage,
[
'prompt_tokens',
'promptTokenCount',
'input_tokens',
'inputTokenCount',
]
);
$completion_tokens = $this->extract_usage_token_value(
$usage,
[
'completion_tokens',
'output_tokens',
'candidatesTokenCount',
'outputTokenCount',
]
);
$total_tokens = $this->extract_usage_token_value(
$usage,
[
'total_tokens',
'totalTokenCount',
]
);
$wpdb->insert(
$table,
@@ -46,6 +69,7 @@ class Groq_AI_Generation_Logger {
'status' => isset( $args['status'] ) ? sanitize_text_field( $args['status'] ) : 'success',
'error_message' => isset( $args['error_message'] ) ? $args['error_message'] : '',
'usage_json' => ! empty( $usage ) ? wp_json_encode( $usage ) : null,
'request_json' => ! empty( $parameters ) ? wp_json_encode( $parameters ) : null,
]
);
}
@@ -77,6 +101,7 @@ class Groq_AI_Generation_Logger {
public function maybe_create_table() {
if ( get_option( self::OPTION_TABLE_CREATED ) ) {
$this->logs_table_exists = true;
$this->maybe_upgrade_table_schema();
return;
}
@@ -106,6 +131,7 @@ class Groq_AI_Generation_Logger {
status varchar(20) NOT NULL,
error_message text DEFAULT NULL,
usage_json longtext DEFAULT NULL,
request_json longtext DEFAULT NULL,
PRIMARY KEY (id),
KEY provider (provider),
KEY post_id (post_id)
@@ -117,6 +143,26 @@ class Groq_AI_Generation_Logger {
update_option( self::OPTION_TABLE_CREATED, 1 );
}
private function extract_usage_token_value( $usage, $keys ) {
foreach ( (array) $keys as $key ) {
if ( isset( $usage[ $key ] ) ) {
return absint( $usage[ $key ] );
}
}
return null;
}
private function maybe_upgrade_table_schema() {
global $wpdb;
$table = $this->get_logs_table_name();
$column = $wpdb->get_var( $wpdb->prepare( "SHOW COLUMNS FROM {$table} LIKE %s", 'request_json' ) );
if ( ! $column ) {
$this->create_table();
}
}
private function get_logs_table_name() {
global $wpdb;

View File

@@ -47,6 +47,7 @@ class Groq_AI_Settings_Manager {
'google_enable_ga' => true,
'google_gsc_site_url' => '',
'google_ga4_property_id' => '',
'google_safety_settings' => [],
'context_fields' => $this->get_default_context_fields(),
'modules' => $this->get_default_modules_settings(),
'image_context_mode' => 'url',
@@ -60,6 +61,7 @@ class Groq_AI_Settings_Manager {
$settings = wp_parse_args( (array) $settings, $defaults );
$settings['context_fields'] = $this->normalize_context_fields( isset( $settings['context_fields'] ) ? $settings['context_fields'] : [] );
$settings['modules'] = $this->sanitize_modules_settings( isset( $settings['modules'] ) ? $settings['modules'] : [] );
$settings['google_safety_settings'] = $this->sanitize_google_safety_settings( isset( $settings['google_safety_settings'] ) ? $settings['google_safety_settings'] : [] );
$settings['model'] = Groq_AI_Model_Exclusions::ensure_allowed( $settings['provider'], isset( $settings['model'] ) ? $settings['model'] : '' );
$image_mode = isset( $settings['image_context_mode'] ) ? sanitize_text_field( $settings['image_context_mode'] ) : 'url';
@@ -120,6 +122,7 @@ class Groq_AI_Settings_Manager {
'google_enable_ga' => true,
'google_gsc_site_url' => '',
'google_ga4_property_id' => '',
'google_safety_settings' => [],
'context_fields' => $this->get_default_context_fields(),
'modules' => $this->get_default_modules_settings(),
'image_context_mode' => 'url',
@@ -193,6 +196,7 @@ class Groq_AI_Settings_Manager {
'google_enable_ga' => ! empty( $raw_input['google_enable_ga'] ),
'google_gsc_site_url' => esc_url_raw( (string) $input['google_gsc_site_url'] ),
'google_ga4_property_id' => sanitize_text_field( (string) $input['google_ga4_property_id'] ),
'google_safety_settings' => $this->sanitize_google_safety_settings( isset( $raw_input['google_safety_settings'] ) ? $raw_input['google_safety_settings'] : [] ),
'response_format_compat' => ! empty( $raw_input['response_format_compat'] ),
'image_context_mode' => $image_mode,
'image_context_limit' => $image_limit,
@@ -422,6 +426,94 @@ class Groq_AI_Settings_Manager {
return $this->sanitize_term_description_char_limit_value( $value, 1200 );
}
public function get_google_safety_settings( $settings = null ) {
if ( null === $settings ) {
$settings = $this->all();
}
return $this->sanitize_google_safety_settings( isset( $settings['google_safety_settings'] ) ? $settings['google_safety_settings'] : [] );
}
public function get_google_safety_categories() {
return self::get_google_safety_categories_list();
}
public function get_google_safety_thresholds() {
return self::get_google_safety_thresholds_list();
}
public function get_loggable_settings_snapshot( $settings = null ) {
if ( null === $settings ) {
$settings = $this->all();
}
$allowed_keys = [
'store_context',
'default_prompt',
'max_output_tokens',
'product_attribute_includes',
'context_fields',
'modules',
'image_context_mode',
'image_context_limit',
'response_format_compat',
'term_top_description_char_limit',
'term_bottom_description_char_limit',
'term_bottom_description_meta_key',
'google_safety_settings',
'google_enable_gsc',
'google_enable_ga',
'google_gsc_site_url',
'google_ga4_property_id',
];
$snapshot = [];
foreach ( $allowed_keys as $key ) {
if ( array_key_exists( $key, $settings ) ) {
$snapshot[ $key ] = $settings[ $key ];
}
}
return $snapshot;
}
public static function get_google_safety_categories_list() {
return [
'HARM_CATEGORY_HARASSMENT' => [
'label' => __( 'Harassment & intimidatie', GROQ_AI_PRODUCT_TEXT_DOMAIN ),
'description' => __( 'Detecteert bedreigingen en pesterijen in de output.', GROQ_AI_PRODUCT_TEXT_DOMAIN ),
],
'HARM_CATEGORY_HATE_SPEECH' => [
'label' => __( 'Haatspraak', GROQ_AI_PRODUCT_TEXT_DOMAIN ),
'description' => __( 'Beperkt discriminerende of denigrerende taal.', GROQ_AI_PRODUCT_TEXT_DOMAIN ),
],
'HARM_CATEGORY_SEXUALLY_EXPLICIT' => [
'label' => __( 'Seksueel expliciet', GROQ_AI_PRODUCT_TEXT_DOMAIN ),
'description' => __( 'Filtert beschrijvingen van seksuele handelingen of fetish-content.', GROQ_AI_PRODUCT_TEXT_DOMAIN ),
],
'HARM_CATEGORY_DANGEROUS_CONTENT' => [
'label' => __( 'Gevaarlijke activiteiten', GROQ_AI_PRODUCT_TEXT_DOMAIN ),
'description' => __( 'Voorkomt instructies rond geweld, wapens of gevaarlijke middelen.', GROQ_AI_PRODUCT_TEXT_DOMAIN ),
],
'HARM_CATEGORY_CIVIC_INTEGRITY' => [
'label' => __( 'Civieke integriteit', GROQ_AI_PRODUCT_TEXT_DOMAIN ),
'description' => __( 'Vermindert desinformatie rond verkiezingen en burgerprocessen.', GROQ_AI_PRODUCT_TEXT_DOMAIN ),
],
];
}
public static function get_google_safety_thresholds_list() {
return [
'' => __( 'Google standaard (niet meesturen)', GROQ_AI_PRODUCT_TEXT_DOMAIN ),
'HARM_BLOCK_THRESHOLD_UNSPECIFIED' => __( 'Onbekende drempel (laat Google beslissen)', GROQ_AI_PRODUCT_TEXT_DOMAIN ),
'BLOCK_LOW_AND_ABOVE' => __( 'Blokkeer lage ernst en hoger', GROQ_AI_PRODUCT_TEXT_DOMAIN ),
'BLOCK_MEDIUM_AND_ABOVE' => __( 'Blokkeer middel en hoger', GROQ_AI_PRODUCT_TEXT_DOMAIN ),
'BLOCK_ONLY_HIGH' => __( 'Blokkeer alleen hoge ernst', GROQ_AI_PRODUCT_TEXT_DOMAIN ),
'BLOCK_NONE' => __( 'Sta alles toe (geen blokkade)', GROQ_AI_PRODUCT_TEXT_DOMAIN ),
];
}
public function is_response_format_compat_enabled( $settings = null ) {
if ( null === $settings ) {
$settings = $this->all();
@@ -505,4 +597,27 @@ class Groq_AI_Settings_Manager {
return min( 10, $limit );
}
private function sanitize_google_safety_settings( $settings ) {
if ( ! is_array( $settings ) ) {
return [];
}
$categories = array_keys( self::get_google_safety_categories_list() );
$thresholds = array_keys( self::get_google_safety_thresholds_list() );
$clean = [];
foreach ( $settings as $category => $threshold ) {
$category = sanitize_text_field( (string) $category );
$threshold = sanitize_text_field( (string) $threshold );
if ( '' === $threshold || ! in_array( $category, $categories, true ) || ! in_array( $threshold, $thresholds, true ) ) {
continue;
}
$clean[ $category ] = $threshold;
}
return $clean;
}
}