feat: Add connection test caching and reasoning content support
Backend improvements: - Add cache auto-clear on settings save (class-settings-v2.php) - Hooks updated_option action - Clears connection test transients when local backend settings change - Add reasoning_content streaming support (class-local-backend-provider.php) - Handles thinking models like Claude extended thinking - Captures chunk['choices'][0]['delta']['reasoning_content'] Documentation: - Add FRONTEND_AND_CHAT_FIX_SUMMARY.md with all fixes - Add FRONTEND-REFACTOR-PHASE2.md with modularization plan Note: Splitting effort deferred - will continue iterating on monolith Next: Fix session history not appearing bug
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
/**
|
||||
* Settings Page V2
|
||||
*
|
||||
* Refactored settings page with Bootstrap design and separated view files.
|
||||
* Refactored settings page with Agentic design tokens and separated view files.
|
||||
*
|
||||
* @package WP_Agentic_Writer
|
||||
*/
|
||||
@@ -75,6 +75,93 @@ class WP_Agentic_Writer_Settings_V2
|
||||
"ajax_test_local_backend",
|
||||
]);
|
||||
add_action("wp_ajax_wpaw_test_memanto", [$this, "ajax_test_memanto"]);
|
||||
|
||||
// Clear connection test cache when local backend settings change
|
||||
add_action(
|
||||
"updated_option",
|
||||
[$this, "clear_local_backend_cache_on_settings_change"],
|
||||
10,
|
||||
3,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the local backend connection test cache when relevant settings change.
|
||||
*
|
||||
* This ensures that after a user updates their local backend URL, API key,
|
||||
* or model settings, the cached "connection test" result is invalidated
|
||||
* so the next chat request will re-test the connection.
|
||||
*
|
||||
* @since 0.2.0
|
||||
* @param string $option Option name that was updated.
|
||||
* @param mixed $old_value Old option value.
|
||||
* @param mixed $new_value New option value.
|
||||
*/
|
||||
public function clear_local_backend_cache_on_settings_change(
|
||||
$option,
|
||||
$old_value,
|
||||
$new_value,
|
||||
) {
|
||||
// Only handle our settings option
|
||||
if ("wp_agentic_writer_settings" !== $option) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if any local backend-related setting changed
|
||||
$local_backend_keys = [
|
||||
"local_backend_url",
|
||||
"local_backend_key",
|
||||
"local_backend_image_url",
|
||||
"local_backend_image_key",
|
||||
"local_backend_model",
|
||||
"local_backend_models",
|
||||
"local_backend_enabled",
|
||||
"local_backend_image_enabled",
|
||||
];
|
||||
|
||||
$old_value = is_array($old_value) ? $old_value : [];
|
||||
$new_value = is_array($new_value) ? $new_value : [];
|
||||
|
||||
foreach ($local_backend_keys as $key) {
|
||||
$old = $old_value[$key] ?? null;
|
||||
$new = $new_value[$key] ?? null;
|
||||
|
||||
// Check if the value changed (handle both array and scalar comparisons)
|
||||
if ($old !== $new) {
|
||||
// Arrays need special comparison
|
||||
if (is_array($old) && is_array($new)) {
|
||||
if (serialize($old) !== serialize($new)) {
|
||||
$this->do_clear_local_backend_cache();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
$this->do_clear_local_backend_cache();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually clear the cache and log the action.
|
||||
*
|
||||
* @since 0.2.0
|
||||
*/
|
||||
private function do_clear_local_backend_cache()
|
||||
{
|
||||
if (!class_exists("WP_Agentic_Writer_Provider_Manager")) {
|
||||
return;
|
||||
}
|
||||
|
||||
$count = WP_Agentic_Writer_Provider_Manager::clear_connection_test_cache();
|
||||
|
||||
if (defined("WP_DEBUG") && WP_DEBUG) {
|
||||
error_log(
|
||||
"WPAW Settings: Local backend settings changed. Cleared " .
|
||||
$count .
|
||||
" connection test cache entries.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,115 +176,36 @@ class WP_Agentic_Writer_Settings_V2
|
||||
return;
|
||||
}
|
||||
|
||||
// Bootstrap 5.3
|
||||
$settings_css_path =
|
||||
WP_AGENTIC_WRITER_DIR . "views/settings-v2/style.css";
|
||||
wp_enqueue_style(
|
||||
"bootstrap",
|
||||
"https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css",
|
||||
"wpaw-settings-v2-stitch",
|
||||
WP_AGENTIC_WRITER_URL . "views/settings-v2/style.css",
|
||||
[],
|
||||
"5.3.3",
|
||||
);
|
||||
wp_enqueue_style(
|
||||
"bootstrap-icons",
|
||||
"https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css",
|
||||
[],
|
||||
"1.11.1",
|
||||
);
|
||||
wp_enqueue_script(
|
||||
"bootstrap",
|
||||
"https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js",
|
||||
[],
|
||||
"5.3.3",
|
||||
true,
|
||||
file_exists($settings_css_path)
|
||||
? filemtime($settings_css_path)
|
||||
: WP_AGENTIC_WRITER_VERSION,
|
||||
);
|
||||
|
||||
// Select2 for searchable dropdowns
|
||||
wp_enqueue_style(
|
||||
"select2",
|
||||
"https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css",
|
||||
"wpaw-select2",
|
||||
WP_AGENTIC_WRITER_URL . "assets/vendor/select2/select2.min.css",
|
||||
[],
|
||||
"4.1.0",
|
||||
);
|
||||
wp_enqueue_style(
|
||||
"select2-bootstrap-5",
|
||||
"https://cdn.jsdelivr.net/npm/select2-bootstrap-5-theme@1.3.0/dist/select2-bootstrap-5-theme.min.css",
|
||||
["select2", "bootstrap"],
|
||||
"1.3.0",
|
||||
"4.1.0-rc.0",
|
||||
);
|
||||
|
||||
wp_enqueue_script(
|
||||
"select2",
|
||||
"https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js",
|
||||
"wpaw-select2",
|
||||
WP_AGENTIC_WRITER_URL . "assets/vendor/select2/select2.min.js",
|
||||
["jquery"],
|
||||
"4.1.0",
|
||||
"4.1.0-rc.0",
|
||||
true,
|
||||
);
|
||||
|
||||
// Agentic Vibe CSS - Design System (in order)
|
||||
wp_enqueue_style(
|
||||
"wpaw-agentic-variables",
|
||||
WP_AGENTIC_WRITER_URL . "assets/css/agentic-variables.css",
|
||||
[],
|
||||
WP_AGENTIC_WRITER_VERSION,
|
||||
);
|
||||
wp_enqueue_style(
|
||||
"wpaw-agentic-bootstrap-custom",
|
||||
WP_AGENTIC_WRITER_URL . "assets/css/agentic-bootstrap-custom.css",
|
||||
["bootstrap", "wpaw-agentic-variables"],
|
||||
WP_AGENTIC_WRITER_VERSION,
|
||||
);
|
||||
wp_enqueue_style(
|
||||
"wpaw-agentic-components",
|
||||
WP_AGENTIC_WRITER_URL . "assets/css/agentic-components.css",
|
||||
["wpaw-agentic-variables"],
|
||||
WP_AGENTIC_WRITER_VERSION,
|
||||
);
|
||||
wp_enqueue_style(
|
||||
"wpaw-agentic-workflow",
|
||||
WP_AGENTIC_WRITER_URL . "assets/css/agentic-workflow.css",
|
||||
["wpaw-agentic-components"],
|
||||
WP_AGENTIC_WRITER_VERSION,
|
||||
);
|
||||
|
||||
// Legacy plugin styles
|
||||
$css_admin_path = WP_AGENTIC_WRITER_DIR . "assets/css/admin-v2.css";
|
||||
$css_settings_path =
|
||||
WP_AGENTIC_WRITER_DIR . "assets/css/settings-v2.css";
|
||||
$css_log_path =
|
||||
WP_AGENTIC_WRITER_DIR . "assets/css/cost-log-grouped.css";
|
||||
|
||||
$ver_admin = file_exists($css_admin_path)
|
||||
? filemtime($css_admin_path)
|
||||
: WP_AGENTIC_WRITER_VERSION;
|
||||
$ver_settings = file_exists($css_settings_path)
|
||||
? filemtime($css_settings_path)
|
||||
: WP_AGENTIC_WRITER_VERSION;
|
||||
$ver_log = file_exists($css_log_path)
|
||||
? filemtime($css_log_path)
|
||||
: WP_AGENTIC_WRITER_VERSION;
|
||||
|
||||
wp_enqueue_style(
|
||||
"wp-agentic-writer-admin-v2",
|
||||
WP_AGENTIC_WRITER_URL . "assets/css/admin-v2.css",
|
||||
["bootstrap", "select2-bootstrap-5"],
|
||||
$ver_admin,
|
||||
);
|
||||
wp_enqueue_style(
|
||||
"wp-agentic-writer-settings-v2",
|
||||
WP_AGENTIC_WRITER_URL . "assets/css/settings-v2.css",
|
||||
["wpaw-agentic-components"],
|
||||
$ver_settings,
|
||||
);
|
||||
wp_enqueue_style(
|
||||
"wp-agentic-writer-cost-log-grouped",
|
||||
WP_AGENTIC_WRITER_URL . "assets/css/cost-log-grouped.css",
|
||||
["wp-agentic-writer-settings-v2"],
|
||||
$ver_log,
|
||||
);
|
||||
|
||||
// Plugin scripts
|
||||
wp_enqueue_script(
|
||||
"wp-agentic-writer-settings-v2",
|
||||
WP_AGENTIC_WRITER_URL . "assets/js/settings-v2.js",
|
||||
["jquery", "bootstrap", "select2"],
|
||||
WP_AGENTIC_WRITER_URL . "assets/js/settings-v2-stitch.js",
|
||||
["jquery", "wpaw-select2"],
|
||||
WP_AGENTIC_WRITER_VERSION,
|
||||
true,
|
||||
);
|
||||
@@ -282,8 +290,8 @@ class WP_Agentic_Writer_Settings_V2
|
||||
"chat" => "google/gemini-2.5-flash",
|
||||
"clarity" => "google/gemini-2.5-flash",
|
||||
"planning" => "google/gemini-2.5-flash",
|
||||
"writing" => "anthropic/claude-3.5-sonnet",
|
||||
"refinement" => "anthropic/claude-3.5-sonnet",
|
||||
"writing" => "anthropic/claude-sonnet-4",
|
||||
"refinement" => "anthropic/claude-sonnet-4",
|
||||
"image" => "openai/gpt-4o",
|
||||
],
|
||||
"premium" => [
|
||||
@@ -704,7 +712,17 @@ class WP_Agentic_Writer_Settings_V2
|
||||
wp_send_json_error(["message" => "Permission denied"]);
|
||||
}
|
||||
|
||||
$provider = WP_Agentic_Writer_OpenRouter_Provider::get_instance();
|
||||
$settings = get_option("wp_agentic_writer_settings", []);
|
||||
$posted_api_key = isset($_POST["api_key"])
|
||||
? trim(sanitize_text_field(wp_unslash($_POST["api_key"])))
|
||||
: "";
|
||||
$api_key = !empty($posted_api_key)
|
||||
? $posted_api_key
|
||||
: $settings["openrouter_api_key"] ?? "";
|
||||
|
||||
$provider = !empty($posted_api_key)
|
||||
? WP_Agentic_Writer_OpenRouter_Provider::for_api_key($api_key)
|
||||
: WP_Agentic_Writer_OpenRouter_Provider::get_instance();
|
||||
$models = $provider->fetch_and_cache_models(true);
|
||||
|
||||
if (is_wp_error($models)) {
|
||||
@@ -1025,6 +1043,58 @@ class WP_Agentic_Writer_Settings_V2
|
||||
...$post_ids,
|
||||
);
|
||||
$detail_rows = $wpdb->get_results($details_sql, ARRAY_A);
|
||||
|
||||
$image_variants_table = $wpdb->prefix . "wpaw_images_variants";
|
||||
$image_variants_table_exists =
|
||||
$wpdb->get_var("SHOW TABLES LIKE '{$image_variants_table}'") ===
|
||||
$image_variants_table;
|
||||
if ($image_variants_table_exists) {
|
||||
// Find posts that already have image_generation in wpaw_cost_tracking
|
||||
// to avoid duplicates from the variants table.
|
||||
$posts_with_tracked_images = [];
|
||||
foreach ($detail_rows as $existing) {
|
||||
if (($existing["action"] ?? "") === "image_generation") {
|
||||
$posts_with_tracked_images[
|
||||
(int) ($existing["post_id"] ?? 0)
|
||||
] = true;
|
||||
}
|
||||
}
|
||||
$variant_post_ids = array_filter($post_ids, function (
|
||||
$pid,
|
||||
) use ($posts_with_tracked_images) {
|
||||
return empty($posts_with_tracked_images[(int) $pid]);
|
||||
});
|
||||
if (!empty($variant_post_ids)) {
|
||||
$variant_placeholders = implode(
|
||||
",",
|
||||
array_fill(0, count($variant_post_ids), "%d"),
|
||||
);
|
||||
$image_details_sql = $wpdb->prepare(
|
||||
"SELECT post_id, created_at, image_model_used AS model, cost
|
||||
FROM {$image_variants_table}
|
||||
WHERE post_id IN ({$variant_placeholders}) AND cost IS NOT NULL AND cost > 0
|
||||
ORDER BY created_at DESC",
|
||||
...$variant_post_ids,
|
||||
);
|
||||
$image_detail_rows = $wpdb->get_results(
|
||||
$image_details_sql,
|
||||
ARRAY_A,
|
||||
);
|
||||
foreach ($image_detail_rows as $image_detail_row) {
|
||||
$detail_rows[] = [
|
||||
"post_id" =>
|
||||
(int) ($image_detail_row["post_id"] ?? 0),
|
||||
"created_at" =>
|
||||
$image_detail_row["created_at"] ?? "",
|
||||
"model" => $image_detail_row["model"] ?? "",
|
||||
"action" => "image_generation",
|
||||
"input_tokens" => 0,
|
||||
"output_tokens" => 0,
|
||||
"cost" => $image_detail_row["cost"] ?? 0,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
$detail_map = [];
|
||||
foreach ($detail_rows as $detail_row) {
|
||||
$pid = (int) ($detail_row["post_id"] ?? 0);
|
||||
@@ -1221,7 +1291,7 @@ class WP_Agentic_Writer_Settings_V2
|
||||
// Check for specific models
|
||||
$check_models = [
|
||||
"deepseek/deepseek-chat-v3-0324",
|
||||
"anthropic/claude-3.5-sonnet",
|
||||
"anthropic/claude-sonnet-4",
|
||||
];
|
||||
$found_models = [];
|
||||
$missing_models = [];
|
||||
@@ -1278,7 +1348,12 @@ class WP_Agentic_Writer_Settings_V2
|
||||
}
|
||||
|
||||
$settings = get_option("wp_agentic_writer_settings", []);
|
||||
$api_key = $settings["openrouter_api_key"] ?? "";
|
||||
$posted_api_key = isset($_POST["api_key"])
|
||||
? trim(sanitize_text_field(wp_unslash($_POST["api_key"])))
|
||||
: "";
|
||||
$api_key = !empty($posted_api_key)
|
||||
? $posted_api_key
|
||||
: $settings["openrouter_api_key"] ?? "";
|
||||
|
||||
if (empty($api_key)) {
|
||||
wp_send_json_error(["message" => "API key is not configured"]);
|
||||
@@ -1394,6 +1469,12 @@ class WP_Agentic_Writer_Settings_V2
|
||||
);
|
||||
}
|
||||
|
||||
if (isset($input["custom_search_url"])) {
|
||||
$sanitized["custom_search_url"] = esc_url_raw(
|
||||
trim($input["custom_search_url"]),
|
||||
);
|
||||
}
|
||||
|
||||
// Sanitize model names (6 models) - using model registry for defaults
|
||||
$sanitized["chat_model"] = sanitize_text_field(
|
||||
$input["chat_model"] ??
|
||||
@@ -1547,14 +1628,29 @@ class WP_Agentic_Writer_Settings_V2
|
||||
isset($input["custom_languages"]) &&
|
||||
is_array($input["custom_languages"])
|
||||
) {
|
||||
$custom_language_values = [];
|
||||
foreach ($input["custom_languages"] as $custom_language_value) {
|
||||
$custom_language_values = array_merge(
|
||||
$custom_language_values,
|
||||
array_map(
|
||||
"trim",
|
||||
explode(",", (string) $custom_language_value),
|
||||
),
|
||||
);
|
||||
}
|
||||
$sanitized["custom_languages"] = array_filter(
|
||||
array_map("sanitize_text_field", $input["custom_languages"]),
|
||||
array_map("sanitize_text_field", $custom_language_values),
|
||||
);
|
||||
} else {
|
||||
$sanitized["custom_languages"] = [];
|
||||
}
|
||||
|
||||
// Sanitize Local Backend settings (Fix for settings wiping out)
|
||||
// Sanitize Global Context
|
||||
$sanitized["global_context"] = isset($input["global_context"])
|
||||
? sanitize_textarea_field(trim($input["global_context"]))
|
||||
: "";
|
||||
|
||||
// Sanitize Custom Endpoint settings (Fix for settings wiping out)
|
||||
if (isset($input["local_backend_url"])) {
|
||||
$sanitized["local_backend_url"] = esc_url_raw(
|
||||
trim($input["local_backend_url"]),
|
||||
@@ -1567,12 +1663,57 @@ class WP_Agentic_Writer_Settings_V2
|
||||
);
|
||||
}
|
||||
|
||||
if (isset($input["local_backend_image_url"])) {
|
||||
$sanitized["local_backend_image_url"] = esc_url_raw(
|
||||
trim($input["local_backend_image_url"]),
|
||||
);
|
||||
}
|
||||
|
||||
if (isset($input["local_backend_image_key"])) {
|
||||
$sanitized["local_backend_image_key"] = sanitize_text_field(
|
||||
trim($input["local_backend_image_key"]),
|
||||
);
|
||||
}
|
||||
|
||||
if (isset($input["local_backend_model"])) {
|
||||
$sanitized["local_backend_model"] = sanitize_text_field(
|
||||
trim($input["local_backend_model"]),
|
||||
);
|
||||
}
|
||||
|
||||
$sanitized["local_backend_enabled"] =
|
||||
isset($input["local_backend_enabled"]) &&
|
||||
"1" === $input["local_backend_enabled"];
|
||||
|
||||
$sanitized["local_backend_image_enabled"] =
|
||||
isset($input["local_backend_image_enabled"]) &&
|
||||
"1" === $input["local_backend_image_enabled"];
|
||||
|
||||
// Per-task model overrides for custom endpoint
|
||||
if (
|
||||
isset($input["local_backend_models"]) &&
|
||||
is_array($input["local_backend_models"])
|
||||
) {
|
||||
$sanitized_models = [];
|
||||
$allowed_model_tasks = [
|
||||
"chat",
|
||||
"clarity",
|
||||
"planning",
|
||||
"writing",
|
||||
"refinement",
|
||||
"image",
|
||||
];
|
||||
foreach ($input["local_backend_models"] as $task => $model_code) {
|
||||
$task = sanitize_text_field($task);
|
||||
if (in_array($task, $allowed_model_tasks, true)) {
|
||||
$sanitized_models[$task] = sanitize_text_field(
|
||||
trim($model_code),
|
||||
);
|
||||
}
|
||||
}
|
||||
$sanitized["local_backend_models"] = $sanitized_models;
|
||||
}
|
||||
|
||||
// Sanitize MEMANTO settings.
|
||||
$sanitized["memanto_enabled"] =
|
||||
isset($input["memanto_enabled"]) &&
|
||||
@@ -1580,14 +1721,44 @@ class WP_Agentic_Writer_Settings_V2
|
||||
$sanitized["memanto_url"] = isset($input["memanto_url"])
|
||||
? esc_url_raw(trim($input["memanto_url"]))
|
||||
: "";
|
||||
$sanitized["memanto_license_key"] = isset($input["memanto_license_key"])
|
||||
? sanitize_text_field(trim($input["memanto_license_key"]))
|
||||
: "";
|
||||
$sanitized["memanto_moorcheh_key"] = isset(
|
||||
$input["memanto_moorcheh_key"],
|
||||
)
|
||||
? sanitize_text_field(trim($input["memanto_moorcheh_key"]))
|
||||
: "";
|
||||
|
||||
// Sanitize Task Providers Routing
|
||||
if (
|
||||
// Sanitize Task Providers Routing.
|
||||
// When custom endpoint is enabled, auto-build task_providers from
|
||||
// the per-task model codes: a non-empty model code ⇒ local_backend.
|
||||
if (!empty($sanitized["local_backend_enabled"])) {
|
||||
$sanitized_providers = [];
|
||||
$lb_models = $sanitized["local_backend_models"] ?? [];
|
||||
$all_tasks = [
|
||||
"chat",
|
||||
"clarity",
|
||||
"planning",
|
||||
"writing",
|
||||
"refinement",
|
||||
"image",
|
||||
];
|
||||
foreach ($all_tasks as $task) {
|
||||
if ($task === "image") {
|
||||
$sanitized_providers[$task] = !empty(
|
||||
$sanitized["local_backend_image_enabled"]
|
||||
)
|
||||
? "local_backend"
|
||||
: "openrouter";
|
||||
} else {
|
||||
$sanitized_providers[$task] = !empty($lb_models[$task])
|
||||
? "local_backend"
|
||||
: "openrouter";
|
||||
}
|
||||
}
|
||||
$sanitized["task_providers"] = $sanitized_providers;
|
||||
} elseif (
|
||||
isset($input["task_providers"]) &&
|
||||
is_array($input["task_providers"])
|
||||
) {
|
||||
@@ -1607,12 +1778,7 @@ class WP_Agentic_Writer_Settings_V2
|
||||
$provider = sanitize_text_field($provider);
|
||||
|
||||
if (in_array($task, $allowed_tasks, true)) {
|
||||
if ("image" === $task && "openrouter" === $provider) {
|
||||
$sanitized_providers[$task] = $provider;
|
||||
} elseif (
|
||||
"image" !== $task &&
|
||||
in_array($provider, $allowed_providers_text, true)
|
||||
) {
|
||||
if (in_array($provider, $allowed_providers_text, true)) {
|
||||
$sanitized_providers[$task] = $provider;
|
||||
}
|
||||
}
|
||||
@@ -1635,8 +1801,8 @@ class WP_Agentic_Writer_Settings_V2
|
||||
// Extract settings for views
|
||||
$view_data = $this->prepare_view_data($settings);
|
||||
|
||||
// Include main layout
|
||||
include WP_AGENTIC_WRITER_DIR . "views/settings/layout.php";
|
||||
// Include Stitch rebuild layout
|
||||
include WP_AGENTIC_WRITER_DIR . "views/settings-v2/layout.php";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1651,6 +1817,7 @@ class WP_Agentic_Writer_Settings_V2
|
||||
// Extract settings (6 models) using model registry for defaults
|
||||
$api_key = $settings["openrouter_api_key"] ?? "";
|
||||
$brave_search_api_key = $settings["brave_search_api_key"] ?? "";
|
||||
$custom_search_url = $settings["custom_search_url"] ?? "";
|
||||
$chat_model =
|
||||
$settings["chat_model"] ??
|
||||
WPAW_Model_Registry::get_default_model("chat");
|
||||
@@ -1698,17 +1865,26 @@ class WP_Agentic_Writer_Settings_V2
|
||||
"Indonesian",
|
||||
];
|
||||
$custom_languages = $settings["custom_languages"] ?? [];
|
||||
$global_context = $settings["global_context"] ?? "";
|
||||
$available_languages = $this->get_available_languages();
|
||||
$custom_models = get_option("wp_agentic_writer_custom_models", []);
|
||||
|
||||
// Local Backend settings
|
||||
// Custom Endpoint settings
|
||||
$local_backend_url = $settings["local_backend_url"] ?? "";
|
||||
$local_backend_key = $settings["local_backend_key"] ?? "dummy";
|
||||
$local_backend_model =
|
||||
$settings["local_backend_model"] ?? "claude-local";
|
||||
$local_backend_key = $settings["local_backend_key"] ?? "";
|
||||
$local_backend_image_url = $settings["local_backend_image_url"] ?? "";
|
||||
$local_backend_image_key = $settings["local_backend_image_key"] ?? "";
|
||||
$local_backend_model = $settings["local_backend_model"] ?? "";
|
||||
$local_backend_enabled = !empty($settings["local_backend_enabled"]);
|
||||
$local_backend_image_enabled = !empty(
|
||||
$settings["local_backend_image_enabled"]
|
||||
);
|
||||
$local_backend_models = $settings["local_backend_models"] ?? [];
|
||||
|
||||
// MEMANTO settings
|
||||
$memanto_enabled = $settings["memanto_enabled"] ?? false;
|
||||
$memanto_url = $settings["memanto_url"] ?? "";
|
||||
$memanto_license_key = $settings["memanto_license_key"] ?? "";
|
||||
$memanto_moorcheh_key = $settings["memanto_moorcheh_key"] ?? "";
|
||||
$task_providers = $settings["task_providers"] ?? [];
|
||||
$allow_openrouter_fallback = !empty(
|
||||
@@ -1741,6 +1917,7 @@ class WP_Agentic_Writer_Settings_V2
|
||||
return compact(
|
||||
"api_key",
|
||||
"brave_search_api_key",
|
||||
"custom_search_url",
|
||||
"chat_model",
|
||||
"clarity_model",
|
||||
"planning_model",
|
||||
@@ -1759,13 +1936,20 @@ class WP_Agentic_Writer_Settings_V2
|
||||
"required_context_categories",
|
||||
"preferred_languages",
|
||||
"custom_languages",
|
||||
"global_context",
|
||||
"available_languages",
|
||||
"custom_models",
|
||||
"monthly_used",
|
||||
"budget_percent",
|
||||
"budget_status",
|
||||
"local_backend_url",
|
||||
"local_backend_key",
|
||||
"local_backend_image_url",
|
||||
"local_backend_image_key",
|
||||
"local_backend_model",
|
||||
"local_backend_enabled",
|
||||
"local_backend_image_enabled",
|
||||
"local_backend_models",
|
||||
"task_providers",
|
||||
"allow_openrouter_fallback",
|
||||
"openrouter_provider_routing_enabled",
|
||||
@@ -1774,6 +1958,7 @@ class WP_Agentic_Writer_Settings_V2
|
||||
"openrouter_allow_provider_fallbacks",
|
||||
"memanto_enabled",
|
||||
"memanto_url",
|
||||
"memanto_license_key",
|
||||
"memanto_moorcheh_key",
|
||||
"settings",
|
||||
);
|
||||
@@ -1822,26 +2007,37 @@ class WP_Agentic_Writer_Settings_V2
|
||||
*/
|
||||
public function ajax_test_local_backend()
|
||||
{
|
||||
check_ajax_referer("wpaw_test_local_backend", "nonce");
|
||||
check_ajax_referer("wpaw_settings", "nonce");
|
||||
|
||||
if (!current_user_can("manage_options")) {
|
||||
wp_send_json_error(["message" => "Insufficient permissions"]);
|
||||
}
|
||||
|
||||
$url = sanitize_text_field(wp_unslash($_POST["url"] ?? ""));
|
||||
$key = sanitize_text_field(wp_unslash($_POST["key"] ?? ""));
|
||||
$model = sanitize_text_field(wp_unslash($_POST["model"] ?? ""));
|
||||
|
||||
if (empty($url)) {
|
||||
wp_send_json_error(["message" => "URL required"]);
|
||||
}
|
||||
|
||||
// Temporarily create provider with this URL
|
||||
$temp_settings = get_option("wp_agentic_writer_settings", []);
|
||||
// Temporarily create provider with these form values.
|
||||
$original_settings = get_option("wp_agentic_writer_settings", []);
|
||||
$temp_settings = $original_settings;
|
||||
$temp_settings["local_backend_url"] = $url;
|
||||
if ("" !== $key) {
|
||||
$temp_settings["local_backend_key"] = $key;
|
||||
}
|
||||
if ("" !== $model) {
|
||||
$temp_settings["local_backend_model"] = $model;
|
||||
}
|
||||
update_option("wp_agentic_writer_settings", $temp_settings);
|
||||
|
||||
$provider = new WP_Agentic_Writer_Local_Backend_Provider();
|
||||
$result = $provider->test_connection();
|
||||
|
||||
update_option("wp_agentic_writer_settings", $original_settings);
|
||||
|
||||
if (is_wp_error($result)) {
|
||||
wp_send_json_error(["message" => $result->get_error_message()]);
|
||||
}
|
||||
@@ -1875,7 +2071,8 @@ class WP_Agentic_Writer_Settings_V2
|
||||
}
|
||||
|
||||
// Temporarily override settings so the client uses the form values.
|
||||
$temp_settings = get_option("wp_agentic_writer_settings", []);
|
||||
$original_settings = get_option("wp_agentic_writer_settings", []);
|
||||
$temp_settings = $original_settings;
|
||||
$temp_settings["memanto_url"] = esc_url_raw(trim($url));
|
||||
$temp_settings["memanto_moorcheh_key"] = sanitize_text_field(
|
||||
trim($key),
|
||||
@@ -1885,8 +2082,12 @@ class WP_Agentic_Writer_Settings_V2
|
||||
// Clear health cache so the fresh URL/key are used.
|
||||
delete_transient("wpaw_memanto_health");
|
||||
|
||||
$client = WP_Agentic_Writer_Memanto_Client::get_instance();
|
||||
$client = WP_Agentic_Writer_Memanto_Client::for_base_url(
|
||||
esc_url_raw(trim($url)),
|
||||
);
|
||||
$result = $client->check_health_fresh();
|
||||
update_option("wp_agentic_writer_settings", $original_settings);
|
||||
delete_transient("wpaw_memanto_health");
|
||||
|
||||
if ($result["healthy"]) {
|
||||
wp_send_json_success($result);
|
||||
|
||||
Reference in New Issue
Block a user