# Changelog - Technodrome AI Content Assistant

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [5.0.0] - 2026-08-09

### Major Release — Images in your articles

For the first time the plugin can generate an image for the article without
needing a separate, dedicated image provider. Version bumped to 5.0.0 because
the image pipeline is new behaviour, not a fix.

### Added (Auto mode — one call, text + image)
- New **Auto — use main AI model** option in the Image Model dropdown, and it is now the default. In Auto mode the same model that writes the article also produces the image, so the picture reflects the article that was just written instead of being drawn blind from a short prompt.
- **OpenAI**: uses the Responses API (`/v1/responses`) with the built-in `image_generation` tool, so a GPT model (GPT-5.6 and family) returns text and image data from a single request.
- **Google Gemini**: uses `generateContent` with `responseModalities: ["IMAGE"]` and reads the returned `inlineData` base64 payload. Gemini is now listed as an image-capable provider — previously selecting it disabled image generation entirely.
- Both paths reuse the existing Media Library code, so generated images are saved and attached as the featured image exactly as before.

### Added (resolution + quality controls)
- **Resolution** now offers 16:9 (1280x720) and 9:16 (720x1280) in addition to square/wide/tall.
- New **Quality** field (Low / Standard / High), separate from pixel resolution. It maps to the provider's own quality parameter — `low`/`medium`/`high` for the GPT Image family — so cost can be traded against detail without changing image size. The field hides itself for providers that do not support it.
- New **Image Description** box (2 rows) and **Style** picker, both saved in the profile. An empty description falls back to the article topic.

### Changed (model list brought up to date)
- **`dall-e-3` was retired by OpenAI on 2026-03-04** but was still the plugin's default image model — meaning image generation failed by default for anyone who had not changed it. It is now transparently remapped to `gpt-image-2` at generation time, so existing profiles keep working.
- Added **GPT Image 2** (released 2026-04-21) as the current dedicated image model. DALL-E 2 is kept in the list, labelled Legacy.
- Image capability is now decided **per provider** rather than by a hardcoded per-model whitelist, which went stale every time a new model shipped.

### Changed (UI reorganization)
- Moved **AI Image Generation** out of the Generate tab's AI Provider panel into the **Content Rules** tab, right column, directly **above Web Sources**.
- The image section is highlighted in light blue and marked **FREE** — it is not license-gated, unlike the PREMIUM fields around it. Styling is defined for both light and dark mode so labels, inputs and hints stay readable in each.
- Reordered the AI Provider panel into the logical setup sequence: **1. AI Provider → 2. API Key → 3. AI Model**. Models are fetched from the provider using the key, so the key now comes before the model list instead of after it.
- All new controls are constrained to the dashboard column ("fit to field") — long option labels are clipped rather than widening the column, hints wrap inside the field, and the description box resizes vertically only.

### Changed (switch and settings split by purpose)
- The plain **YES/NO switch** sits in the Generate tab, in row 3 next to the AI Model, because "do I want a picture for THIS article" is a generation-time decision. Row 3 reads left to right: **refresh models | AI Model | switch | AI IMAGE**. The refresh button is deliberately at the opposite end from the switch so the two cannot be mistaken for each other.
- All the **settings** (description, model, resolution, quality, style) stay in the Content Rules tab, since they are profile settings. That panel is dimmed rather than hidden while the switch is off, so settings remain readable and editable, and it shows an ON/OFF badge plus a hint pointing at the switch.
- The switch itself now signals **availability with a coloured ring**, separately from the on/off state: a **green ring** means this provider can generate images (shown even while the switch is off, so you know the option is there), a **green ring with a green track** means it is switched on, and a **red ring with a grey track** means the provider cannot make images and the switch is locked. The ring is drawn with `box-shadow`, so it adds no width and cannot push the row out of line.
- New **refresh button** reloads the provider's model list without a page reload, keeping the current selection when it still exists.
- Row 3 is laid out so only the model select shrinks; long model names are clipped instead of pushing the switch off the line, and the row wraps to two lines on narrow screens.

### Fixed
- **Auto mode produced no image and an error naming the old image model.** Two separate causes: the main model was read from `$args['model']`, but the selected model actually lives at `$args['ai_settings']['ai_model']` — so every Auto request silently went to a hardcoded fallback model instead of the user's; and the resolution list offered sizes (1792x1024, 1280x720, 720x1280) that the GPT Image models and DALL-E 2 reject outright, which is a hard API error.
- **Auto now always produces an image.** Testing confirmed the GPT-5.6 Luna/Terra/Sol chat models return no image from the Responses API image tool. Instead of failing the article, Auto now falls back to `gpt-image-2` when the chat model returns nothing or errors.
- Requested resolutions are clamped to the nearest ratio the chosen model actually supports (wide → 1536x1024, tall → 1024x1536, DALL-E 2 → square), so no dashboard choice can produce an API error.
- Removed the dead `build_image_prompt()` method and stale DALL-E wording left over from the old image pipeline.
- Per-article image settings are now sent with the generate request (`ai_image_options`), so changing a dropdown applies to that article even if autosave has not persisted the profile yet.
- Profile storage extended with the image `prompt` field and updated defaults (`model: auto`, `quality: standard`, `style: photo`), replacing the old `realistic` style value that no dropdown option matched.

---
## [4.9.1] - 2026-08-02

### Fixed
- **Critical: "Cannot modify header information - headers already sent" on activation.** A UTF-8 byte order mark (`EF BB BF`) preceded the opening `<?php` tag in 10 PHP files, including the main plugin file. PHP emitted those three bytes as output on line 1, before WordPress could send cookies/headers, breaking `wp-login.php` and `wp-admin` while the plugin was active. All BOMs removed; every non-empty PHP file now begins with the exact bytes `<?php`.
- Removed trailing `?>` close tags from 4 files. `includes/class-profile-manager.php` was a second active output source: its closing tag was followed by `


`, emitting 6 bytes on every `init`.
- Moved the `ABSPATH` direct-access guard to the top of the main plugin file so it runs before any other statement.

### Removed
- Deleted 4 empty (0-byte) dead files that were loaded on every request via `require_once`: `class-database.php`, `class-history-manager.php`, `class-security.php`, `class-websources.php`. Their `require_once` calls were removed from `load_dependencies()`. The only reference to any of them (`TAICS_Database`) is already guarded by `class_exists()`, so activation is unaffected.

---
## [4.9.0] - 2026-07-11

### Changed
- Aligned WordPress provider defaults and model catalog with the published Joomla 4.9.0 release line.
- Added a central HTTP transport layer for AI providers and dynamic model discovery, keeping SSL verification enabled and using a narrow IPv4 retry only after hosting-level connection failures.
- Updated Google default generation to `gemini-3.5-flash`, Anthropic default to `claude-sonnet-5`, and OpenAI default to the GPT-5.6 family.

### Fixed
- Restored the missing `TAICS_Photo_Manager` implementation so photo upload/delete no longer fatal-errors.
- Hardened image upload validation with server-side MIME detection, `getimagesize()`, `wp_check_filetype_and_ext()`, and server-selected extensions.
- Improved OpenAI image generation support for GPT Image models and both `url` and `b64_json` responses.
- Routed provider API errors through a shared parser so users see real network/API messages instead of generic failures.

### Removed
- Removed browser debug output from distributed assets and cleaned the stale video manager backup file.

---
## [4.8.6] - 2026-06-13

### Changed - WordPress 7.0 Compatibility Release

- Updated plugin version metadata from `4.2.3` to `4.8.6` so the WordPress release line matches Joomla
- Updated plugin headers and WordPress.org readme metadata to `Tested up to: 7.0`
- Aligned internal version markers and release documentation for cleaner maintenance
- Performed local compatibility audit of the plugin bootstrap/admin flow against WordPress 7.0 expectations; no immediate version-gated breakage found in the current codebase
- Replaced the old mixed model catalog with a June 2026 article-only shortlist for WordPress
- Removed `groq` and `glm` from the main provider dropdown for this release to reduce dead-end article selections
- Switched the default provider flow from Google to OpenAI and added legacy profile model/provider normalization

---

## [4.2.3] - 2026-05-10

### Changed - Model Catalog Update (All Providers)

- **OpenAI**: Dodani GPT-5.5, GPT-5.4, GPT-5.4 Pro, GPT-5.4 Mini na vrh liste
- **Google**: Dodani Gemini 3.1 Pro Preview i Gemini 3.1 Flash-Lite; Gemini 3 Pro označen kao deprecated (Mar 2026); uklonjen lažni Gemini 3 Flash-Lite
- **DeepSeek**: Dodani DeepSeek V4 Pro i V4 Flash; uklonjen nepostojeći V3.1
- **Cohere**: Dodan Command A 03-2025 (novi flagship); uklonjeni nepostojeći command-r7/command-r7-plus/command-r-08-2025; ispravni ID-jevi command-r-08-2024 i command-r-plus-08-2024
- **Groq**: Ispravljeni Llama 4 ID-jevi (bili potpuno pogrešni): `llama-4-maverick-17b-it` → `meta-llama/llama-4-maverick-17b-128e-instruct`; Scout ispravljen analogno; Maverick označen kao deprecated (Feb 2026); uklonjeni nepostojeći tool-use varijanti
- **Mistral**: Dodan `mistral-large-2512` (Mistral Large 3, nov flagship); dodani `ministral-14b-2512`, `ministral-8b-2512`, `ministral-3b-2512`, `codestral-2501`; uklonjeni nepostojeći `mistral-3-large/medium/small` i `codestral-v3`
- **GLM**: Dodani `glm-5.1` (novi flagship) i `glm-5-turbo`
- **Default modeli ažurirani**: openai→gpt-5.5, google→gemini-3.1-pro-preview, deepseek→deepseek-v4-pro, cohere→command-a-03-2025, groq→meta-llama/llama-4-scout-17b-16e-instruct, mistral→mistral-large-2512, glm→glm-5.1

---

## [4.2.1] - 2026-05-10

### Fixed
- **Anthropic Model IDs Corrected**: Replaced fake/speculative IDs (`claude-4-opus-20260210`, `claude-4-sonnet-20260120`, `claude-4-haiku-20260215`) with real Anthropic API IDs (`claude-opus-4-7`, `claude-sonnet-4-6`, `claude-haiku-4-5-20251001`)
- **Anthropic Incomplete IDs Fixed**: `claude-3.7-sonnet` → `claude-3-7-sonnet-20250219`, `claude-3-opus` → `claude-3-opus-20240229`, `claude-3-sonnet` → `claude-3-sonnet-20240229`, `claude-3-haiku` → `claude-3-haiku-20240307`
- **Anthropic Default Model Fixed**: `get_default_model('anthropic')` now returns `claude-opus-4-7` (was: non-existent `claude-4-opus-20260210`)

---

## [4.2.0] - 2026-05-10

### Changed - Single Source of Truth Refactor

This release completes the model catalog unification started in v4.1.5. Models are now defined in **only one place** (`TAICS_Model_Manager::get_hardcoded_models()`), eliminating drift between frontend and backend lists.

- **JS Model Duplicate Eliminated**: `features/generate-tab/ai-provider-select.js` no longer contains its own ~110-line hardcoded model list. Frontend now reads `TAICS_MODELS` JS object injected via `wp_localize_script` from the centralized `TAICS_Model_Manager`.
- **Provider Class Methods Wrap Model_Manager**: All 9 `TAICS_Provider_*::get_available_models()` static methods (OpenAI, Anthropic, Google, DeepSeek, Cohere, Groq, Together, Mistral, GLM) are now thin wrappers delegating to `TAICS_Model_Manager::get_hardcoded_models($provider)`. Removed ~700 lines of duplicate API-fetching code that was never called.
- **Generate.php Fallback Simplified**: Hardcoded `$taics_ai_models` fallback in `dashboard/modules/generate-tab/generate.php` removed; pulls directly from `TAICS_Model_Manager::get_all_models()`.
- **Master class `TAICS_AI_Providers::get_all_models()` populated**: Was returning empty arrays as a stub; now returns the full catalog via Model Manager.
- **`get_ai_models()` in main plugin**: Hardcoded ~130-line array replaced with a wrapper that combines `TAICS_Model_Manager::get_all_models()` with `TAICS_AI_Providers::get_provider_names()`.
- **Template safe for both formats**: `generate.php` model dropdown template now handles both legacy (string IDs) and new (`{id, name}` objects) formats via inline check.

### Result

- Adding a new model now requires editing **one file only**: `includes/class-model-manager.php` (was 5 files in v4.1.5).
- Net code reduction: **~950 lines removed** across PHP and JS, replaced by ~50 lines of delegation/wrapping.
- Frontend and backend lists can no longer drift apart.

### Migration

No DB or settings changes. Existing API keys and saved profiles work unchanged. Updating from 4.1.x is in-place.

---

## [4.1.5] - 2026-04-10

### Security
- **Autosave Nonce Fix**: Nonce verification now runs BEFORE any data processing in `handle_autosave_profile()` — prevents unauthenticated data parsing
- **Clear Cache Nonce Fix**: `handle_clear_model_cache()` now uses `taics_ajax_nonce` consistently with all other handlers (was using non-existent `taics_footer_nonce`)

### Added
- **3 New Video Platforms**: BiliBili, Dailymotion, and Rumble support in Video Manager (embed, validation, metadata, platform detection) — now matches Joomla's 8-platform support
- **Dynamic Model Loading**: Models are now fetched dynamically from provider APIs (OpenAI, DeepSeek, Groq, Mistral) with automatic fallback to hardcoded lists
- **Video Description in AI Context**: Video description from YouTube RSS is now passed to AI prompt for richer article generation in Channel Monitor mode
- **Channel Monitor Metadata**: `generate_article()` now passes full `video_context_metadata` (platform, author, title, description) to Content Generator

### Changed
- **Unified Model Source**: `get_ai_models()` in main plugin file now delegates to `TAICS_Model_Manager::get_all_models()` — single source of truth, no more duplicate model lists
- **Inline CSS Removed**: Demo notice and video attribution sections now use external CSS classes (`.taics-demo-notice`, `.taics-video-attribution`) instead of inline styles

### Removed
- **Dead Code**: Removed 4 unused `example_translation_function_1/2/3/4` methods from Content Generator

---

## [4.1.4] - 2026-03-21

### Fixed
- **Profile Image Preview Race Condition**: Images now display immediately on profile load — `renderExistingPhotos()` re-renders data stored before `$container` was initialized, skipping `loadPhotosFromUserMeta()` which was overwriting profile data

### Security
- **Nonce Removed from Console**: `console.log` exposing nonce value via `this.getNonce()` removed from autosave flow
- **Nonce Verification Standardized**: `ajax_autosave_profile()` now uses `check_ajax_referer()` consistent with all other handlers

### Cleanup
- Removed duplicate `isProfileSwitching` guard (unreachable dead code after first `return`)
- Removed unused `collectLayoutTemplateData()` function (superseded by `collectLayoutTemplateDataWithCanvas()`)
- Removed unused `collectLayoutTemplateDataDirectly()` function (old DOM-based approach, never called)
- Removed commented-out save button event listener block

---

## [4.1.3] - 2026-02-28

### Added
- **Blue Gradient Footer**: Footer now uses `linear-gradient(135deg, #1e3a8a → #3b82f6)` in light mode and `#0f172a → #1e3a8a` in dark mode
- **Contact Us Button**: Circular `?` button in header license area — links to technodrome.nasrpskom.com in a new tab
- Profile buttons updated to glass effect (semi-transparent white) on gradient footer background

---

## [4.1.2] - 2026-02-28

### Fixed
- **AI Content Truncation**: Articles no longer cut off mid-sentence/mid-word for non-English languages (Serbian, Croatian, Bosnian, etc.). Root cause: non-English text uses 2–2.5 tokens per word vs ~1.3 for English, plus HTML tag overhead — the `word_count * 3` formula was too low.

### Improved
- **`max_tokens` Multiplier**: Increased from `word_count × 3` to `word_count × 5` across all 9 AI providers — provides enough headroom for any language and HTML markup:
  - Short (400 words): 1,200 → 2,000 tokens
  - Medium (650 words): 1,950 → 3,250 tokens
  - Long (1,000 words): 3,000 → 5,000 tokens
  - Extended (1,500 words): 4,500 → 7,500 tokens
- **API Request Timeout**: Increased from 60s to 120s for all generation calls — prevents timeouts for longer content with slower models

### Providers Updated
OpenAI, Anthropic, Google (Gemini), DeepSeek, Cohere, Groq, Together AI, Mistral, GLM

---

## [4.1.1] - 2026-02-28

### Removed
- **Bottom Tab Navigation**: Removed duplicate bottom tab bar from dashboard (top tab bar is sufficient, cleaner UI)

### Fixed
- **Mode 5 Slot 2 Labels**: "Video URL" relabeled to "Channel URL", "Video Title" field hidden (not needed for channel monitoring)
- **Channel Monitor Field ID**: `channel-monitor.js` was reading `#taics-video-url-2` but HTML field has `id="video-url-2"` — channel URL was always empty
- **Video Data AJAX Handler**: Registered missing `taics_save_video_data` action — fixed "[VIDEO INLINE SCRIPT] AJAX error: Bad Request" console errors
- **YouTube @handle Scraping**: Added `externalChannelId`, `browseId`, and in-page `/channel/UC...` regex patterns for more reliable channel ID extraction
- **PHPCS Warnings**: Added `phpcs:ignore` for `error_log`/`print_r` in debug blocks, sanitized `$_POST['publish']` with `sanitize_text_field()`

## [4.1.0] - 2026-02-24

### Fixed
- **Mode 5 Channel Videos**: `channel_videos` and `channel_description` now properly forwarded through ContentGenerator to AI prompt
- **Mode 5 AI Prompt**: Channel name, channel type, description, and recent video list now included in prompt context for Mode 5
- **YouTube RSS Feed**: Replaced stub with real implementation - resolves @handle to channel ID, fetches RSS XML, extracts video titles/URLs/descriptions
- **Vimeo Channel Scraping**: Replaced stub with page scraping + oEmbed per video implementation
- **TikTok Profile Scraping**: Replaced stub with page scraping + TikTok oEmbed implementation
- **Frontend Slot Validation**: Generate button now validates Slot 2 has a Channel URL before attempting Mode 5 generation
- **Generation Mode Stats**: Mode 4 (`ai_with_video_url_context`) and Mode 5 (`ai_with_video_channel_context`) now tracked in profile stats

### Changed
- **Generate Content Button**: Changed from gradient blue to gradient red for better visual distinction from other UI elements

## [4.0.7] - 2026-02-21

### Fixed
- **Profile Switching Race Condition**: AutoSave timer now cleared when switching profiles, preventing old profile data from being saved to the new profile slot
- **Default Tone Field Styling**: Removed conflicting CSS overrides (`height: 36px`, `padding: 6px 10px`) from `generate.css` and hardcoded colors from `content-rules.css` - field now inherits `.taics-field` styles and looks identical to Content Type, Content Length, Category, Language and Generation Mode fields

## [4.0.4] - 2026-01-22

### Added
- **Video Slot Renaming**: Slots now show descriptive names in video context modes:
  - "GENERATE AI CONTENT FROM VIDEO URL" for Slot 1 in AI + Video URL Context mode
  - "GENERATE AI CONTENT FROM VIDEO CHANNEL" for Slot 2 in AI + Video Channel Context mode
- **UNDER CONSTRUCTION Overlay**: Added visual overlay on Slot 2 when in video context modes, indicating that channel mode is not yet implemented
- **Mode-Specific Transformation**: Video slot renaming and overlays only apply when in video context modes, keeping regular modes unchanged

### Changed
- Updated video-slot-transformation.js to handle slot renaming and UNDER CONSTRUCTION overlay
- Modified transformation logic to only apply in AI + Video URL Context and AI + Video Channel Context modes
- Added visual feedback with yellow/orange gradient UNDER CONSTRUCTION badge

### Improved
- Better user guidance in video context modes
- Clearer distinction between active and locked slots
- Consistent UI experience across all modes

## [4.0.3] - 2026-01-21

### Added
- **AI + Video URL Context (PREMIUM)**: New generation mode that generates articles from single video URLs (YouTube, Vimeo, TikTok)
- **AI + Video Channel Context (PREMIUM)**: New generation mode that generates articles from entire video channels
- **Video Slot Transformation System**: Smart slot locking mechanism that automatically locks/unlocks slots based on selected generation mode
- **Compact Notification**: New compact notification displayed above "Add Content Title" field when video context mode is active
- **Slot-Specific Activation**: Video URL Context activates Slot 1, Video Channel Context activates Slot 2

### Changed
- Updated generation mode dropdown to include two new video context options
- Modified video-slot-transformation.js to handle mutually exclusive slot activation
- Updated video-context-mode.js to properly manage notification visibility
- Modified inline script in layout-templates.php to skip execution when transformation mode is active

### Improved
- Integration with Joomla-style video context patterns
- Inline script compatibility with transformation mode
- UI feedback when video context mode is active
- CSS styling for video context notification

### Fixed
- Video context mode detection in generate-button.js (now checks for both `ai_with_video_url_context` and `ai_with_video_channel_context`)
- CSS styles for video context notification placement above title field
- Plugin registration for video-manager.js CSS file

### Updated
- Plugin version to 4.0.0
- readme.txt with new features and changelog
- Created CHANGELOG.md

## [3.8.3] - 2025-12-15

### Changed
- License Key Format Normalization
- Critical Bug Fixes
- Improved API stability

## [3.8.2] - 2025-11-20

### Changed
- Enhanced AI model compatibility
- Performance improvements

## [3.8.1] - 2025-11-01

### Fixed
- Language handler integration
- Added new AI models

## [3.8.0] - 2025-10-15

### Added
- 40+ language support
- Enhanced content rules system
- New layout templates

## Previous Versions

For changelog of versions prior to 3.8.0, please refer to the plugin's commit history.

---

## Generation Modes Reference

| Mode | Plan Required | Description |
|------|---------------|-------------|
| AI Without Rules | FREE | Standard AI generation without content rules |
| AI + Content Rules | PRO | AI skills combined with custom Content Rules |
| Only with Content Rules | PREMIUM | Uses only your rules (no AI creativity) |
| AI + Video URL Context | PREMIUM | Generate article from single video URL |
| AI + Video Channel Context | PREMIUM | Generate article from entire video channel |

## Video Slot Behavior

When using Video Context modes, only ONE video slot is active:

| Generation Mode | Slot 1 | Slot 2 |
|-----------------|--------|--------|
| AI + Video URL Context | 🔓 Active | 🔒 Locked |
| AI + Video Channel Context | 🔒 Locked | 🔓 Active |
| Regular modes | 🎬 Normal | 🎬 Normal |



