Major refactoring cleanup: - Add new controller architecture (class-controller-*.php) - Add new settings-v2 UI (views/settings-v2/) - Add new CSS architecture (agentic-sidebar.css, tokens) - Add esbuild build pipeline (scripts/build.js, package.json) - Add composer dependencies (vendor/) - Add frontend src directory (assets/js/src/index.jsx) - Add documentation files - Remove old/obsolete files (class-settings.php, old CSS) This commits all pending changes from previous refactoring efforts.
352 lines
14 KiB
PHP
352 lines
14 KiB
PHP
<?php
|
|
/**
|
|
* Settings V2: Models.
|
|
*
|
|
* @package WP_Agentic_Writer
|
|
*/
|
|
if (!defined("ABSPATH")) {
|
|
exit();
|
|
}
|
|
$task_labels = [
|
|
"chat" => __("Chat", "wp-agentic-writer"),
|
|
"clarity" => __("Clarity", "wp-agentic-writer"),
|
|
"planning" => __("Planning", "wp-agentic-writer"),
|
|
"writing" => __("Writing", "wp-agentic-writer"),
|
|
"refinement" => __("Refinement", "wp-agentic-writer"),
|
|
"image" => __("Image", "wp-agentic-writer"),
|
|
];
|
|
$model_values = compact(
|
|
"chat_model",
|
|
"clarity_model",
|
|
"planning_model",
|
|
"writing_model",
|
|
"refinement_model",
|
|
"image_model",
|
|
);
|
|
?>
|
|
<div class="section-head"><div><p class="eyebrow"><?php esc_html_e(
|
|
"OpenRouter Connection",
|
|
"wp-agentic-writer",
|
|
); ?></p><h2><?php esc_html_e(
|
|
"OpenRouter",
|
|
"wp-agentic-writer",
|
|
); ?></h2><p><?php esc_html_e(
|
|
"Choose presets, assign models by task, and manage web search features.",
|
|
"wp-agentic-writer",
|
|
); ?></p></div><button type="button" class="btn" id="wpaw-refresh-models"><?php esc_html_e(
|
|
"Refresh models",
|
|
"wp-agentic-writer",
|
|
); ?></button></div>
|
|
|
|
<div class="subtab-nav" role="tablist">
|
|
<button type="button" class="subtab-btn" role="tab" aria-selected="true" data-aw2-subtab-target="or-connection">Connection</button>
|
|
<button type="button" class="subtab-btn" role="tab" aria-selected="false" data-aw2-subtab-target="or-models">Models</button>
|
|
</div>
|
|
|
|
<!-- =======================
|
|
TAB: CONNECTION
|
|
======================= -->
|
|
<div class="subtab-panel active" id="or-connection">
|
|
<div class="panel">
|
|
<div class="panel-head">
|
|
<div class="panel-title"><h3><?php esc_html_e(
|
|
"API configuration",
|
|
"wp-agentic-writer",
|
|
); ?></h3><p><?php esc_html_e(
|
|
"OpenRouter powers cloud model access.",
|
|
"wp-agentic-writer",
|
|
); ?></p></div>
|
|
<button type="button" class="btn btn-small" id="wpaw-test-api-key"><?php esc_html_e(
|
|
"Test connection",
|
|
"wp-agentic-writer",
|
|
); ?></button>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div class="field">
|
|
<label for="openrouter_api_key"><?php esc_html_e(
|
|
"OpenRouter API key",
|
|
"wp-agentic-writer",
|
|
); ?></label>
|
|
<div class="password-row">
|
|
<input class="field-control" type="password" id="openrouter_api_key" name="wp_agentic_writer_settings[openrouter_api_key]" value="<?php echo esc_attr(
|
|
$api_key,
|
|
); ?>" placeholder="sk-or-v1-...">
|
|
<button type="button" class="btn" data-aw2-toggle-password="#openrouter_api_key"><?php esc_html_e(
|
|
"Show",
|
|
"wp-agentic-writer",
|
|
); ?></button>
|
|
</div>
|
|
<p class="help"><?php esc_html_e(
|
|
"Stored in WordPress options. Used for model, image, and OpenRouter search requests.",
|
|
"wp-agentic-writer",
|
|
); ?></p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel">
|
|
<div class="panel-head"><div class="panel-title"><h3><?php esc_html_e(
|
|
"Budget & cost tracking",
|
|
"wp-agentic-writer",
|
|
); ?></h3><p><?php esc_html_e(
|
|
"Track monthly usage and prevent surprise spend.",
|
|
"wp-agentic-writer",
|
|
); ?></p></div><span class="status <?php echo esc_attr(
|
|
"danger" === $budget_status
|
|
? "error"
|
|
: ("warning" === $budget_status
|
|
? "warn"
|
|
: "connected"),
|
|
); ?>"><?php echo esc_html(
|
|
number_format_i18n($budget_percent, 1),
|
|
); ?>%</span></div>
|
|
<div class="panel-body">
|
|
<div class="grid-3">
|
|
<div class="metric-card"><div class="metric-value">$<?php echo esc_html(
|
|
number_format_i18n($monthly_used, 2),
|
|
); ?></div><div class="metric-label"><?php esc_html_e(
|
|
"Used this month",
|
|
"wp-agentic-writer",
|
|
); ?></div></div>
|
|
<div class="metric-card"><div class="metric-value">$<?php echo esc_html(
|
|
number_format_i18n($monthly_budget, 2),
|
|
); ?></div><div class="metric-label"><?php esc_html_e(
|
|
"Monthly budget",
|
|
"wp-agentic-writer",
|
|
); ?></div></div>
|
|
<div class="metric-card"><div class="metric-value"><?php echo esc_html(
|
|
number_format_i18n($budget_percent, 1),
|
|
); ?>%</div><div class="progress"><span style="width: <?php echo esc_attr(
|
|
min(100, $budget_percent),
|
|
); ?>%"></span></div><div class="metric-label"><?php esc_html_e(
|
|
"Budget usage",
|
|
"wp-agentic-writer",
|
|
); ?></div></div>
|
|
</div>
|
|
<div class="budget-controls grid-2" style="margin-top:16px">
|
|
<div class="field">
|
|
<label for="monthly_budget"><?php esc_html_e(
|
|
"Monthly budget (USD)",
|
|
"wp-agentic-writer",
|
|
); ?></label>
|
|
<input class="field-control" type="number" min="0" step="0.01" id="monthly_budget" name="wp_agentic_writer_settings[monthly_budget]" value="<?php echo esc_attr(
|
|
$monthly_budget,
|
|
); ?>">
|
|
</div>
|
|
<div class="field">
|
|
<label><?php esc_html_e("Enable cost tracking", "wp-agentic-writer"); ?></label>
|
|
<label class="switch-row" style="margin-top:4px"><input type="checkbox" name="wp_agentic_writer_settings[cost_tracking_enabled]" value="1" <?php checked(
|
|
$cost_tracking_enabled,
|
|
); ?>><span class="switch"></span><span><?php esc_html_e(
|
|
"Show usage estimates in the editor sidebar.",
|
|
"wp-agentic-writer",
|
|
); ?></span></label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel"><div class="panel-head"><div class="panel-title"><h3><?php esc_html_e(
|
|
"OpenRouter provider routing",
|
|
"wp-agentic-writer",
|
|
); ?></h3><p><?php esc_html_e(
|
|
"Optional BYOK/provider controls.",
|
|
"wp-agentic-writer",
|
|
); ?></p></div></div><div class="panel-body">
|
|
<label class="switch-row"><input type="checkbox" id="openrouter_provider_routing_enabled" name="wp_agentic_writer_settings[openrouter_provider_routing_enabled]" value="1" <?php checked(
|
|
$openrouter_provider_routing_enabled,
|
|
); ?> data-aw2-toggle-panel="#wpaw2-provider-routing-fields"><span class="switch"></span><span><?php esc_html_e(
|
|
"Enable provider routing",
|
|
"wp-agentic-writer",
|
|
); ?></span></label>
|
|
<div id="wpaw2-provider-routing-fields" class="provider-routing-fields" <?php echo $openrouter_provider_routing_enabled
|
|
? ""
|
|
: "hidden"; ?>>
|
|
<div class="field-label-row"><span><?php esc_html_e(
|
|
"Provider slug",
|
|
"wp-agentic-writer",
|
|
); ?></span><span class="help"><?php esc_html_e(
|
|
"Applies to the slug input and provider routing behavior below.",
|
|
"wp-agentic-writer",
|
|
); ?></span></div>
|
|
<div class="grid-3 provider-routing-grid"><div class="field"><input class="field-control" type="text" aria-label="<?php esc_attr_e(
|
|
"Provider slug",
|
|
"wp-agentic-writer",
|
|
); ?>" name="wp_agentic_writer_settings[openrouter_provider_slug]" value="<?php echo esc_attr(
|
|
$openrouter_provider_slug,
|
|
); ?>" placeholder="openai"></div><label class="switch-row"><input type="checkbox" name="wp_agentic_writer_settings[openrouter_provider_only]" value="1" <?php checked(
|
|
$openrouter_provider_only,
|
|
); ?>><span class="switch"></span><span><?php esc_html_e(
|
|
"Only provider",
|
|
"wp-agentic-writer",
|
|
); ?></span></label><label class="switch-row"><input type="checkbox" name="wp_agentic_writer_settings[openrouter_allow_provider_fallbacks]" value="1" <?php checked(
|
|
$openrouter_allow_provider_fallbacks,
|
|
); ?>><span class="switch"></span><span><?php esc_html_e(
|
|
"Allow fallback",
|
|
"wp-agentic-writer",
|
|
); ?></span></label></div>
|
|
</div>
|
|
</div></div>
|
|
</div>
|
|
|
|
<!-- =======================
|
|
TAB: MODELS
|
|
======================= -->
|
|
<div class="subtab-panel" id="or-models">
|
|
<div class="panel"><div class="panel-head"><div class="panel-title"><h3><?php esc_html_e(
|
|
"Quick presets",
|
|
"wp-agentic-writer",
|
|
); ?></h3><p><?php esc_html_e(
|
|
"Apply common model combinations.",
|
|
"wp-agentic-writer",
|
|
); ?></p></div></div><div class="panel-body grid-3">
|
|
|
|
<button type="button" class="preset-card" data-aw2-preset="budget">
|
|
<span class="preset-tier-label"><?php esc_html_e(
|
|
"Budget",
|
|
"wp-agentic-writer",
|
|
); ?></span>
|
|
<span class="preset-price">$0<span class="preset-price-cents">.06</span></span>
|
|
<span class="preset-price-unit"><?php esc_html_e(
|
|
"per article",
|
|
"wp-agentic-writer",
|
|
); ?></span>
|
|
<span class="preset-divider"></span>
|
|
<span class="preset-models">
|
|
<span class="preset-model-row"><span class="preset-model-dot" style="background:#4285f4"></span><span class="preset-model-name">Gemini 2.5 Flash</span><span class="preset-model-role"><?php esc_html_e(
|
|
"Chat · Plan · Clarity",
|
|
"wp-agentic-writer",
|
|
); ?></span></span>
|
|
<span class="preset-model-row"><span class="preset-model-dot" style="background:#ff7000"></span><span class="preset-model-name">Mistral Small</span><span class="preset-model-role"><?php esc_html_e(
|
|
"Writing",
|
|
"wp-agentic-writer",
|
|
); ?></span></span>
|
|
<span class="preset-model-row"><span class="preset-model-dot" style="background:#10a37f"></span><span class="preset-model-name">GPT-4o</span><span class="preset-model-role"><?php esc_html_e(
|
|
"Image",
|
|
"wp-agentic-writer",
|
|
); ?></span></span>
|
|
</span>
|
|
</button>
|
|
|
|
<button type="button" class="preset-card active" data-aw2-preset="balanced">
|
|
<span class="preset-tier-label"><?php esc_html_e(
|
|
"Balanced",
|
|
"wp-agentic-writer",
|
|
); ?> <span class="preset-badge"><?php esc_html_e(
|
|
"Recommended",
|
|
"wp-agentic-writer",
|
|
); ?></span></span>
|
|
<span class="preset-price">$0<span class="preset-price-cents">.14</span></span>
|
|
<span class="preset-price-unit"><?php esc_html_e(
|
|
"per article",
|
|
"wp-agentic-writer",
|
|
); ?></span>
|
|
<span class="preset-divider"></span>
|
|
<span class="preset-models">
|
|
<span class="preset-model-row"><span class="preset-model-dot" style="background:#4285f4"></span><span class="preset-model-name">Gemini 2.5 Flash</span><span class="preset-model-role"><?php esc_html_e(
|
|
"Chat · Plan · Clarity",
|
|
"wp-agentic-writer",
|
|
); ?></span></span>
|
|
<span class="preset-model-row"><span class="preset-model-dot" style="background:#d97757"></span><span class="preset-model-name">Claude Sonnet 4</span><span class="preset-model-role"><?php esc_html_e(
|
|
"Writing · Refinement",
|
|
"wp-agentic-writer",
|
|
); ?></span></span>
|
|
<span class="preset-model-row"><span class="preset-model-dot" style="background:#10a37f"></span><span class="preset-model-name">GPT-4o</span><span class="preset-model-role"><?php esc_html_e(
|
|
"Image",
|
|
"wp-agentic-writer",
|
|
); ?></span></span>
|
|
</span>
|
|
</button>
|
|
|
|
<button type="button" class="preset-card" data-aw2-preset="premium">
|
|
<span class="preset-tier-label"><?php esc_html_e(
|
|
"Premium",
|
|
"wp-agentic-writer",
|
|
); ?></span>
|
|
<span class="preset-price">$0<span class="preset-price-cents">.31</span></span>
|
|
<span class="preset-price-unit"><?php esc_html_e(
|
|
"per article",
|
|
"wp-agentic-writer",
|
|
); ?></span>
|
|
<span class="preset-divider"></span>
|
|
<span class="preset-models">
|
|
<span class="preset-model-row"><span class="preset-model-dot" style="background:#4285f4"></span><span class="preset-model-name">Gemini 3 Flash</span><span class="preset-model-role"><?php esc_html_e(
|
|
"Chat · Plan",
|
|
"wp-agentic-writer",
|
|
); ?></span></span>
|
|
<span class="preset-model-row"><span class="preset-model-dot" style="background:#d97757"></span><span class="preset-model-name">Claude Sonnet 4</span><span class="preset-model-role"><?php esc_html_e(
|
|
"Clarity",
|
|
"wp-agentic-writer",
|
|
); ?></span></span>
|
|
<span class="preset-model-row"><span class="preset-model-dot" style="background:#10a37f"></span><span class="preset-model-name">GPT-4.1</span><span class="preset-model-role"><?php esc_html_e(
|
|
"Writing · Refinement",
|
|
"wp-agentic-writer",
|
|
); ?></span></span>
|
|
<span class="preset-model-row"><span class="preset-model-dot" style="background:#10a37f"></span><span class="preset-model-name">GPT-4o</span><span class="preset-model-role"><?php esc_html_e(
|
|
"Image",
|
|
"wp-agentic-writer",
|
|
); ?></span></span>
|
|
</span>
|
|
</button>
|
|
|
|
</div></div>
|
|
<div class="panel"><div class="panel-head"><div class="panel-title"><h3><?php esc_html_e(
|
|
"Task model assignments",
|
|
"wp-agentic-writer",
|
|
); ?></h3><p><?php esc_html_e(
|
|
"Each workflow stage can use a specialized model.",
|
|
"wp-agentic-writer",
|
|
); ?></p></div><span class="status connected" id="wpaw2-cost-estimate">~$0.14</span></div><div class="panel-body grid-2">
|
|
<?php foreach ($task_labels as $task_key => $task_label):
|
|
$field =
|
|
"writing" === $task_key ? "writing_model" : $task_key . "_model"; ?>
|
|
<div class="field"><label for="<?php echo esc_attr(
|
|
$field,
|
|
); ?>"><?php echo esc_html(
|
|
$task_label,
|
|
); ?></label><select class="field-control wpaw2-model-select" id="<?php echo esc_attr(
|
|
$field,
|
|
); ?>" name="wp_agentic_writer_settings[<?php echo esc_attr(
|
|
$field,
|
|
); ?>]"><option value="<?php echo esc_attr(
|
|
$model_values[$field] ?? "",
|
|
); ?>"><?php echo esc_html(
|
|
$model_values[$field] ?? "",
|
|
); ?></option></select><p class="help"><?php echo esc_html(
|
|
ucfirst($task_key),
|
|
); ?> <?php esc_html_e("stage model.", "wp-agentic-writer"); ?></p></div>
|
|
<?php
|
|
endforeach; ?>
|
|
</div></div>
|
|
<div class="panel"><div class="panel-head"><div class="panel-title"><h3><?php esc_html_e(
|
|
"Custom models",
|
|
"wp-agentic-writer",
|
|
); ?></h3><p><?php esc_html_e(
|
|
"Add exact model IDs not returned by the API.",
|
|
"wp-agentic-writer",
|
|
); ?></p></div><button type="button" class="btn btn-small" id="wpaw2-add-custom-model"><?php esc_html_e(
|
|
"Add model",
|
|
"wp-agentic-writer",
|
|
); ?></button></div><div class="panel-body" id="wpaw2-custom-models">
|
|
<?php foreach ((array) $custom_models as $custom_model): ?>
|
|
<div class="custom-row"><input class="field-control" type="text" value="<?php echo esc_attr(
|
|
$custom_model["id"] ?? "",
|
|
); ?>" placeholder="provider/model-id"><input class="field-control" type="text" value="<?php echo esc_attr(
|
|
$custom_model["name"] ?? "",
|
|
); ?>" placeholder="Display name"><select class="field-control"><option value="text" <?php selected(
|
|
$custom_model["type"] ?? "text",
|
|
"text",
|
|
); ?>>Text</option><option value="image" <?php selected(
|
|
$custom_model["type"] ?? "text",
|
|
"image",
|
|
); ?>>Image</option></select><button type="button" class="btn btn-danger btn-small" data-remove><?php esc_html_e(
|
|
"Remove",
|
|
"wp-agentic-writer",
|
|
); ?></button></div>
|
|
<?php endforeach; ?>
|
|
</div></div>
|
|
|
|
</div>
|
|
|
|
|