# WP Agentic Writer — Settings Page Specification > **Purpose:** Complete reference for rebuilding the wp-admin settings page. > **Plugin option key:** `wp_agentic_writer_settings` (single serialized option). > **Active settings class:** `WP_Agentic_Writer_Settings_V2` (`includes/class-settings-v2.php`). > **Settings group (for `settings_fields()`):** `wp_agentic_writer_settings`. > **Form action:** `options.php`. --- ## Table of Contents 1. [Page Layout Overview](#1-page-layout-overview) 2. [Tab: General](#2-tab-general) 3. [Tab: AI Models](#3-tab-ai-models) 4. [Tab: Local Backend](#4-tab-local-backend) 5. [Tab: MEMANTO](#5-tab-memanto) 6. [Tab: OpenRouter Cost Log](#6-tab-openrouter-cost-log) 7. [Tab: Model Guide (Read-Only)](#7-tab-model-guide-read-only) 8. [Global UI Components](#8-global-ui-components) 9. [AJAX Actions Reference](#9-ajax-actions-reference) 10. [Complete Option Key Index](#10-complete-option-key-index) 11. [Sanitization & Validation Rules](#11-sanitization--validation-rules) --- ## 1. Page Layout Overview The settings page uses a **sidebar + content pane** layout (IDE-style split view). ``` ┌──────────────────┬─────────────────────────────────────┐ │ Sidebar Nav │ Content Pane (scrollable) │ │ │ │ │ [Plugin Logo] │ ┌───────────────────────────────┐ │ │ │ │ Writing Pipeline Progress Bar │ │ │ CONFIGURATION │ └───────────────────────────────┘ │ │ ○ General │ │ │ ○ AI Models │ ┌───────────────────────────────┐ │ │ ○ Local Backend │ │ Active Tab Content │ │ │ ○ MEMANTO │ │ │ │ │ │ │ │ │ │ ANALYTICS&DOCS │ └───────────────────────────────┘ │ │ ○ Cost Log │ │ │ ○ Model Guide │ ┌───────────────────────────────┐ │ │ │ │ [Reset] [Save Settings ⌘+S] │ │ │ │ └───────────────────────────────┘ │ └──────────────────┴─────────────────────────────────────┘ ``` - **Framework:** Bootstrap 5 (loaded by the plugin via CDN or bundled) - **Icons:** Bootstrap Icons (`bi-*`) + WordPress Dashicons - **Theme:** Dark theme with accent colors - **Select2:** Used for model selection dropdowns (searchable) - **Sticky save bar** at the bottom with version display, Reset, and Save buttons - **Toast notifications** for save confirmations ### Navigation Tabs | Tab ID | Label | Icon | Section | |--------|-------|------|---------| | `general` | General | `bi-sliders` | Configuration | | `models` | AI Models | `bi-stars` | Configuration | | `local-backend` | Local Backend | `bi-house-fill` | Configuration | | `memanto` | MEMANTO | `bi-cpu` | Configuration | | `cost-log` | OpenRouter Cost Log | `bi-graph-up` | Analytics & Docs | | `guide` | Model Guide | `bi-book` | Analytics & Docs | --- ## 2. Tab: General **Description:** "Configure global API keys, budget, and content parameters." ### Section 2.1 — API Configuration | Field | Option Key | Type | Input | Required | Default | Description | |-------|-----------|------|-------|----------|---------|-------------| | OpenRouter API Key | `openrouter_api_key` | `string` | `password` with show/hide toggle | Yes (marked `*`) | `""` | Get from [openrouter.ai/keys](https://openrouter.ai/keys). Placeholder: `sk-or-v1-...` | | Test Connection | _(button)_ | — | `button` | — | — | AJAX call to `wpaw_test_api_connection`. Shows spinner + result badge. | ### Section 2.2 — OpenRouter Budget & Cost Tracking Displays a **3-column dashboard** before the input fields: | Display Card | Variable | Source | |-------------|----------|--------| | Used This Month | `$monthly_used` | `Cost_Tracker::get_monthly_total()` | | Budget Usage (progress bar) | `$budget_percent` | Calculated: `(used/budget)*100` | | Remaining | Calculated | `max(0, budget - used)` | Progress bar color: `success` (<70%), `warning` (70-90%), `danger` (>90%). | Field | Option Key | Type | Input | Default | Validation | Description | |-------|-----------|------|-------|---------|------------|-------------| | Monthly Budget (USD) | `monthly_budget` | `float` | `number` with `$` prefix | `600` | `floatval()`, min 0, step 0.01 | Maximum spend per month. 0 = unlimited. | | Enable Cost Tracking | `cost_tracking_enabled` | `bool` | `checkbox` (switch) | `true` | Boolean | Show cost tracking in editor sidebar. | ### Section 2.3 — Research & Web Search | Field | Option Key | Type | Input | Default | Options | Description | |-------|-----------|------|-------|---------|---------|-------------| | Enable Web Search | `web_search_enabled` | `bool` | `checkbox` (switch) | `false` | — | Default for new posts. Can also be toggled per-request in editor sidebar. | | Search Depth | `search_depth` | `string` | `select` | `"medium"` | `low` / `medium` / `high` | Controls search depth level. | **Two-column sub-section:** **Left — OpenRouter Search Engine:** | Field | Option Key | Type | Input | Default | Options | Description | |-------|-----------|------|-------|---------|---------|-------------| | Search Engine | `search_engine` | `string` | `select` | `"auto"` | `auto` (Native → Exa fallback) / `native` (Free, built-in) / `exa` (Paid, ~$0.02/search) | Used when active model routes through OpenRouter. | **Right — Brave Search API (for Local/Codex):** | Field | Option Key | Type | Input | Default | Description | |-------|-----------|------|-------|---------|-------------| | Brave Search API Key | `brave_search_api_key` | `string` | `password` | `""` | Used automatically when active model is Local Backend or Codex. Placeholder: `BSA...`. Free at [brave.com/search/api](https://brave.com/search/api/) (2,000 requests/month). | ### Section 2.4 — Clarification Quiz | Field | Option Key | Type | Input | Default | Options | Description | |-------|-----------|------|-------|---------|---------|-------------| | Enable Clarification Quiz | `enable_clarification_quiz` | `bool` | `checkbox` (switch) | `true` | — | Ask clarifying questions when context is missing. | | Confidence Threshold | `clarity_confidence_threshold` | `string` | `select` | `"0.6"` | `0.5` (Very Sensitive) / `0.6` (Sensitive - Recommended) / `0.7` (Balanced) / `0.8` (Strict) / `0.9` (Very Strict) | When to trigger the quiz. | | Context Categories | `required_context_categories` | `array` | multi-checkbox (scrollable box, max-height 200px) | All 7 checked | `target_outcome` / `target_audience` / `tone` / `content_depth` / `expertise_level` / `content_type` / `pov` | Which context dimensions to ask about. | ### Section 2.5 — Content Settings (Language) | Field | Option Key | Type | Input | Default | Description | |-------|-----------|------|-------|---------|-------------| | Preferred Languages | `preferred_languages` | `array` | multi-checkbox grid (2 cols on mobile, 4 on md+) | `["auto", "English", "Indonesian"]` | Languages shown in the language selector when creating articles. | **Available language options (24 total):** | Value | Label | |-------|-------| | `auto` | Auto-detect | | `English` | English | | `Indonesian` | Indonesian (Bahasa Indonesia) | | `Javanese` | Javanese (Basa Jawa) | | `Sundanese` | Sundanese (Basa Sunda) | | `Spanish` | Spanish (Español) | | `French` | French (Français) | | `Arabic` | Arabic (العربية) | | `Chinese` | Chinese (中文) | | `Japanese` | Japanese (日本語) | | `Portuguese` | Portuguese (Português) | | `German` | German (Deutsch) | | `Hindi` | Hindi (हिंदी) | | `Korean` | Korean (한국어) | | `Vietnamese` | Vietnamese (Tiếng Việt) | | `Thai` | Thai (ไทย) | | `Tagalog` | Tagalog | | `Malay` | Malay (Bahasa Melayu) | | `Russian` | Russian (Русский) | | `Italian` | Italian (Italiano) | | `Dutch` | Dutch (Nederlands) | | `Polish` | Polish (Polski) | | `Turkish` | Turkish (Türkçe) | | `Swedish` | Swedish (Svenska) | | Field | Option Key | Type | Input | Default | Description | |-------|-----------|------|-------|---------|-------------| | Custom Languages | `custom_languages` | `array` | Dynamic text input list with add/remove buttons | `[]` | Add any language not listed above (e.g., regional dialects). Placeholder: `e.g., Betawi, Minangkabau`. | ### Section 2.6 — Advanced Settings | Field | Option Key | Type | Input | Default | Validation | Description | |-------|-----------|------|-------|---------|------------|-------------| | Enable Automated FAQ Schema | `enable_faq_schema` | `bool` | `checkbox` (switch) | `false` | Boolean | Auto-inject FAQPage JSON-LD. Compatible with Yoast/RankMath. Disable if SEO plugin handles it. | | Chat History Limit | `chat_history_limit` | `int` | `number` (max-width 120px) | `20` | `absint()`, capped at 200, min 0 | Messages stored per post. 0 = disable chat history. | --- ## 3. Tab: AI Models **Description:** "Select logic engines for different stages of the writing pipeline." ### Section 3.1 — Quick Presets (3 clickable cards) These are **not saved fields** — they populate the 6 model selects below via JavaScript. | Preset | Cost | Chat/Clarity/Planning | Writing | Refinement | Image | |--------|------|----------------------|---------|------------|-------| | **Budget** | ~$0.06/article | Gemini 2.5 Flash | Mistral Small Creative | Gemini 2.5 Flash | FLUX.2 klein | | **Balanced** ⭐ | ~$0.14/article | Gemini 2.5 Flash | Claude 3.5 Sonnet | Claude 3.5 Sonnet | Riverflow V2 Max | | **Premium** | ~$0.31/article | Gemini 3 Flash Preview | GPT-4.1 | GPT-4.1 | FLUX.2 max | ### Section 3.2 — OpenRouter Provider Routing (collapsible sub-section) | Field | Option Key | Type | Input | Default | Description | |-------|-----------|------|-------|---------|-------------| | Enable Provider Routing | `openrouter_provider_routing_enabled` | `bool` | `checkbox` (switch) | `false` | Pin OpenRouter requests to a specific provider for BYOK/routing. | | Provider Slug | `openrouter_provider_slug` | `string` | `text` (small) | `"auto"` | Examples: `openai`, `anthropic`, `google`, `z-ai`. Sanitized via `sanitize_key()`. | | Only Use This Provider | `openrouter_provider_only` | `bool` | `checkbox` | `false` | Prevents Azure or other providers when slug is `openai`. | | Allow Fallback Providers | `openrouter_allow_provider_fallbacks` | `bool` | `checkbox` | `false` | Leave off for BYOK-only behavior. | ### Section 3.3 — AI Model Configuration (6 model selectors) All use **Select2 searchable dropdowns** populated via AJAX from the OpenRouter models API. Each has a provider badge (OpenRouter / Local Backend / Codex) showing which provider the model routes through. | Field | Option Key | Badge | Default Model | data-model-type | Description | |-------|-----------|-------|--------------|-----------------|-------------| | Chat Model | `chat_model` | Discussion (info) | `google/gemini-2.5-flash` | `chat` | Discussion, research, recommendations | | Clarity Model | `clarity_model` | Analysis (info) | `google/gemini-2.5-flash` | `clarity` | Prompt analysis, quiz generation | | Planning Model | `planning_model` | Outline (info) | `google/gemini-2.5-flash` | `planning` | Article outline generation | | Writing Model | `writing_model` | Main Writer (primary) | `anthropic/claude-3.5-haiku` | `execution` | Article draft generation (2-5k words) | | Refinement Model | `refinement_model` | Editing (info) | `anthropic/claude-3.5-sonnet` | `execution` | Paragraph edits, rewrites, polish | | Image Model | `image_model` | Visual (warning) | `openai/gpt-4o` | `image` | Image generation | **Note:** Writing Model has a legacy alias `execution_model` (mapped to `writing_model` during sanitization). **Refresh Models button:** `#wpaw-refresh-models` — AJAX call to `wpaw_refresh_models`. ### Section 3.4 — Custom Models | Sub-field | Type | Input | Description | |-----------|------|-------|-------------| | Model ID | `string` | `text` | Exact OpenRouter model ID. Placeholder: `model-provider/model-name` | | Display Name | `string` | `text` | Optional friendly name. Placeholder: `Display Name (optional)` | | Model Type | `string` | `select` | `text` or `image` | | Remove | — | `button` | Delete row | Stored in separate option: `wp_agentic_writer_custom_models` (array of `{id, name, type}` objects). - **Add button:** `#wpaw-add-custom-model` — clones from `